From 958cc4bcc33725bd14f9cd535a51343c509df82b Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Thu, 21 May 2026 14:10:43 +0200 Subject: [PATCH 1/6] feat: Add `@flue/runtime` instrumentation --- .agents/skills/e2e-tests/SKILL.md | 1 + e2e/config/pr-comment-scenarios.json | 12 + .../.agents/skills/e2e-flue-skill/SKILL.md | 6 + .../flue-v0-7-0-auto-hook.cassette.json | 2345 ++++++++++++++ .../flue-v0-7-0-wrapped.cassette.json | 2345 ++++++++++++++ .../flue-v0-7-0-auto-hook.span-tree.json | 552 ++++ .../flue-v0-7-0-auto-hook.span-tree.txt | 455 +++ .../flue-v0-7-0-wrapped.span-tree.json | 552 ++++ .../flue-v0-7-0-wrapped.span-tree.txt | 455 +++ .../flue-instrumentation/assertions.ts | 453 +++ .../flue-instrumentation/cassette-filter.mjs | 11 + .../flue-instrumentation/constants.mjs | 4 + .../flue-instrumentation/package.json | 8 + .../flue-instrumentation/pnpm-lock.yaml | 2715 +++++++++++++++++ .../flue-instrumentation/scenario.impl.mjs | 217 ++ .../flue-instrumentation/scenario.mjs | 3 + .../flue-instrumentation/scenario.test.ts | 58 + .../flue-instrumentation/scenario.ts | 3 + .../configs/ai-sdk.test.ts | 64 - .../auto-instrumentations/configs/all.test.ts | 40 - js/src/auto-instrumentations/configs/all.ts | 2 + js/src/auto-instrumentations/configs/flue.ts | 32 + .../configs/github-copilot.test.ts | 90 - js/src/exports.ts | 1 + js/src/instrumentation/braintrust-plugin.ts | 13 + .../instrumentation/plugins/flue-channels.ts | 92 + .../plugins/flue-plugin.test.ts | 472 +++ js/src/instrumentation/plugins/flue-plugin.ts | 1187 +++++++ js/src/instrumentation/registry.ts | 4 + js/src/vendor-sdk-types/flue.ts | 207 ++ js/src/wrappers/flue.test.ts | 195 ++ js/src/wrappers/flue.ts | 391 +++ 32 files changed, 12791 insertions(+), 194 deletions(-) create mode 100644 e2e/scenarios/flue-instrumentation/.agents/skills/e2e-flue-skill/SKILL.md create mode 100644 e2e/scenarios/flue-instrumentation/__cassettes__/flue-v0-7-0-auto-hook.cassette.json create mode 100644 e2e/scenarios/flue-instrumentation/__cassettes__/flue-v0-7-0-wrapped.cassette.json create mode 100644 e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-auto-hook.span-tree.json create mode 100644 e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-auto-hook.span-tree.txt create mode 100644 e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-wrapped.span-tree.json create mode 100644 e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-wrapped.span-tree.txt create mode 100644 e2e/scenarios/flue-instrumentation/assertions.ts create mode 100644 e2e/scenarios/flue-instrumentation/cassette-filter.mjs create mode 100644 e2e/scenarios/flue-instrumentation/constants.mjs create mode 100644 e2e/scenarios/flue-instrumentation/package.json create mode 100644 e2e/scenarios/flue-instrumentation/pnpm-lock.yaml create mode 100644 e2e/scenarios/flue-instrumentation/scenario.impl.mjs create mode 100644 e2e/scenarios/flue-instrumentation/scenario.mjs create mode 100644 e2e/scenarios/flue-instrumentation/scenario.test.ts create mode 100644 e2e/scenarios/flue-instrumentation/scenario.ts delete mode 100644 js/src/auto-instrumentations/configs/ai-sdk.test.ts delete mode 100644 js/src/auto-instrumentations/configs/all.test.ts create mode 100644 js/src/auto-instrumentations/configs/flue.ts delete mode 100644 js/src/auto-instrumentations/configs/github-copilot.test.ts create mode 100644 js/src/instrumentation/plugins/flue-channels.ts create mode 100644 js/src/instrumentation/plugins/flue-plugin.test.ts create mode 100644 js/src/instrumentation/plugins/flue-plugin.ts create mode 100644 js/src/vendor-sdk-types/flue.ts create mode 100644 js/src/wrappers/flue.test.ts create mode 100644 js/src/wrappers/flue.ts diff --git a/.agents/skills/e2e-tests/SKILL.md b/.agents/skills/e2e-tests/SKILL.md index 4dae66340..ede026517 100644 --- a/.agents/skills/e2e-tests/SKILL.md +++ b/.agents/skills/e2e-tests/SKILL.md @@ -64,6 +64,7 @@ Cassettes mock provider HTTP responses (OpenAI, Anthropic, ...) so external-prov - When a scenario family already has `assertions.ts`, keep version- or provider-specific test setup in `scenario.test.ts` and reuse the shared assertions file. - Keep the CI e2e summary up to date. If a scenario version matrix or `variantKey` changes, update `e2e/config/pr-comment-scenarios.json` in the same change and follow the established pattern used by other versioned scenarios: one summary row per version, not separate wrapped/auto rows unless that pattern already exists for the scenario family. - Run new or updated scenarios three times in a row before considering snapshots stable. +- Do not add tests directly asserting on the auto instrumentation configs. ## Scenario Patterns diff --git a/e2e/config/pr-comment-scenarios.json b/e2e/config/pr-comment-scenarios.json index d080197c7..33b671103 100644 --- a/e2e/config/pr-comment-scenarios.json +++ b/e2e/config/pr-comment-scenarios.json @@ -154,6 +154,18 @@ "metadataScenario": "cursor-sdk-instrumentation", "variants": [{ "variantKey": "cursor-sdk-v1", "label": "v1" }] }, + { + "scenarioDirName": "flue-instrumentation", + "label": "Flue Instrumentation", + "metadataScenario": "flue-instrumentation", + "variants": [ + { "variantKey": "flue-v0-7-0-wrapped", "label": "v0.7.0 wrapped" }, + { + "variantKey": "flue-v0-7-0-auto-hook", + "label": "v0.7.0 auto-hook" + } + ] + }, { "scenarioDirName": "github-copilot-instrumentation", "label": "GitHub Copilot SDK Instrumentation", diff --git a/e2e/scenarios/flue-instrumentation/.agents/skills/e2e-flue-skill/SKILL.md b/e2e/scenarios/flue-instrumentation/.agents/skills/e2e-flue-skill/SKILL.md new file mode 100644 index 000000000..54e9f8362 --- /dev/null +++ b/e2e/scenarios/flue-instrumentation/.agents/skills/e2e-flue-skill/SKILL.md @@ -0,0 +1,6 @@ +--- +name: e2e-flue-skill +description: Deterministic skill used by the Braintrust Flue instrumentation e2e test. +--- + +Return the marker from the provided args exactly once. Output no other text. diff --git a/e2e/scenarios/flue-instrumentation/__cassettes__/flue-v0-7-0-auto-hook.cassette.json b/e2e/scenarios/flue-instrumentation/__cassettes__/flue-v0-7-0-auto-hook.cassette.json new file mode 100644 index 000000000..c778acdca --- /dev/null +++ b/e2e/scenarios/flue-instrumentation/__cassettes__/flue-v0-7-0-auto-hook.cassette.json @@ -0,0 +1,2345 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "fcd9d51c145fb90b", + "matchKey": "POST api.anthropic.com/v1/messages", + "recordedAt": "2026-05-21T06:48:59.246Z", + "request": { + "body": { + "kind": "json", + "value": { + "max_tokens": 64000, + "messages": [ + { + "content": [ + { + "cache_control": { + "type": "ephemeral" + }, + "text": "Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.", + "type": "text" + } + ], + "role": "user" + } + ], + "model": "claude-sonnet-4-5-20250929", + "stream": true, + "system": [ + { + "cache_control": { + "type": "ephemeral" + }, + "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Thu, May 21, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-LqmoTW/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + "type": "text" + } + ], + "thinking": { + "budget_tokens": 8192, + "display": "summarized", + "type": "enabled" + }, + "tools": [ + { + "description": "Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "limit": { + "description": "Maximum number of lines to read", + "type": "number" + }, + "offset": { + "description": "Line number to start from (1-indexed)", + "type": "number" + }, + "path": { + "description": "Path to the file to read", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + }, + "name": "read" + }, + { + "description": "Write content to a file. Creates the file and parent directories if they do not exist.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Path to the file to write", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + }, + "name": "write" + }, + { + "description": "Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "newText": { + "description": "Replacement text", + "type": "string" + }, + "oldText": { + "description": "Exact text to find (must be unique)", + "type": "string" + }, + "path": { + "description": "Path to the file to edit", + "type": "string" + }, + "replaceAll": { + "description": "Replace all occurrences", + "type": "boolean" + } + }, + "required": ["path", "oldText", "newText"], + "type": "object" + }, + "name": "edit" + }, + { + "description": "Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "command": { + "description": "Bash command to execute", + "type": "string" + }, + "timeout": { + "description": "Timeout in seconds", + "type": "number" + } + }, + "required": ["command"], + "type": "object" + }, + "name": "bash" + }, + { + "description": "Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "include": { + "description": "Glob filter, e.g. \"*.ts\"", + "type": "string" + }, + "path": { + "description": "Directory or file to search (default: .)", + "type": "string" + }, + "pattern": { + "description": "Search pattern (regex)", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + }, + "name": "grep" + }, + { + "description": "Find files by filename pattern using shell find -name semantics. Returns matching file paths.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "path": { + "description": "Directory to search in (default: .)", + "type": "string" + }, + "pattern": { + "description": "Filename pattern, e.g. \"*.ts\"", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + }, + "name": "glob" + }, + { + "description": "Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "cwd": { + "description": "Working directory for the child agent. AGENTS.md and skills are discovered from here.", + "type": "string" + }, + "description": { + "description": "Short human-readable label for the delegated work", + "type": "string" + }, + "prompt": { + "description": "Focused instructions for the child agent", + "type": "string" + }, + "role": { + "description": "Role to use for the child agent", + "type": "string" + } + }, + "required": ["prompt"], + "type": "object" + }, + "name": "task" + }, + { + "description": "Return a deterministic lookup result with an id needed by web_search.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "query": { + "type": "string" + } + }, + "required": ["query"], + "type": "object" + }, + "name": "lookup" + }, + { + "description": "Search a deterministic local web index. Requires the id returned by lookup.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "lookupId": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": ["lookupId", "query"], + "type": "object" + }, + "name": "web_search" + }, + { + "cache_control": { + "type": "ephemeral" + }, + "description": "Summarize the selected deterministic source after web_search returns a URL.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "url": { + "type": "string" + } + }, + "required": ["url"], + "type": "object" + }, + "name": "summarize_source" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.anthropic.com/v1/messages" + }, + "response": { + "body": { + "chunks": [ + "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-5-20250929\",\"id\":\"msg_01Au3mXEtqA63VYCtzrcsMMJ\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":10,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":2182,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":6,\"service_tier\":\"standard\",\"inference_geo\":\"not_available\"}}}", + "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"thinking\",\"thinking\":\"\",\"signature\":\"\"}}", + "event: ping\ndata: {\"type\":\"ping\"}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\"The user wants me to complete\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\" a specific instrumented research flow with three steps:\\n1. Call lookup with query \\\"flue instrumentation\\\"\\n2. Use the lookup result id to call web_search with query \\\"\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\"Braintrust Flue reasoning stream instrumentation\\\"\\n3. Use the first web_search result url to call summarize_source\\n4. Reply with exactly \\\"PROMPT_DONE\\\" after summarize_source returns\\n\\nThe user emphas\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\"izes calling exactly one tool per turn and waiting for each result. Let me start with step\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\" 1.\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"signature_delta\",\"signature\":\"ErUFCm4IDRgCKkAHu6lMZFTp53LRtoPoqjh0UrHuoIv5LTsJ7I3lHUVfs2ATNSQg9u7H+Ep/U2V3+dm55Z9I4XCuyKRcFlBIT0W2MhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMD1Qwe6/eMf8eVU1xGgwRhWxvkBZIEe9uad4iMGqUVZm3nslEGlnXnWFtC1Lo7eVfCTKPyaVMydEWLFdEkVYBr4jZ8G6xirmMvluO/Sr0A7PXSEQ+n3qF+VkUcwgO7gbSD97SYUIXKVh6QvFX9zzPIU40Ahbqq5bqU0TKXv4hbAoU8sDV4Af0KXw/9r8FocY9Ys2xX6YrVAi8v61I23dP82Zxy2VbaLrL4i744blW+VmU77L7xpH7y3RzQfldUrYzh0Buu45sh3yG/v3woK9FY1wm1v3dvDmQpV+HOU5hl0zyk8Mr/SpDm2uTAqjoT8DsOdKVerDvP9SrSbpG8sNiqT9ROv6ziY1Yq89hRR7F159Ntc1w8thi3evN7QYO2GD5LkR1GeGY5gOA4134B6/EktGcmzb1Rx0LY6BRb3T2QipZTDq+G7xwsnJNDiPz4/hchrWNzlXvc/6auvuOb9WkMGgtnox5/4/C8ZI/hCIGyvpb+mZcbewPbBXD91/neSrVP1dJC6F0t645nUK49AK8AE41lOJA6rB3sxfCItl2SiScJuRSBEE9NiseNJvpaZDxjuXQc4UWT6Uszo+LrngRTsJDWTUnF5239i15Sb7WQW0Xs0EgNA1Y6n7/6ma0EH+U9DmPD1c01o19iL9AI2ADGUeIQLSNA9OmUsLpquqFFmvWMLJ6ubYCbgHyogMfdRD6hpoN25OCQl2EP24yB0BY27rVuygYXbIOJ+vSpat0uCd8akup/g26YxcXouSYf98LTuE6GAE=\"}}", + "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0}", + "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":1,\"content_block\":{\"type\":\"text\",\"text\":\"\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"text_delta\",\"text\":\"I'll complete this instrumented research flow step by step. Starting with Step 1:\"}}", + "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":1}", + "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":2,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01NWGcbaEYFCSv7jbHaV61xR\",\"name\":\"lookup\",\"input\":{},\"caller\":{\"type\":\"direct\"}}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"query\\\": \\\"flue instrumentation\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"}\"}}", + "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":2}", + "event: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":10,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":2182,\"output_tokens\":199}}", + "event: message_stop\ndata: {\"type\":\"message_stop\"}" + ], + "kind": "sse" + }, + "headers": { + "anthropic-organization-id": "27796668-7351-40ac-acc4-024aee8995a5", + "anthropic-ratelimit-input-tokens-limit": "3000000", + "anthropic-ratelimit-input-tokens-remaining": "2999000", + "anthropic-ratelimit-input-tokens-reset": "2026-05-21T06:48:55Z", + "anthropic-ratelimit-output-tokens-limit": "600000", + "anthropic-ratelimit-output-tokens-remaining": "600000", + "anthropic-ratelimit-output-tokens-reset": "2026-05-21T06:48:55Z", + "anthropic-ratelimit-requests-limit": "20000", + "anthropic-ratelimit-requests-remaining": "19999", + "anthropic-ratelimit-requests-reset": "2026-05-21T06:48:55Z", + "anthropic-ratelimit-tokens-limit": "3600000", + "anthropic-ratelimit-tokens-remaining": "3599000", + "anthropic-ratelimit-tokens-reset": "2026-05-21T06:48:55Z", + "cache-control": "no-cache", + "cf-cache-status": "DYNAMIC", + "cf-ray": "9ff1a3628fa9c2f2-VIE", + "connection": "keep-alive", + "content-encoding": "gzip", + "content-security-policy": "default-src 'none'; frame-ancestors 'none'", + "content-type": "text/event-stream; charset=utf-8", + "date": "Thu, 21 May 2026 06:48:56 GMT", + "request-id": "req_011CbFGUxevnbsqp1nrp72Qd", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "traceresponse": "00-71c45f5456568c06df63b6a8d15fcff6-36384d0f5ffaa0a1-01", + "transfer-encoding": "chunked", + "vary": "Accept-Encoding", + "x-envoy-upstream-service-time": "1304", + "x-robots-tag": "none" + }, + "status": 200, + "statusText": "OK" + } + }, + { + "callIndex": 1, + "id": "ff22a182ea5a9c06", + "matchKey": "POST api.anthropic.com/v1/messages", + "recordedAt": "2026-05-21T06:49:03.945Z", + "request": { + "body": { + "kind": "json", + "value": { + "max_tokens": 64000, + "messages": [ + { + "content": [ + { + "text": "Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "signature": "ErUFCm4IDRgCKkAHu6lMZFTp53LRtoPoqjh0UrHuoIv5LTsJ7I3lHUVfs2ATNSQg9u7H+Ep/U2V3+dm55Z9I4XCuyKRcFlBIT0W2MhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMD1Qwe6/eMf8eVU1xGgwRhWxvkBZIEe9uad4iMGqUVZm3nslEGlnXnWFtC1Lo7eVfCTKPyaVMydEWLFdEkVYBr4jZ8G6xirmMvluO/Sr0A7PXSEQ+n3qF+VkUcwgO7gbSD97SYUIXKVh6QvFX9zzPIU40Ahbqq5bqU0TKXv4hbAoU8sDV4Af0KXw/9r8FocY9Ys2xX6YrVAi8v61I23dP82Zxy2VbaLrL4i744blW+VmU77L7xpH7y3RzQfldUrYzh0Buu45sh3yG/v3woK9FY1wm1v3dvDmQpV+HOU5hl0zyk8Mr/SpDm2uTAqjoT8DsOdKVerDvP9SrSbpG8sNiqT9ROv6ziY1Yq89hRR7F159Ntc1w8thi3evN7QYO2GD5LkR1GeGY5gOA4134B6/EktGcmzb1Rx0LY6BRb3T2QipZTDq+G7xwsnJNDiPz4/hchrWNzlXvc/6auvuOb9WkMGgtnox5/4/C8ZI/hCIGyvpb+mZcbewPbBXD91/neSrVP1dJC6F0t645nUK49AK8AE41lOJA6rB3sxfCItl2SiScJuRSBEE9NiseNJvpaZDxjuXQc4UWT6Uszo+LrngRTsJDWTUnF5239i15Sb7WQW0Xs0EgNA1Y6n7/6ma0EH+U9DmPD1c01o19iL9AI2ADGUeIQLSNA9OmUsLpquqFFmvWMLJ6ubYCbgHyogMfdRD6hpoN25OCQl2EP24yB0BY27rVuygYXbIOJ+vSpat0uCd8akup/g26YxcXouSYf98LTuE6GAE=", + "thinking": "The user wants me to complete a specific instrumented research flow with three steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id to call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url to call summarize_source\n4. Reply with exactly \"PROMPT_DONE\" after summarize_source returns\n\nThe user emphasizes calling exactly one tool per turn and waiting for each result. Let me start with step 1.", + "type": "thinking" + }, + { + "text": "I'll complete this instrumented research flow step by step. Starting with Step 1:", + "type": "text" + }, + { + "id": "toolu_01NWGcbaEYFCSv7jbHaV61xR", + "input": { + "query": "flue instrumentation" + }, + "name": "lookup", + "type": "tool_use" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "cache_control": { + "type": "ephemeral" + }, + "content": "{\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}", + "is_error": false, + "tool_use_id": "toolu_01NWGcbaEYFCSv7jbHaV61xR", + "type": "tool_result" + } + ], + "role": "user" + } + ], + "model": "claude-sonnet-4-5-20250929", + "stream": true, + "system": [ + { + "cache_control": { + "type": "ephemeral" + }, + "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Thu, May 21, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-LqmoTW/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + "type": "text" + } + ], + "thinking": { + "budget_tokens": 8192, + "display": "summarized", + "type": "enabled" + }, + "tools": [ + { + "description": "Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "limit": { + "description": "Maximum number of lines to read", + "type": "number" + }, + "offset": { + "description": "Line number to start from (1-indexed)", + "type": "number" + }, + "path": { + "description": "Path to the file to read", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + }, + "name": "read" + }, + { + "description": "Write content to a file. Creates the file and parent directories if they do not exist.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Path to the file to write", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + }, + "name": "write" + }, + { + "description": "Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "newText": { + "description": "Replacement text", + "type": "string" + }, + "oldText": { + "description": "Exact text to find (must be unique)", + "type": "string" + }, + "path": { + "description": "Path to the file to edit", + "type": "string" + }, + "replaceAll": { + "description": "Replace all occurrences", + "type": "boolean" + } + }, + "required": ["path", "oldText", "newText"], + "type": "object" + }, + "name": "edit" + }, + { + "description": "Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "command": { + "description": "Bash command to execute", + "type": "string" + }, + "timeout": { + "description": "Timeout in seconds", + "type": "number" + } + }, + "required": ["command"], + "type": "object" + }, + "name": "bash" + }, + { + "description": "Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "include": { + "description": "Glob filter, e.g. \"*.ts\"", + "type": "string" + }, + "path": { + "description": "Directory or file to search (default: .)", + "type": "string" + }, + "pattern": { + "description": "Search pattern (regex)", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + }, + "name": "grep" + }, + { + "description": "Find files by filename pattern using shell find -name semantics. Returns matching file paths.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "path": { + "description": "Directory to search in (default: .)", + "type": "string" + }, + "pattern": { + "description": "Filename pattern, e.g. \"*.ts\"", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + }, + "name": "glob" + }, + { + "description": "Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "cwd": { + "description": "Working directory for the child agent. AGENTS.md and skills are discovered from here.", + "type": "string" + }, + "description": { + "description": "Short human-readable label for the delegated work", + "type": "string" + }, + "prompt": { + "description": "Focused instructions for the child agent", + "type": "string" + }, + "role": { + "description": "Role to use for the child agent", + "type": "string" + } + }, + "required": ["prompt"], + "type": "object" + }, + "name": "task" + }, + { + "description": "Return a deterministic lookup result with an id needed by web_search.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "query": { + "type": "string" + } + }, + "required": ["query"], + "type": "object" + }, + "name": "lookup" + }, + { + "description": "Search a deterministic local web index. Requires the id returned by lookup.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "lookupId": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": ["lookupId", "query"], + "type": "object" + }, + "name": "web_search" + }, + { + "cache_control": { + "type": "ephemeral" + }, + "description": "Summarize the selected deterministic source after web_search returns a URL.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "url": { + "type": "string" + } + }, + "required": ["url"], + "type": "object" + }, + "name": "summarize_source" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.anthropic.com/v1/messages" + }, + "response": { + "body": { + "chunks": [ + "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-5-20250929\",\"id\":\"msg_01VJkPtnXDH2vYcShtiH4bA4\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":13,\"cache_creation_input_tokens\":239,\"cache_read_input_tokens\":2182,\"cache_creation\":{\"ephemeral_5m_input_tokens\":239,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":1,\"service_tier\":\"standard\",\"inference_geo\":\"not_available\"}}}", + "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"thinking\",\"thinking\":\"\",\"signature\":\"\"}}", + "event: ping\ndata: {\"type\":\"ping\"}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\"Good\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\", I got the lookup result with id \\\"flue-session-2026\\\". Now I'll proceed to step 2 and\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\" use this id as the lookupId parameter in the web_search call with the specified\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\" query.\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"signature_delta\",\"signature\":\"EoEDCm4IDRgCKkDHERZTLDmLPqGPffwRXgcxBhBgIrYXgMYvN2Ub70fw9ROsylVddlwVjiBc/lIRhKFlmKk3yGyVqaTpeWzivYSNMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMvygGdKoloZH9PbB/GgyNsBVPv5CiUkum+Q0iMO4QWY/lnhO5B8dFYJLBlnx3xICN/4EZrOIoQNdBLFV3U+M8som8sSiwj3uJx1OI8irAAbcyFYPvt3ZNfLNUReqOr+m7INr6/Ie2gnkRu9unXD+vYwFg9FbyV0lgmLyu4I3e6A+P3r6rACTCCVKokSYjy2IWp8e6v5c1+++qdywmPbK444LgqFCxOF2CF7gtf8iHoMo/rRhm/v4ypQOUdWW/lvo8sokRYHdJsSTOFLHmsuSk4eapbjPa9IjmFXOf+fNTqVY1quk3HJuLBKr7Q9PblMUX7Q4hqwo/E89HS5M3WTcm2sHl7Vict+Qbr5+8JZVlNRgB\"}}", + "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0}", + "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":1,\"content_block\":{\"type\":\"text\",\"text\":\"\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"text_delta\",\"text\":\"Now proceeding to Step 2:\"}}", + "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":1}", + "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":2,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_0153ktjSHv2H1SaKu8xPjQDj\",\"name\":\"web_search\",\"input\":{},\"caller\":{\"type\":\"direct\"}}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"lookupId\\\": \\\"fl\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ue-session-2026\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\", \\\"query\\\": \\\"Braintrust Flue reasoning stream instrumentation\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"}\"}}", + "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":2}", + "event: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":13,\"cache_creation_input_tokens\":239,\"cache_read_input_tokens\":2182,\"output_tokens\":153}}", + "event: message_stop\ndata: {\"type\":\"message_stop\"}" + ], + "kind": "sse" + }, + "headers": { + "anthropic-organization-id": "27796668-7351-40ac-acc4-024aee8995a5", + "anthropic-ratelimit-input-tokens-limit": "3000000", + "anthropic-ratelimit-input-tokens-remaining": "2999000", + "anthropic-ratelimit-input-tokens-reset": "2026-05-21T06:48:59Z", + "anthropic-ratelimit-output-tokens-limit": "600000", + "anthropic-ratelimit-output-tokens-remaining": "600000", + "anthropic-ratelimit-output-tokens-reset": "2026-05-21T06:48:59Z", + "anthropic-ratelimit-requests-limit": "20000", + "anthropic-ratelimit-requests-remaining": "19999", + "anthropic-ratelimit-requests-reset": "2026-05-21T06:48:59Z", + "anthropic-ratelimit-tokens-limit": "3600000", + "anthropic-ratelimit-tokens-remaining": "3599000", + "anthropic-ratelimit-tokens-reset": "2026-05-21T06:48:59Z", + "cache-control": "no-cache", + "cf-cache-status": "DYNAMIC", + "cf-ray": "9ff1a37acb62c2f2-VIE", + "connection": "keep-alive", + "content-encoding": "gzip", + "content-security-policy": "default-src 'none'; frame-ancestors 'none'", + "content-type": "text/event-stream; charset=utf-8", + "date": "Thu, 21 May 2026 06:49:02 GMT", + "request-id": "req_011CbFGVFFKnFuKGwHxKghcD", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "traceresponse": "00-f46a9b0cbf31085d3cea916f4cb849e0-9567490ed2d35f0c-01", + "transfer-encoding": "chunked", + "vary": "Accept-Encoding", + "x-envoy-upstream-service-time": "2617", + "x-robots-tag": "none" + }, + "status": 200, + "statusText": "OK" + } + }, + { + "callIndex": 2, + "id": "f1d50a1e6c760d6c", + "matchKey": "POST api.anthropic.com/v1/messages", + "recordedAt": "2026-05-21T06:49:07.390Z", + "request": { + "body": { + "kind": "json", + "value": { + "max_tokens": 64000, + "messages": [ + { + "content": [ + { + "text": "Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "signature": "ErUFCm4IDRgCKkAHu6lMZFTp53LRtoPoqjh0UrHuoIv5LTsJ7I3lHUVfs2ATNSQg9u7H+Ep/U2V3+dm55Z9I4XCuyKRcFlBIT0W2MhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMD1Qwe6/eMf8eVU1xGgwRhWxvkBZIEe9uad4iMGqUVZm3nslEGlnXnWFtC1Lo7eVfCTKPyaVMydEWLFdEkVYBr4jZ8G6xirmMvluO/Sr0A7PXSEQ+n3qF+VkUcwgO7gbSD97SYUIXKVh6QvFX9zzPIU40Ahbqq5bqU0TKXv4hbAoU8sDV4Af0KXw/9r8FocY9Ys2xX6YrVAi8v61I23dP82Zxy2VbaLrL4i744blW+VmU77L7xpH7y3RzQfldUrYzh0Buu45sh3yG/v3woK9FY1wm1v3dvDmQpV+HOU5hl0zyk8Mr/SpDm2uTAqjoT8DsOdKVerDvP9SrSbpG8sNiqT9ROv6ziY1Yq89hRR7F159Ntc1w8thi3evN7QYO2GD5LkR1GeGY5gOA4134B6/EktGcmzb1Rx0LY6BRb3T2QipZTDq+G7xwsnJNDiPz4/hchrWNzlXvc/6auvuOb9WkMGgtnox5/4/C8ZI/hCIGyvpb+mZcbewPbBXD91/neSrVP1dJC6F0t645nUK49AK8AE41lOJA6rB3sxfCItl2SiScJuRSBEE9NiseNJvpaZDxjuXQc4UWT6Uszo+LrngRTsJDWTUnF5239i15Sb7WQW0Xs0EgNA1Y6n7/6ma0EH+U9DmPD1c01o19iL9AI2ADGUeIQLSNA9OmUsLpquqFFmvWMLJ6ubYCbgHyogMfdRD6hpoN25OCQl2EP24yB0BY27rVuygYXbIOJ+vSpat0uCd8akup/g26YxcXouSYf98LTuE6GAE=", + "thinking": "The user wants me to complete a specific instrumented research flow with three steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id to call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url to call summarize_source\n4. Reply with exactly \"PROMPT_DONE\" after summarize_source returns\n\nThe user emphasizes calling exactly one tool per turn and waiting for each result. Let me start with step 1.", + "type": "thinking" + }, + { + "text": "I'll complete this instrumented research flow step by step. Starting with Step 1:", + "type": "text" + }, + { + "id": "toolu_01NWGcbaEYFCSv7jbHaV61xR", + "input": { + "query": "flue instrumentation" + }, + "name": "lookup", + "type": "tool_use" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "content": "{\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}", + "is_error": false, + "tool_use_id": "toolu_01NWGcbaEYFCSv7jbHaV61xR", + "type": "tool_result" + } + ], + "role": "user" + }, + { + "content": [ + { + "signature": "EoEDCm4IDRgCKkDHERZTLDmLPqGPffwRXgcxBhBgIrYXgMYvN2Ub70fw9ROsylVddlwVjiBc/lIRhKFlmKk3yGyVqaTpeWzivYSNMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMvygGdKoloZH9PbB/GgyNsBVPv5CiUkum+Q0iMO4QWY/lnhO5B8dFYJLBlnx3xICN/4EZrOIoQNdBLFV3U+M8som8sSiwj3uJx1OI8irAAbcyFYPvt3ZNfLNUReqOr+m7INr6/Ie2gnkRu9unXD+vYwFg9FbyV0lgmLyu4I3e6A+P3r6rACTCCVKokSYjy2IWp8e6v5c1+++qdywmPbK444LgqFCxOF2CF7gtf8iHoMo/rRhm/v4ypQOUdWW/lvo8sokRYHdJsSTOFLHmsuSk4eapbjPa9IjmFXOf+fNTqVY1quk3HJuLBKr7Q9PblMUX7Q4hqwo/E89HS5M3WTcm2sHl7Vict+Qbr5+8JZVlNRgB", + "thinking": "Good, I got the lookup result with id \"flue-session-2026\". Now I'll proceed to step 2 and use this id as the lookupId parameter in the web_search call with the specified query.", + "type": "thinking" + }, + { + "text": "Now proceeding to Step 2:", + "type": "text" + }, + { + "id": "toolu_0153ktjSHv2H1SaKu8xPjQDj", + "input": { + "lookupId": "flue-session-2026", + "query": "Braintrust Flue reasoning stream instrumentation" + }, + "name": "web_search", + "type": "tool_use" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "cache_control": { + "type": "ephemeral" + }, + "content": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\",\"results\":[{\"title\":\"Flue reasoning stream instrumentation\",\"url\":\"https://example.test/flue/reasoning-streams\"}]}", + "is_error": false, + "tool_use_id": "toolu_0153ktjSHv2H1SaKu8xPjQDj", + "type": "tool_result" + } + ], + "role": "user" + } + ], + "model": "claude-sonnet-4-5-20250929", + "stream": true, + "system": [ + { + "cache_control": { + "type": "ephemeral" + }, + "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Thu, May 21, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-LqmoTW/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + "type": "text" + } + ], + "thinking": { + "budget_tokens": 8192, + "display": "summarized", + "type": "enabled" + }, + "tools": [ + { + "description": "Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "limit": { + "description": "Maximum number of lines to read", + "type": "number" + }, + "offset": { + "description": "Line number to start from (1-indexed)", + "type": "number" + }, + "path": { + "description": "Path to the file to read", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + }, + "name": "read" + }, + { + "description": "Write content to a file. Creates the file and parent directories if they do not exist.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Path to the file to write", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + }, + "name": "write" + }, + { + "description": "Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "newText": { + "description": "Replacement text", + "type": "string" + }, + "oldText": { + "description": "Exact text to find (must be unique)", + "type": "string" + }, + "path": { + "description": "Path to the file to edit", + "type": "string" + }, + "replaceAll": { + "description": "Replace all occurrences", + "type": "boolean" + } + }, + "required": ["path", "oldText", "newText"], + "type": "object" + }, + "name": "edit" + }, + { + "description": "Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "command": { + "description": "Bash command to execute", + "type": "string" + }, + "timeout": { + "description": "Timeout in seconds", + "type": "number" + } + }, + "required": ["command"], + "type": "object" + }, + "name": "bash" + }, + { + "description": "Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "include": { + "description": "Glob filter, e.g. \"*.ts\"", + "type": "string" + }, + "path": { + "description": "Directory or file to search (default: .)", + "type": "string" + }, + "pattern": { + "description": "Search pattern (regex)", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + }, + "name": "grep" + }, + { + "description": "Find files by filename pattern using shell find -name semantics. Returns matching file paths.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "path": { + "description": "Directory to search in (default: .)", + "type": "string" + }, + "pattern": { + "description": "Filename pattern, e.g. \"*.ts\"", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + }, + "name": "glob" + }, + { + "description": "Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "cwd": { + "description": "Working directory for the child agent. AGENTS.md and skills are discovered from here.", + "type": "string" + }, + "description": { + "description": "Short human-readable label for the delegated work", + "type": "string" + }, + "prompt": { + "description": "Focused instructions for the child agent", + "type": "string" + }, + "role": { + "description": "Role to use for the child agent", + "type": "string" + } + }, + "required": ["prompt"], + "type": "object" + }, + "name": "task" + }, + { + "description": "Return a deterministic lookup result with an id needed by web_search.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "query": { + "type": "string" + } + }, + "required": ["query"], + "type": "object" + }, + "name": "lookup" + }, + { + "description": "Search a deterministic local web index. Requires the id returned by lookup.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "lookupId": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": ["lookupId", "query"], + "type": "object" + }, + "name": "web_search" + }, + { + "cache_control": { + "type": "ephemeral" + }, + "description": "Summarize the selected deterministic source after web_search returns a URL.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "url": { + "type": "string" + } + }, + "required": ["url"], + "type": "object" + }, + "name": "summarize_source" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.anthropic.com/v1/messages" + }, + "response": { + "body": { + "chunks": [ + "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-5-20250929\",\"id\":\"msg_01DSg9ZeMjZLnXapLdFgSFc3\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":13,\"cache_creation_input_tokens\":229,\"cache_read_input_tokens\":2421,\"cache_creation\":{\"ephemeral_5m_input_tokens\":229,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":1,\"service_tier\":\"standard\",\"inference_geo\":\"not_available\"}}}", + "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"thinking\",\"thinking\":\"\",\"signature\":\"\"}}", + "event: ping\ndata: {\"type\":\"ping\"}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\"Perfect\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\"! I got the web_search results. There's one result with the URL\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\" \\\"https://example.test/flue/reasoning-streams\\\". Now I need to proceed to step 3 and call summarize_source with this URL.\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"signature_delta\",\"signature\":\"Eo8DCm4IDRgCKkCwCXv4kPtKJjZgEBptfdwHoQRED540G2dBIGSNpbLq/d/7YUemt0VtsBkdWJx9I38IxfHuMed6CS8/KHNVf63wMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMZREYYDCUibC7js33GgzoCMUuvYX25rvN1wAiMN8TPVM+m1UBPOv7LwNn0Fl5crfh6XeYMelsdRSq090k5nPOUQCRGwMhwfhIg7rDCCrOAepv53M8zcXCM+2pzYKPgxRDkY3DwMUWnjS2z7jXN4AMavQWyGi0dIFDARVsbcKLAFyXPVwfy/EMSHMuCHYcX5kA/oz3+gWu5ka5cOjvp60k2ZUURJptjU7UIG5TYtW96oTo2wYrZOyiYAZKIRoRMn48RgU8b8oxjQJH6RU6aKXgicvp0DV9dmrcONvLGlftpp2UNBTvHqrhhXFtDtv46/I3QUE7aMT7VTlF6p+bO9gPSZAkrm53y2koG4E5hzWEhiRuFckYs24dThVN1cMnGAE=\"}}", + "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0}", + "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":1,\"content_block\":{\"type\":\"text\",\"text\":\"\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"text_delta\",\"text\":\"Now proceeding\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"text_delta\",\"text\":\" to Step 3:\"}}", + "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":1}", + "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":2,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01JDUQddZCp23NQj8eGJLFbo\",\"name\":\"summarize_source\",\"input\":{},\"caller\":{\"type\":\"direct\"}}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"url\\\": \\\"https://example.test/flue/reasoning-streams\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"}\"}}", + "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":2}", + "event: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":13,\"cache_creation_input_tokens\":229,\"cache_read_input_tokens\":2421,\"output_tokens\":133}}", + "event: message_stop\ndata: {\"type\":\"message_stop\"}" + ], + "kind": "sse" + }, + "headers": { + "anthropic-organization-id": "27796668-7351-40ac-acc4-024aee8995a5", + "anthropic-ratelimit-input-tokens-limit": "3000000", + "anthropic-ratelimit-input-tokens-remaining": "2999000", + "anthropic-ratelimit-input-tokens-reset": "2026-05-21T06:49:04Z", + "anthropic-ratelimit-output-tokens-limit": "600000", + "anthropic-ratelimit-output-tokens-remaining": "600000", + "anthropic-ratelimit-output-tokens-reset": "2026-05-21T06:49:04Z", + "anthropic-ratelimit-requests-limit": "20000", + "anthropic-ratelimit-requests-remaining": "19999", + "anthropic-ratelimit-requests-reset": "2026-05-21T06:49:04Z", + "anthropic-ratelimit-tokens-limit": "3600000", + "anthropic-ratelimit-tokens-remaining": "3599000", + "anthropic-ratelimit-tokens-reset": "2026-05-21T06:49:04Z", + "cache-control": "no-cache", + "cf-cache-status": "DYNAMIC", + "cf-ray": "9ff1a3982ce9c2f2-VIE", + "connection": "keep-alive", + "content-encoding": "gzip", + "content-security-policy": "default-src 'none'; frame-ancestors 'none'", + "content-type": "text/event-stream; charset=utf-8", + "date": "Thu, 21 May 2026 06:49:05 GMT", + "request-id": "req_011CbFGVbQGvo9PCcG5DH13G", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "traceresponse": "00-386ca9e81514f84a92a0a346caa1b1ed-da425a4f1e2abe78-01", + "transfer-encoding": "chunked", + "vary": "Accept-Encoding", + "x-envoy-upstream-service-time": "1324", + "x-robots-tag": "none" + }, + "status": 200, + "statusText": "OK" + } + }, + { + "callIndex": 3, + "id": "305957222aa1f6e9", + "matchKey": "POST api.anthropic.com/v1/messages", + "recordedAt": "2026-05-21T06:49:12.438Z", + "request": { + "body": { + "kind": "json", + "value": { + "max_tokens": 64000, + "messages": [ + { + "content": [ + { + "text": "Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "signature": "ErUFCm4IDRgCKkAHu6lMZFTp53LRtoPoqjh0UrHuoIv5LTsJ7I3lHUVfs2ATNSQg9u7H+Ep/U2V3+dm55Z9I4XCuyKRcFlBIT0W2MhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMD1Qwe6/eMf8eVU1xGgwRhWxvkBZIEe9uad4iMGqUVZm3nslEGlnXnWFtC1Lo7eVfCTKPyaVMydEWLFdEkVYBr4jZ8G6xirmMvluO/Sr0A7PXSEQ+n3qF+VkUcwgO7gbSD97SYUIXKVh6QvFX9zzPIU40Ahbqq5bqU0TKXv4hbAoU8sDV4Af0KXw/9r8FocY9Ys2xX6YrVAi8v61I23dP82Zxy2VbaLrL4i744blW+VmU77L7xpH7y3RzQfldUrYzh0Buu45sh3yG/v3woK9FY1wm1v3dvDmQpV+HOU5hl0zyk8Mr/SpDm2uTAqjoT8DsOdKVerDvP9SrSbpG8sNiqT9ROv6ziY1Yq89hRR7F159Ntc1w8thi3evN7QYO2GD5LkR1GeGY5gOA4134B6/EktGcmzb1Rx0LY6BRb3T2QipZTDq+G7xwsnJNDiPz4/hchrWNzlXvc/6auvuOb9WkMGgtnox5/4/C8ZI/hCIGyvpb+mZcbewPbBXD91/neSrVP1dJC6F0t645nUK49AK8AE41lOJA6rB3sxfCItl2SiScJuRSBEE9NiseNJvpaZDxjuXQc4UWT6Uszo+LrngRTsJDWTUnF5239i15Sb7WQW0Xs0EgNA1Y6n7/6ma0EH+U9DmPD1c01o19iL9AI2ADGUeIQLSNA9OmUsLpquqFFmvWMLJ6ubYCbgHyogMfdRD6hpoN25OCQl2EP24yB0BY27rVuygYXbIOJ+vSpat0uCd8akup/g26YxcXouSYf98LTuE6GAE=", + "thinking": "The user wants me to complete a specific instrumented research flow with three steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id to call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url to call summarize_source\n4. Reply with exactly \"PROMPT_DONE\" after summarize_source returns\n\nThe user emphasizes calling exactly one tool per turn and waiting for each result. Let me start with step 1.", + "type": "thinking" + }, + { + "text": "I'll complete this instrumented research flow step by step. Starting with Step 1:", + "type": "text" + }, + { + "id": "toolu_01NWGcbaEYFCSv7jbHaV61xR", + "input": { + "query": "flue instrumentation" + }, + "name": "lookup", + "type": "tool_use" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "content": "{\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}", + "is_error": false, + "tool_use_id": "toolu_01NWGcbaEYFCSv7jbHaV61xR", + "type": "tool_result" + } + ], + "role": "user" + }, + { + "content": [ + { + "signature": "EoEDCm4IDRgCKkDHERZTLDmLPqGPffwRXgcxBhBgIrYXgMYvN2Ub70fw9ROsylVddlwVjiBc/lIRhKFlmKk3yGyVqaTpeWzivYSNMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMvygGdKoloZH9PbB/GgyNsBVPv5CiUkum+Q0iMO4QWY/lnhO5B8dFYJLBlnx3xICN/4EZrOIoQNdBLFV3U+M8som8sSiwj3uJx1OI8irAAbcyFYPvt3ZNfLNUReqOr+m7INr6/Ie2gnkRu9unXD+vYwFg9FbyV0lgmLyu4I3e6A+P3r6rACTCCVKokSYjy2IWp8e6v5c1+++qdywmPbK444LgqFCxOF2CF7gtf8iHoMo/rRhm/v4ypQOUdWW/lvo8sokRYHdJsSTOFLHmsuSk4eapbjPa9IjmFXOf+fNTqVY1quk3HJuLBKr7Q9PblMUX7Q4hqwo/E89HS5M3WTcm2sHl7Vict+Qbr5+8JZVlNRgB", + "thinking": "Good, I got the lookup result with id \"flue-session-2026\". Now I'll proceed to step 2 and use this id as the lookupId parameter in the web_search call with the specified query.", + "type": "thinking" + }, + { + "text": "Now proceeding to Step 2:", + "type": "text" + }, + { + "id": "toolu_0153ktjSHv2H1SaKu8xPjQDj", + "input": { + "lookupId": "flue-session-2026", + "query": "Braintrust Flue reasoning stream instrumentation" + }, + "name": "web_search", + "type": "tool_use" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "content": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\",\"results\":[{\"title\":\"Flue reasoning stream instrumentation\",\"url\":\"https://example.test/flue/reasoning-streams\"}]}", + "is_error": false, + "tool_use_id": "toolu_0153ktjSHv2H1SaKu8xPjQDj", + "type": "tool_result" + } + ], + "role": "user" + }, + { + "content": [ + { + "signature": "Eo8DCm4IDRgCKkCwCXv4kPtKJjZgEBptfdwHoQRED540G2dBIGSNpbLq/d/7YUemt0VtsBkdWJx9I38IxfHuMed6CS8/KHNVf63wMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMZREYYDCUibC7js33GgzoCMUuvYX25rvN1wAiMN8TPVM+m1UBPOv7LwNn0Fl5crfh6XeYMelsdRSq090k5nPOUQCRGwMhwfhIg7rDCCrOAepv53M8zcXCM+2pzYKPgxRDkY3DwMUWnjS2z7jXN4AMavQWyGi0dIFDARVsbcKLAFyXPVwfy/EMSHMuCHYcX5kA/oz3+gWu5ka5cOjvp60k2ZUURJptjU7UIG5TYtW96oTo2wYrZOyiYAZKIRoRMn48RgU8b8oxjQJH6RU6aKXgicvp0DV9dmrcONvLGlftpp2UNBTvHqrhhXFtDtv46/I3QUE7aMT7VTlF6p+bO9gPSZAkrm53y2koG4E5hzWEhiRuFckYs24dThVN1cMnGAE=", + "thinking": "Perfect! I got the web_search results. There's one result with the URL \"https://example.test/flue/reasoning-streams\". Now I need to proceed to step 3 and call summarize_source with this URL.", + "type": "thinking" + }, + { + "text": "Now proceeding to Step 3:", + "type": "text" + }, + { + "id": "toolu_01JDUQddZCp23NQj8eGJLFbo", + "input": { + "url": "https://example.test/flue/reasoning-streams" + }, + "name": "summarize_source", + "type": "tool_use" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "cache_control": { + "type": "ephemeral" + }, + "content": "{\"summary\":\"Flue emits reasoning, tool execution, and LLM turn events separately.\",\"url\":\"https://example.test/flue/reasoning-streams\"}", + "is_error": false, + "tool_use_id": "toolu_01JDUQddZCp23NQj8eGJLFbo", + "type": "tool_result" + } + ], + "role": "user" + } + ], + "model": "claude-sonnet-4-5-20250929", + "stream": true, + "system": [ + { + "cache_control": { + "type": "ephemeral" + }, + "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Thu, May 21, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-LqmoTW/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + "type": "text" + } + ], + "thinking": { + "budget_tokens": 8192, + "display": "summarized", + "type": "enabled" + }, + "tools": [ + { + "description": "Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "limit": { + "description": "Maximum number of lines to read", + "type": "number" + }, + "offset": { + "description": "Line number to start from (1-indexed)", + "type": "number" + }, + "path": { + "description": "Path to the file to read", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + }, + "name": "read" + }, + { + "description": "Write content to a file. Creates the file and parent directories if they do not exist.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Path to the file to write", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + }, + "name": "write" + }, + { + "description": "Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "newText": { + "description": "Replacement text", + "type": "string" + }, + "oldText": { + "description": "Exact text to find (must be unique)", + "type": "string" + }, + "path": { + "description": "Path to the file to edit", + "type": "string" + }, + "replaceAll": { + "description": "Replace all occurrences", + "type": "boolean" + } + }, + "required": ["path", "oldText", "newText"], + "type": "object" + }, + "name": "edit" + }, + { + "description": "Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "command": { + "description": "Bash command to execute", + "type": "string" + }, + "timeout": { + "description": "Timeout in seconds", + "type": "number" + } + }, + "required": ["command"], + "type": "object" + }, + "name": "bash" + }, + { + "description": "Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "include": { + "description": "Glob filter, e.g. \"*.ts\"", + "type": "string" + }, + "path": { + "description": "Directory or file to search (default: .)", + "type": "string" + }, + "pattern": { + "description": "Search pattern (regex)", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + }, + "name": "grep" + }, + { + "description": "Find files by filename pattern using shell find -name semantics. Returns matching file paths.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "path": { + "description": "Directory to search in (default: .)", + "type": "string" + }, + "pattern": { + "description": "Filename pattern, e.g. \"*.ts\"", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + }, + "name": "glob" + }, + { + "description": "Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "cwd": { + "description": "Working directory for the child agent. AGENTS.md and skills are discovered from here.", + "type": "string" + }, + "description": { + "description": "Short human-readable label for the delegated work", + "type": "string" + }, + "prompt": { + "description": "Focused instructions for the child agent", + "type": "string" + }, + "role": { + "description": "Role to use for the child agent", + "type": "string" + } + }, + "required": ["prompt"], + "type": "object" + }, + "name": "task" + }, + { + "description": "Return a deterministic lookup result with an id needed by web_search.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "query": { + "type": "string" + } + }, + "required": ["query"], + "type": "object" + }, + "name": "lookup" + }, + { + "description": "Search a deterministic local web index. Requires the id returned by lookup.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "lookupId": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": ["lookupId", "query"], + "type": "object" + }, + "name": "web_search" + }, + { + "cache_control": { + "type": "ephemeral" + }, + "description": "Summarize the selected deterministic source after web_search returns a URL.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "url": { + "type": "string" + } + }, + "required": ["url"], + "type": "object" + }, + "name": "summarize_source" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.anthropic.com/v1/messages" + }, + "response": { + "body": { + "chunks": [ + "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-5-20250929\",\"id\":\"msg_01EN81qE9Tc5YtCkCYHNw4rf\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":13,\"cache_creation_input_tokens\":189,\"cache_read_input_tokens\":2650,\"cache_creation\":{\"ephemeral_5m_input_tokens\":189,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":1,\"service_tier\":\"standard\",\"inference_geo\":\"not_available\"}}}", + "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"thinking\",\"thinking\":\"\",\"signature\":\"\"}}", + "event: ping\ndata: {\"type\":\"ping\"}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\"Perfect\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\"! The summarize_source has returned. According to the instructions, I should now reply with exactly \\\"PROMPT_DONE\\\" and no other text.\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"signature_delta\",\"signature\":\"EtwCCm4IDRgCKkDWm62nouoyuXYPpjzuPS1+UJeLeIZyIDn94RTeLHzVNz7qPgE94dz4ISSKXUgrBhj4Zk7utrk913b4m0qskKn+MhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMoR0NtFW81tnWRAWCGgy/101Czdnc257hNQciMBzR4jFR6DEEtSUxGAmd/O69U6dH2ng8SGI5noHrR67R60iT2aw5Dt2p+owoIzJHGSqbAS3sXeHyzNRY4IOgBQqnkx32YL6ZKFBG83FnhkcYnChbUpPnf1s831BWEmK7piDMhJ6Oj+QjB+3MAbcZKOps50TPCh79rR/XnYuFni57e/3hTpNZVhLcZVkx0Zu1EeNVXkqWJAoXaknErU3po3+pJsOaPUaGgzl/qDcouGLOA3u+D6xiz7dZejgqVJc4TBXVqVCTz7iSSsqYQH+lGAE=\"}}", + "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0}", + "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":1,\"content_block\":{\"type\":\"text\",\"text\":\"\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"text_delta\",\"text\":\"PROMPT_DONE\"}}", + "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":1}", + "event: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":13,\"cache_creation_input_tokens\":189,\"cache_read_input_tokens\":2650,\"output_tokens\":49}}", + "event: message_stop\ndata: {\"type\":\"message_stop\"}" + ], + "kind": "sse" + }, + "headers": { + "anthropic-organization-id": "27796668-7351-40ac-acc4-024aee8995a5", + "anthropic-ratelimit-input-tokens-limit": "3000000", + "anthropic-ratelimit-input-tokens-remaining": "2998000", + "anthropic-ratelimit-input-tokens-reset": "2026-05-21T06:49:07Z", + "anthropic-ratelimit-output-tokens-limit": "600000", + "anthropic-ratelimit-output-tokens-remaining": "600000", + "anthropic-ratelimit-output-tokens-reset": "2026-05-21T06:49:07Z", + "anthropic-ratelimit-requests-limit": "20000", + "anthropic-ratelimit-requests-remaining": "19999", + "anthropic-ratelimit-requests-reset": "2026-05-21T06:49:07Z", + "anthropic-ratelimit-tokens-limit": "3600000", + "anthropic-ratelimit-tokens-remaining": "3598000", + "anthropic-ratelimit-tokens-reset": "2026-05-21T06:49:07Z", + "cache-control": "no-cache", + "cf-cache-status": "DYNAMIC", + "cf-ray": "9ff1a3ad9fe6c2f2-VIE", + "connection": "keep-alive", + "content-encoding": "gzip", + "content-security-policy": "default-src 'none'; frame-ancestors 'none'", + "content-type": "text/event-stream; charset=utf-8", + "date": "Thu, 21 May 2026 06:49:11 GMT", + "request-id": "req_011CbFGVr1re2qwBcH69XKHA", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "traceresponse": "00-7d6d116e436c5ee5da5bbabc73b46826-8fc3ea8a06eeec11-01", + "transfer-encoding": "chunked", + "vary": "Accept-Encoding", + "x-envoy-upstream-service-time": "4366", + "x-robots-tag": "none" + }, + "status": 200, + "statusText": "OK" + } + }, + { + "callIndex": 4, + "id": "3d93fe37f72a947f", + "matchKey": "POST api.anthropic.com/v1/messages", + "recordedAt": "2026-05-21T06:49:14.852Z", + "request": { + "body": { + "kind": "json", + "value": { + "max_tokens": 64000, + "messages": [ + { + "content": [ + { + "cache_control": { + "type": "ephemeral" + }, + "text": "Run the skill named \"e2e-flue-skill\".\n\nArguments:\n{\n \"marker\": \"SKILL_DONE\"\n}", + "type": "text" + } + ], + "role": "user" + } + ], + "model": "claude-sonnet-4-5-20250929", + "stream": true, + "system": [ + { + "cache_control": { + "type": "ephemeral" + }, + "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Thu, May 21, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-LqmoTW/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts\n\n\nNever call the task tool. Do not delegate e2e-flue-skill to another session. If you need the skill body, read .agents/skills/e2e-flue-skill/SKILL.md yourself with the read tool. Return the marker from the Arguments object exactly, with no other text.\n", + "type": "text" + } + ], + "thinking": { + "type": "disabled" + }, + "tools": [ + { + "description": "Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "limit": { + "description": "Maximum number of lines to read", + "type": "number" + }, + "offset": { + "description": "Line number to start from (1-indexed)", + "type": "number" + }, + "path": { + "description": "Path to the file to read", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + }, + "name": "read" + }, + { + "description": "Write content to a file. Creates the file and parent directories if they do not exist.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Path to the file to write", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + }, + "name": "write" + }, + { + "description": "Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "newText": { + "description": "Replacement text", + "type": "string" + }, + "oldText": { + "description": "Exact text to find (must be unique)", + "type": "string" + }, + "path": { + "description": "Path to the file to edit", + "type": "string" + }, + "replaceAll": { + "description": "Replace all occurrences", + "type": "boolean" + } + }, + "required": ["path", "oldText", "newText"], + "type": "object" + }, + "name": "edit" + }, + { + "description": "Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "command": { + "description": "Bash command to execute", + "type": "string" + }, + "timeout": { + "description": "Timeout in seconds", + "type": "number" + } + }, + "required": ["command"], + "type": "object" + }, + "name": "bash" + }, + { + "description": "Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "include": { + "description": "Glob filter, e.g. \"*.ts\"", + "type": "string" + }, + "path": { + "description": "Directory or file to search (default: .)", + "type": "string" + }, + "pattern": { + "description": "Search pattern (regex)", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + }, + "name": "grep" + }, + { + "description": "Find files by filename pattern using shell find -name semantics. Returns matching file paths.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "path": { + "description": "Directory to search in (default: .)", + "type": "string" + }, + "pattern": { + "description": "Filename pattern, e.g. \"*.ts\"", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + }, + "name": "glob" + }, + { + "cache_control": { + "type": "ephemeral" + }, + "description": "Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "cwd": { + "description": "Working directory for the child agent. AGENTS.md and skills are discovered from here.", + "type": "string" + }, + "description": { + "description": "Short human-readable label for the delegated work", + "type": "string" + }, + "prompt": { + "description": "Focused instructions for the child agent", + "type": "string" + }, + "role": { + "description": "Role to use for the child agent", + "type": "string" + } + }, + "required": ["prompt"], + "type": "object" + }, + "name": "task" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.anthropic.com/v1/messages" + }, + "response": { + "body": { + "chunks": [ + "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-5-20250929\",\"id\":\"msg_019mZ4kaqaQKoxnqaBHfhAKp\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":3,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":1809,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":5,\"service_tier\":\"standard\",\"inference_geo\":\"not_available\"}}}", + "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"}}", + "event: ping\ndata: {\"type\":\"ping\"}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"I'll run the e\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"2e-flue-skill by reading its instructions and following them.\"}}", + "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0}", + "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":1,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01TJVfeBb5CPsHTxgyECHJqB\",\"name\":\"read\",\"input\":{},\"caller\":{\"type\":\"direct\"}}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"path\\\": \\\".agents/skills/e2e-flue-skill/SKILL.md\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"}\"}}", + "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":1}", + "event: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":3,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":1809,\"output_tokens\":89}}", + "event: message_stop\ndata: {\"type\":\"message_stop\"}" + ], + "kind": "sse" + }, + "headers": { + "anthropic-organization-id": "27796668-7351-40ac-acc4-024aee8995a5", + "anthropic-ratelimit-input-tokens-limit": "3000000", + "anthropic-ratelimit-input-tokens-remaining": "2999000", + "anthropic-ratelimit-input-tokens-reset": "2026-05-21T06:49:12Z", + "anthropic-ratelimit-output-tokens-limit": "600000", + "anthropic-ratelimit-output-tokens-remaining": "600000", + "anthropic-ratelimit-output-tokens-reset": "2026-05-21T06:49:12Z", + "anthropic-ratelimit-requests-limit": "20000", + "anthropic-ratelimit-requests-remaining": "19999", + "anthropic-ratelimit-requests-reset": "2026-05-21T06:49:12Z", + "anthropic-ratelimit-tokens-limit": "3600000", + "anthropic-ratelimit-tokens-remaining": "3599000", + "anthropic-ratelimit-tokens-reset": "2026-05-21T06:49:12Z", + "cache-control": "no-cache", + "cf-cache-status": "DYNAMIC", + "cf-ray": "9ff1a3cd29ccc2f2-VIE", + "connection": "keep-alive", + "content-encoding": "gzip", + "content-security-policy": "default-src 'none'; frame-ancestors 'none'", + "content-type": "text/event-stream; charset=utf-8", + "date": "Thu, 21 May 2026 06:49:13 GMT", + "request-id": "req_011CbFGWDcsgmaGCFP5KYhft", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "traceresponse": "00-174011067c2daa49ddeab98ec0e79edb-17db276d56b0de5a-01", + "transfer-encoding": "chunked", + "vary": "Accept-Encoding", + "x-envoy-upstream-service-time": "1289", + "x-robots-tag": "none" + }, + "status": 200, + "statusText": "OK" + } + }, + { + "callIndex": 5, + "id": "fb4ed2bb1569d980", + "matchKey": "POST api.anthropic.com/v1/messages", + "recordedAt": "2026-05-21T06:49:16.371Z", + "request": { + "body": { + "kind": "json", + "value": { + "max_tokens": 64000, + "messages": [ + { + "content": [ + { + "text": "Run the skill named \"e2e-flue-skill\".\n\nArguments:\n{\n \"marker\": \"SKILL_DONE\"\n}", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "text": "I'll run the e2e-flue-skill by reading its instructions and following them.", + "type": "text" + }, + { + "id": "toolu_01TJVfeBb5CPsHTxgyECHJqB", + "input": { + "path": ".agents/skills/e2e-flue-skill/SKILL.md" + }, + "name": "read", + "type": "tool_use" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "cache_control": { + "type": "ephemeral" + }, + "content": "---\nname: e2e-flue-skill\ndescription: Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n---\n\nReturn the marker from the provided args exactly once. Output no other text.\n", + "is_error": false, + "tool_use_id": "toolu_01TJVfeBb5CPsHTxgyECHJqB", + "type": "tool_result" + } + ], + "role": "user" + } + ], + "model": "claude-sonnet-4-5-20250929", + "stream": true, + "system": [ + { + "cache_control": { + "type": "ephemeral" + }, + "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Thu, May 21, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-LqmoTW/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts\n\n\nNever call the task tool. Do not delegate e2e-flue-skill to another session. If you need the skill body, read .agents/skills/e2e-flue-skill/SKILL.md yourself with the read tool. Return the marker from the Arguments object exactly, with no other text.\n", + "type": "text" + } + ], + "thinking": { + "type": "disabled" + }, + "tools": [ + { + "description": "Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "limit": { + "description": "Maximum number of lines to read", + "type": "number" + }, + "offset": { + "description": "Line number to start from (1-indexed)", + "type": "number" + }, + "path": { + "description": "Path to the file to read", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + }, + "name": "read" + }, + { + "description": "Write content to a file. Creates the file and parent directories if they do not exist.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Path to the file to write", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + }, + "name": "write" + }, + { + "description": "Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "newText": { + "description": "Replacement text", + "type": "string" + }, + "oldText": { + "description": "Exact text to find (must be unique)", + "type": "string" + }, + "path": { + "description": "Path to the file to edit", + "type": "string" + }, + "replaceAll": { + "description": "Replace all occurrences", + "type": "boolean" + } + }, + "required": ["path", "oldText", "newText"], + "type": "object" + }, + "name": "edit" + }, + { + "description": "Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "command": { + "description": "Bash command to execute", + "type": "string" + }, + "timeout": { + "description": "Timeout in seconds", + "type": "number" + } + }, + "required": ["command"], + "type": "object" + }, + "name": "bash" + }, + { + "description": "Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "include": { + "description": "Glob filter, e.g. \"*.ts\"", + "type": "string" + }, + "path": { + "description": "Directory or file to search (default: .)", + "type": "string" + }, + "pattern": { + "description": "Search pattern (regex)", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + }, + "name": "grep" + }, + { + "description": "Find files by filename pattern using shell find -name semantics. Returns matching file paths.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "path": { + "description": "Directory to search in (default: .)", + "type": "string" + }, + "pattern": { + "description": "Filename pattern, e.g. \"*.ts\"", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + }, + "name": "glob" + }, + { + "cache_control": { + "type": "ephemeral" + }, + "description": "Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "cwd": { + "description": "Working directory for the child agent. AGENTS.md and skills are discovered from here.", + "type": "string" + }, + "description": { + "description": "Short human-readable label for the delegated work", + "type": "string" + }, + "prompt": { + "description": "Focused instructions for the child agent", + "type": "string" + }, + "role": { + "description": "Role to use for the child agent", + "type": "string" + } + }, + "required": ["prompt"], + "type": "object" + }, + "name": "task" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.anthropic.com/v1/messages" + }, + "response": { + "body": { + "chunks": [ + "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-5-20250929\",\"id\":\"msg_01CA3PrSTFThZsazE6nWdyfW\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":6,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":1962,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":7,\"service_tier\":\"standard\",\"inference_geo\":\"not_available\"}}}", + "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"}}", + "event: ping\ndata: {\"type\":\"ping\"}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"SKILL_DONE\"}}", + "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0}", + "event: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":6,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":1962,\"output_tokens\":8}}", + "event: message_stop\ndata: {\"type\":\"message_stop\"}" + ], + "kind": "sse" + }, + "headers": { + "anthropic-organization-id": "27796668-7351-40ac-acc4-024aee8995a5", + "anthropic-ratelimit-input-tokens-limit": "3000000", + "anthropic-ratelimit-input-tokens-remaining": "2999000", + "anthropic-ratelimit-input-tokens-reset": "2026-05-21T06:49:15Z", + "anthropic-ratelimit-output-tokens-limit": "600000", + "anthropic-ratelimit-output-tokens-remaining": "600000", + "anthropic-ratelimit-output-tokens-reset": "2026-05-21T06:49:15Z", + "anthropic-ratelimit-requests-limit": "20000", + "anthropic-ratelimit-requests-remaining": "19999", + "anthropic-ratelimit-requests-reset": "2026-05-21T06:49:15Z", + "anthropic-ratelimit-tokens-limit": "3600000", + "anthropic-ratelimit-tokens-remaining": "3599000", + "anthropic-ratelimit-tokens-reset": "2026-05-21T06:49:15Z", + "cache-control": "no-cache", + "cf-cache-status": "DYNAMIC", + "cf-ray": "9ff1a3dc4eb2c2f2-VIE", + "connection": "keep-alive", + "content-encoding": "gzip", + "content-security-policy": "default-src 'none'; frame-ancestors 'none'", + "content-type": "text/event-stream; charset=utf-8", + "date": "Thu, 21 May 2026 06:49:16 GMT", + "request-id": "req_011CbFGWPvF2JLYeSinnfsKq", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "traceresponse": "00-aa018edfc984405c8755646830f6edef-3420a5b320e70476-01", + "transfer-encoding": "chunked", + "vary": "Accept-Encoding", + "x-envoy-upstream-service-time": "1261", + "x-robots-tag": "none" + }, + "status": 200, + "statusText": "OK" + } + }, + { + "callIndex": 0, + "id": "7c0e162d6794cf5d", + "matchKey": "POST api.openai.com/v1/responses", + "recordedAt": "2026-05-21T06:49:17.223Z", + "request": { + "body": { + "kind": "json", + "value": { + "input": [ + { + "content": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Thu, May 21, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-LqmoTW/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + "role": "system" + }, + { + "content": [ + { + "text": "Reply with exactly TASK_DONE and no other text.", + "type": "input_text" + } + ], + "role": "user" + } + ], + "model": "gpt-4o-mini", + "prompt_cache_key": "[REDACTED]", + "store": false, + "stream": true, + "tools": [ + { + "description": "Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.", + "name": "read", + "parameters": { + "properties": { + "limit": { + "description": "Maximum number of lines to read", + "type": "number" + }, + "offset": { + "description": "Line number to start from (1-indexed)", + "type": "number" + }, + "path": { + "description": "Path to the file to read", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Write content to a file. Creates the file and parent directories if they do not exist.", + "name": "write", + "parameters": { + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Path to the file to write", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.", + "name": "edit", + "parameters": { + "properties": { + "newText": { + "description": "Replacement text", + "type": "string" + }, + "oldText": { + "description": "Exact text to find (must be unique)", + "type": "string" + }, + "path": { + "description": "Path to the file to edit", + "type": "string" + }, + "replaceAll": { + "description": "Replace all occurrences", + "type": "boolean" + } + }, + "required": ["path", "oldText", "newText"], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.", + "name": "bash", + "parameters": { + "properties": { + "command": { + "description": "Bash command to execute", + "type": "string" + }, + "timeout": { + "description": "Timeout in seconds", + "type": "number" + } + }, + "required": ["command"], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.", + "name": "grep", + "parameters": { + "properties": { + "include": { + "description": "Glob filter, e.g. \"*.ts\"", + "type": "string" + }, + "path": { + "description": "Directory or file to search (default: .)", + "type": "string" + }, + "pattern": { + "description": "Search pattern (regex)", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Find files by filename pattern using shell find -name semantics. Returns matching file paths.", + "name": "glob", + "parameters": { + "properties": { + "path": { + "description": "Directory to search in (default: .)", + "type": "string" + }, + "pattern": { + "description": "Filename pattern, e.g. \"*.ts\"", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.", + "name": "task", + "parameters": { + "properties": { + "cwd": { + "description": "Working directory for the child agent. AGENTS.md and skills are discovered from here.", + "type": "string" + }, + "description": { + "description": "Short human-readable label for the delegated work", + "type": "string" + }, + "prompt": { + "description": "Focused instructions for the child agent", + "type": "string" + }, + "role": { + "description": "Role to use for the child agent", + "type": "string" + } + }, + "required": ["prompt"], + "type": "object" + }, + "strict": false, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/responses" + }, + "response": { + "body": { + "chunks": [ + "event: response.created\ndata: {\"type\":\"response.created\",\"response\":{\"id\":\"resp_0bd28b8a5ad18b2e016a0eaaeca6e88195b38d143e2272e210\",\"object\":\"response\",\"created_at\":1779346156,\"status\":\"in_progress\",\"background\":false,\"completed_at\":null,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":null,\"instructions\":null,\"max_output_tokens\":null,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":\"flue-e2e-instance::default::task:task:adc71368-3f10-4ddf-ac19-18\",\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"auto\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[{\"type\":\"function\",\"description\":\"Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.\",\"name\":\"read\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to read\"},\"offset\":{\"type\":\"number\",\"description\":\"Line number to start from (1-indexed)\"},\"limit\":{\"type\":\"number\",\"description\":\"Maximum number of lines to read\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Write content to a file. Creates the file and parent directories if they do not exist.\",\"name\":\"write\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"content\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to write\"},\"content\":{\"type\":\"string\",\"description\":\"Content to write to the file\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.\",\"name\":\"edit\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"oldText\",\"newText\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to edit\"},\"oldText\":{\"type\":\"string\",\"description\":\"Exact text to find (must be unique)\"},\"newText\":{\"type\":\"string\",\"description\":\"Replacement text\"},\"replaceAll\":{\"type\":\"boolean\",\"description\":\"Replace all occurrences\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.\",\"name\":\"bash\",\"parameters\":{\"type\":\"object\",\"required\":[\"command\"],\"properties\":{\"command\":{\"type\":\"string\",\"description\":\"Bash command to execute\"},\"timeout\":{\"type\":\"number\",\"description\":\"Timeout in seconds\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.\",\"name\":\"grep\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Search pattern (regex)\"},\"path\":{\"type\":\"string\",\"description\":\"Directory or file to search (default: .)\"},\"include\":{\"type\":\"string\",\"description\":\"Glob filter, e.g. \\\"*.ts\\\"\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Find files by filename pattern using shell find -name semantics. Returns matching file paths.\",\"name\":\"glob\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Filename pattern, e.g. \\\"*.ts\\\"\"},\"path\":{\"type\":\"string\",\"description\":\"Directory to search in (default: .)\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.\",\"name\":\"task\",\"parameters\":{\"type\":\"object\",\"required\":[\"prompt\"],\"properties\":{\"description\":{\"type\":\"string\",\"description\":\"Short human-readable label for the delegated work\"},\"prompt\":{\"type\":\"string\",\"description\":\"Focused instructions for the child agent\"},\"role\":{\"type\":\"string\",\"description\":\"Role to use for the child agent\"},\"cwd\":{\"type\":\"string\",\"description\":\"Working directory for the child agent. AGENTS.md and skills are discovered from here.\"}}},\"strict\":false}],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":null,\"user\":null,\"metadata\":{}},\"sequence_number\":0}", + "event: response.in_progress\ndata: {\"type\":\"response.in_progress\",\"response\":{\"id\":\"resp_0bd28b8a5ad18b2e016a0eaaeca6e88195b38d143e2272e210\",\"object\":\"response\",\"created_at\":1779346156,\"status\":\"in_progress\",\"background\":false,\"completed_at\":null,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":null,\"instructions\":null,\"max_output_tokens\":null,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":\"flue-e2e-instance::default::task:task:adc71368-3f10-4ddf-ac19-18\",\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"auto\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[{\"type\":\"function\",\"description\":\"Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.\",\"name\":\"read\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to read\"},\"offset\":{\"type\":\"number\",\"description\":\"Line number to start from (1-indexed)\"},\"limit\":{\"type\":\"number\",\"description\":\"Maximum number of lines to read\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Write content to a file. Creates the file and parent directories if they do not exist.\",\"name\":\"write\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"content\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to write\"},\"content\":{\"type\":\"string\",\"description\":\"Content to write to the file\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.\",\"name\":\"edit\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"oldText\",\"newText\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to edit\"},\"oldText\":{\"type\":\"string\",\"description\":\"Exact text to find (must be unique)\"},\"newText\":{\"type\":\"string\",\"description\":\"Replacement text\"},\"replaceAll\":{\"type\":\"boolean\",\"description\":\"Replace all occurrences\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.\",\"name\":\"bash\",\"parameters\":{\"type\":\"object\",\"required\":[\"command\"],\"properties\":{\"command\":{\"type\":\"string\",\"description\":\"Bash command to execute\"},\"timeout\":{\"type\":\"number\",\"description\":\"Timeout in seconds\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.\",\"name\":\"grep\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Search pattern (regex)\"},\"path\":{\"type\":\"string\",\"description\":\"Directory or file to search (default: .)\"},\"include\":{\"type\":\"string\",\"description\":\"Glob filter, e.g. \\\"*.ts\\\"\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Find files by filename pattern using shell find -name semantics. Returns matching file paths.\",\"name\":\"glob\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Filename pattern, e.g. \\\"*.ts\\\"\"},\"path\":{\"type\":\"string\",\"description\":\"Directory to search in (default: .)\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.\",\"name\":\"task\",\"parameters\":{\"type\":\"object\",\"required\":[\"prompt\"],\"properties\":{\"description\":{\"type\":\"string\",\"description\":\"Short human-readable label for the delegated work\"},\"prompt\":{\"type\":\"string\",\"description\":\"Focused instructions for the child agent\"},\"role\":{\"type\":\"string\",\"description\":\"Role to use for the child agent\"},\"cwd\":{\"type\":\"string\",\"description\":\"Working directory for the child agent. AGENTS.md and skills are discovered from here.\"}}},\"strict\":false}],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":null,\"user\":null,\"metadata\":{}},\"sequence_number\":1}", + "event: response.output_item.added\ndata: {\"type\":\"response.output_item.added\",\"item\":{\"id\":\"msg_0bd28b8a5ad18b2e016a0eaaed1ce8819588a498f3dddd9da6\",\"type\":\"message\",\"status\":\"in_progress\",\"content\":[],\"role\":\"assistant\"},\"output_index\":0,\"sequence_number\":2}", + "event: response.content_part.added\ndata: {\"type\":\"response.content_part.added\",\"content_index\":0,\"item_id\":\"msg_0bd28b8a5ad18b2e016a0eaaed1ce8819588a498f3dddd9da6\",\"output_index\":0,\"part\":{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"\"},\"sequence_number\":3}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"TASK\",\"item_id\":\"msg_0bd28b8a5ad18b2e016a0eaaed1ce8819588a498f3dddd9da6\",\"logprobs\":[],\"obfuscation\":\"ibBHNPoZui5G\",\"output_index\":0,\"sequence_number\":4}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"_DONE\",\"item_id\":\"msg_0bd28b8a5ad18b2e016a0eaaed1ce8819588a498f3dddd9da6\",\"logprobs\":[],\"obfuscation\":\"aiYlRYCETDx\",\"output_index\":0,\"sequence_number\":5}", + "event: response.output_text.done\ndata: {\"type\":\"response.output_text.done\",\"content_index\":0,\"item_id\":\"msg_0bd28b8a5ad18b2e016a0eaaed1ce8819588a498f3dddd9da6\",\"logprobs\":[],\"output_index\":0,\"sequence_number\":6,\"text\":\"TASK_DONE\"}", + "event: response.content_part.done\ndata: {\"type\":\"response.content_part.done\",\"content_index\":0,\"item_id\":\"msg_0bd28b8a5ad18b2e016a0eaaed1ce8819588a498f3dddd9da6\",\"output_index\":0,\"part\":{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"TASK_DONE\"},\"sequence_number\":7}", + "event: response.output_item.done\ndata: {\"type\":\"response.output_item.done\",\"item\":{\"id\":\"msg_0bd28b8a5ad18b2e016a0eaaed1ce8819588a498f3dddd9da6\",\"type\":\"message\",\"status\":\"completed\",\"content\":[{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"TASK_DONE\"}],\"role\":\"assistant\"},\"output_index\":0,\"sequence_number\":8}", + "event: response.completed\ndata: {\"type\":\"response.completed\",\"response\":{\"id\":\"resp_0bd28b8a5ad18b2e016a0eaaeca6e88195b38d143e2272e210\",\"object\":\"response\",\"created_at\":1779346156,\"status\":\"completed\",\"background\":false,\"completed_at\":1779346157,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":null,\"instructions\":null,\"max_output_tokens\":null,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[{\"id\":\"msg_0bd28b8a5ad18b2e016a0eaaed1ce8819588a498f3dddd9da6\",\"type\":\"message\",\"status\":\"completed\",\"content\":[{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"TASK_DONE\"}],\"role\":\"assistant\"}],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":\"flue-e2e-instance::default::task:task:adc71368-3f10-4ddf-ac19-18\",\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"default\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[{\"type\":\"function\",\"description\":\"Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.\",\"name\":\"read\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to read\"},\"offset\":{\"type\":\"number\",\"description\":\"Line number to start from (1-indexed)\"},\"limit\":{\"type\":\"number\",\"description\":\"Maximum number of lines to read\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Write content to a file. Creates the file and parent directories if they do not exist.\",\"name\":\"write\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"content\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to write\"},\"content\":{\"type\":\"string\",\"description\":\"Content to write to the file\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.\",\"name\":\"edit\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"oldText\",\"newText\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to edit\"},\"oldText\":{\"type\":\"string\",\"description\":\"Exact text to find (must be unique)\"},\"newText\":{\"type\":\"string\",\"description\":\"Replacement text\"},\"replaceAll\":{\"type\":\"boolean\",\"description\":\"Replace all occurrences\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.\",\"name\":\"bash\",\"parameters\":{\"type\":\"object\",\"required\":[\"command\"],\"properties\":{\"command\":{\"type\":\"string\",\"description\":\"Bash command to execute\"},\"timeout\":{\"type\":\"number\",\"description\":\"Timeout in seconds\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.\",\"name\":\"grep\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Search pattern (regex)\"},\"path\":{\"type\":\"string\",\"description\":\"Directory or file to search (default: .)\"},\"include\":{\"type\":\"string\",\"description\":\"Glob filter, e.g. \\\"*.ts\\\"\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Find files by filename pattern using shell find -name semantics. Returns matching file paths.\",\"name\":\"glob\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Filename pattern, e.g. \\\"*.ts\\\"\"},\"path\":{\"type\":\"string\",\"description\":\"Directory to search in (default: .)\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.\",\"name\":\"task\",\"parameters\":{\"type\":\"object\",\"required\":[\"prompt\"],\"properties\":{\"description\":{\"type\":\"string\",\"description\":\"Short human-readable label for the delegated work\"},\"prompt\":{\"type\":\"string\",\"description\":\"Focused instructions for the child agent\"},\"role\":{\"type\":\"string\",\"description\":\"Role to use for the child agent\"},\"cwd\":{\"type\":\"string\",\"description\":\"Working directory for the child agent. AGENTS.md and skills are discovered from here.\"}}},\"strict\":false}],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":{\"input_tokens\":770,\"input_tokens_details\":{\"cached_tokens\":0},\"output_tokens\":4,\"output_tokens_details\":{\"reasoning_tokens\":0},\"total_tokens\":774},\"user\":null,\"metadata\":{}},\"sequence_number\":9}" + ], + "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": "9ff1a3e66ba04baf-VIE", + "connection": "keep-alive", + "content-type": "text/event-stream; charset=utf-8", + "date": "Thu, 21 May 2026 06:49:16 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "113", + "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-request-id": "req_02753ec51e9049688579854113b3c5a9" + }, + "status": 200, + "statusText": "OK" + } + }, + { + "callIndex": 1, + "id": "f12aff3913439248", + "matchKey": "POST api.openai.com/v1/responses", + "recordedAt": "2026-05-21T06:49:18.520Z", + "request": { + "body": { + "kind": "json", + "value": { + "input": [ + { + "content": "You are a context summarization assistant. Your task is to read a conversation between a user and an AI coding assistant, then produce a structured summary following the exact format specified.\n\nDo NOT continue the conversation. Do NOT respond to any questions in the conversation. ONLY output the structured summary.", + "role": "system" + }, + { + "content": [ + { + "text": "\n[User]: Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.\n\n[Assistant thinking]: The user wants me to complete a specific instrumented research flow with three steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id to call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url to call summarize_source\n4. Reply with exactly \"PROMPT_DONE\" after summarize_source returns\n\nThe user emphasizes calling exactly one tool per turn and waiting for each result. Let me start with step 1.\n\n[Assistant]: I'll complete this instrumented research flow step by step. Starting with Step 1:\n\n[Assistant tool calls]: lookup(query=\"flue instrumentation\")\n\n[Tool result]: {\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}\n\n[Assistant thinking]: Good, I got the lookup result with id \"flue-session-2026\". Now I'll proceed to step 2 and use this id as the lookupId parameter in the web_search call with the specified query.\n\n[Assistant]: Now proceeding to Step 2:\n\n[Assistant tool calls]: web_search(lookupId=\"flue-session-2026\", query=\"Braintrust Flue reasoning stream instrumentation\")\n\n[Tool result]: {\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\",\"results\":[{\"title\":\"Flue reasoning stream instrumentation\",\"url\":\"https://example.test/flue/reasoning-streams\"}]}\n\n[Assistant thinking]: Perfect! I got the web_search results. There's one result with the URL \"https://example.test/flue/reasoning-streams\". Now I need to proceed to step 3 and call summarize_source with this URL.\n\n[Assistant]: Now proceeding to Step 3:\n\n[Assistant tool calls]: summarize_source(url=\"https://example.test/flue/reasoning-streams\")\n\n[Tool result]: {\"summary\":\"Flue emits reasoning, tool execution, and LLM turn events separately.\",\"url\":\"https://example.test/flue/reasoning-streams\"}\n\n\nThis is the PREFIX of a turn that was too large to keep. The SUFFIX (recent work) is retained.\n\nSummarize the prefix to provide context for the retained suffix:\n\n## Original Request\n[What did the user ask for in this turn?]\n\n## Early Progress\n- [Key decisions and work done in the prefix]\n\n## Context for Suffix\n- [Information needed to understand the retained recent work]\n\nBe concise. Focus on what's needed to understand the kept suffix.", + "type": "input_text" + } + ], + "role": "user" + } + ], + "max_output_tokens": 32, + "model": "gpt-4o-mini", + "store": false, + "stream": true + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/responses" + }, + "response": { + "body": { + "chunks": [ + "event: response.created\ndata: {\"type\":\"response.created\",\"response\":{\"id\":\"resp_059650b5d3870fbb016a0eaaed6b1c81a3b09f299be5949f66\",\"object\":\"response\",\"created_at\":1779346157,\"status\":\"in_progress\",\"background\":false,\"completed_at\":null,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":null,\"instructions\":null,\"max_output_tokens\":32,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":null,\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"auto\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":null,\"user\":null,\"metadata\":{}},\"sequence_number\":0}", + "event: response.in_progress\ndata: {\"type\":\"response.in_progress\",\"response\":{\"id\":\"resp_059650b5d3870fbb016a0eaaed6b1c81a3b09f299be5949f66\",\"object\":\"response\",\"created_at\":1779346157,\"status\":\"in_progress\",\"background\":false,\"completed_at\":null,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":null,\"instructions\":null,\"max_output_tokens\":32,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":null,\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"auto\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":null,\"user\":null,\"metadata\":{}},\"sequence_number\":1}", + "event: response.output_item.added\ndata: {\"type\":\"response.output_item.added\",\"item\":{\"id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"type\":\"message\",\"status\":\"in_progress\",\"content\":[],\"role\":\"assistant\"},\"output_index\":0,\"sequence_number\":2}", + "event: response.content_part.added\ndata: {\"type\":\"response.content_part.added\",\"content_index\":0,\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"output_index\":0,\"part\":{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"\"},\"sequence_number\":3}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"##\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"Gx1RR140b3nmJL\",\"output_index\":0,\"sequence_number\":4}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" Original\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"i6nbcXY\",\"output_index\":0,\"sequence_number\":5}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" Request\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"vSDcpK06\",\"output_index\":0,\"sequence_number\":6}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"\\n\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"hjszm5ObsMVJkTP\",\"output_index\":0,\"sequence_number\":7}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"The\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"agJz2xzIesCwJ\",\"output_index\":0,\"sequence_number\":8}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" user\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"9XQS29fCkws\",\"output_index\":0,\"sequence_number\":9}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" asked\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"njDxIRByDT\",\"output_index\":0,\"sequence_number\":10}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" to\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"AceYhCJ3kV1Uu\",\"output_index\":0,\"sequence_number\":11}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" complete\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"fUd6Jdo\",\"output_index\":0,\"sequence_number\":12}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" an\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"EAx4xF5lBjVb9\",\"output_index\":0,\"sequence_number\":13}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" instrument\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"XQP2H\",\"output_index\":0,\"sequence_number\":14}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"ed\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"Ywp2sXXXLqDZqn\",\"output_index\":0,\"sequence_number\":15}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" research\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"d8Mr1pV\",\"output_index\":0,\"sequence_number\":16}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" flow\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"20oSEoErG5e\",\"output_index\":0,\"sequence_number\":17}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" involving\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"dtt4Mm\",\"output_index\":0,\"sequence_number\":18}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" three\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"i5TEaWCQL5\",\"output_index\":0,\"sequence_number\":19}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" steps\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"BsofJH6d3j\",\"output_index\":0,\"sequence_number\":20}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\":\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"f4qnjYsPPBa3NkH\",\"output_index\":0,\"sequence_number\":21}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" calling\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"IyToLqWH\",\"output_index\":0,\"sequence_number\":22}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" a\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"XrSHPJJcskbkcn\",\"output_index\":0,\"sequence_number\":23}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" lookup\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"ouCoM5Kbc\",\"output_index\":0,\"sequence_number\":24}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" for\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"iDjkarnmFyYP\",\"output_index\":0,\"sequence_number\":25}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" \\\"\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"earEp7YaHZreUj\",\"output_index\":0,\"sequence_number\":26}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"fl\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"abHWveRt5Ly4mw\",\"output_index\":0,\"sequence_number\":27}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"ue\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"k2uewXc0pS32xH\",\"output_index\":0,\"sequence_number\":28}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" instrumentation\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"\",\"output_index\":0,\"sequence_number\":29}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"\\\",\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"m4823gb2EonmFG\",\"output_index\":0,\"sequence_number\":30}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" using\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"d7jC7AqvYZ\",\"output_index\":0,\"sequence_number\":31}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" the\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"Mvs3a27G5DtQ\",\"output_index\":0,\"sequence_number\":32}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" lookup\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"PcfTiAZFw\",\"output_index\":0,\"sequence_number\":33}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" result\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"s9rQaPiGV\",\"output_index\":0,\"sequence_number\":34}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" to\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"ktTVhusNsXeOz\",\"output_index\":0,\"sequence_number\":35}", + "event: response.output_text.done\ndata: {\"type\":\"response.output_text.done\",\"content_index\":0,\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"output_index\":0,\"sequence_number\":36,\"text\":\"## Original Request\\nThe user asked to complete an instrumented research flow involving three steps: calling a lookup for \\\"flue instrumentation\\\", using the lookup result to\"}", + "event: response.content_part.done\ndata: {\"type\":\"response.content_part.done\",\"content_index\":0,\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"output_index\":0,\"part\":{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"## Original Request\\nThe user asked to complete an instrumented research flow involving three steps: calling a lookup for \\\"flue instrumentation\\\", using the lookup result to\"},\"sequence_number\":37}", + "event: response.output_item.done\ndata: {\"type\":\"response.output_item.done\",\"item\":{\"id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"type\":\"message\",\"status\":\"incomplete\",\"content\":[{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"## Original Request\\nThe user asked to complete an instrumented research flow involving three steps: calling a lookup for \\\"flue instrumentation\\\", using the lookup result to\"}],\"role\":\"assistant\"},\"output_index\":0,\"sequence_number\":38}", + "event: response.incomplete\ndata: {\"type\":\"response.incomplete\",\"response\":{\"id\":\"resp_059650b5d3870fbb016a0eaaed6b1c81a3b09f299be5949f66\",\"object\":\"response\",\"created_at\":1779346157,\"status\":\"incomplete\",\"background\":false,\"completed_at\":null,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":{\"reason\":\"max_output_tokens\"},\"instructions\":null,\"max_output_tokens\":32,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[{\"id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"type\":\"message\",\"status\":\"incomplete\",\"content\":[{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"## Original Request\\nThe user asked to complete an instrumented research flow involving three steps: calling a lookup for \\\"flue instrumentation\\\", using the lookup result to\"}],\"role\":\"assistant\"}],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":null,\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"default\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":{\"input_tokens\":687,\"input_tokens_details\":{\"cached_tokens\":0},\"output_tokens\":32,\"output_tokens_details\":{\"reasoning_tokens\":0},\"total_tokens\":719},\"user\":null,\"metadata\":{}},\"sequence_number\":39}" + ], + "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": "9ff1a3eb491c4baf-VIE", + "connection": "keep-alive", + "content-type": "text/event-stream; charset=utf-8", + "date": "Thu, 21 May 2026 06:49:17 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "115", + "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-request-id": "req_b92f207d3e4647da98518cc8147b231c" + }, + "status": 200, + "statusText": "OK" + } + } + ], + "meta": { + "createdAt": "2026-05-20T19:15:29.584Z" + } +} diff --git a/e2e/scenarios/flue-instrumentation/__cassettes__/flue-v0-7-0-wrapped.cassette.json b/e2e/scenarios/flue-instrumentation/__cassettes__/flue-v0-7-0-wrapped.cassette.json new file mode 100644 index 000000000..111d4cbd0 --- /dev/null +++ b/e2e/scenarios/flue-instrumentation/__cassettes__/flue-v0-7-0-wrapped.cassette.json @@ -0,0 +1,2345 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "fcd9d51c145fb90b", + "matchKey": "POST api.anthropic.com/v1/messages", + "recordedAt": "2026-05-21T06:48:36.059Z", + "request": { + "body": { + "kind": "json", + "value": { + "max_tokens": 64000, + "messages": [ + { + "content": [ + { + "cache_control": { + "type": "ephemeral" + }, + "text": "Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.", + "type": "text" + } + ], + "role": "user" + } + ], + "model": "claude-sonnet-4-5-20250929", + "stream": true, + "system": [ + { + "cache_control": { + "type": "ephemeral" + }, + "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Thu, May 21, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-LqmoTW/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + "type": "text" + } + ], + "thinking": { + "budget_tokens": 8192, + "display": "summarized", + "type": "enabled" + }, + "tools": [ + { + "description": "Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "limit": { + "description": "Maximum number of lines to read", + "type": "number" + }, + "offset": { + "description": "Line number to start from (1-indexed)", + "type": "number" + }, + "path": { + "description": "Path to the file to read", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + }, + "name": "read" + }, + { + "description": "Write content to a file. Creates the file and parent directories if they do not exist.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Path to the file to write", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + }, + "name": "write" + }, + { + "description": "Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "newText": { + "description": "Replacement text", + "type": "string" + }, + "oldText": { + "description": "Exact text to find (must be unique)", + "type": "string" + }, + "path": { + "description": "Path to the file to edit", + "type": "string" + }, + "replaceAll": { + "description": "Replace all occurrences", + "type": "boolean" + } + }, + "required": ["path", "oldText", "newText"], + "type": "object" + }, + "name": "edit" + }, + { + "description": "Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "command": { + "description": "Bash command to execute", + "type": "string" + }, + "timeout": { + "description": "Timeout in seconds", + "type": "number" + } + }, + "required": ["command"], + "type": "object" + }, + "name": "bash" + }, + { + "description": "Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "include": { + "description": "Glob filter, e.g. \"*.ts\"", + "type": "string" + }, + "path": { + "description": "Directory or file to search (default: .)", + "type": "string" + }, + "pattern": { + "description": "Search pattern (regex)", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + }, + "name": "grep" + }, + { + "description": "Find files by filename pattern using shell find -name semantics. Returns matching file paths.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "path": { + "description": "Directory to search in (default: .)", + "type": "string" + }, + "pattern": { + "description": "Filename pattern, e.g. \"*.ts\"", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + }, + "name": "glob" + }, + { + "description": "Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "cwd": { + "description": "Working directory for the child agent. AGENTS.md and skills are discovered from here.", + "type": "string" + }, + "description": { + "description": "Short human-readable label for the delegated work", + "type": "string" + }, + "prompt": { + "description": "Focused instructions for the child agent", + "type": "string" + }, + "role": { + "description": "Role to use for the child agent", + "type": "string" + } + }, + "required": ["prompt"], + "type": "object" + }, + "name": "task" + }, + { + "description": "Return a deterministic lookup result with an id needed by web_search.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "query": { + "type": "string" + } + }, + "required": ["query"], + "type": "object" + }, + "name": "lookup" + }, + { + "description": "Search a deterministic local web index. Requires the id returned by lookup.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "lookupId": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": ["lookupId", "query"], + "type": "object" + }, + "name": "web_search" + }, + { + "cache_control": { + "type": "ephemeral" + }, + "description": "Summarize the selected deterministic source after web_search returns a URL.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "url": { + "type": "string" + } + }, + "required": ["url"], + "type": "object" + }, + "name": "summarize_source" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.anthropic.com/v1/messages" + }, + "response": { + "body": { + "chunks": [ + "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-5-20250929\",\"id\":\"msg_01SM4G3aUCHLPmaurSygvHCw\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":10,\"cache_creation_input_tokens\":885,\"cache_read_input_tokens\":1297,\"cache_creation\":{\"ephemeral_5m_input_tokens\":885,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":7,\"service_tier\":\"standard\",\"inference_geo\":\"not_available\"}}}", + "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"thinking\",\"thinking\":\"\",\"signature\":\"\"}}", + "event: ping\ndata: {\"type\":\"ping\"}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\"The user wants me to complete an\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\" instrumented research flow with exactly three steps:\\n1. Call lookup with query \\\"flue instrumentation\\\"\\n2. Use the lookup result id to call\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\" web_search with query \\\"Braintrust Flue reasoning stream instrumentation\\\"\\n3. Use the first web_search result url to call summarize_source\\n4. After that, reply with exactly \\\"PROMPT_DONE\\\"\\n\\nThe\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\" user also emphasizes that I should call exactly one tool per turn and wait for each tool result before choosing the next tool.\\n\\nLet me start with Step 1: calling\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\" lookup with query \\\"flue instrumentation\\\".\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"signature_delta\",\"signature\":\"EoUGCm4IDRgCKkBGG1EQWIA9O/tsHYduxoTUS/i0gICgUs3GdrJlpnNSzO7qWVpXyAV/QYunxiJ/pbuy1AxKmw6zIb/6D5H7ZGWfMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMRXKds4wYcGMYouIkGgwZoj3tniSPvjyfUQ0iMJTYUR1cOzdSxBk9UN+23wtgAo9/8kEQNV+xOUHpUah0CvD2CK4e6+Mxn9U0PvwTTyrEBACjWEoJTpmbj0w1MNh5K+OwmDdBIpCbBeZgNfwk/5hZlooub3A2Da3jc6kIQPcSJAyzDcURqiosMVZblqqzxHM/aEXrQka5eZe/CELGEOZLcy2L0sRYjYzcKh+2/4hKScq3jltGM/MwmdE0y1P21raJdOxIpcXaIyQDncBiL9EQ3oPmRuhDHM9giLQaRdA8spWQs8P15X7ZcxxaVV4bI26aJoQa9/BoEBqDbNGNi0jPABVoEoUprtXqNJcl3lb4GUerTKVvEPlXluwJbN0ozQ3j9v8GGqqHlAe5J4WpjO3RA5CjKU6poKdB+CW2/MjTMA5noiDFJzqE5krdR/ll4UusUXFv+DYdLIXvm/RF/EGZa1FAmk+knqhbodSkL78m/AKpDOHNH9qymwstVSQP5IH8Xt6jE6olgXNLIHqmztPCsHYGoli+2FajT98T22xZJ/i9UPJyg+w800UtLCVzwa5Abx98Vodu7zyqZFAQ5HwWf9uY4f2T/tCjoPluiIZVb0nTUHziOnvsCpNQVWWi1eWMM6wUmfcki0TDlXaW2CNcBFSpmehGHwN3qjs2iDUG6w7MAo1hMjkKuUdalXTBqFbDa/EoEXIf4gpyNgXB0b5rzLGb8CisCONKT/PT788R7ZbjWrOqxtpIouGWqD0rvVgkGjBnuJ8EhIn1lkn1QXhqLZhcPsR7fal7rM2NRPVdD5fcI/NS9nIHo/Zx3i25gC0jd3hY+Eihl+f2C9K7f7kq78R2tUf62Sjc8XMy/QVWfsogYLIYAQ==\"}}", + "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0}", + "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":1,\"content_block\":{\"type\":\"text\",\"text\":\"\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"text_delta\",\"text\":\"I'll complete this instrumented research flow step by step. Starting with Step 1:\"}}", + "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":1}", + "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":2,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01GD2k3M7867B4B2MdjCqVrG\",\"name\":\"lookup\",\"input\":{},\"caller\":{\"type\":\"direct\"}}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"query\\\": \\\"flue instrumentation\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"}\"}}", + "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":2}", + "event: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":10,\"cache_creation_input_tokens\":885,\"cache_read_input_tokens\":1297,\"output_tokens\":217}}", + "event: message_stop\ndata: {\"type\":\"message_stop\"}" + ], + "kind": "sse" + }, + "headers": { + "anthropic-organization-id": "27796668-7351-40ac-acc4-024aee8995a5", + "anthropic-ratelimit-input-tokens-limit": "3000000", + "anthropic-ratelimit-input-tokens-remaining": "2999000", + "anthropic-ratelimit-input-tokens-reset": "2026-05-21T06:48:32Z", + "anthropic-ratelimit-output-tokens-limit": "600000", + "anthropic-ratelimit-output-tokens-remaining": "600000", + "anthropic-ratelimit-output-tokens-reset": "2026-05-21T06:48:32Z", + "anthropic-ratelimit-requests-limit": "20000", + "anthropic-ratelimit-requests-remaining": "19999", + "anthropic-ratelimit-requests-reset": "2026-05-21T06:48:32Z", + "anthropic-ratelimit-tokens-limit": "3600000", + "anthropic-ratelimit-tokens-remaining": "3599000", + "anthropic-ratelimit-tokens-reset": "2026-05-21T06:48:32Z", + "cache-control": "no-cache", + "cf-cache-status": "DYNAMIC", + "cf-ray": "9ff1a2d24f775b94-VIE", + "connection": "keep-alive", + "content-encoding": "gzip", + "content-security-policy": "default-src 'none'; frame-ancestors 'none'", + "content-type": "text/event-stream; charset=utf-8", + "date": "Thu, 21 May 2026 06:48:33 GMT", + "request-id": "req_011CbFGTGEoBYWfGWrG8AWpG", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "traceresponse": "00-82368401eaf4c73a1631ded37323150e-994a044e3d1c5ec7-01", + "transfer-encoding": "chunked", + "vary": "Accept-Encoding", + "x-envoy-upstream-service-time": "1246", + "x-robots-tag": "none" + }, + "status": 200, + "statusText": "OK" + } + }, + { + "callIndex": 1, + "id": "ff22a182ea5a9c06", + "matchKey": "POST api.anthropic.com/v1/messages", + "recordedAt": "2026-05-21T06:48:39.636Z", + "request": { + "body": { + "kind": "json", + "value": { + "max_tokens": 64000, + "messages": [ + { + "content": [ + { + "text": "Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "signature": "EoUGCm4IDRgCKkBGG1EQWIA9O/tsHYduxoTUS/i0gICgUs3GdrJlpnNSzO7qWVpXyAV/QYunxiJ/pbuy1AxKmw6zIb/6D5H7ZGWfMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMRXKds4wYcGMYouIkGgwZoj3tniSPvjyfUQ0iMJTYUR1cOzdSxBk9UN+23wtgAo9/8kEQNV+xOUHpUah0CvD2CK4e6+Mxn9U0PvwTTyrEBACjWEoJTpmbj0w1MNh5K+OwmDdBIpCbBeZgNfwk/5hZlooub3A2Da3jc6kIQPcSJAyzDcURqiosMVZblqqzxHM/aEXrQka5eZe/CELGEOZLcy2L0sRYjYzcKh+2/4hKScq3jltGM/MwmdE0y1P21raJdOxIpcXaIyQDncBiL9EQ3oPmRuhDHM9giLQaRdA8spWQs8P15X7ZcxxaVV4bI26aJoQa9/BoEBqDbNGNi0jPABVoEoUprtXqNJcl3lb4GUerTKVvEPlXluwJbN0ozQ3j9v8GGqqHlAe5J4WpjO3RA5CjKU6poKdB+CW2/MjTMA5noiDFJzqE5krdR/ll4UusUXFv+DYdLIXvm/RF/EGZa1FAmk+knqhbodSkL78m/AKpDOHNH9qymwstVSQP5IH8Xt6jE6olgXNLIHqmztPCsHYGoli+2FajT98T22xZJ/i9UPJyg+w800UtLCVzwa5Abx98Vodu7zyqZFAQ5HwWf9uY4f2T/tCjoPluiIZVb0nTUHziOnvsCpNQVWWi1eWMM6wUmfcki0TDlXaW2CNcBFSpmehGHwN3qjs2iDUG6w7MAo1hMjkKuUdalXTBqFbDa/EoEXIf4gpyNgXB0b5rzLGb8CisCONKT/PT788R7ZbjWrOqxtpIouGWqD0rvVgkGjBnuJ8EhIn1lkn1QXhqLZhcPsR7fal7rM2NRPVdD5fcI/NS9nIHo/Zx3i25gC0jd3hY+Eihl+f2C9K7f7kq78R2tUf62Sjc8XMy/QVWfsogYLIYAQ==", + "thinking": "The user wants me to complete an instrumented research flow with exactly three steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id to call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url to call summarize_source\n4. After that, reply with exactly \"PROMPT_DONE\"\n\nThe user also emphasizes that I should call exactly one tool per turn and wait for each tool result before choosing the next tool.\n\nLet me start with Step 1: calling lookup with query \"flue instrumentation\".", + "type": "thinking" + }, + { + "text": "I'll complete this instrumented research flow step by step. Starting with Step 1:", + "type": "text" + }, + { + "id": "toolu_01GD2k3M7867B4B2MdjCqVrG", + "input": { + "query": "flue instrumentation" + }, + "name": "lookup", + "type": "tool_use" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "cache_control": { + "type": "ephemeral" + }, + "content": "{\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}", + "is_error": false, + "tool_use_id": "toolu_01GD2k3M7867B4B2MdjCqVrG", + "type": "tool_result" + } + ], + "role": "user" + } + ], + "model": "claude-sonnet-4-5-20250929", + "stream": true, + "system": [ + { + "cache_control": { + "type": "ephemeral" + }, + "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Thu, May 21, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-LqmoTW/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + "type": "text" + } + ], + "thinking": { + "budget_tokens": 8192, + "display": "summarized", + "type": "enabled" + }, + "tools": [ + { + "description": "Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "limit": { + "description": "Maximum number of lines to read", + "type": "number" + }, + "offset": { + "description": "Line number to start from (1-indexed)", + "type": "number" + }, + "path": { + "description": "Path to the file to read", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + }, + "name": "read" + }, + { + "description": "Write content to a file. Creates the file and parent directories if they do not exist.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Path to the file to write", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + }, + "name": "write" + }, + { + "description": "Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "newText": { + "description": "Replacement text", + "type": "string" + }, + "oldText": { + "description": "Exact text to find (must be unique)", + "type": "string" + }, + "path": { + "description": "Path to the file to edit", + "type": "string" + }, + "replaceAll": { + "description": "Replace all occurrences", + "type": "boolean" + } + }, + "required": ["path", "oldText", "newText"], + "type": "object" + }, + "name": "edit" + }, + { + "description": "Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "command": { + "description": "Bash command to execute", + "type": "string" + }, + "timeout": { + "description": "Timeout in seconds", + "type": "number" + } + }, + "required": ["command"], + "type": "object" + }, + "name": "bash" + }, + { + "description": "Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "include": { + "description": "Glob filter, e.g. \"*.ts\"", + "type": "string" + }, + "path": { + "description": "Directory or file to search (default: .)", + "type": "string" + }, + "pattern": { + "description": "Search pattern (regex)", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + }, + "name": "grep" + }, + { + "description": "Find files by filename pattern using shell find -name semantics. Returns matching file paths.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "path": { + "description": "Directory to search in (default: .)", + "type": "string" + }, + "pattern": { + "description": "Filename pattern, e.g. \"*.ts\"", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + }, + "name": "glob" + }, + { + "description": "Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "cwd": { + "description": "Working directory for the child agent. AGENTS.md and skills are discovered from here.", + "type": "string" + }, + "description": { + "description": "Short human-readable label for the delegated work", + "type": "string" + }, + "prompt": { + "description": "Focused instructions for the child agent", + "type": "string" + }, + "role": { + "description": "Role to use for the child agent", + "type": "string" + } + }, + "required": ["prompt"], + "type": "object" + }, + "name": "task" + }, + { + "description": "Return a deterministic lookup result with an id needed by web_search.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "query": { + "type": "string" + } + }, + "required": ["query"], + "type": "object" + }, + "name": "lookup" + }, + { + "description": "Search a deterministic local web index. Requires the id returned by lookup.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "lookupId": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": ["lookupId", "query"], + "type": "object" + }, + "name": "web_search" + }, + { + "cache_control": { + "type": "ephemeral" + }, + "description": "Summarize the selected deterministic source after web_search returns a URL.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "url": { + "type": "string" + } + }, + "required": ["url"], + "type": "object" + }, + "name": "summarize_source" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.anthropic.com/v1/messages" + }, + "response": { + "body": { + "chunks": [ + "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-5-20250929\",\"id\":\"msg_01CbdemsVyAkiFbARhovXpDk\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":13,\"cache_creation_input_tokens\":257,\"cache_read_input_tokens\":2182,\"cache_creation\":{\"ephemeral_5m_input_tokens\":257,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":1,\"service_tier\":\"standard\",\"inference_geo\":\"not_available\"}}}", + "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"thinking\",\"thinking\":\"\",\"signature\":\"\"}}", + "event: ping\ndata: {\"type\":\"ping\"}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\"Good\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\", I got the lookup result with id \\\"flue-session-2026\\\". Now I need to proceed to Step 2: call web_search using\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\" this lookupId and the query \\\"Braintrust Flue reasoning stream instrumentation\\\".\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"signature_delta\",\"signature\":\"EpIDCm4IDRgCKkAGraaqPdHGE2HAbbEXcB/tBYIme5NcenLqHXnwfLjt8F2BUuO3FdH/1DhJ+cGEblVkRTDTtr6gwSbDyYOpIMTZMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIM0hkEt+QHz3frKV+dGgzBzyZSSik/kTiNJUIiMIXWT5AewGcoAk3E5CRsl/7bJoySRe2JV3p8Jv7ioYkJy08euGanth1HahprJhsG3irRAZ1GCOHuwJ6itCVds3y3W1r2Ksy1ShGPrOk0sXjC1RZXt3bTsQAQfi1AU0QaqlgI1RLzXRDhQEbTRQKa7UmMsbCBABlqQrh+90j6u3CqpkibXv5TwnyNlIl3aTBk+HQ+bPPdbQ/yagDMeMG4E4pEik7IFcKet39ynV6QCyTgcxrcgBJZ1uZb4mMxBPuPAwNqHCOdPDRMk8SVreU9PqR54j7fsuMnLBgV85AC8r1iI5cKo3MuhD6KcZG58ls3Yj3exA+XH2OauTFxaa0lDcEYmkAhGAE=\"}}", + "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0}", + "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":1,\"content_block\":{\"type\":\"text\",\"text\":\"\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"text_delta\",\"text\":\"Now proceeding to Step 2:\"}}", + "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":1}", + "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":2,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_016VW8Z7PawkTryuu3wNMQZM\",\"name\":\"web_search\",\"input\":{},\"caller\":{\"type\":\"direct\"}}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"lookupId\\\": \\\"flue-session-2026\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\", \\\"query\\\": \\\"Braintrust Flue reasoning stream instru\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"mentation\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"}\"}}", + "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":2}", + "event: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":13,\"cache_creation_input_tokens\":257,\"cache_read_input_tokens\":2182,\"output_tokens\":158}}", + "event: message_stop\ndata: {\"type\":\"message_stop\"}" + ], + "kind": "sse" + }, + "headers": { + "anthropic-organization-id": "27796668-7351-40ac-acc4-024aee8995a5", + "anthropic-ratelimit-input-tokens-limit": "3000000", + "anthropic-ratelimit-input-tokens-remaining": "2999000", + "anthropic-ratelimit-input-tokens-reset": "2026-05-21T06:48:36Z", + "anthropic-ratelimit-output-tokens-limit": "600000", + "anthropic-ratelimit-output-tokens-remaining": "600000", + "anthropic-ratelimit-output-tokens-reset": "2026-05-21T06:48:36Z", + "anthropic-ratelimit-requests-limit": "20000", + "anthropic-ratelimit-requests-remaining": "19999", + "anthropic-ratelimit-requests-reset": "2026-05-21T06:48:36Z", + "anthropic-ratelimit-tokens-limit": "3600000", + "anthropic-ratelimit-tokens-remaining": "3599000", + "anthropic-ratelimit-tokens-reset": "2026-05-21T06:48:36Z", + "cache-control": "no-cache", + "cf-cache-status": "DYNAMIC", + "cf-ray": "9ff1a2e9dc315b94-VIE", + "connection": "keep-alive", + "content-encoding": "gzip", + "content-security-policy": "default-src 'none'; frame-ancestors 'none'", + "content-type": "text/event-stream; charset=utf-8", + "date": "Thu, 21 May 2026 06:48:38 GMT", + "request-id": "req_011CbFGTY7XYyU143kqeCPvJ", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "traceresponse": "00-70dfa42b365a8f6c7805eea761a41ed6-a282aba5d0474c79-01", + "transfer-encoding": "chunked", + "vary": "Accept-Encoding", + "x-envoy-upstream-service-time": "1764", + "x-robots-tag": "none" + }, + "status": 200, + "statusText": "OK" + } + }, + { + "callIndex": 2, + "id": "f1d50a1e6c760d6c", + "matchKey": "POST api.anthropic.com/v1/messages", + "recordedAt": "2026-05-21T06:48:42.864Z", + "request": { + "body": { + "kind": "json", + "value": { + "max_tokens": 64000, + "messages": [ + { + "content": [ + { + "text": "Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "signature": "EoUGCm4IDRgCKkBGG1EQWIA9O/tsHYduxoTUS/i0gICgUs3GdrJlpnNSzO7qWVpXyAV/QYunxiJ/pbuy1AxKmw6zIb/6D5H7ZGWfMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMRXKds4wYcGMYouIkGgwZoj3tniSPvjyfUQ0iMJTYUR1cOzdSxBk9UN+23wtgAo9/8kEQNV+xOUHpUah0CvD2CK4e6+Mxn9U0PvwTTyrEBACjWEoJTpmbj0w1MNh5K+OwmDdBIpCbBeZgNfwk/5hZlooub3A2Da3jc6kIQPcSJAyzDcURqiosMVZblqqzxHM/aEXrQka5eZe/CELGEOZLcy2L0sRYjYzcKh+2/4hKScq3jltGM/MwmdE0y1P21raJdOxIpcXaIyQDncBiL9EQ3oPmRuhDHM9giLQaRdA8spWQs8P15X7ZcxxaVV4bI26aJoQa9/BoEBqDbNGNi0jPABVoEoUprtXqNJcl3lb4GUerTKVvEPlXluwJbN0ozQ3j9v8GGqqHlAe5J4WpjO3RA5CjKU6poKdB+CW2/MjTMA5noiDFJzqE5krdR/ll4UusUXFv+DYdLIXvm/RF/EGZa1FAmk+knqhbodSkL78m/AKpDOHNH9qymwstVSQP5IH8Xt6jE6olgXNLIHqmztPCsHYGoli+2FajT98T22xZJ/i9UPJyg+w800UtLCVzwa5Abx98Vodu7zyqZFAQ5HwWf9uY4f2T/tCjoPluiIZVb0nTUHziOnvsCpNQVWWi1eWMM6wUmfcki0TDlXaW2CNcBFSpmehGHwN3qjs2iDUG6w7MAo1hMjkKuUdalXTBqFbDa/EoEXIf4gpyNgXB0b5rzLGb8CisCONKT/PT788R7ZbjWrOqxtpIouGWqD0rvVgkGjBnuJ8EhIn1lkn1QXhqLZhcPsR7fal7rM2NRPVdD5fcI/NS9nIHo/Zx3i25gC0jd3hY+Eihl+f2C9K7f7kq78R2tUf62Sjc8XMy/QVWfsogYLIYAQ==", + "thinking": "The user wants me to complete an instrumented research flow with exactly three steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id to call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url to call summarize_source\n4. After that, reply with exactly \"PROMPT_DONE\"\n\nThe user also emphasizes that I should call exactly one tool per turn and wait for each tool result before choosing the next tool.\n\nLet me start with Step 1: calling lookup with query \"flue instrumentation\".", + "type": "thinking" + }, + { + "text": "I'll complete this instrumented research flow step by step. Starting with Step 1:", + "type": "text" + }, + { + "id": "toolu_01GD2k3M7867B4B2MdjCqVrG", + "input": { + "query": "flue instrumentation" + }, + "name": "lookup", + "type": "tool_use" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "content": "{\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}", + "is_error": false, + "tool_use_id": "toolu_01GD2k3M7867B4B2MdjCqVrG", + "type": "tool_result" + } + ], + "role": "user" + }, + { + "content": [ + { + "signature": "EpIDCm4IDRgCKkAGraaqPdHGE2HAbbEXcB/tBYIme5NcenLqHXnwfLjt8F2BUuO3FdH/1DhJ+cGEblVkRTDTtr6gwSbDyYOpIMTZMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIM0hkEt+QHz3frKV+dGgzBzyZSSik/kTiNJUIiMIXWT5AewGcoAk3E5CRsl/7bJoySRe2JV3p8Jv7ioYkJy08euGanth1HahprJhsG3irRAZ1GCOHuwJ6itCVds3y3W1r2Ksy1ShGPrOk0sXjC1RZXt3bTsQAQfi1AU0QaqlgI1RLzXRDhQEbTRQKa7UmMsbCBABlqQrh+90j6u3CqpkibXv5TwnyNlIl3aTBk+HQ+bPPdbQ/yagDMeMG4E4pEik7IFcKet39ynV6QCyTgcxrcgBJZ1uZb4mMxBPuPAwNqHCOdPDRMk8SVreU9PqR54j7fsuMnLBgV85AC8r1iI5cKo3MuhD6KcZG58ls3Yj3exA+XH2OauTFxaa0lDcEYmkAhGAE=", + "thinking": "Good, I got the lookup result with id \"flue-session-2026\". Now I need to proceed to Step 2: call web_search using this lookupId and the query \"Braintrust Flue reasoning stream instrumentation\".", + "type": "thinking" + }, + { + "text": "Now proceeding to Step 2:", + "type": "text" + }, + { + "id": "toolu_016VW8Z7PawkTryuu3wNMQZM", + "input": { + "lookupId": "flue-session-2026", + "query": "Braintrust Flue reasoning stream instrumentation" + }, + "name": "web_search", + "type": "tool_use" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "cache_control": { + "type": "ephemeral" + }, + "content": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\",\"results\":[{\"title\":\"Flue reasoning stream instrumentation\",\"url\":\"https://example.test/flue/reasoning-streams\"}]}", + "is_error": false, + "tool_use_id": "toolu_016VW8Z7PawkTryuu3wNMQZM", + "type": "tool_result" + } + ], + "role": "user" + } + ], + "model": "claude-sonnet-4-5-20250929", + "stream": true, + "system": [ + { + "cache_control": { + "type": "ephemeral" + }, + "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Thu, May 21, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-LqmoTW/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + "type": "text" + } + ], + "thinking": { + "budget_tokens": 8192, + "display": "summarized", + "type": "enabled" + }, + "tools": [ + { + "description": "Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "limit": { + "description": "Maximum number of lines to read", + "type": "number" + }, + "offset": { + "description": "Line number to start from (1-indexed)", + "type": "number" + }, + "path": { + "description": "Path to the file to read", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + }, + "name": "read" + }, + { + "description": "Write content to a file. Creates the file and parent directories if they do not exist.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Path to the file to write", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + }, + "name": "write" + }, + { + "description": "Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "newText": { + "description": "Replacement text", + "type": "string" + }, + "oldText": { + "description": "Exact text to find (must be unique)", + "type": "string" + }, + "path": { + "description": "Path to the file to edit", + "type": "string" + }, + "replaceAll": { + "description": "Replace all occurrences", + "type": "boolean" + } + }, + "required": ["path", "oldText", "newText"], + "type": "object" + }, + "name": "edit" + }, + { + "description": "Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "command": { + "description": "Bash command to execute", + "type": "string" + }, + "timeout": { + "description": "Timeout in seconds", + "type": "number" + } + }, + "required": ["command"], + "type": "object" + }, + "name": "bash" + }, + { + "description": "Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "include": { + "description": "Glob filter, e.g. \"*.ts\"", + "type": "string" + }, + "path": { + "description": "Directory or file to search (default: .)", + "type": "string" + }, + "pattern": { + "description": "Search pattern (regex)", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + }, + "name": "grep" + }, + { + "description": "Find files by filename pattern using shell find -name semantics. Returns matching file paths.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "path": { + "description": "Directory to search in (default: .)", + "type": "string" + }, + "pattern": { + "description": "Filename pattern, e.g. \"*.ts\"", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + }, + "name": "glob" + }, + { + "description": "Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "cwd": { + "description": "Working directory for the child agent. AGENTS.md and skills are discovered from here.", + "type": "string" + }, + "description": { + "description": "Short human-readable label for the delegated work", + "type": "string" + }, + "prompt": { + "description": "Focused instructions for the child agent", + "type": "string" + }, + "role": { + "description": "Role to use for the child agent", + "type": "string" + } + }, + "required": ["prompt"], + "type": "object" + }, + "name": "task" + }, + { + "description": "Return a deterministic lookup result with an id needed by web_search.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "query": { + "type": "string" + } + }, + "required": ["query"], + "type": "object" + }, + "name": "lookup" + }, + { + "description": "Search a deterministic local web index. Requires the id returned by lookup.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "lookupId": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": ["lookupId", "query"], + "type": "object" + }, + "name": "web_search" + }, + { + "cache_control": { + "type": "ephemeral" + }, + "description": "Summarize the selected deterministic source after web_search returns a URL.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "url": { + "type": "string" + } + }, + "required": ["url"], + "type": "object" + }, + "name": "summarize_source" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.anthropic.com/v1/messages" + }, + "response": { + "body": { + "chunks": [ + "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-5-20250929\",\"id\":\"msg_0127ncLrvEhbdvmzcmsakH7k\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":13,\"cache_creation_input_tokens\":234,\"cache_read_input_tokens\":2439,\"cache_creation\":{\"ephemeral_5m_input_tokens\":234,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":1,\"service_tier\":\"standard\",\"inference_geo\":\"not_available\"}}}", + "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"thinking\",\"thinking\":\"\",\"signature\":\"\"}}", + "event: ping\ndata: {\"type\":\"ping\"}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\"Perfect\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\"! I got the web_search results. There's one result with the URL\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\" \\\"https://example.test/flue/reasoning-streams\\\". Now I need to proceed to Step 3: call summarize_source with this URL.\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"signature_delta\",\"signature\":\"EowDCm4IDRgCKkBAx8dB8EGMSxpAE1bkbv5IFMJcST9qVcl0KHwBXOCrtNNuK9rYk/fasBvKRf6NsyQU3hPl6KMhPmyo1RdgrlbyMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMemkNtsvVXGxVJiFJGgz6AuNoagcBoR2BOdgiMFUYr/5iFJKYgrBdik3Xu8ppJPGcUDuB6f4EI2N39i9sNQHVR8XBCvZaXwJqEILnsSrLAQ1TaPrVNMVCJ5ly8rltFaB3uEBGoaXmduyD/0NFlU6zSySG1hnGrY/tgcH3erm3AOCRJugGoDuSUEn301OxHooiKXGMh/2CsQ1LqQu1nwyrmbK/7+U/UtbouGJQaLkmoAfSWPDKm08zU6filkzdihRiWMkJ9wO/sqbtu8US3zxrIEqE+IPWGBJIHoncA1mAM7pPjqTPZEu4z5f69C0//fQszysmRRO2QejYfGu6m216yFGNwJnirhMFzlXbj5kU1FO21VQ8Wb6dAv0PGAE=\"}}", + "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0}", + "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":1,\"content_block\":{\"type\":\"text\",\"text\":\"\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"text_delta\",\"text\":\"Now proceeding to Step\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"text_delta\",\"text\":\" 3:\"}}", + "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":1}", + "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":2,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01JvdxTjoCLCdYkoec6bWgVv\",\"name\":\"summarize_source\",\"input\":{},\"caller\":{\"type\":\"direct\"}}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"url\\\": \\\"https://example.test/flue/reasoning-streams\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"}\"}}", + "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":2}", + "event: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":13,\"cache_creation_input_tokens\":234,\"cache_read_input_tokens\":2439,\"output_tokens\":132}}", + "event: message_stop\ndata: {\"type\":\"message_stop\"}" + ], + "kind": "sse" + }, + "headers": { + "anthropic-organization-id": "27796668-7351-40ac-acc4-024aee8995a5", + "anthropic-ratelimit-input-tokens-limit": "3000000", + "anthropic-ratelimit-input-tokens-remaining": "2999000", + "anthropic-ratelimit-input-tokens-reset": "2026-05-21T06:48:39Z", + "anthropic-ratelimit-output-tokens-limit": "600000", + "anthropic-ratelimit-output-tokens-remaining": "600000", + "anthropic-ratelimit-output-tokens-reset": "2026-05-21T06:48:39Z", + "anthropic-ratelimit-requests-limit": "20000", + "anthropic-ratelimit-requests-remaining": "19999", + "anthropic-ratelimit-requests-reset": "2026-05-21T06:48:39Z", + "anthropic-ratelimit-tokens-limit": "3600000", + "anthropic-ratelimit-tokens-remaining": "3599000", + "anthropic-ratelimit-tokens-reset": "2026-05-21T06:48:39Z", + "cache-control": "no-cache", + "cf-cache-status": "DYNAMIC", + "cf-ray": "9ff1a30038c95b94-VIE", + "connection": "keep-alive", + "content-encoding": "gzip", + "content-security-policy": "default-src 'none'; frame-ancestors 'none'", + "content-type": "text/event-stream; charset=utf-8", + "date": "Thu, 21 May 2026 06:48:41 GMT", + "request-id": "req_011CbFGToRH9Dj7DccSdji4e", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "traceresponse": "00-5adb360c6209ec709b5896e9afca02b1-3e5b34b916b3f3b1-01", + "transfer-encoding": "chunked", + "vary": "Accept-Encoding", + "x-envoy-upstream-service-time": "1389", + "x-robots-tag": "none" + }, + "status": 200, + "statusText": "OK" + } + }, + { + "callIndex": 3, + "id": "305957222aa1f6e9", + "matchKey": "POST api.anthropic.com/v1/messages", + "recordedAt": "2026-05-21T06:48:45.714Z", + "request": { + "body": { + "kind": "json", + "value": { + "max_tokens": 64000, + "messages": [ + { + "content": [ + { + "text": "Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "signature": "EoUGCm4IDRgCKkBGG1EQWIA9O/tsHYduxoTUS/i0gICgUs3GdrJlpnNSzO7qWVpXyAV/QYunxiJ/pbuy1AxKmw6zIb/6D5H7ZGWfMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMRXKds4wYcGMYouIkGgwZoj3tniSPvjyfUQ0iMJTYUR1cOzdSxBk9UN+23wtgAo9/8kEQNV+xOUHpUah0CvD2CK4e6+Mxn9U0PvwTTyrEBACjWEoJTpmbj0w1MNh5K+OwmDdBIpCbBeZgNfwk/5hZlooub3A2Da3jc6kIQPcSJAyzDcURqiosMVZblqqzxHM/aEXrQka5eZe/CELGEOZLcy2L0sRYjYzcKh+2/4hKScq3jltGM/MwmdE0y1P21raJdOxIpcXaIyQDncBiL9EQ3oPmRuhDHM9giLQaRdA8spWQs8P15X7ZcxxaVV4bI26aJoQa9/BoEBqDbNGNi0jPABVoEoUprtXqNJcl3lb4GUerTKVvEPlXluwJbN0ozQ3j9v8GGqqHlAe5J4WpjO3RA5CjKU6poKdB+CW2/MjTMA5noiDFJzqE5krdR/ll4UusUXFv+DYdLIXvm/RF/EGZa1FAmk+knqhbodSkL78m/AKpDOHNH9qymwstVSQP5IH8Xt6jE6olgXNLIHqmztPCsHYGoli+2FajT98T22xZJ/i9UPJyg+w800UtLCVzwa5Abx98Vodu7zyqZFAQ5HwWf9uY4f2T/tCjoPluiIZVb0nTUHziOnvsCpNQVWWi1eWMM6wUmfcki0TDlXaW2CNcBFSpmehGHwN3qjs2iDUG6w7MAo1hMjkKuUdalXTBqFbDa/EoEXIf4gpyNgXB0b5rzLGb8CisCONKT/PT788R7ZbjWrOqxtpIouGWqD0rvVgkGjBnuJ8EhIn1lkn1QXhqLZhcPsR7fal7rM2NRPVdD5fcI/NS9nIHo/Zx3i25gC0jd3hY+Eihl+f2C9K7f7kq78R2tUf62Sjc8XMy/QVWfsogYLIYAQ==", + "thinking": "The user wants me to complete an instrumented research flow with exactly three steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id to call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url to call summarize_source\n4. After that, reply with exactly \"PROMPT_DONE\"\n\nThe user also emphasizes that I should call exactly one tool per turn and wait for each tool result before choosing the next tool.\n\nLet me start with Step 1: calling lookup with query \"flue instrumentation\".", + "type": "thinking" + }, + { + "text": "I'll complete this instrumented research flow step by step. Starting with Step 1:", + "type": "text" + }, + { + "id": "toolu_01GD2k3M7867B4B2MdjCqVrG", + "input": { + "query": "flue instrumentation" + }, + "name": "lookup", + "type": "tool_use" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "content": "{\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}", + "is_error": false, + "tool_use_id": "toolu_01GD2k3M7867B4B2MdjCqVrG", + "type": "tool_result" + } + ], + "role": "user" + }, + { + "content": [ + { + "signature": "EpIDCm4IDRgCKkAGraaqPdHGE2HAbbEXcB/tBYIme5NcenLqHXnwfLjt8F2BUuO3FdH/1DhJ+cGEblVkRTDTtr6gwSbDyYOpIMTZMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIM0hkEt+QHz3frKV+dGgzBzyZSSik/kTiNJUIiMIXWT5AewGcoAk3E5CRsl/7bJoySRe2JV3p8Jv7ioYkJy08euGanth1HahprJhsG3irRAZ1GCOHuwJ6itCVds3y3W1r2Ksy1ShGPrOk0sXjC1RZXt3bTsQAQfi1AU0QaqlgI1RLzXRDhQEbTRQKa7UmMsbCBABlqQrh+90j6u3CqpkibXv5TwnyNlIl3aTBk+HQ+bPPdbQ/yagDMeMG4E4pEik7IFcKet39ynV6QCyTgcxrcgBJZ1uZb4mMxBPuPAwNqHCOdPDRMk8SVreU9PqR54j7fsuMnLBgV85AC8r1iI5cKo3MuhD6KcZG58ls3Yj3exA+XH2OauTFxaa0lDcEYmkAhGAE=", + "thinking": "Good, I got the lookup result with id \"flue-session-2026\". Now I need to proceed to Step 2: call web_search using this lookupId and the query \"Braintrust Flue reasoning stream instrumentation\".", + "type": "thinking" + }, + { + "text": "Now proceeding to Step 2:", + "type": "text" + }, + { + "id": "toolu_016VW8Z7PawkTryuu3wNMQZM", + "input": { + "lookupId": "flue-session-2026", + "query": "Braintrust Flue reasoning stream instrumentation" + }, + "name": "web_search", + "type": "tool_use" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "content": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\",\"results\":[{\"title\":\"Flue reasoning stream instrumentation\",\"url\":\"https://example.test/flue/reasoning-streams\"}]}", + "is_error": false, + "tool_use_id": "toolu_016VW8Z7PawkTryuu3wNMQZM", + "type": "tool_result" + } + ], + "role": "user" + }, + { + "content": [ + { + "signature": "EowDCm4IDRgCKkBAx8dB8EGMSxpAE1bkbv5IFMJcST9qVcl0KHwBXOCrtNNuK9rYk/fasBvKRf6NsyQU3hPl6KMhPmyo1RdgrlbyMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMemkNtsvVXGxVJiFJGgz6AuNoagcBoR2BOdgiMFUYr/5iFJKYgrBdik3Xu8ppJPGcUDuB6f4EI2N39i9sNQHVR8XBCvZaXwJqEILnsSrLAQ1TaPrVNMVCJ5ly8rltFaB3uEBGoaXmduyD/0NFlU6zSySG1hnGrY/tgcH3erm3AOCRJugGoDuSUEn301OxHooiKXGMh/2CsQ1LqQu1nwyrmbK/7+U/UtbouGJQaLkmoAfSWPDKm08zU6filkzdihRiWMkJ9wO/sqbtu8US3zxrIEqE+IPWGBJIHoncA1mAM7pPjqTPZEu4z5f69C0//fQszysmRRO2QejYfGu6m216yFGNwJnirhMFzlXbj5kU1FO21VQ8Wb6dAv0PGAE=", + "thinking": "Perfect! I got the web_search results. There's one result with the URL \"https://example.test/flue/reasoning-streams\". Now I need to proceed to Step 3: call summarize_source with this URL.", + "type": "thinking" + }, + { + "text": "Now proceeding to Step 3:", + "type": "text" + }, + { + "id": "toolu_01JvdxTjoCLCdYkoec6bWgVv", + "input": { + "url": "https://example.test/flue/reasoning-streams" + }, + "name": "summarize_source", + "type": "tool_use" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "cache_control": { + "type": "ephemeral" + }, + "content": "{\"summary\":\"Flue emits reasoning, tool execution, and LLM turn events separately.\",\"url\":\"https://example.test/flue/reasoning-streams\"}", + "is_error": false, + "tool_use_id": "toolu_01JvdxTjoCLCdYkoec6bWgVv", + "type": "tool_result" + } + ], + "role": "user" + } + ], + "model": "claude-sonnet-4-5-20250929", + "stream": true, + "system": [ + { + "cache_control": { + "type": "ephemeral" + }, + "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Thu, May 21, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-LqmoTW/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + "type": "text" + } + ], + "thinking": { + "budget_tokens": 8192, + "display": "summarized", + "type": "enabled" + }, + "tools": [ + { + "description": "Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "limit": { + "description": "Maximum number of lines to read", + "type": "number" + }, + "offset": { + "description": "Line number to start from (1-indexed)", + "type": "number" + }, + "path": { + "description": "Path to the file to read", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + }, + "name": "read" + }, + { + "description": "Write content to a file. Creates the file and parent directories if they do not exist.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Path to the file to write", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + }, + "name": "write" + }, + { + "description": "Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "newText": { + "description": "Replacement text", + "type": "string" + }, + "oldText": { + "description": "Exact text to find (must be unique)", + "type": "string" + }, + "path": { + "description": "Path to the file to edit", + "type": "string" + }, + "replaceAll": { + "description": "Replace all occurrences", + "type": "boolean" + } + }, + "required": ["path", "oldText", "newText"], + "type": "object" + }, + "name": "edit" + }, + { + "description": "Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "command": { + "description": "Bash command to execute", + "type": "string" + }, + "timeout": { + "description": "Timeout in seconds", + "type": "number" + } + }, + "required": ["command"], + "type": "object" + }, + "name": "bash" + }, + { + "description": "Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "include": { + "description": "Glob filter, e.g. \"*.ts\"", + "type": "string" + }, + "path": { + "description": "Directory or file to search (default: .)", + "type": "string" + }, + "pattern": { + "description": "Search pattern (regex)", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + }, + "name": "grep" + }, + { + "description": "Find files by filename pattern using shell find -name semantics. Returns matching file paths.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "path": { + "description": "Directory to search in (default: .)", + "type": "string" + }, + "pattern": { + "description": "Filename pattern, e.g. \"*.ts\"", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + }, + "name": "glob" + }, + { + "description": "Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "cwd": { + "description": "Working directory for the child agent. AGENTS.md and skills are discovered from here.", + "type": "string" + }, + "description": { + "description": "Short human-readable label for the delegated work", + "type": "string" + }, + "prompt": { + "description": "Focused instructions for the child agent", + "type": "string" + }, + "role": { + "description": "Role to use for the child agent", + "type": "string" + } + }, + "required": ["prompt"], + "type": "object" + }, + "name": "task" + }, + { + "description": "Return a deterministic lookup result with an id needed by web_search.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "query": { + "type": "string" + } + }, + "required": ["query"], + "type": "object" + }, + "name": "lookup" + }, + { + "description": "Search a deterministic local web index. Requires the id returned by lookup.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "lookupId": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": ["lookupId", "query"], + "type": "object" + }, + "name": "web_search" + }, + { + "cache_control": { + "type": "ephemeral" + }, + "description": "Summarize the selected deterministic source after web_search returns a URL.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "url": { + "type": "string" + } + }, + "required": ["url"], + "type": "object" + }, + "name": "summarize_source" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.anthropic.com/v1/messages" + }, + "response": { + "body": { + "chunks": [ + "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-5-20250929\",\"id\":\"msg_01HwXz99DRaxy131BhTvg7aL\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":13,\"cache_creation_input_tokens\":188,\"cache_read_input_tokens\":2673,\"cache_creation\":{\"ephemeral_5m_input_tokens\":188,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":3,\"service_tier\":\"standard\",\"inference_geo\":\"not_available\"}}}", + "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"thinking\",\"thinking\":\"\",\"signature\":\"\"}}", + "event: ping\ndata: {\"type\":\"ping\"}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\"Great! The\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\" summarize_source call has completed successfully. According to the instructions, I should now reply with exactly \\\"PROMPT_DONE\\\" and no other text.\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\"\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"signature_delta\",\"signature\":\"Eu0CCm4IDRgCKkCBUYqhsARXFm5YQdB8B4fq/pryhtdDMyve+qLrKjJqHD3e6i8qwtMvaYLPzEs5dagCGN78HUOXUIGRyxayFLsaMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMSAGOY3KKONucZdv2GgwbIH0DASkcx2PNO3IiMPgbDWU64PZih2E9L5bJKlJG3YlBOkpzlkj0KsH27P2yeVtf6gEKV1ym8v01eo+22SqsAZjELp8qSjTomJDJAbv93WPF4OwY0KKNhLiGYj3CGUOcybr7g+02AkHtaxp1YyYNtX1cXsUoTCPPAtGgW+4Mj6V48xqSppxoF67gzfoLd3DbqN1ZpCjcGTaOlEQwRdKZU7eUS81aRksb5Vb5tiQCHPG8f55AmRy0kn4eZ0LhQLm/qUQwRznV0EsNSrHdkozFlf4rUQS+BdDYgf+eECSpMoo7TX2P9lBg4h5EsREYAQ==\"}}", + "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0}", + "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":1,\"content_block\":{\"type\":\"text\",\"text\":\"\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"text_delta\",\"text\":\"PROMPT_DONE\"}}", + "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":1}", + "event: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":13,\"cache_creation_input_tokens\":188,\"cache_read_input_tokens\":2673,\"output_tokens\":51}}", + "event: message_stop\ndata: {\"type\":\"message_stop\"}" + ], + "kind": "sse" + }, + "headers": { + "anthropic-organization-id": "27796668-7351-40ac-acc4-024aee8995a5", + "anthropic-ratelimit-input-tokens-limit": "3000000", + "anthropic-ratelimit-input-tokens-remaining": "2998000", + "anthropic-ratelimit-input-tokens-reset": "2026-05-21T06:48:43Z", + "anthropic-ratelimit-output-tokens-limit": "600000", + "anthropic-ratelimit-output-tokens-remaining": "600000", + "anthropic-ratelimit-output-tokens-reset": "2026-05-21T06:48:43Z", + "anthropic-ratelimit-requests-limit": "20000", + "anthropic-ratelimit-requests-remaining": "19999", + "anthropic-ratelimit-requests-reset": "2026-05-21T06:48:43Z", + "anthropic-ratelimit-tokens-limit": "3600000", + "anthropic-ratelimit-tokens-remaining": "3598000", + "anthropic-ratelimit-tokens-reset": "2026-05-21T06:48:43Z", + "cache-control": "no-cache", + "cf-cache-status": "DYNAMIC", + "cf-ray": "9ff1a3145cd25b94-VIE", + "connection": "keep-alive", + "content-encoding": "gzip", + "content-security-policy": "default-src 'none'; frame-ancestors 'none'", + "content-type": "text/event-stream; charset=utf-8", + "date": "Thu, 21 May 2026 06:48:45 GMT", + "request-id": "req_011CbFGU3Bkpmx8QxaBcUhtq", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "traceresponse": "00-408b026ccc4d384d0269512a66aa3826-2c341f620252cb31-01", + "transfer-encoding": "chunked", + "vary": "Accept-Encoding", + "x-envoy-upstream-service-time": "1997", + "x-robots-tag": "none" + }, + "status": 200, + "statusText": "OK" + } + }, + { + "callIndex": 4, + "id": "3d93fe37f72a947f", + "matchKey": "POST api.anthropic.com/v1/messages", + "recordedAt": "2026-05-21T06:48:48.470Z", + "request": { + "body": { + "kind": "json", + "value": { + "max_tokens": 64000, + "messages": [ + { + "content": [ + { + "cache_control": { + "type": "ephemeral" + }, + "text": "Run the skill named \"e2e-flue-skill\".\n\nArguments:\n{\n \"marker\": \"SKILL_DONE\"\n}", + "type": "text" + } + ], + "role": "user" + } + ], + "model": "claude-sonnet-4-5-20250929", + "stream": true, + "system": [ + { + "cache_control": { + "type": "ephemeral" + }, + "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Thu, May 21, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-LqmoTW/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts\n\n\nNever call the task tool. Do not delegate e2e-flue-skill to another session. If you need the skill body, read .agents/skills/e2e-flue-skill/SKILL.md yourself with the read tool. Return the marker from the Arguments object exactly, with no other text.\n", + "type": "text" + } + ], + "thinking": { + "type": "disabled" + }, + "tools": [ + { + "description": "Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "limit": { + "description": "Maximum number of lines to read", + "type": "number" + }, + "offset": { + "description": "Line number to start from (1-indexed)", + "type": "number" + }, + "path": { + "description": "Path to the file to read", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + }, + "name": "read" + }, + { + "description": "Write content to a file. Creates the file and parent directories if they do not exist.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Path to the file to write", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + }, + "name": "write" + }, + { + "description": "Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "newText": { + "description": "Replacement text", + "type": "string" + }, + "oldText": { + "description": "Exact text to find (must be unique)", + "type": "string" + }, + "path": { + "description": "Path to the file to edit", + "type": "string" + }, + "replaceAll": { + "description": "Replace all occurrences", + "type": "boolean" + } + }, + "required": ["path", "oldText", "newText"], + "type": "object" + }, + "name": "edit" + }, + { + "description": "Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "command": { + "description": "Bash command to execute", + "type": "string" + }, + "timeout": { + "description": "Timeout in seconds", + "type": "number" + } + }, + "required": ["command"], + "type": "object" + }, + "name": "bash" + }, + { + "description": "Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "include": { + "description": "Glob filter, e.g. \"*.ts\"", + "type": "string" + }, + "path": { + "description": "Directory or file to search (default: .)", + "type": "string" + }, + "pattern": { + "description": "Search pattern (regex)", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + }, + "name": "grep" + }, + { + "description": "Find files by filename pattern using shell find -name semantics. Returns matching file paths.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "path": { + "description": "Directory to search in (default: .)", + "type": "string" + }, + "pattern": { + "description": "Filename pattern, e.g. \"*.ts\"", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + }, + "name": "glob" + }, + { + "cache_control": { + "type": "ephemeral" + }, + "description": "Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "cwd": { + "description": "Working directory for the child agent. AGENTS.md and skills are discovered from here.", + "type": "string" + }, + "description": { + "description": "Short human-readable label for the delegated work", + "type": "string" + }, + "prompt": { + "description": "Focused instructions for the child agent", + "type": "string" + }, + "role": { + "description": "Role to use for the child agent", + "type": "string" + } + }, + "required": ["prompt"], + "type": "object" + }, + "name": "task" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.anthropic.com/v1/messages" + }, + "response": { + "body": { + "chunks": [ + "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-5-20250929\",\"id\":\"msg_01JoaqaveV26zPPyn36eqMii\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":3,\"cache_creation_input_tokens\":716,\"cache_read_input_tokens\":1093,\"cache_creation\":{\"ephemeral_5m_input_tokens\":716,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":5,\"service_tier\":\"standard\",\"inference_geo\":\"not_available\"}}}", + "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"}}", + "event: ping\ndata: {\"type\":\"ping\"}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"I'll run the e\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"2e-flue-skill by reading its instructions and following them.\"}}", + "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0}", + "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":1,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01PD5NfHENNe1rtoqGk42TWG\",\"name\":\"read\",\"input\":{},\"caller\":{\"type\":\"direct\"}}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"path\\\": \\\".agents/skills/e2e-flue-skill/SKILL.md\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"}\"}}", + "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":1}", + "event: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":3,\"cache_creation_input_tokens\":716,\"cache_read_input_tokens\":1093,\"output_tokens\":89}}", + "event: message_stop\ndata: {\"type\":\"message_stop\"}" + ], + "kind": "sse" + }, + "headers": { + "anthropic-organization-id": "27796668-7351-40ac-acc4-024aee8995a5", + "anthropic-ratelimit-input-tokens-limit": "3000000", + "anthropic-ratelimit-input-tokens-remaining": "2999000", + "anthropic-ratelimit-input-tokens-reset": "2026-05-21T06:48:45Z", + "anthropic-ratelimit-output-tokens-limit": "600000", + "anthropic-ratelimit-output-tokens-remaining": "600000", + "anthropic-ratelimit-output-tokens-reset": "2026-05-21T06:48:45Z", + "anthropic-ratelimit-requests-limit": "20000", + "anthropic-ratelimit-requests-remaining": "19999", + "anthropic-ratelimit-requests-reset": "2026-05-21T06:48:45Z", + "anthropic-ratelimit-tokens-limit": "3600000", + "anthropic-ratelimit-tokens-remaining": "3599000", + "anthropic-ratelimit-tokens-reset": "2026-05-21T06:48:45Z", + "cache-control": "no-cache", + "cf-cache-status": "DYNAMIC", + "cf-ray": "9ff1a3261ce85b94-VIE", + "connection": "keep-alive", + "content-encoding": "gzip", + "content-security-policy": "default-src 'none'; frame-ancestors 'none'", + "content-type": "text/event-stream; charset=utf-8", + "date": "Thu, 21 May 2026 06:48:47 GMT", + "request-id": "req_011CbFGUFLzxnhHqjcYYgyca", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "traceresponse": "00-240fefcf6768b2ee326e503bca81b492-db5bae8e1a36da5d-01", + "transfer-encoding": "chunked", + "vary": "Accept-Encoding", + "x-envoy-upstream-service-time": "1635", + "x-robots-tag": "none" + }, + "status": 200, + "statusText": "OK" + } + }, + { + "callIndex": 5, + "id": "fb4ed2bb1569d980", + "matchKey": "POST api.anthropic.com/v1/messages", + "recordedAt": "2026-05-21T06:48:50.434Z", + "request": { + "body": { + "kind": "json", + "value": { + "max_tokens": 64000, + "messages": [ + { + "content": [ + { + "text": "Run the skill named \"e2e-flue-skill\".\n\nArguments:\n{\n \"marker\": \"SKILL_DONE\"\n}", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "text": "I'll run the e2e-flue-skill by reading its instructions and following them.", + "type": "text" + }, + { + "id": "toolu_01PD5NfHENNe1rtoqGk42TWG", + "input": { + "path": ".agents/skills/e2e-flue-skill/SKILL.md" + }, + "name": "read", + "type": "tool_use" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "cache_control": { + "type": "ephemeral" + }, + "content": "---\nname: e2e-flue-skill\ndescription: Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n---\n\nReturn the marker from the provided args exactly once. Output no other text.\n", + "is_error": false, + "tool_use_id": "toolu_01PD5NfHENNe1rtoqGk42TWG", + "type": "tool_result" + } + ], + "role": "user" + } + ], + "model": "claude-sonnet-4-5-20250929", + "stream": true, + "system": [ + { + "cache_control": { + "type": "ephemeral" + }, + "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Thu, May 21, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-LqmoTW/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts\n\n\nNever call the task tool. Do not delegate e2e-flue-skill to another session. If you need the skill body, read .agents/skills/e2e-flue-skill/SKILL.md yourself with the read tool. Return the marker from the Arguments object exactly, with no other text.\n", + "type": "text" + } + ], + "thinking": { + "type": "disabled" + }, + "tools": [ + { + "description": "Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "limit": { + "description": "Maximum number of lines to read", + "type": "number" + }, + "offset": { + "description": "Line number to start from (1-indexed)", + "type": "number" + }, + "path": { + "description": "Path to the file to read", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + }, + "name": "read" + }, + { + "description": "Write content to a file. Creates the file and parent directories if they do not exist.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Path to the file to write", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + }, + "name": "write" + }, + { + "description": "Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "newText": { + "description": "Replacement text", + "type": "string" + }, + "oldText": { + "description": "Exact text to find (must be unique)", + "type": "string" + }, + "path": { + "description": "Path to the file to edit", + "type": "string" + }, + "replaceAll": { + "description": "Replace all occurrences", + "type": "boolean" + } + }, + "required": ["path", "oldText", "newText"], + "type": "object" + }, + "name": "edit" + }, + { + "description": "Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "command": { + "description": "Bash command to execute", + "type": "string" + }, + "timeout": { + "description": "Timeout in seconds", + "type": "number" + } + }, + "required": ["command"], + "type": "object" + }, + "name": "bash" + }, + { + "description": "Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "include": { + "description": "Glob filter, e.g. \"*.ts\"", + "type": "string" + }, + "path": { + "description": "Directory or file to search (default: .)", + "type": "string" + }, + "pattern": { + "description": "Search pattern (regex)", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + }, + "name": "grep" + }, + { + "description": "Find files by filename pattern using shell find -name semantics. Returns matching file paths.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "path": { + "description": "Directory to search in (default: .)", + "type": "string" + }, + "pattern": { + "description": "Filename pattern, e.g. \"*.ts\"", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + }, + "name": "glob" + }, + { + "cache_control": { + "type": "ephemeral" + }, + "description": "Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "cwd": { + "description": "Working directory for the child agent. AGENTS.md and skills are discovered from here.", + "type": "string" + }, + "description": { + "description": "Short human-readable label for the delegated work", + "type": "string" + }, + "prompt": { + "description": "Focused instructions for the child agent", + "type": "string" + }, + "role": { + "description": "Role to use for the child agent", + "type": "string" + } + }, + "required": ["prompt"], + "type": "object" + }, + "name": "task" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.anthropic.com/v1/messages" + }, + "response": { + "body": { + "chunks": [ + "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-5-20250929\",\"id\":\"msg_011AmwNdKn8z3XPfujJbRjA3\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":6,\"cache_creation_input_tokens\":153,\"cache_read_input_tokens\":1809,\"cache_creation\":{\"ephemeral_5m_input_tokens\":153,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":7,\"service_tier\":\"standard\",\"inference_geo\":\"not_available\"}}}", + "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"}}", + "event: ping\ndata: {\"type\":\"ping\"}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"SKILL_DONE\"}}", + "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0}", + "event: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":6,\"cache_creation_input_tokens\":153,\"cache_read_input_tokens\":1809,\"output_tokens\":8}}", + "event: message_stop\ndata: {\"type\":\"message_stop\"}" + ], + "kind": "sse" + }, + "headers": { + "anthropic-organization-id": "27796668-7351-40ac-acc4-024aee8995a5", + "anthropic-ratelimit-input-tokens-limit": "3000000", + "anthropic-ratelimit-input-tokens-remaining": "2999000", + "anthropic-ratelimit-input-tokens-reset": "2026-05-21T06:48:48Z", + "anthropic-ratelimit-output-tokens-limit": "600000", + "anthropic-ratelimit-output-tokens-remaining": "600000", + "anthropic-ratelimit-output-tokens-reset": "2026-05-21T06:48:48Z", + "anthropic-ratelimit-requests-limit": "20000", + "anthropic-ratelimit-requests-remaining": "19999", + "anthropic-ratelimit-requests-reset": "2026-05-21T06:48:48Z", + "anthropic-ratelimit-tokens-limit": "3600000", + "anthropic-ratelimit-tokens-remaining": "3599000", + "anthropic-ratelimit-tokens-reset": "2026-05-21T06:48:48Z", + "cache-control": "no-cache", + "cf-cache-status": "DYNAMIC", + "cf-ray": "9ff1a3375ccc5b94-VIE", + "connection": "keep-alive", + "content-encoding": "gzip", + "content-security-policy": "default-src 'none'; frame-ancestors 'none'", + "content-type": "text/event-stream; charset=utf-8", + "date": "Thu, 21 May 2026 06:48:50 GMT", + "request-id": "req_011CbFGUT9etAvivisBwyd9k", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "traceresponse": "00-c3f1d31c1e9f55400e02f81a6b4dc844-2853195a6edda6de-01", + "transfer-encoding": "chunked", + "vary": "Accept-Encoding", + "x-envoy-upstream-service-time": "1692", + "x-robots-tag": "none" + }, + "status": 200, + "statusText": "OK" + } + }, + { + "callIndex": 0, + "id": "7c0e162d6794cf5d", + "matchKey": "POST api.openai.com/v1/responses", + "recordedAt": "2026-05-21T06:48:53.133Z", + "request": { + "body": { + "kind": "json", + "value": { + "input": [ + { + "content": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Thu, May 21, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-LqmoTW/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + "role": "system" + }, + { + "content": [ + { + "text": "Reply with exactly TASK_DONE and no other text.", + "type": "input_text" + } + ], + "role": "user" + } + ], + "model": "gpt-4o-mini", + "prompt_cache_key": "[REDACTED]", + "store": false, + "stream": true, + "tools": [ + { + "description": "Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.", + "name": "read", + "parameters": { + "properties": { + "limit": { + "description": "Maximum number of lines to read", + "type": "number" + }, + "offset": { + "description": "Line number to start from (1-indexed)", + "type": "number" + }, + "path": { + "description": "Path to the file to read", + "type": "string" + } + }, + "required": ["path"], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Write content to a file. Creates the file and parent directories if they do not exist.", + "name": "write", + "parameters": { + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Path to the file to write", + "type": "string" + } + }, + "required": ["path", "content"], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.", + "name": "edit", + "parameters": { + "properties": { + "newText": { + "description": "Replacement text", + "type": "string" + }, + "oldText": { + "description": "Exact text to find (must be unique)", + "type": "string" + }, + "path": { + "description": "Path to the file to edit", + "type": "string" + }, + "replaceAll": { + "description": "Replace all occurrences", + "type": "boolean" + } + }, + "required": ["path", "oldText", "newText"], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.", + "name": "bash", + "parameters": { + "properties": { + "command": { + "description": "Bash command to execute", + "type": "string" + }, + "timeout": { + "description": "Timeout in seconds", + "type": "number" + } + }, + "required": ["command"], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.", + "name": "grep", + "parameters": { + "properties": { + "include": { + "description": "Glob filter, e.g. \"*.ts\"", + "type": "string" + }, + "path": { + "description": "Directory or file to search (default: .)", + "type": "string" + }, + "pattern": { + "description": "Search pattern (regex)", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Find files by filename pattern using shell find -name semantics. Returns matching file paths.", + "name": "glob", + "parameters": { + "properties": { + "path": { + "description": "Directory to search in (default: .)", + "type": "string" + }, + "pattern": { + "description": "Filename pattern, e.g. \"*.ts\"", + "type": "string" + } + }, + "required": ["pattern"], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.", + "name": "task", + "parameters": { + "properties": { + "cwd": { + "description": "Working directory for the child agent. AGENTS.md and skills are discovered from here.", + "type": "string" + }, + "description": { + "description": "Short human-readable label for the delegated work", + "type": "string" + }, + "prompt": { + "description": "Focused instructions for the child agent", + "type": "string" + }, + "role": { + "description": "Role to use for the child agent", + "type": "string" + } + }, + "required": ["prompt"], + "type": "object" + }, + "strict": false, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/responses" + }, + "response": { + "body": { + "chunks": [ + "event: response.created\ndata: {\"type\":\"response.created\",\"response\":{\"id\":\"resp_096103382013eb85016a0eaad439ec81a285f2218da4217678\",\"object\":\"response\",\"created_at\":1779346132,\"status\":\"in_progress\",\"background\":false,\"completed_at\":null,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":null,\"instructions\":null,\"max_output_tokens\":null,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":\"flue-e2e-instance::default::task:task:3eb8d137-c6b5-45ef-968e-a7\",\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"auto\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[{\"type\":\"function\",\"description\":\"Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.\",\"name\":\"read\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to read\"},\"offset\":{\"type\":\"number\",\"description\":\"Line number to start from (1-indexed)\"},\"limit\":{\"type\":\"number\",\"description\":\"Maximum number of lines to read\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Write content to a file. Creates the file and parent directories if they do not exist.\",\"name\":\"write\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"content\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to write\"},\"content\":{\"type\":\"string\",\"description\":\"Content to write to the file\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.\",\"name\":\"edit\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"oldText\",\"newText\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to edit\"},\"oldText\":{\"type\":\"string\",\"description\":\"Exact text to find (must be unique)\"},\"newText\":{\"type\":\"string\",\"description\":\"Replacement text\"},\"replaceAll\":{\"type\":\"boolean\",\"description\":\"Replace all occurrences\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.\",\"name\":\"bash\",\"parameters\":{\"type\":\"object\",\"required\":[\"command\"],\"properties\":{\"command\":{\"type\":\"string\",\"description\":\"Bash command to execute\"},\"timeout\":{\"type\":\"number\",\"description\":\"Timeout in seconds\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.\",\"name\":\"grep\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Search pattern (regex)\"},\"path\":{\"type\":\"string\",\"description\":\"Directory or file to search (default: .)\"},\"include\":{\"type\":\"string\",\"description\":\"Glob filter, e.g. \\\"*.ts\\\"\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Find files by filename pattern using shell find -name semantics. Returns matching file paths.\",\"name\":\"glob\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Filename pattern, e.g. \\\"*.ts\\\"\"},\"path\":{\"type\":\"string\",\"description\":\"Directory to search in (default: .)\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.\",\"name\":\"task\",\"parameters\":{\"type\":\"object\",\"required\":[\"prompt\"],\"properties\":{\"description\":{\"type\":\"string\",\"description\":\"Short human-readable label for the delegated work\"},\"prompt\":{\"type\":\"string\",\"description\":\"Focused instructions for the child agent\"},\"role\":{\"type\":\"string\",\"description\":\"Role to use for the child agent\"},\"cwd\":{\"type\":\"string\",\"description\":\"Working directory for the child agent. AGENTS.md and skills are discovered from here.\"}}},\"strict\":false}],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":null,\"user\":null,\"metadata\":{}},\"sequence_number\":0}", + "event: response.in_progress\ndata: {\"type\":\"response.in_progress\",\"response\":{\"id\":\"resp_096103382013eb85016a0eaad439ec81a285f2218da4217678\",\"object\":\"response\",\"created_at\":1779346132,\"status\":\"in_progress\",\"background\":false,\"completed_at\":null,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":null,\"instructions\":null,\"max_output_tokens\":null,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":\"flue-e2e-instance::default::task:task:3eb8d137-c6b5-45ef-968e-a7\",\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"auto\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[{\"type\":\"function\",\"description\":\"Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.\",\"name\":\"read\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to read\"},\"offset\":{\"type\":\"number\",\"description\":\"Line number to start from (1-indexed)\"},\"limit\":{\"type\":\"number\",\"description\":\"Maximum number of lines to read\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Write content to a file. Creates the file and parent directories if they do not exist.\",\"name\":\"write\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"content\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to write\"},\"content\":{\"type\":\"string\",\"description\":\"Content to write to the file\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.\",\"name\":\"edit\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"oldText\",\"newText\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to edit\"},\"oldText\":{\"type\":\"string\",\"description\":\"Exact text to find (must be unique)\"},\"newText\":{\"type\":\"string\",\"description\":\"Replacement text\"},\"replaceAll\":{\"type\":\"boolean\",\"description\":\"Replace all occurrences\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.\",\"name\":\"bash\",\"parameters\":{\"type\":\"object\",\"required\":[\"command\"],\"properties\":{\"command\":{\"type\":\"string\",\"description\":\"Bash command to execute\"},\"timeout\":{\"type\":\"number\",\"description\":\"Timeout in seconds\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.\",\"name\":\"grep\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Search pattern (regex)\"},\"path\":{\"type\":\"string\",\"description\":\"Directory or file to search (default: .)\"},\"include\":{\"type\":\"string\",\"description\":\"Glob filter, e.g. \\\"*.ts\\\"\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Find files by filename pattern using shell find -name semantics. Returns matching file paths.\",\"name\":\"glob\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Filename pattern, e.g. \\\"*.ts\\\"\"},\"path\":{\"type\":\"string\",\"description\":\"Directory to search in (default: .)\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.\",\"name\":\"task\",\"parameters\":{\"type\":\"object\",\"required\":[\"prompt\"],\"properties\":{\"description\":{\"type\":\"string\",\"description\":\"Short human-readable label for the delegated work\"},\"prompt\":{\"type\":\"string\",\"description\":\"Focused instructions for the child agent\"},\"role\":{\"type\":\"string\",\"description\":\"Role to use for the child agent\"},\"cwd\":{\"type\":\"string\",\"description\":\"Working directory for the child agent. AGENTS.md and skills are discovered from here.\"}}},\"strict\":false}],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":null,\"user\":null,\"metadata\":{}},\"sequence_number\":1}", + "event: response.output_item.added\ndata: {\"type\":\"response.output_item.added\",\"item\":{\"id\":\"msg_096103382013eb85016a0eaad4da7081a2aff38723fc8bb352\",\"type\":\"message\",\"status\":\"in_progress\",\"content\":[],\"role\":\"assistant\"},\"output_index\":0,\"sequence_number\":2}", + "event: response.content_part.added\ndata: {\"type\":\"response.content_part.added\",\"content_index\":0,\"item_id\":\"msg_096103382013eb85016a0eaad4da7081a2aff38723fc8bb352\",\"output_index\":0,\"part\":{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"\"},\"sequence_number\":3}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"TASK\",\"item_id\":\"msg_096103382013eb85016a0eaad4da7081a2aff38723fc8bb352\",\"logprobs\":[],\"obfuscation\":\"fpYfkU75RFuY\",\"output_index\":0,\"sequence_number\":4}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"_DONE\",\"item_id\":\"msg_096103382013eb85016a0eaad4da7081a2aff38723fc8bb352\",\"logprobs\":[],\"obfuscation\":\"n7VXctSvkaB\",\"output_index\":0,\"sequence_number\":5}", + "event: response.output_text.done\ndata: {\"type\":\"response.output_text.done\",\"content_index\":0,\"item_id\":\"msg_096103382013eb85016a0eaad4da7081a2aff38723fc8bb352\",\"logprobs\":[],\"output_index\":0,\"sequence_number\":6,\"text\":\"TASK_DONE\"}", + "event: response.content_part.done\ndata: {\"type\":\"response.content_part.done\",\"content_index\":0,\"item_id\":\"msg_096103382013eb85016a0eaad4da7081a2aff38723fc8bb352\",\"output_index\":0,\"part\":{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"TASK_DONE\"},\"sequence_number\":7}", + "event: response.output_item.done\ndata: {\"type\":\"response.output_item.done\",\"item\":{\"id\":\"msg_096103382013eb85016a0eaad4da7081a2aff38723fc8bb352\",\"type\":\"message\",\"status\":\"completed\",\"content\":[{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"TASK_DONE\"}],\"role\":\"assistant\"},\"output_index\":0,\"sequence_number\":8}", + "event: response.completed\ndata: {\"type\":\"response.completed\",\"response\":{\"id\":\"resp_096103382013eb85016a0eaad439ec81a285f2218da4217678\",\"object\":\"response\",\"created_at\":1779346132,\"status\":\"completed\",\"background\":false,\"completed_at\":1779346132,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":null,\"instructions\":null,\"max_output_tokens\":null,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[{\"id\":\"msg_096103382013eb85016a0eaad4da7081a2aff38723fc8bb352\",\"type\":\"message\",\"status\":\"completed\",\"content\":[{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"TASK_DONE\"}],\"role\":\"assistant\"}],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":\"flue-e2e-instance::default::task:task:3eb8d137-c6b5-45ef-968e-a7\",\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"default\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[{\"type\":\"function\",\"description\":\"Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.\",\"name\":\"read\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to read\"},\"offset\":{\"type\":\"number\",\"description\":\"Line number to start from (1-indexed)\"},\"limit\":{\"type\":\"number\",\"description\":\"Maximum number of lines to read\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Write content to a file. Creates the file and parent directories if they do not exist.\",\"name\":\"write\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"content\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to write\"},\"content\":{\"type\":\"string\",\"description\":\"Content to write to the file\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.\",\"name\":\"edit\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"oldText\",\"newText\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to edit\"},\"oldText\":{\"type\":\"string\",\"description\":\"Exact text to find (must be unique)\"},\"newText\":{\"type\":\"string\",\"description\":\"Replacement text\"},\"replaceAll\":{\"type\":\"boolean\",\"description\":\"Replace all occurrences\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.\",\"name\":\"bash\",\"parameters\":{\"type\":\"object\",\"required\":[\"command\"],\"properties\":{\"command\":{\"type\":\"string\",\"description\":\"Bash command to execute\"},\"timeout\":{\"type\":\"number\",\"description\":\"Timeout in seconds\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.\",\"name\":\"grep\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Search pattern (regex)\"},\"path\":{\"type\":\"string\",\"description\":\"Directory or file to search (default: .)\"},\"include\":{\"type\":\"string\",\"description\":\"Glob filter, e.g. \\\"*.ts\\\"\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Find files by filename pattern using shell find -name semantics. Returns matching file paths.\",\"name\":\"glob\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Filename pattern, e.g. \\\"*.ts\\\"\"},\"path\":{\"type\":\"string\",\"description\":\"Directory to search in (default: .)\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.\",\"name\":\"task\",\"parameters\":{\"type\":\"object\",\"required\":[\"prompt\"],\"properties\":{\"description\":{\"type\":\"string\",\"description\":\"Short human-readable label for the delegated work\"},\"prompt\":{\"type\":\"string\",\"description\":\"Focused instructions for the child agent\"},\"role\":{\"type\":\"string\",\"description\":\"Role to use for the child agent\"},\"cwd\":{\"type\":\"string\",\"description\":\"Working directory for the child agent. AGENTS.md and skills are discovered from here.\"}}},\"strict\":false}],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":{\"input_tokens\":770,\"input_tokens_details\":{\"cached_tokens\":0},\"output_tokens\":4,\"output_tokens_details\":{\"reasoning_tokens\":0},\"total_tokens\":774},\"user\":null,\"metadata\":{}},\"sequence_number\":9}" + ], + "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": "9ff1a34b8d2fc2e1-VIE", + "connection": "keep-alive", + "content-type": "text/event-stream; charset=utf-8", + "date": "Thu, 21 May 2026 06:48:52 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "275", + "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-request-id": "req_be83807190d94355ac6fd63b2891b416" + }, + "status": 200, + "statusText": "OK" + } + }, + { + "callIndex": 1, + "id": "f12aff3913439248", + "matchKey": "POST api.openai.com/v1/responses", + "recordedAt": "2026-05-21T06:48:54.176Z", + "request": { + "body": { + "kind": "json", + "value": { + "input": [ + { + "content": "You are a context summarization assistant. Your task is to read a conversation between a user and an AI coding assistant, then produce a structured summary following the exact format specified.\n\nDo NOT continue the conversation. Do NOT respond to any questions in the conversation. ONLY output the structured summary.", + "role": "system" + }, + { + "content": [ + { + "text": "\n[User]: Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.\n\n[Assistant thinking]: The user wants me to complete an instrumented research flow with exactly three steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id to call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url to call summarize_source\n4. After that, reply with exactly \"PROMPT_DONE\"\n\nThe user also emphasizes that I should call exactly one tool per turn and wait for each tool result before choosing the next tool.\n\nLet me start with Step 1: calling lookup with query \"flue instrumentation\".\n\n[Assistant]: I'll complete this instrumented research flow step by step. Starting with Step 1:\n\n[Assistant tool calls]: lookup(query=\"flue instrumentation\")\n\n[Tool result]: {\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}\n\n[Assistant thinking]: Good, I got the lookup result with id \"flue-session-2026\". Now I need to proceed to Step 2: call web_search using this lookupId and the query \"Braintrust Flue reasoning stream instrumentation\".\n\n[Assistant]: Now proceeding to Step 2:\n\n[Assistant tool calls]: web_search(lookupId=\"flue-session-2026\", query=\"Braintrust Flue reasoning stream instrumentation\")\n\n[Tool result]: {\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\",\"results\":[{\"title\":\"Flue reasoning stream instrumentation\",\"url\":\"https://example.test/flue/reasoning-streams\"}]}\n\n[Assistant thinking]: Perfect! I got the web_search results. There's one result with the URL \"https://example.test/flue/reasoning-streams\". Now I need to proceed to Step 3: call summarize_source with this URL.\n\n[Assistant]: Now proceeding to Step 3:\n\n[Assistant tool calls]: summarize_source(url=\"https://example.test/flue/reasoning-streams\")\n\n[Tool result]: {\"summary\":\"Flue emits reasoning, tool execution, and LLM turn events separately.\",\"url\":\"https://example.test/flue/reasoning-streams\"}\n\n\nThis is the PREFIX of a turn that was too large to keep. The SUFFIX (recent work) is retained.\n\nSummarize the prefix to provide context for the retained suffix:\n\n## Original Request\n[What did the user ask for in this turn?]\n\n## Early Progress\n- [Key decisions and work done in the prefix]\n\n## Context for Suffix\n- [Information needed to understand the retained recent work]\n\nBe concise. Focus on what's needed to understand the kept suffix.", + "type": "input_text" + } + ], + "role": "user" + } + ], + "max_output_tokens": 32, + "model": "gpt-4o-mini", + "store": false, + "stream": true + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/responses" + }, + "response": { + "body": { + "chunks": [ + "event: response.created\ndata: {\"type\":\"response.created\",\"response\":{\"id\":\"resp_0bad5a1de3e678f7016a0eaad5534c81959938a717dfba279b\",\"object\":\"response\",\"created_at\":1779346133,\"status\":\"in_progress\",\"background\":false,\"completed_at\":null,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":null,\"instructions\":null,\"max_output_tokens\":32,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":null,\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"auto\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":null,\"user\":null,\"metadata\":{}},\"sequence_number\":0}", + "event: response.in_progress\ndata: {\"type\":\"response.in_progress\",\"response\":{\"id\":\"resp_0bad5a1de3e678f7016a0eaad5534c81959938a717dfba279b\",\"object\":\"response\",\"created_at\":1779346133,\"status\":\"in_progress\",\"background\":false,\"completed_at\":null,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":null,\"instructions\":null,\"max_output_tokens\":32,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":null,\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"auto\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":null,\"user\":null,\"metadata\":{}},\"sequence_number\":1}", + "event: response.output_item.added\ndata: {\"type\":\"response.output_item.added\",\"item\":{\"id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"type\":\"message\",\"status\":\"in_progress\",\"content\":[],\"role\":\"assistant\"},\"output_index\":0,\"sequence_number\":2}", + "event: response.content_part.added\ndata: {\"type\":\"response.content_part.added\",\"content_index\":0,\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"output_index\":0,\"part\":{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"\"},\"sequence_number\":3}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"##\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"ZPu7BY4Of9RVt1\",\"output_index\":0,\"sequence_number\":4}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" Original\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"NTCRLVI\",\"output_index\":0,\"sequence_number\":5}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" Request\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"lvHw79ol\",\"output_index\":0,\"sequence_number\":6}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"\\n\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"qgDK72d0DqJzShe\",\"output_index\":0,\"sequence_number\":7}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"The\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"zxiLObn7xQuJc\",\"output_index\":0,\"sequence_number\":8}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" user\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"ZmDPVxDahg1\",\"output_index\":0,\"sequence_number\":9}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" asked\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"juGAL5bL8H\",\"output_index\":0,\"sequence_number\":10}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" for\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"UqT8QyGWJ1Cs\",\"output_index\":0,\"sequence_number\":11}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" a\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"ZFz9DG88CCg2d0\",\"output_index\":0,\"sequence_number\":12}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" step\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"FtIRl6vb8rh\",\"output_index\":0,\"sequence_number\":13}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"-by\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"fVbs7xkoxEmPY\",\"output_index\":0,\"sequence_number\":14}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"-step\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"JRwkU4V2Oy5\",\"output_index\":0,\"sequence_number\":15}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" completion\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"mSb47\",\"output_index\":0,\"sequence_number\":16}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" of\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"cSzEvYcwXoDYU\",\"output_index\":0,\"sequence_number\":17}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" an\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"v0eKIIYEcUvcM\",\"output_index\":0,\"sequence_number\":18}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" instrument\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"Tjoqr\",\"output_index\":0,\"sequence_number\":19}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"ed\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"PjMtpfwUF0hHJt\",\"output_index\":0,\"sequence_number\":20}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" research\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"dUx9fbZ\",\"output_index\":0,\"sequence_number\":21}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" flow\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"QrmkD9iirTC\",\"output_index\":0,\"sequence_number\":22}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" involving\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"GgVVoR\",\"output_index\":0,\"sequence_number\":23}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" lookup\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"jbRyl42fm\",\"output_index\":0,\"sequence_number\":24}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\",\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"M1ztdjqKpVB87HF\",\"output_index\":0,\"sequence_number\":25}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" web\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"mIXL607CP0CD\",\"output_index\":0,\"sequence_number\":26}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" search\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"8dBYoFevC\",\"output_index\":0,\"sequence_number\":27}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\",\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"ESNpvnq3vrWxNgG\",\"output_index\":0,\"sequence_number\":28}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" and\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"vxNZIlXgihwA\",\"output_index\":0,\"sequence_number\":29}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" summar\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"LvmNVHkMr\",\"output_index\":0,\"sequence_number\":30}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"ization\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"vuIOLbmmg\",\"output_index\":0,\"sequence_number\":31}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\".\\n\\n\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"bSs8GprnEKUEZ\",\"output_index\":0,\"sequence_number\":32}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"##\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"o50Zp3Jj2IWoZb\",\"output_index\":0,\"sequence_number\":33}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" Early\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"oJYzY8lvrF\",\"output_index\":0,\"sequence_number\":34}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" Progress\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"JwRxUVU\",\"output_index\":0,\"sequence_number\":35}", + "event: response.output_text.done\ndata: {\"type\":\"response.output_text.done\",\"content_index\":0,\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"output_index\":0,\"sequence_number\":36,\"text\":\"## Original Request\\nThe user asked for a step-by-step completion of an instrumented research flow involving lookup, web search, and summarization.\\n\\n## Early Progress\"}", + "event: response.content_part.done\ndata: {\"type\":\"response.content_part.done\",\"content_index\":0,\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"output_index\":0,\"part\":{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"## Original Request\\nThe user asked for a step-by-step completion of an instrumented research flow involving lookup, web search, and summarization.\\n\\n## Early Progress\"},\"sequence_number\":37}", + "event: response.output_item.done\ndata: {\"type\":\"response.output_item.done\",\"item\":{\"id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"type\":\"message\",\"status\":\"incomplete\",\"content\":[{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"## Original Request\\nThe user asked for a step-by-step completion of an instrumented research flow involving lookup, web search, and summarization.\\n\\n## Early Progress\"}],\"role\":\"assistant\"},\"output_index\":0,\"sequence_number\":38}", + "event: response.incomplete\ndata: {\"type\":\"response.incomplete\",\"response\":{\"id\":\"resp_0bad5a1de3e678f7016a0eaad5534c81959938a717dfba279b\",\"object\":\"response\",\"created_at\":1779346133,\"status\":\"incomplete\",\"background\":false,\"completed_at\":null,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":{\"reason\":\"max_output_tokens\"},\"instructions\":null,\"max_output_tokens\":32,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[{\"id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"type\":\"message\",\"status\":\"incomplete\",\"content\":[{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"## Original Request\\nThe user asked for a step-by-step completion of an instrumented research flow involving lookup, web search, and summarization.\\n\\n## Early Progress\"}],\"role\":\"assistant\"}],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":null,\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"default\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":{\"input_tokens\":707,\"input_tokens_details\":{\"cached_tokens\":0},\"output_tokens\":32,\"output_tokens_details\":{\"reasoning_tokens\":0},\"total_tokens\":739},\"user\":null,\"metadata\":{}},\"sequence_number\":39}" + ], + "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": "9ff1a3548f88c2e1-VIE", + "connection": "keep-alive", + "content-type": "text/event-stream; charset=utf-8", + "date": "Thu, 21 May 2026 06:48:53 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "184", + "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-request-id": "req_32645668215e477d8c3d40610baa18b7" + }, + "status": 200, + "statusText": "OK" + } + } + ], + "meta": { + "createdAt": "2026-05-20T19:14:48.342Z" + } +} diff --git a/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-auto-hook.span-tree.json b/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-auto-hook.span-tree.json new file mode 100644 index 000000000..6ecd8cb36 --- /dev/null +++ b/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-auto-hook.span-tree.json @@ -0,0 +1,552 @@ +{ + "span_tree": [ + { + "name": "flue-root", + "type": "task", + "children": [ + { + "name": "flue-prompt-operation", + "children": [ + { + "name": "flue.session.prompt", + "type": "task", + "children": [ + { + "name": "flue.turn", + "type": "llm", + "children": [], + "output": [ + { + "finish_reason": "toolUse", + "index": 0, + "message": { + "content": "I'll complete this instrumented research flow step by step. Starting with Step 1:", + "reasoning": "The user wants me to complete a specific instrumented research flow with three steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id to call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url to call summarize_source\n4. Reply with exactly \"PROMPT_DONE\" after summarize_source returns\n\nThe user emphasizes calling exactly one tool per turn and waiting for each result. Let me start with step 1.", + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"query\":\"flue instrumentation\"}", + "name": "lookup" + }, + "id": "", + "type": "function" + } + ] + } + } + ], + "metadata": { + "flue.model": "claude-sonnet-4-5-20250929", + "flue.session": "main", + "flue.thinking": true, + "model": "claude-sonnet-4-5-20250929", + "provider": "flue" + }, + "metrics": { + "completion_tokens": 199, + "duration_ms": 0, + "estimated_cost": 0.0036696000000000003, + "prompt_cache_creation_tokens": 0, + "prompt_cached_tokens": 2182, + "prompt_tokens": 10, + "tokens": 2391 + } + }, + { + "name": "tool: lookup", + "type": "tool", + "children": [], + "input": { + "query": "flue instrumentation" + }, + "output": { + "content": [ + { + "text": "{\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}", + "type": "text" + } + ], + "details": { + "customTool": "lookup" + } + }, + "metadata": { + "flue.session": "main", + "flue.tool_name": "lookup", + "provider": "flue" + }, + "metrics": { + "duration_ms": 0 + } + }, + { + "name": "flue.turn", + "type": "llm", + "children": [], + "output": [ + { + "finish_reason": "toolUse", + "index": 0, + "message": { + "content": "Now proceeding to Step 2:", + "reasoning": "Good, I got the lookup result with id \"flue-session-2026\". Now I'll proceed to step 2 and use this id as the lookupId parameter in the web_search call with the specified query.", + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\"}", + "name": "web_search" + }, + "id": "", + "type": "function" + } + ] + } + } + ], + "metadata": { + "flue.model": "claude-sonnet-4-5-20250929", + "flue.session": "main", + "flue.thinking": true, + "model": "claude-sonnet-4-5-20250929", + "provider": "flue" + }, + "metrics": { + "completion_tokens": 153, + "duration_ms": 0, + "estimated_cost": 0.00388485, + "prompt_cache_creation_tokens": 239, + "prompt_cached_tokens": 2182, + "prompt_tokens": 13, + "tokens": 2587 + } + }, + { + "name": "tool: web_search", + "type": "tool", + "children": [], + "input": { + "lookupId": "flue-session-2026", + "query": "Braintrust Flue reasoning stream instrumentation" + }, + "output": { + "content": [ + { + "text": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\",\"results\":[{\"title\":\"Flue reasoning stream instrumentation\",\"url\":\"https://example.test/flue/reasoning-streams\"}]}", + "type": "text" + } + ], + "details": { + "customTool": "web_search" + } + }, + "metadata": { + "flue.session": "main", + "flue.tool_name": "web_search", + "provider": "flue" + }, + "metrics": { + "duration_ms": 0 + } + }, + { + "name": "flue.turn", + "type": "llm", + "children": [], + "output": [ + { + "finish_reason": "toolUse", + "index": 0, + "message": { + "content": "Now proceeding to Step 3:", + "reasoning": "Perfect! I got the web_search results. There's one result with the URL \"https://example.test/flue/reasoning-streams\". Now I need to proceed to step 3 and call summarize_source with this URL.", + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"url\":\"https://example.test/flue/reasoning-streams\"}", + "name": "summarize_source" + }, + "id": "", + "type": "function" + } + ] + } + } + ], + "metadata": { + "flue.model": "claude-sonnet-4-5-20250929", + "flue.session": "main", + "flue.thinking": true, + "model": "claude-sonnet-4-5-20250929", + "provider": "flue" + }, + "metrics": { + "completion_tokens": 133, + "duration_ms": 0, + "estimated_cost": 0.0036190500000000004, + "prompt_cache_creation_tokens": 229, + "prompt_cached_tokens": 2421, + "prompt_tokens": 13, + "tokens": 2796 + } + }, + { + "name": "tool: summarize_source", + "type": "tool", + "children": [], + "input": { + "url": "https://example.test/flue/reasoning-streams" + }, + "output": { + "content": [ + { + "text": "{\"summary\":\"Flue emits reasoning, tool execution, and LLM turn events separately.\",\"url\":\"https://example.test/flue/reasoning-streams\"}", + "type": "text" + } + ], + "details": { + "customTool": "summarize_source" + } + }, + "metadata": { + "flue.session": "main", + "flue.tool_name": "summarize_source", + "provider": "flue" + }, + "metrics": { + "duration_ms": 0 + } + }, + { + "name": "flue.turn", + "type": "llm", + "children": [], + "output": [ + { + "finish_reason": "stop", + "index": 0, + "message": { + "content": "PROMPT_DONE", + "reasoning": "Perfect! The summarize_source has returned. According to the instructions, I should now reply with exactly \"PROMPT_DONE\" and no other text.", + "role": "assistant" + } + } + ], + "metadata": { + "flue.model": "claude-sonnet-4-5-20250929", + "flue.session": "main", + "flue.thinking": true, + "model": "claude-sonnet-4-5-20250929", + "provider": "flue" + }, + "metrics": { + "completion_tokens": 49, + "duration_ms": 0, + "estimated_cost": 0.00227775, + "prompt_cache_creation_tokens": 189, + "prompt_cached_tokens": 2650, + "prompt_tokens": 13, + "tokens": 2901 + } + } + ], + "input": "Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.", + "output": "PROMPT_DONE", + "metadata": { + "flue.model": "claude-sonnet-4-5-20250929", + "flue.operation": "prompt", + "flue.session": "main", + "flue.thinking_level": "medium", + "flue.tools_count": 3, + "model": "claude-sonnet-4-5-20250929", + "provider": "flue" + }, + "metrics": { + "completion_tokens": 534, + "duration_ms": 0, + "estimated_cost": 0.013451250000000001, + "prompt_cache_creation_tokens": 657, + "prompt_cached_tokens": 9435, + "prompt_tokens": 49, + "tokens": 10675 + } + } + ], + "metadata": { + "operation": "prompt" + } + }, + { + "name": "flue-skill-operation", + "children": [ + { + "name": "flue.session.skill", + "type": "task", + "children": [ + { + "name": "flue.turn", + "type": "llm", + "children": [], + "output": [ + { + "finish_reason": "toolUse", + "index": 0, + "message": { + "content": "I'll run the e2e-flue-skill by reading its instructions and following them.", + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"path\":\".agents/skills/e2e-flue-skill/SKILL.md\"}", + "name": "read" + }, + "id": "", + "type": "function" + } + ] + } + } + ], + "metadata": { + "flue.model": "claude-sonnet-4-5-20250929", + "flue.session": "skill", + "model": "claude-sonnet-4-5-20250929", + "provider": "flue" + }, + "metrics": { + "completion_tokens": 89, + "duration_ms": 0, + "estimated_cost": 0.0018866999999999998, + "prompt_cache_creation_tokens": 0, + "prompt_cached_tokens": 1809, + "prompt_tokens": 3, + "tokens": 1901 + } + }, + { + "name": "tool: read", + "type": "tool", + "children": [], + "input": { + "path": ".agents/skills/e2e-flue-skill/SKILL.md" + }, + "output": { + "content": [ + { + "text": "---\nname: e2e-flue-skill\ndescription: Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n---\n\nReturn the marker from the provided args exactly once. Output no other text.\n", + "type": "text" + } + ], + "details": { + "lines": 7, + "path": ".agents/skills/e2e-flue-skill/SKILL.md" + } + }, + "metadata": { + "flue.session": "skill", + "flue.tool_name": "read", + "provider": "flue" + }, + "metrics": { + "duration_ms": 0 + } + }, + { + "name": "flue.turn", + "type": "llm", + "children": [], + "output": [ + { + "finish_reason": "stop", + "index": 0, + "message": { + "content": "SKILL_DONE", + "role": "assistant" + } + } + ], + "metadata": { + "flue.model": "claude-sonnet-4-5-20250929", + "flue.session": "skill", + "model": "claude-sonnet-4-5-20250929", + "provider": "flue" + }, + "metrics": { + "completion_tokens": 8, + "duration_ms": 0, + "estimated_cost": 0.0007266, + "prompt_cache_creation_tokens": 0, + "prompt_cached_tokens": 1962, + "prompt_tokens": 6, + "tokens": 1976 + } + } + ], + "input": { + "args": { + "marker": "SKILL_DONE" + }, + "name": "e2e-flue-skill" + }, + "output": "SKILL_DONE", + "metadata": { + "flue.model": "claude-sonnet-4-5-20250929", + "flue.operation": "skill", + "flue.role": "skillRunner", + "flue.session": "skill", + "flue.skill_name": "e2e-flue-skill", + "flue.thinking_level": "off", + "model": "claude-sonnet-4-5-20250929", + "provider": "flue" + }, + "metrics": { + "completion_tokens": 97, + "duration_ms": 0, + "estimated_cost": 0.0026133, + "prompt_cache_creation_tokens": 0, + "prompt_cached_tokens": 3771, + "prompt_tokens": 9, + "tokens": 3877 + } + } + ], + "metadata": { + "operation": "skill" + } + }, + { + "name": "flue-task-operation", + "children": [ + { + "name": "flue.session.task", + "type": "task", + "children": [ + { + "name": "flue.task", + "type": "task", + "children": [ + { + "name": "flue.turn", + "type": "llm", + "children": [], + "output": [ + { + "finish_reason": "stop", + "index": 0, + "message": { + "content": "TASK_DONE", + "role": "assistant" + } + } + ], + "metadata": { + "flue.model": "gpt-4o-mini", + "flue.session": "task:task:", + "model": "gpt-4o-mini", + "provider": "flue" + }, + "metrics": { + "completion_tokens": 4, + "duration_ms": 0, + "estimated_cost": 0.00011789999999999999, + "prompt_cache_creation_tokens": 0, + "prompt_cached_tokens": 0, + "prompt_tokens": 770, + "tokens": 774 + } + } + ], + "input": "Reply with exactly TASK_DONE and no other text.", + "output": "TASK_DONE", + "metadata": { + "flue.session": "task", + "provider": "flue" + }, + "metrics": { + "duration_ms": 0 + } + } + ], + "input": "Reply with exactly TASK_DONE and no other text.", + "output": "TASK_DONE", + "metadata": { + "flue.model": "gpt-4o-mini", + "flue.operation": "task", + "flue.session": "task", + "flue.thinking_level": "off", + "model": "gpt-4o-mini", + "provider": "flue" + }, + "metrics": { + "completion_tokens": 4, + "duration_ms": 0, + "estimated_cost": 0.00011789999999999999, + "prompt_cache_creation_tokens": 0, + "prompt_cached_tokens": 0, + "prompt_tokens": 770, + "tokens": 774 + } + } + ], + "metadata": { + "operation": "task" + } + }, + { + "name": "flue-compact-operation", + "children": [ + { + "name": "flue.session.compact", + "type": "task", + "children": [ + { + "name": "flue.compaction", + "type": "task", + "children": [], + "input": { + "estimatedTokens": 2901, + "reason": "manual" + }, + "output": { + "messagesAfter": 2, + "messagesBefore": 8 + }, + "metadata": { + "flue.compaction_reason": "manual", + "flue.session": "main", + "provider": "flue" + }, + "metrics": { + "completion_tokens": 0, + "duration_ms": 0, + "estimated_cost": 0, + "prompt_cache_creation_tokens": 0, + "prompt_cached_tokens": 0, + "prompt_tokens": 0, + "tokens": 0 + } + } + ], + "metadata": { + "flue.operation": "compact", + "flue.session": "main", + "provider": "flue" + }, + "metrics": { + "duration_ms": 0 + } + } + ], + "metadata": { + "operation": "compact" + } + } + ], + "metadata": { + "scenario": "flue-instrumentation" + } + } + ] +} diff --git a/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-auto-hook.span-tree.txt b/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-auto-hook.span-tree.txt new file mode 100644 index 000000000..5a000aebd --- /dev/null +++ b/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-auto-hook.span-tree.txt @@ -0,0 +1,455 @@ +span_tree: +└── flue-root [task] + metadata: { + "scenario": "flue-instrumentation" + } + ├── flue-prompt-operation + │ metadata: { + │ "operation": "prompt" + │ } + │ └── flue.session.prompt [task] + │ input: "Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text." + │ output: "PROMPT_DONE" + │ metadata: { + │ "flue.model": "claude-sonnet-4-5-20250929", + │ "flue.operation": "prompt", + │ "flue.session": "main", + │ "flue.thinking_level": "medium", + │ "flue.tools_count": 3, + │ "model": "claude-sonnet-4-5-20250929", + │ "provider": "flue" + │ } + │ metrics: { + │ "completion_tokens": 534, + │ "duration_ms": 0, + │ "estimated_cost": 0.013451250000000001, + │ "prompt_cache_creation_tokens": 657, + │ "prompt_cached_tokens": 9435, + │ "prompt_tokens": 49, + │ "tokens": 10675 + │ } + │ ├── flue.turn [llm] + │ │ output: [ + │ │ { + │ │ "finish_reason": "toolUse", + │ │ "index": 0, + │ │ "message": { + │ │ "content": "I'll complete this instrumented research flow step by step. Starting with Step 1:", + │ │ "reasoning": "The user wants me to complete a specific instrumented research flow with three steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id to call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url to call summarize_source\n4. Reply with exactly \"PROMPT_DONE\" after summarize_source returns\n\nThe user emphasizes calling exactly one tool per turn and waiting for each result. Let me start with step 1.", + │ │ "role": "assistant", + │ │ "tool_calls": [ + │ │ { + │ │ "function": { + │ │ "arguments": "{\"query\":\"flue instrumentation\"}", + │ │ "name": "lookup" + │ │ }, + │ │ "id": "", + │ │ "type": "function" + │ │ } + │ │ ] + │ │ } + │ │ } + │ │ ] + │ │ metadata: { + │ │ "flue.model": "claude-sonnet-4-5-20250929", + │ │ "flue.session": "main", + │ │ "flue.thinking": true, + │ │ "model": "claude-sonnet-4-5-20250929", + │ │ "provider": "flue" + │ │ } + │ │ metrics: { + │ │ "completion_tokens": 199, + │ │ "duration_ms": 0, + │ │ "estimated_cost": 0.0036696000000000003, + │ │ "prompt_cache_creation_tokens": 0, + │ │ "prompt_cached_tokens": 2182, + │ │ "prompt_tokens": 10, + │ │ "tokens": 2391 + │ │ } + │ ├── tool: lookup [tool] + │ │ input: { + │ │ "query": "flue instrumentation" + │ │ } + │ │ output: { + │ │ "content": [ + │ │ { + │ │ "text": "{\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}", + │ │ "type": "text" + │ │ } + │ │ ], + │ │ "details": { + │ │ "customTool": "lookup" + │ │ } + │ │ } + │ │ metadata: { + │ │ "flue.session": "main", + │ │ "flue.tool_name": "lookup", + │ │ "provider": "flue" + │ │ } + │ │ metrics: { + │ │ "duration_ms": 0 + │ │ } + │ ├── flue.turn [llm] + │ │ output: [ + │ │ { + │ │ "finish_reason": "toolUse", + │ │ "index": 0, + │ │ "message": { + │ │ "content": "Now proceeding to Step 2:", + │ │ "reasoning": "Good, I got the lookup result with id \"flue-session-2026\". Now I'll proceed to step 2 and use this id as the lookupId parameter in the web_search call with the specified query.", + │ │ "role": "assistant", + │ │ "tool_calls": [ + │ │ { + │ │ "function": { + │ │ "arguments": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\"}", + │ │ "name": "web_search" + │ │ }, + │ │ "id": "", + │ │ "type": "function" + │ │ } + │ │ ] + │ │ } + │ │ } + │ │ ] + │ │ metadata: { + │ │ "flue.model": "claude-sonnet-4-5-20250929", + │ │ "flue.session": "main", + │ │ "flue.thinking": true, + │ │ "model": "claude-sonnet-4-5-20250929", + │ │ "provider": "flue" + │ │ } + │ │ metrics: { + │ │ "completion_tokens": 153, + │ │ "duration_ms": 0, + │ │ "estimated_cost": 0.00388485, + │ │ "prompt_cache_creation_tokens": 239, + │ │ "prompt_cached_tokens": 2182, + │ │ "prompt_tokens": 13, + │ │ "tokens": 2587 + │ │ } + │ ├── tool: web_search [tool] + │ │ input: { + │ │ "lookupId": "flue-session-2026", + │ │ "query": "Braintrust Flue reasoning stream instrumentation" + │ │ } + │ │ output: { + │ │ "content": [ + │ │ { + │ │ "text": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\",\"results\":[{\"title\":\"Flue reasoning stream instrumentation\",\"url\":\"https://example.test/flue/reasoning-streams\"}]}", + │ │ "type": "text" + │ │ } + │ │ ], + │ │ "details": { + │ │ "customTool": "web_search" + │ │ } + │ │ } + │ │ metadata: { + │ │ "flue.session": "main", + │ │ "flue.tool_name": "web_search", + │ │ "provider": "flue" + │ │ } + │ │ metrics: { + │ │ "duration_ms": 0 + │ │ } + │ ├── flue.turn [llm] + │ │ output: [ + │ │ { + │ │ "finish_reason": "toolUse", + │ │ "index": 0, + │ │ "message": { + │ │ "content": "Now proceeding to Step 3:", + │ │ "reasoning": "Perfect! I got the web_search results. There's one result with the URL \"https://example.test/flue/reasoning-streams\". Now I need to proceed to step 3 and call summarize_source with this URL.", + │ │ "role": "assistant", + │ │ "tool_calls": [ + │ │ { + │ │ "function": { + │ │ "arguments": "{\"url\":\"https://example.test/flue/reasoning-streams\"}", + │ │ "name": "summarize_source" + │ │ }, + │ │ "id": "", + │ │ "type": "function" + │ │ } + │ │ ] + │ │ } + │ │ } + │ │ ] + │ │ metadata: { + │ │ "flue.model": "claude-sonnet-4-5-20250929", + │ │ "flue.session": "main", + │ │ "flue.thinking": true, + │ │ "model": "claude-sonnet-4-5-20250929", + │ │ "provider": "flue" + │ │ } + │ │ metrics: { + │ │ "completion_tokens": 133, + │ │ "duration_ms": 0, + │ │ "estimated_cost": 0.0036190500000000004, + │ │ "prompt_cache_creation_tokens": 229, + │ │ "prompt_cached_tokens": 2421, + │ │ "prompt_tokens": 13, + │ │ "tokens": 2796 + │ │ } + │ ├── tool: summarize_source [tool] + │ │ input: { + │ │ "url": "https://example.test/flue/reasoning-streams" + │ │ } + │ │ output: { + │ │ "content": [ + │ │ { + │ │ "text": "{\"summary\":\"Flue emits reasoning, tool execution, and LLM turn events separately.\",\"url\":\"https://example.test/flue/reasoning-streams\"}", + │ │ "type": "text" + │ │ } + │ │ ], + │ │ "details": { + │ │ "customTool": "summarize_source" + │ │ } + │ │ } + │ │ metadata: { + │ │ "flue.session": "main", + │ │ "flue.tool_name": "summarize_source", + │ │ "provider": "flue" + │ │ } + │ │ metrics: { + │ │ "duration_ms": 0 + │ │ } + │ └── flue.turn [llm] + │ output: [ + │ { + │ "finish_reason": "stop", + │ "index": 0, + │ "message": { + │ "content": "PROMPT_DONE", + │ "reasoning": "Perfect! The summarize_source has returned. According to the instructions, I should now reply with exactly \"PROMPT_DONE\" and no other text.", + │ "role": "assistant" + │ } + │ } + │ ] + │ metadata: { + │ "flue.model": "claude-sonnet-4-5-20250929", + │ "flue.session": "main", + │ "flue.thinking": true, + │ "model": "claude-sonnet-4-5-20250929", + │ "provider": "flue" + │ } + │ metrics: { + │ "completion_tokens": 49, + │ "duration_ms": 0, + │ "estimated_cost": 0.00227775, + │ "prompt_cache_creation_tokens": 189, + │ "prompt_cached_tokens": 2650, + │ "prompt_tokens": 13, + │ "tokens": 2901 + │ } + ├── flue-skill-operation + │ metadata: { + │ "operation": "skill" + │ } + │ └── flue.session.skill [task] + │ input: { + │ "args": { + │ "marker": "SKILL_DONE" + │ }, + │ "name": "e2e-flue-skill" + │ } + │ output: "SKILL_DONE" + │ metadata: { + │ "flue.model": "claude-sonnet-4-5-20250929", + │ "flue.operation": "skill", + │ "flue.role": "skillRunner", + │ "flue.session": "skill", + │ "flue.skill_name": "e2e-flue-skill", + │ "flue.thinking_level": "off", + │ "model": "claude-sonnet-4-5-20250929", + │ "provider": "flue" + │ } + │ metrics: { + │ "completion_tokens": 97, + │ "duration_ms": 0, + │ "estimated_cost": 0.0026133, + │ "prompt_cache_creation_tokens": 0, + │ "prompt_cached_tokens": 3771, + │ "prompt_tokens": 9, + │ "tokens": 3877 + │ } + │ ├── flue.turn [llm] + │ │ output: [ + │ │ { + │ │ "finish_reason": "toolUse", + │ │ "index": 0, + │ │ "message": { + │ │ "content": "I'll run the e2e-flue-skill by reading its instructions and following them.", + │ │ "role": "assistant", + │ │ "tool_calls": [ + │ │ { + │ │ "function": { + │ │ "arguments": "{\"path\":\".agents/skills/e2e-flue-skill/SKILL.md\"}", + │ │ "name": "read" + │ │ }, + │ │ "id": "", + │ │ "type": "function" + │ │ } + │ │ ] + │ │ } + │ │ } + │ │ ] + │ │ metadata: { + │ │ "flue.model": "claude-sonnet-4-5-20250929", + │ │ "flue.session": "skill", + │ │ "model": "claude-sonnet-4-5-20250929", + │ │ "provider": "flue" + │ │ } + │ │ metrics: { + │ │ "completion_tokens": 89, + │ │ "duration_ms": 0, + │ │ "estimated_cost": 0.0018866999999999998, + │ │ "prompt_cache_creation_tokens": 0, + │ │ "prompt_cached_tokens": 1809, + │ │ "prompt_tokens": 3, + │ │ "tokens": 1901 + │ │ } + │ ├── tool: read [tool] + │ │ input: { + │ │ "path": ".agents/skills/e2e-flue-skill/SKILL.md" + │ │ } + │ │ output: { + │ │ "content": [ + │ │ { + │ │ "text": "---\nname: e2e-flue-skill\ndescription: Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n---\n\nReturn the marker from the provided args exactly once. Output no other text.\n", + │ │ "type": "text" + │ │ } + │ │ ], + │ │ "details": { + │ │ "lines": 7, + │ │ "path": ".agents/skills/e2e-flue-skill/SKILL.md" + │ │ } + │ │ } + │ │ metadata: { + │ │ "flue.session": "skill", + │ │ "flue.tool_name": "read", + │ │ "provider": "flue" + │ │ } + │ │ metrics: { + │ │ "duration_ms": 0 + │ │ } + │ └── flue.turn [llm] + │ output: [ + │ { + │ "finish_reason": "stop", + │ "index": 0, + │ "message": { + │ "content": "SKILL_DONE", + │ "role": "assistant" + │ } + │ } + │ ] + │ metadata: { + │ "flue.model": "claude-sonnet-4-5-20250929", + │ "flue.session": "skill", + │ "model": "claude-sonnet-4-5-20250929", + │ "provider": "flue" + │ } + │ metrics: { + │ "completion_tokens": 8, + │ "duration_ms": 0, + │ "estimated_cost": 0.0007266, + │ "prompt_cache_creation_tokens": 0, + │ "prompt_cached_tokens": 1962, + │ "prompt_tokens": 6, + │ "tokens": 1976 + │ } + ├── flue-task-operation + │ metadata: { + │ "operation": "task" + │ } + │ └── flue.session.task [task] + │ input: "Reply with exactly TASK_DONE and no other text." + │ output: "TASK_DONE" + │ metadata: { + │ "flue.model": "gpt-4o-mini", + │ "flue.operation": "task", + │ "flue.session": "task", + │ "flue.thinking_level": "off", + │ "model": "gpt-4o-mini", + │ "provider": "flue" + │ } + │ metrics: { + │ "completion_tokens": 4, + │ "duration_ms": 0, + │ "estimated_cost": 0.00011789999999999999, + │ "prompt_cache_creation_tokens": 0, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 770, + │ "tokens": 774 + │ } + │ └── flue.task [task] + │ input: "Reply with exactly TASK_DONE and no other text." + │ output: "TASK_DONE" + │ metadata: { + │ "flue.session": "task", + │ "provider": "flue" + │ } + │ metrics: { + │ "duration_ms": 0 + │ } + │ └── flue.turn [llm] + │ output: [ + │ { + │ "finish_reason": "stop", + │ "index": 0, + │ "message": { + │ "content": "TASK_DONE", + │ "role": "assistant" + │ } + │ } + │ ] + │ metadata: { + │ "flue.model": "gpt-4o-mini", + │ "flue.session": "task:task:", + │ "model": "gpt-4o-mini", + │ "provider": "flue" + │ } + │ metrics: { + │ "completion_tokens": 4, + │ "duration_ms": 0, + │ "estimated_cost": 0.00011789999999999999, + │ "prompt_cache_creation_tokens": 0, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 770, + │ "tokens": 774 + │ } + └── flue-compact-operation + metadata: { + "operation": "compact" + } + └── flue.session.compact [task] + metadata: { + "flue.operation": "compact", + "flue.session": "main", + "provider": "flue" + } + metrics: { + "duration_ms": 0 + } + └── flue.compaction [task] + input: { + "estimatedTokens": 2901, + "reason": "manual" + } + output: { + "messagesAfter": 2, + "messagesBefore": 8 + } + metadata: { + "flue.compaction_reason": "manual", + "flue.session": "main", + "provider": "flue" + } + metrics: { + "completion_tokens": 0, + "duration_ms": 0, + "estimated_cost": 0, + "prompt_cache_creation_tokens": 0, + "prompt_cached_tokens": 0, + "prompt_tokens": 0, + "tokens": 0 + } diff --git a/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-wrapped.span-tree.json b/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-wrapped.span-tree.json new file mode 100644 index 000000000..241cd79aa --- /dev/null +++ b/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-wrapped.span-tree.json @@ -0,0 +1,552 @@ +{ + "span_tree": [ + { + "name": "flue-root", + "type": "task", + "children": [ + { + "name": "flue-prompt-operation", + "children": [ + { + "name": "flue.session.prompt", + "type": "task", + "children": [ + { + "name": "flue.turn", + "type": "llm", + "children": [], + "output": [ + { + "finish_reason": "toolUse", + "index": 0, + "message": { + "content": "I'll complete this instrumented research flow step by step. Starting with Step 1:", + "reasoning": "The user wants me to complete an instrumented research flow with exactly three steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id to call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url to call summarize_source\n4. After that, reply with exactly \"PROMPT_DONE\"\n\nThe user also emphasizes that I should call exactly one tool per turn and wait for each tool result before choosing the next tool.\n\nLet me start with Step 1: calling lookup with query \"flue instrumentation\".", + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"query\":\"flue instrumentation\"}", + "name": "lookup" + }, + "id": "", + "type": "function" + } + ] + } + } + ], + "metadata": { + "flue.model": "claude-sonnet-4-5-20250929", + "flue.session": "main", + "flue.thinking": true, + "model": "claude-sonnet-4-5-20250929", + "provider": "flue" + }, + "metrics": { + "completion_tokens": 217, + "duration_ms": 0, + "estimated_cost": 0.00699285, + "prompt_cache_creation_tokens": 885, + "prompt_cached_tokens": 1297, + "prompt_tokens": 10, + "tokens": 2409 + } + }, + { + "name": "tool: lookup", + "type": "tool", + "children": [], + "input": { + "query": "flue instrumentation" + }, + "output": { + "content": [ + { + "text": "{\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}", + "type": "text" + } + ], + "details": { + "customTool": "lookup" + } + }, + "metadata": { + "flue.session": "main", + "flue.tool_name": "lookup", + "provider": "flue" + }, + "metrics": { + "duration_ms": 0 + } + }, + { + "name": "flue.turn", + "type": "llm", + "children": [], + "output": [ + { + "finish_reason": "toolUse", + "index": 0, + "message": { + "content": "Now proceeding to Step 2:", + "reasoning": "Good, I got the lookup result with id \"flue-session-2026\". Now I need to proceed to Step 2: call web_search using this lookupId and the query \"Braintrust Flue reasoning stream instrumentation\".", + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\"}", + "name": "web_search" + }, + "id": "", + "type": "function" + } + ] + } + } + ], + "metadata": { + "flue.model": "claude-sonnet-4-5-20250929", + "flue.session": "main", + "flue.thinking": true, + "model": "claude-sonnet-4-5-20250929", + "provider": "flue" + }, + "metrics": { + "completion_tokens": 158, + "duration_ms": 0, + "estimated_cost": 0.00402735, + "prompt_cache_creation_tokens": 257, + "prompt_cached_tokens": 2182, + "prompt_tokens": 13, + "tokens": 2610 + } + }, + { + "name": "tool: web_search", + "type": "tool", + "children": [], + "input": { + "lookupId": "flue-session-2026", + "query": "Braintrust Flue reasoning stream instrumentation" + }, + "output": { + "content": [ + { + "text": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\",\"results\":[{\"title\":\"Flue reasoning stream instrumentation\",\"url\":\"https://example.test/flue/reasoning-streams\"}]}", + "type": "text" + } + ], + "details": { + "customTool": "web_search" + } + }, + "metadata": { + "flue.session": "main", + "flue.tool_name": "web_search", + "provider": "flue" + }, + "metrics": { + "duration_ms": 0 + } + }, + { + "name": "flue.turn", + "type": "llm", + "children": [], + "output": [ + { + "finish_reason": "toolUse", + "index": 0, + "message": { + "content": "Now proceeding to Step 3:", + "reasoning": "Perfect! I got the web_search results. There's one result with the URL \"https://example.test/flue/reasoning-streams\". Now I need to proceed to Step 3: call summarize_source with this URL.", + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"url\":\"https://example.test/flue/reasoning-streams\"}", + "name": "summarize_source" + }, + "id": "", + "type": "function" + } + ] + } + } + ], + "metadata": { + "flue.model": "claude-sonnet-4-5-20250929", + "flue.session": "main", + "flue.thinking": true, + "model": "claude-sonnet-4-5-20250929", + "provider": "flue" + }, + "metrics": { + "completion_tokens": 132, + "duration_ms": 0, + "estimated_cost": 0.0036282, + "prompt_cache_creation_tokens": 234, + "prompt_cached_tokens": 2439, + "prompt_tokens": 13, + "tokens": 2818 + } + }, + { + "name": "tool: summarize_source", + "type": "tool", + "children": [], + "input": { + "url": "https://example.test/flue/reasoning-streams" + }, + "output": { + "content": [ + { + "text": "{\"summary\":\"Flue emits reasoning, tool execution, and LLM turn events separately.\",\"url\":\"https://example.test/flue/reasoning-streams\"}", + "type": "text" + } + ], + "details": { + "customTool": "summarize_source" + } + }, + "metadata": { + "flue.session": "main", + "flue.tool_name": "summarize_source", + "provider": "flue" + }, + "metrics": { + "duration_ms": 0 + } + }, + { + "name": "flue.turn", + "type": "llm", + "children": [], + "output": [ + { + "finish_reason": "stop", + "index": 0, + "message": { + "content": "PROMPT_DONE", + "reasoning": "Great! The summarize_source call has completed successfully. According to the instructions, I should now reply with exactly \"PROMPT_DONE\" and no other text.", + "role": "assistant" + } + } + ], + "metadata": { + "flue.model": "claude-sonnet-4-5-20250929", + "flue.session": "main", + "flue.thinking": true, + "model": "claude-sonnet-4-5-20250929", + "provider": "flue" + }, + "metrics": { + "completion_tokens": 51, + "duration_ms": 0, + "estimated_cost": 0.0023109, + "prompt_cache_creation_tokens": 188, + "prompt_cached_tokens": 2673, + "prompt_tokens": 13, + "tokens": 2925 + } + } + ], + "input": "Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.", + "output": "PROMPT_DONE", + "metadata": { + "flue.model": "claude-sonnet-4-5-20250929", + "flue.operation": "prompt", + "flue.session": "main", + "flue.thinking_level": "medium", + "flue.tools_count": 3, + "model": "claude-sonnet-4-5-20250929", + "provider": "flue" + }, + "metrics": { + "completion_tokens": 558, + "duration_ms": 0, + "estimated_cost": 0.0169593, + "prompt_cache_creation_tokens": 1564, + "prompt_cached_tokens": 8591, + "prompt_tokens": 49, + "tokens": 10762 + } + } + ], + "metadata": { + "operation": "prompt" + } + }, + { + "name": "flue-skill-operation", + "children": [ + { + "name": "flue.session.skill", + "type": "task", + "children": [ + { + "name": "flue.turn", + "type": "llm", + "children": [], + "output": [ + { + "finish_reason": "toolUse", + "index": 0, + "message": { + "content": "I'll run the e2e-flue-skill by reading its instructions and following them.", + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"path\":\".agents/skills/e2e-flue-skill/SKILL.md\"}", + "name": "read" + }, + "id": "", + "type": "function" + } + ] + } + } + ], + "metadata": { + "flue.model": "claude-sonnet-4-5-20250929", + "flue.session": "skill", + "model": "claude-sonnet-4-5-20250929", + "provider": "flue" + }, + "metrics": { + "completion_tokens": 89, + "duration_ms": 0, + "estimated_cost": 0.0043569, + "prompt_cache_creation_tokens": 716, + "prompt_cached_tokens": 1093, + "prompt_tokens": 3, + "tokens": 1901 + } + }, + { + "name": "tool: read", + "type": "tool", + "children": [], + "input": { + "path": ".agents/skills/e2e-flue-skill/SKILL.md" + }, + "output": { + "content": [ + { + "text": "---\nname: e2e-flue-skill\ndescription: Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n---\n\nReturn the marker from the provided args exactly once. Output no other text.\n", + "type": "text" + } + ], + "details": { + "lines": 7, + "path": ".agents/skills/e2e-flue-skill/SKILL.md" + } + }, + "metadata": { + "flue.session": "skill", + "flue.tool_name": "read", + "provider": "flue" + }, + "metrics": { + "duration_ms": 0 + } + }, + { + "name": "flue.turn", + "type": "llm", + "children": [], + "output": [ + { + "finish_reason": "stop", + "index": 0, + "message": { + "content": "SKILL_DONE", + "role": "assistant" + } + } + ], + "metadata": { + "flue.model": "claude-sonnet-4-5-20250929", + "flue.session": "skill", + "model": "claude-sonnet-4-5-20250929", + "provider": "flue" + }, + "metrics": { + "completion_tokens": 8, + "duration_ms": 0, + "estimated_cost": 0.00125445, + "prompt_cache_creation_tokens": 153, + "prompt_cached_tokens": 1809, + "prompt_tokens": 6, + "tokens": 1976 + } + } + ], + "input": { + "args": { + "marker": "SKILL_DONE" + }, + "name": "e2e-flue-skill" + }, + "output": "SKILL_DONE", + "metadata": { + "flue.model": "claude-sonnet-4-5-20250929", + "flue.operation": "skill", + "flue.role": "skillRunner", + "flue.session": "skill", + "flue.skill_name": "e2e-flue-skill", + "flue.thinking_level": "off", + "model": "claude-sonnet-4-5-20250929", + "provider": "flue" + }, + "metrics": { + "completion_tokens": 97, + "duration_ms": 0, + "estimated_cost": 0.00561135, + "prompt_cache_creation_tokens": 869, + "prompt_cached_tokens": 2902, + "prompt_tokens": 9, + "tokens": 3877 + } + } + ], + "metadata": { + "operation": "skill" + } + }, + { + "name": "flue-task-operation", + "children": [ + { + "name": "flue.session.task", + "type": "task", + "children": [ + { + "name": "flue.task", + "type": "task", + "children": [ + { + "name": "flue.turn", + "type": "llm", + "children": [], + "output": [ + { + "finish_reason": "stop", + "index": 0, + "message": { + "content": "TASK_DONE", + "role": "assistant" + } + } + ], + "metadata": { + "flue.model": "gpt-4o-mini", + "flue.session": "task:task:", + "model": "gpt-4o-mini", + "provider": "flue" + }, + "metrics": { + "completion_tokens": 4, + "duration_ms": 0, + "estimated_cost": 0.00011789999999999999, + "prompt_cache_creation_tokens": 0, + "prompt_cached_tokens": 0, + "prompt_tokens": 770, + "tokens": 774 + } + } + ], + "input": "Reply with exactly TASK_DONE and no other text.", + "output": "TASK_DONE", + "metadata": { + "flue.session": "task", + "provider": "flue" + }, + "metrics": { + "duration_ms": 0 + } + } + ], + "input": "Reply with exactly TASK_DONE and no other text.", + "output": "TASK_DONE", + "metadata": { + "flue.model": "gpt-4o-mini", + "flue.operation": "task", + "flue.session": "task", + "flue.thinking_level": "off", + "model": "gpt-4o-mini", + "provider": "flue" + }, + "metrics": { + "completion_tokens": 4, + "duration_ms": 0, + "estimated_cost": 0.00011789999999999999, + "prompt_cache_creation_tokens": 0, + "prompt_cached_tokens": 0, + "prompt_tokens": 770, + "tokens": 774 + } + } + ], + "metadata": { + "operation": "task" + } + }, + { + "name": "flue-compact-operation", + "children": [ + { + "name": "flue.session.compact", + "type": "task", + "children": [ + { + "name": "flue.compaction", + "type": "task", + "children": [], + "input": { + "estimatedTokens": 2925, + "reason": "manual" + }, + "output": { + "messagesAfter": 2, + "messagesBefore": 8 + }, + "metadata": { + "flue.compaction_reason": "manual", + "flue.session": "main", + "provider": "flue" + }, + "metrics": { + "completion_tokens": 0, + "duration_ms": 0, + "estimated_cost": 0, + "prompt_cache_creation_tokens": 0, + "prompt_cached_tokens": 0, + "prompt_tokens": 0, + "tokens": 0 + } + } + ], + "metadata": { + "flue.operation": "compact", + "flue.session": "main", + "provider": "flue" + }, + "metrics": { + "duration_ms": 0 + } + } + ], + "metadata": { + "operation": "compact" + } + } + ], + "metadata": { + "scenario": "flue-instrumentation" + } + } + ] +} diff --git a/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-wrapped.span-tree.txt b/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-wrapped.span-tree.txt new file mode 100644 index 000000000..0bbfd3d1b --- /dev/null +++ b/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-wrapped.span-tree.txt @@ -0,0 +1,455 @@ +span_tree: +└── flue-root [task] + metadata: { + "scenario": "flue-instrumentation" + } + ├── flue-prompt-operation + │ metadata: { + │ "operation": "prompt" + │ } + │ └── flue.session.prompt [task] + │ input: "Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text." + │ output: "PROMPT_DONE" + │ metadata: { + │ "flue.model": "claude-sonnet-4-5-20250929", + │ "flue.operation": "prompt", + │ "flue.session": "main", + │ "flue.thinking_level": "medium", + │ "flue.tools_count": 3, + │ "model": "claude-sonnet-4-5-20250929", + │ "provider": "flue" + │ } + │ metrics: { + │ "completion_tokens": 558, + │ "duration_ms": 0, + │ "estimated_cost": 0.0169593, + │ "prompt_cache_creation_tokens": 1564, + │ "prompt_cached_tokens": 8591, + │ "prompt_tokens": 49, + │ "tokens": 10762 + │ } + │ ├── flue.turn [llm] + │ │ output: [ + │ │ { + │ │ "finish_reason": "toolUse", + │ │ "index": 0, + │ │ "message": { + │ │ "content": "I'll complete this instrumented research flow step by step. Starting with Step 1:", + │ │ "reasoning": "The user wants me to complete an instrumented research flow with exactly three steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id to call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url to call summarize_source\n4. After that, reply with exactly \"PROMPT_DONE\"\n\nThe user also emphasizes that I should call exactly one tool per turn and wait for each tool result before choosing the next tool.\n\nLet me start with Step 1: calling lookup with query \"flue instrumentation\".", + │ │ "role": "assistant", + │ │ "tool_calls": [ + │ │ { + │ │ "function": { + │ │ "arguments": "{\"query\":\"flue instrumentation\"}", + │ │ "name": "lookup" + │ │ }, + │ │ "id": "", + │ │ "type": "function" + │ │ } + │ │ ] + │ │ } + │ │ } + │ │ ] + │ │ metadata: { + │ │ "flue.model": "claude-sonnet-4-5-20250929", + │ │ "flue.session": "main", + │ │ "flue.thinking": true, + │ │ "model": "claude-sonnet-4-5-20250929", + │ │ "provider": "flue" + │ │ } + │ │ metrics: { + │ │ "completion_tokens": 217, + │ │ "duration_ms": 0, + │ │ "estimated_cost": 0.00699285, + │ │ "prompt_cache_creation_tokens": 885, + │ │ "prompt_cached_tokens": 1297, + │ │ "prompt_tokens": 10, + │ │ "tokens": 2409 + │ │ } + │ ├── tool: lookup [tool] + │ │ input: { + │ │ "query": "flue instrumentation" + │ │ } + │ │ output: { + │ │ "content": [ + │ │ { + │ │ "text": "{\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}", + │ │ "type": "text" + │ │ } + │ │ ], + │ │ "details": { + │ │ "customTool": "lookup" + │ │ } + │ │ } + │ │ metadata: { + │ │ "flue.session": "main", + │ │ "flue.tool_name": "lookup", + │ │ "provider": "flue" + │ │ } + │ │ metrics: { + │ │ "duration_ms": 0 + │ │ } + │ ├── flue.turn [llm] + │ │ output: [ + │ │ { + │ │ "finish_reason": "toolUse", + │ │ "index": 0, + │ │ "message": { + │ │ "content": "Now proceeding to Step 2:", + │ │ "reasoning": "Good, I got the lookup result with id \"flue-session-2026\". Now I need to proceed to Step 2: call web_search using this lookupId and the query \"Braintrust Flue reasoning stream instrumentation\".", + │ │ "role": "assistant", + │ │ "tool_calls": [ + │ │ { + │ │ "function": { + │ │ "arguments": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\"}", + │ │ "name": "web_search" + │ │ }, + │ │ "id": "", + │ │ "type": "function" + │ │ } + │ │ ] + │ │ } + │ │ } + │ │ ] + │ │ metadata: { + │ │ "flue.model": "claude-sonnet-4-5-20250929", + │ │ "flue.session": "main", + │ │ "flue.thinking": true, + │ │ "model": "claude-sonnet-4-5-20250929", + │ │ "provider": "flue" + │ │ } + │ │ metrics: { + │ │ "completion_tokens": 158, + │ │ "duration_ms": 0, + │ │ "estimated_cost": 0.00402735, + │ │ "prompt_cache_creation_tokens": 257, + │ │ "prompt_cached_tokens": 2182, + │ │ "prompt_tokens": 13, + │ │ "tokens": 2610 + │ │ } + │ ├── tool: web_search [tool] + │ │ input: { + │ │ "lookupId": "flue-session-2026", + │ │ "query": "Braintrust Flue reasoning stream instrumentation" + │ │ } + │ │ output: { + │ │ "content": [ + │ │ { + │ │ "text": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\",\"results\":[{\"title\":\"Flue reasoning stream instrumentation\",\"url\":\"https://example.test/flue/reasoning-streams\"}]}", + │ │ "type": "text" + │ │ } + │ │ ], + │ │ "details": { + │ │ "customTool": "web_search" + │ │ } + │ │ } + │ │ metadata: { + │ │ "flue.session": "main", + │ │ "flue.tool_name": "web_search", + │ │ "provider": "flue" + │ │ } + │ │ metrics: { + │ │ "duration_ms": 0 + │ │ } + │ ├── flue.turn [llm] + │ │ output: [ + │ │ { + │ │ "finish_reason": "toolUse", + │ │ "index": 0, + │ │ "message": { + │ │ "content": "Now proceeding to Step 3:", + │ │ "reasoning": "Perfect! I got the web_search results. There's one result with the URL \"https://example.test/flue/reasoning-streams\". Now I need to proceed to Step 3: call summarize_source with this URL.", + │ │ "role": "assistant", + │ │ "tool_calls": [ + │ │ { + │ │ "function": { + │ │ "arguments": "{\"url\":\"https://example.test/flue/reasoning-streams\"}", + │ │ "name": "summarize_source" + │ │ }, + │ │ "id": "", + │ │ "type": "function" + │ │ } + │ │ ] + │ │ } + │ │ } + │ │ ] + │ │ metadata: { + │ │ "flue.model": "claude-sonnet-4-5-20250929", + │ │ "flue.session": "main", + │ │ "flue.thinking": true, + │ │ "model": "claude-sonnet-4-5-20250929", + │ │ "provider": "flue" + │ │ } + │ │ metrics: { + │ │ "completion_tokens": 132, + │ │ "duration_ms": 0, + │ │ "estimated_cost": 0.0036282, + │ │ "prompt_cache_creation_tokens": 234, + │ │ "prompt_cached_tokens": 2439, + │ │ "prompt_tokens": 13, + │ │ "tokens": 2818 + │ │ } + │ ├── tool: summarize_source [tool] + │ │ input: { + │ │ "url": "https://example.test/flue/reasoning-streams" + │ │ } + │ │ output: { + │ │ "content": [ + │ │ { + │ │ "text": "{\"summary\":\"Flue emits reasoning, tool execution, and LLM turn events separately.\",\"url\":\"https://example.test/flue/reasoning-streams\"}", + │ │ "type": "text" + │ │ } + │ │ ], + │ │ "details": { + │ │ "customTool": "summarize_source" + │ │ } + │ │ } + │ │ metadata: { + │ │ "flue.session": "main", + │ │ "flue.tool_name": "summarize_source", + │ │ "provider": "flue" + │ │ } + │ │ metrics: { + │ │ "duration_ms": 0 + │ │ } + │ └── flue.turn [llm] + │ output: [ + │ { + │ "finish_reason": "stop", + │ "index": 0, + │ "message": { + │ "content": "PROMPT_DONE", + │ "reasoning": "Great! The summarize_source call has completed successfully. According to the instructions, I should now reply with exactly \"PROMPT_DONE\" and no other text.", + │ "role": "assistant" + │ } + │ } + │ ] + │ metadata: { + │ "flue.model": "claude-sonnet-4-5-20250929", + │ "flue.session": "main", + │ "flue.thinking": true, + │ "model": "claude-sonnet-4-5-20250929", + │ "provider": "flue" + │ } + │ metrics: { + │ "completion_tokens": 51, + │ "duration_ms": 0, + │ "estimated_cost": 0.0023109, + │ "prompt_cache_creation_tokens": 188, + │ "prompt_cached_tokens": 2673, + │ "prompt_tokens": 13, + │ "tokens": 2925 + │ } + ├── flue-skill-operation + │ metadata: { + │ "operation": "skill" + │ } + │ └── flue.session.skill [task] + │ input: { + │ "args": { + │ "marker": "SKILL_DONE" + │ }, + │ "name": "e2e-flue-skill" + │ } + │ output: "SKILL_DONE" + │ metadata: { + │ "flue.model": "claude-sonnet-4-5-20250929", + │ "flue.operation": "skill", + │ "flue.role": "skillRunner", + │ "flue.session": "skill", + │ "flue.skill_name": "e2e-flue-skill", + │ "flue.thinking_level": "off", + │ "model": "claude-sonnet-4-5-20250929", + │ "provider": "flue" + │ } + │ metrics: { + │ "completion_tokens": 97, + │ "duration_ms": 0, + │ "estimated_cost": 0.00561135, + │ "prompt_cache_creation_tokens": 869, + │ "prompt_cached_tokens": 2902, + │ "prompt_tokens": 9, + │ "tokens": 3877 + │ } + │ ├── flue.turn [llm] + │ │ output: [ + │ │ { + │ │ "finish_reason": "toolUse", + │ │ "index": 0, + │ │ "message": { + │ │ "content": "I'll run the e2e-flue-skill by reading its instructions and following them.", + │ │ "role": "assistant", + │ │ "tool_calls": [ + │ │ { + │ │ "function": { + │ │ "arguments": "{\"path\":\".agents/skills/e2e-flue-skill/SKILL.md\"}", + │ │ "name": "read" + │ │ }, + │ │ "id": "", + │ │ "type": "function" + │ │ } + │ │ ] + │ │ } + │ │ } + │ │ ] + │ │ metadata: { + │ │ "flue.model": "claude-sonnet-4-5-20250929", + │ │ "flue.session": "skill", + │ │ "model": "claude-sonnet-4-5-20250929", + │ │ "provider": "flue" + │ │ } + │ │ metrics: { + │ │ "completion_tokens": 89, + │ │ "duration_ms": 0, + │ │ "estimated_cost": 0.0043569, + │ │ "prompt_cache_creation_tokens": 716, + │ │ "prompt_cached_tokens": 1093, + │ │ "prompt_tokens": 3, + │ │ "tokens": 1901 + │ │ } + │ ├── tool: read [tool] + │ │ input: { + │ │ "path": ".agents/skills/e2e-flue-skill/SKILL.md" + │ │ } + │ │ output: { + │ │ "content": [ + │ │ { + │ │ "text": "---\nname: e2e-flue-skill\ndescription: Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n---\n\nReturn the marker from the provided args exactly once. Output no other text.\n", + │ │ "type": "text" + │ │ } + │ │ ], + │ │ "details": { + │ │ "lines": 7, + │ │ "path": ".agents/skills/e2e-flue-skill/SKILL.md" + │ │ } + │ │ } + │ │ metadata: { + │ │ "flue.session": "skill", + │ │ "flue.tool_name": "read", + │ │ "provider": "flue" + │ │ } + │ │ metrics: { + │ │ "duration_ms": 0 + │ │ } + │ └── flue.turn [llm] + │ output: [ + │ { + │ "finish_reason": "stop", + │ "index": 0, + │ "message": { + │ "content": "SKILL_DONE", + │ "role": "assistant" + │ } + │ } + │ ] + │ metadata: { + │ "flue.model": "claude-sonnet-4-5-20250929", + │ "flue.session": "skill", + │ "model": "claude-sonnet-4-5-20250929", + │ "provider": "flue" + │ } + │ metrics: { + │ "completion_tokens": 8, + │ "duration_ms": 0, + │ "estimated_cost": 0.00125445, + │ "prompt_cache_creation_tokens": 153, + │ "prompt_cached_tokens": 1809, + │ "prompt_tokens": 6, + │ "tokens": 1976 + │ } + ├── flue-task-operation + │ metadata: { + │ "operation": "task" + │ } + │ └── flue.session.task [task] + │ input: "Reply with exactly TASK_DONE and no other text." + │ output: "TASK_DONE" + │ metadata: { + │ "flue.model": "gpt-4o-mini", + │ "flue.operation": "task", + │ "flue.session": "task", + │ "flue.thinking_level": "off", + │ "model": "gpt-4o-mini", + │ "provider": "flue" + │ } + │ metrics: { + │ "completion_tokens": 4, + │ "duration_ms": 0, + │ "estimated_cost": 0.00011789999999999999, + │ "prompt_cache_creation_tokens": 0, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 770, + │ "tokens": 774 + │ } + │ └── flue.task [task] + │ input: "Reply with exactly TASK_DONE and no other text." + │ output: "TASK_DONE" + │ metadata: { + │ "flue.session": "task", + │ "provider": "flue" + │ } + │ metrics: { + │ "duration_ms": 0 + │ } + │ └── flue.turn [llm] + │ output: [ + │ { + │ "finish_reason": "stop", + │ "index": 0, + │ "message": { + │ "content": "TASK_DONE", + │ "role": "assistant" + │ } + │ } + │ ] + │ metadata: { + │ "flue.model": "gpt-4o-mini", + │ "flue.session": "task:task:", + │ "model": "gpt-4o-mini", + │ "provider": "flue" + │ } + │ metrics: { + │ "completion_tokens": 4, + │ "duration_ms": 0, + │ "estimated_cost": 0.00011789999999999999, + │ "prompt_cache_creation_tokens": 0, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 770, + │ "tokens": 774 + │ } + └── flue-compact-operation + metadata: { + "operation": "compact" + } + └── flue.session.compact [task] + metadata: { + "flue.operation": "compact", + "flue.session": "main", + "provider": "flue" + } + metrics: { + "duration_ms": 0 + } + └── flue.compaction [task] + input: { + "estimatedTokens": 2925, + "reason": "manual" + } + output: { + "messagesAfter": 2, + "messagesBefore": 8 + } + metadata: { + "flue.compaction_reason": "manual", + "flue.session": "main", + "provider": "flue" + } + metrics: { + "completion_tokens": 0, + "duration_ms": 0, + "estimated_cost": 0, + "prompt_cache_creation_tokens": 0, + "prompt_cached_tokens": 0, + "prompt_tokens": 0, + "tokens": 0 + } diff --git a/e2e/scenarios/flue-instrumentation/assertions.ts b/e2e/scenarios/flue-instrumentation/assertions.ts new file mode 100644 index 000000000..7e1770e69 --- /dev/null +++ b/e2e/scenarios/flue-instrumentation/assertions.ts @@ -0,0 +1,453 @@ +import { beforeAll, describe, expect, test } from "vitest"; +import type { CapturedLogEvent } from "../../helpers/mock-braintrust-server"; +import { resolveFileSnapshotPath } from "../../helpers/file-snapshot"; +import { + effectiveScenarioTimeoutMs, + withScenarioHarness, + type ScenarioRunContext, +} from "../../helpers/scenario-harness"; +import { + matchSpanTreeSnapshot, + spanTreeFields, + type SpanTreeEntry, + type SpanTreeFields, +} from "../../helpers/span-tree"; +import { + findAllSpans, + findLatestChildSpan, + findLatestSpan, +} from "../../helpers/trace-selectors"; +import { ROOT_NAME, SCENARIO_NAME } from "./constants.mjs"; + +type RunFlueScenario = (harness: { + runNodeScenarioDir: (options: { + entry: string; + nodeArgs: string[]; + runContext?: ScenarioRunContext; + scenarioDir: string; + timeoutMs: number; + }) => Promise; + runScenarioDir: (options: { + entry: string; + runContext?: ScenarioRunContext; + scenarioDir: string; + timeoutMs: number; + }) => Promise; +}) => Promise; + +const SNAPSHOT_METADATA_KEYS = [ + "provider", + "model", + "operation", + "scenario", + "flue.operation", + "flue.version", + "flue.session", + "flue.model", + "flue.role", + "flue.skill_name", + "flue.thinking", + "flue.thinking_level", + "flue.tools_count", + "flue.tool_name", + "flue.compaction_reason", +] as const; + +function snapshotFields(event: CapturedLogEvent): SpanTreeFields { + const fields = spanTreeFields(event); + const metadata = + fields.metadata && + typeof fields.metadata === "object" && + !Array.isArray(fields.metadata) + ? Object.fromEntries( + Object.entries(fields.metadata).filter(([key]) => + SNAPSHOT_METADATA_KEYS.includes( + key as (typeof SNAPSHOT_METADATA_KEYS)[number], + ), + ), + ) + : undefined; + + return { + ...fields, + metadata, + }; +} + +function findFlueOperation( + events: CapturedLogEvent[], + operationName: string, + flueSpanName: string, +) { + const operation = findLatestSpan(events, operationName); + return findLatestChildSpan(events, flueSpanName, operation?.span.id); +} + +function findMatchingDescendants( + events: CapturedLogEvent[], + ancestor: CapturedLogEvent | undefined, + predicate: (event: CapturedLogEvent) => boolean, +): CapturedLogEvent[] { + if (!ancestor) { + return []; + } + const visited = new Set(); + const matches: CapturedLogEvent[] = []; + let frontier = [ancestor.span.id]; + while (frontier.length > 0) { + const next: string[] = []; + for (const parentId of frontier) { + const children = events.filter((event) => + event.span.parentIds.includes(parentId), + ); + for (const child of children) { + if (child.span.id && !visited.has(child.span.id)) { + visited.add(child.span.id); + if (predicate(child)) { + matches.push(latestSpanEvent(events, child.span.id) ?? child); + } + next.push(child.span.id); + } + } + } + frontier = next; + } + return matches.sort( + (left, right) => + firstSpanIndex(events, left) - firstSpanIndex(events, right), + ); +} + +function latestSpanEvent( + events: CapturedLogEvent[], + spanId: string | undefined, +): CapturedLogEvent | undefined { + if (!spanId) { + return undefined; + } + return [...events].reverse().find((event) => event.span.id === spanId); +} + +function firstSpanIndex( + events: CapturedLogEvent[], + event: CapturedLogEvent, +): number { + if (!event.span.id) { + return Number.MAX_SAFE_INTEGER; + } + const index = events.findIndex( + (candidate) => candidate.span.id === event.span.id, + ); + return index === -1 ? Number.MAX_SAFE_INTEGER : index; +} + +function findFlueDescendants( + events: CapturedLogEvent[], + flueSpan: CapturedLogEvent | undefined, + operationSpan: CapturedLogEvent | undefined, + predicate: (event: CapturedLogEvent) => boolean, +): CapturedLogEvent[] { + const bySpanId = new Map(); + for (const event of [ + ...findMatchingDescendants(events, flueSpan, predicate), + ...findMatchingDescendants(events, operationSpan, predicate), + ]) { + if (event.span.id && !bySpanId.has(event.span.id)) { + bySpanId.set(event.span.id, event); + } + } + return [...bySpanId.values()].sort( + (left, right) => + firstSpanIndex(events, left) - firstSpanIndex(events, right), + ); +} + +function isFlueChildSpan(event: CapturedLogEvent): boolean { + return ( + event.span.name === "flue.turn" || + event.span.name === "flue.task" || + event.span.name === "flue.compaction" || + event.span.name?.startsWith("tool: ") === true + ); +} + +function expectToolsAndTurnsShareParent( + parent: CapturedLogEvent | undefined, + turns: CapturedLogEvent[], + tools: CapturedLogEvent[], +): void { + expect(parent).toBeDefined(); + const parentId = parent?.span.id; + expect(parentId).toBeDefined(); + if (!parentId) { + return; + } + const turnIds = new Set( + turns.flatMap((event) => (event.span.id ? [event.span.id] : [])), + ); + + expect(turns.length).toBeGreaterThan(0); + expect(tools.length).toBeGreaterThan(0); + expect(turns.every((event) => event.span.parentIds.includes(parentId))).toBe( + true, + ); + expect(tools.every((event) => event.span.parentIds.includes(parentId))).toBe( + true, + ); + expect( + tools.some((event) => + event.span.parentIds.some((parentId) => turnIds.has(parentId)), + ), + ).toBe(false); +} + +function buildSpanTree(events: CapturedLogEvent[]): SpanTreeEntry[] { + const promptOperation = findLatestSpan(events, "flue-prompt-operation"); + const skillOperation = findLatestSpan(events, "flue-skill-operation"); + const taskOperation = findLatestSpan(events, "flue-task-operation"); + const compactOperation = findLatestSpan(events, "flue-compact-operation"); + const promptSpan = findFlueOperation( + events, + "flue-prompt-operation", + "flue.session.prompt", + ); + const skillSpan = findFlueOperation( + events, + "flue-skill-operation", + "flue.session.skill", + ); + const taskSpan = findFlueOperation( + events, + "flue-task-operation", + "flue.session.task", + ); + const compactSpan = findFlueOperation( + events, + "flue-compact-operation", + "flue.session.compact", + ); + + const promptChildren = findFlueDescendants( + events, + promptSpan, + promptOperation, + isFlueChildSpan, + ); + const skillChildren = findFlueDescendants( + events, + skillSpan, + skillOperation, + isFlueChildSpan, + ); + const taskChildren = findFlueDescendants( + events, + taskSpan, + taskOperation, + isFlueChildSpan, + ); + const compactChildren = findFlueDescendants( + events, + compactSpan, + compactOperation, + isFlueChildSpan, + ); + + return [ + findLatestSpan(events, ROOT_NAME), + promptOperation, + promptSpan, + ...promptChildren, + skillOperation, + skillSpan, + ...skillChildren, + taskOperation, + taskSpan, + ...taskChildren, + compactOperation, + compactSpan, + ...compactChildren, + ].flatMap((event) => + event ? [{ event, fields: snapshotFields(event) }] : [], + ); +} + +export function defineFlueInstrumentationAssertions(options: { + name: string; + runScenario: RunFlueScenario; + snapshotName: string; + testFileUrl: string; + timeoutMs: number; +}): void { + const snapshotPath = resolveFileSnapshotPath( + options.testFileUrl, + `${options.snapshotName}.span-tree.json`, + ); + const timeoutMs = effectiveScenarioTimeoutMs(options.timeoutMs); + const testConfig = { timeout: timeoutMs }; + + describe(options.name, () => { + let events: CapturedLogEvent[] = []; + + beforeAll(async () => { + await withScenarioHarness(async (harness) => { + await options.runScenario(harness); + events = harness.events(); + }); + }, timeoutMs); + + test("captures the root trace", testConfig, () => { + const root = findLatestSpan(events, ROOT_NAME); + + expect(root).toBeDefined(); + expect(root?.row.metadata).toMatchObject({ scenario: SCENARIO_NAME }); + }); + + test("captures wrapped Flue operation spans", testConfig, () => { + for (const [operationName, flueSpanName] of [ + ["flue-prompt-operation", "flue.session.prompt"], + ["flue-skill-operation", "flue.session.skill"], + ["flue-task-operation", "flue.session.task"], + ["flue-compact-operation", "flue.session.compact"], + ] as const) { + const operation = findLatestSpan(events, operationName); + const span = findLatestChildSpan( + events, + flueSpanName, + operation?.span.id, + ); + + expect(operation).toBeDefined(); + expect(span).toBeDefined(); + expect(span?.span.type).toBe("task"); + expect(span?.row.metadata).toMatchObject({ + provider: "flue", + }); + } + }); + + test( + "captures Flue child turn, tool, task, and compaction spans", + testConfig, + () => { + const promptSpan = findFlueOperation( + events, + "flue-prompt-operation", + "flue.session.prompt", + ); + const promptOperation = findLatestSpan(events, "flue-prompt-operation"); + const promptChildren = findFlueDescendants( + events, + promptSpan, + promptOperation, + isFlueChildSpan, + ); + const promptTurns = promptChildren.filter( + (event) => event.span.name === "flue.turn", + ); + const promptTools = promptChildren.filter((event) => + event.span.name?.startsWith("tool: "), + ); + const lookupToolSpan = promptTools.find( + (event) => event.span.name === "tool: lookup", + ); + const reasoningTurn = promptTurns.find((event) => + JSON.stringify(event.output).includes('"reasoning"'), + ); + const skillSpan = findFlueOperation( + events, + "flue-skill-operation", + "flue.session.skill", + ); + const skillOperation = findLatestSpan(events, "flue-skill-operation"); + const skillChildren = findFlueDescendants( + events, + skillSpan, + skillOperation, + isFlueChildSpan, + ); + const skillTurns = skillChildren.filter( + (event) => event.span.name === "flue.turn", + ); + const skillTools = skillChildren.filter((event) => + event.span.name?.startsWith("tool: "), + ); + const taskSpan = findFlueOperation( + events, + "flue-task-operation", + "flue.session.task", + ); + const taskOperation = findLatestSpan(events, "flue-task-operation"); + const childTask = findFlueDescendants( + events, + taskSpan, + taskOperation, + (event) => event.span.name === "flue.task", + )[0]; + const compactSpan = findFlueOperation( + events, + "flue-compact-operation", + "flue.session.compact", + ); + const compactOperation = findLatestSpan( + events, + "flue-compact-operation", + ); + const compaction = findFlueDescendants( + events, + compactSpan, + compactOperation, + (event) => event.span.name === "flue.compaction", + )[0]; + + expect(promptTurns.length).toBeGreaterThanOrEqual(3); + expect(promptTools.map((event) => event.span.name)).toEqual( + expect.arrayContaining([ + "tool: lookup", + "tool: web_search", + "tool: summarize_source", + ]), + ); + expectToolsAndTurnsShareParent(promptSpan, promptTurns, promptTools); + expectToolsAndTurnsShareParent(skillSpan, skillTurns, skillTools); + expect(reasoningTurn?.span.type).toBe("llm"); + expect(reasoningTurn?.output).toBeDefined(); + const reasoningOutput = JSON.stringify(reasoningTurn?.output); + expect(reasoningOutput).not.toContain(""); + expect(reasoningOutput).not.toContain("content unavailable"); + expect(reasoningOutput).not.toContain("[Reasoning redacted]"); + expect(reasoningTurn?.metadata).toMatchObject({ + "flue.thinking": true, + }); + expect(promptTurns[0]?.metrics).toMatchObject({ + completion_tokens: expect.any(Number), + prompt_tokens: expect.any(Number), + tokens: expect.any(Number), + }); + expect(lookupToolSpan?.span.type).toBe("tool"); + expect(lookupToolSpan?.input).toMatchObject({ + query: "flue instrumentation", + }); + expect(JSON.stringify(lookupToolSpan?.output)).toContain( + "flue-session-2026", + ); + expect(skillSpan?.output).toBe("SKILL_DONE"); + expect(childTask?.span.type).toBe("task"); + expect(childTask?.input).toBe( + "Reply with exactly TASK_DONE and no other text.", + ); + expect(compaction?.span.type).toBe("task"); + expect(compaction?.metadata).toMatchObject({ + "flue.compaction_reason": "manual", + }); + }, + ); + + test("does not instrument session.shell", testConfig, () => { + expect(findAllSpans(events, "flue.session.shell")).toHaveLength(0); + }); + + test("matches the span tree snapshot", testConfig, async () => { + await matchSpanTreeSnapshot(buildSpanTree(events), snapshotPath); + }); + }); +} diff --git a/e2e/scenarios/flue-instrumentation/cassette-filter.mjs b/e2e/scenarios/flue-instrumentation/cassette-filter.mjs new file mode 100644 index 000000000..31b01bfa4 --- /dev/null +++ b/e2e/scenarios/flue-instrumentation/cassette-filter.mjs @@ -0,0 +1,11 @@ +// @ts-check +/** @type {import("@braintrust/seinfeld").FilterSpec} */ +export const filter = [ + "default", + { + // Flue includes temp workspace paths, generated operation ids, and + // prompt_cache_key values in OpenAI Responses request bodies. The scenario + // call order is the stable contract, so use callIndex for disambiguation. + ignoreBodyFields: ["**"], + }, +]; diff --git a/e2e/scenarios/flue-instrumentation/constants.mjs b/e2e/scenarios/flue-instrumentation/constants.mjs new file mode 100644 index 000000000..1787ba58d --- /dev/null +++ b/e2e/scenarios/flue-instrumentation/constants.mjs @@ -0,0 +1,4 @@ +export const ROOT_NAME = "flue-root"; +export const SCENARIO_NAME = "flue-instrumentation"; +export const FLUE_MODEL = "openai/gpt-4o-mini"; +export const FLUE_REASONING_MODEL = "anthropic/claude-sonnet-4-5-20250929"; diff --git a/e2e/scenarios/flue-instrumentation/package.json b/e2e/scenarios/flue-instrumentation/package.json new file mode 100644 index 000000000..bd5839aab --- /dev/null +++ b/e2e/scenarios/flue-instrumentation/package.json @@ -0,0 +1,8 @@ +{ + "name": "flue-instrumentation-scenario", + "private": true, + "type": "module", + "dependencies": { + "@flue/runtime": "0.7.0" + } +} diff --git a/e2e/scenarios/flue-instrumentation/pnpm-lock.yaml b/e2e/scenarios/flue-instrumentation/pnpm-lock.yaml new file mode 100644 index 000000000..24d16999c --- /dev/null +++ b/e2e/scenarios/flue-instrumentation/pnpm-lock.yaml @@ -0,0 +1,2715 @@ +lockfileVersion: '9.0' + +settings: + autoInstallPeers: true + excludeLinksFromLockfile: false + +importers: + + .: + dependencies: + '@flue/runtime': + specifier: 0.7.0 + version: 0.7.0(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(typebox@1.1.38)(ws@8.20.1)(zod-to-json-schema@3.25.2(zod@4.4.3))(zod@4.4.3) + +packages: + + '@anthropic-ai/sdk@0.91.1': + resolution: {integrity: sha512-LAmu761tSN9r66ixvmciswUj/ZC+1Q4iAfpedTfSVLeswRwnY3n2Nb6Tsk+cLPP28aLOPWeMgIuTuCcMC6W/iw==} + hasBin: true + peerDependencies: + zod: ^3.25.0 || ^4.0.0 + peerDependenciesMeta: + zod: + optional: true + + '@aws-crypto/crc32@5.2.0': + resolution: {integrity: sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==} + engines: {node: '>=16.0.0'} + + '@aws-crypto/sha256-browser@5.2.0': + resolution: {integrity: sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==} + + '@aws-crypto/sha256-js@5.2.0': + resolution: {integrity: sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==} + engines: {node: '>=16.0.0'} + + '@aws-crypto/supports-web-crypto@5.2.0': + resolution: {integrity: sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==} + + '@aws-crypto/util@5.2.0': + resolution: {integrity: sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==} + + '@aws-sdk/client-bedrock-runtime@3.1048.0': + resolution: {integrity: sha512-u+NT61JZEkRFtpL0CAw1N1dwxnaLgwVXQl/zjJxTGgLyS/jTIdg2SdoEoCTHxgDyCnqa1HEi9QOoE9/pYRNpOQ==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/core@3.974.12': + resolution: {integrity: sha512-qrqgioqYFjwR6LatVNS1L2Vk++EwRIxqSQXPKNv5Ofux2D8UNgqMQ1znnMyEImXquVPTtbf71fc128pvmU6y9A==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-env@3.972.38': + resolution: {integrity: sha512-m3WjZEgPtioMhPmwqUt+DhlTJ2i9ufR6DhfkyXojb9puEvfR+ur2U5shavu5/Cc9WHHsDCvALi6UFHgcqjhQ5w==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-http@3.972.40': + resolution: {integrity: sha512-D78L/m2Dr6cJnnSvWoAudPhQmCwmJ7j6APXsPYmFpPaKfQTfCSu0rdm8j14Np+VmXF9z8Aj8HE3xFpsrwtfgeg==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-ini@3.972.42': + resolution: {integrity: sha512-Mu5ESvFXeinafVM8jTIvRqcvK2Ehj4kz3auT39yUcHwu1Vfxo6xRlmUafdKLW4tusjAJukQwK09sCSMgOm7OKg==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-login@3.972.42': + resolution: {integrity: sha512-O6WkZga3kf0yqyJYd1dbeJqVhEgJx/x1UaLgtbR+XuL/YP+K5y6QTxQKL7ka9z3jnQASESKGAPnRyt4D5hQrxA==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-node@3.972.43': + resolution: {integrity: sha512-D/DJmbrWRP5BXEO3FH+ar4el+2n6OlGofiud7dQun2jES+AQEJjczenp1jBb4MBN7CpGpS8nsWGQLtuzc9tQbA==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-process@3.972.38': + resolution: {integrity: sha512-EnbYVajGgbkb24s0K1eo4VNAPV5mHIET7LSvirTaFCwkfrfaOJxtSE+wY/tJdKDS21cEYkZs2ruCaAm+W4iblg==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-sso@3.972.42': + resolution: {integrity: sha512-RVV/9NbFwI8ZHEH5dn39lGyFmSbSVj1+orZdr6QsOe1mW9DCglmlen0cFaNZmCcqkqc7erNRHNBduxbeZuHAnw==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/credential-provider-web-identity@3.972.42': + resolution: {integrity: sha512-/67fXX0ddllD4u2Nujc5PvT4byHgpMUfz6+RxIKi/0nFIckeorm7JvXgzBuDyVKw0s58EbofmETDWUf9vTEuHQ==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/eventstream-handler-node@3.972.16': + resolution: {integrity: sha512-yedpPgKftqjU5SlPFHfqWpOw6xSCRieWRG1euWOlXn4WJxt2VX92VprCa2PpSOXjVCAeK6dTjW9eJRXVig9yGA==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/middleware-eventstream@3.972.12': + resolution: {integrity: sha512-tHTHHCHNrq6XklQvlzHBDJG4Iuhh7NVPRdtmvP+nHFA+5sxPlIDzlAHHgfoYHGvT3NXP1yVP/L5c3opUn6T3Qg==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/middleware-websocket@3.972.20': + resolution: {integrity: sha512-LM6P0i+Lu6pi25oNw2nqxjRxiEOtLgPB7xIvHfa+FxHTRLg8wcgqu3qg2COl4QaT7Es2yCxYdeRLVYazKAwL8g==} + engines: {node: '>= 14.0.0'} + + '@aws-sdk/nested-clients@3.997.10': + resolution: {integrity: sha512-FtQ/Bt327peZJuyo4WZSOLVUTw9ujRxntepiC7L65FxA2P82Xlq0g14T22BuqBUeMjDoxa9nvwiMHjLIfP3eUg==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/signature-v4-multi-region@3.996.27': + resolution: {integrity: sha512-0Phbz4t6HI3D3skxvG2uI+VWU034/nSIw1T8d+FPzzQG9EQTrw94o9mOKO2Gv3n3Oc8P7JD7RAUxkoneLWv5Eg==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/token-providers@3.1048.0': + resolution: {integrity: sha512-k0y/GcuesuSfWyUM0WamrGyeZmltRYaPbHO82UDA6mZ/doB+FOHKutikPAtSXMn/hDz970cF+iRuuiYO9VEbAA==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/token-providers@3.1049.0': + resolution: {integrity: sha512-r7+d0lQMTHKypkmaF5jRTBYLYHCUHzt3gaVoN9SidLhQeWhCmHk3AKrboDTpPF5b7Pt7vKu3+oeMjznM2Eu1ow==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/types@3.973.8': + resolution: {integrity: sha512-gjlAdtHMbtR9X5iIhVUvbVcy55KnznpC6bkDUWW9z915bi0ckdUr5cjf16Kp6xq0bP5HBD2xzgbL9F9Quv5vUw==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/util-locate-window@3.965.5': + resolution: {integrity: sha512-WhlJNNINQB+9qtLtZJcpQdgZw3SCDCpXdUJP7cToGwHbCWCnRckGlc6Bx/OhWwIYFNAn+FIydY8SZ0QmVu3xTQ==} + engines: {node: '>=20.0.0'} + + '@aws-sdk/xml-builder@3.972.24': + resolution: {integrity: sha512-V8z5YcDPfsvzrBlj0xR1vhRtocblhYbqdreCJB/voGd4Sr5zjNAeWxexbnqVtskTJe0vFb5KMqbSL++ePl+zRw==} + engines: {node: '>=20.0.0'} + + '@aws/lambda-invoke-store@0.2.4': + resolution: {integrity: sha512-iY8yvjE0y651BixKNPgmv1WrQc+GZ142sb0z4gYnChDDY2YqI4P/jsSopBWrKfAt7LOJAkOXt7rC/hms+WclQQ==} + engines: {node: '>=18.0.0'} + + '@babel/runtime@7.29.2': + resolution: {integrity: sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==} + engines: {node: '>=6.9.0'} + + '@borewit/text-codec@0.2.2': + resolution: {integrity: sha512-DDaRehssg1aNrH4+2hnj1B7vnUGEjU6OIlyRdkMd0aUdIUvKXrJfXsy8LVtXAy7DRvYVluWbMspsRhz2lcW0mQ==} + + '@cloudflare/codemode@0.3.7': + resolution: {integrity: sha512-Tc2AcF39ZExXMcCkTYtYGRHgIbWLePdWcRErEAS+RrpNgQht5dG0A9TkQDUQ1kyE43AC+gl4leVwhoWY2V9sWw==} + peerDependencies: + '@modelcontextprotocol/sdk': ^1.25.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/shell@0.3.8': + resolution: {integrity: sha512-tuseZ2bYEIiiOioGOgD9SqhchUQfHPOaRcifw8fj0YwTZNvcmO/wSvbtWDxxC/CUlnEJ1Y+tvNHub97TyTyoEQ==} + + '@earendil-works/pi-agent-core@0.75.4': + resolution: {integrity: sha512-cGYbysb4EqUf0B28OeqFq2ppm1XF3bYBOP71q9dv38yf/UJfzMjiXBeNelrcio+QWIoVrW+xzYm7sMzYIUc9Og==} + engines: {node: '>=22.19.0'} + + '@earendil-works/pi-ai@0.75.4': + resolution: {integrity: sha512-m/w8Hh3vQ0rAycwJiJWdzkypkn4295f4eq/966lDRy8aX5sk6bgYXH8TQmL16TO7Uwc7MbJG0QoyFHgX8RqXUQ==} + engines: {node: '>=22.19.0'} + hasBin: true + + '@flue/runtime@0.7.0': + resolution: {integrity: sha512-irkY9cqXkerzONBUtkrVBA869llLrzmzu97phWBm/z/LivgWBkt7YDfg8SrpNuTGbP9ScGjJmLtIXswe0Cz4Gw==} + engines: {node: '>=22.18.0'} + + '@google/genai@1.52.0': + resolution: {integrity: sha512-gwSvbpiN/17O9TbsqSsE/OzZcpv5Fo4RQjdngGgogtuB9RsyJ8ZHhX5KjHj1bp5N9snN2eK8LDGXSaWW2hof8Q==} + engines: {node: '>=20.0.0'} + peerDependencies: + '@modelcontextprotocol/sdk': ^1.25.2 + peerDependenciesMeta: + '@modelcontextprotocol/sdk': + optional: true + + '@hono/node-server@1.19.14': + resolution: {integrity: sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw==} + engines: {node: '>=18.14.1'} + peerDependencies: + hono: ^4 + + '@hono/standard-validator@0.2.2': + resolution: {integrity: sha512-mJ7W84Bt/rSvoIl63Ynew+UZOHAzzRAoAXb3JaWuxAkM/Lzg+ZHTCUiz77KOtn2e623WNN8LkD57Dk0szqUrIw==} + peerDependencies: + '@standard-schema/spec': ^1.0.0 + hono: '>=3.9.0' + + '@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==} + + '@mistralai/mistralai@2.2.1': + resolution: {integrity: sha512-uKU8CZmL2RzYKmplsU01hii4p3pe4HqJefpWNRWXm1Tcm0Sm4xXfwSLIy4k7ZCPlbETCGcp69E7hZs+WOJ5itQ==} + + '@mixmark-io/domino@2.2.0': + resolution: {integrity: sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw==} + + '@modelcontextprotocol/sdk@1.29.0': + resolution: {integrity: sha512-zo37mZA9hJWpULgkRpowewez1y6ML5GsXJPY8FI0tBBCd77HEvza4jDqRKOXgHNn867PVGCyTdzqpz0izu5ZjQ==} + 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'} + + '@nodable/entities@2.1.0': + resolution: {integrity: sha512-nyT7T3nbMyBI/lvr6L5TyWbFJAI9FTgVRakNoBqCD+PmID8DzFrrNdLLtHMwMszOtqZa8PAOV24ZqDnQrhQINA==} + + '@protobufjs/aspromise@1.1.2': + resolution: {integrity: sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==} + + '@protobufjs/base64@1.1.2': + resolution: {integrity: sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==} + + '@protobufjs/codegen@2.0.5': + resolution: {integrity: sha512-zgXFLzW3Ap33e6d0Wlj4MGIm6Ce8O89n/apUaGNB/jx+hw+ruWEp7EwGUshdLKVRCxZW12fp9r40E1mQrf/34g==} + + '@protobufjs/eventemitter@1.1.0': + resolution: {integrity: sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==} + + '@protobufjs/fetch@1.1.1': + resolution: {integrity: sha512-GpptLrs57adMSuHi3VNj0mAF8dwh36LMaYF6XyJ6JMWlVsc+t42tm1HSEDmOs3A8fC9yyeisgLhsTVQokOZ0zw==} + + '@protobufjs/float@1.0.2': + resolution: {integrity: sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==} + + '@protobufjs/inquire@1.1.2': + resolution: {integrity: sha512-pa0vFRuws4wkvaXKK1uXZMAwAX4/t8ANaJo45iw/oQHNQ9q5xUzwgFmVJGXiga2BeN+zpX7Vf9vmsiIa2J+MUw==} + + '@protobufjs/path@1.1.2': + resolution: {integrity: sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==} + + '@protobufjs/pool@1.1.0': + resolution: {integrity: sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==} + + '@protobufjs/utf8@1.1.1': + resolution: {integrity: sha512-oOAWABowe8EAbMyWKM0tYDKi8Yaox52D+HWZhAIJqQXbqe0xI/GV7FhLWqlEKreMkfDjshR5FKgi3mnle0h6Eg==} + + '@smithy/core@3.24.3': + resolution: {integrity: sha512-Ep/7tPamGY8mgESE3LyLKtxJyy6U52WWAqr/3wial47Sj4u3PiIF73AOGI27UyLy9duTkhZbgzodOfLV4TduZg==} + engines: {node: '>=18.0.0'} + + '@smithy/credential-provider-imds@4.3.3': + resolution: {integrity: sha512-I2Bti0DKFo2IJyN28ijCsx51BAumEYR4/1yZ1FXyBygy9MqbnMqCev4JPth/MbpRfBSRAX35hITSnAdJRo1u5w==} + engines: {node: '>=18.0.0'} + + '@smithy/fetch-http-handler@5.4.3': + resolution: {integrity: sha512-F+DRf8IJazRJgYog2A/yJK7eYVc0rqTlRzO+5ZxjJd4WkZoKz0IJRncf7G6t1pdVT3kryJcwuTFhN1c5m6N47A==} + engines: {node: '>=18.0.0'} + + '@smithy/is-array-buffer@2.2.0': + resolution: {integrity: sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==} + engines: {node: '>=14.0.0'} + + '@smithy/node-http-handler@4.7.3': + resolution: {integrity: sha512-/jPhevcTFPMVl6KNjbaI47iOg1zxC7IsnX4PQDGVZKMFceOXtB8IEYaB7a9VvkP/3oC60WzTeKocvSI7vLT0vA==} + engines: {node: '>=18.0.0'} + + '@smithy/signature-v4@5.4.3': + resolution: {integrity: sha512-53+75QuPl6DL+ct6vVEB51FDO5oulXr20TPV46VvJZg76lIlXNWfxi8j+G2V/t0I2qxCBOa3vX/8bmjrpFVo9g==} + engines: {node: '>=18.0.0'} + + '@smithy/types@4.14.2': + resolution: {integrity: sha512-P+otAxbV4CqBybp7EkcJCrig63yE2E7PuNVOmilVMRcx/O+QDzGULTrKsq4DV13gSfak9ObPrWaHl/9bL5YcWw==} + engines: {node: '>=18.0.0'} + + '@smithy/util-buffer-from@2.2.0': + resolution: {integrity: sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==} + engines: {node: '>=14.0.0'} + + '@smithy/util-utf8@2.3.0': + resolution: {integrity: sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==} + engines: {node: '>=14.0.0'} + + '@standard-community/standard-json@0.3.5': + resolution: {integrity: sha512-4+ZPorwDRt47i+O7RjyuaxHRK/37QY/LmgxlGrRrSTLYoFatEOzvqIc85GTlM18SFZ5E91C+v0o/M37wZPpUHA==} + peerDependencies: + '@standard-schema/spec': ^1.0.0 + '@types/json-schema': ^7.0.15 + '@valibot/to-json-schema': ^1.3.0 + arktype: ^2.1.20 + effect: ^3.16.8 + quansync: ^0.2.11 + sury: ^10.0.0 + typebox: ^1.0.17 + valibot: ^1.1.0 + zod: ^3.25.0 || ^4.0.0 + zod-to-json-schema: ^3.24.5 + peerDependenciesMeta: + '@valibot/to-json-schema': + optional: true + arktype: + optional: true + effect: + optional: true + sury: + optional: true + typebox: + optional: true + valibot: + optional: true + zod: + optional: true + zod-to-json-schema: + optional: true + + '@standard-community/standard-openapi@0.2.9': + resolution: {integrity: sha512-htj+yldvN1XncyZi4rehbf9kLbu8os2Ke/rfqoZHCMHuw34kiF3LP/yQPdA0tQ940y8nDq3Iou8R3wG+AGGyvg==} + peerDependencies: + '@standard-community/standard-json': ^0.3.5 + '@standard-schema/spec': ^1.0.0 + arktype: ^2.1.20 + effect: ^3.17.14 + openapi-types: ^12.1.3 + sury: ^10.0.0 + typebox: ^1.0.0 + valibot: ^1.1.0 + zod: ^3.25.0 || ^4.0.0 + zod-openapi: ^4 + peerDependenciesMeta: + arktype: + optional: true + effect: + optional: true + sury: + optional: true + typebox: + optional: true + valibot: + optional: true + zod: + optional: true + zod-openapi: + optional: true + + '@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/json-schema@7.0.15': + resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} + + '@types/node@25.9.1': + resolution: {integrity: sha512-xfrlY7UD5rMJk3ZVJP8BNzS28J36YJg+xp+LPXV1TdWxr8uMH5A860QNxYDGQe/ylDSgjxE52Q9VnO7p75tJxg==} + + '@types/retry@0.12.0': + resolution: {integrity: sha512-wWKOClTTiizcZhXnPY4wikVAwmdYHp8q6DmC+EJUzAMsycb7HB32Kh9RN4+0gExjmPmZSAQjgURXIGATPegAvA==} + + '@valibot/to-json-schema@1.7.0': + resolution: {integrity: sha512-Y3pPVibbIOHzohrlxSINvO7w/bvXkoYS3BQHoImV9ynE+bXKf171bdMucPurV2zp7gdmt0L1HCcNAsbo7cFRQw==} + peerDependencies: + valibot: ^1.4.0 + + 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.16.0: + resolution: {integrity: sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==} + engines: {node: '>=0.4.0'} + hasBin: true + + agent-base@7.1.4: + resolution: {integrity: sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==} + engines: {node: '>= 14'} + + 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==} + + 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'} + + 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==} + + bignumber.js@9.3.1: + resolution: {integrity: sha512-Ko0uX15oIUS7wJ3Rb30Fs6SkVbLmPBAKdlm7q9+ak9bbIeFf0MwuBsQV6z7+X768/cHsfg+WlysDWJcmthjsjQ==} + + bl@4.1.0: + resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} + + body-parser@2.2.2: + resolution: {integrity: sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==} + engines: {node: '>=18'} + + bowser@2.14.1: + resolution: {integrity: sha512-tzPjzCxygAKWFOJP011oxFHs57HzIhOEracIgAePE4pqB3LikALKnSzUyU4MGs9/iCEUuHlAJTjTc5M+u7YEGg==} + + brace-expansion@5.0.6: + resolution: {integrity: sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==} + engines: {node: 18 || 20 || >=22} + + buffer-equal-constant-time@1.0.1: + resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==} + + 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'} + + chownr@1.1.4: + resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} + + clean-git-ref@2.0.1: + resolution: {integrity: sha512-bLSptAy2P0s6hU4PzuIMKmMJJSE6gLXGH1cntDu7bWJUksvuM+7ReOK61mozULErYvP6a15rnYl0zFDef+pyPw==} + + 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'} + + 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'} + + 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 + + cross-spawn@7.0.6: + resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} + engines: {node: '>= 8'} + + data-uri-to-buffer@4.0.1: + resolution: {integrity: sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==} + engines: {node: '>= 12'} + + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + + 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'} + + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + + 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'} + + ecdsa-sig-formatter@1.0.11: + resolution: {integrity: sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==} + + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + + 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==} + + 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.1: + resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + engines: {node: '>= 0.4'} + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + + 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.0.8: + resolution: {integrity: sha512-70QWGkr4snxr0OXLRWsFLeRBIRPuQOvt4s8QYjmUlmlkyTZkRqS7EDVRZtzU3TiyDbXSzaOeF0XUKy8PchzukQ==} + 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.5.2: + resolution: {integrity: sha512-5Kb34ipNX694DH48vN9irak1Qx30nb0PLYHXfJgw4YEjiC3ZEmZJhwOp+VfiCYwFzvFTdB9QkArYS5kXa2cx2A==} + 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.2: + resolution: {integrity: sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==} + + fast-xml-builder@1.2.0: + resolution: {integrity: sha512-00aAWieqff+ZJhsXA4g1g7M8k+7AYoMUUHF+/zFb5U6Uv/P0Vl4QZo84/IcufzYalLuEj9928bXN9PbbFzMF0Q==} + + fast-xml-parser@5.7.3: + resolution: {integrity: sha512-C0AaNuC+mscy6vrAQKAc/rMq+zAPHodfHGZu4sGVehvAQt/JLG1O5zEcYcXSY5zSqr4YVgxsB+pHXTq0i7eDlg==} + hasBin: true + + fast-xml-parser@5.8.0: + resolution: {integrity: sha512-6bIM7fsJxeo3uXv7OncQYsBAMPJ7V16Slahl/6M98C/i2q+vB1+4a0MtrvYwDFEUrwDSbAmeLDRXsOBwrL7yAg==} + hasBin: true + + fetch-blob@3.2.0: + resolution: {integrity: sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==} + engines: {node: ^12.20 || >= 14.13} + + 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'} + + formdata-polyfill@4.0.10: + resolution: {integrity: sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==} + engines: {node: '>=12.20.0'} + + 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==} + + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + gaxios@7.1.4: + resolution: {integrity: sha512-bTIgTsM2bWn3XklZISBTQX7ZSddGW+IO3bMdGaemHZ3tbqExMENHLx6kKZ/KlejgrMtj8q7wBItt51yegqalrA==} + engines: {node: '>=18'} + + gcp-metadata@8.1.2: + resolution: {integrity: sha512-zV/5HKTfCeKWnxG0Dmrw51hEWFGfcF2xiXqcA3+J90WDuP0SvoiSO5ORvcBsifmx/FoIjgQN3oNOGaQ5PhLFkg==} + 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==} + + google-auth-library@10.6.2: + resolution: {integrity: sha512-e27Z6EThmVNNvtYASwQxose/G57rkRuaRbQyxM2bvYLLX/GqWZ5chWq2EBoUchJbCc57eC9ArzO5wMsEmWftCw==} + engines: {node: '>=18'} + + google-logging-utils@1.1.3: + resolution: {integrity: sha512-eAmLkjDjAFCVXg7A1unxHsLf961m6y17QFqXqAXGj/gVkKFrEICfStRfwUlGNfeCEjNRa32JEWOUTlYXPyyKvA==} + engines: {node: '>=14'} + + 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.3: + resolution: {integrity: sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==} + engines: {node: '>= 0.4'} + + hono-openapi@1.3.0: + resolution: {integrity: sha512-xDvCWpWEIv0weEmnl3EjRQzqbHIO8LnfzMuYOCmbuyE5aes6aXxLg4vM3ybnoZD5TiTUkA6PuRQPJs3R7WRBig==} + peerDependencies: + '@hono/standard-validator': ^0.2.0 + '@standard-community/standard-json': ^0.3.5 + '@standard-community/standard-openapi': ^0.2.9 + '@types/json-schema': ^7.0.15 + hono: ^4.8.3 + openapi-types: ^12.1.3 + peerDependenciesMeta: + '@hono/standard-validator': + optional: true + hono: + optional: true + + hono@4.12.21: + resolution: {integrity: sha512-uV63apnb0kyPtAUwoWgaGh9HyIFcv8lgmzPZSiTBQAFOFGIzka5EZ1dZocmGnn0XdX0+XTqJ6Tqv7selMuGLRQ==} + engines: {node: '>=16.9.0'} + + http-errors@2.0.1: + resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} + engines: {node: '>= 0.8'} + + http-proxy-agent@7.0.2: + resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} + engines: {node: '>= 14'} + + https-proxy-agent@7.0.6: + resolution: {integrity: sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==} + engines: {node: '>= 14'} + + iconv-lite@0.7.2: + resolution: {integrity: sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==} + 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'} + + ignore@7.0.5: + resolution: {integrity: sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==} + engines: {node: '>= 4'} + + 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.2.0: + resolution: {integrity: sha512-/+S6j4E9AHvW9SWMSEY9Xfy66O5PWvVEJ08O0y5JGyEKQpojb0K0GKpz/v5HJ/G0vi3D2sjGK78119oXZeE0qA==} + 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-promise@4.0.0: + resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} + + is-typed-array@1.1.15: + resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} + engines: {node: '>= 0.4'} + + isarray@2.0.5: + resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} + + isexe@2.0.0: + resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + + isomorphic-git@1.38.1: + resolution: {integrity: sha512-Vd2u5qDLa04fA/h5nUMU5UuffPXqg+3D3bJIV3n7Sno2qS3XMinUXRvNHrGPVy2kkC1ad5SPCC3WcpXjn0L9oQ==} + engines: {node: '>=14.17'} + hasBin: true + + jose@6.2.3: + resolution: {integrity: sha512-YYVDInQKFJfR/xa3ojUTl8c2KoTwiL1R5Wg9YCydwH0x0B9grbzlg5HC7mMjCtUJjbQ/YnGEZIhI5tCgfTb4Hw==} + + json-bigint@1.0.0: + resolution: {integrity: sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==} + + json-schema-to-ts@3.1.1: + resolution: {integrity: sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g==} + engines: {node: '>=16'} + + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + json-schema-typed@8.0.2: + resolution: {integrity: sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==} + + just-bash@2.14.5: + resolution: {integrity: sha512-MCBGnRlDeZ/MM7mcw+ZuSGFMBsggajrmKz6e/hrOAN7syvVZkjiY+Vh2wyCwN/CdcnAX5SxbiQB51n5nrQuX+g==} + hasBin: true + + jwa@2.0.1: + resolution: {integrity: sha512-hRF04fqJIP8Abbkq5NKGN0Bbr3JxlQ+qhZufXVr0DvujKy93ZCbXZMHDL4EOtodSbCWxOqR8MS1tXA5hwqCXDg==} + + jws@4.0.1: + resolution: {integrity: sha512-EKI/M/yqPncGUUh44xz0PxSidXFr/+r0pA70+gIYhjv+et7yxM+s29Y+VGDkovRofQem0fs7Uvf4+YmAdyRduA==} + + layerr@3.0.0: + resolution: {integrity: sha512-tv754Ki2dXpPVApOrjTyRo4/QegVb9eVFq4mjqp4+NM5NaX7syQvN5BBNfV/ZpAHCEHV24XdUVrBAoka4jt3pA==} + + long@5.3.2: + resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + 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'} + + mime-db@1.54.0: + resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} + engines: {node: '>= 0.6'} + + mime-types@3.0.2: + resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} + engines: {node: '>=18'} + + mimic-response@3.1.0: + resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==} + engines: {node: '>=10'} + + 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.6: + resolution: {integrity: sha512-sweCIVXzx1aIGTCdzcMlSZt1h8k5Tmk08VNAuRk3IU28XamGiOH5ypi11g6De2CH7PhYqSSnGy2A/EFhbWnVKg==} + engines: {node: '>=18.0.0'} + + ms@2.1.3: + resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + + 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.92.0: + resolution: {integrity: sha512-KdHvFWZjEKDf0cakgFjebl371GPsISX2oZHcuyKqM7DtogIsHrqKeLTo8wBHxaXRAQlY2PsPlZmfo+9ZCxEREQ==} + engines: {node: '>=10'} + + node-addon-api@8.7.0: + resolution: {integrity: sha512-9MdFxmkKaOYVTV+XVRG8ArDwwQ77XIgIPyKASB1k3JPq3M8fGQQQE3YpMOrKm6g//Ktx8ivZr8xo1Qmtqub+GA==} + engines: {node: ^18 || ^20 || >= 21} + + node-domexception@1.0.0: + resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} + engines: {node: '>=10.5.0'} + deprecated: Use your platform's native DOMException instead + + node-fetch@3.3.2: + resolution: {integrity: sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + + 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 + + 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'} + + 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==} + + openai@6.26.0: + resolution: {integrity: sha512-zd23dbWTjiJ6sSAX6s0HrCZi41JwTA1bQVs0wLQPZ2/5o2gxOJA5wh7yOAUgwYybfhDXyhwlpeQf7Mlgx8EOCA==} + hasBin: true + peerDependencies: + ws: ^8.18.0 + zod: ^3.25 || ^4.0 + peerDependenciesMeta: + ws: + optional: true + zod: + optional: true + + openapi-types@12.1.3: + resolution: {integrity: sha512-N4YtSYJqghVu4iek2ZUvcN/0aqH1kRDuNqzcycDxhOUpg7GdvLa2F3DgS6yBNhInhv2r/6I0Flkn7CqL8+nIcw==} + + p-retry@4.6.2: + resolution: {integrity: sha512-312Id396EbJdvRONlngUx0NydfrIQ5lsYu0znKVUzVvArzEIt08V1qhtyESbGVd1FGX7UKtiFp5uwKZdM8wIuQ==} + engines: {node: '>=8'} + + pako@1.0.11: + resolution: {integrity: sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==} + + papaparse@5.5.3: + resolution: {integrity: sha512-5QvjGxYVjxO59MGU2lHVYpRWBBtKHnlIAcSe1uNFCkkptUh63NFRj0FJQm7nR67puEruUci/ZkjmEFrjCAyP4A==} + + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + partial-json@0.1.7: + resolution: {integrity: sha512-Njv/59hHaokb/hRUjce3Hdv12wd60MtM9Z5Olmn+nehe0QDAsRtRbJPvJ0Z91TusF0SuZRIvnM+S4l6EIP8leA==} + + path-expression-matcher@1.5.0: + resolution: {integrity: sha512-cbrerZV+6rvdQrrD+iGMcZFEiiSrbv9Tfdkvnusy6y0x0GKBXREFg/Y65GhIfm0tnLntThhzCnfKwp1WRjeCyQ==} + engines: {node: '>=14.0.0'} + + path-key@3.1.1: + resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} + engines: {node: '>=8'} + + path-to-regexp@8.4.2: + resolution: {integrity: sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==} + + 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'} + + 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'} + + protobufjs@7.6.0: + resolution: {integrity: sha512-LtESOsMPTZgyYtwxhvdgdjGL0HmXEaRA/hVD6sol4zA60hVXXXP/SGmxnqDbgGE8gy7pYex7cym+5vYPcmaXBQ==} + engines: {node: '>=12.0.0'} + + proxy-addr@2.0.7: + resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} + engines: {node: '>= 0.10'} + + pump@3.0.4: + resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==} + + qs@6.15.2: + resolution: {integrity: sha512-Rzq0KEyX/w/tEybncDgdkZrJgVUsUMk3xjh3t5bv3S1HTAtg+uOYt72+ZfwiQwKdysThkTBdL/rTi6HDmX9Ddw==} + engines: {node: '>=0.6'} + + quansync@0.2.11: + resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} + + 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.2.1: + resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} + 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==} + + 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} + + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + + retry@0.13.1: + resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} + engines: {node: '>= 4'} + + 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.0: + resolution: {integrity: sha512-AcM7dV/5ul4EekoQ29Agm5vri8JNqRyj39o0qpX6vDF2GZrtutZl5RwgD1XnZjiTAfncsJhMI48QQH3sN87YNA==} + 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 + + 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.0: + resolution: {integrity: sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==} + 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.6.1: + resolution: {integrity: sha512-dWUG8F5sIIARXih1DTaQAX4SsiTXhInKf1buxdY9DIg4ZYPZK5nGM1VRIYmEbDbsHt7USo99xSLFu5Q1IqTmsg==} + engines: {node: '>= 18'} + + 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_decoder@1.3.0: + resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + + strip-json-comments@2.0.1: + resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==} + engines: {node: '>=0.10.0'} + + strnum@2.3.0: + resolution: {integrity: sha512-ums3KNd42PGyx5xaoVTO1mjU1bH3NpY4vsrVlnv9PNGqQj8wd7rJ6nEypLrJ7z5vxK5RP0yMLo6J/Gsm62DI5Q==} + + strtok3@10.3.5: + resolution: {integrity: sha512-ki4hZQfh5rX0QDLLkOCj+h+CVNkqmp/CMf8v8kZpkNVK6jGQooMytqzLZYUVYIZcFZ6yDB70EfD8POcFXiF5oA==} + engines: {node: '>=18'} + + tar-fs@2.1.4: + resolution: {integrity: sha512-mDAjwmZdh7LTT6pNleZ05Yt65HC3E+NiQzl672vQG38jIrehtJk/J3mNwIg+vShQPcLF/LV7CMnDW6vjj6sfYQ==} + + tar-stream@2.2.0: + resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} + engines: {node: '>=6'} + + 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'} + + ts-algebra@2.0.0: + resolution: {integrity: sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw==} + + 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'} + + typebox@1.1.38: + resolution: {integrity: sha512-pZ0aQPmMmXoUvSbeuWf/Hzsc+avNw/Zd6VeE8CFgkVGWyuHPJvqeJJDeJqLve+K70LvjYIoleGcoJHPT17cWoA==} + + 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'} + + ulidx@2.4.1: + resolution: {integrity: sha512-xY7c8LPyzvhvew0Fn+Ek3wBC9STZAuDI/Y5andCKi9AX6/jvfaX45PhsDX8oxgPL0YFp0Jhr8qWMbS/p9375Xg==} + engines: {node: '>=16'} + + undici-types@7.24.6: + resolution: {integrity: sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==} + + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + util-deprecate@1.0.2: + resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + + valibot@1.4.0: + resolution: {integrity: sha512-iC/x7fVcSyOwlm/VSt7RlHnzNGLGvR9GnxdifUeWoCJo0q4ZZvrVkIHC6faTlkxG47I2Y4UrFquPuVHCrOnrLg==} + peerDependencies: + typescript: '>=5' + peerDependenciesMeta: + typescript: + optional: true + + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + web-streams-polyfill@3.3.3: + resolution: {integrity: sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==} + engines: {node: '>= 8'} + + which-typed-array@1.1.20: + resolution: {integrity: sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==} + engines: {node: '>= 0.4'} + + which@2.0.2: + resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} + engines: {node: '>= 8'} + hasBin: true + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + + ws@8.20.1: + resolution: {integrity: sha512-It4dO0K5v//JtTXuPkfEOaI3uUN87iYPnqo/ZzqCoG3g8uhA66QUMs/SrM0YK7/NAu+r4LMh/9dq2A7k+rHs+w==} + 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.1.0: + resolution: {integrity: sha512-k8KO9hrMyNk6tUWqUfkTEZbezRRpONVOzUTnc97VnCvyj6Tf9lyUR9EDAIeiVLv56jsMcoXEwjW8Kv5yPY52lw==} + engines: {node: '>=16.0.0'} + + yaml@2.9.0: + resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==} + engines: {node: '>= 14.6'} + hasBin: true + + zod-to-json-schema@3.25.2: + resolution: {integrity: sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==} + peerDependencies: + zod: ^3.25.28 || ^4 + + zod@4.4.3: + resolution: {integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==} + +snapshots: + + '@anthropic-ai/sdk@0.91.1(zod@4.4.3)': + dependencies: + json-schema-to-ts: 3.1.1 + optionalDependencies: + zod: 4.4.3 + + '@aws-crypto/crc32@5.2.0': + dependencies: + '@aws-crypto/util': 5.2.0 + '@aws-sdk/types': 3.973.8 + tslib: 2.8.1 + + '@aws-crypto/sha256-browser@5.2.0': + dependencies: + '@aws-crypto/sha256-js': 5.2.0 + '@aws-crypto/supports-web-crypto': 5.2.0 + '@aws-crypto/util': 5.2.0 + '@aws-sdk/types': 3.973.8 + '@aws-sdk/util-locate-window': 3.965.5 + '@smithy/util-utf8': 2.3.0 + tslib: 2.8.1 + + '@aws-crypto/sha256-js@5.2.0': + dependencies: + '@aws-crypto/util': 5.2.0 + '@aws-sdk/types': 3.973.8 + tslib: 2.8.1 + + '@aws-crypto/supports-web-crypto@5.2.0': + dependencies: + tslib: 2.8.1 + + '@aws-crypto/util@5.2.0': + dependencies: + '@aws-sdk/types': 3.973.8 + '@smithy/util-utf8': 2.3.0 + tslib: 2.8.1 + + '@aws-sdk/client-bedrock-runtime@3.1048.0': + dependencies: + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/core': 3.974.12 + '@aws-sdk/credential-provider-node': 3.972.43 + '@aws-sdk/eventstream-handler-node': 3.972.16 + '@aws-sdk/middleware-eventstream': 3.972.12 + '@aws-sdk/middleware-websocket': 3.972.20 + '@aws-sdk/token-providers': 3.1048.0 + '@aws-sdk/types': 3.973.8 + '@smithy/core': 3.24.3 + '@smithy/fetch-http-handler': 5.4.3 + '@smithy/node-http-handler': 4.7.3 + '@smithy/types': 4.14.2 + tslib: 2.8.1 + + '@aws-sdk/core@3.974.12': + dependencies: + '@aws-sdk/types': 3.973.8 + '@aws-sdk/xml-builder': 3.972.24 + '@aws/lambda-invoke-store': 0.2.4 + '@smithy/core': 3.24.3 + '@smithy/signature-v4': 5.4.3 + '@smithy/types': 4.14.2 + bowser: 2.14.1 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-env@3.972.38': + dependencies: + '@aws-sdk/core': 3.974.12 + '@aws-sdk/types': 3.973.8 + '@smithy/core': 3.24.3 + '@smithy/types': 4.14.2 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-http@3.972.40': + dependencies: + '@aws-sdk/core': 3.974.12 + '@aws-sdk/types': 3.973.8 + '@smithy/core': 3.24.3 + '@smithy/fetch-http-handler': 5.4.3 + '@smithy/node-http-handler': 4.7.3 + '@smithy/types': 4.14.2 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-ini@3.972.42': + dependencies: + '@aws-sdk/core': 3.974.12 + '@aws-sdk/credential-provider-env': 3.972.38 + '@aws-sdk/credential-provider-http': 3.972.40 + '@aws-sdk/credential-provider-login': 3.972.42 + '@aws-sdk/credential-provider-process': 3.972.38 + '@aws-sdk/credential-provider-sso': 3.972.42 + '@aws-sdk/credential-provider-web-identity': 3.972.42 + '@aws-sdk/nested-clients': 3.997.10 + '@aws-sdk/types': 3.973.8 + '@smithy/core': 3.24.3 + '@smithy/credential-provider-imds': 4.3.3 + '@smithy/types': 4.14.2 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-login@3.972.42': + dependencies: + '@aws-sdk/core': 3.974.12 + '@aws-sdk/nested-clients': 3.997.10 + '@aws-sdk/types': 3.973.8 + '@smithy/core': 3.24.3 + '@smithy/types': 4.14.2 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-node@3.972.43': + dependencies: + '@aws-sdk/credential-provider-env': 3.972.38 + '@aws-sdk/credential-provider-http': 3.972.40 + '@aws-sdk/credential-provider-ini': 3.972.42 + '@aws-sdk/credential-provider-process': 3.972.38 + '@aws-sdk/credential-provider-sso': 3.972.42 + '@aws-sdk/credential-provider-web-identity': 3.972.42 + '@aws-sdk/types': 3.973.8 + '@smithy/core': 3.24.3 + '@smithy/credential-provider-imds': 4.3.3 + '@smithy/types': 4.14.2 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-process@3.972.38': + dependencies: + '@aws-sdk/core': 3.974.12 + '@aws-sdk/types': 3.973.8 + '@smithy/core': 3.24.3 + '@smithy/types': 4.14.2 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-sso@3.972.42': + dependencies: + '@aws-sdk/core': 3.974.12 + '@aws-sdk/nested-clients': 3.997.10 + '@aws-sdk/token-providers': 3.1049.0 + '@aws-sdk/types': 3.973.8 + '@smithy/core': 3.24.3 + '@smithy/types': 4.14.2 + tslib: 2.8.1 + + '@aws-sdk/credential-provider-web-identity@3.972.42': + dependencies: + '@aws-sdk/core': 3.974.12 + '@aws-sdk/nested-clients': 3.997.10 + '@aws-sdk/types': 3.973.8 + '@smithy/core': 3.24.3 + '@smithy/types': 4.14.2 + tslib: 2.8.1 + + '@aws-sdk/eventstream-handler-node@3.972.16': + dependencies: + '@aws-sdk/types': 3.973.8 + '@smithy/core': 3.24.3 + '@smithy/types': 4.14.2 + tslib: 2.8.1 + + '@aws-sdk/middleware-eventstream@3.972.12': + dependencies: + '@aws-sdk/types': 3.973.8 + '@smithy/core': 3.24.3 + '@smithy/types': 4.14.2 + tslib: 2.8.1 + + '@aws-sdk/middleware-websocket@3.972.20': + dependencies: + '@aws-sdk/core': 3.974.12 + '@aws-sdk/types': 3.973.8 + '@smithy/core': 3.24.3 + '@smithy/fetch-http-handler': 5.4.3 + '@smithy/signature-v4': 5.4.3 + '@smithy/types': 4.14.2 + tslib: 2.8.1 + + '@aws-sdk/nested-clients@3.997.10': + dependencies: + '@aws-crypto/sha256-browser': 5.2.0 + '@aws-crypto/sha256-js': 5.2.0 + '@aws-sdk/core': 3.974.12 + '@aws-sdk/signature-v4-multi-region': 3.996.27 + '@aws-sdk/types': 3.973.8 + '@smithy/core': 3.24.3 + '@smithy/fetch-http-handler': 5.4.3 + '@smithy/node-http-handler': 4.7.3 + '@smithy/types': 4.14.2 + tslib: 2.8.1 + + '@aws-sdk/signature-v4-multi-region@3.996.27': + dependencies: + '@aws-sdk/types': 3.973.8 + '@smithy/core': 3.24.3 + '@smithy/signature-v4': 5.4.3 + '@smithy/types': 4.14.2 + tslib: 2.8.1 + + '@aws-sdk/token-providers@3.1048.0': + dependencies: + '@aws-sdk/core': 3.974.12 + '@aws-sdk/nested-clients': 3.997.10 + '@aws-sdk/types': 3.973.8 + '@smithy/core': 3.24.3 + '@smithy/types': 4.14.2 + tslib: 2.8.1 + + '@aws-sdk/token-providers@3.1049.0': + dependencies: + '@aws-sdk/core': 3.974.12 + '@aws-sdk/nested-clients': 3.997.10 + '@aws-sdk/types': 3.973.8 + '@smithy/core': 3.24.3 + '@smithy/types': 4.14.2 + tslib: 2.8.1 + + '@aws-sdk/types@3.973.8': + dependencies: + '@smithy/types': 4.14.2 + tslib: 2.8.1 + + '@aws-sdk/util-locate-window@3.965.5': + dependencies: + tslib: 2.8.1 + + '@aws-sdk/xml-builder@3.972.24': + dependencies: + '@nodable/entities': 2.1.0 + '@smithy/types': 4.14.2 + fast-xml-parser: 5.7.3 + tslib: 2.8.1 + + '@aws/lambda-invoke-store@0.2.4': {} + + '@babel/runtime@7.29.2': {} + + '@borewit/text-codec@0.2.2': {} + + '@cloudflare/codemode@0.3.7(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))(zod@4.4.3)': + dependencies: + '@types/json-schema': 7.0.15 + acorn: 8.16.0 + optionalDependencies: + '@modelcontextprotocol/sdk': 1.29.0(zod@4.4.3) + zod: 4.4.3 + + '@cloudflare/shell@0.3.8(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))(zod@4.4.3)': + dependencies: + '@cloudflare/codemode': 0.3.7(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))(zod@4.4.3) + isomorphic-git: 1.38.1 + transitivePeerDependencies: + - '@modelcontextprotocol/sdk' + - '@tanstack/ai' + - ai + - zod + + '@earendil-works/pi-agent-core@0.75.4(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))(ws@8.20.1)(zod@4.4.3)': + dependencies: + '@earendil-works/pi-ai': 0.75.4(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))(ws@8.20.1)(zod@4.4.3) + ignore: 7.0.5 + typebox: 1.1.38 + yaml: 2.9.0 + transitivePeerDependencies: + - '@modelcontextprotocol/sdk' + - bufferutil + - supports-color + - utf-8-validate + - ws + - zod + + '@earendil-works/pi-ai@0.75.4(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))(ws@8.20.1)(zod@4.4.3)': + dependencies: + '@anthropic-ai/sdk': 0.91.1(zod@4.4.3) + '@aws-sdk/client-bedrock-runtime': 3.1048.0 + '@google/genai': 1.52.0(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3)) + '@mistralai/mistralai': 2.2.1 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.6 + openai: 6.26.0(ws@8.20.1)(zod@4.4.3) + partial-json: 0.1.7 + typebox: 1.1.38 + transitivePeerDependencies: + - '@modelcontextprotocol/sdk' + - bufferutil + - supports-color + - utf-8-validate + - ws + - zod + + '@flue/runtime@0.7.0(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(typebox@1.1.38)(ws@8.20.1)(zod-to-json-schema@3.25.2(zod@4.4.3))(zod@4.4.3)': + dependencies: + '@cloudflare/codemode': 0.3.7(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))(zod@4.4.3) + '@cloudflare/shell': 0.3.8(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))(zod@4.4.3) + '@earendil-works/pi-agent-core': 0.75.4(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))(ws@8.20.1)(zod@4.4.3) + '@earendil-works/pi-ai': 0.75.4(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))(ws@8.20.1)(zod@4.4.3) + '@hono/node-server': 1.19.14(hono@4.12.21) + '@hono/standard-validator': 0.2.2(@standard-schema/spec@1.1.0)(hono@4.12.21) + '@modelcontextprotocol/sdk': 1.29.0(zod@4.4.3) + '@standard-community/standard-json': 0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(@valibot/to-json-schema@1.7.0(valibot@1.4.0))(quansync@0.2.11)(typebox@1.1.38)(valibot@1.4.0)(zod-to-json-schema@3.25.2(zod@4.4.3))(zod@4.4.3) + '@standard-community/standard-openapi': 0.2.9(@standard-community/standard-json@0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(@valibot/to-json-schema@1.7.0(valibot@1.4.0))(quansync@0.2.11)(typebox@1.1.38)(valibot@1.4.0)(zod-to-json-schema@3.25.2(zod@4.4.3))(zod@4.4.3))(@standard-schema/spec@1.1.0)(openapi-types@12.1.3)(typebox@1.1.38)(valibot@1.4.0)(zod@4.4.3) + '@valibot/to-json-schema': 1.7.0(valibot@1.4.0) + hono: 4.12.21 + hono-openapi: 1.3.0(@hono/standard-validator@0.2.2(@standard-schema/spec@1.1.0)(hono@4.12.21))(@standard-community/standard-json@0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(@valibot/to-json-schema@1.7.0(valibot@1.4.0))(quansync@0.2.11)(typebox@1.1.38)(valibot@1.4.0)(zod-to-json-schema@3.25.2(zod@4.4.3))(zod@4.4.3))(@standard-community/standard-openapi@0.2.9(@standard-community/standard-json@0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(@valibot/to-json-schema@1.7.0(valibot@1.4.0))(quansync@0.2.11)(typebox@1.1.38)(valibot@1.4.0)(zod-to-json-schema@3.25.2(zod@4.4.3))(zod@4.4.3))(@standard-schema/spec@1.1.0)(openapi-types@12.1.3)(typebox@1.1.38)(valibot@1.4.0)(zod@4.4.3))(@types/json-schema@7.0.15)(hono@4.12.21)(openapi-types@12.1.3) + just-bash: 2.14.5 + openapi-types: 12.1.3 + quansync: 0.2.11 + ulidx: 2.4.1 + valibot: 1.4.0 + transitivePeerDependencies: + - '@cfworker/json-schema' + - '@standard-schema/spec' + - '@tanstack/ai' + - '@types/json-schema' + - ai + - arktype + - bufferutil + - effect + - supports-color + - sury + - typebox + - typescript + - utf-8-validate + - ws + - zod + - zod-openapi + - zod-to-json-schema + + '@google/genai@1.52.0(@modelcontextprotocol/sdk@1.29.0(zod@4.4.3))': + dependencies: + google-auth-library: 10.6.2 + p-retry: 4.6.2 + protobufjs: 7.6.0 + ws: 8.20.1 + optionalDependencies: + '@modelcontextprotocol/sdk': 1.29.0(zod@4.4.3) + transitivePeerDependencies: + - bufferutil + - supports-color + - utf-8-validate + + '@hono/node-server@1.19.14(hono@4.12.21)': + dependencies: + hono: 4.12.21 + + '@hono/standard-validator@0.2.2(@standard-schema/spec@1.1.0)(hono@4.12.21)': + dependencies: + '@standard-schema/spec': 1.1.0 + hono: 4.12.21 + + '@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 + + '@mistralai/mistralai@2.2.1': + dependencies: + ws: 8.20.1 + zod: 4.4.3 + zod-to-json-schema: 3.25.2(zod@4.4.3) + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@mixmark-io/domino@2.2.0': {} + + '@modelcontextprotocol/sdk@1.29.0(zod@4.4.3)': + dependencies: + '@hono/node-server': 1.19.14(hono@4.12.21) + 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.0.8 + express: 5.2.1 + express-rate-limit: 8.5.2(express@5.2.1) + hono: 4.12.21 + jose: 6.2.3 + json-schema-typed: 8.0.2 + pkce-challenge: 5.0.1 + raw-body: 3.0.2 + zod: 4.4.3 + zod-to-json-schema: 3.25.2(zod@4.4.3) + transitivePeerDependencies: + - supports-color + + '@mongodb-js/zstd@7.0.0': + dependencies: + node-addon-api: 8.7.0 + prebuild-install: 7.1.3 + optional: true + + '@nodable/entities@2.1.0': {} + + '@protobufjs/aspromise@1.1.2': {} + + '@protobufjs/base64@1.1.2': {} + + '@protobufjs/codegen@2.0.5': {} + + '@protobufjs/eventemitter@1.1.0': {} + + '@protobufjs/fetch@1.1.1': + dependencies: + '@protobufjs/aspromise': 1.1.2 + + '@protobufjs/float@1.0.2': {} + + '@protobufjs/inquire@1.1.2': {} + + '@protobufjs/path@1.1.2': {} + + '@protobufjs/pool@1.1.0': {} + + '@protobufjs/utf8@1.1.1': {} + + '@smithy/core@3.24.3': + dependencies: + '@aws-crypto/crc32': 5.2.0 + '@smithy/types': 4.14.2 + tslib: 2.8.1 + + '@smithy/credential-provider-imds@4.3.3': + dependencies: + '@smithy/core': 3.24.3 + '@smithy/types': 4.14.2 + tslib: 2.8.1 + + '@smithy/fetch-http-handler@5.4.3': + dependencies: + '@smithy/core': 3.24.3 + '@smithy/types': 4.14.2 + tslib: 2.8.1 + + '@smithy/is-array-buffer@2.2.0': + dependencies: + tslib: 2.8.1 + + '@smithy/node-http-handler@4.7.3': + dependencies: + '@smithy/core': 3.24.3 + '@smithy/types': 4.14.2 + tslib: 2.8.1 + + '@smithy/signature-v4@5.4.3': + dependencies: + '@smithy/core': 3.24.3 + '@smithy/types': 4.14.2 + tslib: 2.8.1 + + '@smithy/types@4.14.2': + dependencies: + tslib: 2.8.1 + + '@smithy/util-buffer-from@2.2.0': + dependencies: + '@smithy/is-array-buffer': 2.2.0 + tslib: 2.8.1 + + '@smithy/util-utf8@2.3.0': + dependencies: + '@smithy/util-buffer-from': 2.2.0 + tslib: 2.8.1 + + '@standard-community/standard-json@0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(@valibot/to-json-schema@1.7.0(valibot@1.4.0))(quansync@0.2.11)(typebox@1.1.38)(valibot@1.4.0)(zod-to-json-schema@3.25.2(zod@4.4.3))(zod@4.4.3)': + dependencies: + '@standard-schema/spec': 1.1.0 + '@types/json-schema': 7.0.15 + quansync: 0.2.11 + optionalDependencies: + '@valibot/to-json-schema': 1.7.0(valibot@1.4.0) + typebox: 1.1.38 + valibot: 1.4.0 + zod: 4.4.3 + zod-to-json-schema: 3.25.2(zod@4.4.3) + + '@standard-community/standard-openapi@0.2.9(@standard-community/standard-json@0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(@valibot/to-json-schema@1.7.0(valibot@1.4.0))(quansync@0.2.11)(typebox@1.1.38)(valibot@1.4.0)(zod-to-json-schema@3.25.2(zod@4.4.3))(zod@4.4.3))(@standard-schema/spec@1.1.0)(openapi-types@12.1.3)(typebox@1.1.38)(valibot@1.4.0)(zod@4.4.3)': + dependencies: + '@standard-community/standard-json': 0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(@valibot/to-json-schema@1.7.0(valibot@1.4.0))(quansync@0.2.11)(typebox@1.1.38)(valibot@1.4.0)(zod-to-json-schema@3.25.2(zod@4.4.3))(zod@4.4.3) + '@standard-schema/spec': 1.1.0 + openapi-types: 12.1.3 + optionalDependencies: + typebox: 1.1.38 + valibot: 1.4.0 + zod: 4.4.3 + + '@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/json-schema@7.0.15': {} + + '@types/node@25.9.1': + dependencies: + undici-types: 7.24.6 + + '@types/retry@0.12.0': {} + + '@valibot/to-json-schema@1.7.0(valibot@1.4.0)': + dependencies: + valibot: 1.4.0 + + 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.16.0: {} + + agent-base@7.1.4: {} + + 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.2 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + + async-lock@1.4.1: {} + + available-typed-arrays@1.0.7: + dependencies: + possible-typed-array-names: 1.1.0 + + balanced-match@4.0.4: {} + + base64-js@1.5.1: {} + + bignumber.js@9.3.1: {} + + bl@4.1.0: + dependencies: + buffer: 5.7.1 + inherits: 2.0.4 + readable-stream: 3.6.2 + optional: true + + body-parser@2.2.2: + dependencies: + bytes: 3.1.2 + content-type: 1.0.5 + debug: 4.4.3 + http-errors: 2.0.1 + iconv-lite: 0.7.2 + on-finished: 2.4.1 + qs: 6.15.2 + raw-body: 3.0.2 + type-is: 2.1.0 + transitivePeerDependencies: + - supports-color + + bowser@2.14.1: {} + + brace-expansion@5.0.6: + dependencies: + balanced-match: 4.0.4 + + buffer-equal-constant-time@1.0.1: {} + + 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 + + chownr@1.1.4: + optional: true + + clean-git-ref@2.0.1: {} + + commander@6.2.1: {} + + content-disposition@1.1.0: {} + + content-type@1.0.5: {} + + content-type@2.0.0: {} + + cookie-signature@1.2.2: {} + + cookie@0.7.2: {} + + cors@2.8.6: + dependencies: + object-assign: 4.1.1 + vary: 1.1.2 + + crc-32@1.2.2: {} + + cross-spawn@7.0.6: + dependencies: + path-key: 3.1.1 + shebang-command: 2.0.0 + which: 2.0.2 + + data-uri-to-buffer@4.0.1: {} + + debug@4.4.3: + dependencies: + ms: 2.1.3 + + 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: {} + + detect-libc@2.1.2: + optional: true + + 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 + + ecdsa-sig-formatter@1.0.11: + dependencies: + safe-buffer: 5.2.1 + + ee-first@1.1.1: {} + + encodeurl@2.0.0: {} + + end-of-stream@1.4.5: + dependencies: + once: 1.4.0 + optional: true + + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-object-atoms@1.1.1: + dependencies: + es-errors: 1.3.0 + + escape-html@1.0.3: {} + + etag@1.8.1: {} + + event-target-shim@5.0.1: {} + + events@3.3.0: {} + + eventsource-parser@3.0.8: {} + + eventsource@3.0.7: + dependencies: + eventsource-parser: 3.0.8 + + expand-template@2.0.3: + optional: true + + express-rate-limit@8.5.2(express@5.2.1): + dependencies: + express: 5.2.1 + ip-address: 10.2.0 + + express@5.2.1: + dependencies: + accepts: 2.0.0 + body-parser: 2.2.2 + 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.7 + qs: 6.15.2 + range-parser: 1.2.1 + 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.2: {} + + fast-xml-builder@1.2.0: + dependencies: + path-expression-matcher: 1.5.0 + xml-naming: 0.1.0 + + fast-xml-parser@5.7.3: + dependencies: + '@nodable/entities': 2.1.0 + fast-xml-builder: 1.2.0 + path-expression-matcher: 1.5.0 + strnum: 2.3.0 + + fast-xml-parser@5.8.0: + dependencies: + '@nodable/entities': 2.1.0 + fast-xml-builder: 1.2.0 + path-expression-matcher: 1.5.0 + strnum: 2.3.0 + xml-naming: 0.1.0 + + fetch-blob@3.2.0: + dependencies: + node-domexception: 1.0.0 + web-streams-polyfill: 3.3.3 + + 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 + + formdata-polyfill@4.0.10: + dependencies: + fetch-blob: 3.2.0 + + forwarded@0.2.0: {} + + fresh@2.0.0: {} + + fs-constants@1.0.0: + optional: true + + function-bind@1.1.2: {} + + gaxios@7.1.4: + dependencies: + extend: 3.0.2 + https-proxy-agent: 7.0.6 + node-fetch: 3.3.2 + transitivePeerDependencies: + - supports-color + + gcp-metadata@8.1.2: + dependencies: + gaxios: 7.1.4 + google-logging-utils: 1.1.3 + json-bigint: 1.0.0 + transitivePeerDependencies: + - supports-color + + 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.1 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.3 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.1 + + github-from-package@0.0.0: + optional: true + + google-auth-library@10.6.2: + dependencies: + base64-js: 1.5.1 + ecdsa-sig-formatter: 1.0.11 + gaxios: 7.1.4 + gcp-metadata: 8.1.2 + google-logging-utils: 1.1.3 + jws: 4.0.1 + transitivePeerDependencies: + - supports-color + + google-logging-utils@1.1.3: {} + + 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.3: + dependencies: + function-bind: 1.1.2 + + hono-openapi@1.3.0(@hono/standard-validator@0.2.2(@standard-schema/spec@1.1.0)(hono@4.12.21))(@standard-community/standard-json@0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(@valibot/to-json-schema@1.7.0(valibot@1.4.0))(quansync@0.2.11)(typebox@1.1.38)(valibot@1.4.0)(zod-to-json-schema@3.25.2(zod@4.4.3))(zod@4.4.3))(@standard-community/standard-openapi@0.2.9(@standard-community/standard-json@0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(@valibot/to-json-schema@1.7.0(valibot@1.4.0))(quansync@0.2.11)(typebox@1.1.38)(valibot@1.4.0)(zod-to-json-schema@3.25.2(zod@4.4.3))(zod@4.4.3))(@standard-schema/spec@1.1.0)(openapi-types@12.1.3)(typebox@1.1.38)(valibot@1.4.0)(zod@4.4.3))(@types/json-schema@7.0.15)(hono@4.12.21)(openapi-types@12.1.3): + dependencies: + '@standard-community/standard-json': 0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(@valibot/to-json-schema@1.7.0(valibot@1.4.0))(quansync@0.2.11)(typebox@1.1.38)(valibot@1.4.0)(zod-to-json-schema@3.25.2(zod@4.4.3))(zod@4.4.3) + '@standard-community/standard-openapi': 0.2.9(@standard-community/standard-json@0.3.5(@standard-schema/spec@1.1.0)(@types/json-schema@7.0.15)(@valibot/to-json-schema@1.7.0(valibot@1.4.0))(quansync@0.2.11)(typebox@1.1.38)(valibot@1.4.0)(zod-to-json-schema@3.25.2(zod@4.4.3))(zod@4.4.3))(@standard-schema/spec@1.1.0)(openapi-types@12.1.3)(typebox@1.1.38)(valibot@1.4.0)(zod@4.4.3) + '@types/json-schema': 7.0.15 + openapi-types: 12.1.3 + optionalDependencies: + '@hono/standard-validator': 0.2.2(@standard-schema/spec@1.1.0)(hono@4.12.21) + hono: 4.12.21 + + hono@4.12.21: {} + + 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 + + http-proxy-agent@7.0.2: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + https-proxy-agent@7.0.6: + dependencies: + agent-base: 7.1.4 + debug: 4.4.3 + transitivePeerDependencies: + - supports-color + + iconv-lite@0.7.2: + dependencies: + safer-buffer: 2.1.2 + + ieee754@1.2.1: {} + + ignore@5.3.2: {} + + ignore@7.0.5: {} + + inherits@2.0.4: {} + + ini@1.3.8: + optional: true + + ini@6.0.0: {} + + ip-address@10.2.0: {} + + ipaddr.js@1.9.1: {} + + is-callable@1.2.7: {} + + is-promise@4.0.0: {} + + is-typed-array@1.1.15: + dependencies: + which-typed-array: 1.1.20 + + isarray@2.0.5: {} + + isexe@2.0.0: {} + + isomorphic-git@1.38.1: + 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: {} + + json-bigint@1.0.0: + dependencies: + bignumber.js: 9.3.1 + + json-schema-to-ts@3.1.1: + dependencies: + '@babel/runtime': 7.29.2 + ts-algebra: 2.0.0 + + json-schema-traverse@1.0.0: {} + + json-schema-typed@8.0.2: {} + + just-bash@2.14.5: + dependencies: + diff: 8.0.4 + fast-xml-parser: 5.8.0 + file-type: 21.3.4 + ini: 6.0.0 + minimatch: 10.2.5 + modern-tar: 0.7.6 + papaparse: 5.5.3 + quickjs-emscripten: 0.32.0 + re2js: 1.3.3 + seek-bzip: 2.0.0 + smol-toml: 1.6.1 + 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 + + jwa@2.0.1: + dependencies: + buffer-equal-constant-time: 1.0.1 + ecdsa-sig-formatter: 1.0.11 + safe-buffer: 5.2.1 + + jws@4.0.1: + dependencies: + jwa: 2.0.1 + safe-buffer: 5.2.1 + + layerr@3.0.0: {} + + long@5.3.2: {} + + math-intrinsics@1.1.0: {} + + media-typer@1.1.0: {} + + merge-descriptors@2.0.0: {} + + mime-db@1.54.0: {} + + mime-types@3.0.2: + dependencies: + mime-db: 1.54.0 + + mimic-response@3.1.0: {} + + minimatch@10.2.5: + dependencies: + brace-expansion: 5.0.6 + + minimist@1.2.8: {} + + minimisted@2.0.1: + dependencies: + minimist: 1.2.8 + + mkdirp-classic@0.5.3: + optional: true + + modern-tar@0.7.6: {} + + ms@2.1.3: {} + + napi-build-utils@2.0.0: + optional: true + + negotiator@1.0.0: {} + + node-abi@3.92.0: + dependencies: + semver: 7.8.0 + optional: true + + node-addon-api@8.7.0: + optional: true + + node-domexception@1.0.0: {} + + node-fetch@3.3.2: + dependencies: + data-uri-to-buffer: 4.0.1 + fetch-blob: 3.2.0 + formdata-polyfill: 4.0.10 + + node-gyp-build@4.8.4: + optional: true + + node-liblzma@2.2.0: + dependencies: + node-addon-api: 8.7.0 + node-gyp-build: 4.8.4 + optional: true + + object-assign@4.1.1: {} + + object-inspect@1.13.4: {} + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + openai@6.26.0(ws@8.20.1)(zod@4.4.3): + optionalDependencies: + ws: 8.20.1 + zod: 4.4.3 + + openapi-types@12.1.3: {} + + p-retry@4.6.2: + dependencies: + '@types/retry': 0.12.0 + retry: 0.13.1 + + pako@1.0.11: {} + + papaparse@5.5.3: {} + + parseurl@1.3.3: {} + + partial-json@0.1.7: {} + + path-expression-matcher@1.5.0: {} + + path-key@3.1.1: {} + + path-to-regexp@8.4.2: {} + + pify@4.0.1: {} + + pkce-challenge@5.0.1: {} + + possible-typed-array-names@1.1.0: {} + + 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.92.0 + pump: 3.0.4 + rc: 1.2.8 + simple-get: 4.0.1 + tar-fs: 2.1.4 + tunnel-agent: 0.6.0 + optional: true + + process@0.11.10: {} + + protobufjs@7.6.0: + dependencies: + '@protobufjs/aspromise': 1.1.2 + '@protobufjs/base64': 1.1.2 + '@protobufjs/codegen': 2.0.5 + '@protobufjs/eventemitter': 1.1.0 + '@protobufjs/fetch': 1.1.1 + '@protobufjs/float': 1.0.2 + '@protobufjs/inquire': 1.1.2 + '@protobufjs/path': 1.1.2 + '@protobufjs/pool': 1.1.0 + '@protobufjs/utf8': 1.1.1 + '@types/node': 25.9.1 + long: 5.3.2 + + proxy-addr@2.0.7: + 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.2: + dependencies: + side-channel: 1.1.0 + + quansync@0.2.11: {} + + 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.2.1: {} + + raw-body@3.0.2: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.1 + iconv-lite: 0.7.2 + 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: {} + + 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 + + require-from-string@2.0.2: {} + + retry@0.13.1: {} + + 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.0: + optional: true + + 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.2.1 + 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 + + 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.0: + 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.6.1: {} + + sprintf-js@1.1.3: {} + + sql.js@1.14.1: {} + + statuses@2.0.2: {} + + string_decoder@1.3.0: + dependencies: + safe-buffer: 5.2.1 + + strip-json-comments@2.0.1: + optional: true + + strnum@2.3.0: {} + + strtok3@10.3.5: + dependencies: + '@tokenizer/token': 0.3.0 + + tar-fs@2.1.4: + 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 + + 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 + + ts-algebra@2.0.0: {} + + tslib@2.8.1: {} + + 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 + + typebox@1.1.38: {} + + 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: {} + + ulidx@2.4.1: + dependencies: + layerr: 3.0.0 + + undici-types@7.24.6: {} + + unpipe@1.0.0: {} + + util-deprecate@1.0.2: + optional: true + + valibot@1.4.0: {} + + vary@1.1.2: {} + + web-streams-polyfill@3.3.3: {} + + which-typed-array@1.1.20: + 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 + + wrappy@1.0.2: {} + + ws@8.20.1: {} + + xml-naming@0.1.0: {} + + yaml@2.9.0: {} + + zod-to-json-schema@3.25.2(zod@4.4.3): + dependencies: + zod: 4.4.3 + + zod@4.4.3: {} diff --git a/e2e/scenarios/flue-instrumentation/scenario.impl.mjs b/e2e/scenarios/flue-instrumentation/scenario.impl.mjs new file mode 100644 index 000000000..04c77c4c5 --- /dev/null +++ b/e2e/scenarios/flue-instrumentation/scenario.impl.mjs @@ -0,0 +1,217 @@ +import { Type } from "@flue/runtime"; +import { configureProvider } from "@flue/runtime/app"; +import { + createFlueContext, + InMemorySessionStore, + resolveModel, +} from "@flue/runtime/internal"; +import { local } from "@flue/runtime/node"; +import { wrapFlueContext } from "braintrust"; +import { + runMain, + runOperation, + runTracedScenario, +} from "../../helpers/provider-runtime.mjs"; +import { + FLUE_MODEL, + FLUE_REASONING_MODEL, + ROOT_NAME, + SCENARIO_NAME, +} from "./constants.mjs"; + +const openAIBaseUrl = + process.env.OPENAI_BASE_URL ?? process.env.BRAINTRUST_E2E_MODEL_BASE_URL; +if (openAIBaseUrl) { + configureProvider("openai", { baseUrl: openAIBaseUrl }); +} + +const anthropicBaseUrl = process.env.ANTHROPIC_BASE_URL; +if (anthropicBaseUrl) { + configureProvider("anthropic", { + apiKey: process.env.ANTHROPIC_API_KEY ?? "test-key", + baseUrl: anthropicBaseUrl, + }); +} + +function makeContext() { + const sandbox = local({ cwd: process.cwd() }); + return createFlueContext({ + agentConfig: { + compaction: { + keepRecentTokens: 1, + reserveTokens: 64, + }, + model: resolveModel(FLUE_MODEL), + resolveModel, + roles: { + skillRunner: { + description: "Runs the Flue e2e skill without delegating.", + instructions: [ + "Never call the task tool.", + "Do not delegate e2e-flue-skill to another session.", + "If you need the skill body, read .agents/skills/e2e-flue-skill/SKILL.md yourself with the read tool.", + "Return the marker from the Arguments object exactly, with no other text.", + ].join(" "), + name: "skillRunner", + }, + }, + skills: {}, + systemPrompt: [ + "You are a deterministic Flue instrumentation test agent.", + "Follow user instructions exactly.", + "When asked for a marker, output only that marker and no extra text.", + "When running a local skill file, read it yourself and do not delegate it to a task.", + ].join(" "), + thinkingLevel: "off", + }, + createDefaultEnv: async () => + sandbox.createSessionEnv({ + cwd: process.cwd(), + id: "flue-e2e-default", + }), + defaultStore: new InMemorySessionStore(), + env: process.env, + id: "flue-e2e-instance", + payload: { + scenario: SCENARIO_NAME, + }, + runId: `flue-e2e-${process.env.BRAINTRUST_E2E_RUN_ID ?? "local"}`, + }); +} + +const lookupTool = { + description: + "Return a deterministic lookup result with an id needed by web_search.", + execute: async (args) => + JSON.stringify({ + id: "flue-session-2026", + query: args.query, + topic: "session instrumentation", + }), + name: "lookup", + parameters: Type.Object({ + query: Type.String(), + }), +}; + +const webSearchTool = { + description: + "Search a deterministic local web index. Requires the id returned by lookup.", + execute: async (args) => + JSON.stringify({ + lookupId: args.lookupId, + query: args.query, + results: [ + { + title: "Flue reasoning stream instrumentation", + url: "https://example.test/flue/reasoning-streams", + }, + ], + }), + name: "web_search", + parameters: Type.Object({ + lookupId: Type.String(), + query: Type.String(), + }), +}; + +const summarizeSourceTool = { + description: + "Summarize the selected deterministic source after web_search returns a URL.", + execute: async (args) => + JSON.stringify({ + summary: + "Flue emits reasoning, tool execution, and LLM turn events separately.", + url: args.url, + }), + name: "summarize_source", + parameters: Type.Object({ + url: Type.String(), + }), +}; + +export async function runFlueInstrumentationScenario({ wrapContext }) { + const rawContext = makeContext(); + const ctx = wrapContext ? wrapFlueContext(rawContext) : rawContext; + + await runTracedScenario({ + callback: async () => { + const harness = await ctx.init({ + compaction: { + keepRecentTokens: 1, + reserveTokens: 64, + }, + cwd: process.cwd(), + model: FLUE_MODEL, + sandbox: local({ cwd: process.cwd() }), + }); + const session = await harness.session("main"); + const skillSession = await harness.session("skill"); + const taskSession = await harness.session("task"); + + await runOperation("flue-prompt-operation", "prompt", async () => { + await session.prompt( + [ + "Complete this instrumented research flow.", + "Call exactly one tool per turn and wait for each tool result before choosing the next tool.", + 'Step 1: call lookup with query "flue instrumentation".', + 'Step 2: use the lookup result id as lookupId and call web_search with query "Braintrust Flue reasoning stream instrumentation".', + "Step 3: use the first web_search result url and call summarize_source.", + "After summarize_source returns, reply with exactly PROMPT_DONE and no other text.", + ].join(" "), + { + cacheRetention: "none", + maxTokens: 2048, + model: FLUE_REASONING_MODEL, + thinkingLevel: "medium", + tools: [lookupTool, webSearchTool, summarizeSourceTool], + }, + ); + }); + + await runOperation("flue-skill-operation", "skill", async () => { + await skillSession.skill("e2e-flue-skill", { + args: { marker: "SKILL_DONE" }, + cacheRetention: "none", + maxTokens: 128, + model: FLUE_REASONING_MODEL, + role: "skillRunner", + thinkingLevel: "off", + }); + }); + + await runOperation("flue-task-operation", "task", async () => { + await taskSession.task( + "Reply with exactly TASK_DONE and no other text.", + { + cacheRetention: "none", + maxTokens: 32, + model: FLUE_MODEL, + thinkingLevel: "off", + }, + ); + }); + + await runOperation("flue-compact-operation", "compact", async () => { + await session.compact(); + }); + }, + flushCount: 2, + flushDelayMs: 100, + metadata: { + scenario: SCENARIO_NAME, + }, + projectNameBase: "e2e-flue-instrumentation", + rootName: ROOT_NAME, + }); +} + +export function runWrappedFlueInstrumentation() { + return runFlueInstrumentationScenario({ wrapContext: true }); +} + +export function runAutoFlueInstrumentation() { + return runFlueInstrumentationScenario({ wrapContext: false }); +} + +export { runMain }; diff --git a/e2e/scenarios/flue-instrumentation/scenario.mjs b/e2e/scenarios/flue-instrumentation/scenario.mjs new file mode 100644 index 000000000..015d18e6d --- /dev/null +++ b/e2e/scenarios/flue-instrumentation/scenario.mjs @@ -0,0 +1,3 @@ +import { runAutoFlueInstrumentation, runMain } from "./scenario.impl.mjs"; + +runMain(runAutoFlueInstrumentation); diff --git a/e2e/scenarios/flue-instrumentation/scenario.test.ts b/e2e/scenarios/flue-instrumentation/scenario.test.ts new file mode 100644 index 000000000..717c1743f --- /dev/null +++ b/e2e/scenarios/flue-instrumentation/scenario.test.ts @@ -0,0 +1,58 @@ +import { describe } from "vitest"; +import { + prepareScenarioDir, + readInstalledPackageVersion, + resolveScenarioDir, +} from "../../helpers/scenario-harness"; +import { defineFlueInstrumentationAssertions } from "./assertions"; + +const originalScenarioDir = resolveScenarioDir(import.meta.url); +const scenarioDir = await prepareScenarioDir({ + scenarioDir: originalScenarioDir, +}); +const flueVersion = await readInstalledPackageVersion( + scenarioDir, + "@flue/runtime", +); +const TIMEOUT_MS = 120_000; +const wrappedVariantKey = "flue-v0-7-0-wrapped"; +const autoHookVariantKey = "flue-v0-7-0-auto-hook"; + +describe(`flue ${flueVersion}`, () => { + defineFlueInstrumentationAssertions({ + name: "wrapped instrumentation", + runScenario: async ({ runScenarioDir }) => { + await runScenarioDir({ + entry: "scenario.ts", + runContext: { + originalScenarioDir, + variantKey: wrappedVariantKey, + }, + scenarioDir, + timeoutMs: TIMEOUT_MS, + }); + }, + snapshotName: "flue-v0-7-0-wrapped", + testFileUrl: import.meta.url, + timeoutMs: TIMEOUT_MS, + }); + + defineFlueInstrumentationAssertions({ + name: "auto-hook instrumentation", + runScenario: async ({ runNodeScenarioDir }) => { + await runNodeScenarioDir({ + entry: "scenario.mjs", + nodeArgs: ["--import", "braintrust/hook.mjs"], + runContext: { + originalScenarioDir, + variantKey: autoHookVariantKey, + }, + scenarioDir, + timeoutMs: TIMEOUT_MS, + }); + }, + snapshotName: "flue-v0-7-0-auto-hook", + testFileUrl: import.meta.url, + timeoutMs: TIMEOUT_MS, + }); +}); diff --git a/e2e/scenarios/flue-instrumentation/scenario.ts b/e2e/scenarios/flue-instrumentation/scenario.ts new file mode 100644 index 000000000..c5c71cef2 --- /dev/null +++ b/e2e/scenarios/flue-instrumentation/scenario.ts @@ -0,0 +1,3 @@ +import { runMain, runWrappedFlueInstrumentation } from "./scenario.impl.mjs"; + +runMain(runWrappedFlueInstrumentation); diff --git a/js/src/auto-instrumentations/configs/ai-sdk.test.ts b/js/src/auto-instrumentations/configs/ai-sdk.test.ts deleted file mode 100644 index 2c8390800..000000000 --- a/js/src/auto-instrumentations/configs/ai-sdk.test.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { describe, expect, it } from "vitest"; -import { aiSDKChannels } from "../../instrumentation/plugins/ai-sdk-channels"; -import { aiSDKConfigs } from "./ai-sdk"; - -function findConfigsByFunctionName(functionName: string) { - return aiSDKConfigs.filter((config) => { - if (!("functionQuery" in config)) { - return false; - } - const query = config.functionQuery as { functionName?: unknown }; - return query.functionName === functionName; - }); -} - -describe("aiSDKConfigs", () => { - it("defines embed channels", () => { - expect(aiSDKChannels.embed.channelName).toBe("embed"); - expect(aiSDKChannels.embedMany.channelName).toBe("embedMany"); - expect(aiSDKChannels.rerank.channelName).toBe("rerank"); - }); - - it("instruments embed() in both ESM and CJS entrypoints", () => { - const embedConfigs = findConfigsByFunctionName("embed"); - - expect(embedConfigs).toHaveLength(2); - expect(embedConfigs.map((config) => config.channelName)).toEqual([ - aiSDKChannels.embed.channelName, - aiSDKChannels.embed.channelName, - ]); - expect(embedConfigs.map((config) => config.module.filePath).sort()).toEqual( - ["dist/index.js", "dist/index.mjs"], - ); - }); - - it("instruments embedMany() in both ESM and CJS entrypoints", () => { - const embedManyConfigs = findConfigsByFunctionName("embedMany"); - - expect(embedManyConfigs).toHaveLength(2); - expect(embedManyConfigs.map((config) => config.channelName)).toEqual([ - aiSDKChannels.embedMany.channelName, - aiSDKChannels.embedMany.channelName, - ]); - expect( - embedManyConfigs.map((config) => config.module.filePath).sort(), - ).toEqual(["dist/index.js", "dist/index.mjs"]); - }); - - it("instruments rerank() in both ESM and CJS entrypoints", () => { - const rerankConfigs = findConfigsByFunctionName("rerank"); - - expect(rerankConfigs).toHaveLength(2); - expect(rerankConfigs.map((config) => config.channelName)).toEqual([ - aiSDKChannels.rerank.channelName, - aiSDKChannels.rerank.channelName, - ]); - expect( - rerankConfigs.map((config) => config.module.filePath).sort(), - ).toEqual(["dist/index.js", "dist/index.mjs"]); - expect(rerankConfigs.map((config) => config.module.versionRange)).toEqual([ - ">=5.0.0", - ">=5.0.0", - ]); - }); -}); diff --git a/js/src/auto-instrumentations/configs/all.test.ts b/js/src/auto-instrumentations/configs/all.test.ts deleted file mode 100644 index af0c2920b..000000000 --- a/js/src/auto-instrumentations/configs/all.test.ts +++ /dev/null @@ -1,40 +0,0 @@ -import { describe, expect, it } from "vitest"; -import type { InstrumentationConfig } from "@apm-js-collab/code-transformer"; -import { aiSDKConfigs } from "./ai-sdk"; -import { getDefaultInstrumentationConfigs } from "./all"; -import { googleADKConfigs } from "./google-adk"; -import { openaiConfigs } from "./openai"; -import { openAICodexConfigs } from "./openai-codex"; - -describe("getDefaultInstrumentationConfigs", () => { - it("includes config families that used to drift between entrypoints", () => { - const configs = getDefaultInstrumentationConfigs(); - - expect(configs).toContain(openAICodexConfigs[0]); - expect(configs).toContain(googleADKConfigs[0]); - }); - - it("appends custom instrumentations after the defaults", () => { - const customConfig: InstrumentationConfig = { - ...openaiConfigs[0], - channelName: "custom.test", - }; - - const configs = getDefaultInstrumentationConfigs({ - additionalInstrumentations: [customConfig], - }); - - expect(configs[configs.length - 1]).toBe(customConfig); - }); - - it("filters disabled integration aliases for the load-time hook", () => { - const configs = getDefaultInstrumentationConfigs({ - disabledIntegrations: new Set(["openai-codex", "googleadk", "vercel-ai"]), - }); - - expect(configs).not.toContain(openAICodexConfigs[0]); - expect(configs).not.toContain(googleADKConfigs[0]); - expect(configs).not.toContain(aiSDKConfigs[0]); - expect(configs).toContain(openaiConfigs[0]); - }); -}); diff --git a/js/src/auto-instrumentations/configs/all.ts b/js/src/auto-instrumentations/configs/all.ts index be558f31a..f496afc94 100644 --- a/js/src/auto-instrumentations/configs/all.ts +++ b/js/src/auto-instrumentations/configs/all.ts @@ -4,6 +4,7 @@ import { anthropicConfigs } from "./anthropic"; import { claudeAgentSDKConfigs } from "./claude-agent-sdk"; import { cohereConfigs } from "./cohere"; import { cursorSDKConfigs } from "./cursor-sdk"; +import { flueConfigs } from "./flue"; import { genkitConfigs } from "./genkit"; import { gitHubCopilotConfigs } from "./github-copilot"; import { googleADKConfigs } from "./google-adk"; @@ -38,6 +39,7 @@ const defaultInstrumentationConfigGroups: readonly InstrumentationConfigGroup[] configs: claudeAgentSDKConfigs, }, { disabledNames: ["cursor", "cursor-sdk"], configs: cursorSDKConfigs }, + { disabledNames: ["flue", "flue-runtime"], configs: flueConfigs }, { disabledNames: ["google", "google-genai"], configs: googleGenAIConfigs, diff --git a/js/src/auto-instrumentations/configs/flue.ts b/js/src/auto-instrumentations/configs/flue.ts new file mode 100644 index 000000000..cba01deef --- /dev/null +++ b/js/src/auto-instrumentations/configs/flue.ts @@ -0,0 +1,32 @@ +import type { InstrumentationConfig } from "@apm-js-collab/code-transformer"; +import { flueChannels } from "../../instrumentation/plugins/flue-channels"; + +const flueVersionRange = ">=0.7.0 <0.8.0"; + +export const flueConfigs: InstrumentationConfig[] = [ + { + channelName: flueChannels.createContext.channelName, + module: { + name: "@flue/runtime", + versionRange: flueVersionRange, + filePath: "dist/internal.mjs", + }, + functionQuery: { + functionName: "createFlueContext", + kind: "Sync", + }, + }, + { + channelName: flueChannels.openSession.channelName, + module: { + name: "@flue/runtime", + versionRange: flueVersionRange, + filePath: "dist/internal.mjs", + }, + functionQuery: { + className: "Harness", + methodName: "openSession", + kind: "Async", + }, + }, +]; diff --git a/js/src/auto-instrumentations/configs/github-copilot.test.ts b/js/src/auto-instrumentations/configs/github-copilot.test.ts deleted file mode 100644 index 2cfc3a650..000000000 --- a/js/src/auto-instrumentations/configs/github-copilot.test.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { describe, expect, it } from "vitest"; -import { gitHubCopilotChannels } from "../../instrumentation/plugins/github-copilot-channels"; -import { gitHubCopilotConfigs } from "./github-copilot"; - -function findConfigsByMethod(methodName: string) { - return gitHubCopilotConfigs.filter((config) => { - if (!("functionQuery" in config)) { - return false; - } - const query = config.functionQuery as { methodName?: string }; - return query.methodName === methodName; - }); -} - -describe("gitHubCopilotConfigs", () => { - it("defines channels for createSession, resumeSession, sendAndWait", () => { - expect(gitHubCopilotChannels.createSession.channelName).toContain( - "createSession", - ); - expect(gitHubCopilotChannels.resumeSession.channelName).toContain( - "resumeSession", - ); - expect(gitHubCopilotChannels.sendAndWait.channelName).toContain( - "sendAndWait", - ); - }); - - it("instruments createSession in both ESM and CJS", () => { - const configs = findConfigsByMethod("createSession"); - expect(configs).toHaveLength(2); - expect(configs.map((c) => c.channelName)).toEqual([ - gitHubCopilotChannels.createSession.channelName, - gitHubCopilotChannels.createSession.channelName, - ]); - expect(configs.map((c) => c.module.filePath).sort()).toEqual([ - "dist/cjs/client.js", - "dist/client.js", - ]); - for (const config of configs) { - expect(config.module.name).toBe("@github/copilot-sdk"); - expect(config.module.versionRange).toBe(">=0.3.0"); - expect((config.functionQuery as { className?: string }).className).toBe( - "CopilotClient", - ); - } - }); - - it("instruments resumeSession in both ESM and CJS", () => { - const configs = findConfigsByMethod("resumeSession"); - expect(configs).toHaveLength(2); - expect(configs.map((c) => c.channelName)).toEqual([ - gitHubCopilotChannels.resumeSession.channelName, - gitHubCopilotChannels.resumeSession.channelName, - ]); - expect(configs.map((c) => c.module.filePath).sort()).toEqual([ - "dist/cjs/client.js", - "dist/client.js", - ]); - for (const config of configs) { - expect((config.functionQuery as { className?: string }).className).toBe( - "CopilotClient", - ); - } - }); - - it("instruments sendAndWait in both ESM and CJS", () => { - const configs = findConfigsByMethod("sendAndWait"); - expect(configs).toHaveLength(2); - expect(configs.map((c) => c.channelName)).toEqual([ - gitHubCopilotChannels.sendAndWait.channelName, - gitHubCopilotChannels.sendAndWait.channelName, - ]); - expect(configs.map((c) => c.module.filePath).sort()).toEqual([ - "dist/cjs/session.js", - "dist/session.js", - ]); - for (const config of configs) { - expect((config.functionQuery as { className?: string }).className).toBe( - "CopilotSession", - ); - } - }); - - it("all configs target @github/copilot-sdk >=0.3.0", () => { - for (const config of gitHubCopilotConfigs) { - expect(config.module.name).toBe("@github/copilot-sdk"); - expect(config.module.versionRange).toBe(">=0.3.0"); - } - }); -}); diff --git a/js/src/exports.ts b/js/src/exports.ts index 6ca48e966..581cf8f8b 100644 --- a/js/src/exports.ts +++ b/js/src/exports.ts @@ -179,6 +179,7 @@ export { wrapMastraAgent } from "./wrappers/mastra"; export { wrapClaudeAgentSDK } from "./wrappers/claude-agent-sdk/claude-agent-sdk"; export { wrapOpenAICodexSDK } from "./wrappers/openai-codex"; export { wrapCursorSDK } from "./wrappers/cursor-sdk"; +export { wrapFlueContext, wrapFlueSession } from "./wrappers/flue"; export { wrapGoogleGenAI } from "./wrappers/google-genai"; export { wrapGoogleADK } from "./wrappers/google-adk"; export { wrapGenkit } from "./wrappers/genkit"; diff --git a/js/src/instrumentation/braintrust-plugin.ts b/js/src/instrumentation/braintrust-plugin.ts index cc03dcfc2..1d2725cb8 100644 --- a/js/src/instrumentation/braintrust-plugin.ts +++ b/js/src/instrumentation/braintrust-plugin.ts @@ -15,6 +15,7 @@ import { CoherePlugin } from "./plugins/cohere-plugin"; import { GroqPlugin } from "./plugins/groq-plugin"; import { GenkitPlugin } from "./plugins/genkit-plugin"; import { GitHubCopilotPlugin } from "./plugins/github-copilot-plugin"; +import { FluePlugin } from "./plugins/flue-plugin"; export interface BraintrustPluginConfig { integrations?: { @@ -37,6 +38,7 @@ export interface BraintrustPluginConfig { genkit?: boolean; gitHubCopilot?: boolean; openaiCodexSDK?: boolean; + flue?: boolean; }; } @@ -81,6 +83,7 @@ export class BraintrustPlugin extends BasePlugin { private groqPlugin: GroqPlugin | null = null; private genkitPlugin: GenkitPlugin | null = null; private gitHubCopilotPlugin: GitHubCopilotPlugin | null = null; + private fluePlugin: FluePlugin | null = null; constructor(config: BraintrustPluginConfig = {}) { super(); @@ -177,6 +180,11 @@ export class BraintrustPlugin extends BasePlugin { this.gitHubCopilotPlugin = new GitHubCopilotPlugin(); this.gitHubCopilotPlugin.enable(); } + + if (getIntegrationConfig(integrations, "flue") !== false) { + this.fluePlugin = new FluePlugin(); + this.fluePlugin.enable(); + } } protected onDisable(): void { @@ -259,6 +267,11 @@ export class BraintrustPlugin extends BasePlugin { this.gitHubCopilotPlugin.disable(); this.gitHubCopilotPlugin = null; } + + if (this.fluePlugin) { + this.fluePlugin.disable(); + this.fluePlugin = null; + } } } diff --git a/js/src/instrumentation/plugins/flue-channels.ts b/js/src/instrumentation/plugins/flue-channels.ts new file mode 100644 index 000000000..2ee0ab0c3 --- /dev/null +++ b/js/src/instrumentation/plugins/flue-channels.ts @@ -0,0 +1,92 @@ +import { channel, defineChannels } from "../core/channel-definitions"; +import type { + FlueCallHandle, + FlueCallOptions, + FlueContext, + FlueEvent, + FlueHarness, + FlueOperationKind, + FluePromptResponse, + FlueSession, + FlueSkillOptions, + FlueTaskOptions, +} from "../../vendor-sdk-types/flue"; + +export const flueChannels = defineChannels("@flue/runtime", { + createContext: channel<[unknown], FlueContext>({ + channelName: "createFlueContext", + kind: "sync-stream", + }), + + openSession: channel< + [string | undefined, string | undefined, unknown], + FlueSession, + { + harness?: FlueHarness; + } + >({ + channelName: "Harness.openSession", + kind: "async", + }), + + contextEvent: channel< + [FlueEvent], + void, + { + context?: FlueContext; + } + >({ + channelName: "context.event", + kind: "sync-stream", + }), + + prompt: channel< + [string, FlueCallOptions | undefined], + FluePromptResponse, + { + operation: FlueOperationKind; + session?: FlueSession; + } + >({ + channelName: "session.prompt", + kind: "async", + }), + + skill: channel< + [string, FlueSkillOptions | undefined], + FluePromptResponse, + { + operation: FlueOperationKind; + session?: FlueSession; + } + >({ + channelName: "session.skill", + kind: "async", + }), + + task: channel< + [string, FlueTaskOptions | undefined], + FluePromptResponse, + { + operation: FlueOperationKind; + session?: FlueSession; + } + >({ + channelName: "session.task", + kind: "async", + }), + + compact: channel< + [], + void, + { + operation: FlueOperationKind; + session?: FlueSession; + } + >({ + channelName: "session.compact", + kind: "async", + }), +}); + +export type FlueThenableResult = FlueCallHandle | PromiseLike; diff --git a/js/src/instrumentation/plugins/flue-plugin.test.ts b/js/src/instrumentation/plugins/flue-plugin.test.ts new file mode 100644 index 000000000..e1b12bd14 --- /dev/null +++ b/js/src/instrumentation/plugins/flue-plugin.test.ts @@ -0,0 +1,472 @@ +import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; + +const { mockCurrentParentSpan, mockStartSpan } = vi.hoisted(() => ({ + mockCurrentParentSpan: { current: undefined as any }, + mockStartSpan: vi.fn(), +})); + +vi.mock("../../isomorph", () => ({ + default: { + newTracingChannel: vi.fn(), + }, +})); + +vi.mock("../../logger", () => ({ + startSpan: (...args: unknown[]) => mockStartSpan(...args), + withCurrent: (span: unknown, callback: () => unknown) => { + const previous = mockCurrentParentSpan.current; + mockCurrentParentSpan.current = span; + try { + return callback(); + } finally { + mockCurrentParentSpan.current = previous; + } + }, +})); + +import iso from "../../isomorph"; +import { FluePlugin } from "./flue-plugin"; + +const mockNewTracingChannel = iso.newTracingChannel as ReturnType; + +describe("FluePlugin", () => { + let handlersByName: Map; + let spans: Array<{ + end: ReturnType; + export: ReturnType; + log: ReturnType; + name?: string; + rootSpanId: string; + spanId: string; + spanParents: string[]; + }>; + + beforeEach(() => { + handlersByName = new Map(); + spans = []; + mockCurrentParentSpan.current = undefined; + mockNewTracingChannel.mockImplementation((name: string) => ({ + subscribe: vi.fn((handlers) => handlersByName.set(name, handlers)), + tracePromise: vi.fn((fn) => fn()), + traceSync: vi.fn((fn) => fn()), + unsubscribe: vi.fn(), + })); + mockStartSpan.mockImplementation((args: any) => { + const spanId = `span-${spans.length}`; + const parentSpan = mockCurrentParentSpan.current; + const rootSpanId = + args.parentSpanIds?.rootSpanId ?? parentSpan?.rootSpanId ?? spanId; + const spanParents = args.parentSpanIds?.spanId + ? [args.parentSpanIds.spanId] + : parentSpan?.spanId + ? [parentSpan.spanId] + : []; + const span = { + end: vi.fn(), + export: vi.fn(async () => `${args.name}-export-${spans.length}`), + log: vi.fn(), + name: args.name, + rootSpanId, + spanId, + spanParents, + }; + spans.push(span); + return span; + }); + }); + + afterEach(() => { + vi.clearAllMocks(); + }); + + it("subscribes to Flue channels", () => { + const plugin = new FluePlugin(); + + plugin.enable(); + + expect( + handlersByName.has("orchestrion:@flue/runtime:createFlueContext"), + ).toBe(true); + expect( + handlersByName.has("orchestrion:@flue/runtime:Harness.openSession"), + ).toBe(true); + expect(handlersByName.has("orchestrion:@flue/runtime:context.event")).toBe( + true, + ); + expect(handlersByName.has("orchestrion:@flue/runtime:session.prompt")).toBe( + true, + ); + expect(handlersByName.has("orchestrion:@flue/runtime:session.skill")).toBe( + true, + ); + expect(handlersByName.has("orchestrion:@flue/runtime:session.task")).toBe( + true, + ); + expect( + handlersByName.has("orchestrion:@flue/runtime:session.compact"), + ).toBe(true); + }); + + it("patches contexts and sessions returned by auto-instrumented entrypoints", async () => { + const plugin = new FluePlugin(); + plugin.enable(); + + const session = makeSession(); + const harness = { session: vi.fn(async () => session) }; + const ctx = { + init: vi.fn(async () => harness), + subscribeEvent: vi.fn(() => vi.fn()), + }; + handlersByName + .get("orchestrion:@flue/runtime:createFlueContext") + .end({ arguments: [{}], result: ctx }); + + await ctx.init({ model: "pi/test" }); + const wrappedSession = await harness.session(); + await wrappedSession.prompt("hello"); + + expect(ctx.subscribeEvent).toHaveBeenCalledTimes(1); + await expect(wrappedSession.prompt("hello again")).resolves.toEqual({ + text: "ok", + }); + }); + + it("correlates operation, turn, tool, task, and compaction spans", () => { + const plugin = new FluePlugin(); + plugin.enable(); + + const contextHandlers = handlersByName.get( + "orchestrion:@flue/runtime:context.event", + ); + const promptHandlers = handlersByName.get( + "orchestrion:@flue/runtime:session.prompt", + ); + const promptEvent = { + arguments: [ + "Use a tool and delegate work", + { model: "pi/test", tools: [{ name: "lookup", parameters: {} }] }, + ], + operation: "prompt", + session: { name: "main" }, + }; + + promptHandlers.start(promptEvent); + contextHandlers.start({ + arguments: [ + { + eventIndex: 1, + operationId: "op_1", + operationKind: "prompt", + session: "main", + type: "operation_start", + }, + ], + }); + contextHandlers.start({ + arguments: [{ operationId: "op_1", text: "Looking", type: "text_delta" }], + }); + contextHandlers.start({ + arguments: [{ operationId: "op_1", type: "thinking_start" }], + }); + contextHandlers.start({ + arguments: [ + { delta: "Think it ", operationId: "op_1", type: "thinking_delta" }, + ], + }); + contextHandlers.start({ + arguments: [ + { + content: "Think it through.", + operationId: "op_1", + type: "thinking_end", + }, + ], + }); + contextHandlers.start({ + arguments: [ + { + args: { query: "braintrust" }, + operationId: "op_1", + toolCallId: "tool_1", + toolName: "lookup", + type: "tool_start", + }, + ], + }); + contextHandlers.start({ + arguments: [ + { + durationMs: 3, + isError: false, + operationId: "op_1", + result: "lookup ok", + toolCallId: "tool_1", + toolName: "lookup", + type: "tool_call", + }, + ], + }); + contextHandlers.start({ + arguments: [ + { + durationMs: 10, + isError: false, + model: "pi/test", + operationId: "op_1", + stopReason: "stop", + type: "turn", + usage: usage(), + }, + ], + }); + contextHandlers.start({ + arguments: [ + { + operationId: "op_1", + parentSession: "main", + prompt: "child prompt", + taskId: "task_1", + type: "task_start", + }, + ], + }); + contextHandlers.start({ + arguments: [ + { + taskId: "task_1", + text: "child done", + type: "text_delta", + }, + ], + }); + contextHandlers.start({ + arguments: [ + { + durationMs: 8, + isError: false, + model: "pi/test", + stopReason: "stop", + taskId: "task_1", + type: "turn", + usage: usage(), + }, + ], + }); + contextHandlers.start({ + arguments: [ + { + durationMs: 20, + isError: false, + result: "task ok", + taskId: "task_1", + type: "task", + }, + ], + }); + contextHandlers.start({ + arguments: [ + { + estimatedTokens: 100, + operationId: "op_1", + reason: "manual", + type: "compaction_start", + }, + ], + }); + contextHandlers.start({ + arguments: [ + { + durationMs: 4, + messagesAfter: 2, + messagesBefore: 8, + operationId: "op_1", + type: "compaction", + usage: usage(), + }, + ], + }); + contextHandlers.start({ + arguments: [ + { + durationMs: 50, + isError: false, + operationId: "op_1", + operationKind: "prompt", + type: "operation", + usage: usage(), + }, + ], + }); + (promptEvent as any).result = { + model: { id: "pi/test" }, + text: "done", + usage: usage(), + }; + promptHandlers.asyncEnd(promptEvent); + + const operationSpan = spans.find( + (span) => span.name === "flue.session.prompt", + ); + const turnSpan = spans.find((span) => span.name === "flue.turn"); + const toolSpan = spans.find((span) => span.name === "tool: lookup"); + const taskSpan = spans.find((span) => span.name === "flue.task"); + const childTurnSpan = spans.filter((span) => span.name === "flue.turn")[1]; + const compactionSpan = spans.find( + (span) => span.name === "flue.compaction", + ); + + expect(operationSpan?.log).toHaveBeenCalledWith( + expect.objectContaining({ + input: "Use a tool and delegate work", + metadata: expect.objectContaining({ + "flue.operation": "prompt", + "flue.tools_count": 1, + provider: "flue", + }), + }), + ); + expect(turnSpan?.spanParents).toEqual([operationSpan?.spanId]); + expect(toolSpan?.spanParents).toEqual([operationSpan?.spanId]); + expect(toolSpan?.spanParents).toEqual(turnSpan?.spanParents); + expect(toolSpan?.spanParents).not.toContain(turnSpan?.spanId); + expect(taskSpan?.spanParents).toEqual([operationSpan?.spanId]); + expect(childTurnSpan?.spanParents).toEqual([taskSpan?.spanId]); + expect(compactionSpan?.spanParents).toEqual([operationSpan?.spanId]); + expect(turnSpan?.log).toHaveBeenCalledWith( + expect.objectContaining({ + metrics: expect.objectContaining({ + completion_tokens: 4, + estimated_cost: 0.01, + prompt_cache_creation_tokens: 2, + prompt_cached_tokens: 1, + prompt_tokens: 3, + tokens: 10, + }), + output: [ + expect.objectContaining({ + message: expect.objectContaining({ + content: "Looking", + reasoning: "Think it through.", + role: "assistant", + tool_calls: [ + { + function: { + arguments: JSON.stringify({ query: "braintrust" }), + name: "lookup", + }, + id: "tool_1", + type: "function", + }, + ], + }), + }), + ], + }), + ); + expect(operationSpan?.end).toHaveBeenCalledTimes(1); + }); + + it("parents synthetic tool spans as siblings of active turn spans", () => { + const plugin = new FluePlugin(); + plugin.enable(); + + const contextHandlers = handlersByName.get( + "orchestrion:@flue/runtime:context.event", + ); + const promptHandlers = handlersByName.get( + "orchestrion:@flue/runtime:session.prompt", + ); + const promptEvent = { + arguments: ["Use a tool", { model: "pi/test" }], + operation: "prompt", + session: { name: "main" }, + }; + + promptHandlers.start(promptEvent); + contextHandlers.start({ + arguments: [ + { + operationId: "op_1", + operationKind: "prompt", + session: "main", + type: "operation_start", + }, + ], + }); + contextHandlers.start({ + arguments: [ + { operationId: "op_1", text: "Using a tool", type: "text_delta" }, + ], + }); + contextHandlers.start({ + arguments: [ + { + durationMs: 2, + isError: false, + operationId: "op_1", + result: "lookup ok", + toolCallId: "tool_1", + toolName: "lookup", + type: "tool_call", + }, + ], + }); + contextHandlers.start({ + arguments: [ + { + durationMs: 10, + isError: false, + model: "pi/test", + operationId: "op_1", + stopReason: "toolUse", + type: "turn", + usage: usage(), + }, + ], + }); + + const operationSpan = spans.find( + (span) => span.name === "flue.session.prompt", + ); + const turnSpan = spans.find((span) => span.name === "flue.turn"); + const toolSpan = spans.find((span) => span.name === "tool: lookup"); + + expect(turnSpan?.spanParents).toEqual([operationSpan?.spanId]); + expect(toolSpan?.spanParents).toEqual([operationSpan?.spanId]); + expect(toolSpan?.spanParents).toEqual(turnSpan?.spanParents); + expect(toolSpan?.spanParents).not.toContain(turnSpan?.spanId); + }); +}); + +function makeSession() { + const promise = Promise.resolve({ text: "ok" }); + const handle = { + abort: vi.fn(), + signal: new AbortController().signal, + then: promise.then.bind(promise), + }; + return { + compact: vi.fn(async () => undefined), + name: "main", + prompt: vi.fn(() => handle), + skill: vi.fn(() => handle), + task: vi.fn(() => handle), + }; +} + +function usage() { + return { + cacheRead: 1, + cacheWrite: 2, + cost: { + cacheRead: 0, + cacheWrite: 0, + input: 0, + output: 0, + total: 0.01, + }, + input: 3, + output: 4, + totalTokens: 10, + }; +} diff --git a/js/src/instrumentation/plugins/flue-plugin.ts b/js/src/instrumentation/plugins/flue-plugin.ts new file mode 100644 index 000000000..9d6d43662 --- /dev/null +++ b/js/src/instrumentation/plugins/flue-plugin.ts @@ -0,0 +1,1187 @@ +import { BasePlugin } from "../core"; +import type { ChannelMessage } from "../core/channel-definitions"; +import type { IsoChannelHandlers } from "../../isomorph"; +import { startSpan, withCurrent } from "../../logger"; +import type { Span } from "../../logger"; +import { getCurrentUnixTimestamp, isObject } from "../../util"; +import { SpanTypeAttribute } from "../../../util/index"; +import { + patchFlueSessionInPlace, + subscribeFlueContextEvents, + wrapFlueContext, + wrapFlueHarness, +} from "../../wrappers/flue"; +import { flueChannels } from "./flue-channels"; +import type { + FlueBaseEvent, + FlueCallOptions, + FlueCompactionEvent, + FlueCompactionStartEvent, + FlueEvent, + FlueOperationEvent, + FlueOperationKind, + FlueOperationStartEvent, + FluePromptResponse, + FlueSession, + FlueSkillOptions, + FlueTaskEvent, + FlueTaskOptions, + FlueTaskStartEvent, + FlueThinkingDeltaEvent, + FlueThinkingEndEvent, + FlueToolCallEvent, + FlueToolStartEvent, + FlueTurnEvent, + FlueUsage, +} from "../../vendor-sdk-types/flue"; + +type OperationState = { + metadata: Record; + operation: FlueOperationKind; + operationId?: string; + sessionName?: string; + span: Span; + startTime: number; +}; + +type SpanState = { + metadata: Record; + span: Span; + startTime: number; +}; + +type TurnState = SpanState & { + finalThinking?: string; + hasThinking: boolean; + text: string[]; + thinking: string[]; + toolCalls: Array<{ + args?: unknown; + toolCallId?: string; + toolName?: string; + }>; +}; + +export class FluePlugin extends BasePlugin { + private activeOperationsById = new Map(); + private activeOperationsByScope = new Map(); + private compactionsByScope = new Map(); + private pendingOperationsByKey = new Map(); + private tasksById = new Map(); + private toolsById = new Map(); + private turnsByScope = new Map(); + + protected onEnable(): void { + this.subscribeToContextCreation(); + this.subscribeToSessionCreation(); + this.subscribeToContextEvents(); + this.subscribeToSessionOperations(); + } + + protected onDisable(): void { + for (const unsubscribe of this.unsubscribers) { + unsubscribe(); + } + this.unsubscribers = []; + this.activeOperationsById.clear(); + this.activeOperationsByScope.clear(); + this.compactionsByScope.clear(); + this.pendingOperationsByKey.clear(); + this.tasksById.clear(); + this.toolsById.clear(); + this.turnsByScope.clear(); + } + + private subscribeToContextCreation(): void { + const channel = flueChannels.createContext.tracingChannel(); + const handlers: IsoChannelHandlers< + ChannelMessage + > = { + end: (event) => { + const ctx = event.result; + if (!ctx) { + return; + } + subscribeFlueContextEvents(ctx); + wrapFlueContext(ctx); + }, + error: () => {}, + }; + + channel.subscribe(handlers); + this.unsubscribers.push(() => { + channel.unsubscribe(handlers); + }); + } + + private subscribeToSessionCreation(): void { + const channel = flueChannels.openSession.tracingChannel(); + const handlers: IsoChannelHandlers< + ChannelMessage + > = { + asyncEnd: (event) => { + if (event.result) { + patchFlueSessionInPlace( + event.result as FlueSession & Record, + ); + } + if (event.harness) { + wrapFlueHarness(event.harness); + } + }, + error: () => {}, + }; + + channel.subscribe(handlers); + this.unsubscribers.push(() => { + channel.unsubscribe(handlers); + }); + } + + private subscribeToSessionOperations(): void { + this.subscribeToSessionOperation(flueChannels.prompt); + this.subscribeToSessionOperation(flueChannels.skill); + this.subscribeToSessionOperation(flueChannels.task); + this.subscribeToCompact(); + } + + private subscribeToSessionOperation( + channel: + | typeof flueChannels.prompt + | typeof flueChannels.skill + | typeof flueChannels.task, + ): void { + const tracingChannel = channel.tracingChannel(); + const states = new WeakMap(); + const handlers: IsoChannelHandlers> = { + start: (event) => { + const state = this.startOperationState({ + args: event.arguments, + moduleVersion: + typeof event.moduleVersion === "string" + ? event.moduleVersion + : undefined, + operation: event.operation, + session: event.session, + }); + states.set(event, state); + }, + asyncEnd: (event) => { + this.endOperationState(states.get(event), event.result); + states.delete(event); + }, + error: (event) => { + const state = states.get(event); + if (state && event.error) { + safeLog(state.span, { error: errorToString(event.error) }); + this.finishOperationState(state); + } + states.delete(event); + }, + }; + + tracingChannel.subscribe(handlers); + this.unsubscribers.push(() => { + tracingChannel.unsubscribe(handlers); + }); + } + + private subscribeToCompact(): void { + const tracingChannel = flueChannels.compact.tracingChannel(); + const states = new WeakMap(); + const handlers: IsoChannelHandlers< + ChannelMessage + > = { + start: (event) => { + const state = this.startOperationState({ + args: [], + moduleVersion: + typeof event.moduleVersion === "string" + ? event.moduleVersion + : undefined, + operation: event.operation, + session: event.session, + }); + states.set(event, state); + }, + asyncEnd: (event) => { + this.endOperationState(states.get(event), undefined); + states.delete(event); + }, + error: (event) => { + const state = states.get(event); + if (state && event.error) { + safeLog(state.span, { error: errorToString(event.error) }); + this.finishOperationState(state); + } + states.delete(event); + }, + }; + + tracingChannel.subscribe(handlers); + this.unsubscribers.push(() => { + tracingChannel.unsubscribe(handlers); + }); + } + + private subscribeToContextEvents(): void { + const channel = flueChannels.contextEvent.tracingChannel(); + const handlers: IsoChannelHandlers< + ChannelMessage + > = { + start: (event) => { + const flueEvent = event.arguments[0]; + if (!flueEvent) { + return; + } + + try { + this.handleFlueEvent(flueEvent); + } catch (error) { + logInstrumentationError("Flue event", error); + } + }, + error: () => {}, + }; + + channel.subscribe(handlers); + this.unsubscribers.push(() => { + channel.unsubscribe(handlers); + }); + } + + private startOperationState(args: { + args: ArrayLike; + moduleVersion?: string; + operation: FlueOperationKind; + session?: FlueSession; + }): OperationState { + const sessionName = getSessionName(args.session); + const metadata = { + ...extractOperationInputMetadata(args.operation, args.args), + ...extractSessionMetadata(args.session), + "flue.operation": args.operation, + provider: "flue", + ...(args.moduleVersion ? { "flue.version": args.moduleVersion } : {}), + }; + const span = startSpan({ + name: `flue.session.${args.operation}`, + spanAttributes: { type: SpanTypeAttribute.TASK }, + }); + const state: OperationState = { + metadata, + operation: args.operation, + sessionName, + span, + startTime: getCurrentUnixTimestamp(), + }; + + safeLog(span, { + input: extractOperationInput(args.operation, args.args), + metadata, + }); + + this.pendingOperationQueue(operationKey(sessionName, args.operation)).push( + state, + ); + addOperationToScope( + this.activeOperationsByScope, + sessionName ?? "unknown", + state, + ); + + return state; + } + + private endOperationState( + state: OperationState | undefined, + result: FluePromptResponse | undefined, + ): void { + if (!state) { + return; + } + + const metadata = { + ...state.metadata, + ...extractPromptResponseMetadata(result), + }; + const metrics = { + ...buildDurationMetrics(state.startTime), + ...metricsFromUsage(result?.usage), + }; + + safeLog(state.span, { + metadata, + metrics, + output: extractOperationOutput(result), + }); + this.finishOperationState(state); + } + + private finishOperationState(state: OperationState): void { + removePendingOperation(this.pendingOperationsByKey, state); + if (state.operationId) { + this.activeOperationsById.delete(state.operationId); + } + removeScopedOperation(this.activeOperationsByScope, state); + state.span.end(); + } + + private handleFlueEvent(event: FlueEvent): void { + switch (event.type) { + case "operation_start": + this.handleOperationStart(event as FlueOperationStartEvent); + return; + case "operation": + this.handleOperation(event as FlueOperationEvent); + return; + case "text_delta": + this.ensureTurnState(event).text.push( + typeof event.text === "string" ? event.text : "", + ); + return; + case "thinking_start": + this.handleThinkingStart(event); + return; + case "thinking_delta": + this.handleThinkingDelta(event as FlueThinkingDeltaEvent); + return; + case "thinking_end": + this.handleThinkingEnd(event as FlueThinkingEndEvent); + return; + case "turn": + this.handleTurn(event as FlueTurnEvent); + return; + case "tool_start": + this.handleToolStart(event as FlueToolStartEvent); + return; + case "tool_call": + this.handleToolCall(event as FlueToolCallEvent); + return; + case "task_start": + this.handleTaskStart(event as FlueTaskStartEvent); + return; + case "task": + this.handleTask(event as FlueTaskEvent); + return; + case "compaction_start": + this.handleCompactionStart(event as FlueCompactionStartEvent); + return; + case "compaction": + this.handleCompaction(event as FlueCompactionEvent); + return; + default: + return; + } + } + + private handleOperationStart(event: FlueOperationStartEvent): void { + if (!isInstrumentedOperation(event.operationKind)) { + return; + } + + const state = this.takePendingOperationForEvent(event); + if (!state) { + return; + } + + state.operationId = event.operationId; + this.activeOperationsById.set(event.operationId, state); + addScopedOperation(this.activeOperationsByScope, event, state); + state.metadata = { + ...state.metadata, + ...extractEventMetadata(event), + "flue.operation_id": event.operationId, + }; + safeLog(state.span, { metadata: state.metadata }); + } + + private handleOperation(event: FlueOperationEvent): void { + const state = event.operationId + ? this.activeOperationsById.get(event.operationId) + : undefined; + if (!state) { + return; + } + + const metadata = { + ...state.metadata, + ...extractEventMetadata(event), + ...(typeof event.durationMs === "number" + ? { "flue.duration_ms": event.durationMs } + : {}), + ...(event.isError !== undefined + ? { "flue.is_error": event.isError } + : {}), + }; + const metrics = metricsFromUsage(event.usage); + + safeLog(state.span, { + ...(event.error ? { error: errorToString(event.error) } : {}), + metadata, + ...(Object.keys(metrics).length ? { metrics } : {}), + }); + } + + private ensureTurnState(event: FlueBaseEvent): TurnState { + const scope = scopeKey(event); + const existing = this.turnsByScope.get(scope); + if (existing) { + return existing; + } + + const parent = this.parentSpanForEvent(event); + const metadata = { + ...extractEventMetadata(event), + provider: "flue", + }; + const span = startFlueSpan(parent, { + name: "flue.turn", + spanAttributes: { type: SpanTypeAttribute.LLM }, + }); + const state: TurnState = { + metadata, + span, + hasThinking: false, + startTime: getCurrentUnixTimestamp(), + text: [], + thinking: [], + toolCalls: [], + }; + safeLog(span, { metadata }); + this.turnsByScope.set(scope, state); + return state; + } + + private handleTurn(event: FlueTurnEvent): void { + const scope = scopeKey(event); + const state = this.ensureTurnState(event); + const text = state.text.join(""); + const reasoning = state.finalThinking ?? state.thinking.join(""); + const outputReasoning = + reasoning || + (state.hasThinking + ? "[reasoning stream present; content unavailable]" + : undefined); + const metadata = { + ...state.metadata, + ...extractEventMetadata(event), + ...(event.model ? { model: event.model, "flue.model": event.model } : {}), + ...(event.stopReason ? { "flue.stop_reason": event.stopReason } : {}), + ...(event.isError !== undefined + ? { "flue.is_error": event.isError } + : {}), + provider: "flue", + }; + + safeLog(state.span, { + ...(event.error ? { error: errorToString(event.error) } : {}), + metadata, + metrics: { + ...durationMsMetrics(event.durationMs), + ...metricsFromUsage(event.usage), + }, + output: toAssistantOutput( + text, + event.stopReason, + outputReasoning, + state.toolCalls, + ), + }); + state.span.end(); + this.turnsByScope.delete(scope); + } + + private handleThinkingDelta(event: FlueThinkingDeltaEvent): void { + const delta = event.delta; + if (typeof delta !== "string" || !delta) { + return; + } + const state = this.ensureTurnState(event); + state.hasThinking = true; + state.metadata["flue.thinking"] = true; + state.thinking.push(delta); + } + + private handleThinkingStart(event: FlueBaseEvent): void { + const state = this.ensureTurnState(event); + state.hasThinking = true; + state.metadata["flue.thinking"] = true; + } + + private handleThinkingEnd(event: FlueThinkingEndEvent): void { + const state = this.ensureTurnState(event); + state.hasThinking = true; + state.metadata["flue.thinking"] = true; + if (typeof event.content === "string" && event.content) { + state.finalThinking = event.content; + } + } + + private handleToolStart(event: FlueToolStartEvent): void { + const toolCallId = event.toolCallId; + if (!toolCallId) { + return; + } + + const parent = this.parentSpanForEvent(event); + const metadata = { + ...extractEventMetadata(event), + ...(event.toolName ? { "flue.tool_name": event.toolName } : {}), + "flue.tool_call_id": toolCallId, + provider: "flue", + }; + const span = startFlueSpan(parent, { + name: `tool: ${event.toolName ?? "unknown"}`, + spanAttributes: { type: SpanTypeAttribute.TOOL }, + }); + const turnState = this.turnsByScope.get(scopeKey(event)); + if (turnState) { + turnState.toolCalls.push({ + args: event.args, + toolCallId, + toolName: event.toolName, + }); + } + safeLog(span, { + input: event.args, + metadata, + }); + this.toolsById.set(toolKey(event), { + metadata, + span, + startTime: getCurrentUnixTimestamp(), + }); + } + + private handleToolCall(event: FlueToolCallEvent): void { + const key = toolKey(event); + const state = + this.toolsById.get(key) ?? + this.startSyntheticToolState(event, event.toolName ?? "unknown"); + const metadata = { + ...state.metadata, + ...extractEventMetadata(event), + ...(event.toolName ? { "flue.tool_name": event.toolName } : {}), + ...(event.toolCallId ? { "flue.tool_call_id": event.toolCallId } : {}), + ...(event.isError !== undefined + ? { "flue.is_error": event.isError } + : {}), + }; + + safeLog(state.span, { + ...(event.isError ? { error: errorToString(event.result) } : {}), + metadata, + metrics: durationMsMetrics(event.durationMs), + output: event.result, + }); + state.span.end(); + this.toolsById.delete(key); + } + + private handleTaskStart(event: FlueTaskStartEvent): void { + const parent = this.parentSpanForEvent(event); + const metadata = { + ...extractEventMetadata(event), + ...(event.role ? { "flue.role": event.role } : {}), + ...(event.cwd ? { "flue.cwd": event.cwd } : {}), + "flue.task_id": event.taskId, + provider: "flue", + }; + const span = startFlueSpan(parent, { + name: "flue.task", + spanAttributes: { type: SpanTypeAttribute.TASK }, + }); + safeLog(span, { + input: event.prompt, + metadata, + }); + this.tasksById.set(event.taskId, { + metadata, + span, + startTime: getCurrentUnixTimestamp(), + }); + } + + private handleTask(event: FlueTaskEvent): void { + const state = this.tasksById.get(event.taskId); + if (!state) { + return; + } + + safeLog(state.span, { + ...(event.isError ? { error: errorToString(event.result) } : {}), + metadata: { + ...state.metadata, + ...extractEventMetadata(event), + ...(event.isError !== undefined + ? { "flue.is_error": event.isError } + : {}), + }, + metrics: durationMsMetrics(event.durationMs), + output: event.result, + }); + state.span.end(); + this.tasksById.delete(event.taskId); + } + + private handleCompactionStart(event: FlueCompactionStartEvent): void { + const parent = this.parentSpanForEvent(event); + const metadata = { + ...extractEventMetadata(event), + ...(event.reason ? { "flue.compaction_reason": event.reason } : {}), + provider: "flue", + }; + const span = startFlueSpan(parent, { + name: "flue.compaction", + spanAttributes: { type: SpanTypeAttribute.TASK }, + }); + safeLog(span, { + input: { + estimatedTokens: event.estimatedTokens, + reason: event.reason, + }, + metadata, + }); + this.compactionsByScope.set(scopeKey(event), { + metadata, + span, + startTime: getCurrentUnixTimestamp(), + }); + } + + private handleCompaction(event: FlueCompactionEvent): void { + const key = scopeKey(event); + const state = this.compactionsByScope.get(key); + if (!state) { + return; + } + + safeLog(state.span, { + metadata: { + ...state.metadata, + ...extractEventMetadata(event), + ...(typeof event.messagesBefore === "number" + ? { "flue.messages_before": event.messagesBefore } + : {}), + ...(typeof event.messagesAfter === "number" + ? { "flue.messages_after": event.messagesAfter } + : {}), + }, + metrics: { + ...durationMsMetrics(event.durationMs), + ...metricsFromUsage(event.usage), + }, + output: { + messagesAfter: event.messagesAfter, + messagesBefore: event.messagesBefore, + }, + }); + state.span.end(); + this.compactionsByScope.delete(key); + } + + private startSyntheticToolState( + event: FlueToolCallEvent, + toolName: string, + ): SpanState { + const parent = this.parentSpanForEvent(event); + const metadata = { + ...extractEventMetadata(event), + ...(event.toolCallId ? { "flue.tool_call_id": event.toolCallId } : {}), + "flue.tool_name": toolName, + provider: "flue", + }; + const span = startFlueSpan(parent, { + name: `tool: ${toolName}`, + spanAttributes: { type: SpanTypeAttribute.TOOL }, + }); + safeLog(span, { metadata }); + return { metadata, span, startTime: getCurrentUnixTimestamp() }; + } + + private parentSpanForEvent(event: FlueBaseEvent): Span | undefined { + if (event.operationId) { + const operation = + this.activeOperationsById.get(event.operationId) ?? + this.promotePendingOperationForEvent(event); + if (operation) { + return operation.span; + } + } + if (event.taskId) { + return this.tasksById.get(event.taskId)?.span; + } + return ( + this.activeOperationForEventScope(event)?.span ?? + this.pendingOperationForEventScope(event)?.span + ); + } + + private promotePendingOperationForEvent( + event: FlueBaseEvent, + ): OperationState | undefined { + if (!event.operationId) { + return undefined; + } + + const scopePrefixes = operationScopePrefixes(event); + for (const [candidateKey, candidateQueue] of this.pendingOperationsByKey) { + if ( + !candidateQueue.length || + !operationKeyMatchesScopes(candidateKey, scopePrefixes) + ) { + continue; + } + + const state = candidateQueue.shift(); + if (!state) { + return undefined; + } + state.operationId = event.operationId; + this.activeOperationsById.set(event.operationId, state); + addScopedOperation(this.activeOperationsByScope, event, state); + state.metadata = { + ...state.metadata, + ...extractEventMetadata(event), + "flue.operation_id": event.operationId, + }; + safeLog(state.span, { metadata: state.metadata }); + return state; + } + + return undefined; + } + + private activeOperationForEventScope( + event: FlueBaseEvent, + ): OperationState | undefined { + for (const scope of operationScopeNames(event)) { + const operations = this.activeOperationsByScope.get(scope); + if (operations?.length) { + return operations[operations.length - 1]; + } + } + + return undefined; + } + + private pendingOperationForEventScope( + event: FlueBaseEvent, + ): OperationState | undefined { + const scopePrefixes = operationScopePrefixes(event); + for (const [candidateKey, candidateQueue] of this.pendingOperationsByKey) { + if ( + !candidateQueue.length || + !operationKeyMatchesScopes(candidateKey, scopePrefixes) + ) { + continue; + } + return candidateQueue[0]; + } + + return undefined; + } + + private takePendingOperationForEvent( + event: FlueOperationStartEvent, + ): OperationState | undefined { + const key = operationKey(event.session, event.operationKind); + const queue = this.pendingOperationsByKey.get(key); + if (queue?.length) { + return queue.shift(); + } + + for (const [candidateKey, candidateQueue] of this.pendingOperationsByKey) { + if ( + candidateKey.endsWith(`::${event.operationKind}`) && + candidateQueue.length + ) { + return candidateQueue.shift(); + } + } + + return undefined; + } + + private pendingOperationQueue(key: string): OperationState[] { + const existing = this.pendingOperationsByKey.get(key); + if (existing) { + return existing; + } + const queue: OperationState[] = []; + this.pendingOperationsByKey.set(key, queue); + return queue; + } +} + +function isInstrumentedOperation( + operation: FlueOperationKind | "shell", +): operation is FlueOperationKind { + return ( + operation === "prompt" || + operation === "skill" || + operation === "task" || + operation === "compact" + ); +} + +function getSessionName(session: FlueSession | undefined): string | undefined { + return typeof session?.name === "string" ? session.name : undefined; +} + +function operationKey( + sessionName: string | undefined, + operation: FlueOperationKind | "shell", +): string { + return `${sessionName ?? "unknown"}::${operation}`; +} + +function operationScopePrefixes(event: FlueBaseEvent): Set { + const scopes = new Set(); + for (const scope of operationScopeNames(event)) { + scopes.add(`${scope}::`); + } + return scopes; +} + +function operationKeyMatchesScopes(key: string, scopes: Set): boolean { + for (const scope of scopes) { + if (key.startsWith(scope)) { + return true; + } + } + return false; +} + +function operationScopeNames(event: FlueBaseEvent): Set { + const scopes = new Set(); + if (event.session) { + scopes.add(event.session); + } + if (event.parentSession) { + scopes.add(event.parentSession); + } + if (!scopes.size) { + scopes.add("unknown"); + } + return scopes; +} + +function addScopedOperation( + operationsByScope: Map, + event: FlueBaseEvent, + state: OperationState, +): void { + for (const scope of operationScopeNames(event)) { + addOperationToScope(operationsByScope, scope, state); + } +} + +function addOperationToScope( + operationsByScope: Map, + scope: string, + state: OperationState, +): void { + const operations = operationsByScope.get(scope); + if (operations) { + if (!operations.includes(state)) { + operations.push(state); + } + } else { + operationsByScope.set(scope, [state]); + } +} + +function removeScopedOperation( + operationsByScope: Map, + state: OperationState, +): void { + for (const [scope, operations] of operationsByScope) { + const index = operations.indexOf(state); + if (index === -1) { + continue; + } + operations.splice(index, 1); + if (operations.length === 0) { + operationsByScope.delete(scope); + } + } +} + +function removePendingOperation( + pendingOperationsByKey: Map, + state: OperationState, +): void { + for (const [key, queue] of pendingOperationsByKey) { + const index = queue.indexOf(state); + if (index === -1) { + continue; + } + queue.splice(index, 1); + if (queue.length === 0) { + pendingOperationsByKey.delete(key); + } + return; + } +} + +function extractSessionMetadata( + session: FlueSession | undefined, +): Record { + const sessionName = getSessionName(session); + return sessionName ? { "flue.session": sessionName } : {}; +} + +function extractEventMetadata(event: FlueBaseEvent): Record { + return { + ...(event.runId ? { "flue.run_id": event.runId } : {}), + ...(typeof event.eventIndex === "number" + ? { "flue.event_index": event.eventIndex } + : {}), + ...(event.session ? { "flue.session": event.session } : {}), + ...(event.parentSession + ? { "flue.parent_session": event.parentSession } + : {}), + ...(event.harness ? { "flue.harness": event.harness } : {}), + ...(event.taskId ? { "flue.task_id": event.taskId } : {}), + ...(event.operationId ? { "flue.operation_id": event.operationId } : {}), + }; +} + +function extractOperationInput( + operation: FlueOperationKind, + args: ArrayLike, +): unknown { + switch (operation) { + case "prompt": + case "task": + return args[0]; + case "skill": + return { + args: getOptionObject(args[1])?.args, + name: args[0], + }; + case "compact": + return undefined; + } +} + +function extractOperationInputMetadata( + operation: FlueOperationKind, + args: ArrayLike, +): Record { + const options = getOptionObject(args[1]); + return { + ...(operation === "skill" && typeof args[0] === "string" + ? { "flue.skill_name": args[0] } + : {}), + ...(options?.model + ? { model: options.model, "flue.model": options.model } + : {}), + ...(options?.role ? { "flue.role": options.role } : {}), + ...(options?.thinkingLevel + ? { "flue.thinking_level": options.thinkingLevel } + : {}), + ...(typeof options?.cwd === "string" ? { "flue.cwd": options.cwd } : {}), + ...(Array.isArray(options?.tools) + ? { + "flue.tools_count": options.tools.length, + tools: summarizeTools(options.tools), + } + : {}), + ...(Array.isArray(options?.images) + ? { "flue.images_count": options.images.length } + : {}), + ...(options?.result || options?.schema + ? { "flue.result_schema": true } + : {}), + }; +} + +function getOptionObject( + value: unknown, +): (FlueCallOptions & FlueSkillOptions & FlueTaskOptions) | undefined { + return isObject(value) + ? (value as FlueCallOptions & FlueSkillOptions & FlueTaskOptions) + : undefined; +} + +function summarizeTools(tools: unknown[]): unknown[] { + return tools.flatMap((tool) => { + if (!isObject(tool)) { + return []; + } + const name = typeof tool.name === "string" ? tool.name : undefined; + if (!name) { + return []; + } + return [ + { + function: { + description: + typeof tool.description === "string" ? tool.description : undefined, + name, + parameters: tool.parameters, + }, + type: "function", + }, + ]; + }); +} + +function extractPromptResponseMetadata( + result: FluePromptResponse | undefined, +): Record { + const modelId = + result?.model && typeof result.model.id === "string" + ? result.model.id + : undefined; + return modelId + ? { + model: modelId, + "flue.model": modelId, + } + : {}; +} + +function extractOperationOutput( + result: FluePromptResponse | undefined, +): unknown { + if (!result) { + return undefined; + } + if ("data" in result) { + return result.data; + } + if ("text" in result) { + return result.text; + } + return result; +} + +function metricsFromUsage( + usage: FlueUsage | undefined, +): Record { + return { + ...(typeof usage?.input === "number" ? { prompt_tokens: usage.input } : {}), + ...(typeof usage?.output === "number" + ? { completion_tokens: usage.output } + : {}), + ...(typeof usage?.cacheRead === "number" + ? { prompt_cached_tokens: usage.cacheRead } + : {}), + ...(typeof usage?.cacheWrite === "number" + ? { prompt_cache_creation_tokens: usage.cacheWrite } + : {}), + ...(typeof usage?.totalTokens === "number" + ? { tokens: usage.totalTokens } + : {}), + ...(typeof usage?.cost?.total === "number" + ? { estimated_cost: usage.cost.total } + : {}), + }; +} + +function buildDurationMetrics(startTime: number): Record { + return { + duration_ms: Math.max(0, (getCurrentUnixTimestamp() - startTime) * 1000), + }; +} + +function durationMsMetrics(durationMs: unknown): Record { + return typeof durationMs === "number" ? { duration_ms: durationMs } : {}; +} + +function scopeKey(event: FlueBaseEvent): string { + if (event.operationId) { + return `operation:${event.operationId}`; + } + if (event.taskId) { + return `task:${event.taskId}`; + } + if (event.session) { + return `session:${event.session}`; + } + return "flue:unknown"; +} + +function toolKey( + event: Pick & { + toolCallId?: string; + }, +): string { + return `${scopeKey(event)}::tool:${event.toolCallId ?? "unknown"}`; +} + +function toAssistantOutput( + text: string, + finishReason: string | undefined, + reasoning?: string, + toolCalls?: Array<{ + args?: unknown; + toolCallId?: string; + toolName?: string; + }>, +): unknown { + return [ + { + finish_reason: finishReason ?? "stop", + index: 0, + message: { + content: text, + ...(reasoning ? { reasoning } : {}), + role: "assistant", + ...(toolCalls?.length + ? { + tool_calls: toolCalls.map((toolCall) => ({ + function: { + arguments: + toolCall.args === undefined + ? "{}" + : JSON.stringify(toolCall.args), + name: toolCall.toolName ?? "unknown", + }, + ...(toolCall.toolCallId ? { id: toolCall.toolCallId } : {}), + type: "function", + })), + } + : {}), + }, + }, + ]; +} + +function startFlueSpan( + parent: Span | undefined, + args: Parameters[0], +): Span { + return parent ? withCurrent(parent, () => startSpan(args)) : startSpan(args); +} + +function safeLog(span: Span, event: Parameters[0]): void { + try { + span.log(event); + } catch (error) { + logInstrumentationError("Flue span log", error); + } +} + +function errorToString(error: unknown): string { + if (error instanceof Error) { + return error.message; + } + if (typeof error === "string") { + return error; + } + try { + return JSON.stringify(error); + } catch { + return String(error); + } +} + +function logInstrumentationError(label: string, error: unknown): void { + // eslint-disable-next-line no-restricted-properties -- preserving intentional console usage. + console.error(`Error in ${label} instrumentation:`, error); +} diff --git a/js/src/instrumentation/registry.ts b/js/src/instrumentation/registry.ts index 6ee4755ea..577e5fd3a 100644 --- a/js/src/instrumentation/registry.ts +++ b/js/src/instrumentation/registry.ts @@ -58,6 +58,7 @@ export interface InstrumentationConfig { genkit?: boolean; gitHubCopilot?: boolean; openaiCodexSDK?: boolean; + flue?: boolean; }; } @@ -171,6 +172,7 @@ class PluginRegistry { groq: true, genkit: true, gitHubCopilot: true, + flue: true, }; } @@ -199,6 +201,8 @@ class PluginRegistry { integrations.gitHubCopilot = false; } else if (sdk === "openai-codex-sdk") { integrations.openaiCodexSDK = false; + } else if (sdk === "flue-runtime") { + integrations.flue = false; } else { integrations[sdk] = false; } diff --git a/js/src/vendor-sdk-types/flue.ts b/js/src/vendor-sdk-types/flue.ts new file mode 100644 index 000000000..bc1174ebf --- /dev/null +++ b/js/src/vendor-sdk-types/flue.ts @@ -0,0 +1,207 @@ +/** + * Vendored types for @flue/runtime used by Braintrust instrumentation. + * + * Keep this surface intentionally narrow. These types are not exported to SDK + * users and should only cover fields we read, wrap, or log. + */ + +export type FlueOperationKind = "prompt" | "skill" | "task" | "compact"; + +export interface FlueUsage { + input?: number; + output?: number; + cacheRead?: number; + cacheWrite?: number; + totalTokens?: number; + cost?: { + input?: number; + output?: number; + cacheRead?: number; + cacheWrite?: number; + total?: number; + }; +} + +export interface FluePromptResponse { + text?: string; + data?: unknown; + result?: unknown; + usage?: FlueUsage; + model?: { + id?: string; + }; + [key: string]: unknown; +} + +export interface FlueCallOptions { + model?: string; + role?: string; + thinkingLevel?: string; + tools?: FlueToolDef[]; + signal?: AbortSignal; + images?: unknown[]; + result?: unknown; + schema?: unknown; + [key: string]: unknown; +} + +export interface FlueSkillOptions extends FlueCallOptions { + args?: Record; +} + +export interface FlueTaskOptions extends FlueCallOptions { + cwd?: string; +} + +export interface FlueToolDef { + name?: string; + description?: string; + parameters?: unknown; + execute?: unknown; + [key: string]: unknown; +} + +export interface FlueCallHandle extends PromiseLike { + readonly signal: AbortSignal; + abort(reason?: unknown): void; +} + +export interface FlueSession { + readonly name?: string; + prompt(text: string, options?: FlueCallOptions): FlueCallHandle; + skill(name: string, options?: FlueSkillOptions): FlueCallHandle; + task(text: string, options?: FlueTaskOptions): FlueCallHandle; + compact(): Promise; + [key: string | symbol]: unknown; +} + +export interface FlueSessions { + get(name?: string, options?: unknown): Promise; + create(name?: string, options?: unknown): Promise; + [key: string | symbol]: unknown; +} + +export interface FlueHarness { + readonly name?: string; + session(name?: string, options?: unknown): Promise; + readonly sessions?: FlueSessions; + [key: string | symbol]: unknown; +} + +export interface FlueContext { + readonly id?: string; + readonly runId?: string; + init(options: unknown): Promise; + subscribeEvent?: (callback: (event: FlueEvent) => void) => () => void; + [key: string | symbol]: unknown; +} + +export interface FlueBaseEvent { + type?: string; + runId?: string; + eventIndex?: number; + timestamp?: string; + session?: string; + parentSession?: string; + taskId?: string; + harness?: string; + operationId?: string; + [key: string]: unknown; +} + +export interface FlueOperationStartEvent extends FlueBaseEvent { + type: "operation_start"; + operationId: string; + operationKind: FlueOperationKind | "shell"; +} + +export interface FlueOperationEvent extends FlueBaseEvent { + type: "operation"; + operationId: string; + operationKind: FlueOperationKind | "shell"; + durationMs?: number; + isError?: boolean; + error?: unknown; + result?: unknown; + usage?: FlueUsage; +} + +export interface FlueTurnEvent extends FlueBaseEvent { + type: "turn"; + durationMs?: number; + model?: string; + usage?: FlueUsage; + stopReason?: string; + isError?: boolean; + error?: unknown; +} + +export interface FlueThinkingDeltaEvent extends FlueBaseEvent { + type: "thinking_delta"; + delta?: string; +} + +export interface FlueThinkingEndEvent extends FlueBaseEvent { + type: "thinking_end"; + content?: string; +} + +export interface FlueToolStartEvent extends FlueBaseEvent { + type: "tool_start"; + toolName?: string; + toolCallId?: string; + args?: unknown; +} + +export interface FlueToolCallEvent extends FlueBaseEvent { + type: "tool_call"; + toolName?: string; + toolCallId?: string; + isError?: boolean; + result?: unknown; + durationMs?: number; +} + +export interface FlueTaskStartEvent extends FlueBaseEvent { + type: "task_start"; + taskId: string; + prompt?: string; + role?: string; + cwd?: string; +} + +export interface FlueTaskEvent extends FlueBaseEvent { + type: "task"; + taskId: string; + isError?: boolean; + result?: unknown; + durationMs?: number; +} + +export interface FlueCompactionStartEvent extends FlueBaseEvent { + type: "compaction_start"; + reason?: "threshold" | "overflow" | "manual"; + estimatedTokens?: number; +} + +export interface FlueCompactionEvent extends FlueBaseEvent { + type: "compaction"; + messagesBefore?: number; + messagesAfter?: number; + durationMs?: number; + usage?: FlueUsage; +} + +export type FlueEvent = + | FlueOperationStartEvent + | FlueOperationEvent + | FlueThinkingDeltaEvent + | FlueThinkingEndEvent + | FlueTurnEvent + | FlueToolStartEvent + | FlueToolCallEvent + | FlueTaskStartEvent + | FlueTaskEvent + | FlueCompactionStartEvent + | FlueCompactionEvent + | FlueBaseEvent; diff --git a/js/src/wrappers/flue.test.ts b/js/src/wrappers/flue.test.ts new file mode 100644 index 000000000..27b252b57 --- /dev/null +++ b/js/src/wrappers/flue.test.ts @@ -0,0 +1,195 @@ +import { afterEach, describe, expect, it, vi } from "vitest"; + +const { + publishAsyncEnd, + publishAsyncStart, + publishEnd, + publishStart, + traceSync, +} = vi.hoisted(() => ({ + publishAsyncEnd: vi.fn(), + publishAsyncStart: vi.fn(), + publishEnd: vi.fn(), + publishStart: vi.fn(), + traceSync: vi.fn((fn: () => unknown) => fn()), +})); + +vi.mock("../isomorph", () => ({ + default: { + newTracingChannel: vi.fn(() => ({ + asyncEnd: { + publish: publishAsyncEnd, + }, + asyncStart: { + publish: publishAsyncStart, + }, + end: { + publish: publishEnd, + }, + error: { + publish: vi.fn(), + }, + start: { + publish: publishStart, + }, + subscribe: vi.fn(), + traceSync, + unsubscribe: vi.fn(), + })), + }, +})); + +import { wrapFlueContext, wrapFlueSession } from "./flue"; + +describe("wrapFlueSession", () => { + afterEach(() => { + vi.clearAllMocks(); + }); + + it("patches prompt, skill, task, and compact", async () => { + const session = makeSession(); + + wrapFlueSession(session); + + await session.prompt("hello", { model: "pi/test" }); + await session.skill("review", { args: { id: 1 } }); + await session.task("delegate this"); + await session.compact(); + + expect(publishStart).toHaveBeenCalledTimes(4); + expect(publishEnd).toHaveBeenCalledTimes(4); + expect(publishAsyncStart).toHaveBeenCalledTimes(4); + expect(publishAsyncEnd).toHaveBeenCalledTimes(4); + expect(session.originals.prompt).toHaveBeenCalledWith("hello", { + model: "pi/test", + }); + expect(session.originals.skill).toHaveBeenCalledWith("review", { + args: { id: 1 }, + }); + expect(session.originals.task).toHaveBeenCalledWith( + "delegate this", + undefined, + ); + expect(session.originals.compact).toHaveBeenCalledTimes(1); + }); + + it("preserves CallHandle signal, abort, and then behavior", async () => { + const controller = new AbortController(); + const abort = vi.fn(); + const promise = Promise.resolve({ text: "ok" }); + const handle = { + abort, + signal: controller.signal, + then: promise.then.bind(promise), + }; + const session = { + compact: vi.fn(async () => undefined), + name: "main", + prompt: vi.fn(() => handle), + skill: vi.fn(() => handle), + task: vi.fn(() => handle), + }; + + wrapFlueSession(session); + const returned = session.prompt("hello"); + + expect(returned).not.toBe(handle); + expect(returned.signal).toBe(controller.signal); + returned.abort("stop"); + await expect(returned).resolves.toEqual({ text: "ok" }); + expect(abort).toHaveBeenCalledWith("stop"); + }); + + it("is idempotent", async () => { + const session = makeSession(); + + wrapFlueSession(session); + wrapFlueSession(session); + await session.prompt("hello"); + + expect(publishStart).toHaveBeenCalledTimes(1); + expect(session.originals.prompt).toHaveBeenCalledTimes(1); + }); +}); + +describe("wrapFlueContext", () => { + afterEach(() => { + vi.clearAllMocks(); + }); + + it("subscribes to context events and wraps harness sessions returned by init", async () => { + let subscriber: ((event: unknown) => void) | undefined; + const session = makeSession(); + const harness = { + name: "default", + session: vi.fn(async () => session), + sessions: { + create: vi.fn(async () => session), + get: vi.fn(async () => session), + }, + }; + const ctx = { + init: vi.fn(async () => harness), + subscribeEvent: vi.fn((callback) => { + subscriber = callback; + return vi.fn(); + }), + }; + + wrapFlueContext(ctx); + const returnedHarness = await ctx.init({ model: "pi/test" }); + const returnedSession = await returnedHarness.session("main"); + + await returnedSession.prompt("hello"); + subscriber?.({ operationId: "op_1", type: "operation_start" }); + + expect(ctx.subscribeEvent).toHaveBeenCalledTimes(1); + expect(publishStart).toHaveBeenCalledTimes(1); + expect(traceSync).toHaveBeenCalledWith( + expect.any(Function), + expect.objectContaining({ + arguments: [{ operationId: "op_1", type: "operation_start" }], + context: ctx, + }), + ); + }); + + it("returns invalid contexts unchanged", () => { + const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => {}); + const value = { session: vi.fn() }; + + expect(wrapFlueContext(value)).toBe(value); + expect(warnSpy).toHaveBeenCalledWith( + "Unsupported Flue context. Not wrapping.", + ); + + warnSpy.mockRestore(); + }); +}); + +function makeHandle(result: unknown = { text: "ok" }) { + const promise = Promise.resolve(result); + return { + abort: vi.fn(), + signal: new AbortController().signal, + then: promise.then.bind(promise), + }; +} + +function makeSession() { + const originals = { + compact: vi.fn(async () => undefined), + prompt: vi.fn(() => makeHandle({ text: "prompt ok" })), + skill: vi.fn(() => makeHandle({ text: "skill ok" })), + task: vi.fn(() => makeHandle({ text: "task ok" })), + }; + + return { + compact: originals.compact, + name: "main", + originals, + prompt: originals.prompt, + skill: originals.skill, + task: originals.task, + }; +} diff --git a/js/src/wrappers/flue.ts b/js/src/wrappers/flue.ts new file mode 100644 index 000000000..170348c55 --- /dev/null +++ b/js/src/wrappers/flue.ts @@ -0,0 +1,391 @@ +import { flueChannels } from "../instrumentation/plugins/flue-channels"; +import type { + FlueCallHandle, + FlueCallOptions, + FlueContext, + FlueEvent, + FlueHarness, + FlueSession, + FlueSkillOptions, + FlueTaskOptions, +} from "../vendor-sdk-types/flue"; + +const WRAPPED_FLUE_CONTEXT = Symbol.for("braintrust.flue.wrapped-context"); +const WRAPPED_FLUE_HARNESS = Symbol.for("braintrust.flue.wrapped-harness"); +const WRAPPED_FLUE_SESSION = Symbol.for("braintrust.flue.wrapped-session"); +const SUBSCRIBED_FLUE_CONTEXT_EVENTS = Symbol.for( + "braintrust.flue.subscribed-context-events", +); + +type FlueContextRecord = FlueContext & Record; +type FlueHarnessRecord = FlueHarness & Record; +type FlueSessionRecord = FlueSession & Record; +type FlueOperationChannel = + | typeof flueChannels.prompt + | typeof flueChannels.skill + | typeof flueChannels.task + | typeof flueChannels.compact; +type PublishChannel = { + publish(message: unknown): void; +}; +type ManualTracingChannel = { + asyncEnd?: PublishChannel; + asyncStart?: PublishChannel; + end?: PublishChannel; + error?: PublishChannel; + start?: PublishChannel; +}; + +/** + * Wraps a Flue context with Braintrust tracing. Context wrapping subscribes to + * Flue's event stream and patches ctx.init() so returned harness sessions emit + * operation diagnostics-channel events. + */ +export function wrapFlueContext(ctx: T): T { + if (!isPlausibleFlueContext(ctx)) { + // eslint-disable-next-line no-restricted-properties -- preserving intentional console usage. + console.warn("Unsupported Flue context. Not wrapping."); + return ctx; + } + + const context = ctx as FlueContextRecord; + subscribeFlueContextEvents(context); + if (context[WRAPPED_FLUE_CONTEXT]) { + return ctx; + } + + const originalInit = context.init.bind(context); + try { + Object.defineProperty(context, WRAPPED_FLUE_CONTEXT, { + configurable: false, + enumerable: false, + value: true, + }); + Object.defineProperty(context, "init", { + configurable: true, + value: async function wrappedFlueInit(options: unknown) { + const harness = await originalInit(options); + return wrapFlueHarness(harness); + }, + writable: true, + }); + } catch { + // Frozen/sealed contexts cannot be patched. Leave user behavior untouched. + } + + return ctx; +} + +/** + * Wraps a Flue session with Braintrust tracing. Direct session wrapping traces + * top-level prompt/skill/task/compact calls. Event-derived child spans require + * context instrumentation through wrapFlueContext() or auto-instrumentation. + */ +export function wrapFlueSession(session: T): T { + if (!isPlausibleFlueSession(session)) { + // eslint-disable-next-line no-restricted-properties -- preserving intentional console usage. + console.warn("Unsupported Flue session. Not wrapping."); + return session; + } + + return patchFlueSessionInPlace(session as FlueSessionRecord) as T; +} + +export function subscribeFlueContextEvents( + ctx: FlueContext, +): (() => void) | undefined { + if ( + !ctx || + typeof ctx !== "object" || + typeof ctx.subscribeEvent !== "function" + ) { + return undefined; + } + + const context = ctx as FlueContextRecord; + if (context[SUBSCRIBED_FLUE_CONTEXT_EVENTS]) { + return undefined; + } + + try { + const unsubscribe = ctx.subscribeEvent((event: FlueEvent) => { + flueChannels.contextEvent.traceSync(() => undefined, { + arguments: [event], + context: ctx, + } as never); + }); + Object.defineProperty(context, SUBSCRIBED_FLUE_CONTEXT_EVENTS, { + configurable: false, + enumerable: false, + value: true, + }); + return unsubscribe; + } catch { + return undefined; + } +} + +export function wrapFlueHarness(harness: T): T { + if (!isPlausibleFlueHarness(harness)) { + return harness; + } + + const target = harness as FlueHarnessRecord; + if (target[WRAPPED_FLUE_HARNESS]) { + return harness; + } + + const originalSession = target.session.bind(target); + try { + Object.defineProperty(target, WRAPPED_FLUE_HARNESS, { + configurable: false, + enumerable: false, + value: true, + }); + Object.defineProperty(target, "session", { + configurable: true, + value: async function wrappedFlueHarnessSession( + name?: string, + options?: unknown, + ) { + const session = await originalSession(name, options); + return patchFlueSessionInPlace(session as FlueSessionRecord); + }, + writable: true, + }); + + const sessions = target.sessions; + if (sessions && typeof sessions === "object") { + patchFlueSessionFactory(sessions, "get"); + patchFlueSessionFactory(sessions, "create"); + } + } catch { + // Frozen/sealed harnesses cannot be patched. Leave user behavior untouched. + } + + return harness; +} + +export function patchFlueSessionInPlace( + session: T, +): T { + if (session[WRAPPED_FLUE_SESSION]) { + return session; + } + + try { + Object.defineProperty(session, WRAPPED_FLUE_SESSION, { + configurable: false, + enumerable: false, + value: true, + }); + + patchCallHandleMethod(session, "prompt", flueChannels.prompt); + patchCallHandleMethod(session, "skill", flueChannels.skill); + patchCallHandleMethod(session, "task", flueChannels.task); + patchCompact(session); + } catch { + // Frozen/sealed sessions cannot be patched. Leave user behavior untouched. + } + + return session; +} + +function patchFlueSessionFactory( + sessions: Record, + method: "get" | "create", +): void { + const original = sessions[method]; + if (typeof original !== "function") { + return; + } + + const bound = original.bind(sessions); + Object.defineProperty(sessions, method, { + configurable: true, + value: async function wrappedFlueSessionFactory( + name?: string, + options?: unknown, + ) { + const session = await bound(name, options); + return patchFlueSessionInPlace(session as FlueSessionRecord); + }, + writable: true, + }); +} + +function patchCallHandleMethod( + session: FlueSessionRecord, + method: "prompt" | "skill" | "task", + channel: + | typeof flueChannels.prompt + | typeof flueChannels.skill + | typeof flueChannels.task, +): void { + const original = session[method]; + if (typeof original !== "function") { + return; + } + + const bound = original.bind(session); + Object.defineProperty(session, method, { + configurable: true, + value( + input: string, + options?: FlueCallOptions | FlueSkillOptions | FlueTaskOptions, + ) { + const args = [input, options] as never; + const { originalResult, traced } = traceFlueOperation(channel, { + context: { + arguments: args, + operation: method, + session, + } as never, + run: () => bound(input, options), + }); + return preserveCallHandle(originalResult, traced); + }, + writable: true, + }); +} + +function patchCompact(session: FlueSessionRecord): void { + const original = session.compact; + if (typeof original !== "function") { + return; + } + + const bound = original.bind(session); + Object.defineProperty(session, "compact", { + configurable: true, + value() { + return traceFlueOperation(flueChannels.compact, { + context: { + arguments: [], + operation: "compact", + session, + } as never, + run: () => bound(), + }).traced; + }, + writable: true, + }); +} + +function traceFlueOperation( + channel: FlueOperationChannel, + args: { + context: Parameters[1]; + run: () => PromiseLike; + }, +): { + originalResult: PromiseLike; + traced: Promise; +} { + const tracingChannel = channel.tracingChannel() as ManualTracingChannel; + const context = args.context as Record; + + tracingChannel.start?.publish(context); + let originalResult: PromiseLike; + try { + originalResult = args.run(); + tracingChannel.end?.publish(context); + } catch (error) { + context.error = normalizeError(error); + tracingChannel.error?.publish(context); + tracingChannel.end?.publish(context); + throw error; + } + + const traced = Promise.resolve(originalResult).then( + (result) => { + context.result = result; + tracingChannel.asyncStart?.publish(context); + tracingChannel.asyncEnd?.publish(context); + return result; + }, + (error: unknown) => { + context.error = normalizeError(error); + tracingChannel.error?.publish(context); + tracingChannel.asyncStart?.publish(context); + tracingChannel.asyncEnd?.publish(context); + throw error; + }, + ); + + return { originalResult, traced }; +} + +function normalizeError(error: unknown): Error { + return error instanceof Error ? error : new Error(String(error)); +} + +function preserveCallHandle( + originalHandle: unknown, + traced: PromiseLike, +): PromiseLike { + if (!isFlueCallHandle(originalHandle)) { + return traced; + } + + const handle = originalHandle; + const wrapped = { + get signal() { + return handle.signal; + }, + abort(reason?: unknown) { + return handle.abort(reason); + }, + then( + onfulfilled?: + | ((value: unknown) => TResult1 | PromiseLike) + | undefined + | null, + onrejected?: + | ((reason: unknown) => TResult2 | PromiseLike) + | undefined + | null, + ) { + return traced.then(onfulfilled, onrejected); + }, + } satisfies FlueCallHandle; + + return wrapped; +} + +function isPlausibleFlueContext(value: unknown): value is FlueContext { + return ( + !!value && + typeof value === "object" && + typeof (value as { init?: unknown }).init === "function" + ); +} + +function isPlausibleFlueHarness(value: unknown): value is FlueHarness { + return ( + !!value && + typeof value === "object" && + typeof (value as { session?: unknown }).session === "function" + ); +} + +function isPlausibleFlueSession(value: unknown): value is FlueSession { + return ( + !!value && + typeof value === "object" && + typeof (value as { prompt?: unknown }).prompt === "function" && + typeof (value as { skill?: unknown }).skill === "function" && + typeof (value as { task?: unknown }).task === "function" && + typeof (value as { compact?: unknown }).compact === "function" + ); +} + +function isFlueCallHandle(value: unknown): value is FlueCallHandle { + return ( + !!value && + typeof value === "object" && + typeof (value as { then?: unknown }).then === "function" && + typeof (value as { abort?: unknown }).abort === "function" && + "signal" in value + ); +} From eedfd68e3c1febca85690664ed927588f8ece112 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Thu, 21 May 2026 14:32:05 +0200 Subject: [PATCH 2/6] . --- .../plugins/flue-plugin.test.ts | 98 +++++++++++++++++++ js/src/instrumentation/plugins/flue-plugin.ts | 6 +- 2 files changed, 103 insertions(+), 1 deletion(-) diff --git a/js/src/instrumentation/plugins/flue-plugin.test.ts b/js/src/instrumentation/plugins/flue-plugin.test.ts index e1b12bd14..26864deaa 100644 --- a/js/src/instrumentation/plugins/flue-plugin.test.ts +++ b/js/src/instrumentation/plugins/flue-plugin.test.ts @@ -436,6 +436,104 @@ describe("FluePlugin", () => { expect(toolSpan?.spanParents).toEqual(turnSpan?.spanParents); expect(toolSpan?.spanParents).not.toContain(turnSpan?.spanId); }); + + it("records tool calls when tool_start is the first turn event", () => { + const plugin = new FluePlugin(); + plugin.enable(); + + const contextHandlers = handlersByName.get( + "orchestrion:@flue/runtime:context.event", + ); + const promptHandlers = handlersByName.get( + "orchestrion:@flue/runtime:session.prompt", + ); + const promptEvent = { + arguments: ["Use a tool", { model: "pi/test" }], + operation: "prompt", + session: { name: "main" }, + }; + + promptHandlers.start(promptEvent); + contextHandlers.start({ + arguments: [ + { + operationId: "op_1", + operationKind: "prompt", + session: "main", + type: "operation_start", + }, + ], + }); + contextHandlers.start({ + arguments: [ + { + args: { query: "braintrust" }, + operationId: "op_1", + toolCallId: "tool_1", + toolName: "lookup", + type: "tool_start", + }, + ], + }); + contextHandlers.start({ + arguments: [ + { + durationMs: 2, + isError: false, + operationId: "op_1", + result: "lookup ok", + toolCallId: "tool_1", + toolName: "lookup", + type: "tool_call", + }, + ], + }); + contextHandlers.start({ + arguments: [ + { + durationMs: 10, + isError: false, + model: "pi/test", + operationId: "op_1", + stopReason: "toolUse", + type: "turn", + usage: usage(), + }, + ], + }); + + const operationSpan = spans.find( + (span) => span.name === "flue.session.prompt", + ); + const turnSpan = spans.find((span) => span.name === "flue.turn"); + const toolSpan = spans.find((span) => span.name === "tool: lookup"); + + expect(turnSpan?.spanParents).toEqual([operationSpan?.spanId]); + expect(toolSpan?.spanParents).toEqual([operationSpan?.spanId]); + expect(toolSpan?.spanParents).not.toContain(turnSpan?.spanId); + expect(turnSpan?.log).toHaveBeenCalledWith( + expect.objectContaining({ + output: [ + expect.objectContaining({ + message: expect.objectContaining({ + content: "", + role: "assistant", + tool_calls: [ + { + function: { + arguments: JSON.stringify({ query: "braintrust" }), + name: "lookup", + }, + id: "tool_1", + type: "function", + }, + ], + }), + }), + ], + }), + ); + }); }); function makeSession() { diff --git a/js/src/instrumentation/plugins/flue-plugin.ts b/js/src/instrumentation/plugins/flue-plugin.ts index 9d6d43662..bdac30735 100644 --- a/js/src/instrumentation/plugins/flue-plugin.ts +++ b/js/src/instrumentation/plugins/flue-plugin.ts @@ -525,6 +525,11 @@ export class FluePlugin extends BasePlugin { } const parent = this.parentSpanForEvent(event); + const scope = scopeKey(event); + let turnState = this.turnsByScope.get(scope); + if (!turnState && parent) { + turnState = this.ensureTurnState(event); + } const metadata = { ...extractEventMetadata(event), ...(event.toolName ? { "flue.tool_name": event.toolName } : {}), @@ -535,7 +540,6 @@ export class FluePlugin extends BasePlugin { name: `tool: ${event.toolName ?? "unknown"}`, spanAttributes: { type: SpanTypeAttribute.TOOL }, }); - const turnState = this.turnsByScope.get(scopeKey(event)); if (turnState) { turnState.toolCalls.push({ args: event.args, From 579390ba70323645d2694d1c91445af7def2d55d Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Thu, 21 May 2026 14:32:49 +0200 Subject: [PATCH 3/6] cs --- .changeset/clear-months-fold.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/clear-months-fold.md diff --git a/.changeset/clear-months-fold.md b/.changeset/clear-months-fold.md new file mode 100644 index 000000000..640e64513 --- /dev/null +++ b/.changeset/clear-months-fold.md @@ -0,0 +1,5 @@ +--- +"braintrust": minor +--- + +feat: Add `@flue/runtime` instrumentation From 97acac2e18a2e959561e15a913b5a7bca25d4ddf Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Fri, 22 May 2026 10:55:37 +0200 Subject: [PATCH 4/6] reuse ai provider instrumentation --- e2e/config/pr-comment-scenarios.json | 4 + .../flue-v0-7-0-auto-hook.cassette.json | 678 +++-- ...flue-v0-7-0-openai-auto-hook.cassette.json | 2292 +++++++++++++++++ .../flue-v0-7-0-wrapped.cassette.json | 659 +++-- .../flue-v0-7-0-auto-hook.span-tree.json | 672 ++++- .../flue-v0-7-0-auto-hook.span-tree.txt | 677 ++++- ...lue-v0-7-0-openai-auto-hook.span-tree.json | 962 +++++++ ...flue-v0-7-0-openai-auto-hook.span-tree.txt | 834 ++++++ .../flue-v0-7-0-wrapped.span-tree.json | 147 +- .../flue-v0-7-0-wrapped.span-tree.txt | 146 +- .../flue-instrumentation/assertions.ts | 74 +- .../flue-instrumentation/scenario.impl.mjs | 32 +- .../flue-instrumentation/scenario.test.ts | 29 + .../plugins/flue-plugin.test.ts | 119 +- js/src/instrumentation/plugins/flue-plugin.ts | 187 +- js/src/wrappers/flue.test.ts | 22 + js/src/wrappers/flue.ts | 72 +- 17 files changed, 6678 insertions(+), 928 deletions(-) create mode 100644 e2e/scenarios/flue-instrumentation/__cassettes__/flue-v0-7-0-openai-auto-hook.cassette.json create mode 100644 e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-openai-auto-hook.span-tree.json create mode 100644 e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-openai-auto-hook.span-tree.txt diff --git a/e2e/config/pr-comment-scenarios.json b/e2e/config/pr-comment-scenarios.json index 17033f05a..ff360f812 100644 --- a/e2e/config/pr-comment-scenarios.json +++ b/e2e/config/pr-comment-scenarios.json @@ -171,6 +171,10 @@ { "variantKey": "flue-v0-7-0-auto-hook", "label": "v0.7.0 auto-hook" + }, + { + "variantKey": "flue-v0-7-0-openai-auto-hook", + "label": "v0.7.0 OpenAI auto-hook" } ] }, diff --git a/e2e/scenarios/flue-instrumentation/__cassettes__/flue-v0-7-0-auto-hook.cassette.json b/e2e/scenarios/flue-instrumentation/__cassettes__/flue-v0-7-0-auto-hook.cassette.json index c778acdca..f7947d6c0 100644 --- a/e2e/scenarios/flue-instrumentation/__cassettes__/flue-v0-7-0-auto-hook.cassette.json +++ b/e2e/scenarios/flue-instrumentation/__cassettes__/flue-v0-7-0-auto-hook.cassette.json @@ -4,7 +4,7 @@ "callIndex": 0, "id": "fcd9d51c145fb90b", "matchKey": "POST api.anthropic.com/v1/messages", - "recordedAt": "2026-05-21T06:48:59.246Z", + "recordedAt": "2026-05-22T08:13:16.879Z", "request": { "body": { "kind": "json", @@ -31,7 +31,7 @@ "cache_control": { "type": "ephemeral" }, - "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Thu, May 21, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-LqmoTW/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-HpI3r1/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", "type": "text" } ], @@ -59,7 +59,9 @@ "type": "string" } }, - "required": ["path"], + "required": [ + "path" + ], "type": "object" }, "name": "read" @@ -78,7 +80,10 @@ "type": "string" } }, - "required": ["path", "content"], + "required": [ + "path", + "content" + ], "type": "object" }, "name": "write" @@ -105,7 +110,11 @@ "type": "boolean" } }, - "required": ["path", "oldText", "newText"], + "required": [ + "path", + "oldText", + "newText" + ], "type": "object" }, "name": "edit" @@ -124,7 +133,9 @@ "type": "number" } }, - "required": ["command"], + "required": [ + "command" + ], "type": "object" }, "name": "bash" @@ -147,7 +158,9 @@ "type": "string" } }, - "required": ["pattern"], + "required": [ + "pattern" + ], "type": "object" }, "name": "grep" @@ -166,7 +179,9 @@ "type": "string" } }, - "required": ["pattern"], + "required": [ + "pattern" + ], "type": "object" }, "name": "glob" @@ -193,7 +208,9 @@ "type": "string" } }, - "required": ["prompt"], + "required": [ + "prompt" + ], "type": "object" }, "name": "task" @@ -207,7 +224,9 @@ "type": "string" } }, - "required": ["query"], + "required": [ + "query" + ], "type": "object" }, "name": "lookup" @@ -224,7 +243,10 @@ "type": "string" } }, - "required": ["lookupId", "query"], + "required": [ + "lookupId", + "query" + ], "type": "object" }, "name": "web_search" @@ -241,7 +263,9 @@ "type": "string" } }, - "required": ["url"], + "required": [ + "url" + ], "type": "object" }, "name": "summarize_source" @@ -256,25 +280,26 @@ "response": { "body": { "chunks": [ - "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-5-20250929\",\"id\":\"msg_01Au3mXEtqA63VYCtzrcsMMJ\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":10,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":2182,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":6,\"service_tier\":\"standard\",\"inference_geo\":\"not_available\"}}}", + "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-5-20250929\",\"id\":\"msg_01DgnJ1WxXezkCZXuWV4N4UV\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":10,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":2184,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":8,\"service_tier\":\"standard\",\"inference_geo\":\"not_available\"}}}", "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"thinking\",\"thinking\":\"\",\"signature\":\"\"}}", "event: ping\ndata: {\"type\":\"ping\"}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\"The user wants me to complete\"}}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\" a specific instrumented research flow with three steps:\\n1. Call lookup with query \\\"flue instrumentation\\\"\\n2. Use the lookup result id to call web_search with query \\\"\"}}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\"Braintrust Flue reasoning stream instrumentation\\\"\\n3. Use the first web_search result url to call summarize_source\\n4. Reply with exactly \\\"PROMPT_DONE\\\" after summarize_source returns\\n\\nThe user emphas\"}}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\"izes calling exactly one tool per turn and waiting for each result. Let me start with step\"}}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\" 1.\"}}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"signature_delta\",\"signature\":\"ErUFCm4IDRgCKkAHu6lMZFTp53LRtoPoqjh0UrHuoIv5LTsJ7I3lHUVfs2ATNSQg9u7H+Ep/U2V3+dm55Z9I4XCuyKRcFlBIT0W2MhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMD1Qwe6/eMf8eVU1xGgwRhWxvkBZIEe9uad4iMGqUVZm3nslEGlnXnWFtC1Lo7eVfCTKPyaVMydEWLFdEkVYBr4jZ8G6xirmMvluO/Sr0A7PXSEQ+n3qF+VkUcwgO7gbSD97SYUIXKVh6QvFX9zzPIU40Ahbqq5bqU0TKXv4hbAoU8sDV4Af0KXw/9r8FocY9Ys2xX6YrVAi8v61I23dP82Zxy2VbaLrL4i744blW+VmU77L7xpH7y3RzQfldUrYzh0Buu45sh3yG/v3woK9FY1wm1v3dvDmQpV+HOU5hl0zyk8Mr/SpDm2uTAqjoT8DsOdKVerDvP9SrSbpG8sNiqT9ROv6ziY1Yq89hRR7F159Ntc1w8thi3evN7QYO2GD5LkR1GeGY5gOA4134B6/EktGcmzb1Rx0LY6BRb3T2QipZTDq+G7xwsnJNDiPz4/hchrWNzlXvc/6auvuOb9WkMGgtnox5/4/C8ZI/hCIGyvpb+mZcbewPbBXD91/neSrVP1dJC6F0t645nUK49AK8AE41lOJA6rB3sxfCItl2SiScJuRSBEE9NiseNJvpaZDxjuXQc4UWT6Uszo+LrngRTsJDWTUnF5239i15Sb7WQW0Xs0EgNA1Y6n7/6ma0EH+U9DmPD1c01o19iL9AI2ADGUeIQLSNA9OmUsLpquqFFmvWMLJ6ubYCbgHyogMfdRD6hpoN25OCQl2EP24yB0BY27rVuygYXbIOJ+vSpat0uCd8akup/g26YxcXouSYf98LTuE6GAE=\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\"The user wants me to complete a specific\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\" instrumented research flow with these steps:\\n1. Call lookup with query \\\"flue instrumentation\\\"\\n2. Use the lookup result id as lookupId and\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\" call web_search with query \\\"Braintrust Flue reasoning stream instrumentation\\\"\\n3. Use the first web_search result url and call summarize_source\\n4. After summarize_source returns, reply with exactly \\\"PROMPT_DONE\\\" and no\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\" other text\\n\\nThe user emphasizes calling exactly one tool per turn and waiting for each result. Let me start\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\" with step 1.\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"signature_delta\",\"signature\":\"EtYFCm4IDRgCKkC/lJUT/EhYE72Jr10vREWOZ4vwSSugL9RsNrhJg9wjli7iCBt2/hEandW2KZpRqluVbV3ehHY/n0Mge6VmWF1cMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMHcfwfYOEmmJZGyBBGgyYm8sT/W36vQdF0dQiMFC5CVRWmqhR2r90pB0R8Wjbq0ITTIN0abxhOezE1NDsrj6CM4/DXLaOsJp4TD5DNCqVBEgEEzFdeaRrRB0CeXdlWoo+wf7yR9EMOVhLmyRf3nItrqN/cb30rpaexhXDm0/Hj3WxQH+o0K73Oyr6qtiDVe9xGNt6v5DrUz31HcE+GJ0Yw8ThoufXvqNyFQV3lLhpZExUDX6hwlmKvaRpj5YH+q5TTx3jAIgzD+zGkgUS0vC7Muftm2VZcuI/2wVsbtWo6hYdvbbdxr+8FzJsCOWc3ptVaUBimC5//HRSNBXFJ9zlkt6l7YxnUeKWiesSdE6h1EJ08Rp4OrAP+oaYWU4v6IODdnJmsqGKbN//i6gGCnAHBBAZr/pnnmEyUOsBGc6ARMOtcwjFIN3/B1YkJi8r8QbbtGHJHfH/v102MSZG8UJk2RXxt1fTQUWNbp0DjA7gUn00H3dnmSAQyqFjKLIFncnhiH5PSSgdvErNB7y/2UBk2CY2i4dpevr+7uvHZDLPjSBcovpvgJ4ihdUM9S080xCm1NNkjs+QP+AQAh20t33t7EN6aZS0+CZcfJxf1QV6mGIkL7BKAPeIXjD8TKuW/at4pqwrvvesI2cZY5RDjC7v7tz/+tqiEkob1s8J3jx2dbIgPBFOR5PFFwPby0H9Guv4ZB63YAlP3sXX+F5fC6fQifQeJK8fuWK+FKe3v+gK/hZcuBuU/Jfhrst4CsEWeaBhmPktZOHu5f85KZ/layh4Pp39yxR0FiHY5eXibsTh2SfDN3K6GAE=\"}}", "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0}", "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":1,\"content_block\":{\"type\":\"text\",\"text\":\"\"}}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"text_delta\",\"text\":\"I'll complete this instrumented research flow step by step. Starting with Step 1:\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"text_delta\",\"text\":\"I'll complete this instrumented research flow step by step. Starting with step\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"text_delta\",\"text\":\" 1:\"}}", "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":1}", - "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":2,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01NWGcbaEYFCSv7jbHaV61xR\",\"name\":\"lookup\",\"input\":{},\"caller\":{\"type\":\"direct\"}}}", + "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":2,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01QHXkUBddKx6pexY4WSjMR1\",\"name\":\"lookup\",\"input\":{},\"caller\":{\"type\":\"direct\"}}}", "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"}}", "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"query\\\": \\\"flue instrumentation\"}}", "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"}\"}}", "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":2}", - "event: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":10,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":2182,\"output_tokens\":199}}", + "event: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":10,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":2184,\"output_tokens\":208}}", "event: message_stop\ndata: {\"type\":\"message_stop\"}" ], "kind": "sse" @@ -283,32 +308,32 @@ "anthropic-organization-id": "27796668-7351-40ac-acc4-024aee8995a5", "anthropic-ratelimit-input-tokens-limit": "3000000", "anthropic-ratelimit-input-tokens-remaining": "2999000", - "anthropic-ratelimit-input-tokens-reset": "2026-05-21T06:48:55Z", + "anthropic-ratelimit-input-tokens-reset": "2026-05-22T08:13:13Z", "anthropic-ratelimit-output-tokens-limit": "600000", "anthropic-ratelimit-output-tokens-remaining": "600000", - "anthropic-ratelimit-output-tokens-reset": "2026-05-21T06:48:55Z", + "anthropic-ratelimit-output-tokens-reset": "2026-05-22T08:13:13Z", "anthropic-ratelimit-requests-limit": "20000", "anthropic-ratelimit-requests-remaining": "19999", - "anthropic-ratelimit-requests-reset": "2026-05-21T06:48:55Z", + "anthropic-ratelimit-requests-reset": "2026-05-22T08:13:13Z", "anthropic-ratelimit-tokens-limit": "3600000", "anthropic-ratelimit-tokens-remaining": "3599000", - "anthropic-ratelimit-tokens-reset": "2026-05-21T06:48:55Z", + "anthropic-ratelimit-tokens-reset": "2026-05-22T08:13:13Z", "cache-control": "no-cache", "cf-cache-status": "DYNAMIC", - "cf-ray": "9ff1a3628fa9c2f2-VIE", + "cf-ray": "9ffa5c3e0d7f5db9-VIE", "connection": "keep-alive", "content-encoding": "gzip", "content-security-policy": "default-src 'none'; frame-ancestors 'none'", "content-type": "text/event-stream; charset=utf-8", - "date": "Thu, 21 May 2026 06:48:56 GMT", - "request-id": "req_011CbFGUxevnbsqp1nrp72Qd", + "date": "Fri, 22 May 2026 08:13:14 GMT", + "request-id": "req_011CbHGiiBgdQNkASsMRCwgj", "server": "cloudflare", "set-cookie": "[REDACTED]", "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "traceresponse": "00-71c45f5456568c06df63b6a8d15fcff6-36384d0f5ffaa0a1-01", + "traceresponse": "00-6da7462cb717a4ab8a48b5d921204a81-14185ff13cd15781-01", "transfer-encoding": "chunked", "vary": "Accept-Encoding", - "x-envoy-upstream-service-time": "1304", + "x-envoy-upstream-service-time": "1122", "x-robots-tag": "none" }, "status": 200, @@ -319,7 +344,7 @@ "callIndex": 1, "id": "ff22a182ea5a9c06", "matchKey": "POST api.anthropic.com/v1/messages", - "recordedAt": "2026-05-21T06:49:03.945Z", + "recordedAt": "2026-05-22T08:13:19.986Z", "request": { "body": { "kind": "json", @@ -338,16 +363,16 @@ { "content": [ { - "signature": "ErUFCm4IDRgCKkAHu6lMZFTp53LRtoPoqjh0UrHuoIv5LTsJ7I3lHUVfs2ATNSQg9u7H+Ep/U2V3+dm55Z9I4XCuyKRcFlBIT0W2MhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMD1Qwe6/eMf8eVU1xGgwRhWxvkBZIEe9uad4iMGqUVZm3nslEGlnXnWFtC1Lo7eVfCTKPyaVMydEWLFdEkVYBr4jZ8G6xirmMvluO/Sr0A7PXSEQ+n3qF+VkUcwgO7gbSD97SYUIXKVh6QvFX9zzPIU40Ahbqq5bqU0TKXv4hbAoU8sDV4Af0KXw/9r8FocY9Ys2xX6YrVAi8v61I23dP82Zxy2VbaLrL4i744blW+VmU77L7xpH7y3RzQfldUrYzh0Buu45sh3yG/v3woK9FY1wm1v3dvDmQpV+HOU5hl0zyk8Mr/SpDm2uTAqjoT8DsOdKVerDvP9SrSbpG8sNiqT9ROv6ziY1Yq89hRR7F159Ntc1w8thi3evN7QYO2GD5LkR1GeGY5gOA4134B6/EktGcmzb1Rx0LY6BRb3T2QipZTDq+G7xwsnJNDiPz4/hchrWNzlXvc/6auvuOb9WkMGgtnox5/4/C8ZI/hCIGyvpb+mZcbewPbBXD91/neSrVP1dJC6F0t645nUK49AK8AE41lOJA6rB3sxfCItl2SiScJuRSBEE9NiseNJvpaZDxjuXQc4UWT6Uszo+LrngRTsJDWTUnF5239i15Sb7WQW0Xs0EgNA1Y6n7/6ma0EH+U9DmPD1c01o19iL9AI2ADGUeIQLSNA9OmUsLpquqFFmvWMLJ6ubYCbgHyogMfdRD6hpoN25OCQl2EP24yB0BY27rVuygYXbIOJ+vSpat0uCd8akup/g26YxcXouSYf98LTuE6GAE=", - "thinking": "The user wants me to complete a specific instrumented research flow with three steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id to call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url to call summarize_source\n4. Reply with exactly \"PROMPT_DONE\" after summarize_source returns\n\nThe user emphasizes calling exactly one tool per turn and waiting for each result. Let me start with step 1.", + "signature": "EtYFCm4IDRgCKkC/lJUT/EhYE72Jr10vREWOZ4vwSSugL9RsNrhJg9wjli7iCBt2/hEandW2KZpRqluVbV3ehHY/n0Mge6VmWF1cMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMHcfwfYOEmmJZGyBBGgyYm8sT/W36vQdF0dQiMFC5CVRWmqhR2r90pB0R8Wjbq0ITTIN0abxhOezE1NDsrj6CM4/DXLaOsJp4TD5DNCqVBEgEEzFdeaRrRB0CeXdlWoo+wf7yR9EMOVhLmyRf3nItrqN/cb30rpaexhXDm0/Hj3WxQH+o0K73Oyr6qtiDVe9xGNt6v5DrUz31HcE+GJ0Yw8ThoufXvqNyFQV3lLhpZExUDX6hwlmKvaRpj5YH+q5TTx3jAIgzD+zGkgUS0vC7Muftm2VZcuI/2wVsbtWo6hYdvbbdxr+8FzJsCOWc3ptVaUBimC5//HRSNBXFJ9zlkt6l7YxnUeKWiesSdE6h1EJ08Rp4OrAP+oaYWU4v6IODdnJmsqGKbN//i6gGCnAHBBAZr/pnnmEyUOsBGc6ARMOtcwjFIN3/B1YkJi8r8QbbtGHJHfH/v102MSZG8UJk2RXxt1fTQUWNbp0DjA7gUn00H3dnmSAQyqFjKLIFncnhiH5PSSgdvErNB7y/2UBk2CY2i4dpevr+7uvHZDLPjSBcovpvgJ4ihdUM9S080xCm1NNkjs+QP+AQAh20t33t7EN6aZS0+CZcfJxf1QV6mGIkL7BKAPeIXjD8TKuW/at4pqwrvvesI2cZY5RDjC7v7tz/+tqiEkob1s8J3jx2dbIgPBFOR5PFFwPby0H9Guv4ZB63YAlP3sXX+F5fC6fQifQeJK8fuWK+FKe3v+gK/hZcuBuU/Jfhrst4CsEWeaBhmPktZOHu5f85KZ/layh4Pp39yxR0FiHY5eXibsTh2SfDN3K6GAE=", + "thinking": "The user wants me to complete a specific instrumented research flow with these steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url and call summarize_source\n4. After summarize_source returns, reply with exactly \"PROMPT_DONE\" and no other text\n\nThe user emphasizes calling exactly one tool per turn and waiting for each result. Let me start with step 1.", "type": "thinking" }, { - "text": "I'll complete this instrumented research flow step by step. Starting with Step 1:", + "text": "I'll complete this instrumented research flow step by step. Starting with step 1:", "type": "text" }, { - "id": "toolu_01NWGcbaEYFCSv7jbHaV61xR", + "id": "toolu_01QHXkUBddKx6pexY4WSjMR1", "input": { "query": "flue instrumentation" }, @@ -365,7 +390,7 @@ }, "content": "{\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}", "is_error": false, - "tool_use_id": "toolu_01NWGcbaEYFCSv7jbHaV61xR", + "tool_use_id": "toolu_01QHXkUBddKx6pexY4WSjMR1", "type": "tool_result" } ], @@ -379,7 +404,7 @@ "cache_control": { "type": "ephemeral" }, - "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Thu, May 21, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-LqmoTW/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-HpI3r1/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", "type": "text" } ], @@ -407,7 +432,9 @@ "type": "string" } }, - "required": ["path"], + "required": [ + "path" + ], "type": "object" }, "name": "read" @@ -426,7 +453,10 @@ "type": "string" } }, - "required": ["path", "content"], + "required": [ + "path", + "content" + ], "type": "object" }, "name": "write" @@ -453,7 +483,11 @@ "type": "boolean" } }, - "required": ["path", "oldText", "newText"], + "required": [ + "path", + "oldText", + "newText" + ], "type": "object" }, "name": "edit" @@ -472,7 +506,9 @@ "type": "number" } }, - "required": ["command"], + "required": [ + "command" + ], "type": "object" }, "name": "bash" @@ -495,7 +531,9 @@ "type": "string" } }, - "required": ["pattern"], + "required": [ + "pattern" + ], "type": "object" }, "name": "grep" @@ -514,7 +552,9 @@ "type": "string" } }, - "required": ["pattern"], + "required": [ + "pattern" + ], "type": "object" }, "name": "glob" @@ -541,7 +581,9 @@ "type": "string" } }, - "required": ["prompt"], + "required": [ + "prompt" + ], "type": "object" }, "name": "task" @@ -555,7 +597,9 @@ "type": "string" } }, - "required": ["query"], + "required": [ + "query" + ], "type": "object" }, "name": "lookup" @@ -572,7 +616,10 @@ "type": "string" } }, - "required": ["lookupId", "query"], + "required": [ + "lookupId", + "query" + ], "type": "object" }, "name": "web_search" @@ -589,7 +636,9 @@ "type": "string" } }, - "required": ["url"], + "required": [ + "url" + ], "type": "object" }, "name": "summarize_source" @@ -604,26 +653,26 @@ "response": { "body": { "chunks": [ - "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-5-20250929\",\"id\":\"msg_01VJkPtnXDH2vYcShtiH4bA4\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":13,\"cache_creation_input_tokens\":239,\"cache_read_input_tokens\":2182,\"cache_creation\":{\"ephemeral_5m_input_tokens\":239,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":1,\"service_tier\":\"standard\",\"inference_geo\":\"not_available\"}}}", + "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-5-20250929\",\"id\":\"msg_01S7r43QJxMWSvMAaBeLZgV4\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":13,\"cache_creation_input_tokens\":248,\"cache_read_input_tokens\":2184,\"cache_creation\":{\"ephemeral_5m_input_tokens\":248,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":1,\"service_tier\":\"standard\",\"inference_geo\":\"not_available\"}}}", "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"thinking\",\"thinking\":\"\",\"signature\":\"\"}}", "event: ping\ndata: {\"type\":\"ping\"}", "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\"Good\"}}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\", I got the lookup result with id \\\"flue-session-2026\\\". Now I'll proceed to step 2 and\"}}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\" use this id as the lookupId parameter in the web_search call with the specified\"}}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\" query.\"}}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"signature_delta\",\"signature\":\"EoEDCm4IDRgCKkDHERZTLDmLPqGPffwRXgcxBhBgIrYXgMYvN2Ub70fw9ROsylVddlwVjiBc/lIRhKFlmKk3yGyVqaTpeWzivYSNMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMvygGdKoloZH9PbB/GgyNsBVPv5CiUkum+Q0iMO4QWY/lnhO5B8dFYJLBlnx3xICN/4EZrOIoQNdBLFV3U+M8som8sSiwj3uJx1OI8irAAbcyFYPvt3ZNfLNUReqOr+m7INr6/Ie2gnkRu9unXD+vYwFg9FbyV0lgmLyu4I3e6A+P3r6rACTCCVKokSYjy2IWp8e6v5c1+++qdywmPbK444LgqFCxOF2CF7gtf8iHoMo/rRhm/v4ypQOUdWW/lvo8sokRYHdJsSTOFLHmsuSk4eapbjPa9IjmFXOf+fNTqVY1quk3HJuLBKr7Q9PblMUX7Q4hqwo/E89HS5M3WTcm2sHl7Vict+Qbr5+8JZVlNRgB\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\", I got the lookup result with id \\\"flue-session-2026\\\". Now I need to proceed to step 2: call\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\" web_search with this lookupId and the query \\\"Braintrust Flue reasoning stream instrumentation\\\".\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"signature_delta\",\"signature\":\"EpEDCm4IDRgCKkAMahve1kB1j4njp1ZSzO8eCK4bb5Ex7MB6tjdoOXfuUDRfkBqvIGdwVly8GiA8GGYC7Y/RVfREXF6A6OXHTwFyMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMI25UM/xFQ9Bh625NGgyP2lwn3SKJlMxLUwciMH3VyS+uXCYaj8hlEdHVLz3HDLA5DCge72pzSyECwbUqqdxyZgtWjWYo/v0qA6XIsirQAQUbwyS/JWdGjeoTVbN2wMlsvu6j2cZmYMhk2HDKvmRIKpFTX5Ha82HBMwuM+f/7faDeQM5ldk8a5Tnm6iWFUj5jOoNqCYa+lBzhWor1vuZ5ieA569nGcMa0z1QmEP8WC3zNkI+kDazdS9FcuJP8KltHVfNr/wf/5AgAYFMt8fIaolvtJmN7uZ0yJKVfuJ58yx0nlQyEkxK8siXz7in2ulTuflohdD37ZErfxQNM3iYlCEfBOfa6kuJhwOwQ+HWJA1LXmUxzR/9AHRq0f3euNXkYAQ==\"}}", "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0}", "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":1,\"content_block\":{\"type\":\"text\",\"text\":\"\"}}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"text_delta\",\"text\":\"Now proceeding to Step 2:\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"text_delta\",\"text\":\"Now proce\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"text_delta\",\"text\":\"eding to step 2:\"}}", "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":1}", - "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":2,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_0153ktjSHv2H1SaKu8xPjQDj\",\"name\":\"web_search\",\"input\":{},\"caller\":{\"type\":\"direct\"}}}", + "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":2,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01CvT1mSWwETua7LWwSQiyq6\",\"name\":\"web_search\",\"input\":{},\"caller\":{\"type\":\"direct\"}}}", "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"}}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"lookupId\\\": \\\"fl\"}}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"ue-session-2026\"}}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\", \\\"query\\\": \\\"Braintrust Flue reasoning stream instrumentation\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"lookupId\\\": \\\"flue-session-2026\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\", \\\"query\\\": \\\"Br\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"aintrust Flue reasoning stream instrumentation\"}}", "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"}\"}}", "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":2}", - "event: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":13,\"cache_creation_input_tokens\":239,\"cache_read_input_tokens\":2182,\"output_tokens\":153}}", + "event: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":13,\"cache_creation_input_tokens\":248,\"cache_read_input_tokens\":2184,\"output_tokens\":158}}", "event: message_stop\ndata: {\"type\":\"message_stop\"}" ], "kind": "sse" @@ -632,32 +681,32 @@ "anthropic-organization-id": "27796668-7351-40ac-acc4-024aee8995a5", "anthropic-ratelimit-input-tokens-limit": "3000000", "anthropic-ratelimit-input-tokens-remaining": "2999000", - "anthropic-ratelimit-input-tokens-reset": "2026-05-21T06:48:59Z", + "anthropic-ratelimit-input-tokens-reset": "2026-05-22T08:13:17Z", "anthropic-ratelimit-output-tokens-limit": "600000", "anthropic-ratelimit-output-tokens-remaining": "600000", - "anthropic-ratelimit-output-tokens-reset": "2026-05-21T06:48:59Z", + "anthropic-ratelimit-output-tokens-reset": "2026-05-22T08:13:17Z", "anthropic-ratelimit-requests-limit": "20000", "anthropic-ratelimit-requests-remaining": "19999", - "anthropic-ratelimit-requests-reset": "2026-05-21T06:48:59Z", + "anthropic-ratelimit-requests-reset": "2026-05-22T08:13:17Z", "anthropic-ratelimit-tokens-limit": "3600000", "anthropic-ratelimit-tokens-remaining": "3599000", - "anthropic-ratelimit-tokens-reset": "2026-05-21T06:48:59Z", + "anthropic-ratelimit-tokens-reset": "2026-05-22T08:13:17Z", "cache-control": "no-cache", "cf-cache-status": "DYNAMIC", - "cf-ray": "9ff1a37acb62c2f2-VIE", + "cf-ray": "9ffa5c54d9545db9-VIE", "connection": "keep-alive", "content-encoding": "gzip", "content-security-policy": "default-src 'none'; frame-ancestors 'none'", "content-type": "text/event-stream; charset=utf-8", - "date": "Thu, 21 May 2026 06:49:02 GMT", - "request-id": "req_011CbFGVFFKnFuKGwHxKghcD", + "date": "Fri, 22 May 2026 08:13:18 GMT", + "request-id": "req_011CbHGiyn3iTHWVPAkpZhcY", "server": "cloudflare", "set-cookie": "[REDACTED]", "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "traceresponse": "00-f46a9b0cbf31085d3cea916f4cb849e0-9567490ed2d35f0c-01", + "traceresponse": "00-4cdb6d6d0536e1b2d282935aec231b2f-a96d2334e551f8ea-01", "transfer-encoding": "chunked", "vary": "Accept-Encoding", - "x-envoy-upstream-service-time": "2617", + "x-envoy-upstream-service-time": "1178", "x-robots-tag": "none" }, "status": 200, @@ -668,7 +717,7 @@ "callIndex": 2, "id": "f1d50a1e6c760d6c", "matchKey": "POST api.anthropic.com/v1/messages", - "recordedAt": "2026-05-21T06:49:07.390Z", + "recordedAt": "2026-05-22T08:13:23.056Z", "request": { "body": { "kind": "json", @@ -687,16 +736,16 @@ { "content": [ { - "signature": "ErUFCm4IDRgCKkAHu6lMZFTp53LRtoPoqjh0UrHuoIv5LTsJ7I3lHUVfs2ATNSQg9u7H+Ep/U2V3+dm55Z9I4XCuyKRcFlBIT0W2MhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMD1Qwe6/eMf8eVU1xGgwRhWxvkBZIEe9uad4iMGqUVZm3nslEGlnXnWFtC1Lo7eVfCTKPyaVMydEWLFdEkVYBr4jZ8G6xirmMvluO/Sr0A7PXSEQ+n3qF+VkUcwgO7gbSD97SYUIXKVh6QvFX9zzPIU40Ahbqq5bqU0TKXv4hbAoU8sDV4Af0KXw/9r8FocY9Ys2xX6YrVAi8v61I23dP82Zxy2VbaLrL4i744blW+VmU77L7xpH7y3RzQfldUrYzh0Buu45sh3yG/v3woK9FY1wm1v3dvDmQpV+HOU5hl0zyk8Mr/SpDm2uTAqjoT8DsOdKVerDvP9SrSbpG8sNiqT9ROv6ziY1Yq89hRR7F159Ntc1w8thi3evN7QYO2GD5LkR1GeGY5gOA4134B6/EktGcmzb1Rx0LY6BRb3T2QipZTDq+G7xwsnJNDiPz4/hchrWNzlXvc/6auvuOb9WkMGgtnox5/4/C8ZI/hCIGyvpb+mZcbewPbBXD91/neSrVP1dJC6F0t645nUK49AK8AE41lOJA6rB3sxfCItl2SiScJuRSBEE9NiseNJvpaZDxjuXQc4UWT6Uszo+LrngRTsJDWTUnF5239i15Sb7WQW0Xs0EgNA1Y6n7/6ma0EH+U9DmPD1c01o19iL9AI2ADGUeIQLSNA9OmUsLpquqFFmvWMLJ6ubYCbgHyogMfdRD6hpoN25OCQl2EP24yB0BY27rVuygYXbIOJ+vSpat0uCd8akup/g26YxcXouSYf98LTuE6GAE=", - "thinking": "The user wants me to complete a specific instrumented research flow with three steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id to call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url to call summarize_source\n4. Reply with exactly \"PROMPT_DONE\" after summarize_source returns\n\nThe user emphasizes calling exactly one tool per turn and waiting for each result. Let me start with step 1.", + "signature": "EtYFCm4IDRgCKkC/lJUT/EhYE72Jr10vREWOZ4vwSSugL9RsNrhJg9wjli7iCBt2/hEandW2KZpRqluVbV3ehHY/n0Mge6VmWF1cMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMHcfwfYOEmmJZGyBBGgyYm8sT/W36vQdF0dQiMFC5CVRWmqhR2r90pB0R8Wjbq0ITTIN0abxhOezE1NDsrj6CM4/DXLaOsJp4TD5DNCqVBEgEEzFdeaRrRB0CeXdlWoo+wf7yR9EMOVhLmyRf3nItrqN/cb30rpaexhXDm0/Hj3WxQH+o0K73Oyr6qtiDVe9xGNt6v5DrUz31HcE+GJ0Yw8ThoufXvqNyFQV3lLhpZExUDX6hwlmKvaRpj5YH+q5TTx3jAIgzD+zGkgUS0vC7Muftm2VZcuI/2wVsbtWo6hYdvbbdxr+8FzJsCOWc3ptVaUBimC5//HRSNBXFJ9zlkt6l7YxnUeKWiesSdE6h1EJ08Rp4OrAP+oaYWU4v6IODdnJmsqGKbN//i6gGCnAHBBAZr/pnnmEyUOsBGc6ARMOtcwjFIN3/B1YkJi8r8QbbtGHJHfH/v102MSZG8UJk2RXxt1fTQUWNbp0DjA7gUn00H3dnmSAQyqFjKLIFncnhiH5PSSgdvErNB7y/2UBk2CY2i4dpevr+7uvHZDLPjSBcovpvgJ4ihdUM9S080xCm1NNkjs+QP+AQAh20t33t7EN6aZS0+CZcfJxf1QV6mGIkL7BKAPeIXjD8TKuW/at4pqwrvvesI2cZY5RDjC7v7tz/+tqiEkob1s8J3jx2dbIgPBFOR5PFFwPby0H9Guv4ZB63YAlP3sXX+F5fC6fQifQeJK8fuWK+FKe3v+gK/hZcuBuU/Jfhrst4CsEWeaBhmPktZOHu5f85KZ/layh4Pp39yxR0FiHY5eXibsTh2SfDN3K6GAE=", + "thinking": "The user wants me to complete a specific instrumented research flow with these steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url and call summarize_source\n4. After summarize_source returns, reply with exactly \"PROMPT_DONE\" and no other text\n\nThe user emphasizes calling exactly one tool per turn and waiting for each result. Let me start with step 1.", "type": "thinking" }, { - "text": "I'll complete this instrumented research flow step by step. Starting with Step 1:", + "text": "I'll complete this instrumented research flow step by step. Starting with step 1:", "type": "text" }, { - "id": "toolu_01NWGcbaEYFCSv7jbHaV61xR", + "id": "toolu_01QHXkUBddKx6pexY4WSjMR1", "input": { "query": "flue instrumentation" }, @@ -711,7 +760,7 @@ { "content": "{\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}", "is_error": false, - "tool_use_id": "toolu_01NWGcbaEYFCSv7jbHaV61xR", + "tool_use_id": "toolu_01QHXkUBddKx6pexY4WSjMR1", "type": "tool_result" } ], @@ -720,16 +769,16 @@ { "content": [ { - "signature": "EoEDCm4IDRgCKkDHERZTLDmLPqGPffwRXgcxBhBgIrYXgMYvN2Ub70fw9ROsylVddlwVjiBc/lIRhKFlmKk3yGyVqaTpeWzivYSNMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMvygGdKoloZH9PbB/GgyNsBVPv5CiUkum+Q0iMO4QWY/lnhO5B8dFYJLBlnx3xICN/4EZrOIoQNdBLFV3U+M8som8sSiwj3uJx1OI8irAAbcyFYPvt3ZNfLNUReqOr+m7INr6/Ie2gnkRu9unXD+vYwFg9FbyV0lgmLyu4I3e6A+P3r6rACTCCVKokSYjy2IWp8e6v5c1+++qdywmPbK444LgqFCxOF2CF7gtf8iHoMo/rRhm/v4ypQOUdWW/lvo8sokRYHdJsSTOFLHmsuSk4eapbjPa9IjmFXOf+fNTqVY1quk3HJuLBKr7Q9PblMUX7Q4hqwo/E89HS5M3WTcm2sHl7Vict+Qbr5+8JZVlNRgB", - "thinking": "Good, I got the lookup result with id \"flue-session-2026\". Now I'll proceed to step 2 and use this id as the lookupId parameter in the web_search call with the specified query.", + "signature": "EpEDCm4IDRgCKkAMahve1kB1j4njp1ZSzO8eCK4bb5Ex7MB6tjdoOXfuUDRfkBqvIGdwVly8GiA8GGYC7Y/RVfREXF6A6OXHTwFyMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMI25UM/xFQ9Bh625NGgyP2lwn3SKJlMxLUwciMH3VyS+uXCYaj8hlEdHVLz3HDLA5DCge72pzSyECwbUqqdxyZgtWjWYo/v0qA6XIsirQAQUbwyS/JWdGjeoTVbN2wMlsvu6j2cZmYMhk2HDKvmRIKpFTX5Ha82HBMwuM+f/7faDeQM5ldk8a5Tnm6iWFUj5jOoNqCYa+lBzhWor1vuZ5ieA569nGcMa0z1QmEP8WC3zNkI+kDazdS9FcuJP8KltHVfNr/wf/5AgAYFMt8fIaolvtJmN7uZ0yJKVfuJ58yx0nlQyEkxK8siXz7in2ulTuflohdD37ZErfxQNM3iYlCEfBOfa6kuJhwOwQ+HWJA1LXmUxzR/9AHRq0f3euNXkYAQ==", + "thinking": "Good, I got the lookup result with id \"flue-session-2026\". Now I need to proceed to step 2: call web_search with this lookupId and the query \"Braintrust Flue reasoning stream instrumentation\".", "type": "thinking" }, { - "text": "Now proceeding to Step 2:", + "text": "Now proceeding to step 2:", "type": "text" }, { - "id": "toolu_0153ktjSHv2H1SaKu8xPjQDj", + "id": "toolu_01CvT1mSWwETua7LWwSQiyq6", "input": { "lookupId": "flue-session-2026", "query": "Braintrust Flue reasoning stream instrumentation" @@ -748,7 +797,7 @@ }, "content": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\",\"results\":[{\"title\":\"Flue reasoning stream instrumentation\",\"url\":\"https://example.test/flue/reasoning-streams\"}]}", "is_error": false, - "tool_use_id": "toolu_0153ktjSHv2H1SaKu8xPjQDj", + "tool_use_id": "toolu_01CvT1mSWwETua7LWwSQiyq6", "type": "tool_result" } ], @@ -762,7 +811,7 @@ "cache_control": { "type": "ephemeral" }, - "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Thu, May 21, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-LqmoTW/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-HpI3r1/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", "type": "text" } ], @@ -790,7 +839,9 @@ "type": "string" } }, - "required": ["path"], + "required": [ + "path" + ], "type": "object" }, "name": "read" @@ -809,7 +860,10 @@ "type": "string" } }, - "required": ["path", "content"], + "required": [ + "path", + "content" + ], "type": "object" }, "name": "write" @@ -836,7 +890,11 @@ "type": "boolean" } }, - "required": ["path", "oldText", "newText"], + "required": [ + "path", + "oldText", + "newText" + ], "type": "object" }, "name": "edit" @@ -855,7 +913,9 @@ "type": "number" } }, - "required": ["command"], + "required": [ + "command" + ], "type": "object" }, "name": "bash" @@ -878,7 +938,9 @@ "type": "string" } }, - "required": ["pattern"], + "required": [ + "pattern" + ], "type": "object" }, "name": "grep" @@ -897,7 +959,9 @@ "type": "string" } }, - "required": ["pattern"], + "required": [ + "pattern" + ], "type": "object" }, "name": "glob" @@ -924,7 +988,9 @@ "type": "string" } }, - "required": ["prompt"], + "required": [ + "prompt" + ], "type": "object" }, "name": "task" @@ -938,7 +1004,9 @@ "type": "string" } }, - "required": ["query"], + "required": [ + "query" + ], "type": "object" }, "name": "lookup" @@ -955,7 +1023,10 @@ "type": "string" } }, - "required": ["lookupId", "query"], + "required": [ + "lookupId", + "query" + ], "type": "object" }, "name": "web_search" @@ -972,7 +1043,9 @@ "type": "string" } }, - "required": ["url"], + "required": [ + "url" + ], "type": "object" }, "name": "summarize_source" @@ -987,24 +1060,24 @@ "response": { "body": { "chunks": [ - "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-5-20250929\",\"id\":\"msg_01DSg9ZeMjZLnXapLdFgSFc3\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":13,\"cache_creation_input_tokens\":229,\"cache_read_input_tokens\":2421,\"cache_creation\":{\"ephemeral_5m_input_tokens\":229,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":1,\"service_tier\":\"standard\",\"inference_geo\":\"not_available\"}}}", + "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-5-20250929\",\"id\":\"msg_01GTvJuwvfvP5uhxvUX85xDb\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":13,\"cache_creation_input_tokens\":234,\"cache_read_input_tokens\":2432,\"cache_creation\":{\"ephemeral_5m_input_tokens\":234,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":1,\"service_tier\":\"standard\",\"inference_geo\":\"not_available\"}}}", "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"thinking\",\"thinking\":\"\",\"signature\":\"\"}}", "event: ping\ndata: {\"type\":\"ping\"}", "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\"Perfect\"}}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\"! I got the web_search results. There's one result with the URL\"}}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\" \\\"https://example.test/flue/reasoning-streams\\\". Now I need to proceed to step 3 and call summarize_source with this URL.\"}}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"signature_delta\",\"signature\":\"Eo8DCm4IDRgCKkCwCXv4kPtKJjZgEBptfdwHoQRED540G2dBIGSNpbLq/d/7YUemt0VtsBkdWJx9I38IxfHuMed6CS8/KHNVf63wMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMZREYYDCUibC7js33GgzoCMUuvYX25rvN1wAiMN8TPVM+m1UBPOv7LwNn0Fl5crfh6XeYMelsdRSq090k5nPOUQCRGwMhwfhIg7rDCCrOAepv53M8zcXCM+2pzYKPgxRDkY3DwMUWnjS2z7jXN4AMavQWyGi0dIFDARVsbcKLAFyXPVwfy/EMSHMuCHYcX5kA/oz3+gWu5ka5cOjvp60k2ZUURJptjU7UIG5TYtW96oTo2wYrZOyiYAZKIRoRMn48RgU8b8oxjQJH6RU6aKXgicvp0DV9dmrcONvLGlftpp2UNBTvHqrhhXFtDtv46/I3QUE7aMT7VTlF6p+bO9gPSZAkrm53y2koG4E5hzWEhiRuFckYs24dThVN1cMnGAE=\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\"! I got the web_search results. There's one result with the\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\" URL \\\"https://example.test/flue/reasoning-streams\\\". Now I need to proceed to step 3: call summarize_source with this URL.\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"signature_delta\",\"signature\":\"EowDCm4IDRgCKkCpqmoUHjbaZYvB4bWm+hVDlxgU/iOCEn0v3xAMT4QsjKM7cIZMOWD2eEF8ENjGq0ttAvO8ZNI9YpiASikG2gnNMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMI5+VQnffadMSNsXEGgy1YAi10m6jJ39wq2UiMAUy8rg67GdkT4VUKix3ULTWnPfKucap7VLRPGDqK7ZhF0nDl2pcYGshMviSbzOjuyrLAXh3IPAAc3rvDuYAAHaWed6JE7/4gg/gzWhfVeAb0qXzXoiIHh8Z9KyHDfDDfpesr4TzmJHT/T8mhem3UfZc87ZLzFom8Vi+76Y2eVWcoI/EyPuyj+KVxU5kPh030LYWxUeSTUViRu9NAd+Wzz/5ZAgD+TiEmCnpNMI3eGqOiBPtwK7y/JIvxZRWvsJ1ghXNaEVShN3h8OUk9zmzIhBuUujWVZtc5wuM28726mOqMLwKckegl+q2vNrR+U+AqbMSYWUVlWLKZvd1LXiZGAE=\"}}", "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0}", "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":1,\"content_block\":{\"type\":\"text\",\"text\":\"\"}}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"text_delta\",\"text\":\"Now proceeding\"}}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"text_delta\",\"text\":\" to Step 3:\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"text_delta\",\"text\":\"Now proce\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"text_delta\",\"text\":\"eding to step 3:\"}}", "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":1}", - "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":2,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01JDUQddZCp23NQj8eGJLFbo\",\"name\":\"summarize_source\",\"input\":{},\"caller\":{\"type\":\"direct\"}}}", + "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":2,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01NHkkJuQNXyRuWk58FCecye\",\"name\":\"summarize_source\",\"input\":{},\"caller\":{\"type\":\"direct\"}}}", "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"}}", "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"url\\\": \\\"https://example.test/flue/reasoning-streams\"}}", "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"}\"}}", "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":2}", - "event: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":13,\"cache_creation_input_tokens\":229,\"cache_read_input_tokens\":2421,\"output_tokens\":133}}", + "event: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":13,\"cache_creation_input_tokens\":234,\"cache_read_input_tokens\":2432,\"output_tokens\":132}}", "event: message_stop\ndata: {\"type\":\"message_stop\"}" ], "kind": "sse" @@ -1013,32 +1086,32 @@ "anthropic-organization-id": "27796668-7351-40ac-acc4-024aee8995a5", "anthropic-ratelimit-input-tokens-limit": "3000000", "anthropic-ratelimit-input-tokens-remaining": "2999000", - "anthropic-ratelimit-input-tokens-reset": "2026-05-21T06:49:04Z", + "anthropic-ratelimit-input-tokens-reset": "2026-05-22T08:13:20Z", "anthropic-ratelimit-output-tokens-limit": "600000", "anthropic-ratelimit-output-tokens-remaining": "600000", - "anthropic-ratelimit-output-tokens-reset": "2026-05-21T06:49:04Z", + "anthropic-ratelimit-output-tokens-reset": "2026-05-22T08:13:20Z", "anthropic-ratelimit-requests-limit": "20000", "anthropic-ratelimit-requests-remaining": "19999", - "anthropic-ratelimit-requests-reset": "2026-05-21T06:49:04Z", + "anthropic-ratelimit-requests-reset": "2026-05-22T08:13:20Z", "anthropic-ratelimit-tokens-limit": "3600000", "anthropic-ratelimit-tokens-remaining": "3599000", - "anthropic-ratelimit-tokens-reset": "2026-05-21T06:49:04Z", + "anthropic-ratelimit-tokens-reset": "2026-05-22T08:13:20Z", "cache-control": "no-cache", "cf-cache-status": "DYNAMIC", - "cf-ray": "9ff1a3982ce9c2f2-VIE", + "cf-ray": "9ffa5c684d5d5db9-VIE", "connection": "keep-alive", "content-encoding": "gzip", "content-security-policy": "default-src 'none'; frame-ancestors 'none'", "content-type": "text/event-stream; charset=utf-8", - "date": "Thu, 21 May 2026 06:49:05 GMT", - "request-id": "req_011CbFGVbQGvo9PCcG5DH13G", + "date": "Fri, 22 May 2026 08:13:21 GMT", + "request-id": "req_011CbHGjD7jNriq9KH2cWiZX", "server": "cloudflare", "set-cookie": "[REDACTED]", "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "traceresponse": "00-386ca9e81514f84a92a0a346caa1b1ed-da425a4f1e2abe78-01", + "traceresponse": "00-2bfd6efb042ad6f4d2349d2a08779605-538e2a8207df00c0-01", "transfer-encoding": "chunked", "vary": "Accept-Encoding", - "x-envoy-upstream-service-time": "1324", + "x-envoy-upstream-service-time": "1330", "x-robots-tag": "none" }, "status": 200, @@ -1049,7 +1122,7 @@ "callIndex": 3, "id": "305957222aa1f6e9", "matchKey": "POST api.anthropic.com/v1/messages", - "recordedAt": "2026-05-21T06:49:12.438Z", + "recordedAt": "2026-05-22T08:13:25.313Z", "request": { "body": { "kind": "json", @@ -1068,16 +1141,16 @@ { "content": [ { - "signature": "ErUFCm4IDRgCKkAHu6lMZFTp53LRtoPoqjh0UrHuoIv5LTsJ7I3lHUVfs2ATNSQg9u7H+Ep/U2V3+dm55Z9I4XCuyKRcFlBIT0W2MhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMD1Qwe6/eMf8eVU1xGgwRhWxvkBZIEe9uad4iMGqUVZm3nslEGlnXnWFtC1Lo7eVfCTKPyaVMydEWLFdEkVYBr4jZ8G6xirmMvluO/Sr0A7PXSEQ+n3qF+VkUcwgO7gbSD97SYUIXKVh6QvFX9zzPIU40Ahbqq5bqU0TKXv4hbAoU8sDV4Af0KXw/9r8FocY9Ys2xX6YrVAi8v61I23dP82Zxy2VbaLrL4i744blW+VmU77L7xpH7y3RzQfldUrYzh0Buu45sh3yG/v3woK9FY1wm1v3dvDmQpV+HOU5hl0zyk8Mr/SpDm2uTAqjoT8DsOdKVerDvP9SrSbpG8sNiqT9ROv6ziY1Yq89hRR7F159Ntc1w8thi3evN7QYO2GD5LkR1GeGY5gOA4134B6/EktGcmzb1Rx0LY6BRb3T2QipZTDq+G7xwsnJNDiPz4/hchrWNzlXvc/6auvuOb9WkMGgtnox5/4/C8ZI/hCIGyvpb+mZcbewPbBXD91/neSrVP1dJC6F0t645nUK49AK8AE41lOJA6rB3sxfCItl2SiScJuRSBEE9NiseNJvpaZDxjuXQc4UWT6Uszo+LrngRTsJDWTUnF5239i15Sb7WQW0Xs0EgNA1Y6n7/6ma0EH+U9DmPD1c01o19iL9AI2ADGUeIQLSNA9OmUsLpquqFFmvWMLJ6ubYCbgHyogMfdRD6hpoN25OCQl2EP24yB0BY27rVuygYXbIOJ+vSpat0uCd8akup/g26YxcXouSYf98LTuE6GAE=", - "thinking": "The user wants me to complete a specific instrumented research flow with three steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id to call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url to call summarize_source\n4. Reply with exactly \"PROMPT_DONE\" after summarize_source returns\n\nThe user emphasizes calling exactly one tool per turn and waiting for each result. Let me start with step 1.", + "signature": "EtYFCm4IDRgCKkC/lJUT/EhYE72Jr10vREWOZ4vwSSugL9RsNrhJg9wjli7iCBt2/hEandW2KZpRqluVbV3ehHY/n0Mge6VmWF1cMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMHcfwfYOEmmJZGyBBGgyYm8sT/W36vQdF0dQiMFC5CVRWmqhR2r90pB0R8Wjbq0ITTIN0abxhOezE1NDsrj6CM4/DXLaOsJp4TD5DNCqVBEgEEzFdeaRrRB0CeXdlWoo+wf7yR9EMOVhLmyRf3nItrqN/cb30rpaexhXDm0/Hj3WxQH+o0K73Oyr6qtiDVe9xGNt6v5DrUz31HcE+GJ0Yw8ThoufXvqNyFQV3lLhpZExUDX6hwlmKvaRpj5YH+q5TTx3jAIgzD+zGkgUS0vC7Muftm2VZcuI/2wVsbtWo6hYdvbbdxr+8FzJsCOWc3ptVaUBimC5//HRSNBXFJ9zlkt6l7YxnUeKWiesSdE6h1EJ08Rp4OrAP+oaYWU4v6IODdnJmsqGKbN//i6gGCnAHBBAZr/pnnmEyUOsBGc6ARMOtcwjFIN3/B1YkJi8r8QbbtGHJHfH/v102MSZG8UJk2RXxt1fTQUWNbp0DjA7gUn00H3dnmSAQyqFjKLIFncnhiH5PSSgdvErNB7y/2UBk2CY2i4dpevr+7uvHZDLPjSBcovpvgJ4ihdUM9S080xCm1NNkjs+QP+AQAh20t33t7EN6aZS0+CZcfJxf1QV6mGIkL7BKAPeIXjD8TKuW/at4pqwrvvesI2cZY5RDjC7v7tz/+tqiEkob1s8J3jx2dbIgPBFOR5PFFwPby0H9Guv4ZB63YAlP3sXX+F5fC6fQifQeJK8fuWK+FKe3v+gK/hZcuBuU/Jfhrst4CsEWeaBhmPktZOHu5f85KZ/layh4Pp39yxR0FiHY5eXibsTh2SfDN3K6GAE=", + "thinking": "The user wants me to complete a specific instrumented research flow with these steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url and call summarize_source\n4. After summarize_source returns, reply with exactly \"PROMPT_DONE\" and no other text\n\nThe user emphasizes calling exactly one tool per turn and waiting for each result. Let me start with step 1.", "type": "thinking" }, { - "text": "I'll complete this instrumented research flow step by step. Starting with Step 1:", + "text": "I'll complete this instrumented research flow step by step. Starting with step 1:", "type": "text" }, { - "id": "toolu_01NWGcbaEYFCSv7jbHaV61xR", + "id": "toolu_01QHXkUBddKx6pexY4WSjMR1", "input": { "query": "flue instrumentation" }, @@ -1092,7 +1165,7 @@ { "content": "{\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}", "is_error": false, - "tool_use_id": "toolu_01NWGcbaEYFCSv7jbHaV61xR", + "tool_use_id": "toolu_01QHXkUBddKx6pexY4WSjMR1", "type": "tool_result" } ], @@ -1101,16 +1174,16 @@ { "content": [ { - "signature": "EoEDCm4IDRgCKkDHERZTLDmLPqGPffwRXgcxBhBgIrYXgMYvN2Ub70fw9ROsylVddlwVjiBc/lIRhKFlmKk3yGyVqaTpeWzivYSNMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMvygGdKoloZH9PbB/GgyNsBVPv5CiUkum+Q0iMO4QWY/lnhO5B8dFYJLBlnx3xICN/4EZrOIoQNdBLFV3U+M8som8sSiwj3uJx1OI8irAAbcyFYPvt3ZNfLNUReqOr+m7INr6/Ie2gnkRu9unXD+vYwFg9FbyV0lgmLyu4I3e6A+P3r6rACTCCVKokSYjy2IWp8e6v5c1+++qdywmPbK444LgqFCxOF2CF7gtf8iHoMo/rRhm/v4ypQOUdWW/lvo8sokRYHdJsSTOFLHmsuSk4eapbjPa9IjmFXOf+fNTqVY1quk3HJuLBKr7Q9PblMUX7Q4hqwo/E89HS5M3WTcm2sHl7Vict+Qbr5+8JZVlNRgB", - "thinking": "Good, I got the lookup result with id \"flue-session-2026\". Now I'll proceed to step 2 and use this id as the lookupId parameter in the web_search call with the specified query.", + "signature": "EpEDCm4IDRgCKkAMahve1kB1j4njp1ZSzO8eCK4bb5Ex7MB6tjdoOXfuUDRfkBqvIGdwVly8GiA8GGYC7Y/RVfREXF6A6OXHTwFyMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMI25UM/xFQ9Bh625NGgyP2lwn3SKJlMxLUwciMH3VyS+uXCYaj8hlEdHVLz3HDLA5DCge72pzSyECwbUqqdxyZgtWjWYo/v0qA6XIsirQAQUbwyS/JWdGjeoTVbN2wMlsvu6j2cZmYMhk2HDKvmRIKpFTX5Ha82HBMwuM+f/7faDeQM5ldk8a5Tnm6iWFUj5jOoNqCYa+lBzhWor1vuZ5ieA569nGcMa0z1QmEP8WC3zNkI+kDazdS9FcuJP8KltHVfNr/wf/5AgAYFMt8fIaolvtJmN7uZ0yJKVfuJ58yx0nlQyEkxK8siXz7in2ulTuflohdD37ZErfxQNM3iYlCEfBOfa6kuJhwOwQ+HWJA1LXmUxzR/9AHRq0f3euNXkYAQ==", + "thinking": "Good, I got the lookup result with id \"flue-session-2026\". Now I need to proceed to step 2: call web_search with this lookupId and the query \"Braintrust Flue reasoning stream instrumentation\".", "type": "thinking" }, { - "text": "Now proceeding to Step 2:", + "text": "Now proceeding to step 2:", "type": "text" }, { - "id": "toolu_0153ktjSHv2H1SaKu8xPjQDj", + "id": "toolu_01CvT1mSWwETua7LWwSQiyq6", "input": { "lookupId": "flue-session-2026", "query": "Braintrust Flue reasoning stream instrumentation" @@ -1126,7 +1199,7 @@ { "content": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\",\"results\":[{\"title\":\"Flue reasoning stream instrumentation\",\"url\":\"https://example.test/flue/reasoning-streams\"}]}", "is_error": false, - "tool_use_id": "toolu_0153ktjSHv2H1SaKu8xPjQDj", + "tool_use_id": "toolu_01CvT1mSWwETua7LWwSQiyq6", "type": "tool_result" } ], @@ -1135,16 +1208,16 @@ { "content": [ { - "signature": "Eo8DCm4IDRgCKkCwCXv4kPtKJjZgEBptfdwHoQRED540G2dBIGSNpbLq/d/7YUemt0VtsBkdWJx9I38IxfHuMed6CS8/KHNVf63wMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMZREYYDCUibC7js33GgzoCMUuvYX25rvN1wAiMN8TPVM+m1UBPOv7LwNn0Fl5crfh6XeYMelsdRSq090k5nPOUQCRGwMhwfhIg7rDCCrOAepv53M8zcXCM+2pzYKPgxRDkY3DwMUWnjS2z7jXN4AMavQWyGi0dIFDARVsbcKLAFyXPVwfy/EMSHMuCHYcX5kA/oz3+gWu5ka5cOjvp60k2ZUURJptjU7UIG5TYtW96oTo2wYrZOyiYAZKIRoRMn48RgU8b8oxjQJH6RU6aKXgicvp0DV9dmrcONvLGlftpp2UNBTvHqrhhXFtDtv46/I3QUE7aMT7VTlF6p+bO9gPSZAkrm53y2koG4E5hzWEhiRuFckYs24dThVN1cMnGAE=", - "thinking": "Perfect! I got the web_search results. There's one result with the URL \"https://example.test/flue/reasoning-streams\". Now I need to proceed to step 3 and call summarize_source with this URL.", + "signature": "EowDCm4IDRgCKkCpqmoUHjbaZYvB4bWm+hVDlxgU/iOCEn0v3xAMT4QsjKM7cIZMOWD2eEF8ENjGq0ttAvO8ZNI9YpiASikG2gnNMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMI5+VQnffadMSNsXEGgy1YAi10m6jJ39wq2UiMAUy8rg67GdkT4VUKix3ULTWnPfKucap7VLRPGDqK7ZhF0nDl2pcYGshMviSbzOjuyrLAXh3IPAAc3rvDuYAAHaWed6JE7/4gg/gzWhfVeAb0qXzXoiIHh8Z9KyHDfDDfpesr4TzmJHT/T8mhem3UfZc87ZLzFom8Vi+76Y2eVWcoI/EyPuyj+KVxU5kPh030LYWxUeSTUViRu9NAd+Wzz/5ZAgD+TiEmCnpNMI3eGqOiBPtwK7y/JIvxZRWvsJ1ghXNaEVShN3h8OUk9zmzIhBuUujWVZtc5wuM28726mOqMLwKckegl+q2vNrR+U+AqbMSYWUVlWLKZvd1LXiZGAE=", + "thinking": "Perfect! I got the web_search results. There's one result with the URL \"https://example.test/flue/reasoning-streams\". Now I need to proceed to step 3: call summarize_source with this URL.", "type": "thinking" }, { - "text": "Now proceeding to Step 3:", + "text": "Now proceeding to step 3:", "type": "text" }, { - "id": "toolu_01JDUQddZCp23NQj8eGJLFbo", + "id": "toolu_01NHkkJuQNXyRuWk58FCecye", "input": { "url": "https://example.test/flue/reasoning-streams" }, @@ -1162,7 +1235,7 @@ }, "content": "{\"summary\":\"Flue emits reasoning, tool execution, and LLM turn events separately.\",\"url\":\"https://example.test/flue/reasoning-streams\"}", "is_error": false, - "tool_use_id": "toolu_01JDUQddZCp23NQj8eGJLFbo", + "tool_use_id": "toolu_01NHkkJuQNXyRuWk58FCecye", "type": "tool_result" } ], @@ -1176,7 +1249,7 @@ "cache_control": { "type": "ephemeral" }, - "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Thu, May 21, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-LqmoTW/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-HpI3r1/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", "type": "text" } ], @@ -1204,7 +1277,9 @@ "type": "string" } }, - "required": ["path"], + "required": [ + "path" + ], "type": "object" }, "name": "read" @@ -1223,7 +1298,10 @@ "type": "string" } }, - "required": ["path", "content"], + "required": [ + "path", + "content" + ], "type": "object" }, "name": "write" @@ -1250,7 +1328,11 @@ "type": "boolean" } }, - "required": ["path", "oldText", "newText"], + "required": [ + "path", + "oldText", + "newText" + ], "type": "object" }, "name": "edit" @@ -1269,7 +1351,9 @@ "type": "number" } }, - "required": ["command"], + "required": [ + "command" + ], "type": "object" }, "name": "bash" @@ -1292,7 +1376,9 @@ "type": "string" } }, - "required": ["pattern"], + "required": [ + "pattern" + ], "type": "object" }, "name": "grep" @@ -1311,7 +1397,9 @@ "type": "string" } }, - "required": ["pattern"], + "required": [ + "pattern" + ], "type": "object" }, "name": "glob" @@ -1338,7 +1426,9 @@ "type": "string" } }, - "required": ["prompt"], + "required": [ + "prompt" + ], "type": "object" }, "name": "task" @@ -1352,7 +1442,9 @@ "type": "string" } }, - "required": ["query"], + "required": [ + "query" + ], "type": "object" }, "name": "lookup" @@ -1369,7 +1461,10 @@ "type": "string" } }, - "required": ["lookupId", "query"], + "required": [ + "lookupId", + "query" + ], "type": "object" }, "name": "web_search" @@ -1386,7 +1481,9 @@ "type": "string" } }, - "required": ["url"], + "required": [ + "url" + ], "type": "object" }, "name": "summarize_source" @@ -1401,17 +1498,18 @@ "response": { "body": { "chunks": [ - "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-5-20250929\",\"id\":\"msg_01EN81qE9Tc5YtCkCYHNw4rf\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":13,\"cache_creation_input_tokens\":189,\"cache_read_input_tokens\":2650,\"cache_creation\":{\"ephemeral_5m_input_tokens\":189,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":1,\"service_tier\":\"standard\",\"inference_geo\":\"not_available\"}}}", + "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-5-20250929\",\"id\":\"msg_01DePVY82UbrSeVG6FmJbDAw\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":13,\"cache_creation_input_tokens\":188,\"cache_read_input_tokens\":2666,\"cache_creation\":{\"ephemeral_5m_input_tokens\":188,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":1,\"service_tier\":\"standard\",\"inference_geo\":\"not_available\"}}}", "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"thinking\",\"thinking\":\"\",\"signature\":\"\"}}", "event: ping\ndata: {\"type\":\"ping\"}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\"Perfect\"}}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\"! The summarize_source has returned. According to the instructions, I should now reply with exactly \\\"PROMPT_DONE\\\" and no other text.\"}}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"signature_delta\",\"signature\":\"EtwCCm4IDRgCKkDWm62nouoyuXYPpjzuPS1+UJeLeIZyIDn94RTeLHzVNz7qPgE94dz4ISSKXUgrBhj4Zk7utrk913b4m0qskKn+MhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMoR0NtFW81tnWRAWCGgy/101Czdnc257hNQciMBzR4jFR6DEEtSUxGAmd/O69U6dH2ng8SGI5noHrR67R60iT2aw5Dt2p+owoIzJHGSqbAS3sXeHyzNRY4IOgBQqnkx32YL6ZKFBG83FnhkcYnChbUpPnf1s831BWEmK7piDMhJ6Oj+QjB+3MAbcZKOps50TPCh79rR/XnYuFni57e/3hTpNZVhLcZVkx0Zu1EeNVXkqWJAoXaknErU3po3+pJsOaPUaGgzl/qDcouGLOA3u+D6xiz7dZejgqVJc4TBXVqVCTz7iSSsqYQH+lGAE=\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\"The\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\" summarize_source has returned successfully. According to the instructions, I should now reply with exactly\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\" \\\"PROMPT_DONE\\\" and no other text.\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"signature_delta\",\"signature\":\"EuACCm4IDRgCKkBFFJkLPfdTPaxLI9uliA7Q7HFBV/YIU6/QTIWGrMPbGdbjMR8KXKHC6r4UKTpeAOTR7R0lZ9V3T1GHMwGw0zKUMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMoQyoPhCL7TEv5y6rGgxRN3h6q4vat+wUsB8iME6oLmgjwKuqei/kSCgs/uSR4fB7DLTS+EWcZrZOU1fvrPQ2h7oAwtExZ72a5gucgyqfAVk0ULeWED//olNSNP/7YqX+iYj3K81eZMwKNeOdFICjK4lA9BtxcyI9wgLfu8b/z9DTMh/DO9l+RUVzcLGLgaer+kHbj4qXH9ihYoQOstrdkHRihi9W7oXOUe9xn34XbrvVtsnWmXZWLx0lWbX6xr1E/T5WYb3/d4R1o02dIamFgB/u5Xaw7w1SzgzQZdHFQ3KgkuSkCohay00zaMbkyRgB\"}}", "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0}", "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":1,\"content_block\":{\"type\":\"text\",\"text\":\"\"}}", "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"text_delta\",\"text\":\"PROMPT_DONE\"}}", "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":1}", - "event: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":13,\"cache_creation_input_tokens\":189,\"cache_read_input_tokens\":2650,\"output_tokens\":49}}", + "event: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":13,\"cache_creation_input_tokens\":188,\"cache_read_input_tokens\":2666,\"output_tokens\":48}}", "event: message_stop\ndata: {\"type\":\"message_stop\"}" ], "kind": "sse" @@ -1420,32 +1518,32 @@ "anthropic-organization-id": "27796668-7351-40ac-acc4-024aee8995a5", "anthropic-ratelimit-input-tokens-limit": "3000000", "anthropic-ratelimit-input-tokens-remaining": "2998000", - "anthropic-ratelimit-input-tokens-reset": "2026-05-21T06:49:07Z", + "anthropic-ratelimit-input-tokens-reset": "2026-05-22T08:13:23Z", "anthropic-ratelimit-output-tokens-limit": "600000", "anthropic-ratelimit-output-tokens-remaining": "600000", - "anthropic-ratelimit-output-tokens-reset": "2026-05-21T06:49:07Z", + "anthropic-ratelimit-output-tokens-reset": "2026-05-22T08:13:23Z", "anthropic-ratelimit-requests-limit": "20000", "anthropic-ratelimit-requests-remaining": "19999", - "anthropic-ratelimit-requests-reset": "2026-05-21T06:49:07Z", + "anthropic-ratelimit-requests-reset": "2026-05-22T08:13:23Z", "anthropic-ratelimit-tokens-limit": "3600000", "anthropic-ratelimit-tokens-remaining": "3598000", - "anthropic-ratelimit-tokens-reset": "2026-05-21T06:49:07Z", + "anthropic-ratelimit-tokens-reset": "2026-05-22T08:13:23Z", "cache-control": "no-cache", "cf-cache-status": "DYNAMIC", - "cf-ray": "9ff1a3ad9fe6c2f2-VIE", + "cf-ray": "9ffa5c7b99075db9-VIE", "connection": "keep-alive", "content-encoding": "gzip", "content-security-policy": "default-src 'none'; frame-ancestors 'none'", "content-type": "text/event-stream; charset=utf-8", - "date": "Thu, 21 May 2026 06:49:11 GMT", - "request-id": "req_011CbFGVr1re2qwBcH69XKHA", + "date": "Fri, 22 May 2026 08:13:24 GMT", + "request-id": "req_011CbHGjSJVD4R2rgh6TmzGF", "server": "cloudflare", "set-cookie": "[REDACTED]", "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "traceresponse": "00-7d6d116e436c5ee5da5bbabc73b46826-8fc3ea8a06eeec11-01", + "traceresponse": "00-21d68585e85af0175a50663b297e1a1c-b80e62b25474b64f-01", "transfer-encoding": "chunked", "vary": "Accept-Encoding", - "x-envoy-upstream-service-time": "4366", + "x-envoy-upstream-service-time": "1213", "x-robots-tag": "none" }, "status": 200, @@ -1456,7 +1554,7 @@ "callIndex": 4, "id": "3d93fe37f72a947f", "matchKey": "POST api.anthropic.com/v1/messages", - "recordedAt": "2026-05-21T06:49:14.852Z", + "recordedAt": "2026-05-22T08:13:27.558Z", "request": { "body": { "kind": "json", @@ -1483,7 +1581,7 @@ "cache_control": { "type": "ephemeral" }, - "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Thu, May 21, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-LqmoTW/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts\n\n\nNever call the task tool. Do not delegate e2e-flue-skill to another session. If you need the skill body, read .agents/skills/e2e-flue-skill/SKILL.md yourself with the read tool. Return the marker from the Arguments object exactly, with no other text.\n", + "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-HpI3r1/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts\n\n\nNever call the task tool. Do not delegate e2e-flue-skill to another session. If you need the skill body, read .agents/skills/e2e-flue-skill/SKILL.md yourself with the read tool. Return the marker from the Arguments object exactly, with no other text.\n", "type": "text" } ], @@ -1509,7 +1607,9 @@ "type": "string" } }, - "required": ["path"], + "required": [ + "path" + ], "type": "object" }, "name": "read" @@ -1528,7 +1628,10 @@ "type": "string" } }, - "required": ["path", "content"], + "required": [ + "path", + "content" + ], "type": "object" }, "name": "write" @@ -1555,7 +1658,11 @@ "type": "boolean" } }, - "required": ["path", "oldText", "newText"], + "required": [ + "path", + "oldText", + "newText" + ], "type": "object" }, "name": "edit" @@ -1574,7 +1681,9 @@ "type": "number" } }, - "required": ["command"], + "required": [ + "command" + ], "type": "object" }, "name": "bash" @@ -1597,7 +1706,9 @@ "type": "string" } }, - "required": ["pattern"], + "required": [ + "pattern" + ], "type": "object" }, "name": "grep" @@ -1616,7 +1727,9 @@ "type": "string" } }, - "required": ["pattern"], + "required": [ + "pattern" + ], "type": "object" }, "name": "glob" @@ -1646,7 +1759,9 @@ "type": "string" } }, - "required": ["prompt"], + "required": [ + "prompt" + ], "type": "object" }, "name": "task" @@ -1661,18 +1776,19 @@ "response": { "body": { "chunks": [ - "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-5-20250929\",\"id\":\"msg_019mZ4kaqaQKoxnqaBHfhAKp\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":3,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":1809,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":5,\"service_tier\":\"standard\",\"inference_geo\":\"not_available\"}}}", + "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-5-20250929\",\"id\":\"msg_01VMLMxbJcjsVPZkWat83Xxs\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":3,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":1811,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":3,\"service_tier\":\"standard\",\"inference_geo\":\"not_available\"}}}", "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"}}", "event: ping\ndata: {\"type\":\"ping\"}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"I'll run the e\"}}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"2e-flue-skill by reading its instructions and following them.\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"I'll read\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\" the skill file and execute it according to its instructions.\"}}", "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0}", - "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":1,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01TJVfeBb5CPsHTxgyECHJqB\",\"name\":\"read\",\"input\":{},\"caller\":{\"type\":\"direct\"}}}", + "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":1,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01HmmsNYZUC67GqVoKKLbfiQ\",\"name\":\"read\",\"input\":{},\"caller\":{\"type\":\"direct\"}}}", "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"}}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"path\\\": \\\".agents/skills/e2e-flue-skill/SKILL.md\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"path\\\": \\\".\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"agents/skills/e2e-flue-skill/SKILL.md\"}}", "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"}\"}}", "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":1}", - "event: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":3,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":1809,\"output_tokens\":89}}", + "event: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":3,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":1811,\"output_tokens\":83}}", "event: message_stop\ndata: {\"type\":\"message_stop\"}" ], "kind": "sse" @@ -1681,32 +1797,32 @@ "anthropic-organization-id": "27796668-7351-40ac-acc4-024aee8995a5", "anthropic-ratelimit-input-tokens-limit": "3000000", "anthropic-ratelimit-input-tokens-remaining": "2999000", - "anthropic-ratelimit-input-tokens-reset": "2026-05-21T06:49:12Z", + "anthropic-ratelimit-input-tokens-reset": "2026-05-22T08:13:25Z", "anthropic-ratelimit-output-tokens-limit": "600000", "anthropic-ratelimit-output-tokens-remaining": "600000", - "anthropic-ratelimit-output-tokens-reset": "2026-05-21T06:49:12Z", + "anthropic-ratelimit-output-tokens-reset": "2026-05-22T08:13:25Z", "anthropic-ratelimit-requests-limit": "20000", "anthropic-ratelimit-requests-remaining": "19999", - "anthropic-ratelimit-requests-reset": "2026-05-21T06:49:12Z", + "anthropic-ratelimit-requests-reset": "2026-05-22T08:13:25Z", "anthropic-ratelimit-tokens-limit": "3600000", "anthropic-ratelimit-tokens-remaining": "3599000", - "anthropic-ratelimit-tokens-reset": "2026-05-21T06:49:12Z", + "anthropic-ratelimit-tokens-reset": "2026-05-22T08:13:25Z", "cache-control": "no-cache", "cf-cache-status": "DYNAMIC", - "cf-ray": "9ff1a3cd29ccc2f2-VIE", + "cf-ray": "9ffa5c898c435db9-VIE", "connection": "keep-alive", "content-encoding": "gzip", "content-security-policy": "default-src 'none'; frame-ancestors 'none'", "content-type": "text/event-stream; charset=utf-8", - "date": "Thu, 21 May 2026 06:49:13 GMT", - "request-id": "req_011CbFGWDcsgmaGCFP5KYhft", + "date": "Fri, 22 May 2026 08:13:26 GMT", + "request-id": "req_011CbHGjbpDzh7hV47HWeiWq", "server": "cloudflare", "set-cookie": "[REDACTED]", "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "traceresponse": "00-174011067c2daa49ddeab98ec0e79edb-17db276d56b0de5a-01", + "traceresponse": "00-e2983bef9d410175021182eb9be77d7a-c77c00237b48e432-01", "transfer-encoding": "chunked", "vary": "Accept-Encoding", - "x-envoy-upstream-service-time": "1289", + "x-envoy-upstream-service-time": "1249", "x-robots-tag": "none" }, "status": 200, @@ -1717,7 +1833,7 @@ "callIndex": 5, "id": "fb4ed2bb1569d980", "matchKey": "POST api.anthropic.com/v1/messages", - "recordedAt": "2026-05-21T06:49:16.371Z", + "recordedAt": "2026-05-22T08:13:29.044Z", "request": { "body": { "kind": "json", @@ -1736,11 +1852,11 @@ { "content": [ { - "text": "I'll run the e2e-flue-skill by reading its instructions and following them.", + "text": "I'll read the skill file and execute it according to its instructions.", "type": "text" }, { - "id": "toolu_01TJVfeBb5CPsHTxgyECHJqB", + "id": "toolu_01HmmsNYZUC67GqVoKKLbfiQ", "input": { "path": ".agents/skills/e2e-flue-skill/SKILL.md" }, @@ -1758,7 +1874,7 @@ }, "content": "---\nname: e2e-flue-skill\ndescription: Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n---\n\nReturn the marker from the provided args exactly once. Output no other text.\n", "is_error": false, - "tool_use_id": "toolu_01TJVfeBb5CPsHTxgyECHJqB", + "tool_use_id": "toolu_01HmmsNYZUC67GqVoKKLbfiQ", "type": "tool_result" } ], @@ -1772,7 +1888,7 @@ "cache_control": { "type": "ephemeral" }, - "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Thu, May 21, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-LqmoTW/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts\n\n\nNever call the task tool. Do not delegate e2e-flue-skill to another session. If you need the skill body, read .agents/skills/e2e-flue-skill/SKILL.md yourself with the read tool. Return the marker from the Arguments object exactly, with no other text.\n", + "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-HpI3r1/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts\n\n\nNever call the task tool. Do not delegate e2e-flue-skill to another session. If you need the skill body, read .agents/skills/e2e-flue-skill/SKILL.md yourself with the read tool. Return the marker from the Arguments object exactly, with no other text.\n", "type": "text" } ], @@ -1798,7 +1914,9 @@ "type": "string" } }, - "required": ["path"], + "required": [ + "path" + ], "type": "object" }, "name": "read" @@ -1817,7 +1935,10 @@ "type": "string" } }, - "required": ["path", "content"], + "required": [ + "path", + "content" + ], "type": "object" }, "name": "write" @@ -1844,7 +1965,11 @@ "type": "boolean" } }, - "required": ["path", "oldText", "newText"], + "required": [ + "path", + "oldText", + "newText" + ], "type": "object" }, "name": "edit" @@ -1863,7 +1988,9 @@ "type": "number" } }, - "required": ["command"], + "required": [ + "command" + ], "type": "object" }, "name": "bash" @@ -1886,7 +2013,9 @@ "type": "string" } }, - "required": ["pattern"], + "required": [ + "pattern" + ], "type": "object" }, "name": "grep" @@ -1905,7 +2034,9 @@ "type": "string" } }, - "required": ["pattern"], + "required": [ + "pattern" + ], "type": "object" }, "name": "glob" @@ -1935,7 +2066,9 @@ "type": "string" } }, - "required": ["prompt"], + "required": [ + "prompt" + ], "type": "object" }, "name": "task" @@ -1950,12 +2083,12 @@ "response": { "body": { "chunks": [ - "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-5-20250929\",\"id\":\"msg_01CA3PrSTFThZsazE6nWdyfW\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":6,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":1962,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":7,\"service_tier\":\"standard\",\"inference_geo\":\"not_available\"}}}", + "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-5-20250929\",\"id\":\"msg_01TaPPFSvzUDKTNU8n4TA2Ub\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":6,\"cache_creation_input_tokens\":147,\"cache_read_input_tokens\":1811,\"cache_creation\":{\"ephemeral_5m_input_tokens\":147,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":7,\"service_tier\":\"standard\",\"inference_geo\":\"not_available\"}}}", "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"}}", "event: ping\ndata: {\"type\":\"ping\"}", "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"SKILL_DONE\"}}", "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0}", - "event: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":6,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":1962,\"output_tokens\":8}}", + "event: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":6,\"cache_creation_input_tokens\":147,\"cache_read_input_tokens\":1811,\"output_tokens\":8}}", "event: message_stop\ndata: {\"type\":\"message_stop\"}" ], "kind": "sse" @@ -1964,32 +2097,32 @@ "anthropic-organization-id": "27796668-7351-40ac-acc4-024aee8995a5", "anthropic-ratelimit-input-tokens-limit": "3000000", "anthropic-ratelimit-input-tokens-remaining": "2999000", - "anthropic-ratelimit-input-tokens-reset": "2026-05-21T06:49:15Z", + "anthropic-ratelimit-input-tokens-reset": "2026-05-22T08:13:27Z", "anthropic-ratelimit-output-tokens-limit": "600000", "anthropic-ratelimit-output-tokens-remaining": "600000", - "anthropic-ratelimit-output-tokens-reset": "2026-05-21T06:49:15Z", + "anthropic-ratelimit-output-tokens-reset": "2026-05-22T08:13:27Z", "anthropic-ratelimit-requests-limit": "20000", "anthropic-ratelimit-requests-remaining": "19999", - "anthropic-ratelimit-requests-reset": "2026-05-21T06:49:15Z", + "anthropic-ratelimit-requests-reset": "2026-05-22T08:13:27Z", "anthropic-ratelimit-tokens-limit": "3600000", "anthropic-ratelimit-tokens-remaining": "3599000", - "anthropic-ratelimit-tokens-reset": "2026-05-21T06:49:15Z", + "anthropic-ratelimit-tokens-reset": "2026-05-22T08:13:27Z", "cache-control": "no-cache", "cf-cache-status": "DYNAMIC", - "cf-ray": "9ff1a3dc4eb2c2f2-VIE", + "cf-ray": "9ffa5c97bf115db9-VIE", "connection": "keep-alive", "content-encoding": "gzip", "content-security-policy": "default-src 'none'; frame-ancestors 'none'", "content-type": "text/event-stream; charset=utf-8", - "date": "Thu, 21 May 2026 06:49:16 GMT", - "request-id": "req_011CbFGWPvF2JLYeSinnfsKq", + "date": "Fri, 22 May 2026 08:13:28 GMT", + "request-id": "req_011CbHGjmZcbfZvsk78nq5vh", "server": "cloudflare", "set-cookie": "[REDACTED]", "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "traceresponse": "00-aa018edfc984405c8755646830f6edef-3420a5b320e70476-01", + "traceresponse": "00-d1ba118962f5cad41869cc135494676d-a3266ad88f2939d3-01", "transfer-encoding": "chunked", "vary": "Accept-Encoding", - "x-envoy-upstream-service-time": "1261", + "x-envoy-upstream-service-time": "1209", "x-robots-tag": "none" }, "status": 200, @@ -2000,14 +2133,14 @@ "callIndex": 0, "id": "7c0e162d6794cf5d", "matchKey": "POST api.openai.com/v1/responses", - "recordedAt": "2026-05-21T06:49:17.223Z", + "recordedAt": "2026-05-22T08:13:30.439Z", "request": { "body": { "kind": "json", "value": { "input": [ { - "content": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Thu, May 21, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-LqmoTW/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + "content": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-HpI3r1/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", "role": "system" }, { @@ -2043,7 +2176,9 @@ "type": "string" } }, - "required": ["path"], + "required": [ + "path" + ], "type": "object" }, "strict": false, @@ -2063,7 +2198,10 @@ "type": "string" } }, - "required": ["path", "content"], + "required": [ + "path", + "content" + ], "type": "object" }, "strict": false, @@ -2091,7 +2229,11 @@ "type": "boolean" } }, - "required": ["path", "oldText", "newText"], + "required": [ + "path", + "oldText", + "newText" + ], "type": "object" }, "strict": false, @@ -2111,7 +2253,9 @@ "type": "number" } }, - "required": ["command"], + "required": [ + "command" + ], "type": "object" }, "strict": false, @@ -2135,7 +2279,9 @@ "type": "string" } }, - "required": ["pattern"], + "required": [ + "pattern" + ], "type": "object" }, "strict": false, @@ -2155,7 +2301,9 @@ "type": "string" } }, - "required": ["pattern"], + "required": [ + "pattern" + ], "type": "object" }, "strict": false, @@ -2183,7 +2331,9 @@ "type": "string" } }, - "required": ["prompt"], + "required": [ + "prompt" + ], "type": "object" }, "strict": false, @@ -2199,16 +2349,16 @@ "response": { "body": { "chunks": [ - "event: response.created\ndata: {\"type\":\"response.created\",\"response\":{\"id\":\"resp_0bd28b8a5ad18b2e016a0eaaeca6e88195b38d143e2272e210\",\"object\":\"response\",\"created_at\":1779346156,\"status\":\"in_progress\",\"background\":false,\"completed_at\":null,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":null,\"instructions\":null,\"max_output_tokens\":null,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":\"flue-e2e-instance::default::task:task:adc71368-3f10-4ddf-ac19-18\",\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"auto\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[{\"type\":\"function\",\"description\":\"Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.\",\"name\":\"read\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to read\"},\"offset\":{\"type\":\"number\",\"description\":\"Line number to start from (1-indexed)\"},\"limit\":{\"type\":\"number\",\"description\":\"Maximum number of lines to read\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Write content to a file. Creates the file and parent directories if they do not exist.\",\"name\":\"write\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"content\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to write\"},\"content\":{\"type\":\"string\",\"description\":\"Content to write to the file\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.\",\"name\":\"edit\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"oldText\",\"newText\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to edit\"},\"oldText\":{\"type\":\"string\",\"description\":\"Exact text to find (must be unique)\"},\"newText\":{\"type\":\"string\",\"description\":\"Replacement text\"},\"replaceAll\":{\"type\":\"boolean\",\"description\":\"Replace all occurrences\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.\",\"name\":\"bash\",\"parameters\":{\"type\":\"object\",\"required\":[\"command\"],\"properties\":{\"command\":{\"type\":\"string\",\"description\":\"Bash command to execute\"},\"timeout\":{\"type\":\"number\",\"description\":\"Timeout in seconds\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.\",\"name\":\"grep\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Search pattern (regex)\"},\"path\":{\"type\":\"string\",\"description\":\"Directory or file to search (default: .)\"},\"include\":{\"type\":\"string\",\"description\":\"Glob filter, e.g. \\\"*.ts\\\"\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Find files by filename pattern using shell find -name semantics. Returns matching file paths.\",\"name\":\"glob\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Filename pattern, e.g. \\\"*.ts\\\"\"},\"path\":{\"type\":\"string\",\"description\":\"Directory to search in (default: .)\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.\",\"name\":\"task\",\"parameters\":{\"type\":\"object\",\"required\":[\"prompt\"],\"properties\":{\"description\":{\"type\":\"string\",\"description\":\"Short human-readable label for the delegated work\"},\"prompt\":{\"type\":\"string\",\"description\":\"Focused instructions for the child agent\"},\"role\":{\"type\":\"string\",\"description\":\"Role to use for the child agent\"},\"cwd\":{\"type\":\"string\",\"description\":\"Working directory for the child agent. AGENTS.md and skills are discovered from here.\"}}},\"strict\":false}],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":null,\"user\":null,\"metadata\":{}},\"sequence_number\":0}", - "event: response.in_progress\ndata: {\"type\":\"response.in_progress\",\"response\":{\"id\":\"resp_0bd28b8a5ad18b2e016a0eaaeca6e88195b38d143e2272e210\",\"object\":\"response\",\"created_at\":1779346156,\"status\":\"in_progress\",\"background\":false,\"completed_at\":null,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":null,\"instructions\":null,\"max_output_tokens\":null,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":\"flue-e2e-instance::default::task:task:adc71368-3f10-4ddf-ac19-18\",\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"auto\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[{\"type\":\"function\",\"description\":\"Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.\",\"name\":\"read\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to read\"},\"offset\":{\"type\":\"number\",\"description\":\"Line number to start from (1-indexed)\"},\"limit\":{\"type\":\"number\",\"description\":\"Maximum number of lines to read\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Write content to a file. Creates the file and parent directories if they do not exist.\",\"name\":\"write\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"content\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to write\"},\"content\":{\"type\":\"string\",\"description\":\"Content to write to the file\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.\",\"name\":\"edit\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"oldText\",\"newText\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to edit\"},\"oldText\":{\"type\":\"string\",\"description\":\"Exact text to find (must be unique)\"},\"newText\":{\"type\":\"string\",\"description\":\"Replacement text\"},\"replaceAll\":{\"type\":\"boolean\",\"description\":\"Replace all occurrences\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.\",\"name\":\"bash\",\"parameters\":{\"type\":\"object\",\"required\":[\"command\"],\"properties\":{\"command\":{\"type\":\"string\",\"description\":\"Bash command to execute\"},\"timeout\":{\"type\":\"number\",\"description\":\"Timeout in seconds\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.\",\"name\":\"grep\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Search pattern (regex)\"},\"path\":{\"type\":\"string\",\"description\":\"Directory or file to search (default: .)\"},\"include\":{\"type\":\"string\",\"description\":\"Glob filter, e.g. \\\"*.ts\\\"\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Find files by filename pattern using shell find -name semantics. Returns matching file paths.\",\"name\":\"glob\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Filename pattern, e.g. \\\"*.ts\\\"\"},\"path\":{\"type\":\"string\",\"description\":\"Directory to search in (default: .)\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.\",\"name\":\"task\",\"parameters\":{\"type\":\"object\",\"required\":[\"prompt\"],\"properties\":{\"description\":{\"type\":\"string\",\"description\":\"Short human-readable label for the delegated work\"},\"prompt\":{\"type\":\"string\",\"description\":\"Focused instructions for the child agent\"},\"role\":{\"type\":\"string\",\"description\":\"Role to use for the child agent\"},\"cwd\":{\"type\":\"string\",\"description\":\"Working directory for the child agent. AGENTS.md and skills are discovered from here.\"}}},\"strict\":false}],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":null,\"user\":null,\"metadata\":{}},\"sequence_number\":1}", - "event: response.output_item.added\ndata: {\"type\":\"response.output_item.added\",\"item\":{\"id\":\"msg_0bd28b8a5ad18b2e016a0eaaed1ce8819588a498f3dddd9da6\",\"type\":\"message\",\"status\":\"in_progress\",\"content\":[],\"role\":\"assistant\"},\"output_index\":0,\"sequence_number\":2}", - "event: response.content_part.added\ndata: {\"type\":\"response.content_part.added\",\"content_index\":0,\"item_id\":\"msg_0bd28b8a5ad18b2e016a0eaaed1ce8819588a498f3dddd9da6\",\"output_index\":0,\"part\":{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"\"},\"sequence_number\":3}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"TASK\",\"item_id\":\"msg_0bd28b8a5ad18b2e016a0eaaed1ce8819588a498f3dddd9da6\",\"logprobs\":[],\"obfuscation\":\"ibBHNPoZui5G\",\"output_index\":0,\"sequence_number\":4}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"_DONE\",\"item_id\":\"msg_0bd28b8a5ad18b2e016a0eaaed1ce8819588a498f3dddd9da6\",\"logprobs\":[],\"obfuscation\":\"aiYlRYCETDx\",\"output_index\":0,\"sequence_number\":5}", - "event: response.output_text.done\ndata: {\"type\":\"response.output_text.done\",\"content_index\":0,\"item_id\":\"msg_0bd28b8a5ad18b2e016a0eaaed1ce8819588a498f3dddd9da6\",\"logprobs\":[],\"output_index\":0,\"sequence_number\":6,\"text\":\"TASK_DONE\"}", - "event: response.content_part.done\ndata: {\"type\":\"response.content_part.done\",\"content_index\":0,\"item_id\":\"msg_0bd28b8a5ad18b2e016a0eaaed1ce8819588a498f3dddd9da6\",\"output_index\":0,\"part\":{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"TASK_DONE\"},\"sequence_number\":7}", - "event: response.output_item.done\ndata: {\"type\":\"response.output_item.done\",\"item\":{\"id\":\"msg_0bd28b8a5ad18b2e016a0eaaed1ce8819588a498f3dddd9da6\",\"type\":\"message\",\"status\":\"completed\",\"content\":[{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"TASK_DONE\"}],\"role\":\"assistant\"},\"output_index\":0,\"sequence_number\":8}", - "event: response.completed\ndata: {\"type\":\"response.completed\",\"response\":{\"id\":\"resp_0bd28b8a5ad18b2e016a0eaaeca6e88195b38d143e2272e210\",\"object\":\"response\",\"created_at\":1779346156,\"status\":\"completed\",\"background\":false,\"completed_at\":1779346157,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":null,\"instructions\":null,\"max_output_tokens\":null,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[{\"id\":\"msg_0bd28b8a5ad18b2e016a0eaaed1ce8819588a498f3dddd9da6\",\"type\":\"message\",\"status\":\"completed\",\"content\":[{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"TASK_DONE\"}],\"role\":\"assistant\"}],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":\"flue-e2e-instance::default::task:task:adc71368-3f10-4ddf-ac19-18\",\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"default\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[{\"type\":\"function\",\"description\":\"Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.\",\"name\":\"read\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to read\"},\"offset\":{\"type\":\"number\",\"description\":\"Line number to start from (1-indexed)\"},\"limit\":{\"type\":\"number\",\"description\":\"Maximum number of lines to read\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Write content to a file. Creates the file and parent directories if they do not exist.\",\"name\":\"write\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"content\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to write\"},\"content\":{\"type\":\"string\",\"description\":\"Content to write to the file\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.\",\"name\":\"edit\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"oldText\",\"newText\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to edit\"},\"oldText\":{\"type\":\"string\",\"description\":\"Exact text to find (must be unique)\"},\"newText\":{\"type\":\"string\",\"description\":\"Replacement text\"},\"replaceAll\":{\"type\":\"boolean\",\"description\":\"Replace all occurrences\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.\",\"name\":\"bash\",\"parameters\":{\"type\":\"object\",\"required\":[\"command\"],\"properties\":{\"command\":{\"type\":\"string\",\"description\":\"Bash command to execute\"},\"timeout\":{\"type\":\"number\",\"description\":\"Timeout in seconds\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.\",\"name\":\"grep\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Search pattern (regex)\"},\"path\":{\"type\":\"string\",\"description\":\"Directory or file to search (default: .)\"},\"include\":{\"type\":\"string\",\"description\":\"Glob filter, e.g. \\\"*.ts\\\"\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Find files by filename pattern using shell find -name semantics. Returns matching file paths.\",\"name\":\"glob\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Filename pattern, e.g. \\\"*.ts\\\"\"},\"path\":{\"type\":\"string\",\"description\":\"Directory to search in (default: .)\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.\",\"name\":\"task\",\"parameters\":{\"type\":\"object\",\"required\":[\"prompt\"],\"properties\":{\"description\":{\"type\":\"string\",\"description\":\"Short human-readable label for the delegated work\"},\"prompt\":{\"type\":\"string\",\"description\":\"Focused instructions for the child agent\"},\"role\":{\"type\":\"string\",\"description\":\"Role to use for the child agent\"},\"cwd\":{\"type\":\"string\",\"description\":\"Working directory for the child agent. AGENTS.md and skills are discovered from here.\"}}},\"strict\":false}],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":{\"input_tokens\":770,\"input_tokens_details\":{\"cached_tokens\":0},\"output_tokens\":4,\"output_tokens_details\":{\"reasoning_tokens\":0},\"total_tokens\":774},\"user\":null,\"metadata\":{}},\"sequence_number\":9}" + "event: response.created\ndata: {\"type\":\"response.created\",\"response\":{\"id\":\"resp_077d996caec5e196016a10102959d4819ca5fb0b8d10048c4b\",\"object\":\"response\",\"created_at\":1779437609,\"status\":\"in_progress\",\"background\":false,\"completed_at\":null,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":null,\"instructions\":null,\"max_output_tokens\":null,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":\"flue-e2e-instance::default::task:task:f2db752a-32d6-408a-8d80-c1\",\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"auto\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[{\"type\":\"function\",\"description\":\"Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.\",\"name\":\"read\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to read\"},\"offset\":{\"type\":\"number\",\"description\":\"Line number to start from (1-indexed)\"},\"limit\":{\"type\":\"number\",\"description\":\"Maximum number of lines to read\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Write content to a file. Creates the file and parent directories if they do not exist.\",\"name\":\"write\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"content\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to write\"},\"content\":{\"type\":\"string\",\"description\":\"Content to write to the file\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.\",\"name\":\"edit\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"oldText\",\"newText\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to edit\"},\"oldText\":{\"type\":\"string\",\"description\":\"Exact text to find (must be unique)\"},\"newText\":{\"type\":\"string\",\"description\":\"Replacement text\"},\"replaceAll\":{\"type\":\"boolean\",\"description\":\"Replace all occurrences\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.\",\"name\":\"bash\",\"parameters\":{\"type\":\"object\",\"required\":[\"command\"],\"properties\":{\"command\":{\"type\":\"string\",\"description\":\"Bash command to execute\"},\"timeout\":{\"type\":\"number\",\"description\":\"Timeout in seconds\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.\",\"name\":\"grep\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Search pattern (regex)\"},\"path\":{\"type\":\"string\",\"description\":\"Directory or file to search (default: .)\"},\"include\":{\"type\":\"string\",\"description\":\"Glob filter, e.g. \\\"*.ts\\\"\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Find files by filename pattern using shell find -name semantics. Returns matching file paths.\",\"name\":\"glob\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Filename pattern, e.g. \\\"*.ts\\\"\"},\"path\":{\"type\":\"string\",\"description\":\"Directory to search in (default: .)\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.\",\"name\":\"task\",\"parameters\":{\"type\":\"object\",\"required\":[\"prompt\"],\"properties\":{\"description\":{\"type\":\"string\",\"description\":\"Short human-readable label for the delegated work\"},\"prompt\":{\"type\":\"string\",\"description\":\"Focused instructions for the child agent\"},\"role\":{\"type\":\"string\",\"description\":\"Role to use for the child agent\"},\"cwd\":{\"type\":\"string\",\"description\":\"Working directory for the child agent. AGENTS.md and skills are discovered from here.\"}}},\"strict\":false}],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":null,\"user\":null,\"metadata\":{}},\"sequence_number\":0}", + "event: response.in_progress\ndata: {\"type\":\"response.in_progress\",\"response\":{\"id\":\"resp_077d996caec5e196016a10102959d4819ca5fb0b8d10048c4b\",\"object\":\"response\",\"created_at\":1779437609,\"status\":\"in_progress\",\"background\":false,\"completed_at\":null,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":null,\"instructions\":null,\"max_output_tokens\":null,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":\"flue-e2e-instance::default::task:task:f2db752a-32d6-408a-8d80-c1\",\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"auto\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[{\"type\":\"function\",\"description\":\"Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.\",\"name\":\"read\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to read\"},\"offset\":{\"type\":\"number\",\"description\":\"Line number to start from (1-indexed)\"},\"limit\":{\"type\":\"number\",\"description\":\"Maximum number of lines to read\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Write content to a file. Creates the file and parent directories if they do not exist.\",\"name\":\"write\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"content\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to write\"},\"content\":{\"type\":\"string\",\"description\":\"Content to write to the file\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.\",\"name\":\"edit\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"oldText\",\"newText\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to edit\"},\"oldText\":{\"type\":\"string\",\"description\":\"Exact text to find (must be unique)\"},\"newText\":{\"type\":\"string\",\"description\":\"Replacement text\"},\"replaceAll\":{\"type\":\"boolean\",\"description\":\"Replace all occurrences\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.\",\"name\":\"bash\",\"parameters\":{\"type\":\"object\",\"required\":[\"command\"],\"properties\":{\"command\":{\"type\":\"string\",\"description\":\"Bash command to execute\"},\"timeout\":{\"type\":\"number\",\"description\":\"Timeout in seconds\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.\",\"name\":\"grep\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Search pattern (regex)\"},\"path\":{\"type\":\"string\",\"description\":\"Directory or file to search (default: .)\"},\"include\":{\"type\":\"string\",\"description\":\"Glob filter, e.g. \\\"*.ts\\\"\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Find files by filename pattern using shell find -name semantics. Returns matching file paths.\",\"name\":\"glob\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Filename pattern, e.g. \\\"*.ts\\\"\"},\"path\":{\"type\":\"string\",\"description\":\"Directory to search in (default: .)\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.\",\"name\":\"task\",\"parameters\":{\"type\":\"object\",\"required\":[\"prompt\"],\"properties\":{\"description\":{\"type\":\"string\",\"description\":\"Short human-readable label for the delegated work\"},\"prompt\":{\"type\":\"string\",\"description\":\"Focused instructions for the child agent\"},\"role\":{\"type\":\"string\",\"description\":\"Role to use for the child agent\"},\"cwd\":{\"type\":\"string\",\"description\":\"Working directory for the child agent. AGENTS.md and skills are discovered from here.\"}}},\"strict\":false}],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":null,\"user\":null,\"metadata\":{}},\"sequence_number\":1}", + "event: response.output_item.added\ndata: {\"type\":\"response.output_item.added\",\"item\":{\"id\":\"msg_077d996caec5e196016a10102a47f8819c9406a2757082ab93\",\"type\":\"message\",\"status\":\"in_progress\",\"content\":[],\"role\":\"assistant\"},\"output_index\":0,\"sequence_number\":2}", + "event: response.content_part.added\ndata: {\"type\":\"response.content_part.added\",\"content_index\":0,\"item_id\":\"msg_077d996caec5e196016a10102a47f8819c9406a2757082ab93\",\"output_index\":0,\"part\":{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"\"},\"sequence_number\":3}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"TASK\",\"item_id\":\"msg_077d996caec5e196016a10102a47f8819c9406a2757082ab93\",\"logprobs\":[],\"obfuscation\":\"hxGcDEHJs4KI\",\"output_index\":0,\"sequence_number\":4}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"_DONE\",\"item_id\":\"msg_077d996caec5e196016a10102a47f8819c9406a2757082ab93\",\"logprobs\":[],\"obfuscation\":\"codL24VwzOS\",\"output_index\":0,\"sequence_number\":5}", + "event: response.output_text.done\ndata: {\"type\":\"response.output_text.done\",\"content_index\":0,\"item_id\":\"msg_077d996caec5e196016a10102a47f8819c9406a2757082ab93\",\"logprobs\":[],\"output_index\":0,\"sequence_number\":6,\"text\":\"TASK_DONE\"}", + "event: response.content_part.done\ndata: {\"type\":\"response.content_part.done\",\"content_index\":0,\"item_id\":\"msg_077d996caec5e196016a10102a47f8819c9406a2757082ab93\",\"output_index\":0,\"part\":{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"TASK_DONE\"},\"sequence_number\":7}", + "event: response.output_item.done\ndata: {\"type\":\"response.output_item.done\",\"item\":{\"id\":\"msg_077d996caec5e196016a10102a47f8819c9406a2757082ab93\",\"type\":\"message\",\"status\":\"completed\",\"content\":[{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"TASK_DONE\"}],\"role\":\"assistant\"},\"output_index\":0,\"sequence_number\":8}", + "event: response.completed\ndata: {\"type\":\"response.completed\",\"response\":{\"id\":\"resp_077d996caec5e196016a10102959d4819ca5fb0b8d10048c4b\",\"object\":\"response\",\"created_at\":1779437609,\"status\":\"completed\",\"background\":false,\"completed_at\":1779437610,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":null,\"instructions\":null,\"max_output_tokens\":null,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[{\"id\":\"msg_077d996caec5e196016a10102a47f8819c9406a2757082ab93\",\"type\":\"message\",\"status\":\"completed\",\"content\":[{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"TASK_DONE\"}],\"role\":\"assistant\"}],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":\"flue-e2e-instance::default::task:task:f2db752a-32d6-408a-8d80-c1\",\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"default\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[{\"type\":\"function\",\"description\":\"Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.\",\"name\":\"read\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to read\"},\"offset\":{\"type\":\"number\",\"description\":\"Line number to start from (1-indexed)\"},\"limit\":{\"type\":\"number\",\"description\":\"Maximum number of lines to read\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Write content to a file. Creates the file and parent directories if they do not exist.\",\"name\":\"write\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"content\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to write\"},\"content\":{\"type\":\"string\",\"description\":\"Content to write to the file\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.\",\"name\":\"edit\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"oldText\",\"newText\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to edit\"},\"oldText\":{\"type\":\"string\",\"description\":\"Exact text to find (must be unique)\"},\"newText\":{\"type\":\"string\",\"description\":\"Replacement text\"},\"replaceAll\":{\"type\":\"boolean\",\"description\":\"Replace all occurrences\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.\",\"name\":\"bash\",\"parameters\":{\"type\":\"object\",\"required\":[\"command\"],\"properties\":{\"command\":{\"type\":\"string\",\"description\":\"Bash command to execute\"},\"timeout\":{\"type\":\"number\",\"description\":\"Timeout in seconds\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.\",\"name\":\"grep\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Search pattern (regex)\"},\"path\":{\"type\":\"string\",\"description\":\"Directory or file to search (default: .)\"},\"include\":{\"type\":\"string\",\"description\":\"Glob filter, e.g. \\\"*.ts\\\"\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Find files by filename pattern using shell find -name semantics. Returns matching file paths.\",\"name\":\"glob\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Filename pattern, e.g. \\\"*.ts\\\"\"},\"path\":{\"type\":\"string\",\"description\":\"Directory to search in (default: .)\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.\",\"name\":\"task\",\"parameters\":{\"type\":\"object\",\"required\":[\"prompt\"],\"properties\":{\"description\":{\"type\":\"string\",\"description\":\"Short human-readable label for the delegated work\"},\"prompt\":{\"type\":\"string\",\"description\":\"Focused instructions for the child agent\"},\"role\":{\"type\":\"string\",\"description\":\"Role to use for the child agent\"},\"cwd\":{\"type\":\"string\",\"description\":\"Working directory for the child agent. AGENTS.md and skills are discovered from here.\"}}},\"strict\":false}],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":{\"input_tokens\":772,\"input_tokens_details\":{\"cached_tokens\":0},\"output_tokens\":4,\"output_tokens_details\":{\"reasoning_tokens\":0},\"total_tokens\":776},\"user\":null,\"metadata\":{}},\"sequence_number\":9}" ], "kind": "sse" }, @@ -2216,12 +2366,12 @@ "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", "alt-svc": "h3=\":443\"; ma=86400", "cf-cache-status": "DYNAMIC", - "cf-ray": "9ff1a3e66ba04baf-VIE", + "cf-ray": "9ffa5ca18a7b325f-VIE", "connection": "keep-alive", "content-type": "text/event-stream; charset=utf-8", - "date": "Thu, 21 May 2026 06:49:16 GMT", + "date": "Fri, 22 May 2026 08:13:29 GMT", "openai-organization": "braintrust-data", - "openai-processing-ms": "113", + "openai-processing-ms": "100", "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", "openai-version": "2020-10-01", "server": "cloudflare", @@ -2229,7 +2379,7 @@ "strict-transport-security": "max-age=31536000; includeSubDomains; preload", "transfer-encoding": "chunked", "x-content-type-options": "nosniff", - "x-request-id": "req_02753ec51e9049688579854113b3c5a9" + "x-request-id": "req_34e75f7714614368ad57a8ab8c02e0c8" }, "status": 200, "statusText": "OK" @@ -2239,7 +2389,7 @@ "callIndex": 1, "id": "f12aff3913439248", "matchKey": "POST api.openai.com/v1/responses", - "recordedAt": "2026-05-21T06:49:18.520Z", + "recordedAt": "2026-05-22T08:13:33.761Z", "request": { "body": { "kind": "json", @@ -2252,7 +2402,7 @@ { "content": [ { - "text": "\n[User]: Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.\n\n[Assistant thinking]: The user wants me to complete a specific instrumented research flow with three steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id to call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url to call summarize_source\n4. Reply with exactly \"PROMPT_DONE\" after summarize_source returns\n\nThe user emphasizes calling exactly one tool per turn and waiting for each result. Let me start with step 1.\n\n[Assistant]: I'll complete this instrumented research flow step by step. Starting with Step 1:\n\n[Assistant tool calls]: lookup(query=\"flue instrumentation\")\n\n[Tool result]: {\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}\n\n[Assistant thinking]: Good, I got the lookup result with id \"flue-session-2026\". Now I'll proceed to step 2 and use this id as the lookupId parameter in the web_search call with the specified query.\n\n[Assistant]: Now proceeding to Step 2:\n\n[Assistant tool calls]: web_search(lookupId=\"flue-session-2026\", query=\"Braintrust Flue reasoning stream instrumentation\")\n\n[Tool result]: {\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\",\"results\":[{\"title\":\"Flue reasoning stream instrumentation\",\"url\":\"https://example.test/flue/reasoning-streams\"}]}\n\n[Assistant thinking]: Perfect! I got the web_search results. There's one result with the URL \"https://example.test/flue/reasoning-streams\". Now I need to proceed to step 3 and call summarize_source with this URL.\n\n[Assistant]: Now proceeding to Step 3:\n\n[Assistant tool calls]: summarize_source(url=\"https://example.test/flue/reasoning-streams\")\n\n[Tool result]: {\"summary\":\"Flue emits reasoning, tool execution, and LLM turn events separately.\",\"url\":\"https://example.test/flue/reasoning-streams\"}\n\n\nThis is the PREFIX of a turn that was too large to keep. The SUFFIX (recent work) is retained.\n\nSummarize the prefix to provide context for the retained suffix:\n\n## Original Request\n[What did the user ask for in this turn?]\n\n## Early Progress\n- [Key decisions and work done in the prefix]\n\n## Context for Suffix\n- [Information needed to understand the retained recent work]\n\nBe concise. Focus on what's needed to understand the kept suffix.", + "text": "\n[User]: Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.\n\n[Assistant thinking]: The user wants me to complete a specific instrumented research flow with these steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url and call summarize_source\n4. After summarize_source returns, reply with exactly \"PROMPT_DONE\" and no other text\n\nThe user emphasizes calling exactly one tool per turn and waiting for each result. Let me start with step 1.\n\n[Assistant]: I'll complete this instrumented research flow step by step. Starting with step 1:\n\n[Assistant tool calls]: lookup(query=\"flue instrumentation\")\n\n[Tool result]: {\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}\n\n[Assistant thinking]: Good, I got the lookup result with id \"flue-session-2026\". Now I need to proceed to step 2: call web_search with this lookupId and the query \"Braintrust Flue reasoning stream instrumentation\".\n\n[Assistant]: Now proceeding to step 2:\n\n[Assistant tool calls]: web_search(lookupId=\"flue-session-2026\", query=\"Braintrust Flue reasoning stream instrumentation\")\n\n[Tool result]: {\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\",\"results\":[{\"title\":\"Flue reasoning stream instrumentation\",\"url\":\"https://example.test/flue/reasoning-streams\"}]}\n\n[Assistant thinking]: Perfect! I got the web_search results. There's one result with the URL \"https://example.test/flue/reasoning-streams\". Now I need to proceed to step 3: call summarize_source with this URL.\n\n[Assistant]: Now proceeding to step 3:\n\n[Assistant tool calls]: summarize_source(url=\"https://example.test/flue/reasoning-streams\")\n\n[Tool result]: {\"summary\":\"Flue emits reasoning, tool execution, and LLM turn events separately.\",\"url\":\"https://example.test/flue/reasoning-streams\"}\n\n\nThis is the PREFIX of a turn that was too large to keep. The SUFFIX (recent work) is retained.\n\nSummarize the prefix to provide context for the retained suffix:\n\n## Original Request\n[What did the user ask for in this turn?]\n\n## Early Progress\n- [Key decisions and work done in the prefix]\n\n## Context for Suffix\n- [Information needed to understand the retained recent work]\n\nBe concise. Focus on what's needed to understand the kept suffix.", "type": "input_text" } ], @@ -2272,46 +2422,46 @@ "response": { "body": { "chunks": [ - "event: response.created\ndata: {\"type\":\"response.created\",\"response\":{\"id\":\"resp_059650b5d3870fbb016a0eaaed6b1c81a3b09f299be5949f66\",\"object\":\"response\",\"created_at\":1779346157,\"status\":\"in_progress\",\"background\":false,\"completed_at\":null,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":null,\"instructions\":null,\"max_output_tokens\":32,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":null,\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"auto\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":null,\"user\":null,\"metadata\":{}},\"sequence_number\":0}", - "event: response.in_progress\ndata: {\"type\":\"response.in_progress\",\"response\":{\"id\":\"resp_059650b5d3870fbb016a0eaaed6b1c81a3b09f299be5949f66\",\"object\":\"response\",\"created_at\":1779346157,\"status\":\"in_progress\",\"background\":false,\"completed_at\":null,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":null,\"instructions\":null,\"max_output_tokens\":32,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":null,\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"auto\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":null,\"user\":null,\"metadata\":{}},\"sequence_number\":1}", - "event: response.output_item.added\ndata: {\"type\":\"response.output_item.added\",\"item\":{\"id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"type\":\"message\",\"status\":\"in_progress\",\"content\":[],\"role\":\"assistant\"},\"output_index\":0,\"sequence_number\":2}", - "event: response.content_part.added\ndata: {\"type\":\"response.content_part.added\",\"content_index\":0,\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"output_index\":0,\"part\":{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"\"},\"sequence_number\":3}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"##\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"Gx1RR140b3nmJL\",\"output_index\":0,\"sequence_number\":4}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" Original\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"i6nbcXY\",\"output_index\":0,\"sequence_number\":5}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" Request\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"vSDcpK06\",\"output_index\":0,\"sequence_number\":6}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"\\n\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"hjszm5ObsMVJkTP\",\"output_index\":0,\"sequence_number\":7}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"The\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"agJz2xzIesCwJ\",\"output_index\":0,\"sequence_number\":8}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" user\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"9XQS29fCkws\",\"output_index\":0,\"sequence_number\":9}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" asked\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"njDxIRByDT\",\"output_index\":0,\"sequence_number\":10}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" to\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"AceYhCJ3kV1Uu\",\"output_index\":0,\"sequence_number\":11}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" complete\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"fUd6Jdo\",\"output_index\":0,\"sequence_number\":12}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" an\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"EAx4xF5lBjVb9\",\"output_index\":0,\"sequence_number\":13}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" instrument\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"XQP2H\",\"output_index\":0,\"sequence_number\":14}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"ed\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"Ywp2sXXXLqDZqn\",\"output_index\":0,\"sequence_number\":15}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" research\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"d8Mr1pV\",\"output_index\":0,\"sequence_number\":16}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" flow\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"20oSEoErG5e\",\"output_index\":0,\"sequence_number\":17}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" involving\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"dtt4Mm\",\"output_index\":0,\"sequence_number\":18}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" three\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"i5TEaWCQL5\",\"output_index\":0,\"sequence_number\":19}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" steps\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"BsofJH6d3j\",\"output_index\":0,\"sequence_number\":20}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\":\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"f4qnjYsPPBa3NkH\",\"output_index\":0,\"sequence_number\":21}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" calling\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"IyToLqWH\",\"output_index\":0,\"sequence_number\":22}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" a\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"XrSHPJJcskbkcn\",\"output_index\":0,\"sequence_number\":23}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" lookup\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"ouCoM5Kbc\",\"output_index\":0,\"sequence_number\":24}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" for\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"iDjkarnmFyYP\",\"output_index\":0,\"sequence_number\":25}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" \\\"\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"earEp7YaHZreUj\",\"output_index\":0,\"sequence_number\":26}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"fl\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"abHWveRt5Ly4mw\",\"output_index\":0,\"sequence_number\":27}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"ue\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"k2uewXc0pS32xH\",\"output_index\":0,\"sequence_number\":28}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" instrumentation\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"\",\"output_index\":0,\"sequence_number\":29}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"\\\",\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"m4823gb2EonmFG\",\"output_index\":0,\"sequence_number\":30}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" using\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"d7jC7AqvYZ\",\"output_index\":0,\"sequence_number\":31}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" the\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"Mvs3a27G5DtQ\",\"output_index\":0,\"sequence_number\":32}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" lookup\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"PcfTiAZFw\",\"output_index\":0,\"sequence_number\":33}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" result\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"s9rQaPiGV\",\"output_index\":0,\"sequence_number\":34}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" to\",\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"obfuscation\":\"ktTVhusNsXeOz\",\"output_index\":0,\"sequence_number\":35}", - "event: response.output_text.done\ndata: {\"type\":\"response.output_text.done\",\"content_index\":0,\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"logprobs\":[],\"output_index\":0,\"sequence_number\":36,\"text\":\"## Original Request\\nThe user asked to complete an instrumented research flow involving three steps: calling a lookup for \\\"flue instrumentation\\\", using the lookup result to\"}", - "event: response.content_part.done\ndata: {\"type\":\"response.content_part.done\",\"content_index\":0,\"item_id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"output_index\":0,\"part\":{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"## Original Request\\nThe user asked to complete an instrumented research flow involving three steps: calling a lookup for \\\"flue instrumentation\\\", using the lookup result to\"},\"sequence_number\":37}", - "event: response.output_item.done\ndata: {\"type\":\"response.output_item.done\",\"item\":{\"id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"type\":\"message\",\"status\":\"incomplete\",\"content\":[{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"## Original Request\\nThe user asked to complete an instrumented research flow involving three steps: calling a lookup for \\\"flue instrumentation\\\", using the lookup result to\"}],\"role\":\"assistant\"},\"output_index\":0,\"sequence_number\":38}", - "event: response.incomplete\ndata: {\"type\":\"response.incomplete\",\"response\":{\"id\":\"resp_059650b5d3870fbb016a0eaaed6b1c81a3b09f299be5949f66\",\"object\":\"response\",\"created_at\":1779346157,\"status\":\"incomplete\",\"background\":false,\"completed_at\":null,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":{\"reason\":\"max_output_tokens\"},\"instructions\":null,\"max_output_tokens\":32,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[{\"id\":\"msg_059650b5d3870fbb016a0eaaedce2881a3907a9d1ad86367c9\",\"type\":\"message\",\"status\":\"incomplete\",\"content\":[{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"## Original Request\\nThe user asked to complete an instrumented research flow involving three steps: calling a lookup for \\\"flue instrumentation\\\", using the lookup result to\"}],\"role\":\"assistant\"}],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":null,\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"default\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":{\"input_tokens\":687,\"input_tokens_details\":{\"cached_tokens\":0},\"output_tokens\":32,\"output_tokens_details\":{\"reasoning_tokens\":0},\"total_tokens\":719},\"user\":null,\"metadata\":{}},\"sequence_number\":39}" + "event: response.created\ndata: {\"type\":\"response.created\",\"response\":{\"id\":\"resp_0f13e60caaeaeacb016a10102c8f708192978116e1c09c1c36\",\"object\":\"response\",\"created_at\":1779437612,\"status\":\"in_progress\",\"background\":false,\"completed_at\":null,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":null,\"instructions\":null,\"max_output_tokens\":32,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":null,\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"auto\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":null,\"user\":null,\"metadata\":{}},\"sequence_number\":0}", + "event: response.in_progress\ndata: {\"type\":\"response.in_progress\",\"response\":{\"id\":\"resp_0f13e60caaeaeacb016a10102c8f708192978116e1c09c1c36\",\"object\":\"response\",\"created_at\":1779437612,\"status\":\"in_progress\",\"background\":false,\"completed_at\":null,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":null,\"instructions\":null,\"max_output_tokens\":32,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":null,\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"auto\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":null,\"user\":null,\"metadata\":{}},\"sequence_number\":1}", + "event: response.output_item.added\ndata: {\"type\":\"response.output_item.added\",\"item\":{\"id\":\"msg_0f13e60caaeaeacb016a10102d25e88192992dbed19f1be674\",\"type\":\"message\",\"status\":\"in_progress\",\"content\":[],\"role\":\"assistant\"},\"output_index\":0,\"sequence_number\":2}", + "event: response.content_part.added\ndata: {\"type\":\"response.content_part.added\",\"content_index\":0,\"item_id\":\"msg_0f13e60caaeaeacb016a10102d25e88192992dbed19f1be674\",\"output_index\":0,\"part\":{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"\"},\"sequence_number\":3}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"##\",\"item_id\":\"msg_0f13e60caaeaeacb016a10102d25e88192992dbed19f1be674\",\"logprobs\":[],\"obfuscation\":\"Zk5AP95xcgbrGq\",\"output_index\":0,\"sequence_number\":4}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" Original\",\"item_id\":\"msg_0f13e60caaeaeacb016a10102d25e88192992dbed19f1be674\",\"logprobs\":[],\"obfuscation\":\"JNmcRGZ\",\"output_index\":0,\"sequence_number\":5}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" Request\",\"item_id\":\"msg_0f13e60caaeaeacb016a10102d25e88192992dbed19f1be674\",\"logprobs\":[],\"obfuscation\":\"O7K5LBG6\",\"output_index\":0,\"sequence_number\":6}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"\\n\",\"item_id\":\"msg_0f13e60caaeaeacb016a10102d25e88192992dbed19f1be674\",\"logprobs\":[],\"obfuscation\":\"fPX8shnMg91RYfg\",\"output_index\":0,\"sequence_number\":7}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"The\",\"item_id\":\"msg_0f13e60caaeaeacb016a10102d25e88192992dbed19f1be674\",\"logprobs\":[],\"obfuscation\":\"jvcL8meen0c6o\",\"output_index\":0,\"sequence_number\":8}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" user\",\"item_id\":\"msg_0f13e60caaeaeacb016a10102d25e88192992dbed19f1be674\",\"logprobs\":[],\"obfuscation\":\"IizuQ41krNa\",\"output_index\":0,\"sequence_number\":9}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" asked\",\"item_id\":\"msg_0f13e60caaeaeacb016a10102d25e88192992dbed19f1be674\",\"logprobs\":[],\"obfuscation\":\"WDyPRAeBfW\",\"output_index\":0,\"sequence_number\":10}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" to\",\"item_id\":\"msg_0f13e60caaeaeacb016a10102d25e88192992dbed19f1be674\",\"logprobs\":[],\"obfuscation\":\"bpf69o4XuhkAp\",\"output_index\":0,\"sequence_number\":11}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" complete\",\"item_id\":\"msg_0f13e60caaeaeacb016a10102d25e88192992dbed19f1be674\",\"logprobs\":[],\"obfuscation\":\"rPuf3k4\",\"output_index\":0,\"sequence_number\":12}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" a\",\"item_id\":\"msg_0f13e60caaeaeacb016a10102d25e88192992dbed19f1be674\",\"logprobs\":[],\"obfuscation\":\"kYuPX1nF7hdhQ9\",\"output_index\":0,\"sequence_number\":13}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" step\",\"item_id\":\"msg_0f13e60caaeaeacb016a10102d25e88192992dbed19f1be674\",\"logprobs\":[],\"obfuscation\":\"PmeaAOmKg01\",\"output_index\":0,\"sequence_number\":14}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"-by\",\"item_id\":\"msg_0f13e60caaeaeacb016a10102d25e88192992dbed19f1be674\",\"logprobs\":[],\"obfuscation\":\"a7Th77M6ZkqdB\",\"output_index\":0,\"sequence_number\":15}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"-step\",\"item_id\":\"msg_0f13e60caaeaeacb016a10102d25e88192992dbed19f1be674\",\"logprobs\":[],\"obfuscation\":\"7TkDxFNqlk0\",\"output_index\":0,\"sequence_number\":16}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" instrument\",\"item_id\":\"msg_0f13e60caaeaeacb016a10102d25e88192992dbed19f1be674\",\"logprobs\":[],\"obfuscation\":\"4Mspa\",\"output_index\":0,\"sequence_number\":17}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"ed\",\"item_id\":\"msg_0f13e60caaeaeacb016a10102d25e88192992dbed19f1be674\",\"logprobs\":[],\"obfuscation\":\"HeGlAZhCYDVwdu\",\"output_index\":0,\"sequence_number\":18}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" research\",\"item_id\":\"msg_0f13e60caaeaeacb016a10102d25e88192992dbed19f1be674\",\"logprobs\":[],\"obfuscation\":\"YyNgo2g\",\"output_index\":0,\"sequence_number\":19}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" flow\",\"item_id\":\"msg_0f13e60caaeaeacb016a10102d25e88192992dbed19f1be674\",\"logprobs\":[],\"obfuscation\":\"jyMxpRIPzee\",\"output_index\":0,\"sequence_number\":20}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" involving\",\"item_id\":\"msg_0f13e60caaeaeacb016a10102d25e88192992dbed19f1be674\",\"logprobs\":[],\"obfuscation\":\"i8dhLo\",\"output_index\":0,\"sequence_number\":21}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" lookup\",\"item_id\":\"msg_0f13e60caaeaeacb016a10102d25e88192992dbed19f1be674\",\"logprobs\":[],\"obfuscation\":\"QCW8VTMVe\",\"output_index\":0,\"sequence_number\":22}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\",\",\"item_id\":\"msg_0f13e60caaeaeacb016a10102d25e88192992dbed19f1be674\",\"logprobs\":[],\"obfuscation\":\"SeZZTXzqYNq9c4A\",\"output_index\":0,\"sequence_number\":23}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" web\",\"item_id\":\"msg_0f13e60caaeaeacb016a10102d25e88192992dbed19f1be674\",\"logprobs\":[],\"obfuscation\":\"3QdpjI62mx20\",\"output_index\":0,\"sequence_number\":24}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" search\",\"item_id\":\"msg_0f13e60caaeaeacb016a10102d25e88192992dbed19f1be674\",\"logprobs\":[],\"obfuscation\":\"y3dJPx6HJ\",\"output_index\":0,\"sequence_number\":25}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\",\",\"item_id\":\"msg_0f13e60caaeaeacb016a10102d25e88192992dbed19f1be674\",\"logprobs\":[],\"obfuscation\":\"izeNndQAHqG88Pp\",\"output_index\":0,\"sequence_number\":26}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" and\",\"item_id\":\"msg_0f13e60caaeaeacb016a10102d25e88192992dbed19f1be674\",\"logprobs\":[],\"obfuscation\":\"t9sZc5kj0STX\",\"output_index\":0,\"sequence_number\":27}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" summar\",\"item_id\":\"msg_0f13e60caaeaeacb016a10102d25e88192992dbed19f1be674\",\"logprobs\":[],\"obfuscation\":\"udbTkclSA\",\"output_index\":0,\"sequence_number\":28}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"ization\",\"item_id\":\"msg_0f13e60caaeaeacb016a10102d25e88192992dbed19f1be674\",\"logprobs\":[],\"obfuscation\":\"IHcrLKrJv\",\"output_index\":0,\"sequence_number\":29}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\",\",\"item_id\":\"msg_0f13e60caaeaeacb016a10102d25e88192992dbed19f1be674\",\"logprobs\":[],\"obfuscation\":\"7nRT45jNwn0jJ2o\",\"output_index\":0,\"sequence_number\":30}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" with\",\"item_id\":\"msg_0f13e60caaeaeacb016a10102d25e88192992dbed19f1be674\",\"logprobs\":[],\"obfuscation\":\"NMmxDIFt2A0\",\"output_index\":0,\"sequence_number\":31}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" specific\",\"item_id\":\"msg_0f13e60caaeaeacb016a10102d25e88192992dbed19f1be674\",\"logprobs\":[],\"obfuscation\":\"3bSfcsA\",\"output_index\":0,\"sequence_number\":32}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" instructions\",\"item_id\":\"msg_0f13e60caaeaeacb016a10102d25e88192992dbed19f1be674\",\"logprobs\":[],\"obfuscation\":\"atz\",\"output_index\":0,\"sequence_number\":33}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" to\",\"item_id\":\"msg_0f13e60caaeaeacb016a10102d25e88192992dbed19f1be674\",\"logprobs\":[],\"obfuscation\":\"ConWkiFhiR8RW\",\"output_index\":0,\"sequence_number\":34}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" call\",\"item_id\":\"msg_0f13e60caaeaeacb016a10102d25e88192992dbed19f1be674\",\"logprobs\":[],\"obfuscation\":\"YPgRMyQB0QX\",\"output_index\":0,\"sequence_number\":35}", + "event: response.output_text.done\ndata: {\"type\":\"response.output_text.done\",\"content_index\":0,\"item_id\":\"msg_0f13e60caaeaeacb016a10102d25e88192992dbed19f1be674\",\"logprobs\":[],\"output_index\":0,\"sequence_number\":36,\"text\":\"## Original Request\\nThe user asked to complete a step-by-step instrumented research flow involving lookup, web search, and summarization, with specific instructions to call\"}", + "event: response.content_part.done\ndata: {\"type\":\"response.content_part.done\",\"content_index\":0,\"item_id\":\"msg_0f13e60caaeaeacb016a10102d25e88192992dbed19f1be674\",\"output_index\":0,\"part\":{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"## Original Request\\nThe user asked to complete a step-by-step instrumented research flow involving lookup, web search, and summarization, with specific instructions to call\"},\"sequence_number\":37}", + "event: response.output_item.done\ndata: {\"type\":\"response.output_item.done\",\"item\":{\"id\":\"msg_0f13e60caaeaeacb016a10102d25e88192992dbed19f1be674\",\"type\":\"message\",\"status\":\"incomplete\",\"content\":[{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"## Original Request\\nThe user asked to complete a step-by-step instrumented research flow involving lookup, web search, and summarization, with specific instructions to call\"}],\"role\":\"assistant\"},\"output_index\":0,\"sequence_number\":38}", + "event: response.incomplete\ndata: {\"type\":\"response.incomplete\",\"response\":{\"id\":\"resp_0f13e60caaeaeacb016a10102c8f708192978116e1c09c1c36\",\"object\":\"response\",\"created_at\":1779437612,\"status\":\"incomplete\",\"background\":false,\"completed_at\":null,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":{\"reason\":\"max_output_tokens\"},\"instructions\":null,\"max_output_tokens\":32,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[{\"id\":\"msg_0f13e60caaeaeacb016a10102d25e88192992dbed19f1be674\",\"type\":\"message\",\"status\":\"incomplete\",\"content\":[{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"## Original Request\\nThe user asked to complete a step-by-step instrumented research flow involving lookup, web search, and summarization, with specific instructions to call\"}],\"role\":\"assistant\"}],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":null,\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"default\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":{\"input_tokens\":698,\"input_tokens_details\":{\"cached_tokens\":0},\"output_tokens\":32,\"output_tokens_details\":{\"reasoning_tokens\":0},\"total_tokens\":730},\"user\":null,\"metadata\":{}},\"sequence_number\":39}" ], "kind": "sse" }, @@ -2319,12 +2469,12 @@ "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", "alt-svc": "h3=\":443\"; ma=86400", "cf-cache-status": "DYNAMIC", - "cf-ray": "9ff1a3eb491c4baf-VIE", + "cf-ray": "9ffa5ca999d4325f-VIE", "connection": "keep-alive", "content-type": "text/event-stream; charset=utf-8", - "date": "Thu, 21 May 2026 06:49:17 GMT", + "date": "Fri, 22 May 2026 08:13:32 GMT", "openai-organization": "braintrust-data", - "openai-processing-ms": "115", + "openai-processing-ms": "232", "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", "openai-version": "2020-10-01", "server": "cloudflare", @@ -2332,7 +2482,7 @@ "strict-transport-security": "max-age=31536000; includeSubDomains; preload", "transfer-encoding": "chunked", "x-content-type-options": "nosniff", - "x-request-id": "req_b92f207d3e4647da98518cc8147b231c" + "x-request-id": "req_16e0d0181a854084b110ca11cb77b277" }, "status": 200, "statusText": "OK" diff --git a/e2e/scenarios/flue-instrumentation/__cassettes__/flue-v0-7-0-openai-auto-hook.cassette.json b/e2e/scenarios/flue-instrumentation/__cassettes__/flue-v0-7-0-openai-auto-hook.cassette.json new file mode 100644 index 000000000..e8666bdc4 --- /dev/null +++ b/e2e/scenarios/flue-instrumentation/__cassettes__/flue-v0-7-0-openai-auto-hook.cassette.json @@ -0,0 +1,2292 @@ +{ + "entries": [ + { + "callIndex": 0, + "id": "7c0e162d6794cf5d", + "matchKey": "POST api.openai.com/v1/responses", + "recordedAt": "2026-05-22T08:13:35.865Z", + "request": { + "body": { + "kind": "json", + "value": { + "input": [ + { + "content": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-HpI3r1/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + "role": "system" + }, + { + "content": [ + { + "text": "Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.", + "type": "input_text" + } + ], + "role": "user" + } + ], + "model": "gpt-4o-mini", + "prompt_cache_key": "[REDACTED]", + "store": false, + "stream": true, + "tools": [ + { + "description": "Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.", + "name": "read", + "parameters": { + "properties": { + "limit": { + "description": "Maximum number of lines to read", + "type": "number" + }, + "offset": { + "description": "Line number to start from (1-indexed)", + "type": "number" + }, + "path": { + "description": "Path to the file to read", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Write content to a file. Creates the file and parent directories if they do not exist.", + "name": "write", + "parameters": { + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Path to the file to write", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.", + "name": "edit", + "parameters": { + "properties": { + "newText": { + "description": "Replacement text", + "type": "string" + }, + "oldText": { + "description": "Exact text to find (must be unique)", + "type": "string" + }, + "path": { + "description": "Path to the file to edit", + "type": "string" + }, + "replaceAll": { + "description": "Replace all occurrences", + "type": "boolean" + } + }, + "required": [ + "path", + "oldText", + "newText" + ], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.", + "name": "bash", + "parameters": { + "properties": { + "command": { + "description": "Bash command to execute", + "type": "string" + }, + "timeout": { + "description": "Timeout in seconds", + "type": "number" + } + }, + "required": [ + "command" + ], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.", + "name": "grep", + "parameters": { + "properties": { + "include": { + "description": "Glob filter, e.g. \"*.ts\"", + "type": "string" + }, + "path": { + "description": "Directory or file to search (default: .)", + "type": "string" + }, + "pattern": { + "description": "Search pattern (regex)", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Find files by filename pattern using shell find -name semantics. Returns matching file paths.", + "name": "glob", + "parameters": { + "properties": { + "path": { + "description": "Directory to search in (default: .)", + "type": "string" + }, + "pattern": { + "description": "Filename pattern, e.g. \"*.ts\"", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.", + "name": "task", + "parameters": { + "properties": { + "cwd": { + "description": "Working directory for the child agent. AGENTS.md and skills are discovered from here.", + "type": "string" + }, + "description": { + "description": "Short human-readable label for the delegated work", + "type": "string" + }, + "prompt": { + "description": "Focused instructions for the child agent", + "type": "string" + }, + "role": { + "description": "Role to use for the child agent", + "type": "string" + } + }, + "required": [ + "prompt" + ], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Return a deterministic lookup result with an id needed by web_search.", + "name": "lookup", + "parameters": { + "properties": { + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Search a deterministic local web index. Requires the id returned by lookup.", + "name": "web_search", + "parameters": { + "properties": { + "lookupId": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "lookupId", + "query" + ], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Summarize the selected deterministic source after web_search returns a URL.", + "name": "summarize_source", + "parameters": { + "properties": { + "url": { + "type": "string" + } + }, + "required": [ + "url" + ], + "type": "object" + }, + "strict": false, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/responses" + }, + "response": { + "body": { + "chunks": [ + "event: response.created\ndata: {\"type\":\"response.created\",\"response\":{\"id\":\"resp_0a9628fdef0a9b50016a10102ef6ec8190aea42c9384815417\",\"object\":\"response\",\"created_at\":1779437614,\"status\":\"in_progress\",\"background\":false,\"completed_at\":null,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":null,\"instructions\":null,\"max_output_tokens\":null,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":\"flue-e2e-instance::default::main\",\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"auto\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[{\"type\":\"function\",\"description\":\"Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.\",\"name\":\"read\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to read\"},\"offset\":{\"type\":\"number\",\"description\":\"Line number to start from (1-indexed)\"},\"limit\":{\"type\":\"number\",\"description\":\"Maximum number of lines to read\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Write content to a file. Creates the file and parent directories if they do not exist.\",\"name\":\"write\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"content\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to write\"},\"content\":{\"type\":\"string\",\"description\":\"Content to write to the file\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.\",\"name\":\"edit\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"oldText\",\"newText\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to edit\"},\"oldText\":{\"type\":\"string\",\"description\":\"Exact text to find (must be unique)\"},\"newText\":{\"type\":\"string\",\"description\":\"Replacement text\"},\"replaceAll\":{\"type\":\"boolean\",\"description\":\"Replace all occurrences\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.\",\"name\":\"bash\",\"parameters\":{\"type\":\"object\",\"required\":[\"command\"],\"properties\":{\"command\":{\"type\":\"string\",\"description\":\"Bash command to execute\"},\"timeout\":{\"type\":\"number\",\"description\":\"Timeout in seconds\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.\",\"name\":\"grep\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Search pattern (regex)\"},\"path\":{\"type\":\"string\",\"description\":\"Directory or file to search (default: .)\"},\"include\":{\"type\":\"string\",\"description\":\"Glob filter, e.g. \\\"*.ts\\\"\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Find files by filename pattern using shell find -name semantics. Returns matching file paths.\",\"name\":\"glob\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Filename pattern, e.g. \\\"*.ts\\\"\"},\"path\":{\"type\":\"string\",\"description\":\"Directory to search in (default: .)\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.\",\"name\":\"task\",\"parameters\":{\"type\":\"object\",\"required\":[\"prompt\"],\"properties\":{\"description\":{\"type\":\"string\",\"description\":\"Short human-readable label for the delegated work\"},\"prompt\":{\"type\":\"string\",\"description\":\"Focused instructions for the child agent\"},\"role\":{\"type\":\"string\",\"description\":\"Role to use for the child agent\"},\"cwd\":{\"type\":\"string\",\"description\":\"Working directory for the child agent. AGENTS.md and skills are discovered from here.\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Return a deterministic lookup result with an id needed by web_search.\",\"name\":\"lookup\",\"parameters\":{\"type\":\"object\",\"required\":[\"query\"],\"properties\":{\"query\":{\"type\":\"string\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Search a deterministic local web index. Requires the id returned by lookup.\",\"name\":\"web_search\",\"parameters\":{\"type\":\"object\",\"required\":[\"lookupId\",\"query\"],\"properties\":{\"lookupId\":{\"type\":\"string\"},\"query\":{\"type\":\"string\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Summarize the selected deterministic source after web_search returns a URL.\",\"name\":\"summarize_source\",\"parameters\":{\"type\":\"object\",\"required\":[\"url\"],\"properties\":{\"url\":{\"type\":\"string\"}}},\"strict\":false}],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":null,\"user\":null,\"metadata\":{}},\"sequence_number\":0}", + "event: response.in_progress\ndata: {\"type\":\"response.in_progress\",\"response\":{\"id\":\"resp_0a9628fdef0a9b50016a10102ef6ec8190aea42c9384815417\",\"object\":\"response\",\"created_at\":1779437614,\"status\":\"in_progress\",\"background\":false,\"completed_at\":null,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":null,\"instructions\":null,\"max_output_tokens\":null,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":\"flue-e2e-instance::default::main\",\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"auto\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[{\"type\":\"function\",\"description\":\"Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.\",\"name\":\"read\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to read\"},\"offset\":{\"type\":\"number\",\"description\":\"Line number to start from (1-indexed)\"},\"limit\":{\"type\":\"number\",\"description\":\"Maximum number of lines to read\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Write content to a file. Creates the file and parent directories if they do not exist.\",\"name\":\"write\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"content\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to write\"},\"content\":{\"type\":\"string\",\"description\":\"Content to write to the file\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.\",\"name\":\"edit\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"oldText\",\"newText\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to edit\"},\"oldText\":{\"type\":\"string\",\"description\":\"Exact text to find (must be unique)\"},\"newText\":{\"type\":\"string\",\"description\":\"Replacement text\"},\"replaceAll\":{\"type\":\"boolean\",\"description\":\"Replace all occurrences\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.\",\"name\":\"bash\",\"parameters\":{\"type\":\"object\",\"required\":[\"command\"],\"properties\":{\"command\":{\"type\":\"string\",\"description\":\"Bash command to execute\"},\"timeout\":{\"type\":\"number\",\"description\":\"Timeout in seconds\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.\",\"name\":\"grep\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Search pattern (regex)\"},\"path\":{\"type\":\"string\",\"description\":\"Directory or file to search (default: .)\"},\"include\":{\"type\":\"string\",\"description\":\"Glob filter, e.g. \\\"*.ts\\\"\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Find files by filename pattern using shell find -name semantics. Returns matching file paths.\",\"name\":\"glob\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Filename pattern, e.g. \\\"*.ts\\\"\"},\"path\":{\"type\":\"string\",\"description\":\"Directory to search in (default: .)\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.\",\"name\":\"task\",\"parameters\":{\"type\":\"object\",\"required\":[\"prompt\"],\"properties\":{\"description\":{\"type\":\"string\",\"description\":\"Short human-readable label for the delegated work\"},\"prompt\":{\"type\":\"string\",\"description\":\"Focused instructions for the child agent\"},\"role\":{\"type\":\"string\",\"description\":\"Role to use for the child agent\"},\"cwd\":{\"type\":\"string\",\"description\":\"Working directory for the child agent. AGENTS.md and skills are discovered from here.\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Return a deterministic lookup result with an id needed by web_search.\",\"name\":\"lookup\",\"parameters\":{\"type\":\"object\",\"required\":[\"query\"],\"properties\":{\"query\":{\"type\":\"string\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Search a deterministic local web index. Requires the id returned by lookup.\",\"name\":\"web_search\",\"parameters\":{\"type\":\"object\",\"required\":[\"lookupId\",\"query\"],\"properties\":{\"lookupId\":{\"type\":\"string\"},\"query\":{\"type\":\"string\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Summarize the selected deterministic source after web_search returns a URL.\",\"name\":\"summarize_source\",\"parameters\":{\"type\":\"object\",\"required\":[\"url\"],\"properties\":{\"url\":{\"type\":\"string\"}}},\"strict\":false}],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":null,\"user\":null,\"metadata\":{}},\"sequence_number\":1}", + "event: response.output_item.added\ndata: {\"type\":\"response.output_item.added\",\"item\":{\"id\":\"fc_0a9628fdef0a9b50016a10102fa3308190bfb69b9815d024ea\",\"type\":\"function_call\",\"status\":\"in_progress\",\"arguments\":\"\",\"call_id\":\"call_xELft1kjhTSvPWAp3Z3i4zWk\",\"name\":\"lookup\"},\"output_index\":0,\"sequence_number\":2}", + "event: response.function_call_arguments.delta\ndata: {\"type\":\"response.function_call_arguments.delta\",\"delta\":\"{\\\"\",\"item_id\":\"fc_0a9628fdef0a9b50016a10102fa3308190bfb69b9815d024ea\",\"obfuscation\":\"kdHmbne8Odsv0r\",\"output_index\":0,\"sequence_number\":3}", + "event: response.function_call_arguments.delta\ndata: {\"type\":\"response.function_call_arguments.delta\",\"delta\":\"query\",\"item_id\":\"fc_0a9628fdef0a9b50016a10102fa3308190bfb69b9815d024ea\",\"obfuscation\":\"cakQ2rzCmLJ\",\"output_index\":0,\"sequence_number\":4}", + "event: response.function_call_arguments.delta\ndata: {\"type\":\"response.function_call_arguments.delta\",\"delta\":\"\\\":\\\"\",\"item_id\":\"fc_0a9628fdef0a9b50016a10102fa3308190bfb69b9815d024ea\",\"obfuscation\":\"N775rFu16y6Ut\",\"output_index\":0,\"sequence_number\":5}", + "event: response.function_call_arguments.delta\ndata: {\"type\":\"response.function_call_arguments.delta\",\"delta\":\"fl\",\"item_id\":\"fc_0a9628fdef0a9b50016a10102fa3308190bfb69b9815d024ea\",\"obfuscation\":\"zewsf7KenGBc5O\",\"output_index\":0,\"sequence_number\":6}", + "event: response.function_call_arguments.delta\ndata: {\"type\":\"response.function_call_arguments.delta\",\"delta\":\"ue\",\"item_id\":\"fc_0a9628fdef0a9b50016a10102fa3308190bfb69b9815d024ea\",\"obfuscation\":\"kUL7Os9Ms5z87q\",\"output_index\":0,\"sequence_number\":7}", + "event: response.function_call_arguments.delta\ndata: {\"type\":\"response.function_call_arguments.delta\",\"delta\":\" instrumentation\",\"item_id\":\"fc_0a9628fdef0a9b50016a10102fa3308190bfb69b9815d024ea\",\"obfuscation\":\"\",\"output_index\":0,\"sequence_number\":8}", + "event: response.function_call_arguments.delta\ndata: {\"type\":\"response.function_call_arguments.delta\",\"delta\":\"\\\"}\",\"item_id\":\"fc_0a9628fdef0a9b50016a10102fa3308190bfb69b9815d024ea\",\"obfuscation\":\"WQCLmfqjC6qVKE\",\"output_index\":0,\"sequence_number\":9}", + "event: response.function_call_arguments.done\ndata: {\"type\":\"response.function_call_arguments.done\",\"arguments\":\"{\\\"query\\\":\\\"flue instrumentation\\\"}\",\"item_id\":\"fc_0a9628fdef0a9b50016a10102fa3308190bfb69b9815d024ea\",\"output_index\":0,\"sequence_number\":10}", + "event: response.output_item.done\ndata: {\"type\":\"response.output_item.done\",\"item\":{\"id\":\"fc_0a9628fdef0a9b50016a10102fa3308190bfb69b9815d024ea\",\"type\":\"function_call\",\"status\":\"completed\",\"arguments\":\"{\\\"query\\\":\\\"flue instrumentation\\\"}\",\"call_id\":\"call_xELft1kjhTSvPWAp3Z3i4zWk\",\"name\":\"lookup\"},\"output_index\":0,\"sequence_number\":11}", + "event: response.completed\ndata: {\"type\":\"response.completed\",\"response\":{\"id\":\"resp_0a9628fdef0a9b50016a10102ef6ec8190aea42c9384815417\",\"object\":\"response\",\"created_at\":1779437614,\"status\":\"completed\",\"background\":false,\"completed_at\":1779437615,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":null,\"instructions\":null,\"max_output_tokens\":null,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[{\"id\":\"fc_0a9628fdef0a9b50016a10102fa3308190bfb69b9815d024ea\",\"type\":\"function_call\",\"status\":\"completed\",\"arguments\":\"{\\\"query\\\":\\\"flue instrumentation\\\"}\",\"call_id\":\"call_xELft1kjhTSvPWAp3Z3i4zWk\",\"name\":\"lookup\"}],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":\"flue-e2e-instance::default::main\",\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"default\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[{\"type\":\"function\",\"description\":\"Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.\",\"name\":\"read\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to read\"},\"offset\":{\"type\":\"number\",\"description\":\"Line number to start from (1-indexed)\"},\"limit\":{\"type\":\"number\",\"description\":\"Maximum number of lines to read\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Write content to a file. Creates the file and parent directories if they do not exist.\",\"name\":\"write\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"content\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to write\"},\"content\":{\"type\":\"string\",\"description\":\"Content to write to the file\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.\",\"name\":\"edit\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"oldText\",\"newText\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to edit\"},\"oldText\":{\"type\":\"string\",\"description\":\"Exact text to find (must be unique)\"},\"newText\":{\"type\":\"string\",\"description\":\"Replacement text\"},\"replaceAll\":{\"type\":\"boolean\",\"description\":\"Replace all occurrences\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.\",\"name\":\"bash\",\"parameters\":{\"type\":\"object\",\"required\":[\"command\"],\"properties\":{\"command\":{\"type\":\"string\",\"description\":\"Bash command to execute\"},\"timeout\":{\"type\":\"number\",\"description\":\"Timeout in seconds\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.\",\"name\":\"grep\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Search pattern (regex)\"},\"path\":{\"type\":\"string\",\"description\":\"Directory or file to search (default: .)\"},\"include\":{\"type\":\"string\",\"description\":\"Glob filter, e.g. \\\"*.ts\\\"\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Find files by filename pattern using shell find -name semantics. Returns matching file paths.\",\"name\":\"glob\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Filename pattern, e.g. \\\"*.ts\\\"\"},\"path\":{\"type\":\"string\",\"description\":\"Directory to search in (default: .)\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.\",\"name\":\"task\",\"parameters\":{\"type\":\"object\",\"required\":[\"prompt\"],\"properties\":{\"description\":{\"type\":\"string\",\"description\":\"Short human-readable label for the delegated work\"},\"prompt\":{\"type\":\"string\",\"description\":\"Focused instructions for the child agent\"},\"role\":{\"type\":\"string\",\"description\":\"Role to use for the child agent\"},\"cwd\":{\"type\":\"string\",\"description\":\"Working directory for the child agent. AGENTS.md and skills are discovered from here.\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Return a deterministic lookup result with an id needed by web_search.\",\"name\":\"lookup\",\"parameters\":{\"type\":\"object\",\"required\":[\"query\"],\"properties\":{\"query\":{\"type\":\"string\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Search a deterministic local web index. Requires the id returned by lookup.\",\"name\":\"web_search\",\"parameters\":{\"type\":\"object\",\"required\":[\"lookupId\",\"query\"],\"properties\":{\"lookupId\":{\"type\":\"string\"},\"query\":{\"type\":\"string\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Summarize the selected deterministic source after web_search returns a URL.\",\"name\":\"summarize_source\",\"parameters\":{\"type\":\"object\",\"required\":[\"url\"],\"properties\":{\"url\":{\"type\":\"string\"}}},\"strict\":false}],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":{\"input_tokens\":946,\"input_tokens_details\":{\"cached_tokens\":0},\"output_tokens\":16,\"output_tokens_details\":{\"reasoning_tokens\":0},\"total_tokens\":962},\"user\":null,\"metadata\":{}},\"sequence_number\":12}" + ], + "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": "9ffa5cc4dc2f325f-VIE", + "connection": "keep-alive", + "content-type": "text/event-stream; charset=utf-8", + "date": "Fri, 22 May 2026 08:13:35 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "195", + "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-request-id": "req_d8c4fb03ab4a4920a732debcff08914b" + }, + "status": 200, + "statusText": "OK" + } + }, + { + "callIndex": 1, + "id": "f12aff3913439248", + "matchKey": "POST api.openai.com/v1/responses", + "recordedAt": "2026-05-22T08:13:36.926Z", + "request": { + "body": { + "kind": "json", + "value": { + "input": [ + { + "content": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-HpI3r1/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + "role": "system" + }, + { + "content": [ + { + "text": "Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.", + "type": "input_text" + } + ], + "role": "user" + }, + { + "arguments": "{\"query\":\"flue instrumentation\"}", + "call_id": "call_xELft1kjhTSvPWAp3Z3i4zWk", + "id": "fc_0a9628fdef0a9b50016a10102fa3308190bfb69b9815d024ea", + "name": "lookup", + "type": "function_call" + }, + { + "call_id": "call_xELft1kjhTSvPWAp3Z3i4zWk", + "output": "{\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}", + "type": "function_call_output" + } + ], + "model": "gpt-4o-mini", + "prompt_cache_key": "[REDACTED]", + "store": false, + "stream": true, + "tools": [ + { + "description": "Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.", + "name": "read", + "parameters": { + "properties": { + "limit": { + "description": "Maximum number of lines to read", + "type": "number" + }, + "offset": { + "description": "Line number to start from (1-indexed)", + "type": "number" + }, + "path": { + "description": "Path to the file to read", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Write content to a file. Creates the file and parent directories if they do not exist.", + "name": "write", + "parameters": { + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Path to the file to write", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.", + "name": "edit", + "parameters": { + "properties": { + "newText": { + "description": "Replacement text", + "type": "string" + }, + "oldText": { + "description": "Exact text to find (must be unique)", + "type": "string" + }, + "path": { + "description": "Path to the file to edit", + "type": "string" + }, + "replaceAll": { + "description": "Replace all occurrences", + "type": "boolean" + } + }, + "required": [ + "path", + "oldText", + "newText" + ], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.", + "name": "bash", + "parameters": { + "properties": { + "command": { + "description": "Bash command to execute", + "type": "string" + }, + "timeout": { + "description": "Timeout in seconds", + "type": "number" + } + }, + "required": [ + "command" + ], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.", + "name": "grep", + "parameters": { + "properties": { + "include": { + "description": "Glob filter, e.g. \"*.ts\"", + "type": "string" + }, + "path": { + "description": "Directory or file to search (default: .)", + "type": "string" + }, + "pattern": { + "description": "Search pattern (regex)", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Find files by filename pattern using shell find -name semantics. Returns matching file paths.", + "name": "glob", + "parameters": { + "properties": { + "path": { + "description": "Directory to search in (default: .)", + "type": "string" + }, + "pattern": { + "description": "Filename pattern, e.g. \"*.ts\"", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.", + "name": "task", + "parameters": { + "properties": { + "cwd": { + "description": "Working directory for the child agent. AGENTS.md and skills are discovered from here.", + "type": "string" + }, + "description": { + "description": "Short human-readable label for the delegated work", + "type": "string" + }, + "prompt": { + "description": "Focused instructions for the child agent", + "type": "string" + }, + "role": { + "description": "Role to use for the child agent", + "type": "string" + } + }, + "required": [ + "prompt" + ], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Return a deterministic lookup result with an id needed by web_search.", + "name": "lookup", + "parameters": { + "properties": { + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Search a deterministic local web index. Requires the id returned by lookup.", + "name": "web_search", + "parameters": { + "properties": { + "lookupId": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "lookupId", + "query" + ], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Summarize the selected deterministic source after web_search returns a URL.", + "name": "summarize_source", + "parameters": { + "properties": { + "url": { + "type": "string" + } + }, + "required": [ + "url" + ], + "type": "object" + }, + "strict": false, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/responses" + }, + "response": { + "body": { + "chunks": [ + "event: response.created\ndata: {\"type\":\"response.created\",\"response\":{\"id\":\"resp_0a9628fdef0a9b50016a1010300e24819095d12ec72332326f\",\"object\":\"response\",\"created_at\":1779437616,\"status\":\"in_progress\",\"background\":false,\"completed_at\":null,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":null,\"instructions\":null,\"max_output_tokens\":null,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":\"flue-e2e-instance::default::main\",\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"auto\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[{\"type\":\"function\",\"description\":\"Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.\",\"name\":\"read\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to read\"},\"offset\":{\"type\":\"number\",\"description\":\"Line number to start from (1-indexed)\"},\"limit\":{\"type\":\"number\",\"description\":\"Maximum number of lines to read\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Write content to a file. Creates the file and parent directories if they do not exist.\",\"name\":\"write\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"content\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to write\"},\"content\":{\"type\":\"string\",\"description\":\"Content to write to the file\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.\",\"name\":\"edit\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"oldText\",\"newText\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to edit\"},\"oldText\":{\"type\":\"string\",\"description\":\"Exact text to find (must be unique)\"},\"newText\":{\"type\":\"string\",\"description\":\"Replacement text\"},\"replaceAll\":{\"type\":\"boolean\",\"description\":\"Replace all occurrences\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.\",\"name\":\"bash\",\"parameters\":{\"type\":\"object\",\"required\":[\"command\"],\"properties\":{\"command\":{\"type\":\"string\",\"description\":\"Bash command to execute\"},\"timeout\":{\"type\":\"number\",\"description\":\"Timeout in seconds\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.\",\"name\":\"grep\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Search pattern (regex)\"},\"path\":{\"type\":\"string\",\"description\":\"Directory or file to search (default: .)\"},\"include\":{\"type\":\"string\",\"description\":\"Glob filter, e.g. \\\"*.ts\\\"\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Find files by filename pattern using shell find -name semantics. Returns matching file paths.\",\"name\":\"glob\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Filename pattern, e.g. \\\"*.ts\\\"\"},\"path\":{\"type\":\"string\",\"description\":\"Directory to search in (default: .)\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.\",\"name\":\"task\",\"parameters\":{\"type\":\"object\",\"required\":[\"prompt\"],\"properties\":{\"description\":{\"type\":\"string\",\"description\":\"Short human-readable label for the delegated work\"},\"prompt\":{\"type\":\"string\",\"description\":\"Focused instructions for the child agent\"},\"role\":{\"type\":\"string\",\"description\":\"Role to use for the child agent\"},\"cwd\":{\"type\":\"string\",\"description\":\"Working directory for the child agent. AGENTS.md and skills are discovered from here.\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Return a deterministic lookup result with an id needed by web_search.\",\"name\":\"lookup\",\"parameters\":{\"type\":\"object\",\"required\":[\"query\"],\"properties\":{\"query\":{\"type\":\"string\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Search a deterministic local web index. Requires the id returned by lookup.\",\"name\":\"web_search\",\"parameters\":{\"type\":\"object\",\"required\":[\"lookupId\",\"query\"],\"properties\":{\"lookupId\":{\"type\":\"string\"},\"query\":{\"type\":\"string\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Summarize the selected deterministic source after web_search returns a URL.\",\"name\":\"summarize_source\",\"parameters\":{\"type\":\"object\",\"required\":[\"url\"],\"properties\":{\"url\":{\"type\":\"string\"}}},\"strict\":false}],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":null,\"user\":null,\"metadata\":{}},\"sequence_number\":0}", + "event: response.in_progress\ndata: {\"type\":\"response.in_progress\",\"response\":{\"id\":\"resp_0a9628fdef0a9b50016a1010300e24819095d12ec72332326f\",\"object\":\"response\",\"created_at\":1779437616,\"status\":\"in_progress\",\"background\":false,\"completed_at\":null,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":null,\"instructions\":null,\"max_output_tokens\":null,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":\"flue-e2e-instance::default::main\",\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"auto\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[{\"type\":\"function\",\"description\":\"Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.\",\"name\":\"read\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to read\"},\"offset\":{\"type\":\"number\",\"description\":\"Line number to start from (1-indexed)\"},\"limit\":{\"type\":\"number\",\"description\":\"Maximum number of lines to read\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Write content to a file. Creates the file and parent directories if they do not exist.\",\"name\":\"write\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"content\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to write\"},\"content\":{\"type\":\"string\",\"description\":\"Content to write to the file\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.\",\"name\":\"edit\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"oldText\",\"newText\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to edit\"},\"oldText\":{\"type\":\"string\",\"description\":\"Exact text to find (must be unique)\"},\"newText\":{\"type\":\"string\",\"description\":\"Replacement text\"},\"replaceAll\":{\"type\":\"boolean\",\"description\":\"Replace all occurrences\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.\",\"name\":\"bash\",\"parameters\":{\"type\":\"object\",\"required\":[\"command\"],\"properties\":{\"command\":{\"type\":\"string\",\"description\":\"Bash command to execute\"},\"timeout\":{\"type\":\"number\",\"description\":\"Timeout in seconds\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.\",\"name\":\"grep\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Search pattern (regex)\"},\"path\":{\"type\":\"string\",\"description\":\"Directory or file to search (default: .)\"},\"include\":{\"type\":\"string\",\"description\":\"Glob filter, e.g. \\\"*.ts\\\"\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Find files by filename pattern using shell find -name semantics. Returns matching file paths.\",\"name\":\"glob\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Filename pattern, e.g. \\\"*.ts\\\"\"},\"path\":{\"type\":\"string\",\"description\":\"Directory to search in (default: .)\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.\",\"name\":\"task\",\"parameters\":{\"type\":\"object\",\"required\":[\"prompt\"],\"properties\":{\"description\":{\"type\":\"string\",\"description\":\"Short human-readable label for the delegated work\"},\"prompt\":{\"type\":\"string\",\"description\":\"Focused instructions for the child agent\"},\"role\":{\"type\":\"string\",\"description\":\"Role to use for the child agent\"},\"cwd\":{\"type\":\"string\",\"description\":\"Working directory for the child agent. AGENTS.md and skills are discovered from here.\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Return a deterministic lookup result with an id needed by web_search.\",\"name\":\"lookup\",\"parameters\":{\"type\":\"object\",\"required\":[\"query\"],\"properties\":{\"query\":{\"type\":\"string\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Search a deterministic local web index. Requires the id returned by lookup.\",\"name\":\"web_search\",\"parameters\":{\"type\":\"object\",\"required\":[\"lookupId\",\"query\"],\"properties\":{\"lookupId\":{\"type\":\"string\"},\"query\":{\"type\":\"string\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Summarize the selected deterministic source after web_search returns a URL.\",\"name\":\"summarize_source\",\"parameters\":{\"type\":\"object\",\"required\":[\"url\"],\"properties\":{\"url\":{\"type\":\"string\"}}},\"strict\":false}],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":null,\"user\":null,\"metadata\":{}},\"sequence_number\":1}", + "event: response.output_item.added\ndata: {\"type\":\"response.output_item.added\",\"item\":{\"id\":\"fc_0a9628fdef0a9b50016a101030aa2c8190a6b053f73ee55abc\",\"type\":\"function_call\",\"status\":\"in_progress\",\"arguments\":\"\",\"call_id\":\"call_F7zI4fCOw4jk7rTwqbi8umo7\",\"name\":\"web_search\"},\"output_index\":0,\"sequence_number\":2}", + "event: response.function_call_arguments.delta\ndata: {\"type\":\"response.function_call_arguments.delta\",\"delta\":\"{\\\"\",\"item_id\":\"fc_0a9628fdef0a9b50016a101030aa2c8190a6b053f73ee55abc\",\"obfuscation\":\"D8DIbFMFfKgIqR\",\"output_index\":0,\"sequence_number\":3}", + "event: response.function_call_arguments.delta\ndata: {\"type\":\"response.function_call_arguments.delta\",\"delta\":\"lookup\",\"item_id\":\"fc_0a9628fdef0a9b50016a101030aa2c8190a6b053f73ee55abc\",\"obfuscation\":\"oRLHzvqUcC\",\"output_index\":0,\"sequence_number\":4}", + "event: response.function_call_arguments.delta\ndata: {\"type\":\"response.function_call_arguments.delta\",\"delta\":\"Id\",\"item_id\":\"fc_0a9628fdef0a9b50016a101030aa2c8190a6b053f73ee55abc\",\"obfuscation\":\"ctWwYaf4enBlpn\",\"output_index\":0,\"sequence_number\":5}", + "event: response.function_call_arguments.delta\ndata: {\"type\":\"response.function_call_arguments.delta\",\"delta\":\"\\\":\\\"\",\"item_id\":\"fc_0a9628fdef0a9b50016a101030aa2c8190a6b053f73ee55abc\",\"obfuscation\":\"Bxex01CZf30mb\",\"output_index\":0,\"sequence_number\":6}", + "event: response.function_call_arguments.delta\ndata: {\"type\":\"response.function_call_arguments.delta\",\"delta\":\"fl\",\"item_id\":\"fc_0a9628fdef0a9b50016a101030aa2c8190a6b053f73ee55abc\",\"obfuscation\":\"W5EpmSSJSRsh1B\",\"output_index\":0,\"sequence_number\":7}", + "event: response.function_call_arguments.delta\ndata: {\"type\":\"response.function_call_arguments.delta\",\"delta\":\"ue\",\"item_id\":\"fc_0a9628fdef0a9b50016a101030aa2c8190a6b053f73ee55abc\",\"obfuscation\":\"RXJ3GtNcFEZC3L\",\"output_index\":0,\"sequence_number\":8}", + "event: response.function_call_arguments.delta\ndata: {\"type\":\"response.function_call_arguments.delta\",\"delta\":\"-session\",\"item_id\":\"fc_0a9628fdef0a9b50016a101030aa2c8190a6b053f73ee55abc\",\"obfuscation\":\"FrptSujR\",\"output_index\":0,\"sequence_number\":9}", + "event: response.function_call_arguments.delta\ndata: {\"type\":\"response.function_call_arguments.delta\",\"delta\":\"-\",\"item_id\":\"fc_0a9628fdef0a9b50016a101030aa2c8190a6b053f73ee55abc\",\"obfuscation\":\"AOP9L65fcROFADX\",\"output_index\":0,\"sequence_number\":10}", + "event: response.function_call_arguments.delta\ndata: {\"type\":\"response.function_call_arguments.delta\",\"delta\":\"202\",\"item_id\":\"fc_0a9628fdef0a9b50016a101030aa2c8190a6b053f73ee55abc\",\"obfuscation\":\"4LfPsWU122uTC\",\"output_index\":0,\"sequence_number\":11}", + "event: response.function_call_arguments.delta\ndata: {\"type\":\"response.function_call_arguments.delta\",\"delta\":\"6\",\"item_id\":\"fc_0a9628fdef0a9b50016a101030aa2c8190a6b053f73ee55abc\",\"obfuscation\":\"a35P79vWwEKC2ZE\",\"output_index\":0,\"sequence_number\":12}", + "event: response.function_call_arguments.delta\ndata: {\"type\":\"response.function_call_arguments.delta\",\"delta\":\"\\\",\\\"\",\"item_id\":\"fc_0a9628fdef0a9b50016a101030aa2c8190a6b053f73ee55abc\",\"obfuscation\":\"tUGGlNr5jHxmu\",\"output_index\":0,\"sequence_number\":13}", + "event: response.function_call_arguments.delta\ndata: {\"type\":\"response.function_call_arguments.delta\",\"delta\":\"query\",\"item_id\":\"fc_0a9628fdef0a9b50016a101030aa2c8190a6b053f73ee55abc\",\"obfuscation\":\"GmSsogR2hlQ\",\"output_index\":0,\"sequence_number\":14}", + "event: response.function_call_arguments.delta\ndata: {\"type\":\"response.function_call_arguments.delta\",\"delta\":\"\\\":\\\"\",\"item_id\":\"fc_0a9628fdef0a9b50016a101030aa2c8190a6b053f73ee55abc\",\"obfuscation\":\"lrY20FxVrF4u8\",\"output_index\":0,\"sequence_number\":15}", + "event: response.function_call_arguments.delta\ndata: {\"type\":\"response.function_call_arguments.delta\",\"delta\":\"Brain\",\"item_id\":\"fc_0a9628fdef0a9b50016a101030aa2c8190a6b053f73ee55abc\",\"obfuscation\":\"v9CxBEQbCS9\",\"output_index\":0,\"sequence_number\":16}", + "event: response.function_call_arguments.delta\ndata: {\"type\":\"response.function_call_arguments.delta\",\"delta\":\"trust\",\"item_id\":\"fc_0a9628fdef0a9b50016a101030aa2c8190a6b053f73ee55abc\",\"obfuscation\":\"6i98iwGq0O6\",\"output_index\":0,\"sequence_number\":17}", + "event: response.function_call_arguments.delta\ndata: {\"type\":\"response.function_call_arguments.delta\",\"delta\":\" Fl\",\"item_id\":\"fc_0a9628fdef0a9b50016a101030aa2c8190a6b053f73ee55abc\",\"obfuscation\":\"uZPT710a30mTB\",\"output_index\":0,\"sequence_number\":18}", + "event: response.function_call_arguments.delta\ndata: {\"type\":\"response.function_call_arguments.delta\",\"delta\":\"ue\",\"item_id\":\"fc_0a9628fdef0a9b50016a101030aa2c8190a6b053f73ee55abc\",\"obfuscation\":\"U35GKeW5iDdc4n\",\"output_index\":0,\"sequence_number\":19}", + "event: response.function_call_arguments.delta\ndata: {\"type\":\"response.function_call_arguments.delta\",\"delta\":\" reasoning\",\"item_id\":\"fc_0a9628fdef0a9b50016a101030aa2c8190a6b053f73ee55abc\",\"obfuscation\":\"WrQDfZ\",\"output_index\":0,\"sequence_number\":20}", + "event: response.function_call_arguments.delta\ndata: {\"type\":\"response.function_call_arguments.delta\",\"delta\":\" stream\",\"item_id\":\"fc_0a9628fdef0a9b50016a101030aa2c8190a6b053f73ee55abc\",\"obfuscation\":\"PuhQQRxiZ\",\"output_index\":0,\"sequence_number\":21}", + "event: response.function_call_arguments.delta\ndata: {\"type\":\"response.function_call_arguments.delta\",\"delta\":\" instrumentation\",\"item_id\":\"fc_0a9628fdef0a9b50016a101030aa2c8190a6b053f73ee55abc\",\"obfuscation\":\"\",\"output_index\":0,\"sequence_number\":22}", + "event: response.function_call_arguments.delta\ndata: {\"type\":\"response.function_call_arguments.delta\",\"delta\":\"\\\"}\",\"item_id\":\"fc_0a9628fdef0a9b50016a101030aa2c8190a6b053f73ee55abc\",\"obfuscation\":\"xpwncQL0D58C6q\",\"output_index\":0,\"sequence_number\":23}", + "event: response.function_call_arguments.done\ndata: {\"type\":\"response.function_call_arguments.done\",\"arguments\":\"{\\\"lookupId\\\":\\\"flue-session-2026\\\",\\\"query\\\":\\\"Braintrust Flue reasoning stream instrumentation\\\"}\",\"item_id\":\"fc_0a9628fdef0a9b50016a101030aa2c8190a6b053f73ee55abc\",\"output_index\":0,\"sequence_number\":24}", + "event: response.output_item.done\ndata: {\"type\":\"response.output_item.done\",\"item\":{\"id\":\"fc_0a9628fdef0a9b50016a101030aa2c8190a6b053f73ee55abc\",\"type\":\"function_call\",\"status\":\"completed\",\"arguments\":\"{\\\"lookupId\\\":\\\"flue-session-2026\\\",\\\"query\\\":\\\"Braintrust Flue reasoning stream instrumentation\\\"}\",\"call_id\":\"call_F7zI4fCOw4jk7rTwqbi8umo7\",\"name\":\"web_search\"},\"output_index\":0,\"sequence_number\":25}", + "event: response.completed\ndata: {\"type\":\"response.completed\",\"response\":{\"id\":\"resp_0a9628fdef0a9b50016a1010300e24819095d12ec72332326f\",\"object\":\"response\",\"created_at\":1779437616,\"status\":\"completed\",\"background\":false,\"completed_at\":1779437616,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":null,\"instructions\":null,\"max_output_tokens\":null,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[{\"id\":\"fc_0a9628fdef0a9b50016a101030aa2c8190a6b053f73ee55abc\",\"type\":\"function_call\",\"status\":\"completed\",\"arguments\":\"{\\\"lookupId\\\":\\\"flue-session-2026\\\",\\\"query\\\":\\\"Braintrust Flue reasoning stream instrumentation\\\"}\",\"call_id\":\"call_F7zI4fCOw4jk7rTwqbi8umo7\",\"name\":\"web_search\"}],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":\"flue-e2e-instance::default::main\",\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"default\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[{\"type\":\"function\",\"description\":\"Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.\",\"name\":\"read\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to read\"},\"offset\":{\"type\":\"number\",\"description\":\"Line number to start from (1-indexed)\"},\"limit\":{\"type\":\"number\",\"description\":\"Maximum number of lines to read\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Write content to a file. Creates the file and parent directories if they do not exist.\",\"name\":\"write\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"content\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to write\"},\"content\":{\"type\":\"string\",\"description\":\"Content to write to the file\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.\",\"name\":\"edit\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"oldText\",\"newText\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to edit\"},\"oldText\":{\"type\":\"string\",\"description\":\"Exact text to find (must be unique)\"},\"newText\":{\"type\":\"string\",\"description\":\"Replacement text\"},\"replaceAll\":{\"type\":\"boolean\",\"description\":\"Replace all occurrences\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.\",\"name\":\"bash\",\"parameters\":{\"type\":\"object\",\"required\":[\"command\"],\"properties\":{\"command\":{\"type\":\"string\",\"description\":\"Bash command to execute\"},\"timeout\":{\"type\":\"number\",\"description\":\"Timeout in seconds\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.\",\"name\":\"grep\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Search pattern (regex)\"},\"path\":{\"type\":\"string\",\"description\":\"Directory or file to search (default: .)\"},\"include\":{\"type\":\"string\",\"description\":\"Glob filter, e.g. \\\"*.ts\\\"\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Find files by filename pattern using shell find -name semantics. Returns matching file paths.\",\"name\":\"glob\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Filename pattern, e.g. \\\"*.ts\\\"\"},\"path\":{\"type\":\"string\",\"description\":\"Directory to search in (default: .)\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.\",\"name\":\"task\",\"parameters\":{\"type\":\"object\",\"required\":[\"prompt\"],\"properties\":{\"description\":{\"type\":\"string\",\"description\":\"Short human-readable label for the delegated work\"},\"prompt\":{\"type\":\"string\",\"description\":\"Focused instructions for the child agent\"},\"role\":{\"type\":\"string\",\"description\":\"Role to use for the child agent\"},\"cwd\":{\"type\":\"string\",\"description\":\"Working directory for the child agent. AGENTS.md and skills are discovered from here.\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Return a deterministic lookup result with an id needed by web_search.\",\"name\":\"lookup\",\"parameters\":{\"type\":\"object\",\"required\":[\"query\"],\"properties\":{\"query\":{\"type\":\"string\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Search a deterministic local web index. Requires the id returned by lookup.\",\"name\":\"web_search\",\"parameters\":{\"type\":\"object\",\"required\":[\"lookupId\",\"query\"],\"properties\":{\"lookupId\":{\"type\":\"string\"},\"query\":{\"type\":\"string\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Summarize the selected deterministic source after web_search returns a URL.\",\"name\":\"summarize_source\",\"parameters\":{\"type\":\"object\",\"required\":[\"url\"],\"properties\":{\"url\":{\"type\":\"string\"}}},\"strict\":false}],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":{\"input_tokens\":987,\"input_tokens_details\":{\"cached_tokens\":0},\"output_tokens\":31,\"output_tokens_details\":{\"reasoning_tokens\":0},\"total_tokens\":1018},\"user\":null,\"metadata\":{}},\"sequence_number\":26}" + ], + "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": "9ffa5ccb9b77325f-VIE", + "connection": "keep-alive", + "content-type": "text/event-stream; charset=utf-8", + "date": "Fri, 22 May 2026 08:13:36 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "128", + "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-request-id": "req_c40d10c0c5cb48f39a473dbbfdf4ba74" + }, + "status": 200, + "statusText": "OK" + } + }, + { + "callIndex": 2, + "id": "5d2312f425df9f2f", + "matchKey": "POST api.openai.com/v1/responses", + "recordedAt": "2026-05-22T08:13:38.150Z", + "request": { + "body": { + "kind": "json", + "value": { + "input": [ + { + "content": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-HpI3r1/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + "role": "system" + }, + { + "content": [ + { + "text": "Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.", + "type": "input_text" + } + ], + "role": "user" + }, + { + "arguments": "{\"query\":\"flue instrumentation\"}", + "call_id": "call_xELft1kjhTSvPWAp3Z3i4zWk", + "id": "fc_0a9628fdef0a9b50016a10102fa3308190bfb69b9815d024ea", + "name": "lookup", + "type": "function_call" + }, + { + "call_id": "call_xELft1kjhTSvPWAp3Z3i4zWk", + "output": "{\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}", + "type": "function_call_output" + }, + { + "arguments": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\"}", + "call_id": "call_F7zI4fCOw4jk7rTwqbi8umo7", + "id": "fc_0a9628fdef0a9b50016a101030aa2c8190a6b053f73ee55abc", + "name": "web_search", + "type": "function_call" + }, + { + "call_id": "call_F7zI4fCOw4jk7rTwqbi8umo7", + "output": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\",\"results\":[{\"title\":\"Flue reasoning stream instrumentation\",\"url\":\"https://example.test/flue/reasoning-streams\"}]}", + "type": "function_call_output" + } + ], + "model": "gpt-4o-mini", + "prompt_cache_key": "[REDACTED]", + "store": false, + "stream": true, + "tools": [ + { + "description": "Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.", + "name": "read", + "parameters": { + "properties": { + "limit": { + "description": "Maximum number of lines to read", + "type": "number" + }, + "offset": { + "description": "Line number to start from (1-indexed)", + "type": "number" + }, + "path": { + "description": "Path to the file to read", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Write content to a file. Creates the file and parent directories if they do not exist.", + "name": "write", + "parameters": { + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Path to the file to write", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.", + "name": "edit", + "parameters": { + "properties": { + "newText": { + "description": "Replacement text", + "type": "string" + }, + "oldText": { + "description": "Exact text to find (must be unique)", + "type": "string" + }, + "path": { + "description": "Path to the file to edit", + "type": "string" + }, + "replaceAll": { + "description": "Replace all occurrences", + "type": "boolean" + } + }, + "required": [ + "path", + "oldText", + "newText" + ], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.", + "name": "bash", + "parameters": { + "properties": { + "command": { + "description": "Bash command to execute", + "type": "string" + }, + "timeout": { + "description": "Timeout in seconds", + "type": "number" + } + }, + "required": [ + "command" + ], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.", + "name": "grep", + "parameters": { + "properties": { + "include": { + "description": "Glob filter, e.g. \"*.ts\"", + "type": "string" + }, + "path": { + "description": "Directory or file to search (default: .)", + "type": "string" + }, + "pattern": { + "description": "Search pattern (regex)", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Find files by filename pattern using shell find -name semantics. Returns matching file paths.", + "name": "glob", + "parameters": { + "properties": { + "path": { + "description": "Directory to search in (default: .)", + "type": "string" + }, + "pattern": { + "description": "Filename pattern, e.g. \"*.ts\"", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.", + "name": "task", + "parameters": { + "properties": { + "cwd": { + "description": "Working directory for the child agent. AGENTS.md and skills are discovered from here.", + "type": "string" + }, + "description": { + "description": "Short human-readable label for the delegated work", + "type": "string" + }, + "prompt": { + "description": "Focused instructions for the child agent", + "type": "string" + }, + "role": { + "description": "Role to use for the child agent", + "type": "string" + } + }, + "required": [ + "prompt" + ], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Return a deterministic lookup result with an id needed by web_search.", + "name": "lookup", + "parameters": { + "properties": { + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Search a deterministic local web index. Requires the id returned by lookup.", + "name": "web_search", + "parameters": { + "properties": { + "lookupId": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "lookupId", + "query" + ], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Summarize the selected deterministic source after web_search returns a URL.", + "name": "summarize_source", + "parameters": { + "properties": { + "url": { + "type": "string" + } + }, + "required": [ + "url" + ], + "type": "object" + }, + "strict": false, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/responses" + }, + "response": { + "body": { + "chunks": [ + "event: response.created\ndata: {\"type\":\"response.created\",\"response\":{\"id\":\"resp_0a9628fdef0a9b50016a1010311bb0819090a41f2b4f42dca1\",\"object\":\"response\",\"created_at\":1779437617,\"status\":\"in_progress\",\"background\":false,\"completed_at\":null,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":null,\"instructions\":null,\"max_output_tokens\":null,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":\"flue-e2e-instance::default::main\",\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"auto\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[{\"type\":\"function\",\"description\":\"Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.\",\"name\":\"read\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to read\"},\"offset\":{\"type\":\"number\",\"description\":\"Line number to start from (1-indexed)\"},\"limit\":{\"type\":\"number\",\"description\":\"Maximum number of lines to read\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Write content to a file. Creates the file and parent directories if they do not exist.\",\"name\":\"write\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"content\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to write\"},\"content\":{\"type\":\"string\",\"description\":\"Content to write to the file\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.\",\"name\":\"edit\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"oldText\",\"newText\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to edit\"},\"oldText\":{\"type\":\"string\",\"description\":\"Exact text to find (must be unique)\"},\"newText\":{\"type\":\"string\",\"description\":\"Replacement text\"},\"replaceAll\":{\"type\":\"boolean\",\"description\":\"Replace all occurrences\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.\",\"name\":\"bash\",\"parameters\":{\"type\":\"object\",\"required\":[\"command\"],\"properties\":{\"command\":{\"type\":\"string\",\"description\":\"Bash command to execute\"},\"timeout\":{\"type\":\"number\",\"description\":\"Timeout in seconds\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.\",\"name\":\"grep\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Search pattern (regex)\"},\"path\":{\"type\":\"string\",\"description\":\"Directory or file to search (default: .)\"},\"include\":{\"type\":\"string\",\"description\":\"Glob filter, e.g. \\\"*.ts\\\"\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Find files by filename pattern using shell find -name semantics. Returns matching file paths.\",\"name\":\"glob\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Filename pattern, e.g. \\\"*.ts\\\"\"},\"path\":{\"type\":\"string\",\"description\":\"Directory to search in (default: .)\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.\",\"name\":\"task\",\"parameters\":{\"type\":\"object\",\"required\":[\"prompt\"],\"properties\":{\"description\":{\"type\":\"string\",\"description\":\"Short human-readable label for the delegated work\"},\"prompt\":{\"type\":\"string\",\"description\":\"Focused instructions for the child agent\"},\"role\":{\"type\":\"string\",\"description\":\"Role to use for the child agent\"},\"cwd\":{\"type\":\"string\",\"description\":\"Working directory for the child agent. AGENTS.md and skills are discovered from here.\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Return a deterministic lookup result with an id needed by web_search.\",\"name\":\"lookup\",\"parameters\":{\"type\":\"object\",\"required\":[\"query\"],\"properties\":{\"query\":{\"type\":\"string\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Search a deterministic local web index. Requires the id returned by lookup.\",\"name\":\"web_search\",\"parameters\":{\"type\":\"object\",\"required\":[\"lookupId\",\"query\"],\"properties\":{\"lookupId\":{\"type\":\"string\"},\"query\":{\"type\":\"string\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Summarize the selected deterministic source after web_search returns a URL.\",\"name\":\"summarize_source\",\"parameters\":{\"type\":\"object\",\"required\":[\"url\"],\"properties\":{\"url\":{\"type\":\"string\"}}},\"strict\":false}],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":null,\"user\":null,\"metadata\":{}},\"sequence_number\":0}", + "event: response.in_progress\ndata: {\"type\":\"response.in_progress\",\"response\":{\"id\":\"resp_0a9628fdef0a9b50016a1010311bb0819090a41f2b4f42dca1\",\"object\":\"response\",\"created_at\":1779437617,\"status\":\"in_progress\",\"background\":false,\"completed_at\":null,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":null,\"instructions\":null,\"max_output_tokens\":null,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":\"flue-e2e-instance::default::main\",\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"auto\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[{\"type\":\"function\",\"description\":\"Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.\",\"name\":\"read\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to read\"},\"offset\":{\"type\":\"number\",\"description\":\"Line number to start from (1-indexed)\"},\"limit\":{\"type\":\"number\",\"description\":\"Maximum number of lines to read\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Write content to a file. Creates the file and parent directories if they do not exist.\",\"name\":\"write\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"content\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to write\"},\"content\":{\"type\":\"string\",\"description\":\"Content to write to the file\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.\",\"name\":\"edit\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"oldText\",\"newText\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to edit\"},\"oldText\":{\"type\":\"string\",\"description\":\"Exact text to find (must be unique)\"},\"newText\":{\"type\":\"string\",\"description\":\"Replacement text\"},\"replaceAll\":{\"type\":\"boolean\",\"description\":\"Replace all occurrences\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.\",\"name\":\"bash\",\"parameters\":{\"type\":\"object\",\"required\":[\"command\"],\"properties\":{\"command\":{\"type\":\"string\",\"description\":\"Bash command to execute\"},\"timeout\":{\"type\":\"number\",\"description\":\"Timeout in seconds\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.\",\"name\":\"grep\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Search pattern (regex)\"},\"path\":{\"type\":\"string\",\"description\":\"Directory or file to search (default: .)\"},\"include\":{\"type\":\"string\",\"description\":\"Glob filter, e.g. \\\"*.ts\\\"\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Find files by filename pattern using shell find -name semantics. Returns matching file paths.\",\"name\":\"glob\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Filename pattern, e.g. \\\"*.ts\\\"\"},\"path\":{\"type\":\"string\",\"description\":\"Directory to search in (default: .)\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.\",\"name\":\"task\",\"parameters\":{\"type\":\"object\",\"required\":[\"prompt\"],\"properties\":{\"description\":{\"type\":\"string\",\"description\":\"Short human-readable label for the delegated work\"},\"prompt\":{\"type\":\"string\",\"description\":\"Focused instructions for the child agent\"},\"role\":{\"type\":\"string\",\"description\":\"Role to use for the child agent\"},\"cwd\":{\"type\":\"string\",\"description\":\"Working directory for the child agent. AGENTS.md and skills are discovered from here.\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Return a deterministic lookup result with an id needed by web_search.\",\"name\":\"lookup\",\"parameters\":{\"type\":\"object\",\"required\":[\"query\"],\"properties\":{\"query\":{\"type\":\"string\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Search a deterministic local web index. Requires the id returned by lookup.\",\"name\":\"web_search\",\"parameters\":{\"type\":\"object\",\"required\":[\"lookupId\",\"query\"],\"properties\":{\"lookupId\":{\"type\":\"string\"},\"query\":{\"type\":\"string\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Summarize the selected deterministic source after web_search returns a URL.\",\"name\":\"summarize_source\",\"parameters\":{\"type\":\"object\",\"required\":[\"url\"],\"properties\":{\"url\":{\"type\":\"string\"}}},\"strict\":false}],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":null,\"user\":null,\"metadata\":{}},\"sequence_number\":1}", + "event: response.output_item.added\ndata: {\"type\":\"response.output_item.added\",\"item\":{\"id\":\"fc_0a9628fdef0a9b50016a101031b3fc8190aeb5142bbecd534d\",\"type\":\"function_call\",\"status\":\"in_progress\",\"arguments\":\"\",\"call_id\":\"call_0yinp9edeamv8mKgyhkpaCmG\",\"name\":\"summarize_source\"},\"output_index\":0,\"sequence_number\":2}", + "event: response.function_call_arguments.delta\ndata: {\"type\":\"response.function_call_arguments.delta\",\"delta\":\"{\\\"\",\"item_id\":\"fc_0a9628fdef0a9b50016a101031b3fc8190aeb5142bbecd534d\",\"obfuscation\":\"8FFpGF2J29ZOHN\",\"output_index\":0,\"sequence_number\":3}", + "event: response.function_call_arguments.delta\ndata: {\"type\":\"response.function_call_arguments.delta\",\"delta\":\"url\",\"item_id\":\"fc_0a9628fdef0a9b50016a101031b3fc8190aeb5142bbecd534d\",\"obfuscation\":\"d4fdn4AecZ46t\",\"output_index\":0,\"sequence_number\":4}", + "event: response.function_call_arguments.delta\ndata: {\"type\":\"response.function_call_arguments.delta\",\"delta\":\"\\\":\\\"\",\"item_id\":\"fc_0a9628fdef0a9b50016a101031b3fc8190aeb5142bbecd534d\",\"obfuscation\":\"rPDoeTBqETi8O\",\"output_index\":0,\"sequence_number\":5}", + "event: response.function_call_arguments.delta\ndata: {\"type\":\"response.function_call_arguments.delta\",\"delta\":\"https\",\"item_id\":\"fc_0a9628fdef0a9b50016a101031b3fc8190aeb5142bbecd534d\",\"obfuscation\":\"8WF5UppFrHy\",\"output_index\":0,\"sequence_number\":6}", + "event: response.function_call_arguments.delta\ndata: {\"type\":\"response.function_call_arguments.delta\",\"delta\":\"://\",\"item_id\":\"fc_0a9628fdef0a9b50016a101031b3fc8190aeb5142bbecd534d\",\"obfuscation\":\"PPdSqQktTJe91\",\"output_index\":0,\"sequence_number\":7}", + "event: response.function_call_arguments.delta\ndata: {\"type\":\"response.function_call_arguments.delta\",\"delta\":\"example\",\"item_id\":\"fc_0a9628fdef0a9b50016a101031b3fc8190aeb5142bbecd534d\",\"obfuscation\":\"jZPIqHEcp\",\"output_index\":0,\"sequence_number\":8}", + "event: response.function_call_arguments.delta\ndata: {\"type\":\"response.function_call_arguments.delta\",\"delta\":\".test\",\"item_id\":\"fc_0a9628fdef0a9b50016a101031b3fc8190aeb5142bbecd534d\",\"obfuscation\":\"bnsPzoqO82F\",\"output_index\":0,\"sequence_number\":9}", + "event: response.function_call_arguments.delta\ndata: {\"type\":\"response.function_call_arguments.delta\",\"delta\":\"/fl\",\"item_id\":\"fc_0a9628fdef0a9b50016a101031b3fc8190aeb5142bbecd534d\",\"obfuscation\":\"dvYhn8RmAWcKF\",\"output_index\":0,\"sequence_number\":10}", + "event: response.function_call_arguments.delta\ndata: {\"type\":\"response.function_call_arguments.delta\",\"delta\":\"ue\",\"item_id\":\"fc_0a9628fdef0a9b50016a101031b3fc8190aeb5142bbecd534d\",\"obfuscation\":\"GcZKFcsouE5Bux\",\"output_index\":0,\"sequence_number\":11}", + "event: response.function_call_arguments.delta\ndata: {\"type\":\"response.function_call_arguments.delta\",\"delta\":\"/re\",\"item_id\":\"fc_0a9628fdef0a9b50016a101031b3fc8190aeb5142bbecd534d\",\"obfuscation\":\"JPhCoN74iLW66\",\"output_index\":0,\"sequence_number\":12}", + "event: response.function_call_arguments.delta\ndata: {\"type\":\"response.function_call_arguments.delta\",\"delta\":\"ason\",\"item_id\":\"fc_0a9628fdef0a9b50016a101031b3fc8190aeb5142bbecd534d\",\"obfuscation\":\"YyLaL8Gys893\",\"output_index\":0,\"sequence_number\":13}", + "event: response.function_call_arguments.delta\ndata: {\"type\":\"response.function_call_arguments.delta\",\"delta\":\"ing\",\"item_id\":\"fc_0a9628fdef0a9b50016a101031b3fc8190aeb5142bbecd534d\",\"obfuscation\":\"T1KVZueZc1kD3\",\"output_index\":0,\"sequence_number\":14}", + "event: response.function_call_arguments.delta\ndata: {\"type\":\"response.function_call_arguments.delta\",\"delta\":\"-stream\",\"item_id\":\"fc_0a9628fdef0a9b50016a101031b3fc8190aeb5142bbecd534d\",\"obfuscation\":\"W0Dx2W85S\",\"output_index\":0,\"sequence_number\":15}", + "event: response.function_call_arguments.delta\ndata: {\"type\":\"response.function_call_arguments.delta\",\"delta\":\"s\",\"item_id\":\"fc_0a9628fdef0a9b50016a101031b3fc8190aeb5142bbecd534d\",\"obfuscation\":\"VS7LtwoGUsSOG0P\",\"output_index\":0,\"sequence_number\":16}", + "event: response.function_call_arguments.delta\ndata: {\"type\":\"response.function_call_arguments.delta\",\"delta\":\"\\\"}\",\"item_id\":\"fc_0a9628fdef0a9b50016a101031b3fc8190aeb5142bbecd534d\",\"obfuscation\":\"jvRLaiM8JWmd7e\",\"output_index\":0,\"sequence_number\":17}", + "event: response.function_call_arguments.done\ndata: {\"type\":\"response.function_call_arguments.done\",\"arguments\":\"{\\\"url\\\":\\\"https://example.test/flue/reasoning-streams\\\"}\",\"item_id\":\"fc_0a9628fdef0a9b50016a101031b3fc8190aeb5142bbecd534d\",\"output_index\":0,\"sequence_number\":18}", + "event: response.output_item.done\ndata: {\"type\":\"response.output_item.done\",\"item\":{\"id\":\"fc_0a9628fdef0a9b50016a101031b3fc8190aeb5142bbecd534d\",\"type\":\"function_call\",\"status\":\"completed\",\"arguments\":\"{\\\"url\\\":\\\"https://example.test/flue/reasoning-streams\\\"}\",\"call_id\":\"call_0yinp9edeamv8mKgyhkpaCmG\",\"name\":\"summarize_source\"},\"output_index\":0,\"sequence_number\":19}", + "event: response.completed\ndata: {\"type\":\"response.completed\",\"response\":{\"id\":\"resp_0a9628fdef0a9b50016a1010311bb0819090a41f2b4f42dca1\",\"object\":\"response\",\"created_at\":1779437617,\"status\":\"completed\",\"background\":false,\"completed_at\":1779437617,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":null,\"instructions\":null,\"max_output_tokens\":null,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[{\"id\":\"fc_0a9628fdef0a9b50016a101031b3fc8190aeb5142bbecd534d\",\"type\":\"function_call\",\"status\":\"completed\",\"arguments\":\"{\\\"url\\\":\\\"https://example.test/flue/reasoning-streams\\\"}\",\"call_id\":\"call_0yinp9edeamv8mKgyhkpaCmG\",\"name\":\"summarize_source\"}],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":\"flue-e2e-instance::default::main\",\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"default\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[{\"type\":\"function\",\"description\":\"Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.\",\"name\":\"read\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to read\"},\"offset\":{\"type\":\"number\",\"description\":\"Line number to start from (1-indexed)\"},\"limit\":{\"type\":\"number\",\"description\":\"Maximum number of lines to read\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Write content to a file. Creates the file and parent directories if they do not exist.\",\"name\":\"write\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"content\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to write\"},\"content\":{\"type\":\"string\",\"description\":\"Content to write to the file\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.\",\"name\":\"edit\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"oldText\",\"newText\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to edit\"},\"oldText\":{\"type\":\"string\",\"description\":\"Exact text to find (must be unique)\"},\"newText\":{\"type\":\"string\",\"description\":\"Replacement text\"},\"replaceAll\":{\"type\":\"boolean\",\"description\":\"Replace all occurrences\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.\",\"name\":\"bash\",\"parameters\":{\"type\":\"object\",\"required\":[\"command\"],\"properties\":{\"command\":{\"type\":\"string\",\"description\":\"Bash command to execute\"},\"timeout\":{\"type\":\"number\",\"description\":\"Timeout in seconds\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.\",\"name\":\"grep\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Search pattern (regex)\"},\"path\":{\"type\":\"string\",\"description\":\"Directory or file to search (default: .)\"},\"include\":{\"type\":\"string\",\"description\":\"Glob filter, e.g. \\\"*.ts\\\"\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Find files by filename pattern using shell find -name semantics. Returns matching file paths.\",\"name\":\"glob\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Filename pattern, e.g. \\\"*.ts\\\"\"},\"path\":{\"type\":\"string\",\"description\":\"Directory to search in (default: .)\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.\",\"name\":\"task\",\"parameters\":{\"type\":\"object\",\"required\":[\"prompt\"],\"properties\":{\"description\":{\"type\":\"string\",\"description\":\"Short human-readable label for the delegated work\"},\"prompt\":{\"type\":\"string\",\"description\":\"Focused instructions for the child agent\"},\"role\":{\"type\":\"string\",\"description\":\"Role to use for the child agent\"},\"cwd\":{\"type\":\"string\",\"description\":\"Working directory for the child agent. AGENTS.md and skills are discovered from here.\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Return a deterministic lookup result with an id needed by web_search.\",\"name\":\"lookup\",\"parameters\":{\"type\":\"object\",\"required\":[\"query\"],\"properties\":{\"query\":{\"type\":\"string\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Search a deterministic local web index. Requires the id returned by lookup.\",\"name\":\"web_search\",\"parameters\":{\"type\":\"object\",\"required\":[\"lookupId\",\"query\"],\"properties\":{\"lookupId\":{\"type\":\"string\"},\"query\":{\"type\":\"string\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Summarize the selected deterministic source after web_search returns a URL.\",\"name\":\"summarize_source\",\"parameters\":{\"type\":\"object\",\"required\":[\"url\"],\"properties\":{\"url\":{\"type\":\"string\"}}},\"strict\":false}],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":{\"input_tokens\":1070,\"input_tokens_details\":{\"cached_tokens\":0},\"output_tokens\":27,\"output_tokens_details\":{\"reasoning_tokens\":0},\"total_tokens\":1097},\"user\":null,\"metadata\":{}},\"sequence_number\":20}" + ], + "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": "9ffa5cd21ac7325f-VIE", + "connection": "keep-alive", + "content-type": "text/event-stream; charset=utf-8", + "date": "Fri, 22 May 2026 08:13:37 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "165", + "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-request-id": "req_f5d74822605549e496e2bcbab5a75621" + }, + "status": 200, + "statusText": "OK" + } + }, + { + "callIndex": 3, + "id": "83cbbf6da482c905", + "matchKey": "POST api.openai.com/v1/responses", + "recordedAt": "2026-05-22T08:13:39.243Z", + "request": { + "body": { + "kind": "json", + "value": { + "input": [ + { + "content": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-HpI3r1/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + "role": "system" + }, + { + "content": [ + { + "text": "Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.", + "type": "input_text" + } + ], + "role": "user" + }, + { + "arguments": "{\"query\":\"flue instrumentation\"}", + "call_id": "call_xELft1kjhTSvPWAp3Z3i4zWk", + "id": "fc_0a9628fdef0a9b50016a10102fa3308190bfb69b9815d024ea", + "name": "lookup", + "type": "function_call" + }, + { + "call_id": "call_xELft1kjhTSvPWAp3Z3i4zWk", + "output": "{\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}", + "type": "function_call_output" + }, + { + "arguments": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\"}", + "call_id": "call_F7zI4fCOw4jk7rTwqbi8umo7", + "id": "fc_0a9628fdef0a9b50016a101030aa2c8190a6b053f73ee55abc", + "name": "web_search", + "type": "function_call" + }, + { + "call_id": "call_F7zI4fCOw4jk7rTwqbi8umo7", + "output": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\",\"results\":[{\"title\":\"Flue reasoning stream instrumentation\",\"url\":\"https://example.test/flue/reasoning-streams\"}]}", + "type": "function_call_output" + }, + { + "arguments": "{\"url\":\"https://example.test/flue/reasoning-streams\"}", + "call_id": "call_0yinp9edeamv8mKgyhkpaCmG", + "id": "fc_0a9628fdef0a9b50016a101031b3fc8190aeb5142bbecd534d", + "name": "summarize_source", + "type": "function_call" + }, + { + "call_id": "call_0yinp9edeamv8mKgyhkpaCmG", + "output": "{\"summary\":\"Flue emits reasoning, tool execution, and LLM turn events separately.\",\"url\":\"https://example.test/flue/reasoning-streams\"}", + "type": "function_call_output" + } + ], + "model": "gpt-4o-mini", + "prompt_cache_key": "[REDACTED]", + "store": false, + "stream": true, + "tools": [ + { + "description": "Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.", + "name": "read", + "parameters": { + "properties": { + "limit": { + "description": "Maximum number of lines to read", + "type": "number" + }, + "offset": { + "description": "Line number to start from (1-indexed)", + "type": "number" + }, + "path": { + "description": "Path to the file to read", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Write content to a file. Creates the file and parent directories if they do not exist.", + "name": "write", + "parameters": { + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Path to the file to write", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.", + "name": "edit", + "parameters": { + "properties": { + "newText": { + "description": "Replacement text", + "type": "string" + }, + "oldText": { + "description": "Exact text to find (must be unique)", + "type": "string" + }, + "path": { + "description": "Path to the file to edit", + "type": "string" + }, + "replaceAll": { + "description": "Replace all occurrences", + "type": "boolean" + } + }, + "required": [ + "path", + "oldText", + "newText" + ], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.", + "name": "bash", + "parameters": { + "properties": { + "command": { + "description": "Bash command to execute", + "type": "string" + }, + "timeout": { + "description": "Timeout in seconds", + "type": "number" + } + }, + "required": [ + "command" + ], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.", + "name": "grep", + "parameters": { + "properties": { + "include": { + "description": "Glob filter, e.g. \"*.ts\"", + "type": "string" + }, + "path": { + "description": "Directory or file to search (default: .)", + "type": "string" + }, + "pattern": { + "description": "Search pattern (regex)", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Find files by filename pattern using shell find -name semantics. Returns matching file paths.", + "name": "glob", + "parameters": { + "properties": { + "path": { + "description": "Directory to search in (default: .)", + "type": "string" + }, + "pattern": { + "description": "Filename pattern, e.g. \"*.ts\"", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.", + "name": "task", + "parameters": { + "properties": { + "cwd": { + "description": "Working directory for the child agent. AGENTS.md and skills are discovered from here.", + "type": "string" + }, + "description": { + "description": "Short human-readable label for the delegated work", + "type": "string" + }, + "prompt": { + "description": "Focused instructions for the child agent", + "type": "string" + }, + "role": { + "description": "Role to use for the child agent", + "type": "string" + } + }, + "required": [ + "prompt" + ], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Return a deterministic lookup result with an id needed by web_search.", + "name": "lookup", + "parameters": { + "properties": { + "query": { + "type": "string" + } + }, + "required": [ + "query" + ], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Search a deterministic local web index. Requires the id returned by lookup.", + "name": "web_search", + "parameters": { + "properties": { + "lookupId": { + "type": "string" + }, + "query": { + "type": "string" + } + }, + "required": [ + "lookupId", + "query" + ], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Summarize the selected deterministic source after web_search returns a URL.", + "name": "summarize_source", + "parameters": { + "properties": { + "url": { + "type": "string" + } + }, + "required": [ + "url" + ], + "type": "object" + }, + "strict": false, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/responses" + }, + "response": { + "body": { + "chunks": [ + "event: response.created\ndata: {\"type\":\"response.created\",\"response\":{\"id\":\"resp_0a9628fdef0a9b50016a10103257648190a7953ff23a5d2fb1\",\"object\":\"response\",\"created_at\":1779437618,\"status\":\"in_progress\",\"background\":false,\"completed_at\":null,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":null,\"instructions\":null,\"max_output_tokens\":null,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":\"flue-e2e-instance::default::main\",\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"auto\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[{\"type\":\"function\",\"description\":\"Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.\",\"name\":\"read\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to read\"},\"offset\":{\"type\":\"number\",\"description\":\"Line number to start from (1-indexed)\"},\"limit\":{\"type\":\"number\",\"description\":\"Maximum number of lines to read\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Write content to a file. Creates the file and parent directories if they do not exist.\",\"name\":\"write\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"content\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to write\"},\"content\":{\"type\":\"string\",\"description\":\"Content to write to the file\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.\",\"name\":\"edit\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"oldText\",\"newText\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to edit\"},\"oldText\":{\"type\":\"string\",\"description\":\"Exact text to find (must be unique)\"},\"newText\":{\"type\":\"string\",\"description\":\"Replacement text\"},\"replaceAll\":{\"type\":\"boolean\",\"description\":\"Replace all occurrences\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.\",\"name\":\"bash\",\"parameters\":{\"type\":\"object\",\"required\":[\"command\"],\"properties\":{\"command\":{\"type\":\"string\",\"description\":\"Bash command to execute\"},\"timeout\":{\"type\":\"number\",\"description\":\"Timeout in seconds\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.\",\"name\":\"grep\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Search pattern (regex)\"},\"path\":{\"type\":\"string\",\"description\":\"Directory or file to search (default: .)\"},\"include\":{\"type\":\"string\",\"description\":\"Glob filter, e.g. \\\"*.ts\\\"\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Find files by filename pattern using shell find -name semantics. Returns matching file paths.\",\"name\":\"glob\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Filename pattern, e.g. \\\"*.ts\\\"\"},\"path\":{\"type\":\"string\",\"description\":\"Directory to search in (default: .)\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.\",\"name\":\"task\",\"parameters\":{\"type\":\"object\",\"required\":[\"prompt\"],\"properties\":{\"description\":{\"type\":\"string\",\"description\":\"Short human-readable label for the delegated work\"},\"prompt\":{\"type\":\"string\",\"description\":\"Focused instructions for the child agent\"},\"role\":{\"type\":\"string\",\"description\":\"Role to use for the child agent\"},\"cwd\":{\"type\":\"string\",\"description\":\"Working directory for the child agent. AGENTS.md and skills are discovered from here.\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Return a deterministic lookup result with an id needed by web_search.\",\"name\":\"lookup\",\"parameters\":{\"type\":\"object\",\"required\":[\"query\"],\"properties\":{\"query\":{\"type\":\"string\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Search a deterministic local web index. Requires the id returned by lookup.\",\"name\":\"web_search\",\"parameters\":{\"type\":\"object\",\"required\":[\"lookupId\",\"query\"],\"properties\":{\"lookupId\":{\"type\":\"string\"},\"query\":{\"type\":\"string\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Summarize the selected deterministic source after web_search returns a URL.\",\"name\":\"summarize_source\",\"parameters\":{\"type\":\"object\",\"required\":[\"url\"],\"properties\":{\"url\":{\"type\":\"string\"}}},\"strict\":false}],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":null,\"user\":null,\"metadata\":{}},\"sequence_number\":0}", + "event: response.in_progress\ndata: {\"type\":\"response.in_progress\",\"response\":{\"id\":\"resp_0a9628fdef0a9b50016a10103257648190a7953ff23a5d2fb1\",\"object\":\"response\",\"created_at\":1779437618,\"status\":\"in_progress\",\"background\":false,\"completed_at\":null,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":null,\"instructions\":null,\"max_output_tokens\":null,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":\"flue-e2e-instance::default::main\",\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"auto\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[{\"type\":\"function\",\"description\":\"Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.\",\"name\":\"read\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to read\"},\"offset\":{\"type\":\"number\",\"description\":\"Line number to start from (1-indexed)\"},\"limit\":{\"type\":\"number\",\"description\":\"Maximum number of lines to read\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Write content to a file. Creates the file and parent directories if they do not exist.\",\"name\":\"write\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"content\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to write\"},\"content\":{\"type\":\"string\",\"description\":\"Content to write to the file\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.\",\"name\":\"edit\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"oldText\",\"newText\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to edit\"},\"oldText\":{\"type\":\"string\",\"description\":\"Exact text to find (must be unique)\"},\"newText\":{\"type\":\"string\",\"description\":\"Replacement text\"},\"replaceAll\":{\"type\":\"boolean\",\"description\":\"Replace all occurrences\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.\",\"name\":\"bash\",\"parameters\":{\"type\":\"object\",\"required\":[\"command\"],\"properties\":{\"command\":{\"type\":\"string\",\"description\":\"Bash command to execute\"},\"timeout\":{\"type\":\"number\",\"description\":\"Timeout in seconds\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.\",\"name\":\"grep\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Search pattern (regex)\"},\"path\":{\"type\":\"string\",\"description\":\"Directory or file to search (default: .)\"},\"include\":{\"type\":\"string\",\"description\":\"Glob filter, e.g. \\\"*.ts\\\"\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Find files by filename pattern using shell find -name semantics. Returns matching file paths.\",\"name\":\"glob\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Filename pattern, e.g. \\\"*.ts\\\"\"},\"path\":{\"type\":\"string\",\"description\":\"Directory to search in (default: .)\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.\",\"name\":\"task\",\"parameters\":{\"type\":\"object\",\"required\":[\"prompt\"],\"properties\":{\"description\":{\"type\":\"string\",\"description\":\"Short human-readable label for the delegated work\"},\"prompt\":{\"type\":\"string\",\"description\":\"Focused instructions for the child agent\"},\"role\":{\"type\":\"string\",\"description\":\"Role to use for the child agent\"},\"cwd\":{\"type\":\"string\",\"description\":\"Working directory for the child agent. AGENTS.md and skills are discovered from here.\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Return a deterministic lookup result with an id needed by web_search.\",\"name\":\"lookup\",\"parameters\":{\"type\":\"object\",\"required\":[\"query\"],\"properties\":{\"query\":{\"type\":\"string\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Search a deterministic local web index. Requires the id returned by lookup.\",\"name\":\"web_search\",\"parameters\":{\"type\":\"object\",\"required\":[\"lookupId\",\"query\"],\"properties\":{\"lookupId\":{\"type\":\"string\"},\"query\":{\"type\":\"string\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Summarize the selected deterministic source after web_search returns a URL.\",\"name\":\"summarize_source\",\"parameters\":{\"type\":\"object\",\"required\":[\"url\"],\"properties\":{\"url\":{\"type\":\"string\"}}},\"strict\":false}],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":null,\"user\":null,\"metadata\":{}},\"sequence_number\":1}", + "event: response.output_item.added\ndata: {\"type\":\"response.output_item.added\",\"item\":{\"id\":\"msg_0a9628fdef0a9b50016a10103302208190a4d993aaf77f70f7\",\"type\":\"message\",\"status\":\"in_progress\",\"content\":[],\"role\":\"assistant\"},\"output_index\":0,\"sequence_number\":2}", + "event: response.content_part.added\ndata: {\"type\":\"response.content_part.added\",\"content_index\":0,\"item_id\":\"msg_0a9628fdef0a9b50016a10103302208190a4d993aaf77f70f7\",\"output_index\":0,\"part\":{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"\"},\"sequence_number\":3}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"PROM\",\"item_id\":\"msg_0a9628fdef0a9b50016a10103302208190a4d993aaf77f70f7\",\"logprobs\":[],\"obfuscation\":\"aIGxUUBY6YDG\",\"output_index\":0,\"sequence_number\":4}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"PT\",\"item_id\":\"msg_0a9628fdef0a9b50016a10103302208190a4d993aaf77f70f7\",\"logprobs\":[],\"obfuscation\":\"oYlmnvntzpbIvZ\",\"output_index\":0,\"sequence_number\":5}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"_DONE\",\"item_id\":\"msg_0a9628fdef0a9b50016a10103302208190a4d993aaf77f70f7\",\"logprobs\":[],\"obfuscation\":\"70Nz1XwODHd\",\"output_index\":0,\"sequence_number\":6}", + "event: response.output_text.done\ndata: {\"type\":\"response.output_text.done\",\"content_index\":0,\"item_id\":\"msg_0a9628fdef0a9b50016a10103302208190a4d993aaf77f70f7\",\"logprobs\":[],\"output_index\":0,\"sequence_number\":7,\"text\":\"PROMPT_DONE\"}", + "event: response.content_part.done\ndata: {\"type\":\"response.content_part.done\",\"content_index\":0,\"item_id\":\"msg_0a9628fdef0a9b50016a10103302208190a4d993aaf77f70f7\",\"output_index\":0,\"part\":{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"PROMPT_DONE\"},\"sequence_number\":8}", + "event: response.output_item.done\ndata: {\"type\":\"response.output_item.done\",\"item\":{\"id\":\"msg_0a9628fdef0a9b50016a10103302208190a4d993aaf77f70f7\",\"type\":\"message\",\"status\":\"completed\",\"content\":[{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"PROMPT_DONE\"}],\"role\":\"assistant\"},\"output_index\":0,\"sequence_number\":9}", + "event: response.completed\ndata: {\"type\":\"response.completed\",\"response\":{\"id\":\"resp_0a9628fdef0a9b50016a10103257648190a7953ff23a5d2fb1\",\"object\":\"response\",\"created_at\":1779437618,\"status\":\"completed\",\"background\":false,\"completed_at\":1779437619,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":null,\"instructions\":null,\"max_output_tokens\":null,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[{\"id\":\"msg_0a9628fdef0a9b50016a10103302208190a4d993aaf77f70f7\",\"type\":\"message\",\"status\":\"completed\",\"content\":[{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"PROMPT_DONE\"}],\"role\":\"assistant\"}],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":\"flue-e2e-instance::default::main\",\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"default\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[{\"type\":\"function\",\"description\":\"Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.\",\"name\":\"read\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to read\"},\"offset\":{\"type\":\"number\",\"description\":\"Line number to start from (1-indexed)\"},\"limit\":{\"type\":\"number\",\"description\":\"Maximum number of lines to read\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Write content to a file. Creates the file and parent directories if they do not exist.\",\"name\":\"write\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"content\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to write\"},\"content\":{\"type\":\"string\",\"description\":\"Content to write to the file\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.\",\"name\":\"edit\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"oldText\",\"newText\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to edit\"},\"oldText\":{\"type\":\"string\",\"description\":\"Exact text to find (must be unique)\"},\"newText\":{\"type\":\"string\",\"description\":\"Replacement text\"},\"replaceAll\":{\"type\":\"boolean\",\"description\":\"Replace all occurrences\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.\",\"name\":\"bash\",\"parameters\":{\"type\":\"object\",\"required\":[\"command\"],\"properties\":{\"command\":{\"type\":\"string\",\"description\":\"Bash command to execute\"},\"timeout\":{\"type\":\"number\",\"description\":\"Timeout in seconds\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.\",\"name\":\"grep\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Search pattern (regex)\"},\"path\":{\"type\":\"string\",\"description\":\"Directory or file to search (default: .)\"},\"include\":{\"type\":\"string\",\"description\":\"Glob filter, e.g. \\\"*.ts\\\"\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Find files by filename pattern using shell find -name semantics. Returns matching file paths.\",\"name\":\"glob\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Filename pattern, e.g. \\\"*.ts\\\"\"},\"path\":{\"type\":\"string\",\"description\":\"Directory to search in (default: .)\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.\",\"name\":\"task\",\"parameters\":{\"type\":\"object\",\"required\":[\"prompt\"],\"properties\":{\"description\":{\"type\":\"string\",\"description\":\"Short human-readable label for the delegated work\"},\"prompt\":{\"type\":\"string\",\"description\":\"Focused instructions for the child agent\"},\"role\":{\"type\":\"string\",\"description\":\"Role to use for the child agent\"},\"cwd\":{\"type\":\"string\",\"description\":\"Working directory for the child agent. AGENTS.md and skills are discovered from here.\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Return a deterministic lookup result with an id needed by web_search.\",\"name\":\"lookup\",\"parameters\":{\"type\":\"object\",\"required\":[\"query\"],\"properties\":{\"query\":{\"type\":\"string\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Search a deterministic local web index. Requires the id returned by lookup.\",\"name\":\"web_search\",\"parameters\":{\"type\":\"object\",\"required\":[\"lookupId\",\"query\"],\"properties\":{\"lookupId\":{\"type\":\"string\"},\"query\":{\"type\":\"string\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Summarize the selected deterministic source after web_search returns a URL.\",\"name\":\"summarize_source\",\"parameters\":{\"type\":\"object\",\"required\":[\"url\"],\"properties\":{\"url\":{\"type\":\"string\"}}},\"strict\":false}],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":{\"input_tokens\":1136,\"input_tokens_details\":{\"cached_tokens\":1024},\"output_tokens\":5,\"output_tokens_details\":{\"reasoning_tokens\":0},\"total_tokens\":1141},\"user\":null,\"metadata\":{}},\"sequence_number\":10}" + ], + "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": "9ffa5cd9cadf325f-VIE", + "connection": "keep-alive", + "content-type": "text/event-stream; charset=utf-8", + "date": "Fri, 22 May 2026 08:13:38 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "119", + "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-request-id": "req_3c035efb7de544a1ac3234bcc350ad16" + }, + "status": 200, + "statusText": "OK" + } + }, + { + "callIndex": 0, + "id": "fcd9d51c145fb90b", + "matchKey": "POST api.anthropic.com/v1/messages", + "recordedAt": "2026-05-22T08:13:44.842Z", + "request": { + "body": { + "kind": "json", + "value": { + "max_tokens": 64000, + "messages": [ + { + "content": [ + { + "cache_control": { + "type": "ephemeral" + }, + "text": "Run the skill named \"e2e-flue-skill\".\n\nArguments:\n{\n \"marker\": \"SKILL_DONE\"\n}", + "type": "text" + } + ], + "role": "user" + } + ], + "model": "claude-sonnet-4-5-20250929", + "stream": true, + "system": [ + { + "cache_control": { + "type": "ephemeral" + }, + "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-HpI3r1/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts\n\n\nNever call the task tool. Do not delegate e2e-flue-skill to another session. If you need the skill body, read .agents/skills/e2e-flue-skill/SKILL.md yourself with the read tool. Return the marker from the Arguments object exactly, with no other text.\n", + "type": "text" + } + ], + "thinking": { + "type": "disabled" + }, + "tools": [ + { + "description": "Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "limit": { + "description": "Maximum number of lines to read", + "type": "number" + }, + "offset": { + "description": "Line number to start from (1-indexed)", + "type": "number" + }, + "path": { + "description": "Path to the file to read", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read" + }, + { + "description": "Write content to a file. Creates the file and parent directories if they do not exist.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Path to the file to write", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write" + }, + { + "description": "Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "newText": { + "description": "Replacement text", + "type": "string" + }, + "oldText": { + "description": "Exact text to find (must be unique)", + "type": "string" + }, + "path": { + "description": "Path to the file to edit", + "type": "string" + }, + "replaceAll": { + "description": "Replace all occurrences", + "type": "boolean" + } + }, + "required": [ + "path", + "oldText", + "newText" + ], + "type": "object" + }, + "name": "edit" + }, + { + "description": "Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "command": { + "description": "Bash command to execute", + "type": "string" + }, + "timeout": { + "description": "Timeout in seconds", + "type": "number" + } + }, + "required": [ + "command" + ], + "type": "object" + }, + "name": "bash" + }, + { + "description": "Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "include": { + "description": "Glob filter, e.g. \"*.ts\"", + "type": "string" + }, + "path": { + "description": "Directory or file to search (default: .)", + "type": "string" + }, + "pattern": { + "description": "Search pattern (regex)", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "grep" + }, + { + "description": "Find files by filename pattern using shell find -name semantics. Returns matching file paths.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "path": { + "description": "Directory to search in (default: .)", + "type": "string" + }, + "pattern": { + "description": "Filename pattern, e.g. \"*.ts\"", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "glob" + }, + { + "cache_control": { + "type": "ephemeral" + }, + "description": "Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "cwd": { + "description": "Working directory for the child agent. AGENTS.md and skills are discovered from here.", + "type": "string" + }, + "description": { + "description": "Short human-readable label for the delegated work", + "type": "string" + }, + "prompt": { + "description": "Focused instructions for the child agent", + "type": "string" + }, + "role": { + "description": "Role to use for the child agent", + "type": "string" + } + }, + "required": [ + "prompt" + ], + "type": "object" + }, + "name": "task" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.anthropic.com/v1/messages" + }, + "response": { + "body": { + "chunks": [ + "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-5-20250929\",\"id\":\"msg_01462yLZ8F2ESqxQn7Z9PN3f\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":3,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":1811,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":8,\"service_tier\":\"standard\",\"inference_geo\":\"not_available\"}}}", + "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"}}", + "event: ping\ndata: {\"type\":\"ping\"}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"I'll run the e2e-\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"flue-skill by reading its instructions and following them.\"}}", + "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0}", + "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":1,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01M5rfFBDvwquiyfz2B1GNYz\",\"name\":\"read\",\"input\":{},\"caller\":{\"type\":\"direct\"}}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"path\\\": \\\".agents/skills/e2e-flue-skill/SKILL.md\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"}\"}}", + "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":1}", + "event: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":3,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":1811,\"output_tokens\":89}}", + "event: message_stop\ndata: {\"type\":\"message_stop\"}" + ], + "kind": "sse" + }, + "headers": { + "anthropic-organization-id": "27796668-7351-40ac-acc4-024aee8995a5", + "anthropic-ratelimit-input-tokens-limit": "3000000", + "anthropic-ratelimit-input-tokens-remaining": "2999000", + "anthropic-ratelimit-input-tokens-reset": "2026-05-22T08:13:42Z", + "anthropic-ratelimit-output-tokens-limit": "600000", + "anthropic-ratelimit-output-tokens-remaining": "600000", + "anthropic-ratelimit-output-tokens-reset": "2026-05-22T08:13:42Z", + "anthropic-ratelimit-requests-limit": "20000", + "anthropic-ratelimit-requests-remaining": "19999", + "anthropic-ratelimit-requests-reset": "2026-05-22T08:13:42Z", + "anthropic-ratelimit-tokens-limit": "3600000", + "anthropic-ratelimit-tokens-remaining": "3599000", + "anthropic-ratelimit-tokens-reset": "2026-05-22T08:13:42Z", + "cache-control": "no-cache", + "cf-cache-status": "DYNAMIC", + "cf-ray": "9ffa5cf589335bad-VIE", + "connection": "keep-alive", + "content-encoding": "gzip", + "content-security-policy": "default-src 'none'; frame-ancestors 'none'", + "content-type": "text/event-stream; charset=utf-8", + "date": "Fri, 22 May 2026 08:13:43 GMT", + "request-id": "req_011CbHGksnSn5d7nngACrqDc", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "traceresponse": "00-006501fbd24eb2c22ba9da9d184a6314-1a3c07e594884bf9-01", + "transfer-encoding": "chunked", + "vary": "Accept-Encoding", + "x-envoy-upstream-service-time": "1157", + "x-robots-tag": "none" + }, + "status": 200, + "statusText": "OK" + } + }, + { + "callIndex": 1, + "id": "ff22a182ea5a9c06", + "matchKey": "POST api.anthropic.com/v1/messages", + "recordedAt": "2026-05-22T08:13:49.530Z", + "request": { + "body": { + "kind": "json", + "value": { + "max_tokens": 64000, + "messages": [ + { + "content": [ + { + "text": "Run the skill named \"e2e-flue-skill\".\n\nArguments:\n{\n \"marker\": \"SKILL_DONE\"\n}", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "text": "I'll run the e2e-flue-skill by reading its instructions and following them.", + "type": "text" + }, + { + "id": "toolu_01M5rfFBDvwquiyfz2B1GNYz", + "input": { + "path": ".agents/skills/e2e-flue-skill/SKILL.md" + }, + "name": "read", + "type": "tool_use" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "cache_control": { + "type": "ephemeral" + }, + "content": "---\nname: e2e-flue-skill\ndescription: Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n---\n\nReturn the marker from the provided args exactly once. Output no other text.\n", + "is_error": false, + "tool_use_id": "toolu_01M5rfFBDvwquiyfz2B1GNYz", + "type": "tool_result" + } + ], + "role": "user" + } + ], + "model": "claude-sonnet-4-5-20250929", + "stream": true, + "system": [ + { + "cache_control": { + "type": "ephemeral" + }, + "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-HpI3r1/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts\n\n\nNever call the task tool. Do not delegate e2e-flue-skill to another session. If you need the skill body, read .agents/skills/e2e-flue-skill/SKILL.md yourself with the read tool. Return the marker from the Arguments object exactly, with no other text.\n", + "type": "text" + } + ], + "thinking": { + "type": "disabled" + }, + "tools": [ + { + "description": "Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "limit": { + "description": "Maximum number of lines to read", + "type": "number" + }, + "offset": { + "description": "Line number to start from (1-indexed)", + "type": "number" + }, + "path": { + "description": "Path to the file to read", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "name": "read" + }, + { + "description": "Write content to a file. Creates the file and parent directories if they do not exist.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Path to the file to write", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "name": "write" + }, + { + "description": "Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "newText": { + "description": "Replacement text", + "type": "string" + }, + "oldText": { + "description": "Exact text to find (must be unique)", + "type": "string" + }, + "path": { + "description": "Path to the file to edit", + "type": "string" + }, + "replaceAll": { + "description": "Replace all occurrences", + "type": "boolean" + } + }, + "required": [ + "path", + "oldText", + "newText" + ], + "type": "object" + }, + "name": "edit" + }, + { + "description": "Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "command": { + "description": "Bash command to execute", + "type": "string" + }, + "timeout": { + "description": "Timeout in seconds", + "type": "number" + } + }, + "required": [ + "command" + ], + "type": "object" + }, + "name": "bash" + }, + { + "description": "Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "include": { + "description": "Glob filter, e.g. \"*.ts\"", + "type": "string" + }, + "path": { + "description": "Directory or file to search (default: .)", + "type": "string" + }, + "pattern": { + "description": "Search pattern (regex)", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "grep" + }, + { + "description": "Find files by filename pattern using shell find -name semantics. Returns matching file paths.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "path": { + "description": "Directory to search in (default: .)", + "type": "string" + }, + "pattern": { + "description": "Filename pattern, e.g. \"*.ts\"", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "name": "glob" + }, + { + "cache_control": { + "type": "ephemeral" + }, + "description": "Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.", + "eager_input_streaming": true, + "input_schema": { + "properties": { + "cwd": { + "description": "Working directory for the child agent. AGENTS.md and skills are discovered from here.", + "type": "string" + }, + "description": { + "description": "Short human-readable label for the delegated work", + "type": "string" + }, + "prompt": { + "description": "Focused instructions for the child agent", + "type": "string" + }, + "role": { + "description": "Role to use for the child agent", + "type": "string" + } + }, + "required": [ + "prompt" + ], + "type": "object" + }, + "name": "task" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.anthropic.com/v1/messages" + }, + "response": { + "body": { + "chunks": [ + "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-5-20250929\",\"id\":\"msg_01PPxairsbrK6f4zFxdfAAqS\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":6,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":1964,\"cache_creation\":{\"ephemeral_5m_input_tokens\":0,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":7,\"service_tier\":\"standard\",\"inference_geo\":\"not_available\"}}}", + "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"}}", + "event: ping\ndata: {\"type\":\"ping\"}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"SKILL_DONE\"}}", + "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0}", + "event: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":6,\"cache_creation_input_tokens\":0,\"cache_read_input_tokens\":1964,\"output_tokens\":8}}", + "event: message_stop\ndata: {\"type\":\"message_stop\"}" + ], + "kind": "sse" + }, + "headers": { + "anthropic-organization-id": "27796668-7351-40ac-acc4-024aee8995a5", + "anthropic-ratelimit-input-tokens-limit": "3000000", + "anthropic-ratelimit-input-tokens-remaining": "2999000", + "anthropic-ratelimit-input-tokens-reset": "2026-05-22T08:13:45Z", + "anthropic-ratelimit-output-tokens-limit": "600000", + "anthropic-ratelimit-output-tokens-remaining": "600000", + "anthropic-ratelimit-output-tokens-reset": "2026-05-22T08:13:45Z", + "anthropic-ratelimit-requests-limit": "20000", + "anthropic-ratelimit-requests-remaining": "19999", + "anthropic-ratelimit-requests-reset": "2026-05-22T08:13:45Z", + "anthropic-ratelimit-tokens-limit": "3600000", + "anthropic-ratelimit-tokens-remaining": "3599000", + "anthropic-ratelimit-tokens-reset": "2026-05-22T08:13:45Z", + "cache-control": "no-cache", + "cf-cache-status": "DYNAMIC", + "cf-ray": "9ffa5d0399785bad-VIE", + "connection": "keep-alive", + "content-encoding": "gzip", + "content-security-policy": "default-src 'none'; frame-ancestors 'none'", + "content-type": "text/event-stream; charset=utf-8", + "date": "Fri, 22 May 2026 08:13:49 GMT", + "request-id": "req_011CbHGm3PeHPrCu5QbjecNn", + "server": "cloudflare", + "set-cookie": "[REDACTED]", + "strict-transport-security": "max-age=31536000; includeSubDomains; preload", + "traceresponse": "00-7d974f6ca2035b3d9c8496d4b11ebfd8-fdf893f5e03b8809-01", + "transfer-encoding": "chunked", + "vary": "Accept-Encoding", + "x-envoy-upstream-service-time": "4327", + "x-robots-tag": "none" + }, + "status": 200, + "statusText": "OK" + } + }, + { + "callIndex": 4, + "id": "417e64addcf59da7", + "matchKey": "POST api.openai.com/v1/responses", + "recordedAt": "2026-05-22T08:13:50.457Z", + "request": { + "body": { + "kind": "json", + "value": { + "input": [ + { + "content": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-HpI3r1/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + "role": "system" + }, + { + "content": [ + { + "text": "Reply with exactly TASK_DONE and no other text.", + "type": "input_text" + } + ], + "role": "user" + } + ], + "model": "gpt-4o-mini", + "prompt_cache_key": "[REDACTED]", + "store": false, + "stream": true, + "tools": [ + { + "description": "Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.", + "name": "read", + "parameters": { + "properties": { + "limit": { + "description": "Maximum number of lines to read", + "type": "number" + }, + "offset": { + "description": "Line number to start from (1-indexed)", + "type": "number" + }, + "path": { + "description": "Path to the file to read", + "type": "string" + } + }, + "required": [ + "path" + ], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Write content to a file. Creates the file and parent directories if they do not exist.", + "name": "write", + "parameters": { + "properties": { + "content": { + "description": "Content to write to the file", + "type": "string" + }, + "path": { + "description": "Path to the file to write", + "type": "string" + } + }, + "required": [ + "path", + "content" + ], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.", + "name": "edit", + "parameters": { + "properties": { + "newText": { + "description": "Replacement text", + "type": "string" + }, + "oldText": { + "description": "Exact text to find (must be unique)", + "type": "string" + }, + "path": { + "description": "Path to the file to edit", + "type": "string" + }, + "replaceAll": { + "description": "Replace all occurrences", + "type": "boolean" + } + }, + "required": [ + "path", + "oldText", + "newText" + ], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.", + "name": "bash", + "parameters": { + "properties": { + "command": { + "description": "Bash command to execute", + "type": "string" + }, + "timeout": { + "description": "Timeout in seconds", + "type": "number" + } + }, + "required": [ + "command" + ], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.", + "name": "grep", + "parameters": { + "properties": { + "include": { + "description": "Glob filter, e.g. \"*.ts\"", + "type": "string" + }, + "path": { + "description": "Directory or file to search (default: .)", + "type": "string" + }, + "pattern": { + "description": "Search pattern (regex)", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Find files by filename pattern using shell find -name semantics. Returns matching file paths.", + "name": "glob", + "parameters": { + "properties": { + "path": { + "description": "Directory to search in (default: .)", + "type": "string" + }, + "pattern": { + "description": "Filename pattern, e.g. \"*.ts\"", + "type": "string" + } + }, + "required": [ + "pattern" + ], + "type": "object" + }, + "strict": false, + "type": "function" + }, + { + "description": "Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.", + "name": "task", + "parameters": { + "properties": { + "cwd": { + "description": "Working directory for the child agent. AGENTS.md and skills are discovered from here.", + "type": "string" + }, + "description": { + "description": "Short human-readable label for the delegated work", + "type": "string" + }, + "prompt": { + "description": "Focused instructions for the child agent", + "type": "string" + }, + "role": { + "description": "Role to use for the child agent", + "type": "string" + } + }, + "required": [ + "prompt" + ], + "type": "object" + }, + "strict": false, + "type": "function" + } + ] + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/responses" + }, + "response": { + "body": { + "chunks": [ + "event: response.created\ndata: {\"type\":\"response.created\",\"response\":{\"id\":\"resp_0800f965cc2ee3bf016a10103dc8c881a095690ba4dc3b63cd\",\"object\":\"response\",\"created_at\":1779437629,\"status\":\"in_progress\",\"background\":false,\"completed_at\":null,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":null,\"instructions\":null,\"max_output_tokens\":null,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":\"flue-e2e-instance::default::task:task:6ace14f1-2bce-44f2-afa7-ec\",\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"auto\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[{\"type\":\"function\",\"description\":\"Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.\",\"name\":\"read\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to read\"},\"offset\":{\"type\":\"number\",\"description\":\"Line number to start from (1-indexed)\"},\"limit\":{\"type\":\"number\",\"description\":\"Maximum number of lines to read\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Write content to a file. Creates the file and parent directories if they do not exist.\",\"name\":\"write\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"content\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to write\"},\"content\":{\"type\":\"string\",\"description\":\"Content to write to the file\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.\",\"name\":\"edit\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"oldText\",\"newText\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to edit\"},\"oldText\":{\"type\":\"string\",\"description\":\"Exact text to find (must be unique)\"},\"newText\":{\"type\":\"string\",\"description\":\"Replacement text\"},\"replaceAll\":{\"type\":\"boolean\",\"description\":\"Replace all occurrences\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.\",\"name\":\"bash\",\"parameters\":{\"type\":\"object\",\"required\":[\"command\"],\"properties\":{\"command\":{\"type\":\"string\",\"description\":\"Bash command to execute\"},\"timeout\":{\"type\":\"number\",\"description\":\"Timeout in seconds\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.\",\"name\":\"grep\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Search pattern (regex)\"},\"path\":{\"type\":\"string\",\"description\":\"Directory or file to search (default: .)\"},\"include\":{\"type\":\"string\",\"description\":\"Glob filter, e.g. \\\"*.ts\\\"\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Find files by filename pattern using shell find -name semantics. Returns matching file paths.\",\"name\":\"glob\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Filename pattern, e.g. \\\"*.ts\\\"\"},\"path\":{\"type\":\"string\",\"description\":\"Directory to search in (default: .)\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.\",\"name\":\"task\",\"parameters\":{\"type\":\"object\",\"required\":[\"prompt\"],\"properties\":{\"description\":{\"type\":\"string\",\"description\":\"Short human-readable label for the delegated work\"},\"prompt\":{\"type\":\"string\",\"description\":\"Focused instructions for the child agent\"},\"role\":{\"type\":\"string\",\"description\":\"Role to use for the child agent\"},\"cwd\":{\"type\":\"string\",\"description\":\"Working directory for the child agent. AGENTS.md and skills are discovered from here.\"}}},\"strict\":false}],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":null,\"user\":null,\"metadata\":{}},\"sequence_number\":0}", + "event: response.in_progress\ndata: {\"type\":\"response.in_progress\",\"response\":{\"id\":\"resp_0800f965cc2ee3bf016a10103dc8c881a095690ba4dc3b63cd\",\"object\":\"response\",\"created_at\":1779437629,\"status\":\"in_progress\",\"background\":false,\"completed_at\":null,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":null,\"instructions\":null,\"max_output_tokens\":null,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":\"flue-e2e-instance::default::task:task:6ace14f1-2bce-44f2-afa7-ec\",\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"auto\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[{\"type\":\"function\",\"description\":\"Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.\",\"name\":\"read\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to read\"},\"offset\":{\"type\":\"number\",\"description\":\"Line number to start from (1-indexed)\"},\"limit\":{\"type\":\"number\",\"description\":\"Maximum number of lines to read\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Write content to a file. Creates the file and parent directories if they do not exist.\",\"name\":\"write\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"content\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to write\"},\"content\":{\"type\":\"string\",\"description\":\"Content to write to the file\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.\",\"name\":\"edit\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"oldText\",\"newText\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to edit\"},\"oldText\":{\"type\":\"string\",\"description\":\"Exact text to find (must be unique)\"},\"newText\":{\"type\":\"string\",\"description\":\"Replacement text\"},\"replaceAll\":{\"type\":\"boolean\",\"description\":\"Replace all occurrences\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.\",\"name\":\"bash\",\"parameters\":{\"type\":\"object\",\"required\":[\"command\"],\"properties\":{\"command\":{\"type\":\"string\",\"description\":\"Bash command to execute\"},\"timeout\":{\"type\":\"number\",\"description\":\"Timeout in seconds\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.\",\"name\":\"grep\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Search pattern (regex)\"},\"path\":{\"type\":\"string\",\"description\":\"Directory or file to search (default: .)\"},\"include\":{\"type\":\"string\",\"description\":\"Glob filter, e.g. \\\"*.ts\\\"\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Find files by filename pattern using shell find -name semantics. Returns matching file paths.\",\"name\":\"glob\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Filename pattern, e.g. \\\"*.ts\\\"\"},\"path\":{\"type\":\"string\",\"description\":\"Directory to search in (default: .)\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.\",\"name\":\"task\",\"parameters\":{\"type\":\"object\",\"required\":[\"prompt\"],\"properties\":{\"description\":{\"type\":\"string\",\"description\":\"Short human-readable label for the delegated work\"},\"prompt\":{\"type\":\"string\",\"description\":\"Focused instructions for the child agent\"},\"role\":{\"type\":\"string\",\"description\":\"Role to use for the child agent\"},\"cwd\":{\"type\":\"string\",\"description\":\"Working directory for the child agent. AGENTS.md and skills are discovered from here.\"}}},\"strict\":false}],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":null,\"user\":null,\"metadata\":{}},\"sequence_number\":1}", + "event: response.output_item.added\ndata: {\"type\":\"response.output_item.added\",\"item\":{\"id\":\"msg_0800f965cc2ee3bf016a10103e460c81a0a9f3a24e59af07c2\",\"type\":\"message\",\"status\":\"in_progress\",\"content\":[],\"role\":\"assistant\"},\"output_index\":0,\"sequence_number\":2}", + "event: response.content_part.added\ndata: {\"type\":\"response.content_part.added\",\"content_index\":0,\"item_id\":\"msg_0800f965cc2ee3bf016a10103e460c81a0a9f3a24e59af07c2\",\"output_index\":0,\"part\":{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"\"},\"sequence_number\":3}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"TASK\",\"item_id\":\"msg_0800f965cc2ee3bf016a10103e460c81a0a9f3a24e59af07c2\",\"logprobs\":[],\"obfuscation\":\"Go0E8XPESm7z\",\"output_index\":0,\"sequence_number\":4}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"_DONE\",\"item_id\":\"msg_0800f965cc2ee3bf016a10103e460c81a0a9f3a24e59af07c2\",\"logprobs\":[],\"obfuscation\":\"c8DB1CtA3S6\",\"output_index\":0,\"sequence_number\":5}", + "event: response.output_text.done\ndata: {\"type\":\"response.output_text.done\",\"content_index\":0,\"item_id\":\"msg_0800f965cc2ee3bf016a10103e460c81a0a9f3a24e59af07c2\",\"logprobs\":[],\"output_index\":0,\"sequence_number\":6,\"text\":\"TASK_DONE\"}", + "event: response.content_part.done\ndata: {\"type\":\"response.content_part.done\",\"content_index\":0,\"item_id\":\"msg_0800f965cc2ee3bf016a10103e460c81a0a9f3a24e59af07c2\",\"output_index\":0,\"part\":{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"TASK_DONE\"},\"sequence_number\":7}", + "event: response.output_item.done\ndata: {\"type\":\"response.output_item.done\",\"item\":{\"id\":\"msg_0800f965cc2ee3bf016a10103e460c81a0a9f3a24e59af07c2\",\"type\":\"message\",\"status\":\"completed\",\"content\":[{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"TASK_DONE\"}],\"role\":\"assistant\"},\"output_index\":0,\"sequence_number\":8}", + "event: response.completed\ndata: {\"type\":\"response.completed\",\"response\":{\"id\":\"resp_0800f965cc2ee3bf016a10103dc8c881a095690ba4dc3b63cd\",\"object\":\"response\",\"created_at\":1779437629,\"status\":\"completed\",\"background\":false,\"completed_at\":1779437630,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":null,\"instructions\":null,\"max_output_tokens\":null,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[{\"id\":\"msg_0800f965cc2ee3bf016a10103e460c81a0a9f3a24e59af07c2\",\"type\":\"message\",\"status\":\"completed\",\"content\":[{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"TASK_DONE\"}],\"role\":\"assistant\"}],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":\"flue-e2e-instance::default::task:task:6ace14f1-2bce-44f2-afa7-ec\",\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"default\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[{\"type\":\"function\",\"description\":\"Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.\",\"name\":\"read\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to read\"},\"offset\":{\"type\":\"number\",\"description\":\"Line number to start from (1-indexed)\"},\"limit\":{\"type\":\"number\",\"description\":\"Maximum number of lines to read\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Write content to a file. Creates the file and parent directories if they do not exist.\",\"name\":\"write\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"content\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to write\"},\"content\":{\"type\":\"string\",\"description\":\"Content to write to the file\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.\",\"name\":\"edit\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"oldText\",\"newText\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to edit\"},\"oldText\":{\"type\":\"string\",\"description\":\"Exact text to find (must be unique)\"},\"newText\":{\"type\":\"string\",\"description\":\"Replacement text\"},\"replaceAll\":{\"type\":\"boolean\",\"description\":\"Replace all occurrences\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.\",\"name\":\"bash\",\"parameters\":{\"type\":\"object\",\"required\":[\"command\"],\"properties\":{\"command\":{\"type\":\"string\",\"description\":\"Bash command to execute\"},\"timeout\":{\"type\":\"number\",\"description\":\"Timeout in seconds\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.\",\"name\":\"grep\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Search pattern (regex)\"},\"path\":{\"type\":\"string\",\"description\":\"Directory or file to search (default: .)\"},\"include\":{\"type\":\"string\",\"description\":\"Glob filter, e.g. \\\"*.ts\\\"\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Find files by filename pattern using shell find -name semantics. Returns matching file paths.\",\"name\":\"glob\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Filename pattern, e.g. \\\"*.ts\\\"\"},\"path\":{\"type\":\"string\",\"description\":\"Directory to search in (default: .)\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.\",\"name\":\"task\",\"parameters\":{\"type\":\"object\",\"required\":[\"prompt\"],\"properties\":{\"description\":{\"type\":\"string\",\"description\":\"Short human-readable label for the delegated work\"},\"prompt\":{\"type\":\"string\",\"description\":\"Focused instructions for the child agent\"},\"role\":{\"type\":\"string\",\"description\":\"Role to use for the child agent\"},\"cwd\":{\"type\":\"string\",\"description\":\"Working directory for the child agent. AGENTS.md and skills are discovered from here.\"}}},\"strict\":false}],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":{\"input_tokens\":772,\"input_tokens_details\":{\"cached_tokens\":0},\"output_tokens\":4,\"output_tokens_details\":{\"reasoning_tokens\":0},\"total_tokens\":776},\"user\":null,\"metadata\":{}},\"sequence_number\":9}" + ], + "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": "9ffa5d21691b804e-VIE", + "connection": "keep-alive", + "content-type": "text/event-stream; charset=utf-8", + "date": "Fri, 22 May 2026 08:13:49 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "147", + "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-request-id": "req_263405117afd4b089db94fe44182edb4" + }, + "status": 200, + "statusText": "OK" + } + }, + { + "callIndex": 5, + "id": "341675a0a1a88c63", + "matchKey": "POST api.openai.com/v1/responses", + "recordedAt": "2026-05-22T08:13:51.643Z", + "request": { + "body": { + "kind": "json", + "value": { + "input": [ + { + "content": "You are a context summarization assistant. Your task is to read a conversation between a user and an AI coding assistant, then produce a structured summary following the exact format specified.\n\nDo NOT continue the conversation. Do NOT respond to any questions in the conversation. ONLY output the structured summary.", + "role": "system" + }, + { + "content": [ + { + "text": "\n[User]: Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.\n\n[Assistant tool calls]: lookup(query=\"flue instrumentation\")\n\n[Tool result]: {\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}\n\n[Assistant tool calls]: web_search(lookupId=\"flue-session-2026\", query=\"Braintrust Flue reasoning stream instrumentation\")\n\n[Tool result]: {\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\",\"results\":[{\"title\":\"Flue reasoning stream instrumentation\",\"url\":\"https://example.test/flue/reasoning-streams\"}]}\n\n[Assistant tool calls]: summarize_source(url=\"https://example.test/flue/reasoning-streams\")\n\n[Tool result]: {\"summary\":\"Flue emits reasoning, tool execution, and LLM turn events separately.\",\"url\":\"https://example.test/flue/reasoning-streams\"}\n\n\nThis is the PREFIX of a turn that was too large to keep. The SUFFIX (recent work) is retained.\n\nSummarize the prefix to provide context for the retained suffix:\n\n## Original Request\n[What did the user ask for in this turn?]\n\n## Early Progress\n- [Key decisions and work done in the prefix]\n\n## Context for Suffix\n- [Information needed to understand the retained recent work]\n\nBe concise. Focus on what's needed to understand the kept suffix.", + "type": "input_text" + } + ], + "role": "user" + } + ], + "max_output_tokens": 32, + "model": "gpt-4o-mini", + "store": false, + "stream": true + } + }, + "headers": {}, + "method": "POST", + "url": "https://api.openai.com/v1/responses" + }, + "response": { + "body": { + "chunks": [ + "event: response.created\ndata: {\"type\":\"response.created\",\"response\":{\"id\":\"resp_084209f23358c95f016a10103e99148191bdeabe7e91f87320\",\"object\":\"response\",\"created_at\":1779437630,\"status\":\"in_progress\",\"background\":false,\"completed_at\":null,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":null,\"instructions\":null,\"max_output_tokens\":32,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":null,\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"auto\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":null,\"user\":null,\"metadata\":{}},\"sequence_number\":0}", + "event: response.in_progress\ndata: {\"type\":\"response.in_progress\",\"response\":{\"id\":\"resp_084209f23358c95f016a10103e99148191bdeabe7e91f87320\",\"object\":\"response\",\"created_at\":1779437630,\"status\":\"in_progress\",\"background\":false,\"completed_at\":null,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":null,\"instructions\":null,\"max_output_tokens\":32,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":null,\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"auto\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":null,\"user\":null,\"metadata\":{}},\"sequence_number\":1}", + "event: response.output_item.added\ndata: {\"type\":\"response.output_item.added\",\"item\":{\"id\":\"msg_084209f23358c95f016a10103efe4c819198d1e2ffc5e641b7\",\"type\":\"message\",\"status\":\"in_progress\",\"content\":[],\"role\":\"assistant\"},\"output_index\":0,\"sequence_number\":2}", + "event: response.content_part.added\ndata: {\"type\":\"response.content_part.added\",\"content_index\":0,\"item_id\":\"msg_084209f23358c95f016a10103efe4c819198d1e2ffc5e641b7\",\"output_index\":0,\"part\":{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"\"},\"sequence_number\":3}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"##\",\"item_id\":\"msg_084209f23358c95f016a10103efe4c819198d1e2ffc5e641b7\",\"logprobs\":[],\"obfuscation\":\"M3AlJ8uMZsMVoT\",\"output_index\":0,\"sequence_number\":4}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" Original\",\"item_id\":\"msg_084209f23358c95f016a10103efe4c819198d1e2ffc5e641b7\",\"logprobs\":[],\"obfuscation\":\"YRs1ktR\",\"output_index\":0,\"sequence_number\":5}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" Request\",\"item_id\":\"msg_084209f23358c95f016a10103efe4c819198d1e2ffc5e641b7\",\"logprobs\":[],\"obfuscation\":\"G9k88ga0\",\"output_index\":0,\"sequence_number\":6}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"\\n\",\"item_id\":\"msg_084209f23358c95f016a10103efe4c819198d1e2ffc5e641b7\",\"logprobs\":[],\"obfuscation\":\"UdQRtbAIKPoI5Km\",\"output_index\":0,\"sequence_number\":7}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"The\",\"item_id\":\"msg_084209f23358c95f016a10103efe4c819198d1e2ffc5e641b7\",\"logprobs\":[],\"obfuscation\":\"lU0pjFQSm1oEq\",\"output_index\":0,\"sequence_number\":8}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" user\",\"item_id\":\"msg_084209f23358c95f016a10103efe4c819198d1e2ffc5e641b7\",\"logprobs\":[],\"obfuscation\":\"tYWoiXmPt3i\",\"output_index\":0,\"sequence_number\":9}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" requested\",\"item_id\":\"msg_084209f23358c95f016a10103efe4c819198d1e2ffc5e641b7\",\"logprobs\":[],\"obfuscation\":\"UGYnE6\",\"output_index\":0,\"sequence_number\":10}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" to\",\"item_id\":\"msg_084209f23358c95f016a10103efe4c819198d1e2ffc5e641b7\",\"logprobs\":[],\"obfuscation\":\"Y8c0jT6nW4GwE\",\"output_index\":0,\"sequence_number\":11}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" complete\",\"item_id\":\"msg_084209f23358c95f016a10103efe4c819198d1e2ffc5e641b7\",\"logprobs\":[],\"obfuscation\":\"0YSVIf1\",\"output_index\":0,\"sequence_number\":12}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" an\",\"item_id\":\"msg_084209f23358c95f016a10103efe4c819198d1e2ffc5e641b7\",\"logprobs\":[],\"obfuscation\":\"2lzdKxno9owFI\",\"output_index\":0,\"sequence_number\":13}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" instrument\",\"item_id\":\"msg_084209f23358c95f016a10103efe4c819198d1e2ffc5e641b7\",\"logprobs\":[],\"obfuscation\":\"Yk3lI\",\"output_index\":0,\"sequence_number\":14}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"ed\",\"item_id\":\"msg_084209f23358c95f016a10103efe4c819198d1e2ffc5e641b7\",\"logprobs\":[],\"obfuscation\":\"yNJ7UNf6JCrgfT\",\"output_index\":0,\"sequence_number\":15}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" research\",\"item_id\":\"msg_084209f23358c95f016a10103efe4c819198d1e2ffc5e641b7\",\"logprobs\":[],\"obfuscation\":\"h6fKawz\",\"output_index\":0,\"sequence_number\":16}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" flow\",\"item_id\":\"msg_084209f23358c95f016a10103efe4c819198d1e2ffc5e641b7\",\"logprobs\":[],\"obfuscation\":\"RobYTvkiCGN\",\"output_index\":0,\"sequence_number\":17}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" involving\",\"item_id\":\"msg_084209f23358c95f016a10103efe4c819198d1e2ffc5e641b7\",\"logprobs\":[],\"obfuscation\":\"NUS4Lz\",\"output_index\":0,\"sequence_number\":18}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" multiple\",\"item_id\":\"msg_084209f23358c95f016a10103efe4c819198d1e2ffc5e641b7\",\"logprobs\":[],\"obfuscation\":\"AGsmURG\",\"output_index\":0,\"sequence_number\":19}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" steps\",\"item_id\":\"msg_084209f23358c95f016a10103efe4c819198d1e2ffc5e641b7\",\"logprobs\":[],\"obfuscation\":\"W5EQuh9xDq\",\"output_index\":0,\"sequence_number\":20}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" using\",\"item_id\":\"msg_084209f23358c95f016a10103efe4c819198d1e2ffc5e641b7\",\"logprobs\":[],\"obfuscation\":\"HBLHpXQoEi\",\"output_index\":0,\"sequence_number\":21}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" tool\",\"item_id\":\"msg_084209f23358c95f016a10103efe4c819198d1e2ffc5e641b7\",\"logprobs\":[],\"obfuscation\":\"PdXhCFHWTZ4\",\"output_index\":0,\"sequence_number\":22}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" calls\",\"item_id\":\"msg_084209f23358c95f016a10103efe4c819198d1e2ffc5e641b7\",\"logprobs\":[],\"obfuscation\":\"EYtOQjpO1R\",\"output_index\":0,\"sequence_number\":23}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" for\",\"item_id\":\"msg_084209f23358c95f016a10103efe4c819198d1e2ffc5e641b7\",\"logprobs\":[],\"obfuscation\":\"0lXKd0r4r8cU\",\"output_index\":0,\"sequence_number\":24}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" gathering\",\"item_id\":\"msg_084209f23358c95f016a10103efe4c819198d1e2ffc5e641b7\",\"logprobs\":[],\"obfuscation\":\"ovBPeL\",\"output_index\":0,\"sequence_number\":25}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" information\",\"item_id\":\"msg_084209f23358c95f016a10103efe4c819198d1e2ffc5e641b7\",\"logprobs\":[],\"obfuscation\":\"SVxw\",\"output_index\":0,\"sequence_number\":26}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" about\",\"item_id\":\"msg_084209f23358c95f016a10103efe4c819198d1e2ffc5e641b7\",\"logprobs\":[],\"obfuscation\":\"0LRneRdeVW\",\"output_index\":0,\"sequence_number\":27}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" \\\"\",\"item_id\":\"msg_084209f23358c95f016a10103efe4c819198d1e2ffc5e641b7\",\"logprobs\":[],\"obfuscation\":\"vz8P6a81mJNQMW\",\"output_index\":0,\"sequence_number\":28}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"fl\",\"item_id\":\"msg_084209f23358c95f016a10103efe4c819198d1e2ffc5e641b7\",\"logprobs\":[],\"obfuscation\":\"dla16TkzpV6RXX\",\"output_index\":0,\"sequence_number\":29}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"ue\",\"item_id\":\"msg_084209f23358c95f016a10103efe4c819198d1e2ffc5e641b7\",\"logprobs\":[],\"obfuscation\":\"Fu8Auj66IJgtKJ\",\"output_index\":0,\"sequence_number\":30}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" instrumentation\",\"item_id\":\"msg_084209f23358c95f016a10103efe4c819198d1e2ffc5e641b7\",\"logprobs\":[],\"obfuscation\":\"\",\"output_index\":0,\"sequence_number\":31}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\".\\\"\\n\\n\",\"item_id\":\"msg_084209f23358c95f016a10103efe4c819198d1e2ffc5e641b7\",\"logprobs\":[],\"obfuscation\":\"2kTOhzqCpyYt\",\"output_index\":0,\"sequence_number\":32}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"##\",\"item_id\":\"msg_084209f23358c95f016a10103efe4c819198d1e2ffc5e641b7\",\"logprobs\":[],\"obfuscation\":\"VMTlx6jKXne4i6\",\"output_index\":0,\"sequence_number\":33}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" Early\",\"item_id\":\"msg_084209f23358c95f016a10103efe4c819198d1e2ffc5e641b7\",\"logprobs\":[],\"obfuscation\":\"NKfnbY22gK\",\"output_index\":0,\"sequence_number\":34}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" Progress\",\"item_id\":\"msg_084209f23358c95f016a10103efe4c819198d1e2ffc5e641b7\",\"logprobs\":[],\"obfuscation\":\"j26oekx\",\"output_index\":0,\"sequence_number\":35}", + "event: response.output_text.done\ndata: {\"type\":\"response.output_text.done\",\"content_index\":0,\"item_id\":\"msg_084209f23358c95f016a10103efe4c819198d1e2ffc5e641b7\",\"logprobs\":[],\"output_index\":0,\"sequence_number\":36,\"text\":\"## Original Request\\nThe user requested to complete an instrumented research flow involving multiple steps using tool calls for gathering information about \\\"flue instrumentation.\\\"\\n\\n## Early Progress\"}", + "event: response.content_part.done\ndata: {\"type\":\"response.content_part.done\",\"content_index\":0,\"item_id\":\"msg_084209f23358c95f016a10103efe4c819198d1e2ffc5e641b7\",\"output_index\":0,\"part\":{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"## Original Request\\nThe user requested to complete an instrumented research flow involving multiple steps using tool calls for gathering information about \\\"flue instrumentation.\\\"\\n\\n## Early Progress\"},\"sequence_number\":37}", + "event: response.output_item.done\ndata: {\"type\":\"response.output_item.done\",\"item\":{\"id\":\"msg_084209f23358c95f016a10103efe4c819198d1e2ffc5e641b7\",\"type\":\"message\",\"status\":\"incomplete\",\"content\":[{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"## Original Request\\nThe user requested to complete an instrumented research flow involving multiple steps using tool calls for gathering information about \\\"flue instrumentation.\\\"\\n\\n## Early Progress\"}],\"role\":\"assistant\"},\"output_index\":0,\"sequence_number\":38}", + "event: response.incomplete\ndata: {\"type\":\"response.incomplete\",\"response\":{\"id\":\"resp_084209f23358c95f016a10103e99148191bdeabe7e91f87320\",\"object\":\"response\",\"created_at\":1779437630,\"status\":\"incomplete\",\"background\":false,\"completed_at\":null,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":{\"reason\":\"max_output_tokens\"},\"instructions\":null,\"max_output_tokens\":32,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[{\"id\":\"msg_084209f23358c95f016a10103efe4c819198d1e2ffc5e641b7\",\"type\":\"message\",\"status\":\"incomplete\",\"content\":[{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"## Original Request\\nThe user requested to complete an instrumented research flow involving multiple steps using tool calls for gathering information about \\\"flue instrumentation.\\\"\\n\\n## Early Progress\"}],\"role\":\"assistant\"}],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":null,\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"default\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":{\"input_tokens\":446,\"input_tokens_details\":{\"cached_tokens\":0},\"output_tokens\":32,\"output_tokens_details\":{\"reasoning_tokens\":0},\"total_tokens\":478},\"user\":null,\"metadata\":{}},\"sequence_number\":39}" + ], + "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": "9ffa5d26bae4804e-VIE", + "connection": "keep-alive", + "content-type": "text/event-stream; charset=utf-8", + "date": "Fri, 22 May 2026 08:13:50 GMT", + "openai-organization": "braintrust-data", + "openai-processing-ms": "74", + "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-request-id": "req_cf1aa4da0406473ba47a8cddb664cb57" + }, + "status": 200, + "statusText": "OK" + } + } + ], + "meta": { + "createdAt": "2026-05-22T08:11:35.765Z" + } +} diff --git a/e2e/scenarios/flue-instrumentation/__cassettes__/flue-v0-7-0-wrapped.cassette.json b/e2e/scenarios/flue-instrumentation/__cassettes__/flue-v0-7-0-wrapped.cassette.json index 111d4cbd0..b9338ade6 100644 --- a/e2e/scenarios/flue-instrumentation/__cassettes__/flue-v0-7-0-wrapped.cassette.json +++ b/e2e/scenarios/flue-instrumentation/__cassettes__/flue-v0-7-0-wrapped.cassette.json @@ -4,7 +4,7 @@ "callIndex": 0, "id": "fcd9d51c145fb90b", "matchKey": "POST api.anthropic.com/v1/messages", - "recordedAt": "2026-05-21T06:48:36.059Z", + "recordedAt": "2026-05-22T08:12:53.397Z", "request": { "body": { "kind": "json", @@ -31,7 +31,7 @@ "cache_control": { "type": "ephemeral" }, - "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Thu, May 21, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-LqmoTW/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-HpI3r1/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", "type": "text" } ], @@ -59,7 +59,9 @@ "type": "string" } }, - "required": ["path"], + "required": [ + "path" + ], "type": "object" }, "name": "read" @@ -78,7 +80,10 @@ "type": "string" } }, - "required": ["path", "content"], + "required": [ + "path", + "content" + ], "type": "object" }, "name": "write" @@ -105,7 +110,11 @@ "type": "boolean" } }, - "required": ["path", "oldText", "newText"], + "required": [ + "path", + "oldText", + "newText" + ], "type": "object" }, "name": "edit" @@ -124,7 +133,9 @@ "type": "number" } }, - "required": ["command"], + "required": [ + "command" + ], "type": "object" }, "name": "bash" @@ -147,7 +158,9 @@ "type": "string" } }, - "required": ["pattern"], + "required": [ + "pattern" + ], "type": "object" }, "name": "grep" @@ -166,7 +179,9 @@ "type": "string" } }, - "required": ["pattern"], + "required": [ + "pattern" + ], "type": "object" }, "name": "glob" @@ -193,7 +208,9 @@ "type": "string" } }, - "required": ["prompt"], + "required": [ + "prompt" + ], "type": "object" }, "name": "task" @@ -207,7 +224,9 @@ "type": "string" } }, - "required": ["query"], + "required": [ + "query" + ], "type": "object" }, "name": "lookup" @@ -224,7 +243,10 @@ "type": "string" } }, - "required": ["lookupId", "query"], + "required": [ + "lookupId", + "query" + ], "type": "object" }, "name": "web_search" @@ -241,7 +263,9 @@ "type": "string" } }, - "required": ["url"], + "required": [ + "url" + ], "type": "object" }, "name": "summarize_source" @@ -256,25 +280,25 @@ "response": { "body": { "chunks": [ - "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-5-20250929\",\"id\":\"msg_01SM4G3aUCHLPmaurSygvHCw\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":10,\"cache_creation_input_tokens\":885,\"cache_read_input_tokens\":1297,\"cache_creation\":{\"ephemeral_5m_input_tokens\":885,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":7,\"service_tier\":\"standard\",\"inference_geo\":\"not_available\"}}}", + "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-5-20250929\",\"id\":\"msg_01CABc2tEXNTVK5CC2yf1dBR\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":10,\"cache_creation_input_tokens\":887,\"cache_read_input_tokens\":1297,\"cache_creation\":{\"ephemeral_5m_input_tokens\":887,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":6,\"service_tier\":\"standard\",\"inference_geo\":\"not_available\"}}}", "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"thinking\",\"thinking\":\"\",\"signature\":\"\"}}", "event: ping\ndata: {\"type\":\"ping\"}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\"The user wants me to complete an\"}}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\" instrumented research flow with exactly three steps:\\n1. Call lookup with query \\\"flue instrumentation\\\"\\n2. Use the lookup result id to call\"}}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\" web_search with query \\\"Braintrust Flue reasoning stream instrumentation\\\"\\n3. Use the first web_search result url to call summarize_source\\n4. After that, reply with exactly \\\"PROMPT_DONE\\\"\\n\\nThe\"}}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\" user also emphasizes that I should call exactly one tool per turn and wait for each tool result before choosing the next tool.\\n\\nLet me start with Step 1: calling\"}}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\" lookup with query \\\"flue instrumentation\\\".\"}}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"signature_delta\",\"signature\":\"EoUGCm4IDRgCKkBGG1EQWIA9O/tsHYduxoTUS/i0gICgUs3GdrJlpnNSzO7qWVpXyAV/QYunxiJ/pbuy1AxKmw6zIb/6D5H7ZGWfMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMRXKds4wYcGMYouIkGgwZoj3tniSPvjyfUQ0iMJTYUR1cOzdSxBk9UN+23wtgAo9/8kEQNV+xOUHpUah0CvD2CK4e6+Mxn9U0PvwTTyrEBACjWEoJTpmbj0w1MNh5K+OwmDdBIpCbBeZgNfwk/5hZlooub3A2Da3jc6kIQPcSJAyzDcURqiosMVZblqqzxHM/aEXrQka5eZe/CELGEOZLcy2L0sRYjYzcKh+2/4hKScq3jltGM/MwmdE0y1P21raJdOxIpcXaIyQDncBiL9EQ3oPmRuhDHM9giLQaRdA8spWQs8P15X7ZcxxaVV4bI26aJoQa9/BoEBqDbNGNi0jPABVoEoUprtXqNJcl3lb4GUerTKVvEPlXluwJbN0ozQ3j9v8GGqqHlAe5J4WpjO3RA5CjKU6poKdB+CW2/MjTMA5noiDFJzqE5krdR/ll4UusUXFv+DYdLIXvm/RF/EGZa1FAmk+knqhbodSkL78m/AKpDOHNH9qymwstVSQP5IH8Xt6jE6olgXNLIHqmztPCsHYGoli+2FajT98T22xZJ/i9UPJyg+w800UtLCVzwa5Abx98Vodu7zyqZFAQ5HwWf9uY4f2T/tCjoPluiIZVb0nTUHziOnvsCpNQVWWi1eWMM6wUmfcki0TDlXaW2CNcBFSpmehGHwN3qjs2iDUG6w7MAo1hMjkKuUdalXTBqFbDa/EoEXIf4gpyNgXB0b5rzLGb8CisCONKT/PT788R7ZbjWrOqxtpIouGWqD0rvVgkGjBnuJ8EhIn1lkn1QXhqLZhcPsR7fal7rM2NRPVdD5fcI/NS9nIHo/Zx3i25gC0jd3hY+Eihl+f2C9K7f7kq78R2tUf62Sjc8XMy/QVWfsogYLIYAQ==\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\"The user wants me to complete\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\" an instrumented research flow with specific steps:\\n1. Call lookup with query \\\"flue instrumentation\\\"\\n2. Use the lookup result id to call web_search with query \\\"Braintrust Flue reasoning stream instru\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\"mentation\\\"\\n3. Use the first web_search result url to call summarize_source\\n4. After summarize_source returns, reply with exactly \\\"PROMPT_DONE\\\"\\n\\nI need to call\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\" exactly one tool per turn and wait for each result. Let me start with step 1.\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"signature_delta\",\"signature\":\"EqEFCm4IDRgCKkCx4PeMntf8BRtpLH8OUwiMP53HIajGG0HN/LJgm9YmzwCzrRIdbPW6+RRfidn7le5y+DuWJ3BPl1JgKETNcGOcMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMgjs71MGxsxVHe7zLGgzslRkkjDTjHfOSe/QiMJwuB3ScB/LBWqEoaFVkSh1fQFtJgiUlle/UZtA34zfIz7K6LGnqxb1BZAkBKY2o6SrgA7XVIYhi9V8+7n5o2vSbR9Zu5X2ZL4DZxghVngkmw1K9A8fDUjAkwBV34qSMLqozFC4JbcWTpTHqw4HwJ43B4w8pYoeg67QyIwTtH4c+pU5Z6oMzC/9ruNsH/rb6sFceHQb/g/cUAmfV+S4feseEfrHeGpQwzx146NNee8FuICbOSdVDmUa90b+tzHzXjnolSPgMKFbCWX7lCFLbcfDaBxMNcX9BkOUSLfc4/utTn0C38rYhOKzK//A3al4mh5cxYaNZ73KatbFZL4MLPMuT9f44NswmPylRhtcUCgcjP1eal+E8lWzZjX+7DhAzpyPqUY1ZrUVV6GlTddiE3VapSGS5ixtIdgNW6X5jA2W5NiKB1WWaF6aH1PTWPa6PgKIf9+lpHFJcPeeqhskWHV+w9L7Wcjlm7uRg3B+uFBUyEfw1jgsX+wFfGfCq5rEbVk0jjeG498UD1CzeZwdlsKRA5/2laXqk8Migrbqbw95Bhm1D8muVTftvvPkmrBh9rH7Nh2qfgNKBAx5rtQikbnN8299/33EBXQ7CKzByr9aaLVt6CDX4+6m2qGwCi7gXCHur3n4fUZ/aAoo1xb58QUeXwQriGVBzMF5MZ3PuuDQaQTTOHcP0kzTJe4kiP7TWow+9TRgB\"}}", "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0}", "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":1,\"content_block\":{\"type\":\"text\",\"text\":\"\"}}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"text_delta\",\"text\":\"I'll complete this instrumented research flow step by step. Starting with Step 1:\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"text_delta\",\"text\":\"I'll complete\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"text_delta\",\"text\":\" this instrumented research flow step by step. Starting with Step 1:\"}}", "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":1}", - "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":2,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01GD2k3M7867B4B2MdjCqVrG\",\"name\":\"lookup\",\"input\":{},\"caller\":{\"type\":\"direct\"}}}", + "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":2,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01QcDKhyMNiU8Df4agjz1yt2\",\"name\":\"lookup\",\"input\":{},\"caller\":{\"type\":\"direct\"}}}", "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"}}", "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"query\\\": \\\"flue instrumentation\"}}", "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"}\"}}", "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":2}", - "event: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":10,\"cache_creation_input_tokens\":885,\"cache_read_input_tokens\":1297,\"output_tokens\":217}}", + "event: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":10,\"cache_creation_input_tokens\":887,\"cache_read_input_tokens\":1297,\"output_tokens\":198}}", "event: message_stop\ndata: {\"type\":\"message_stop\"}" ], "kind": "sse" @@ -283,32 +307,32 @@ "anthropic-organization-id": "27796668-7351-40ac-acc4-024aee8995a5", "anthropic-ratelimit-input-tokens-limit": "3000000", "anthropic-ratelimit-input-tokens-remaining": "2999000", - "anthropic-ratelimit-input-tokens-reset": "2026-05-21T06:48:32Z", + "anthropic-ratelimit-input-tokens-reset": "2026-05-22T08:12:48Z", "anthropic-ratelimit-output-tokens-limit": "600000", "anthropic-ratelimit-output-tokens-remaining": "600000", - "anthropic-ratelimit-output-tokens-reset": "2026-05-21T06:48:32Z", + "anthropic-ratelimit-output-tokens-reset": "2026-05-22T08:12:48Z", "anthropic-ratelimit-requests-limit": "20000", "anthropic-ratelimit-requests-remaining": "19999", - "anthropic-ratelimit-requests-reset": "2026-05-21T06:48:32Z", + "anthropic-ratelimit-requests-reset": "2026-05-22T08:12:48Z", "anthropic-ratelimit-tokens-limit": "3600000", "anthropic-ratelimit-tokens-remaining": "3599000", - "anthropic-ratelimit-tokens-reset": "2026-05-21T06:48:32Z", + "anthropic-ratelimit-tokens-reset": "2026-05-22T08:12:48Z", "cache-control": "no-cache", "cf-cache-status": "DYNAMIC", - "cf-ray": "9ff1a2d24f775b94-VIE", + "cf-ray": "9ffa5ba3dd855db9-VIE", "connection": "keep-alive", "content-encoding": "gzip", "content-security-policy": "default-src 'none'; frame-ancestors 'none'", "content-type": "text/event-stream; charset=utf-8", - "date": "Thu, 21 May 2026 06:48:33 GMT", - "request-id": "req_011CbFGTGEoBYWfGWrG8AWpG", + "date": "Fri, 22 May 2026 08:12:51 GMT", + "request-id": "req_011CbHGgtheP2Dveyaa7uo66", "server": "cloudflare", "set-cookie": "[REDACTED]", "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "traceresponse": "00-82368401eaf4c73a1631ded37323150e-994a044e3d1c5ec7-01", + "traceresponse": "00-f3a9a8447ed937d2e123e98c32a04096-799d23e561c9e80a-01", "transfer-encoding": "chunked", "vary": "Accept-Encoding", - "x-envoy-upstream-service-time": "1246", + "x-envoy-upstream-service-time": "2523", "x-robots-tag": "none" }, "status": 200, @@ -319,7 +343,7 @@ "callIndex": 1, "id": "ff22a182ea5a9c06", "matchKey": "POST api.anthropic.com/v1/messages", - "recordedAt": "2026-05-21T06:48:39.636Z", + "recordedAt": "2026-05-22T08:12:57.115Z", "request": { "body": { "kind": "json", @@ -338,8 +362,8 @@ { "content": [ { - "signature": "EoUGCm4IDRgCKkBGG1EQWIA9O/tsHYduxoTUS/i0gICgUs3GdrJlpnNSzO7qWVpXyAV/QYunxiJ/pbuy1AxKmw6zIb/6D5H7ZGWfMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMRXKds4wYcGMYouIkGgwZoj3tniSPvjyfUQ0iMJTYUR1cOzdSxBk9UN+23wtgAo9/8kEQNV+xOUHpUah0CvD2CK4e6+Mxn9U0PvwTTyrEBACjWEoJTpmbj0w1MNh5K+OwmDdBIpCbBeZgNfwk/5hZlooub3A2Da3jc6kIQPcSJAyzDcURqiosMVZblqqzxHM/aEXrQka5eZe/CELGEOZLcy2L0sRYjYzcKh+2/4hKScq3jltGM/MwmdE0y1P21raJdOxIpcXaIyQDncBiL9EQ3oPmRuhDHM9giLQaRdA8spWQs8P15X7ZcxxaVV4bI26aJoQa9/BoEBqDbNGNi0jPABVoEoUprtXqNJcl3lb4GUerTKVvEPlXluwJbN0ozQ3j9v8GGqqHlAe5J4WpjO3RA5CjKU6poKdB+CW2/MjTMA5noiDFJzqE5krdR/ll4UusUXFv+DYdLIXvm/RF/EGZa1FAmk+knqhbodSkL78m/AKpDOHNH9qymwstVSQP5IH8Xt6jE6olgXNLIHqmztPCsHYGoli+2FajT98T22xZJ/i9UPJyg+w800UtLCVzwa5Abx98Vodu7zyqZFAQ5HwWf9uY4f2T/tCjoPluiIZVb0nTUHziOnvsCpNQVWWi1eWMM6wUmfcki0TDlXaW2CNcBFSpmehGHwN3qjs2iDUG6w7MAo1hMjkKuUdalXTBqFbDa/EoEXIf4gpyNgXB0b5rzLGb8CisCONKT/PT788R7ZbjWrOqxtpIouGWqD0rvVgkGjBnuJ8EhIn1lkn1QXhqLZhcPsR7fal7rM2NRPVdD5fcI/NS9nIHo/Zx3i25gC0jd3hY+Eihl+f2C9K7f7kq78R2tUf62Sjc8XMy/QVWfsogYLIYAQ==", - "thinking": "The user wants me to complete an instrumented research flow with exactly three steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id to call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url to call summarize_source\n4. After that, reply with exactly \"PROMPT_DONE\"\n\nThe user also emphasizes that I should call exactly one tool per turn and wait for each tool result before choosing the next tool.\n\nLet me start with Step 1: calling lookup with query \"flue instrumentation\".", + "signature": "EqEFCm4IDRgCKkCx4PeMntf8BRtpLH8OUwiMP53HIajGG0HN/LJgm9YmzwCzrRIdbPW6+RRfidn7le5y+DuWJ3BPl1JgKETNcGOcMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMgjs71MGxsxVHe7zLGgzslRkkjDTjHfOSe/QiMJwuB3ScB/LBWqEoaFVkSh1fQFtJgiUlle/UZtA34zfIz7K6LGnqxb1BZAkBKY2o6SrgA7XVIYhi9V8+7n5o2vSbR9Zu5X2ZL4DZxghVngkmw1K9A8fDUjAkwBV34qSMLqozFC4JbcWTpTHqw4HwJ43B4w8pYoeg67QyIwTtH4c+pU5Z6oMzC/9ruNsH/rb6sFceHQb/g/cUAmfV+S4feseEfrHeGpQwzx146NNee8FuICbOSdVDmUa90b+tzHzXjnolSPgMKFbCWX7lCFLbcfDaBxMNcX9BkOUSLfc4/utTn0C38rYhOKzK//A3al4mh5cxYaNZ73KatbFZL4MLPMuT9f44NswmPylRhtcUCgcjP1eal+E8lWzZjX+7DhAzpyPqUY1ZrUVV6GlTddiE3VapSGS5ixtIdgNW6X5jA2W5NiKB1WWaF6aH1PTWPa6PgKIf9+lpHFJcPeeqhskWHV+w9L7Wcjlm7uRg3B+uFBUyEfw1jgsX+wFfGfCq5rEbVk0jjeG498UD1CzeZwdlsKRA5/2laXqk8Migrbqbw95Bhm1D8muVTftvvPkmrBh9rH7Nh2qfgNKBAx5rtQikbnN8299/33EBXQ7CKzByr9aaLVt6CDX4+6m2qGwCi7gXCHur3n4fUZ/aAoo1xb58QUeXwQriGVBzMF5MZ3PuuDQaQTTOHcP0kzTJe4kiP7TWow+9TRgB", + "thinking": "The user wants me to complete an instrumented research flow with specific steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id to call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url to call summarize_source\n4. After summarize_source returns, reply with exactly \"PROMPT_DONE\"\n\nI need to call exactly one tool per turn and wait for each result. Let me start with step 1.", "type": "thinking" }, { @@ -347,7 +371,7 @@ "type": "text" }, { - "id": "toolu_01GD2k3M7867B4B2MdjCqVrG", + "id": "toolu_01QcDKhyMNiU8Df4agjz1yt2", "input": { "query": "flue instrumentation" }, @@ -365,7 +389,7 @@ }, "content": "{\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}", "is_error": false, - "tool_use_id": "toolu_01GD2k3M7867B4B2MdjCqVrG", + "tool_use_id": "toolu_01QcDKhyMNiU8Df4agjz1yt2", "type": "tool_result" } ], @@ -379,7 +403,7 @@ "cache_control": { "type": "ephemeral" }, - "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Thu, May 21, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-LqmoTW/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-HpI3r1/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", "type": "text" } ], @@ -407,7 +431,9 @@ "type": "string" } }, - "required": ["path"], + "required": [ + "path" + ], "type": "object" }, "name": "read" @@ -426,7 +452,10 @@ "type": "string" } }, - "required": ["path", "content"], + "required": [ + "path", + "content" + ], "type": "object" }, "name": "write" @@ -453,7 +482,11 @@ "type": "boolean" } }, - "required": ["path", "oldText", "newText"], + "required": [ + "path", + "oldText", + "newText" + ], "type": "object" }, "name": "edit" @@ -472,7 +505,9 @@ "type": "number" } }, - "required": ["command"], + "required": [ + "command" + ], "type": "object" }, "name": "bash" @@ -495,7 +530,9 @@ "type": "string" } }, - "required": ["pattern"], + "required": [ + "pattern" + ], "type": "object" }, "name": "grep" @@ -514,7 +551,9 @@ "type": "string" } }, - "required": ["pattern"], + "required": [ + "pattern" + ], "type": "object" }, "name": "glob" @@ -541,7 +580,9 @@ "type": "string" } }, - "required": ["prompt"], + "required": [ + "prompt" + ], "type": "object" }, "name": "task" @@ -555,7 +596,9 @@ "type": "string" } }, - "required": ["query"], + "required": [ + "query" + ], "type": "object" }, "name": "lookup" @@ -572,7 +615,10 @@ "type": "string" } }, - "required": ["lookupId", "query"], + "required": [ + "lookupId", + "query" + ], "type": "object" }, "name": "web_search" @@ -589,7 +635,9 @@ "type": "string" } }, - "required": ["url"], + "required": [ + "url" + ], "type": "object" }, "name": "summarize_source" @@ -604,25 +652,25 @@ "response": { "body": { "chunks": [ - "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-5-20250929\",\"id\":\"msg_01CbdemsVyAkiFbARhovXpDk\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":13,\"cache_creation_input_tokens\":257,\"cache_read_input_tokens\":2182,\"cache_creation\":{\"ephemeral_5m_input_tokens\":257,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":1,\"service_tier\":\"standard\",\"inference_geo\":\"not_available\"}}}", + "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-5-20250929\",\"id\":\"msg_017nRwMuk7cCWy6y3kKL51vE\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":13,\"cache_creation_input_tokens\":238,\"cache_read_input_tokens\":2184,\"cache_creation\":{\"ephemeral_5m_input_tokens\":238,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":1,\"service_tier\":\"standard\",\"inference_geo\":\"not_available\"}}}", "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"thinking\",\"thinking\":\"\",\"signature\":\"\"}}", "event: ping\ndata: {\"type\":\"ping\"}", "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\"Good\"}}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\", I got the lookup result with id \\\"flue-session-2026\\\". Now I need to proceed to Step 2: call web_search using\"}}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\" this lookupId and the query \\\"Braintrust Flue reasoning stream instrumentation\\\".\"}}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"signature_delta\",\"signature\":\"EpIDCm4IDRgCKkAGraaqPdHGE2HAbbEXcB/tBYIme5NcenLqHXnwfLjt8F2BUuO3FdH/1DhJ+cGEblVkRTDTtr6gwSbDyYOpIMTZMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIM0hkEt+QHz3frKV+dGgzBzyZSSik/kTiNJUIiMIXWT5AewGcoAk3E5CRsl/7bJoySRe2JV3p8Jv7ioYkJy08euGanth1HahprJhsG3irRAZ1GCOHuwJ6itCVds3y3W1r2Ksy1ShGPrOk0sXjC1RZXt3bTsQAQfi1AU0QaqlgI1RLzXRDhQEbTRQKa7UmMsbCBABlqQrh+90j6u3CqpkibXv5TwnyNlIl3aTBk+HQ+bPPdbQ/yagDMeMG4E4pEik7IFcKet39ynV6QCyTgcxrcgBJZ1uZb4mMxBPuPAwNqHCOdPDRMk8SVreU9PqR54j7fsuMnLBgV85AC8r1iI5cKo3MuhD6KcZG58ls3Yj3exA+XH2OauTFxaa0lDcEYmkAhGAE=\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\", I got the lookup result with id \\\"flue-session-2026\\\". Now I need to proceed to Step 2 and use this\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\" id as the lookupId parameter when calling web_search with the query \\\"Braintrust Flue reasoning stream instrumentation\\\".\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"signature_delta\",\"signature\":\"ErADCm4IDRgCKkARgZnDUJ+PLc8xrFDS9ecUz7mwqLm2d3m/N8LK5Mk0rTAtu68mre/Pzn/ZhTi/qFz82Hb5mrxdEkiUqtsqivMhMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIM5WDRxd0cfRc2Q7v+GgzP22/9gyiglVHjuwsiMOSnrkUVb3mbmhZUVIc50+orubOjsOtWSRq/NhvyKf/3R70oKKwvPoReenbhZDwjvyrvAVe1dnEhhRKcMZVeabb7qH3A63dU4KykFUas917GFUKUxaGHAd2cO1Ksy+Twz0glNwR7+TImTI9ph3FUKjqAQOoui2je0nCJ4ldrM40Lj10KkXKjxrBktO8lLbZffXB6tshrlThqPmLhgst9sIm/vXPI9/7YT+9Dq8I1Oeh5OQtmvyy0JRiWkaNnDXetugIxC2n4gqeplUkuez54nKt0c1la5q4PwA9MLcQItyNv3gv76iW2kLxwd4BtsxEOo0tma3CNuGrT5Xs0O1CwkguSXJpLKuMPWPu7ow1C3u9gVLguglKMPxR5HJmO1NqwGGxsGAE=\"}}", "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0}", "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":1,\"content_block\":{\"type\":\"text\",\"text\":\"\"}}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"text_delta\",\"text\":\"Now proceeding to Step 2:\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"text_delta\",\"text\":\"Now\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"text_delta\",\"text\":\" proceeding to Step 2 with the lookup ID:\"}}", "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":1}", - "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":2,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_016VW8Z7PawkTryuu3wNMQZM\",\"name\":\"web_search\",\"input\":{},\"caller\":{\"type\":\"direct\"}}}", + "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":2,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_0128czRSGDXRjPdjmHVgYk58\",\"name\":\"web_search\",\"input\":{},\"caller\":{\"type\":\"direct\"}}}", "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"}}", "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"lookupId\\\": \\\"flue-session-2026\"}}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\", \\\"query\\\": \\\"Braintrust Flue reasoning stream instru\"}}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"mentation\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\", \\\"query\\\": \\\"Braintrust Flue reasoning stream instrumentation\"}}", "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"}\"}}", "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":2}", - "event: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":13,\"cache_creation_input_tokens\":257,\"cache_read_input_tokens\":2182,\"output_tokens\":158}}", + "event: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":13,\"cache_creation_input_tokens\":238,\"cache_read_input_tokens\":2184,\"output_tokens\":169}}", "event: message_stop\ndata: {\"type\":\"message_stop\"}" ], "kind": "sse" @@ -631,32 +679,32 @@ "anthropic-organization-id": "27796668-7351-40ac-acc4-024aee8995a5", "anthropic-ratelimit-input-tokens-limit": "3000000", "anthropic-ratelimit-input-tokens-remaining": "2999000", - "anthropic-ratelimit-input-tokens-reset": "2026-05-21T06:48:36Z", + "anthropic-ratelimit-input-tokens-reset": "2026-05-22T08:12:53Z", "anthropic-ratelimit-output-tokens-limit": "600000", "anthropic-ratelimit-output-tokens-remaining": "600000", - "anthropic-ratelimit-output-tokens-reset": "2026-05-21T06:48:36Z", + "anthropic-ratelimit-output-tokens-reset": "2026-05-22T08:12:53Z", "anthropic-ratelimit-requests-limit": "20000", "anthropic-ratelimit-requests-remaining": "19999", - "anthropic-ratelimit-requests-reset": "2026-05-21T06:48:36Z", + "anthropic-ratelimit-requests-reset": "2026-05-22T08:12:53Z", "anthropic-ratelimit-tokens-limit": "3600000", "anthropic-ratelimit-tokens-remaining": "3599000", - "anthropic-ratelimit-tokens-reset": "2026-05-21T06:48:36Z", + "anthropic-ratelimit-tokens-reset": "2026-05-22T08:12:53Z", "cache-control": "no-cache", "cf-cache-status": "DYNAMIC", - "cf-ray": "9ff1a2e9dc315b94-VIE", + "cf-ray": "9ffa5bc22b055db9-VIE", "connection": "keep-alive", "content-encoding": "gzip", "content-security-policy": "default-src 'none'; frame-ancestors 'none'", "content-type": "text/event-stream; charset=utf-8", - "date": "Thu, 21 May 2026 06:48:38 GMT", - "request-id": "req_011CbFGTY7XYyU143kqeCPvJ", + "date": "Fri, 22 May 2026 08:12:55 GMT", + "request-id": "req_011CbHGhFT52pJrjqgL8xPr2", "server": "cloudflare", "set-cookie": "[REDACTED]", "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "traceresponse": "00-70dfa42b365a8f6c7805eea761a41ed6-a282aba5d0474c79-01", + "traceresponse": "00-c22ad5b71b29d497896e0adf1c6beda6-365b8174c6154769-01", "transfer-encoding": "chunked", "vary": "Accept-Encoding", - "x-envoy-upstream-service-time": "1764", + "x-envoy-upstream-service-time": "1643", "x-robots-tag": "none" }, "status": 200, @@ -667,7 +715,7 @@ "callIndex": 2, "id": "f1d50a1e6c760d6c", "matchKey": "POST api.anthropic.com/v1/messages", - "recordedAt": "2026-05-21T06:48:42.864Z", + "recordedAt": "2026-05-22T08:13:01.740Z", "request": { "body": { "kind": "json", @@ -686,8 +734,8 @@ { "content": [ { - "signature": "EoUGCm4IDRgCKkBGG1EQWIA9O/tsHYduxoTUS/i0gICgUs3GdrJlpnNSzO7qWVpXyAV/QYunxiJ/pbuy1AxKmw6zIb/6D5H7ZGWfMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMRXKds4wYcGMYouIkGgwZoj3tniSPvjyfUQ0iMJTYUR1cOzdSxBk9UN+23wtgAo9/8kEQNV+xOUHpUah0CvD2CK4e6+Mxn9U0PvwTTyrEBACjWEoJTpmbj0w1MNh5K+OwmDdBIpCbBeZgNfwk/5hZlooub3A2Da3jc6kIQPcSJAyzDcURqiosMVZblqqzxHM/aEXrQka5eZe/CELGEOZLcy2L0sRYjYzcKh+2/4hKScq3jltGM/MwmdE0y1P21raJdOxIpcXaIyQDncBiL9EQ3oPmRuhDHM9giLQaRdA8spWQs8P15X7ZcxxaVV4bI26aJoQa9/BoEBqDbNGNi0jPABVoEoUprtXqNJcl3lb4GUerTKVvEPlXluwJbN0ozQ3j9v8GGqqHlAe5J4WpjO3RA5CjKU6poKdB+CW2/MjTMA5noiDFJzqE5krdR/ll4UusUXFv+DYdLIXvm/RF/EGZa1FAmk+knqhbodSkL78m/AKpDOHNH9qymwstVSQP5IH8Xt6jE6olgXNLIHqmztPCsHYGoli+2FajT98T22xZJ/i9UPJyg+w800UtLCVzwa5Abx98Vodu7zyqZFAQ5HwWf9uY4f2T/tCjoPluiIZVb0nTUHziOnvsCpNQVWWi1eWMM6wUmfcki0TDlXaW2CNcBFSpmehGHwN3qjs2iDUG6w7MAo1hMjkKuUdalXTBqFbDa/EoEXIf4gpyNgXB0b5rzLGb8CisCONKT/PT788R7ZbjWrOqxtpIouGWqD0rvVgkGjBnuJ8EhIn1lkn1QXhqLZhcPsR7fal7rM2NRPVdD5fcI/NS9nIHo/Zx3i25gC0jd3hY+Eihl+f2C9K7f7kq78R2tUf62Sjc8XMy/QVWfsogYLIYAQ==", - "thinking": "The user wants me to complete an instrumented research flow with exactly three steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id to call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url to call summarize_source\n4. After that, reply with exactly \"PROMPT_DONE\"\n\nThe user also emphasizes that I should call exactly one tool per turn and wait for each tool result before choosing the next tool.\n\nLet me start with Step 1: calling lookup with query \"flue instrumentation\".", + "signature": "EqEFCm4IDRgCKkCx4PeMntf8BRtpLH8OUwiMP53HIajGG0HN/LJgm9YmzwCzrRIdbPW6+RRfidn7le5y+DuWJ3BPl1JgKETNcGOcMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMgjs71MGxsxVHe7zLGgzslRkkjDTjHfOSe/QiMJwuB3ScB/LBWqEoaFVkSh1fQFtJgiUlle/UZtA34zfIz7K6LGnqxb1BZAkBKY2o6SrgA7XVIYhi9V8+7n5o2vSbR9Zu5X2ZL4DZxghVngkmw1K9A8fDUjAkwBV34qSMLqozFC4JbcWTpTHqw4HwJ43B4w8pYoeg67QyIwTtH4c+pU5Z6oMzC/9ruNsH/rb6sFceHQb/g/cUAmfV+S4feseEfrHeGpQwzx146NNee8FuICbOSdVDmUa90b+tzHzXjnolSPgMKFbCWX7lCFLbcfDaBxMNcX9BkOUSLfc4/utTn0C38rYhOKzK//A3al4mh5cxYaNZ73KatbFZL4MLPMuT9f44NswmPylRhtcUCgcjP1eal+E8lWzZjX+7DhAzpyPqUY1ZrUVV6GlTddiE3VapSGS5ixtIdgNW6X5jA2W5NiKB1WWaF6aH1PTWPa6PgKIf9+lpHFJcPeeqhskWHV+w9L7Wcjlm7uRg3B+uFBUyEfw1jgsX+wFfGfCq5rEbVk0jjeG498UD1CzeZwdlsKRA5/2laXqk8Migrbqbw95Bhm1D8muVTftvvPkmrBh9rH7Nh2qfgNKBAx5rtQikbnN8299/33EBXQ7CKzByr9aaLVt6CDX4+6m2qGwCi7gXCHur3n4fUZ/aAoo1xb58QUeXwQriGVBzMF5MZ3PuuDQaQTTOHcP0kzTJe4kiP7TWow+9TRgB", + "thinking": "The user wants me to complete an instrumented research flow with specific steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id to call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url to call summarize_source\n4. After summarize_source returns, reply with exactly \"PROMPT_DONE\"\n\nI need to call exactly one tool per turn and wait for each result. Let me start with step 1.", "type": "thinking" }, { @@ -695,7 +743,7 @@ "type": "text" }, { - "id": "toolu_01GD2k3M7867B4B2MdjCqVrG", + "id": "toolu_01QcDKhyMNiU8Df4agjz1yt2", "input": { "query": "flue instrumentation" }, @@ -710,7 +758,7 @@ { "content": "{\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}", "is_error": false, - "tool_use_id": "toolu_01GD2k3M7867B4B2MdjCqVrG", + "tool_use_id": "toolu_01QcDKhyMNiU8Df4agjz1yt2", "type": "tool_result" } ], @@ -719,16 +767,16 @@ { "content": [ { - "signature": "EpIDCm4IDRgCKkAGraaqPdHGE2HAbbEXcB/tBYIme5NcenLqHXnwfLjt8F2BUuO3FdH/1DhJ+cGEblVkRTDTtr6gwSbDyYOpIMTZMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIM0hkEt+QHz3frKV+dGgzBzyZSSik/kTiNJUIiMIXWT5AewGcoAk3E5CRsl/7bJoySRe2JV3p8Jv7ioYkJy08euGanth1HahprJhsG3irRAZ1GCOHuwJ6itCVds3y3W1r2Ksy1ShGPrOk0sXjC1RZXt3bTsQAQfi1AU0QaqlgI1RLzXRDhQEbTRQKa7UmMsbCBABlqQrh+90j6u3CqpkibXv5TwnyNlIl3aTBk+HQ+bPPdbQ/yagDMeMG4E4pEik7IFcKet39ynV6QCyTgcxrcgBJZ1uZb4mMxBPuPAwNqHCOdPDRMk8SVreU9PqR54j7fsuMnLBgV85AC8r1iI5cKo3MuhD6KcZG58ls3Yj3exA+XH2OauTFxaa0lDcEYmkAhGAE=", - "thinking": "Good, I got the lookup result with id \"flue-session-2026\". Now I need to proceed to Step 2: call web_search using this lookupId and the query \"Braintrust Flue reasoning stream instrumentation\".", + "signature": "ErADCm4IDRgCKkARgZnDUJ+PLc8xrFDS9ecUz7mwqLm2d3m/N8LK5Mk0rTAtu68mre/Pzn/ZhTi/qFz82Hb5mrxdEkiUqtsqivMhMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIM5WDRxd0cfRc2Q7v+GgzP22/9gyiglVHjuwsiMOSnrkUVb3mbmhZUVIc50+orubOjsOtWSRq/NhvyKf/3R70oKKwvPoReenbhZDwjvyrvAVe1dnEhhRKcMZVeabb7qH3A63dU4KykFUas917GFUKUxaGHAd2cO1Ksy+Twz0glNwR7+TImTI9ph3FUKjqAQOoui2je0nCJ4ldrM40Lj10KkXKjxrBktO8lLbZffXB6tshrlThqPmLhgst9sIm/vXPI9/7YT+9Dq8I1Oeh5OQtmvyy0JRiWkaNnDXetugIxC2n4gqeplUkuez54nKt0c1la5q4PwA9MLcQItyNv3gv76iW2kLxwd4BtsxEOo0tma3CNuGrT5Xs0O1CwkguSXJpLKuMPWPu7ow1C3u9gVLguglKMPxR5HJmO1NqwGGxsGAE=", + "thinking": "Good, I got the lookup result with id \"flue-session-2026\". Now I need to proceed to Step 2 and use this id as the lookupId parameter when calling web_search with the query \"Braintrust Flue reasoning stream instrumentation\".", "type": "thinking" }, { - "text": "Now proceeding to Step 2:", + "text": "Now proceeding to Step 2 with the lookup ID:", "type": "text" }, { - "id": "toolu_016VW8Z7PawkTryuu3wNMQZM", + "id": "toolu_0128czRSGDXRjPdjmHVgYk58", "input": { "lookupId": "flue-session-2026", "query": "Braintrust Flue reasoning stream instrumentation" @@ -747,7 +795,7 @@ }, "content": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\",\"results\":[{\"title\":\"Flue reasoning stream instrumentation\",\"url\":\"https://example.test/flue/reasoning-streams\"}]}", "is_error": false, - "tool_use_id": "toolu_016VW8Z7PawkTryuu3wNMQZM", + "tool_use_id": "toolu_0128czRSGDXRjPdjmHVgYk58", "type": "tool_result" } ], @@ -761,7 +809,7 @@ "cache_control": { "type": "ephemeral" }, - "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Thu, May 21, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-LqmoTW/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-HpI3r1/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", "type": "text" } ], @@ -789,7 +837,9 @@ "type": "string" } }, - "required": ["path"], + "required": [ + "path" + ], "type": "object" }, "name": "read" @@ -808,7 +858,10 @@ "type": "string" } }, - "required": ["path", "content"], + "required": [ + "path", + "content" + ], "type": "object" }, "name": "write" @@ -835,7 +888,11 @@ "type": "boolean" } }, - "required": ["path", "oldText", "newText"], + "required": [ + "path", + "oldText", + "newText" + ], "type": "object" }, "name": "edit" @@ -854,7 +911,9 @@ "type": "number" } }, - "required": ["command"], + "required": [ + "command" + ], "type": "object" }, "name": "bash" @@ -877,7 +936,9 @@ "type": "string" } }, - "required": ["pattern"], + "required": [ + "pattern" + ], "type": "object" }, "name": "grep" @@ -896,7 +957,9 @@ "type": "string" } }, - "required": ["pattern"], + "required": [ + "pattern" + ], "type": "object" }, "name": "glob" @@ -923,7 +986,9 @@ "type": "string" } }, - "required": ["prompt"], + "required": [ + "prompt" + ], "type": "object" }, "name": "task" @@ -937,7 +1002,9 @@ "type": "string" } }, - "required": ["query"], + "required": [ + "query" + ], "type": "object" }, "name": "lookup" @@ -954,7 +1021,10 @@ "type": "string" } }, - "required": ["lookupId", "query"], + "required": [ + "lookupId", + "query" + ], "type": "object" }, "name": "web_search" @@ -971,7 +1041,9 @@ "type": "string" } }, - "required": ["url"], + "required": [ + "url" + ], "type": "object" }, "name": "summarize_source" @@ -986,24 +1058,24 @@ "response": { "body": { "chunks": [ - "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-5-20250929\",\"id\":\"msg_0127ncLrvEhbdvmzcmsakH7k\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":13,\"cache_creation_input_tokens\":234,\"cache_read_input_tokens\":2439,\"cache_creation\":{\"ephemeral_5m_input_tokens\":234,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":1,\"service_tier\":\"standard\",\"inference_geo\":\"not_available\"}}}", + "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-5-20250929\",\"id\":\"msg_01G9WD4Bo94yWf1xvktj8g2K\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":13,\"cache_creation_input_tokens\":245,\"cache_read_input_tokens\":2422,\"cache_creation\":{\"ephemeral_5m_input_tokens\":245,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":1,\"service_tier\":\"standard\",\"inference_geo\":\"not_available\"}}}", "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"thinking\",\"thinking\":\"\",\"signature\":\"\"}}", "event: ping\ndata: {\"type\":\"ping\"}", "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\"Perfect\"}}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\"! I got the web_search results. There's one result with the URL\"}}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\" \\\"https://example.test/flue/reasoning-streams\\\". Now I need to proceed to Step 3: call summarize_source with this URL.\"}}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"signature_delta\",\"signature\":\"EowDCm4IDRgCKkBAx8dB8EGMSxpAE1bkbv5IFMJcST9qVcl0KHwBXOCrtNNuK9rYk/fasBvKRf6NsyQU3hPl6KMhPmyo1RdgrlbyMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMemkNtsvVXGxVJiFJGgz6AuNoagcBoR2BOdgiMFUYr/5iFJKYgrBdik3Xu8ppJPGcUDuB6f4EI2N39i9sNQHVR8XBCvZaXwJqEILnsSrLAQ1TaPrVNMVCJ5ly8rltFaB3uEBGoaXmduyD/0NFlU6zSySG1hnGrY/tgcH3erm3AOCRJugGoDuSUEn301OxHooiKXGMh/2CsQ1LqQu1nwyrmbK/7+U/UtbouGJQaLkmoAfSWPDKm08zU6filkzdihRiWMkJ9wO/sqbtu8US3zxrIEqE+IPWGBJIHoncA1mAM7pPjqTPZEu4z5f69C0//fQszysmRRO2QejYfGu6m216yFGNwJnirhMFzlXbj5kU1FO21VQ8Wb6dAv0PGAE=\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\"! I got the web_search results. There's one result with the\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\" URL \\\"https://example.test/flue/reasoning-streams\\\". Now I need to proceed to Step 3 and call summarize_source with this URL.\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"signature_delta\",\"signature\":\"Eo8DCm4IDRgCKkCpQxj76pPFD1cIuWNvkSAbn49WWulnuknh8zzSoZQhpuxpRLNr6jyjTVJ27jKKYd3CuNdH9FWYe0yYjBeHkk+AMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMktEsmuylOI6ScMV/GgwYN30KvKWlXjMiJe0iMF3LCPzouFNrmJ4K+VF6l1erxom5lSLw5Ye9q+H53GgGtbC3uYDj7s24ICXcIsS6cCrOAWE337R71wOflWQzsbDBRx+FIYXLSh+8RfMy3WnL/H7zlZIn5iVmStvhkuC0Ky8FyUZ9oBwjw/ud97COuKveDKr/XhVazxA7S022AMViKlO3il4/CCxW9zRNZmLTKaenDjU4MhidXwn+rBYokApHUB4X5/l/3O+dWGeVAmlA7ZIPs0Zz6X7S0lj23zApH01qcyRBH54qMRvLaEB4AaIPhV3GsuK2sbTjOZjhoDkYsCqFtbhabz5PI4ek7WxrbuOGJUmsItk1tkpEd34fzFxUGAE=\"}}", "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0}", "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":1,\"content_block\":{\"type\":\"text\",\"text\":\"\"}}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"text_delta\",\"text\":\"Now proceeding to Step\"}}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"text_delta\",\"text\":\" 3:\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"text_delta\",\"text\":\"Now proceeding to Step 3 \"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"text_delta\",\"text\":\"with the first result URL:\"}}", "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":1}", - "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":2,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01JvdxTjoCLCdYkoec6bWgVv\",\"name\":\"summarize_source\",\"input\":{},\"caller\":{\"type\":\"direct\"}}}", + "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":2,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_016FXSeX6EbSQ2g6jpZFYuqv\",\"name\":\"summarize_source\",\"input\":{},\"caller\":{\"type\":\"direct\"}}}", "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"}}", "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"url\\\": \\\"https://example.test/flue/reasoning-streams\"}}", "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":2,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"}\"}}", "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":2}", - "event: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":13,\"cache_creation_input_tokens\":234,\"cache_read_input_tokens\":2439,\"output_tokens\":132}}", + "event: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":13,\"cache_creation_input_tokens\":245,\"cache_read_input_tokens\":2422,\"output_tokens\":139}}", "event: message_stop\ndata: {\"type\":\"message_stop\"}" ], "kind": "sse" @@ -1012,32 +1084,32 @@ "anthropic-organization-id": "27796668-7351-40ac-acc4-024aee8995a5", "anthropic-ratelimit-input-tokens-limit": "3000000", "anthropic-ratelimit-input-tokens-remaining": "2999000", - "anthropic-ratelimit-input-tokens-reset": "2026-05-21T06:48:39Z", + "anthropic-ratelimit-input-tokens-reset": "2026-05-22T08:12:57Z", "anthropic-ratelimit-output-tokens-limit": "600000", "anthropic-ratelimit-output-tokens-remaining": "600000", - "anthropic-ratelimit-output-tokens-reset": "2026-05-21T06:48:39Z", + "anthropic-ratelimit-output-tokens-reset": "2026-05-22T08:12:57Z", "anthropic-ratelimit-requests-limit": "20000", "anthropic-ratelimit-requests-remaining": "19999", - "anthropic-ratelimit-requests-reset": "2026-05-21T06:48:39Z", + "anthropic-ratelimit-requests-reset": "2026-05-22T08:12:57Z", "anthropic-ratelimit-tokens-limit": "3600000", "anthropic-ratelimit-tokens-remaining": "3599000", - "anthropic-ratelimit-tokens-reset": "2026-05-21T06:48:39Z", + "anthropic-ratelimit-tokens-reset": "2026-05-22T08:12:57Z", "cache-control": "no-cache", "cf-cache-status": "DYNAMIC", - "cf-ray": "9ff1a30038c95b94-VIE", + "cf-ray": "9ffa5bd94d865db9-VIE", "connection": "keep-alive", "content-encoding": "gzip", "content-security-policy": "default-src 'none'; frame-ancestors 'none'", "content-type": "text/event-stream; charset=utf-8", - "date": "Thu, 21 May 2026 06:48:41 GMT", - "request-id": "req_011CbFGToRH9Dj7DccSdji4e", + "date": "Fri, 22 May 2026 08:12:59 GMT", + "request-id": "req_011CbHGhXH4yFWDdi7Ba8Dcv", "server": "cloudflare", "set-cookie": "[REDACTED]", "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "traceresponse": "00-5adb360c6209ec709b5896e9afca02b1-3e5b34b916b3f3b1-01", + "traceresponse": "00-e883fcca47cdaea9dceb5b7e6d1b3745-19380135cf39e480-01", "transfer-encoding": "chunked", "vary": "Accept-Encoding", - "x-envoy-upstream-service-time": "1389", + "x-envoy-upstream-service-time": "1954", "x-robots-tag": "none" }, "status": 200, @@ -1048,7 +1120,7 @@ "callIndex": 3, "id": "305957222aa1f6e9", "matchKey": "POST api.anthropic.com/v1/messages", - "recordedAt": "2026-05-21T06:48:45.714Z", + "recordedAt": "2026-05-22T08:13:04.843Z", "request": { "body": { "kind": "json", @@ -1067,8 +1139,8 @@ { "content": [ { - "signature": "EoUGCm4IDRgCKkBGG1EQWIA9O/tsHYduxoTUS/i0gICgUs3GdrJlpnNSzO7qWVpXyAV/QYunxiJ/pbuy1AxKmw6zIb/6D5H7ZGWfMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMRXKds4wYcGMYouIkGgwZoj3tniSPvjyfUQ0iMJTYUR1cOzdSxBk9UN+23wtgAo9/8kEQNV+xOUHpUah0CvD2CK4e6+Mxn9U0PvwTTyrEBACjWEoJTpmbj0w1MNh5K+OwmDdBIpCbBeZgNfwk/5hZlooub3A2Da3jc6kIQPcSJAyzDcURqiosMVZblqqzxHM/aEXrQka5eZe/CELGEOZLcy2L0sRYjYzcKh+2/4hKScq3jltGM/MwmdE0y1P21raJdOxIpcXaIyQDncBiL9EQ3oPmRuhDHM9giLQaRdA8spWQs8P15X7ZcxxaVV4bI26aJoQa9/BoEBqDbNGNi0jPABVoEoUprtXqNJcl3lb4GUerTKVvEPlXluwJbN0ozQ3j9v8GGqqHlAe5J4WpjO3RA5CjKU6poKdB+CW2/MjTMA5noiDFJzqE5krdR/ll4UusUXFv+DYdLIXvm/RF/EGZa1FAmk+knqhbodSkL78m/AKpDOHNH9qymwstVSQP5IH8Xt6jE6olgXNLIHqmztPCsHYGoli+2FajT98T22xZJ/i9UPJyg+w800UtLCVzwa5Abx98Vodu7zyqZFAQ5HwWf9uY4f2T/tCjoPluiIZVb0nTUHziOnvsCpNQVWWi1eWMM6wUmfcki0TDlXaW2CNcBFSpmehGHwN3qjs2iDUG6w7MAo1hMjkKuUdalXTBqFbDa/EoEXIf4gpyNgXB0b5rzLGb8CisCONKT/PT788R7ZbjWrOqxtpIouGWqD0rvVgkGjBnuJ8EhIn1lkn1QXhqLZhcPsR7fal7rM2NRPVdD5fcI/NS9nIHo/Zx3i25gC0jd3hY+Eihl+f2C9K7f7kq78R2tUf62Sjc8XMy/QVWfsogYLIYAQ==", - "thinking": "The user wants me to complete an instrumented research flow with exactly three steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id to call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url to call summarize_source\n4. After that, reply with exactly \"PROMPT_DONE\"\n\nThe user also emphasizes that I should call exactly one tool per turn and wait for each tool result before choosing the next tool.\n\nLet me start with Step 1: calling lookup with query \"flue instrumentation\".", + "signature": "EqEFCm4IDRgCKkCx4PeMntf8BRtpLH8OUwiMP53HIajGG0HN/LJgm9YmzwCzrRIdbPW6+RRfidn7le5y+DuWJ3BPl1JgKETNcGOcMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMgjs71MGxsxVHe7zLGgzslRkkjDTjHfOSe/QiMJwuB3ScB/LBWqEoaFVkSh1fQFtJgiUlle/UZtA34zfIz7K6LGnqxb1BZAkBKY2o6SrgA7XVIYhi9V8+7n5o2vSbR9Zu5X2ZL4DZxghVngkmw1K9A8fDUjAkwBV34qSMLqozFC4JbcWTpTHqw4HwJ43B4w8pYoeg67QyIwTtH4c+pU5Z6oMzC/9ruNsH/rb6sFceHQb/g/cUAmfV+S4feseEfrHeGpQwzx146NNee8FuICbOSdVDmUa90b+tzHzXjnolSPgMKFbCWX7lCFLbcfDaBxMNcX9BkOUSLfc4/utTn0C38rYhOKzK//A3al4mh5cxYaNZ73KatbFZL4MLPMuT9f44NswmPylRhtcUCgcjP1eal+E8lWzZjX+7DhAzpyPqUY1ZrUVV6GlTddiE3VapSGS5ixtIdgNW6X5jA2W5NiKB1WWaF6aH1PTWPa6PgKIf9+lpHFJcPeeqhskWHV+w9L7Wcjlm7uRg3B+uFBUyEfw1jgsX+wFfGfCq5rEbVk0jjeG498UD1CzeZwdlsKRA5/2laXqk8Migrbqbw95Bhm1D8muVTftvvPkmrBh9rH7Nh2qfgNKBAx5rtQikbnN8299/33EBXQ7CKzByr9aaLVt6CDX4+6m2qGwCi7gXCHur3n4fUZ/aAoo1xb58QUeXwQriGVBzMF5MZ3PuuDQaQTTOHcP0kzTJe4kiP7TWow+9TRgB", + "thinking": "The user wants me to complete an instrumented research flow with specific steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id to call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url to call summarize_source\n4. After summarize_source returns, reply with exactly \"PROMPT_DONE\"\n\nI need to call exactly one tool per turn and wait for each result. Let me start with step 1.", "type": "thinking" }, { @@ -1076,7 +1148,7 @@ "type": "text" }, { - "id": "toolu_01GD2k3M7867B4B2MdjCqVrG", + "id": "toolu_01QcDKhyMNiU8Df4agjz1yt2", "input": { "query": "flue instrumentation" }, @@ -1091,7 +1163,7 @@ { "content": "{\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}", "is_error": false, - "tool_use_id": "toolu_01GD2k3M7867B4B2MdjCqVrG", + "tool_use_id": "toolu_01QcDKhyMNiU8Df4agjz1yt2", "type": "tool_result" } ], @@ -1100,16 +1172,16 @@ { "content": [ { - "signature": "EpIDCm4IDRgCKkAGraaqPdHGE2HAbbEXcB/tBYIme5NcenLqHXnwfLjt8F2BUuO3FdH/1DhJ+cGEblVkRTDTtr6gwSbDyYOpIMTZMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIM0hkEt+QHz3frKV+dGgzBzyZSSik/kTiNJUIiMIXWT5AewGcoAk3E5CRsl/7bJoySRe2JV3p8Jv7ioYkJy08euGanth1HahprJhsG3irRAZ1GCOHuwJ6itCVds3y3W1r2Ksy1ShGPrOk0sXjC1RZXt3bTsQAQfi1AU0QaqlgI1RLzXRDhQEbTRQKa7UmMsbCBABlqQrh+90j6u3CqpkibXv5TwnyNlIl3aTBk+HQ+bPPdbQ/yagDMeMG4E4pEik7IFcKet39ynV6QCyTgcxrcgBJZ1uZb4mMxBPuPAwNqHCOdPDRMk8SVreU9PqR54j7fsuMnLBgV85AC8r1iI5cKo3MuhD6KcZG58ls3Yj3exA+XH2OauTFxaa0lDcEYmkAhGAE=", - "thinking": "Good, I got the lookup result with id \"flue-session-2026\". Now I need to proceed to Step 2: call web_search using this lookupId and the query \"Braintrust Flue reasoning stream instrumentation\".", + "signature": "ErADCm4IDRgCKkARgZnDUJ+PLc8xrFDS9ecUz7mwqLm2d3m/N8LK5Mk0rTAtu68mre/Pzn/ZhTi/qFz82Hb5mrxdEkiUqtsqivMhMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIM5WDRxd0cfRc2Q7v+GgzP22/9gyiglVHjuwsiMOSnrkUVb3mbmhZUVIc50+orubOjsOtWSRq/NhvyKf/3R70oKKwvPoReenbhZDwjvyrvAVe1dnEhhRKcMZVeabb7qH3A63dU4KykFUas917GFUKUxaGHAd2cO1Ksy+Twz0glNwR7+TImTI9ph3FUKjqAQOoui2je0nCJ4ldrM40Lj10KkXKjxrBktO8lLbZffXB6tshrlThqPmLhgst9sIm/vXPI9/7YT+9Dq8I1Oeh5OQtmvyy0JRiWkaNnDXetugIxC2n4gqeplUkuez54nKt0c1la5q4PwA9MLcQItyNv3gv76iW2kLxwd4BtsxEOo0tma3CNuGrT5Xs0O1CwkguSXJpLKuMPWPu7ow1C3u9gVLguglKMPxR5HJmO1NqwGGxsGAE=", + "thinking": "Good, I got the lookup result with id \"flue-session-2026\". Now I need to proceed to Step 2 and use this id as the lookupId parameter when calling web_search with the query \"Braintrust Flue reasoning stream instrumentation\".", "type": "thinking" }, { - "text": "Now proceeding to Step 2:", + "text": "Now proceeding to Step 2 with the lookup ID:", "type": "text" }, { - "id": "toolu_016VW8Z7PawkTryuu3wNMQZM", + "id": "toolu_0128czRSGDXRjPdjmHVgYk58", "input": { "lookupId": "flue-session-2026", "query": "Braintrust Flue reasoning stream instrumentation" @@ -1125,7 +1197,7 @@ { "content": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\",\"results\":[{\"title\":\"Flue reasoning stream instrumentation\",\"url\":\"https://example.test/flue/reasoning-streams\"}]}", "is_error": false, - "tool_use_id": "toolu_016VW8Z7PawkTryuu3wNMQZM", + "tool_use_id": "toolu_0128czRSGDXRjPdjmHVgYk58", "type": "tool_result" } ], @@ -1134,16 +1206,16 @@ { "content": [ { - "signature": "EowDCm4IDRgCKkBAx8dB8EGMSxpAE1bkbv5IFMJcST9qVcl0KHwBXOCrtNNuK9rYk/fasBvKRf6NsyQU3hPl6KMhPmyo1RdgrlbyMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMemkNtsvVXGxVJiFJGgz6AuNoagcBoR2BOdgiMFUYr/5iFJKYgrBdik3Xu8ppJPGcUDuB6f4EI2N39i9sNQHVR8XBCvZaXwJqEILnsSrLAQ1TaPrVNMVCJ5ly8rltFaB3uEBGoaXmduyD/0NFlU6zSySG1hnGrY/tgcH3erm3AOCRJugGoDuSUEn301OxHooiKXGMh/2CsQ1LqQu1nwyrmbK/7+U/UtbouGJQaLkmoAfSWPDKm08zU6filkzdihRiWMkJ9wO/sqbtu8US3zxrIEqE+IPWGBJIHoncA1mAM7pPjqTPZEu4z5f69C0//fQszysmRRO2QejYfGu6m216yFGNwJnirhMFzlXbj5kU1FO21VQ8Wb6dAv0PGAE=", - "thinking": "Perfect! I got the web_search results. There's one result with the URL \"https://example.test/flue/reasoning-streams\". Now I need to proceed to Step 3: call summarize_source with this URL.", + "signature": "Eo8DCm4IDRgCKkCpQxj76pPFD1cIuWNvkSAbn49WWulnuknh8zzSoZQhpuxpRLNr6jyjTVJ27jKKYd3CuNdH9FWYe0yYjBeHkk+AMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMktEsmuylOI6ScMV/GgwYN30KvKWlXjMiJe0iMF3LCPzouFNrmJ4K+VF6l1erxom5lSLw5Ye9q+H53GgGtbC3uYDj7s24ICXcIsS6cCrOAWE337R71wOflWQzsbDBRx+FIYXLSh+8RfMy3WnL/H7zlZIn5iVmStvhkuC0Ky8FyUZ9oBwjw/ud97COuKveDKr/XhVazxA7S022AMViKlO3il4/CCxW9zRNZmLTKaenDjU4MhidXwn+rBYokApHUB4X5/l/3O+dWGeVAmlA7ZIPs0Zz6X7S0lj23zApH01qcyRBH54qMRvLaEB4AaIPhV3GsuK2sbTjOZjhoDkYsCqFtbhabz5PI4ek7WxrbuOGJUmsItk1tkpEd34fzFxUGAE=", + "thinking": "Perfect! I got the web_search results. There's one result with the URL \"https://example.test/flue/reasoning-streams\". Now I need to proceed to Step 3 and call summarize_source with this URL.", "type": "thinking" }, { - "text": "Now proceeding to Step 3:", + "text": "Now proceeding to Step 3 with the first result URL:", "type": "text" }, { - "id": "toolu_01JvdxTjoCLCdYkoec6bWgVv", + "id": "toolu_016FXSeX6EbSQ2g6jpZFYuqv", "input": { "url": "https://example.test/flue/reasoning-streams" }, @@ -1161,7 +1233,7 @@ }, "content": "{\"summary\":\"Flue emits reasoning, tool execution, and LLM turn events separately.\",\"url\":\"https://example.test/flue/reasoning-streams\"}", "is_error": false, - "tool_use_id": "toolu_01JvdxTjoCLCdYkoec6bWgVv", + "tool_use_id": "toolu_016FXSeX6EbSQ2g6jpZFYuqv", "type": "tool_result" } ], @@ -1175,7 +1247,7 @@ "cache_control": { "type": "ephemeral" }, - "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Thu, May 21, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-LqmoTW/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-HpI3r1/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", "type": "text" } ], @@ -1203,7 +1275,9 @@ "type": "string" } }, - "required": ["path"], + "required": [ + "path" + ], "type": "object" }, "name": "read" @@ -1222,7 +1296,10 @@ "type": "string" } }, - "required": ["path", "content"], + "required": [ + "path", + "content" + ], "type": "object" }, "name": "write" @@ -1249,7 +1326,11 @@ "type": "boolean" } }, - "required": ["path", "oldText", "newText"], + "required": [ + "path", + "oldText", + "newText" + ], "type": "object" }, "name": "edit" @@ -1268,7 +1349,9 @@ "type": "number" } }, - "required": ["command"], + "required": [ + "command" + ], "type": "object" }, "name": "bash" @@ -1291,7 +1374,9 @@ "type": "string" } }, - "required": ["pattern"], + "required": [ + "pattern" + ], "type": "object" }, "name": "grep" @@ -1310,7 +1395,9 @@ "type": "string" } }, - "required": ["pattern"], + "required": [ + "pattern" + ], "type": "object" }, "name": "glob" @@ -1337,7 +1424,9 @@ "type": "string" } }, - "required": ["prompt"], + "required": [ + "prompt" + ], "type": "object" }, "name": "task" @@ -1351,7 +1440,9 @@ "type": "string" } }, - "required": ["query"], + "required": [ + "query" + ], "type": "object" }, "name": "lookup" @@ -1368,7 +1459,10 @@ "type": "string" } }, - "required": ["lookupId", "query"], + "required": [ + "lookupId", + "query" + ], "type": "object" }, "name": "web_search" @@ -1385,7 +1479,9 @@ "type": "string" } }, - "required": ["url"], + "required": [ + "url" + ], "type": "object" }, "name": "summarize_source" @@ -1400,18 +1496,18 @@ "response": { "body": { "chunks": [ - "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-5-20250929\",\"id\":\"msg_01HwXz99DRaxy131BhTvg7aL\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":13,\"cache_creation_input_tokens\":188,\"cache_read_input_tokens\":2673,\"cache_creation\":{\"ephemeral_5m_input_tokens\":188,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":3,\"service_tier\":\"standard\",\"inference_geo\":\"not_available\"}}}", + "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-5-20250929\",\"id\":\"msg_01WLfU56Vt3U9D96LFBG1oeT\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":13,\"cache_creation_input_tokens\":195,\"cache_read_input_tokens\":2667,\"cache_creation\":{\"ephemeral_5m_input_tokens\":195,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":1,\"service_tier\":\"standard\",\"inference_geo\":\"not_available\"}}}", "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"thinking\",\"thinking\":\"\",\"signature\":\"\"}}", "event: ping\ndata: {\"type\":\"ping\"}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\"Great! The\"}}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\" summarize_source call has completed successfully. According to the instructions, I should now reply with exactly \\\"PROMPT_DONE\\\" and no other text.\"}}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\"\"}}", - "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"signature_delta\",\"signature\":\"Eu0CCm4IDRgCKkCBUYqhsARXFm5YQdB8B4fq/pryhtdDMyve+qLrKjJqHD3e6i8qwtMvaYLPzEs5dagCGN78HUOXUIGRyxayFLsaMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMSAGOY3KKONucZdv2GgwbIH0DASkcx2PNO3IiMPgbDWU64PZih2E9L5bJKlJG3YlBOkpzlkj0KsH27P2yeVtf6gEKV1ym8v01eo+22SqsAZjELp8qSjTomJDJAbv93WPF4OwY0KKNhLiGYj3CGUOcybr7g+02AkHtaxp1YyYNtX1cXsUoTCPPAtGgW+4Mj6V48xqSppxoF67gzfoLd3DbqN1ZpCjcGTaOlEQwRdKZU7eUS81aRksb5Vb5tiQCHPG8f55AmRy0kn4eZ0LhQLm/qUQwRznV0EsNSrHdkozFlf4rUQS+BdDYgf+eECSpMoo7TX2P9lBg4h5EsREYAQ==\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\"The\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\" summarize_source call has returned successfully. According to the instructions, I now need to reply with exactly\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"thinking_delta\",\"thinking\":\" \\\"PROMPT_DONE\\\" and no other text.\"}}", + "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"signature_delta\",\"signature\":\"EuYCCm4IDRgCKkBFujunkFxpgR7g2ctw59ci2mFpOy6UZNKTH1CbcjkAhRRFCEjX3vkfQ+Pc94+7qXzVhvYFWLdCo2wTqIX/+LyIMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMvK0etosFMoYw1Z9RGgxoNtoAqpiqe6v2nWsiMOXu8iWWDmDLnqml/Nixpid9nKvlLp34ehcoP4GelAn8RUkUpwDDgcxpMN9U5juyvyqlAXUF63wuY0dTYfCQs7UylzAPjcwPGoRGDSyCB4+bfhKc8vHh521jgjwv7s9JJyuhp5Xj5+vhcOa6UNuXPojhtSxdBH6DNsvUEH/PICsMcgzpNkjNgXMqtUDm/10+fFpXx7GrnHr4BVXP5AreI8hS6gGydoK7EjDorgpGeJHY/RRRDJZr8XANwPlqC3ZU0wlIBwXWqefdr2bTFUtBNh0Qelx5nEgVpBgB\"}}", "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0}", "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":1,\"content_block\":{\"type\":\"text\",\"text\":\"\"}}", "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"text_delta\",\"text\":\"PROMPT_DONE\"}}", "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":1}", - "event: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":13,\"cache_creation_input_tokens\":188,\"cache_read_input_tokens\":2673,\"output_tokens\":51}}", + "event: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":13,\"cache_creation_input_tokens\":195,\"cache_read_input_tokens\":2667,\"output_tokens\":50}}", "event: message_stop\ndata: {\"type\":\"message_stop\"}" ], "kind": "sse" @@ -1420,32 +1516,32 @@ "anthropic-organization-id": "27796668-7351-40ac-acc4-024aee8995a5", "anthropic-ratelimit-input-tokens-limit": "3000000", "anthropic-ratelimit-input-tokens-remaining": "2998000", - "anthropic-ratelimit-input-tokens-reset": "2026-05-21T06:48:43Z", + "anthropic-ratelimit-input-tokens-reset": "2026-05-22T08:13:01Z", "anthropic-ratelimit-output-tokens-limit": "600000", "anthropic-ratelimit-output-tokens-remaining": "600000", - "anthropic-ratelimit-output-tokens-reset": "2026-05-21T06:48:43Z", + "anthropic-ratelimit-output-tokens-reset": "2026-05-22T08:13:01Z", "anthropic-ratelimit-requests-limit": "20000", "anthropic-ratelimit-requests-remaining": "19999", - "anthropic-ratelimit-requests-reset": "2026-05-21T06:48:43Z", + "anthropic-ratelimit-requests-reset": "2026-05-22T08:13:01Z", "anthropic-ratelimit-tokens-limit": "3600000", "anthropic-ratelimit-tokens-remaining": "3598000", - "anthropic-ratelimit-tokens-reset": "2026-05-21T06:48:43Z", + "anthropic-ratelimit-tokens-reset": "2026-05-22T08:13:01Z", "cache-control": "no-cache", "cf-cache-status": "DYNAMIC", - "cf-ray": "9ff1a3145cd25b94-VIE", + "cf-ray": "9ffa5bf63c1a5db9-VIE", "connection": "keep-alive", "content-encoding": "gzip", "content-security-policy": "default-src 'none'; frame-ancestors 'none'", "content-type": "text/event-stream; charset=utf-8", - "date": "Thu, 21 May 2026 06:48:45 GMT", - "request-id": "req_011CbFGU3Bkpmx8QxaBcUhtq", + "date": "Fri, 22 May 2026 08:13:04 GMT", + "request-id": "req_011CbHGhs4TKsmC4kjfmPvcg", "server": "cloudflare", "set-cookie": "[REDACTED]", "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "traceresponse": "00-408b026ccc4d384d0269512a66aa3826-2c341f620252cb31-01", + "traceresponse": "00-f79e47b3df03c590ababa226db12841a-4a86810d2176b8a1-01", "transfer-encoding": "chunked", "vary": "Accept-Encoding", - "x-envoy-upstream-service-time": "1997", + "x-envoy-upstream-service-time": "2146", "x-robots-tag": "none" }, "status": 200, @@ -1456,7 +1552,7 @@ "callIndex": 4, "id": "3d93fe37f72a947f", "matchKey": "POST api.anthropic.com/v1/messages", - "recordedAt": "2026-05-21T06:48:48.470Z", + "recordedAt": "2026-05-22T08:13:07.903Z", "request": { "body": { "kind": "json", @@ -1483,7 +1579,7 @@ "cache_control": { "type": "ephemeral" }, - "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Thu, May 21, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-LqmoTW/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts\n\n\nNever call the task tool. Do not delegate e2e-flue-skill to another session. If you need the skill body, read .agents/skills/e2e-flue-skill/SKILL.md yourself with the read tool. Return the marker from the Arguments object exactly, with no other text.\n", + "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-HpI3r1/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts\n\n\nNever call the task tool. Do not delegate e2e-flue-skill to another session. If you need the skill body, read .agents/skills/e2e-flue-skill/SKILL.md yourself with the read tool. Return the marker from the Arguments object exactly, with no other text.\n", "type": "text" } ], @@ -1509,7 +1605,9 @@ "type": "string" } }, - "required": ["path"], + "required": [ + "path" + ], "type": "object" }, "name": "read" @@ -1528,7 +1626,10 @@ "type": "string" } }, - "required": ["path", "content"], + "required": [ + "path", + "content" + ], "type": "object" }, "name": "write" @@ -1555,7 +1656,11 @@ "type": "boolean" } }, - "required": ["path", "oldText", "newText"], + "required": [ + "path", + "oldText", + "newText" + ], "type": "object" }, "name": "edit" @@ -1574,7 +1679,9 @@ "type": "number" } }, - "required": ["command"], + "required": [ + "command" + ], "type": "object" }, "name": "bash" @@ -1597,7 +1704,9 @@ "type": "string" } }, - "required": ["pattern"], + "required": [ + "pattern" + ], "type": "object" }, "name": "grep" @@ -1616,7 +1725,9 @@ "type": "string" } }, - "required": ["pattern"], + "required": [ + "pattern" + ], "type": "object" }, "name": "glob" @@ -1646,7 +1757,9 @@ "type": "string" } }, - "required": ["prompt"], + "required": [ + "prompt" + ], "type": "object" }, "name": "task" @@ -1661,18 +1774,18 @@ "response": { "body": { "chunks": [ - "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-5-20250929\",\"id\":\"msg_01JoaqaveV26zPPyn36eqMii\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":3,\"cache_creation_input_tokens\":716,\"cache_read_input_tokens\":1093,\"cache_creation\":{\"ephemeral_5m_input_tokens\":716,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":5,\"service_tier\":\"standard\",\"inference_geo\":\"not_available\"}}}", + "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-5-20250929\",\"id\":\"msg_016vwzpiWe299rYyUVo36eHU\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":3,\"cache_creation_input_tokens\":718,\"cache_read_input_tokens\":1093,\"cache_creation\":{\"ephemeral_5m_input_tokens\":718,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":5,\"service_tier\":\"standard\",\"inference_geo\":\"not_available\"}}}", "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"}}", "event: ping\ndata: {\"type\":\"ping\"}", "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"I'll run the e\"}}", "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"2e-flue-skill by reading its instructions and following them.\"}}", "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0}", - "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":1,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01PD5NfHENNe1rtoqGk42TWG\",\"name\":\"read\",\"input\":{},\"caller\":{\"type\":\"direct\"}}}", + "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":1,\"content_block\":{\"type\":\"tool_use\",\"id\":\"toolu_01QkqnD4JzpMgVFLRk6aTJNM\",\"name\":\"read\",\"input\":{},\"caller\":{\"type\":\"direct\"}}}", "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\"}}", "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"{\\\"path\\\": \\\".agents/skills/e2e-flue-skill/SKILL.md\"}}", "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":1,\"delta\":{\"type\":\"input_json_delta\",\"partial_json\":\"\\\"}\"}}", "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":1}", - "event: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":3,\"cache_creation_input_tokens\":716,\"cache_read_input_tokens\":1093,\"output_tokens\":89}}", + "event: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"tool_use\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":3,\"cache_creation_input_tokens\":718,\"cache_read_input_tokens\":1093,\"output_tokens\":89}}", "event: message_stop\ndata: {\"type\":\"message_stop\"}" ], "kind": "sse" @@ -1681,32 +1794,32 @@ "anthropic-organization-id": "27796668-7351-40ac-acc4-024aee8995a5", "anthropic-ratelimit-input-tokens-limit": "3000000", "anthropic-ratelimit-input-tokens-remaining": "2999000", - "anthropic-ratelimit-input-tokens-reset": "2026-05-21T06:48:45Z", + "anthropic-ratelimit-input-tokens-reset": "2026-05-22T08:13:05Z", "anthropic-ratelimit-output-tokens-limit": "600000", "anthropic-ratelimit-output-tokens-remaining": "600000", - "anthropic-ratelimit-output-tokens-reset": "2026-05-21T06:48:45Z", + "anthropic-ratelimit-output-tokens-reset": "2026-05-22T08:13:05Z", "anthropic-ratelimit-requests-limit": "20000", "anthropic-ratelimit-requests-remaining": "19999", - "anthropic-ratelimit-requests-reset": "2026-05-21T06:48:45Z", + "anthropic-ratelimit-requests-reset": "2026-05-22T08:13:05Z", "anthropic-ratelimit-tokens-limit": "3600000", "anthropic-ratelimit-tokens-remaining": "3599000", - "anthropic-ratelimit-tokens-reset": "2026-05-21T06:48:45Z", + "anthropic-ratelimit-tokens-reset": "2026-05-22T08:13:05Z", "cache-control": "no-cache", "cf-cache-status": "DYNAMIC", - "cf-ray": "9ff1a3261ce85b94-VIE", + "cf-ray": "9ffa5c099b265db9-VIE", "connection": "keep-alive", "content-encoding": "gzip", "content-security-policy": "default-src 'none'; frame-ancestors 'none'", "content-type": "text/event-stream; charset=utf-8", - "date": "Thu, 21 May 2026 06:48:47 GMT", - "request-id": "req_011CbFGUFLzxnhHqjcYYgyca", + "date": "Fri, 22 May 2026 08:13:06 GMT", + "request-id": "req_011CbHGi6KRcBp98B8HjsFW3", "server": "cloudflare", "set-cookie": "[REDACTED]", "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "traceresponse": "00-240fefcf6768b2ee326e503bca81b492-db5bae8e1a36da5d-01", + "traceresponse": "00-18c8d7abc86329d1f68499b6fc11374f-d8a0965520f39348-01", "transfer-encoding": "chunked", "vary": "Accept-Encoding", - "x-envoy-upstream-service-time": "1635", + "x-envoy-upstream-service-time": "1927", "x-robots-tag": "none" }, "status": 200, @@ -1717,7 +1830,7 @@ "callIndex": 5, "id": "fb4ed2bb1569d980", "matchKey": "POST api.anthropic.com/v1/messages", - "recordedAt": "2026-05-21T06:48:50.434Z", + "recordedAt": "2026-05-22T08:13:09.385Z", "request": { "body": { "kind": "json", @@ -1740,7 +1853,7 @@ "type": "text" }, { - "id": "toolu_01PD5NfHENNe1rtoqGk42TWG", + "id": "toolu_01QkqnD4JzpMgVFLRk6aTJNM", "input": { "path": ".agents/skills/e2e-flue-skill/SKILL.md" }, @@ -1758,7 +1871,7 @@ }, "content": "---\nname: e2e-flue-skill\ndescription: Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n---\n\nReturn the marker from the provided args exactly once. Output no other text.\n", "is_error": false, - "tool_use_id": "toolu_01PD5NfHENNe1rtoqGk42TWG", + "tool_use_id": "toolu_01QkqnD4JzpMgVFLRk6aTJNM", "type": "tool_result" } ], @@ -1772,7 +1885,7 @@ "cache_control": { "type": "ephemeral" }, - "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Thu, May 21, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-LqmoTW/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts\n\n\nNever call the task tool. Do not delegate e2e-flue-skill to another session. If you need the skill body, read .agents/skills/e2e-flue-skill/SKILL.md yourself with the read tool. Return the marker from the Arguments object exactly, with no other text.\n", + "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-HpI3r1/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts\n\n\nNever call the task tool. Do not delegate e2e-flue-skill to another session. If you need the skill body, read .agents/skills/e2e-flue-skill/SKILL.md yourself with the read tool. Return the marker from the Arguments object exactly, with no other text.\n", "type": "text" } ], @@ -1798,7 +1911,9 @@ "type": "string" } }, - "required": ["path"], + "required": [ + "path" + ], "type": "object" }, "name": "read" @@ -1817,7 +1932,10 @@ "type": "string" } }, - "required": ["path", "content"], + "required": [ + "path", + "content" + ], "type": "object" }, "name": "write" @@ -1844,7 +1962,11 @@ "type": "boolean" } }, - "required": ["path", "oldText", "newText"], + "required": [ + "path", + "oldText", + "newText" + ], "type": "object" }, "name": "edit" @@ -1863,7 +1985,9 @@ "type": "number" } }, - "required": ["command"], + "required": [ + "command" + ], "type": "object" }, "name": "bash" @@ -1886,7 +2010,9 @@ "type": "string" } }, - "required": ["pattern"], + "required": [ + "pattern" + ], "type": "object" }, "name": "grep" @@ -1905,7 +2031,9 @@ "type": "string" } }, - "required": ["pattern"], + "required": [ + "pattern" + ], "type": "object" }, "name": "glob" @@ -1935,7 +2063,9 @@ "type": "string" } }, - "required": ["prompt"], + "required": [ + "prompt" + ], "type": "object" }, "name": "task" @@ -1950,12 +2080,12 @@ "response": { "body": { "chunks": [ - "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-5-20250929\",\"id\":\"msg_011AmwNdKn8z3XPfujJbRjA3\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":6,\"cache_creation_input_tokens\":153,\"cache_read_input_tokens\":1809,\"cache_creation\":{\"ephemeral_5m_input_tokens\":153,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":7,\"service_tier\":\"standard\",\"inference_geo\":\"not_available\"}}}", + "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"model\":\"claude-sonnet-4-5-20250929\",\"id\":\"msg_01VSnypnj2Dam9xTgTsC2AKn\",\"type\":\"message\",\"role\":\"assistant\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"stop_details\":null,\"usage\":{\"input_tokens\":6,\"cache_creation_input_tokens\":153,\"cache_read_input_tokens\":1811,\"cache_creation\":{\"ephemeral_5m_input_tokens\":153,\"ephemeral_1h_input_tokens\":0},\"output_tokens\":7,\"service_tier\":\"standard\",\"inference_geo\":\"not_available\"}}}", "event: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"}}", "event: ping\ndata: {\"type\":\"ping\"}", "event: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"SKILL_DONE\"}}", "event: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0}", - "event: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":6,\"cache_creation_input_tokens\":153,\"cache_read_input_tokens\":1809,\"output_tokens\":8}}", + "event: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null,\"stop_details\":null},\"usage\":{\"input_tokens\":6,\"cache_creation_input_tokens\":153,\"cache_read_input_tokens\":1811,\"output_tokens\":8}}", "event: message_stop\ndata: {\"type\":\"message_stop\"}" ], "kind": "sse" @@ -1964,32 +2094,32 @@ "anthropic-organization-id": "27796668-7351-40ac-acc4-024aee8995a5", "anthropic-ratelimit-input-tokens-limit": "3000000", "anthropic-ratelimit-input-tokens-remaining": "2999000", - "anthropic-ratelimit-input-tokens-reset": "2026-05-21T06:48:48Z", + "anthropic-ratelimit-input-tokens-reset": "2026-05-22T08:13:08Z", "anthropic-ratelimit-output-tokens-limit": "600000", "anthropic-ratelimit-output-tokens-remaining": "600000", - "anthropic-ratelimit-output-tokens-reset": "2026-05-21T06:48:48Z", + "anthropic-ratelimit-output-tokens-reset": "2026-05-22T08:13:08Z", "anthropic-ratelimit-requests-limit": "20000", "anthropic-ratelimit-requests-remaining": "19999", - "anthropic-ratelimit-requests-reset": "2026-05-21T06:48:48Z", + "anthropic-ratelimit-requests-reset": "2026-05-22T08:13:08Z", "anthropic-ratelimit-tokens-limit": "3600000", "anthropic-ratelimit-tokens-remaining": "3599000", - "anthropic-ratelimit-tokens-reset": "2026-05-21T06:48:48Z", + "anthropic-ratelimit-tokens-reset": "2026-05-22T08:13:08Z", "cache-control": "no-cache", "cf-cache-status": "DYNAMIC", - "cf-ray": "9ff1a3375ccc5b94-VIE", + "cf-ray": "9ffa5c1cbcdd5db9-VIE", "connection": "keep-alive", "content-encoding": "gzip", "content-security-policy": "default-src 'none'; frame-ancestors 'none'", "content-type": "text/event-stream; charset=utf-8", - "date": "Thu, 21 May 2026 06:48:50 GMT", - "request-id": "req_011CbFGUT9etAvivisBwyd9k", + "date": "Fri, 22 May 2026 08:13:09 GMT", + "request-id": "req_011CbHGiKQyD4CKrnb72HeYh", "server": "cloudflare", "set-cookie": "[REDACTED]", "strict-transport-security": "max-age=31536000; includeSubDomains; preload", - "traceresponse": "00-c3f1d31c1e9f55400e02f81a6b4dc844-2853195a6edda6de-01", + "traceresponse": "00-8da16ded55b300300e9dc89695f1622a-3b76f650e176116b-01", "transfer-encoding": "chunked", "vary": "Accept-Encoding", - "x-envoy-upstream-service-time": "1692", + "x-envoy-upstream-service-time": "1215", "x-robots-tag": "none" }, "status": 200, @@ -2000,14 +2130,14 @@ "callIndex": 0, "id": "7c0e162d6794cf5d", "matchKey": "POST api.openai.com/v1/responses", - "recordedAt": "2026-05-21T06:48:53.133Z", + "recordedAt": "2026-05-22T08:13:11.160Z", "request": { "body": { "kind": "json", "value": { "input": [ { - "content": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Thu, May 21, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-LqmoTW/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + "content": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /Users/lucaforstner/conductor/workspaces/braintrust-sdk-javascript/tashkent/e2e/.bt-tmp/run-HpI3r1/scenarios/flue-instrumentation\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", "role": "system" }, { @@ -2043,7 +2173,9 @@ "type": "string" } }, - "required": ["path"], + "required": [ + "path" + ], "type": "object" }, "strict": false, @@ -2063,7 +2195,10 @@ "type": "string" } }, - "required": ["path", "content"], + "required": [ + "path", + "content" + ], "type": "object" }, "strict": false, @@ -2091,7 +2226,11 @@ "type": "boolean" } }, - "required": ["path", "oldText", "newText"], + "required": [ + "path", + "oldText", + "newText" + ], "type": "object" }, "strict": false, @@ -2111,7 +2250,9 @@ "type": "number" } }, - "required": ["command"], + "required": [ + "command" + ], "type": "object" }, "strict": false, @@ -2135,7 +2276,9 @@ "type": "string" } }, - "required": ["pattern"], + "required": [ + "pattern" + ], "type": "object" }, "strict": false, @@ -2155,7 +2298,9 @@ "type": "string" } }, - "required": ["pattern"], + "required": [ + "pattern" + ], "type": "object" }, "strict": false, @@ -2183,7 +2328,9 @@ "type": "string" } }, - "required": ["prompt"], + "required": [ + "prompt" + ], "type": "object" }, "strict": false, @@ -2199,16 +2346,16 @@ "response": { "body": { "chunks": [ - "event: response.created\ndata: {\"type\":\"response.created\",\"response\":{\"id\":\"resp_096103382013eb85016a0eaad439ec81a285f2218da4217678\",\"object\":\"response\",\"created_at\":1779346132,\"status\":\"in_progress\",\"background\":false,\"completed_at\":null,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":null,\"instructions\":null,\"max_output_tokens\":null,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":\"flue-e2e-instance::default::task:task:3eb8d137-c6b5-45ef-968e-a7\",\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"auto\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[{\"type\":\"function\",\"description\":\"Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.\",\"name\":\"read\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to read\"},\"offset\":{\"type\":\"number\",\"description\":\"Line number to start from (1-indexed)\"},\"limit\":{\"type\":\"number\",\"description\":\"Maximum number of lines to read\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Write content to a file. Creates the file and parent directories if they do not exist.\",\"name\":\"write\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"content\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to write\"},\"content\":{\"type\":\"string\",\"description\":\"Content to write to the file\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.\",\"name\":\"edit\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"oldText\",\"newText\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to edit\"},\"oldText\":{\"type\":\"string\",\"description\":\"Exact text to find (must be unique)\"},\"newText\":{\"type\":\"string\",\"description\":\"Replacement text\"},\"replaceAll\":{\"type\":\"boolean\",\"description\":\"Replace all occurrences\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.\",\"name\":\"bash\",\"parameters\":{\"type\":\"object\",\"required\":[\"command\"],\"properties\":{\"command\":{\"type\":\"string\",\"description\":\"Bash command to execute\"},\"timeout\":{\"type\":\"number\",\"description\":\"Timeout in seconds\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.\",\"name\":\"grep\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Search pattern (regex)\"},\"path\":{\"type\":\"string\",\"description\":\"Directory or file to search (default: .)\"},\"include\":{\"type\":\"string\",\"description\":\"Glob filter, e.g. \\\"*.ts\\\"\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Find files by filename pattern using shell find -name semantics. Returns matching file paths.\",\"name\":\"glob\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Filename pattern, e.g. \\\"*.ts\\\"\"},\"path\":{\"type\":\"string\",\"description\":\"Directory to search in (default: .)\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.\",\"name\":\"task\",\"parameters\":{\"type\":\"object\",\"required\":[\"prompt\"],\"properties\":{\"description\":{\"type\":\"string\",\"description\":\"Short human-readable label for the delegated work\"},\"prompt\":{\"type\":\"string\",\"description\":\"Focused instructions for the child agent\"},\"role\":{\"type\":\"string\",\"description\":\"Role to use for the child agent\"},\"cwd\":{\"type\":\"string\",\"description\":\"Working directory for the child agent. AGENTS.md and skills are discovered from here.\"}}},\"strict\":false}],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":null,\"user\":null,\"metadata\":{}},\"sequence_number\":0}", - "event: response.in_progress\ndata: {\"type\":\"response.in_progress\",\"response\":{\"id\":\"resp_096103382013eb85016a0eaad439ec81a285f2218da4217678\",\"object\":\"response\",\"created_at\":1779346132,\"status\":\"in_progress\",\"background\":false,\"completed_at\":null,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":null,\"instructions\":null,\"max_output_tokens\":null,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":\"flue-e2e-instance::default::task:task:3eb8d137-c6b5-45ef-968e-a7\",\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"auto\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[{\"type\":\"function\",\"description\":\"Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.\",\"name\":\"read\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to read\"},\"offset\":{\"type\":\"number\",\"description\":\"Line number to start from (1-indexed)\"},\"limit\":{\"type\":\"number\",\"description\":\"Maximum number of lines to read\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Write content to a file. Creates the file and parent directories if they do not exist.\",\"name\":\"write\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"content\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to write\"},\"content\":{\"type\":\"string\",\"description\":\"Content to write to the file\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.\",\"name\":\"edit\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"oldText\",\"newText\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to edit\"},\"oldText\":{\"type\":\"string\",\"description\":\"Exact text to find (must be unique)\"},\"newText\":{\"type\":\"string\",\"description\":\"Replacement text\"},\"replaceAll\":{\"type\":\"boolean\",\"description\":\"Replace all occurrences\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.\",\"name\":\"bash\",\"parameters\":{\"type\":\"object\",\"required\":[\"command\"],\"properties\":{\"command\":{\"type\":\"string\",\"description\":\"Bash command to execute\"},\"timeout\":{\"type\":\"number\",\"description\":\"Timeout in seconds\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.\",\"name\":\"grep\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Search pattern (regex)\"},\"path\":{\"type\":\"string\",\"description\":\"Directory or file to search (default: .)\"},\"include\":{\"type\":\"string\",\"description\":\"Glob filter, e.g. \\\"*.ts\\\"\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Find files by filename pattern using shell find -name semantics. Returns matching file paths.\",\"name\":\"glob\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Filename pattern, e.g. \\\"*.ts\\\"\"},\"path\":{\"type\":\"string\",\"description\":\"Directory to search in (default: .)\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.\",\"name\":\"task\",\"parameters\":{\"type\":\"object\",\"required\":[\"prompt\"],\"properties\":{\"description\":{\"type\":\"string\",\"description\":\"Short human-readable label for the delegated work\"},\"prompt\":{\"type\":\"string\",\"description\":\"Focused instructions for the child agent\"},\"role\":{\"type\":\"string\",\"description\":\"Role to use for the child agent\"},\"cwd\":{\"type\":\"string\",\"description\":\"Working directory for the child agent. AGENTS.md and skills are discovered from here.\"}}},\"strict\":false}],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":null,\"user\":null,\"metadata\":{}},\"sequence_number\":1}", - "event: response.output_item.added\ndata: {\"type\":\"response.output_item.added\",\"item\":{\"id\":\"msg_096103382013eb85016a0eaad4da7081a2aff38723fc8bb352\",\"type\":\"message\",\"status\":\"in_progress\",\"content\":[],\"role\":\"assistant\"},\"output_index\":0,\"sequence_number\":2}", - "event: response.content_part.added\ndata: {\"type\":\"response.content_part.added\",\"content_index\":0,\"item_id\":\"msg_096103382013eb85016a0eaad4da7081a2aff38723fc8bb352\",\"output_index\":0,\"part\":{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"\"},\"sequence_number\":3}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"TASK\",\"item_id\":\"msg_096103382013eb85016a0eaad4da7081a2aff38723fc8bb352\",\"logprobs\":[],\"obfuscation\":\"fpYfkU75RFuY\",\"output_index\":0,\"sequence_number\":4}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"_DONE\",\"item_id\":\"msg_096103382013eb85016a0eaad4da7081a2aff38723fc8bb352\",\"logprobs\":[],\"obfuscation\":\"n7VXctSvkaB\",\"output_index\":0,\"sequence_number\":5}", - "event: response.output_text.done\ndata: {\"type\":\"response.output_text.done\",\"content_index\":0,\"item_id\":\"msg_096103382013eb85016a0eaad4da7081a2aff38723fc8bb352\",\"logprobs\":[],\"output_index\":0,\"sequence_number\":6,\"text\":\"TASK_DONE\"}", - "event: response.content_part.done\ndata: {\"type\":\"response.content_part.done\",\"content_index\":0,\"item_id\":\"msg_096103382013eb85016a0eaad4da7081a2aff38723fc8bb352\",\"output_index\":0,\"part\":{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"TASK_DONE\"},\"sequence_number\":7}", - "event: response.output_item.done\ndata: {\"type\":\"response.output_item.done\",\"item\":{\"id\":\"msg_096103382013eb85016a0eaad4da7081a2aff38723fc8bb352\",\"type\":\"message\",\"status\":\"completed\",\"content\":[{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"TASK_DONE\"}],\"role\":\"assistant\"},\"output_index\":0,\"sequence_number\":8}", - "event: response.completed\ndata: {\"type\":\"response.completed\",\"response\":{\"id\":\"resp_096103382013eb85016a0eaad439ec81a285f2218da4217678\",\"object\":\"response\",\"created_at\":1779346132,\"status\":\"completed\",\"background\":false,\"completed_at\":1779346132,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":null,\"instructions\":null,\"max_output_tokens\":null,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[{\"id\":\"msg_096103382013eb85016a0eaad4da7081a2aff38723fc8bb352\",\"type\":\"message\",\"status\":\"completed\",\"content\":[{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"TASK_DONE\"}],\"role\":\"assistant\"}],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":\"flue-e2e-instance::default::task:task:3eb8d137-c6b5-45ef-968e-a7\",\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"default\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[{\"type\":\"function\",\"description\":\"Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.\",\"name\":\"read\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to read\"},\"offset\":{\"type\":\"number\",\"description\":\"Line number to start from (1-indexed)\"},\"limit\":{\"type\":\"number\",\"description\":\"Maximum number of lines to read\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Write content to a file. Creates the file and parent directories if they do not exist.\",\"name\":\"write\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"content\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to write\"},\"content\":{\"type\":\"string\",\"description\":\"Content to write to the file\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.\",\"name\":\"edit\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"oldText\",\"newText\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to edit\"},\"oldText\":{\"type\":\"string\",\"description\":\"Exact text to find (must be unique)\"},\"newText\":{\"type\":\"string\",\"description\":\"Replacement text\"},\"replaceAll\":{\"type\":\"boolean\",\"description\":\"Replace all occurrences\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.\",\"name\":\"bash\",\"parameters\":{\"type\":\"object\",\"required\":[\"command\"],\"properties\":{\"command\":{\"type\":\"string\",\"description\":\"Bash command to execute\"},\"timeout\":{\"type\":\"number\",\"description\":\"Timeout in seconds\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.\",\"name\":\"grep\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Search pattern (regex)\"},\"path\":{\"type\":\"string\",\"description\":\"Directory or file to search (default: .)\"},\"include\":{\"type\":\"string\",\"description\":\"Glob filter, e.g. \\\"*.ts\\\"\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Find files by filename pattern using shell find -name semantics. Returns matching file paths.\",\"name\":\"glob\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Filename pattern, e.g. \\\"*.ts\\\"\"},\"path\":{\"type\":\"string\",\"description\":\"Directory to search in (default: .)\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.\",\"name\":\"task\",\"parameters\":{\"type\":\"object\",\"required\":[\"prompt\"],\"properties\":{\"description\":{\"type\":\"string\",\"description\":\"Short human-readable label for the delegated work\"},\"prompt\":{\"type\":\"string\",\"description\":\"Focused instructions for the child agent\"},\"role\":{\"type\":\"string\",\"description\":\"Role to use for the child agent\"},\"cwd\":{\"type\":\"string\",\"description\":\"Working directory for the child agent. AGENTS.md and skills are discovered from here.\"}}},\"strict\":false}],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":{\"input_tokens\":770,\"input_tokens_details\":{\"cached_tokens\":0},\"output_tokens\":4,\"output_tokens_details\":{\"reasoning_tokens\":0},\"total_tokens\":774},\"user\":null,\"metadata\":{}},\"sequence_number\":9}" + "event: response.created\ndata: {\"type\":\"response.created\",\"response\":{\"id\":\"resp_02acb0b56a57c778016a101015cb608196ba237c741a1ce434\",\"object\":\"response\",\"created_at\":1779437589,\"status\":\"in_progress\",\"background\":false,\"completed_at\":null,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":null,\"instructions\":null,\"max_output_tokens\":null,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":\"flue-e2e-instance::default::task:task:550c7301-0a1c-47a4-889b-17\",\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"auto\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[{\"type\":\"function\",\"description\":\"Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.\",\"name\":\"read\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to read\"},\"offset\":{\"type\":\"number\",\"description\":\"Line number to start from (1-indexed)\"},\"limit\":{\"type\":\"number\",\"description\":\"Maximum number of lines to read\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Write content to a file. Creates the file and parent directories if they do not exist.\",\"name\":\"write\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"content\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to write\"},\"content\":{\"type\":\"string\",\"description\":\"Content to write to the file\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.\",\"name\":\"edit\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"oldText\",\"newText\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to edit\"},\"oldText\":{\"type\":\"string\",\"description\":\"Exact text to find (must be unique)\"},\"newText\":{\"type\":\"string\",\"description\":\"Replacement text\"},\"replaceAll\":{\"type\":\"boolean\",\"description\":\"Replace all occurrences\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.\",\"name\":\"bash\",\"parameters\":{\"type\":\"object\",\"required\":[\"command\"],\"properties\":{\"command\":{\"type\":\"string\",\"description\":\"Bash command to execute\"},\"timeout\":{\"type\":\"number\",\"description\":\"Timeout in seconds\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.\",\"name\":\"grep\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Search pattern (regex)\"},\"path\":{\"type\":\"string\",\"description\":\"Directory or file to search (default: .)\"},\"include\":{\"type\":\"string\",\"description\":\"Glob filter, e.g. \\\"*.ts\\\"\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Find files by filename pattern using shell find -name semantics. Returns matching file paths.\",\"name\":\"glob\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Filename pattern, e.g. \\\"*.ts\\\"\"},\"path\":{\"type\":\"string\",\"description\":\"Directory to search in (default: .)\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.\",\"name\":\"task\",\"parameters\":{\"type\":\"object\",\"required\":[\"prompt\"],\"properties\":{\"description\":{\"type\":\"string\",\"description\":\"Short human-readable label for the delegated work\"},\"prompt\":{\"type\":\"string\",\"description\":\"Focused instructions for the child agent\"},\"role\":{\"type\":\"string\",\"description\":\"Role to use for the child agent\"},\"cwd\":{\"type\":\"string\",\"description\":\"Working directory for the child agent. AGENTS.md and skills are discovered from here.\"}}},\"strict\":false}],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":null,\"user\":null,\"metadata\":{}},\"sequence_number\":0}", + "event: response.in_progress\ndata: {\"type\":\"response.in_progress\",\"response\":{\"id\":\"resp_02acb0b56a57c778016a101015cb608196ba237c741a1ce434\",\"object\":\"response\",\"created_at\":1779437589,\"status\":\"in_progress\",\"background\":false,\"completed_at\":null,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":null,\"instructions\":null,\"max_output_tokens\":null,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":\"flue-e2e-instance::default::task:task:550c7301-0a1c-47a4-889b-17\",\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"auto\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[{\"type\":\"function\",\"description\":\"Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.\",\"name\":\"read\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to read\"},\"offset\":{\"type\":\"number\",\"description\":\"Line number to start from (1-indexed)\"},\"limit\":{\"type\":\"number\",\"description\":\"Maximum number of lines to read\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Write content to a file. Creates the file and parent directories if they do not exist.\",\"name\":\"write\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"content\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to write\"},\"content\":{\"type\":\"string\",\"description\":\"Content to write to the file\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.\",\"name\":\"edit\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"oldText\",\"newText\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to edit\"},\"oldText\":{\"type\":\"string\",\"description\":\"Exact text to find (must be unique)\"},\"newText\":{\"type\":\"string\",\"description\":\"Replacement text\"},\"replaceAll\":{\"type\":\"boolean\",\"description\":\"Replace all occurrences\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.\",\"name\":\"bash\",\"parameters\":{\"type\":\"object\",\"required\":[\"command\"],\"properties\":{\"command\":{\"type\":\"string\",\"description\":\"Bash command to execute\"},\"timeout\":{\"type\":\"number\",\"description\":\"Timeout in seconds\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.\",\"name\":\"grep\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Search pattern (regex)\"},\"path\":{\"type\":\"string\",\"description\":\"Directory or file to search (default: .)\"},\"include\":{\"type\":\"string\",\"description\":\"Glob filter, e.g. \\\"*.ts\\\"\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Find files by filename pattern using shell find -name semantics. Returns matching file paths.\",\"name\":\"glob\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Filename pattern, e.g. \\\"*.ts\\\"\"},\"path\":{\"type\":\"string\",\"description\":\"Directory to search in (default: .)\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.\",\"name\":\"task\",\"parameters\":{\"type\":\"object\",\"required\":[\"prompt\"],\"properties\":{\"description\":{\"type\":\"string\",\"description\":\"Short human-readable label for the delegated work\"},\"prompt\":{\"type\":\"string\",\"description\":\"Focused instructions for the child agent\"},\"role\":{\"type\":\"string\",\"description\":\"Role to use for the child agent\"},\"cwd\":{\"type\":\"string\",\"description\":\"Working directory for the child agent. AGENTS.md and skills are discovered from here.\"}}},\"strict\":false}],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":null,\"user\":null,\"metadata\":{}},\"sequence_number\":1}", + "event: response.output_item.added\ndata: {\"type\":\"response.output_item.added\",\"item\":{\"id\":\"msg_02acb0b56a57c778016a101016e3388196ad49dd6c55f861ab\",\"type\":\"message\",\"status\":\"in_progress\",\"content\":[],\"role\":\"assistant\"},\"output_index\":0,\"sequence_number\":2}", + "event: response.content_part.added\ndata: {\"type\":\"response.content_part.added\",\"content_index\":0,\"item_id\":\"msg_02acb0b56a57c778016a101016e3388196ad49dd6c55f861ab\",\"output_index\":0,\"part\":{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"\"},\"sequence_number\":3}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"TASK\",\"item_id\":\"msg_02acb0b56a57c778016a101016e3388196ad49dd6c55f861ab\",\"logprobs\":[],\"obfuscation\":\"K6AG6tDa94wn\",\"output_index\":0,\"sequence_number\":4}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"_DONE\",\"item_id\":\"msg_02acb0b56a57c778016a101016e3388196ad49dd6c55f861ab\",\"logprobs\":[],\"obfuscation\":\"XtIFjcwdHFb\",\"output_index\":0,\"sequence_number\":5}", + "event: response.output_text.done\ndata: {\"type\":\"response.output_text.done\",\"content_index\":0,\"item_id\":\"msg_02acb0b56a57c778016a101016e3388196ad49dd6c55f861ab\",\"logprobs\":[],\"output_index\":0,\"sequence_number\":6,\"text\":\"TASK_DONE\"}", + "event: response.content_part.done\ndata: {\"type\":\"response.content_part.done\",\"content_index\":0,\"item_id\":\"msg_02acb0b56a57c778016a101016e3388196ad49dd6c55f861ab\",\"output_index\":0,\"part\":{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"TASK_DONE\"},\"sequence_number\":7}", + "event: response.output_item.done\ndata: {\"type\":\"response.output_item.done\",\"item\":{\"id\":\"msg_02acb0b56a57c778016a101016e3388196ad49dd6c55f861ab\",\"type\":\"message\",\"status\":\"completed\",\"content\":[{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"TASK_DONE\"}],\"role\":\"assistant\"},\"output_index\":0,\"sequence_number\":8}", + "event: response.completed\ndata: {\"type\":\"response.completed\",\"response\":{\"id\":\"resp_02acb0b56a57c778016a101015cb608196ba237c741a1ce434\",\"object\":\"response\",\"created_at\":1779437589,\"status\":\"completed\",\"background\":false,\"completed_at\":1779437590,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":null,\"instructions\":null,\"max_output_tokens\":null,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[{\"id\":\"msg_02acb0b56a57c778016a101016e3388196ad49dd6c55f861ab\",\"type\":\"message\",\"status\":\"completed\",\"content\":[{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"TASK_DONE\"}],\"role\":\"assistant\"}],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":\"flue-e2e-instance::default::task:task:550c7301-0a1c-47a4-889b-17\",\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"default\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[{\"type\":\"function\",\"description\":\"Read a file or list a directory. For files, output is truncated to 2000 lines or 50KB — use offset/limit for large files. For directories, returns the list of entries.\",\"name\":\"read\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to read\"},\"offset\":{\"type\":\"number\",\"description\":\"Line number to start from (1-indexed)\"},\"limit\":{\"type\":\"number\",\"description\":\"Maximum number of lines to read\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Write content to a file. Creates the file and parent directories if they do not exist.\",\"name\":\"write\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"content\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to write\"},\"content\":{\"type\":\"string\",\"description\":\"Content to write to the file\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Edit a file using exact text replacement. The oldText must match a unique region of the file. Use replaceAll to replace all occurrences.\",\"name\":\"edit\",\"parameters\":{\"type\":\"object\",\"required\":[\"path\",\"oldText\",\"newText\"],\"properties\":{\"path\":{\"type\":\"string\",\"description\":\"Path to the file to edit\"},\"oldText\":{\"type\":\"string\",\"description\":\"Exact text to find (must be unique)\"},\"newText\":{\"type\":\"string\",\"description\":\"Replacement text\"},\"replaceAll\":{\"type\":\"boolean\",\"description\":\"Replace all occurrences\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Execute a bash command. Returns stdout and stderr. Output is truncated to the last 2000 lines or 50KB.\",\"name\":\"bash\",\"parameters\":{\"type\":\"object\",\"required\":[\"command\"],\"properties\":{\"command\":{\"type\":\"string\",\"description\":\"Bash command to execute\"},\"timeout\":{\"type\":\"number\",\"description\":\"Timeout in seconds\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Search file contents for a regex pattern. Returns matching lines with file paths and line numbers.\",\"name\":\"grep\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Search pattern (regex)\"},\"path\":{\"type\":\"string\",\"description\":\"Directory or file to search (default: .)\"},\"include\":{\"type\":\"string\",\"description\":\"Glob filter, e.g. \\\"*.ts\\\"\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Find files by filename pattern using shell find -name semantics. Returns matching file paths.\",\"name\":\"glob\",\"parameters\":{\"type\":\"object\",\"required\":[\"pattern\"],\"properties\":{\"pattern\":{\"type\":\"string\",\"description\":\"Filename pattern, e.g. \\\"*.ts\\\"\"},\"path\":{\"type\":\"string\",\"description\":\"Directory to search in (default: .)\"}}},\"strict\":false},{\"type\":\"function\",\"description\":\"Delegate a focused task to a detached child agent with its own context. Use this for independent research, file exploration, or parallel work. The task returns only its final answer to this conversation. Available roles: skillRunner.\",\"name\":\"task\",\"parameters\":{\"type\":\"object\",\"required\":[\"prompt\"],\"properties\":{\"description\":{\"type\":\"string\",\"description\":\"Short human-readable label for the delegated work\"},\"prompt\":{\"type\":\"string\",\"description\":\"Focused instructions for the child agent\"},\"role\":{\"type\":\"string\",\"description\":\"Role to use for the child agent\"},\"cwd\":{\"type\":\"string\",\"description\":\"Working directory for the child agent. AGENTS.md and skills are discovered from here.\"}}},\"strict\":false}],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":{\"input_tokens\":772,\"input_tokens_details\":{\"cached_tokens\":0},\"output_tokens\":4,\"output_tokens_details\":{\"reasoning_tokens\":0},\"total_tokens\":776},\"user\":null,\"metadata\":{}},\"sequence_number\":9}" ], "kind": "sse" }, @@ -2216,12 +2363,12 @@ "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", "alt-svc": "h3=\":443\"; ma=86400", "cf-cache-status": "DYNAMIC", - "cf-ray": "9ff1a34b8d2fc2e1-VIE", + "cf-ray": "9ffa5c2718d6c31f-VIE", "connection": "keep-alive", "content-type": "text/event-stream; charset=utf-8", - "date": "Thu, 21 May 2026 06:48:52 GMT", + "date": "Fri, 22 May 2026 08:13:09 GMT", "openai-organization": "braintrust-data", - "openai-processing-ms": "275", + "openai-processing-ms": "127", "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", "openai-version": "2020-10-01", "server": "cloudflare", @@ -2229,7 +2376,7 @@ "strict-transport-security": "max-age=31536000; includeSubDomains; preload", "transfer-encoding": "chunked", "x-content-type-options": "nosniff", - "x-request-id": "req_be83807190d94355ac6fd63b2891b416" + "x-request-id": "req_2a4bc74503354197a53d2b818e417dcc" }, "status": 200, "statusText": "OK" @@ -2239,7 +2386,7 @@ "callIndex": 1, "id": "f12aff3913439248", "matchKey": "POST api.openai.com/v1/responses", - "recordedAt": "2026-05-21T06:48:54.176Z", + "recordedAt": "2026-05-22T08:13:12.327Z", "request": { "body": { "kind": "json", @@ -2252,7 +2399,7 @@ { "content": [ { - "text": "\n[User]: Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.\n\n[Assistant thinking]: The user wants me to complete an instrumented research flow with exactly three steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id to call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url to call summarize_source\n4. After that, reply with exactly \"PROMPT_DONE\"\n\nThe user also emphasizes that I should call exactly one tool per turn and wait for each tool result before choosing the next tool.\n\nLet me start with Step 1: calling lookup with query \"flue instrumentation\".\n\n[Assistant]: I'll complete this instrumented research flow step by step. Starting with Step 1:\n\n[Assistant tool calls]: lookup(query=\"flue instrumentation\")\n\n[Tool result]: {\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}\n\n[Assistant thinking]: Good, I got the lookup result with id \"flue-session-2026\". Now I need to proceed to Step 2: call web_search using this lookupId and the query \"Braintrust Flue reasoning stream instrumentation\".\n\n[Assistant]: Now proceeding to Step 2:\n\n[Assistant tool calls]: web_search(lookupId=\"flue-session-2026\", query=\"Braintrust Flue reasoning stream instrumentation\")\n\n[Tool result]: {\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\",\"results\":[{\"title\":\"Flue reasoning stream instrumentation\",\"url\":\"https://example.test/flue/reasoning-streams\"}]}\n\n[Assistant thinking]: Perfect! I got the web_search results. There's one result with the URL \"https://example.test/flue/reasoning-streams\". Now I need to proceed to Step 3: call summarize_source with this URL.\n\n[Assistant]: Now proceeding to Step 3:\n\n[Assistant tool calls]: summarize_source(url=\"https://example.test/flue/reasoning-streams\")\n\n[Tool result]: {\"summary\":\"Flue emits reasoning, tool execution, and LLM turn events separately.\",\"url\":\"https://example.test/flue/reasoning-streams\"}\n\n\nThis is the PREFIX of a turn that was too large to keep. The SUFFIX (recent work) is retained.\n\nSummarize the prefix to provide context for the retained suffix:\n\n## Original Request\n[What did the user ask for in this turn?]\n\n## Early Progress\n- [Key decisions and work done in the prefix]\n\n## Context for Suffix\n- [Information needed to understand the retained recent work]\n\nBe concise. Focus on what's needed to understand the kept suffix.", + "text": "\n[User]: Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.\n\n[Assistant thinking]: The user wants me to complete an instrumented research flow with specific steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id to call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url to call summarize_source\n4. After summarize_source returns, reply with exactly \"PROMPT_DONE\"\n\nI need to call exactly one tool per turn and wait for each result. Let me start with step 1.\n\n[Assistant]: I'll complete this instrumented research flow step by step. Starting with Step 1:\n\n[Assistant tool calls]: lookup(query=\"flue instrumentation\")\n\n[Tool result]: {\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}\n\n[Assistant thinking]: Good, I got the lookup result with id \"flue-session-2026\". Now I need to proceed to Step 2 and use this id as the lookupId parameter when calling web_search with the query \"Braintrust Flue reasoning stream instrumentation\".\n\n[Assistant]: Now proceeding to Step 2 with the lookup ID:\n\n[Assistant tool calls]: web_search(lookupId=\"flue-session-2026\", query=\"Braintrust Flue reasoning stream instrumentation\")\n\n[Tool result]: {\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\",\"results\":[{\"title\":\"Flue reasoning stream instrumentation\",\"url\":\"https://example.test/flue/reasoning-streams\"}]}\n\n[Assistant thinking]: Perfect! I got the web_search results. There's one result with the URL \"https://example.test/flue/reasoning-streams\". Now I need to proceed to Step 3 and call summarize_source with this URL.\n\n[Assistant]: Now proceeding to Step 3 with the first result URL:\n\n[Assistant tool calls]: summarize_source(url=\"https://example.test/flue/reasoning-streams\")\n\n[Tool result]: {\"summary\":\"Flue emits reasoning, tool execution, and LLM turn events separately.\",\"url\":\"https://example.test/flue/reasoning-streams\"}\n\n\nThis is the PREFIX of a turn that was too large to keep. The SUFFIX (recent work) is retained.\n\nSummarize the prefix to provide context for the retained suffix:\n\n## Original Request\n[What did the user ask for in this turn?]\n\n## Early Progress\n- [Key decisions and work done in the prefix]\n\n## Context for Suffix\n- [Information needed to understand the retained recent work]\n\nBe concise. Focus on what's needed to understand the kept suffix.", "type": "input_text" } ], @@ -2272,46 +2419,46 @@ "response": { "body": { "chunks": [ - "event: response.created\ndata: {\"type\":\"response.created\",\"response\":{\"id\":\"resp_0bad5a1de3e678f7016a0eaad5534c81959938a717dfba279b\",\"object\":\"response\",\"created_at\":1779346133,\"status\":\"in_progress\",\"background\":false,\"completed_at\":null,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":null,\"instructions\":null,\"max_output_tokens\":32,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":null,\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"auto\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":null,\"user\":null,\"metadata\":{}},\"sequence_number\":0}", - "event: response.in_progress\ndata: {\"type\":\"response.in_progress\",\"response\":{\"id\":\"resp_0bad5a1de3e678f7016a0eaad5534c81959938a717dfba279b\",\"object\":\"response\",\"created_at\":1779346133,\"status\":\"in_progress\",\"background\":false,\"completed_at\":null,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":null,\"instructions\":null,\"max_output_tokens\":32,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":null,\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"auto\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":null,\"user\":null,\"metadata\":{}},\"sequence_number\":1}", - "event: response.output_item.added\ndata: {\"type\":\"response.output_item.added\",\"item\":{\"id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"type\":\"message\",\"status\":\"in_progress\",\"content\":[],\"role\":\"assistant\"},\"output_index\":0,\"sequence_number\":2}", - "event: response.content_part.added\ndata: {\"type\":\"response.content_part.added\",\"content_index\":0,\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"output_index\":0,\"part\":{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"\"},\"sequence_number\":3}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"##\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"ZPu7BY4Of9RVt1\",\"output_index\":0,\"sequence_number\":4}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" Original\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"NTCRLVI\",\"output_index\":0,\"sequence_number\":5}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" Request\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"lvHw79ol\",\"output_index\":0,\"sequence_number\":6}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"\\n\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"qgDK72d0DqJzShe\",\"output_index\":0,\"sequence_number\":7}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"The\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"zxiLObn7xQuJc\",\"output_index\":0,\"sequence_number\":8}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" user\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"ZmDPVxDahg1\",\"output_index\":0,\"sequence_number\":9}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" asked\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"juGAL5bL8H\",\"output_index\":0,\"sequence_number\":10}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" for\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"UqT8QyGWJ1Cs\",\"output_index\":0,\"sequence_number\":11}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" a\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"ZFz9DG88CCg2d0\",\"output_index\":0,\"sequence_number\":12}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" step\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"FtIRl6vb8rh\",\"output_index\":0,\"sequence_number\":13}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"-by\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"fVbs7xkoxEmPY\",\"output_index\":0,\"sequence_number\":14}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"-step\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"JRwkU4V2Oy5\",\"output_index\":0,\"sequence_number\":15}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" completion\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"mSb47\",\"output_index\":0,\"sequence_number\":16}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" of\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"cSzEvYcwXoDYU\",\"output_index\":0,\"sequence_number\":17}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" an\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"v0eKIIYEcUvcM\",\"output_index\":0,\"sequence_number\":18}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" instrument\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"Tjoqr\",\"output_index\":0,\"sequence_number\":19}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"ed\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"PjMtpfwUF0hHJt\",\"output_index\":0,\"sequence_number\":20}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" research\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"dUx9fbZ\",\"output_index\":0,\"sequence_number\":21}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" flow\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"QrmkD9iirTC\",\"output_index\":0,\"sequence_number\":22}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" involving\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"GgVVoR\",\"output_index\":0,\"sequence_number\":23}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" lookup\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"jbRyl42fm\",\"output_index\":0,\"sequence_number\":24}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\",\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"M1ztdjqKpVB87HF\",\"output_index\":0,\"sequence_number\":25}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" web\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"mIXL607CP0CD\",\"output_index\":0,\"sequence_number\":26}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" search\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"8dBYoFevC\",\"output_index\":0,\"sequence_number\":27}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\",\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"ESNpvnq3vrWxNgG\",\"output_index\":0,\"sequence_number\":28}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" and\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"vxNZIlXgihwA\",\"output_index\":0,\"sequence_number\":29}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" summar\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"LvmNVHkMr\",\"output_index\":0,\"sequence_number\":30}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"ization\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"vuIOLbmmg\",\"output_index\":0,\"sequence_number\":31}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\".\\n\\n\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"bSs8GprnEKUEZ\",\"output_index\":0,\"sequence_number\":32}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"##\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"o50Zp3Jj2IWoZb\",\"output_index\":0,\"sequence_number\":33}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" Early\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"oJYzY8lvrF\",\"output_index\":0,\"sequence_number\":34}", - "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" Progress\",\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"obfuscation\":\"JwRxUVU\",\"output_index\":0,\"sequence_number\":35}", - "event: response.output_text.done\ndata: {\"type\":\"response.output_text.done\",\"content_index\":0,\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"logprobs\":[],\"output_index\":0,\"sequence_number\":36,\"text\":\"## Original Request\\nThe user asked for a step-by-step completion of an instrumented research flow involving lookup, web search, and summarization.\\n\\n## Early Progress\"}", - "event: response.content_part.done\ndata: {\"type\":\"response.content_part.done\",\"content_index\":0,\"item_id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"output_index\":0,\"part\":{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"## Original Request\\nThe user asked for a step-by-step completion of an instrumented research flow involving lookup, web search, and summarization.\\n\\n## Early Progress\"},\"sequence_number\":37}", - "event: response.output_item.done\ndata: {\"type\":\"response.output_item.done\",\"item\":{\"id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"type\":\"message\",\"status\":\"incomplete\",\"content\":[{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"## Original Request\\nThe user asked for a step-by-step completion of an instrumented research flow involving lookup, web search, and summarization.\\n\\n## Early Progress\"}],\"role\":\"assistant\"},\"output_index\":0,\"sequence_number\":38}", - "event: response.incomplete\ndata: {\"type\":\"response.incomplete\",\"response\":{\"id\":\"resp_0bad5a1de3e678f7016a0eaad5534c81959938a717dfba279b\",\"object\":\"response\",\"created_at\":1779346133,\"status\":\"incomplete\",\"background\":false,\"completed_at\":null,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":{\"reason\":\"max_output_tokens\"},\"instructions\":null,\"max_output_tokens\":32,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[{\"id\":\"msg_0bad5a1de3e678f7016a0eaad5c4ec8195acb290892786c9cc\",\"type\":\"message\",\"status\":\"incomplete\",\"content\":[{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"## Original Request\\nThe user asked for a step-by-step completion of an instrumented research flow involving lookup, web search, and summarization.\\n\\n## Early Progress\"}],\"role\":\"assistant\"}],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":null,\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"default\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":{\"input_tokens\":707,\"input_tokens_details\":{\"cached_tokens\":0},\"output_tokens\":32,\"output_tokens_details\":{\"reasoning_tokens\":0},\"total_tokens\":739},\"user\":null,\"metadata\":{}},\"sequence_number\":39}" + "event: response.created\ndata: {\"type\":\"response.created\",\"response\":{\"id\":\"resp_0d2b14e39122d1ad016a10101753648197a50d4b2b8228ecfb\",\"object\":\"response\",\"created_at\":1779437591,\"status\":\"in_progress\",\"background\":false,\"completed_at\":null,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":null,\"instructions\":null,\"max_output_tokens\":32,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":null,\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"auto\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":null,\"user\":null,\"metadata\":{}},\"sequence_number\":0}", + "event: response.in_progress\ndata: {\"type\":\"response.in_progress\",\"response\":{\"id\":\"resp_0d2b14e39122d1ad016a10101753648197a50d4b2b8228ecfb\",\"object\":\"response\",\"created_at\":1779437591,\"status\":\"in_progress\",\"background\":false,\"completed_at\":null,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":null,\"instructions\":null,\"max_output_tokens\":32,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":null,\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"auto\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":null,\"user\":null,\"metadata\":{}},\"sequence_number\":1}", + "event: response.output_item.added\ndata: {\"type\":\"response.output_item.added\",\"item\":{\"id\":\"msg_0d2b14e39122d1ad016a101017cac881979435f18a4f122c15\",\"type\":\"message\",\"status\":\"in_progress\",\"content\":[],\"role\":\"assistant\"},\"output_index\":0,\"sequence_number\":2}", + "event: response.content_part.added\ndata: {\"type\":\"response.content_part.added\",\"content_index\":0,\"item_id\":\"msg_0d2b14e39122d1ad016a101017cac881979435f18a4f122c15\",\"output_index\":0,\"part\":{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"\"},\"sequence_number\":3}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"##\",\"item_id\":\"msg_0d2b14e39122d1ad016a101017cac881979435f18a4f122c15\",\"logprobs\":[],\"obfuscation\":\"l2j9wXUI75mlL0\",\"output_index\":0,\"sequence_number\":4}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" Original\",\"item_id\":\"msg_0d2b14e39122d1ad016a101017cac881979435f18a4f122c15\",\"logprobs\":[],\"obfuscation\":\"9GPpYWG\",\"output_index\":0,\"sequence_number\":5}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" Request\",\"item_id\":\"msg_0d2b14e39122d1ad016a101017cac881979435f18a4f122c15\",\"logprobs\":[],\"obfuscation\":\"Vkbxcebp\",\"output_index\":0,\"sequence_number\":6}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"\\n\",\"item_id\":\"msg_0d2b14e39122d1ad016a101017cac881979435f18a4f122c15\",\"logprobs\":[],\"obfuscation\":\"Vsipk4ZEN8K6Ept\",\"output_index\":0,\"sequence_number\":7}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"The\",\"item_id\":\"msg_0d2b14e39122d1ad016a101017cac881979435f18a4f122c15\",\"logprobs\":[],\"obfuscation\":\"E1tFh9aB6fNjV\",\"output_index\":0,\"sequence_number\":8}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" user\",\"item_id\":\"msg_0d2b14e39122d1ad016a101017cac881979435f18a4f122c15\",\"logprobs\":[],\"obfuscation\":\"F5YqKiy40oA\",\"output_index\":0,\"sequence_number\":9}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" asked\",\"item_id\":\"msg_0d2b14e39122d1ad016a101017cac881979435f18a4f122c15\",\"logprobs\":[],\"obfuscation\":\"j3cZjf1sV1\",\"output_index\":0,\"sequence_number\":10}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" the\",\"item_id\":\"msg_0d2b14e39122d1ad016a101017cac881979435f18a4f122c15\",\"logprobs\":[],\"obfuscation\":\"3MOMaNRJmo90\",\"output_index\":0,\"sequence_number\":11}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" assistant\",\"item_id\":\"msg_0d2b14e39122d1ad016a101017cac881979435f18a4f122c15\",\"logprobs\":[],\"obfuscation\":\"xg2YFw\",\"output_index\":0,\"sequence_number\":12}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" to\",\"item_id\":\"msg_0d2b14e39122d1ad016a101017cac881979435f18a4f122c15\",\"logprobs\":[],\"obfuscation\":\"eHeTmYHXADpAt\",\"output_index\":0,\"sequence_number\":13}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" complete\",\"item_id\":\"msg_0d2b14e39122d1ad016a101017cac881979435f18a4f122c15\",\"logprobs\":[],\"obfuscation\":\"bPjj5Hs\",\"output_index\":0,\"sequence_number\":14}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" a\",\"item_id\":\"msg_0d2b14e39122d1ad016a101017cac881979435f18a4f122c15\",\"logprobs\":[],\"obfuscation\":\"0MdoSGeYerfhME\",\"output_index\":0,\"sequence_number\":15}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" specific\",\"item_id\":\"msg_0d2b14e39122d1ad016a101017cac881979435f18a4f122c15\",\"logprobs\":[],\"obfuscation\":\"If4tz8p\",\"output_index\":0,\"sequence_number\":16}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" instrument\",\"item_id\":\"msg_0d2b14e39122d1ad016a101017cac881979435f18a4f122c15\",\"logprobs\":[],\"obfuscation\":\"aI0Wd\",\"output_index\":0,\"sequence_number\":17}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\"ed\",\"item_id\":\"msg_0d2b14e39122d1ad016a101017cac881979435f18a4f122c15\",\"logprobs\":[],\"obfuscation\":\"IRb0EgycyGxKxs\",\"output_index\":0,\"sequence_number\":18}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" research\",\"item_id\":\"msg_0d2b14e39122d1ad016a101017cac881979435f18a4f122c15\",\"logprobs\":[],\"obfuscation\":\"m9TwC2x\",\"output_index\":0,\"sequence_number\":19}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" flow\",\"item_id\":\"msg_0d2b14e39122d1ad016a101017cac881979435f18a4f122c15\",\"logprobs\":[],\"obfuscation\":\"Aomp0L5TyGx\",\"output_index\":0,\"sequence_number\":20}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" involving\",\"item_id\":\"msg_0d2b14e39122d1ad016a101017cac881979435f18a4f122c15\",\"logprobs\":[],\"obfuscation\":\"hyCqCo\",\"output_index\":0,\"sequence_number\":21}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" three\",\"item_id\":\"msg_0d2b14e39122d1ad016a101017cac881979435f18a4f122c15\",\"logprobs\":[],\"obfuscation\":\"Eyr5ZXtJbu\",\"output_index\":0,\"sequence_number\":22}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" steps\",\"item_id\":\"msg_0d2b14e39122d1ad016a101017cac881979435f18a4f122c15\",\"logprobs\":[],\"obfuscation\":\"o5q5KG9DTO\",\"output_index\":0,\"sequence_number\":23}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\":\",\"item_id\":\"msg_0d2b14e39122d1ad016a101017cac881979435f18a4f122c15\",\"logprobs\":[],\"obfuscation\":\"b9SEOrMFY76p0K4\",\"output_index\":0,\"sequence_number\":24}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" calling\",\"item_id\":\"msg_0d2b14e39122d1ad016a101017cac881979435f18a4f122c15\",\"logprobs\":[],\"obfuscation\":\"hnq433sU\",\"output_index\":0,\"sequence_number\":25}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" a\",\"item_id\":\"msg_0d2b14e39122d1ad016a101017cac881979435f18a4f122c15\",\"logprobs\":[],\"obfuscation\":\"wZsQBilARIa3uM\",\"output_index\":0,\"sequence_number\":26}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" lookup\",\"item_id\":\"msg_0d2b14e39122d1ad016a101017cac881979435f18a4f122c15\",\"logprobs\":[],\"obfuscation\":\"RmL7qsS0P\",\"output_index\":0,\"sequence_number\":27}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" tool\",\"item_id\":\"msg_0d2b14e39122d1ad016a101017cac881979435f18a4f122c15\",\"logprobs\":[],\"obfuscation\":\"Tt8WJkAFufP\",\"output_index\":0,\"sequence_number\":28}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\",\",\"item_id\":\"msg_0d2b14e39122d1ad016a101017cac881979435f18a4f122c15\",\"logprobs\":[],\"obfuscation\":\"S7xI9J0wDFseRpl\",\"output_index\":0,\"sequence_number\":29}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" performing\",\"item_id\":\"msg_0d2b14e39122d1ad016a101017cac881979435f18a4f122c15\",\"logprobs\":[],\"obfuscation\":\"0jZMr\",\"output_index\":0,\"sequence_number\":30}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" a\",\"item_id\":\"msg_0d2b14e39122d1ad016a101017cac881979435f18a4f122c15\",\"logprobs\":[],\"obfuscation\":\"Z8tyWvoyEOJHEH\",\"output_index\":0,\"sequence_number\":31}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" web\",\"item_id\":\"msg_0d2b14e39122d1ad016a101017cac881979435f18a4f122c15\",\"logprobs\":[],\"obfuscation\":\"4DarXUesPl3B\",\"output_index\":0,\"sequence_number\":32}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" search\",\"item_id\":\"msg_0d2b14e39122d1ad016a101017cac881979435f18a4f122c15\",\"logprobs\":[],\"obfuscation\":\"ucA8HbYy6\",\"output_index\":0,\"sequence_number\":33}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" using\",\"item_id\":\"msg_0d2b14e39122d1ad016a101017cac881979435f18a4f122c15\",\"logprobs\":[],\"obfuscation\":\"3Bd45YIJg9\",\"output_index\":0,\"sequence_number\":34}", + "event: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"content_index\":0,\"delta\":\" the\",\"item_id\":\"msg_0d2b14e39122d1ad016a101017cac881979435f18a4f122c15\",\"logprobs\":[],\"obfuscation\":\"BhaEain94nJJ\",\"output_index\":0,\"sequence_number\":35}", + "event: response.output_text.done\ndata: {\"type\":\"response.output_text.done\",\"content_index\":0,\"item_id\":\"msg_0d2b14e39122d1ad016a101017cac881979435f18a4f122c15\",\"logprobs\":[],\"output_index\":0,\"sequence_number\":36,\"text\":\"## Original Request\\nThe user asked the assistant to complete a specific instrumented research flow involving three steps: calling a lookup tool, performing a web search using the\"}", + "event: response.content_part.done\ndata: {\"type\":\"response.content_part.done\",\"content_index\":0,\"item_id\":\"msg_0d2b14e39122d1ad016a101017cac881979435f18a4f122c15\",\"output_index\":0,\"part\":{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"## Original Request\\nThe user asked the assistant to complete a specific instrumented research flow involving three steps: calling a lookup tool, performing a web search using the\"},\"sequence_number\":37}", + "event: response.output_item.done\ndata: {\"type\":\"response.output_item.done\",\"item\":{\"id\":\"msg_0d2b14e39122d1ad016a101017cac881979435f18a4f122c15\",\"type\":\"message\",\"status\":\"incomplete\",\"content\":[{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"## Original Request\\nThe user asked the assistant to complete a specific instrumented research flow involving three steps: calling a lookup tool, performing a web search using the\"}],\"role\":\"assistant\"},\"output_index\":0,\"sequence_number\":38}", + "event: response.incomplete\ndata: {\"type\":\"response.incomplete\",\"response\":{\"id\":\"resp_0d2b14e39122d1ad016a10101753648197a50d4b2b8228ecfb\",\"object\":\"response\",\"created_at\":1779437591,\"status\":\"incomplete\",\"background\":false,\"completed_at\":null,\"error\":null,\"frequency_penalty\":0,\"incomplete_details\":{\"reason\":\"max_output_tokens\"},\"instructions\":null,\"max_output_tokens\":32,\"max_tool_calls\":null,\"model\":\"gpt-4o-mini-2024-07-18\",\"moderation\":null,\"output\":[{\"id\":\"msg_0d2b14e39122d1ad016a101017cac881979435f18a4f122c15\",\"type\":\"message\",\"status\":\"incomplete\",\"content\":[{\"type\":\"output_text\",\"annotations\":[],\"logprobs\":[],\"text\":\"## Original Request\\nThe user asked the assistant to complete a specific instrumented research flow involving three steps: calling a lookup tool, performing a web search using the\"}],\"role\":\"assistant\"}],\"parallel_tool_calls\":true,\"presence_penalty\":0,\"previous_response_id\":null,\"prompt_cache_key\":null,\"prompt_cache_retention\":\"in_memory\",\"reasoning\":{\"effort\":null,\"summary\":null},\"safety_identifier\":null,\"service_tier\":\"default\",\"store\":false,\"temperature\":1,\"text\":{\"format\":{\"type\":\"text\"},\"verbosity\":\"medium\"},\"tool_choice\":\"auto\",\"tools\":[],\"top_logprobs\":0,\"top_p\":1,\"truncation\":\"disabled\",\"usage\":{\"input_tokens\":703,\"input_tokens_details\":{\"cached_tokens\":0},\"output_tokens\":32,\"output_tokens_details\":{\"reasoning_tokens\":0},\"total_tokens\":735},\"user\":null,\"metadata\":{}},\"sequence_number\":39}" ], "kind": "sse" }, @@ -2319,12 +2466,12 @@ "access-control-expose-headers": "X-Request-ID, CF-Ray, CF-Ray", "alt-svc": "h3=\":443\"; ma=86400", "cf-cache-status": "DYNAMIC", - "cf-ray": "9ff1a3548f88c2e1-VIE", + "cf-ray": "9ffa5c311b2bc31f-VIE", "connection": "keep-alive", "content-type": "text/event-stream; charset=utf-8", - "date": "Thu, 21 May 2026 06:48:53 GMT", + "date": "Fri, 22 May 2026 08:13:11 GMT", "openai-organization": "braintrust-data", - "openai-processing-ms": "184", + "openai-processing-ms": "96", "openai-project": "proj_vsCSXafhhByzWOThMrJcZiw9", "openai-version": "2020-10-01", "server": "cloudflare", @@ -2332,7 +2479,7 @@ "strict-transport-security": "max-age=31536000; includeSubDomains; preload", "transfer-encoding": "chunked", "x-content-type-options": "nosniff", - "x-request-id": "req_32645668215e477d8c3d40610baa18b7" + "x-request-id": "req_1fc6894099af434791545a929ffa7b92" }, "status": 200, "statusText": "OK" diff --git a/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-auto-hook.span-tree.json b/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-auto-hook.span-tree.json index 6ecd8cb36..08670e291 100644 --- a/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-auto-hook.span-tree.json +++ b/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-auto-hook.span-tree.json @@ -11,6 +11,41 @@ "name": "flue.session.prompt", "type": "task", "children": [ + { + "name": "anthropic.messages.create", + "type": "llm", + "children": [], + "input": [ + { + "content": [ + { + "cache_control": { + "type": "ephemeral" + }, + "text": "Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "cache_control": { + "type": "ephemeral" + }, + "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /e2e/scenarios/flue-instrumentation/\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + "type": "text" + } + ], + "role": "system" + } + ], + "metadata": { + "model": "claude-sonnet-4-5-20250929", + "provider": "anthropic" + } + }, { "name": "flue.turn", "type": "llm", @@ -20,8 +55,8 @@ "finish_reason": "toolUse", "index": 0, "message": { - "content": "I'll complete this instrumented research flow step by step. Starting with Step 1:", - "reasoning": "The user wants me to complete a specific instrumented research flow with three steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id to call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url to call summarize_source\n4. Reply with exactly \"PROMPT_DONE\" after summarize_source returns\n\nThe user emphasizes calling exactly one tool per turn and waiting for each result. Let me start with step 1.", + "content": "I'll complete this instrumented research flow step by step. Starting with step 1:", + "reasoning": "The user wants me to complete a specific instrumented research flow with these steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url and call summarize_source\n4. After summarize_source returns, reply with exactly \"PROMPT_DONE\" and no other text\n\nThe user emphasizes calling exactly one tool per turn and waiting for each result. Let me start with step 1.", "role": "assistant", "tool_calls": [ { @@ -44,13 +79,13 @@ "provider": "flue" }, "metrics": { - "completion_tokens": 199, + "completion_tokens": 208, "duration_ms": 0, - "estimated_cost": 0.0036696000000000003, + "estimated_cost": 0.0038052, "prompt_cache_creation_tokens": 0, - "prompt_cached_tokens": 2182, + "prompt_cached_tokens": 2184, "prompt_tokens": 10, - "tokens": 2391 + "tokens": 2402 } }, { @@ -80,6 +115,74 @@ "duration_ms": 0 } }, + { + "name": "anthropic.messages.create", + "type": "llm", + "children": [], + "input": [ + { + "content": [ + { + "text": "Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "signature": "EtYFCm4IDRgCKkC/lJUT/EhYE72Jr10vREWOZ4vwSSugL9RsNrhJg9wjli7iCBt2/hEandW2KZpRqluVbV3ehHY/n0Mge6VmWF1cMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMHcfwfYOEmmJZGyBBGgyYm8sT/W36vQdF0dQiMFC5CVRWmqhR2r90pB0R8Wjbq0ITTIN0abxhOezE1NDsrj6CM4/DXLaOsJp4TD5DNCqVBEgEEzFdeaRrRB0CeXdlWoo+wf7yR9EMOVhLmyRf3nItrqN/cb30rpaexhXDm0/Hj3WxQH+o0K73Oyr6qtiDVe9xGNt6v5DrUz31HcE+GJ0Yw8ThoufXvqNyFQV3lLhpZExUDX6hwlmKvaRpj5YH+q5TTx3jAIgzD+zGkgUS0vC7Muftm2VZcuI/2wVsbtWo6hYdvbbdxr+8FzJsCOWc3ptVaUBimC5//HRSNBXFJ9zlkt6l7YxnUeKWiesSdE6h1EJ08Rp4OrAP+oaYWU4v6IODdnJmsqGKbN//i6gGCnAHBBAZr/pnnmEyUOsBGc6ARMOtcwjFIN3/B1YkJi8r8QbbtGHJHfH/v102MSZG8UJk2RXxt1fTQUWNbp0DjA7gUn00H3dnmSAQyqFjKLIFncnhiH5PSSgdvErNB7y/2UBk2CY2i4dpevr+7uvHZDLPjSBcovpvgJ4ihdUM9S080xCm1NNkjs+QP+AQAh20t33t7EN6aZS0+CZcfJxf1QV6mGIkL7BKAPeIXjD8TKuW/at4pqwrvvesI2cZY5RDjC7v7tz/+tqiEkob1s8J3jx2dbIgPBFOR5PFFwPby0H9Guv4ZB63YAlP3sXX+F5fC6fQifQeJK8fuWK+FKe3v+gK/hZcuBuU/Jfhrst4CsEWeaBhmPktZOHu5f85KZ/layh4Pp39yxR0FiHY5eXibsTh2SfDN3K6GAE=", + "thinking": "The user wants me to complete a specific instrumented research flow with these steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url and call summarize_source\n4. After summarize_source returns, reply with exactly \"PROMPT_DONE\" and no other text\n\nThe user emphasizes calling exactly one tool per turn and waiting for each result. Let me start with step 1.", + "type": "thinking" + }, + { + "text": "I'll complete this instrumented research flow step by step. Starting with step 1:", + "type": "text" + }, + { + "id": "", + "input": { + "query": "flue instrumentation" + }, + "name": "lookup", + "type": "tool_use" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "cache_control": { + "type": "ephemeral" + }, + "content": "{\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}", + "is_error": false, + "tool_use_id": "toolu_01QHXkUBddKx6pexY4WSjMR1", + "type": "tool_result" + } + ], + "role": "user" + }, + { + "content": [ + { + "cache_control": { + "type": "ephemeral" + }, + "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /e2e/scenarios/flue-instrumentation/\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + "type": "text" + } + ], + "role": "system" + } + ], + "metadata": { + "model": "claude-sonnet-4-5-20250929", + "provider": "anthropic" + } + }, { "name": "flue.turn", "type": "llm", @@ -89,8 +192,8 @@ "finish_reason": "toolUse", "index": 0, "message": { - "content": "Now proceeding to Step 2:", - "reasoning": "Good, I got the lookup result with id \"flue-session-2026\". Now I'll proceed to step 2 and use this id as the lookupId parameter in the web_search call with the specified query.", + "content": "Now proceeding to step 2:", + "reasoning": "Good, I got the lookup result with id \"flue-session-2026\". Now I need to proceed to step 2: call web_search with this lookupId and the query \"Braintrust Flue reasoning stream instrumentation\".", "role": "assistant", "tool_calls": [ { @@ -113,13 +216,13 @@ "provider": "flue" }, "metrics": { - "completion_tokens": 153, + "completion_tokens": 158, "duration_ms": 0, - "estimated_cost": 0.00388485, - "prompt_cache_creation_tokens": 239, - "prompt_cached_tokens": 2182, + "estimated_cost": 0.0039942, + "prompt_cache_creation_tokens": 248, + "prompt_cached_tokens": 2184, "prompt_tokens": 13, - "tokens": 2587 + "tokens": 2603 } }, { @@ -150,6 +253,108 @@ "duration_ms": 0 } }, + { + "name": "anthropic.messages.create", + "type": "llm", + "children": [], + "input": [ + { + "content": [ + { + "text": "Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "signature": "EtYFCm4IDRgCKkC/lJUT/EhYE72Jr10vREWOZ4vwSSugL9RsNrhJg9wjli7iCBt2/hEandW2KZpRqluVbV3ehHY/n0Mge6VmWF1cMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMHcfwfYOEmmJZGyBBGgyYm8sT/W36vQdF0dQiMFC5CVRWmqhR2r90pB0R8Wjbq0ITTIN0abxhOezE1NDsrj6CM4/DXLaOsJp4TD5DNCqVBEgEEzFdeaRrRB0CeXdlWoo+wf7yR9EMOVhLmyRf3nItrqN/cb30rpaexhXDm0/Hj3WxQH+o0K73Oyr6qtiDVe9xGNt6v5DrUz31HcE+GJ0Yw8ThoufXvqNyFQV3lLhpZExUDX6hwlmKvaRpj5YH+q5TTx3jAIgzD+zGkgUS0vC7Muftm2VZcuI/2wVsbtWo6hYdvbbdxr+8FzJsCOWc3ptVaUBimC5//HRSNBXFJ9zlkt6l7YxnUeKWiesSdE6h1EJ08Rp4OrAP+oaYWU4v6IODdnJmsqGKbN//i6gGCnAHBBAZr/pnnmEyUOsBGc6ARMOtcwjFIN3/B1YkJi8r8QbbtGHJHfH/v102MSZG8UJk2RXxt1fTQUWNbp0DjA7gUn00H3dnmSAQyqFjKLIFncnhiH5PSSgdvErNB7y/2UBk2CY2i4dpevr+7uvHZDLPjSBcovpvgJ4ihdUM9S080xCm1NNkjs+QP+AQAh20t33t7EN6aZS0+CZcfJxf1QV6mGIkL7BKAPeIXjD8TKuW/at4pqwrvvesI2cZY5RDjC7v7tz/+tqiEkob1s8J3jx2dbIgPBFOR5PFFwPby0H9Guv4ZB63YAlP3sXX+F5fC6fQifQeJK8fuWK+FKe3v+gK/hZcuBuU/Jfhrst4CsEWeaBhmPktZOHu5f85KZ/layh4Pp39yxR0FiHY5eXibsTh2SfDN3K6GAE=", + "thinking": "The user wants me to complete a specific instrumented research flow with these steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url and call summarize_source\n4. After summarize_source returns, reply with exactly \"PROMPT_DONE\" and no other text\n\nThe user emphasizes calling exactly one tool per turn and waiting for each result. Let me start with step 1.", + "type": "thinking" + }, + { + "text": "I'll complete this instrumented research flow step by step. Starting with step 1:", + "type": "text" + }, + { + "id": "", + "input": { + "query": "flue instrumentation" + }, + "name": "lookup", + "type": "tool_use" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "content": "{\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}", + "is_error": false, + "tool_use_id": "toolu_01QHXkUBddKx6pexY4WSjMR1", + "type": "tool_result" + } + ], + "role": "user" + }, + { + "content": [ + { + "signature": "EpEDCm4IDRgCKkAMahve1kB1j4njp1ZSzO8eCK4bb5Ex7MB6tjdoOXfuUDRfkBqvIGdwVly8GiA8GGYC7Y/RVfREXF6A6OXHTwFyMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMI25UM/xFQ9Bh625NGgyP2lwn3SKJlMxLUwciMH3VyS+uXCYaj8hlEdHVLz3HDLA5DCge72pzSyECwbUqqdxyZgtWjWYo/v0qA6XIsirQAQUbwyS/JWdGjeoTVbN2wMlsvu6j2cZmYMhk2HDKvmRIKpFTX5Ha82HBMwuM+f/7faDeQM5ldk8a5Tnm6iWFUj5jOoNqCYa+lBzhWor1vuZ5ieA569nGcMa0z1QmEP8WC3zNkI+kDazdS9FcuJP8KltHVfNr/wf/5AgAYFMt8fIaolvtJmN7uZ0yJKVfuJ58yx0nlQyEkxK8siXz7in2ulTuflohdD37ZErfxQNM3iYlCEfBOfa6kuJhwOwQ+HWJA1LXmUxzR/9AHRq0f3euNXkYAQ==", + "thinking": "Good, I got the lookup result with id \"flue-session-2026\". Now I need to proceed to step 2: call web_search with this lookupId and the query \"Braintrust Flue reasoning stream instrumentation\".", + "type": "thinking" + }, + { + "text": "Now proceeding to step 2:", + "type": "text" + }, + { + "id": "", + "input": { + "lookupId": "flue-session-2026", + "query": "Braintrust Flue reasoning stream instrumentation" + }, + "name": "web_search", + "type": "tool_use" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "cache_control": { + "type": "ephemeral" + }, + "content": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\",\"results\":[{\"title\":\"Flue reasoning stream instrumentation\",\"url\":\"https://example.test/flue/reasoning-streams\"}]}", + "is_error": false, + "tool_use_id": "toolu_01CvT1mSWwETua7LWwSQiyq6", + "type": "tool_result" + } + ], + "role": "user" + }, + { + "content": [ + { + "cache_control": { + "type": "ephemeral" + }, + "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /e2e/scenarios/flue-instrumentation/\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + "type": "text" + } + ], + "role": "system" + } + ], + "metadata": { + "model": "claude-sonnet-4-5-20250929", + "provider": "anthropic" + } + }, { "name": "flue.turn", "type": "llm", @@ -159,8 +364,8 @@ "finish_reason": "toolUse", "index": 0, "message": { - "content": "Now proceeding to Step 3:", - "reasoning": "Perfect! I got the web_search results. There's one result with the URL \"https://example.test/flue/reasoning-streams\". Now I need to proceed to step 3 and call summarize_source with this URL.", + "content": "Now proceeding to step 3:", + "reasoning": "Perfect! I got the web_search results. There's one result with the URL \"https://example.test/flue/reasoning-streams\". Now I need to proceed to step 3: call summarize_source with this URL.", "role": "assistant", "tool_calls": [ { @@ -183,13 +388,13 @@ "provider": "flue" }, "metrics": { - "completion_tokens": 133, + "completion_tokens": 132, "duration_ms": 0, - "estimated_cost": 0.0036190500000000004, - "prompt_cache_creation_tokens": 229, - "prompt_cached_tokens": 2421, + "estimated_cost": 0.0036261, + "prompt_cache_creation_tokens": 234, + "prompt_cached_tokens": 2432, "prompt_tokens": 13, - "tokens": 2796 + "tokens": 2811 } }, { @@ -219,6 +424,141 @@ "duration_ms": 0 } }, + { + "name": "anthropic.messages.create", + "type": "llm", + "children": [], + "input": [ + { + "content": [ + { + "text": "Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "signature": "EtYFCm4IDRgCKkC/lJUT/EhYE72Jr10vREWOZ4vwSSugL9RsNrhJg9wjli7iCBt2/hEandW2KZpRqluVbV3ehHY/n0Mge6VmWF1cMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMHcfwfYOEmmJZGyBBGgyYm8sT/W36vQdF0dQiMFC5CVRWmqhR2r90pB0R8Wjbq0ITTIN0abxhOezE1NDsrj6CM4/DXLaOsJp4TD5DNCqVBEgEEzFdeaRrRB0CeXdlWoo+wf7yR9EMOVhLmyRf3nItrqN/cb30rpaexhXDm0/Hj3WxQH+o0K73Oyr6qtiDVe9xGNt6v5DrUz31HcE+GJ0Yw8ThoufXvqNyFQV3lLhpZExUDX6hwlmKvaRpj5YH+q5TTx3jAIgzD+zGkgUS0vC7Muftm2VZcuI/2wVsbtWo6hYdvbbdxr+8FzJsCOWc3ptVaUBimC5//HRSNBXFJ9zlkt6l7YxnUeKWiesSdE6h1EJ08Rp4OrAP+oaYWU4v6IODdnJmsqGKbN//i6gGCnAHBBAZr/pnnmEyUOsBGc6ARMOtcwjFIN3/B1YkJi8r8QbbtGHJHfH/v102MSZG8UJk2RXxt1fTQUWNbp0DjA7gUn00H3dnmSAQyqFjKLIFncnhiH5PSSgdvErNB7y/2UBk2CY2i4dpevr+7uvHZDLPjSBcovpvgJ4ihdUM9S080xCm1NNkjs+QP+AQAh20t33t7EN6aZS0+CZcfJxf1QV6mGIkL7BKAPeIXjD8TKuW/at4pqwrvvesI2cZY5RDjC7v7tz/+tqiEkob1s8J3jx2dbIgPBFOR5PFFwPby0H9Guv4ZB63YAlP3sXX+F5fC6fQifQeJK8fuWK+FKe3v+gK/hZcuBuU/Jfhrst4CsEWeaBhmPktZOHu5f85KZ/layh4Pp39yxR0FiHY5eXibsTh2SfDN3K6GAE=", + "thinking": "The user wants me to complete a specific instrumented research flow with these steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url and call summarize_source\n4. After summarize_source returns, reply with exactly \"PROMPT_DONE\" and no other text\n\nThe user emphasizes calling exactly one tool per turn and waiting for each result. Let me start with step 1.", + "type": "thinking" + }, + { + "text": "I'll complete this instrumented research flow step by step. Starting with step 1:", + "type": "text" + }, + { + "id": "", + "input": { + "query": "flue instrumentation" + }, + "name": "lookup", + "type": "tool_use" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "content": "{\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}", + "is_error": false, + "tool_use_id": "toolu_01QHXkUBddKx6pexY4WSjMR1", + "type": "tool_result" + } + ], + "role": "user" + }, + { + "content": [ + { + "signature": "EpEDCm4IDRgCKkAMahve1kB1j4njp1ZSzO8eCK4bb5Ex7MB6tjdoOXfuUDRfkBqvIGdwVly8GiA8GGYC7Y/RVfREXF6A6OXHTwFyMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMI25UM/xFQ9Bh625NGgyP2lwn3SKJlMxLUwciMH3VyS+uXCYaj8hlEdHVLz3HDLA5DCge72pzSyECwbUqqdxyZgtWjWYo/v0qA6XIsirQAQUbwyS/JWdGjeoTVbN2wMlsvu6j2cZmYMhk2HDKvmRIKpFTX5Ha82HBMwuM+f/7faDeQM5ldk8a5Tnm6iWFUj5jOoNqCYa+lBzhWor1vuZ5ieA569nGcMa0z1QmEP8WC3zNkI+kDazdS9FcuJP8KltHVfNr/wf/5AgAYFMt8fIaolvtJmN7uZ0yJKVfuJ58yx0nlQyEkxK8siXz7in2ulTuflohdD37ZErfxQNM3iYlCEfBOfa6kuJhwOwQ+HWJA1LXmUxzR/9AHRq0f3euNXkYAQ==", + "thinking": "Good, I got the lookup result with id \"flue-session-2026\". Now I need to proceed to step 2: call web_search with this lookupId and the query \"Braintrust Flue reasoning stream instrumentation\".", + "type": "thinking" + }, + { + "text": "Now proceeding to step 2:", + "type": "text" + }, + { + "id": "", + "input": { + "lookupId": "flue-session-2026", + "query": "Braintrust Flue reasoning stream instrumentation" + }, + "name": "web_search", + "type": "tool_use" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "content": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\",\"results\":[{\"title\":\"Flue reasoning stream instrumentation\",\"url\":\"https://example.test/flue/reasoning-streams\"}]}", + "is_error": false, + "tool_use_id": "toolu_01CvT1mSWwETua7LWwSQiyq6", + "type": "tool_result" + } + ], + "role": "user" + }, + { + "content": [ + { + "signature": "EowDCm4IDRgCKkCpqmoUHjbaZYvB4bWm+hVDlxgU/iOCEn0v3xAMT4QsjKM7cIZMOWD2eEF8ENjGq0ttAvO8ZNI9YpiASikG2gnNMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMI5+VQnffadMSNsXEGgy1YAi10m6jJ39wq2UiMAUy8rg67GdkT4VUKix3ULTWnPfKucap7VLRPGDqK7ZhF0nDl2pcYGshMviSbzOjuyrLAXh3IPAAc3rvDuYAAHaWed6JE7/4gg/gzWhfVeAb0qXzXoiIHh8Z9KyHDfDDfpesr4TzmJHT/T8mhem3UfZc87ZLzFom8Vi+76Y2eVWcoI/EyPuyj+KVxU5kPh030LYWxUeSTUViRu9NAd+Wzz/5ZAgD+TiEmCnpNMI3eGqOiBPtwK7y/JIvxZRWvsJ1ghXNaEVShN3h8OUk9zmzIhBuUujWVZtc5wuM28726mOqMLwKckegl+q2vNrR+U+AqbMSYWUVlWLKZvd1LXiZGAE=", + "thinking": "Perfect! I got the web_search results. There's one result with the URL \"https://example.test/flue/reasoning-streams\". Now I need to proceed to step 3: call summarize_source with this URL.", + "type": "thinking" + }, + { + "text": "Now proceeding to step 3:", + "type": "text" + }, + { + "id": "", + "input": { + "url": "https://example.test/flue/reasoning-streams" + }, + "name": "summarize_source", + "type": "tool_use" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "cache_control": { + "type": "ephemeral" + }, + "content": "{\"summary\":\"Flue emits reasoning, tool execution, and LLM turn events separately.\",\"url\":\"https://example.test/flue/reasoning-streams\"}", + "is_error": false, + "tool_use_id": "toolu_01NHkkJuQNXyRuWk58FCecye", + "type": "tool_result" + } + ], + "role": "user" + }, + { + "content": [ + { + "cache_control": { + "type": "ephemeral" + }, + "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /e2e/scenarios/flue-instrumentation/\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + "type": "text" + } + ], + "role": "system" + } + ], + "metadata": { + "model": "claude-sonnet-4-5-20250929", + "provider": "anthropic" + } + }, { "name": "flue.turn", "type": "llm", @@ -229,7 +569,7 @@ "index": 0, "message": { "content": "PROMPT_DONE", - "reasoning": "Perfect! The summarize_source has returned. According to the instructions, I should now reply with exactly \"PROMPT_DONE\" and no other text.", + "reasoning": "The summarize_source has returned successfully. According to the instructions, I should now reply with exactly \"PROMPT_DONE\" and no other text.", "role": "assistant" } } @@ -242,13 +582,13 @@ "provider": "flue" }, "metrics": { - "completion_tokens": 49, + "completion_tokens": 48, "duration_ms": 0, - "estimated_cost": 0.00227775, - "prompt_cache_creation_tokens": 189, - "prompt_cached_tokens": 2650, + "estimated_cost": 0.0022638, + "prompt_cache_creation_tokens": 188, + "prompt_cached_tokens": 2666, "prompt_tokens": 13, - "tokens": 2901 + "tokens": 2915 } } ], @@ -264,13 +604,13 @@ "provider": "flue" }, "metrics": { - "completion_tokens": 534, + "completion_tokens": 546, "duration_ms": 0, - "estimated_cost": 0.013451250000000001, - "prompt_cache_creation_tokens": 657, - "prompt_cached_tokens": 9435, + "estimated_cost": 0.0136893, + "prompt_cache_creation_tokens": 670, + "prompt_cached_tokens": 9466, "prompt_tokens": 49, - "tokens": 10675 + "tokens": 10731 } } ], @@ -285,6 +625,41 @@ "name": "flue.session.skill", "type": "task", "children": [ + { + "name": "anthropic.messages.create", + "type": "llm", + "children": [], + "input": [ + { + "content": [ + { + "cache_control": { + "type": "ephemeral" + }, + "text": "Run the skill named \"e2e-flue-skill\".\n\nArguments:\n{\n \"marker\": \"SKILL_DONE\"\n}", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "cache_control": { + "type": "ephemeral" + }, + "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /e2e/scenarios/flue-instrumentation/\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts\n\n\nNever call the task tool. Do not delegate e2e-flue-skill to another session. If you need the skill body, read .agents/skills/e2e-flue-skill/SKILL.md yourself with the read tool. Return the marker from the Arguments object exactly, with no other text.\n", + "type": "text" + } + ], + "role": "system" + } + ], + "metadata": { + "model": "claude-sonnet-4-5-20250929", + "provider": "anthropic" + } + }, { "name": "flue.turn", "type": "llm", @@ -294,7 +669,7 @@ "finish_reason": "toolUse", "index": 0, "message": { - "content": "I'll run the e2e-flue-skill by reading its instructions and following them.", + "content": "I'll read the skill file and execute it according to its instructions.", "role": "assistant", "tool_calls": [ { @@ -316,13 +691,13 @@ "provider": "flue" }, "metrics": { - "completion_tokens": 89, + "completion_tokens": 83, "duration_ms": 0, - "estimated_cost": 0.0018866999999999998, + "estimated_cost": 0.0017973, "prompt_cache_creation_tokens": 0, - "prompt_cached_tokens": 1809, + "prompt_cached_tokens": 1811, "prompt_tokens": 3, - "tokens": 1901 + "tokens": 1897 } }, { @@ -353,6 +728,69 @@ "duration_ms": 0 } }, + { + "name": "anthropic.messages.create", + "type": "llm", + "children": [], + "input": [ + { + "content": [ + { + "text": "Run the skill named \"e2e-flue-skill\".\n\nArguments:\n{\n \"marker\": \"SKILL_DONE\"\n}", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "text": "I'll read the skill file and execute it according to its instructions.", + "type": "text" + }, + { + "id": "", + "input": { + "path": ".agents/skills/e2e-flue-skill/SKILL.md" + }, + "name": "read", + "type": "tool_use" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "cache_control": { + "type": "ephemeral" + }, + "content": "---\nname: e2e-flue-skill\ndescription: Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n---\n\nReturn the marker from the provided args exactly once. Output no other text.\n", + "is_error": false, + "tool_use_id": "toolu_01HmmsNYZUC67GqVoKKLbfiQ", + "type": "tool_result" + } + ], + "role": "user" + }, + { + "content": [ + { + "cache_control": { + "type": "ephemeral" + }, + "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /e2e/scenarios/flue-instrumentation/\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts\n\n\nNever call the task tool. Do not delegate e2e-flue-skill to another session. If you need the skill body, read .agents/skills/e2e-flue-skill/SKILL.md yourself with the read tool. Return the marker from the Arguments object exactly, with no other text.\n", + "type": "text" + } + ], + "role": "system" + } + ], + "metadata": { + "model": "claude-sonnet-4-5-20250929", + "provider": "anthropic" + } + }, { "name": "flue.turn", "type": "llm", @@ -376,11 +814,11 @@ "metrics": { "completion_tokens": 8, "duration_ms": 0, - "estimated_cost": 0.0007266, - "prompt_cache_creation_tokens": 0, - "prompt_cached_tokens": 1962, + "estimated_cost": 0.0012325499999999998, + "prompt_cache_creation_tokens": 147, + "prompt_cached_tokens": 1811, "prompt_tokens": 6, - "tokens": 1976 + "tokens": 1972 } } ], @@ -402,13 +840,13 @@ "provider": "flue" }, "metrics": { - "completion_tokens": 97, + "completion_tokens": 91, "duration_ms": 0, - "estimated_cost": 0.0026133, - "prompt_cache_creation_tokens": 0, - "prompt_cached_tokens": 3771, + "estimated_cost": 0.0030298499999999997, + "prompt_cache_creation_tokens": 147, + "prompt_cached_tokens": 3622, "prompt_tokens": 9, - "tokens": 3877 + "tokens": 3869 } } ], @@ -426,46 +864,93 @@ { "name": "flue.task", "type": "task", - "children": [ - { - "name": "flue.turn", - "type": "llm", - "children": [], - "output": [ - { - "finish_reason": "stop", - "index": 0, - "message": { - "content": "TASK_DONE", - "role": "assistant" - } + "children": [], + "input": "Reply with exactly TASK_DONE and no other text.", + "output": "TASK_DONE", + "metadata": { + "flue.session": "task", + "provider": "flue" + }, + "metrics": { + "duration_ms": 0 + } + }, + { + "name": "openai.responses.create", + "type": "llm", + "children": [], + "input": [ + { + "content": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /e2e/scenarios/flue-instrumentation/\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + "role": "system" + }, + { + "content": [ + { + "text": "Reply with exactly TASK_DONE and no other text.", + "type": "input_text" + } + ], + "role": "user" + } + ], + "output": [ + { + "content": [ + { + "annotations": [], + "logprobs": [], + "text": "TASK_DONE", + "type": "output_text" } ], - "metadata": { - "flue.model": "gpt-4o-mini", - "flue.session": "task:task:", - "model": "gpt-4o-mini", - "provider": "flue" - }, - "metrics": { - "completion_tokens": 4, - "duration_ms": 0, - "estimated_cost": 0.00011789999999999999, - "prompt_cache_creation_tokens": 0, - "prompt_cached_tokens": 0, - "prompt_tokens": 770, - "tokens": 774 + "id": "", + "role": "assistant", + "status": "completed", + "type": "message" + } + ], + "metadata": { + "model": "gpt-4o-mini-2024-07-18", + "provider": "openai" + }, + "metrics": { + "completion_reasoning_tokens": 0, + "completion_tokens": 4, + "prompt_cached_tokens": 0, + "prompt_tokens": 772, + "time_to_first_token": 0, + "tokens": 776 + } + }, + { + "name": "flue.turn", + "type": "llm", + "children": [], + "output": [ + { + "finish_reason": "stop", + "index": 0, + "message": { + "content": "TASK_DONE", + "role": "assistant" } } ], - "input": "Reply with exactly TASK_DONE and no other text.", - "output": "TASK_DONE", "metadata": { - "flue.session": "task", + "flue.model": "gpt-4o-mini", + "flue.session": "task:task:", + "model": "gpt-4o-mini", "provider": "flue" }, "metrics": { - "duration_ms": 0 + "completion_tokens": 4, + "duration_ms": 0, + "estimated_cost": 0.0001182, + "prompt_cache_creation_tokens": 0, + "prompt_cached_tokens": 0, + "prompt_tokens": 772, + "tokens": 776 } } ], @@ -482,11 +967,11 @@ "metrics": { "completion_tokens": 4, "duration_ms": 0, - "estimated_cost": 0.00011789999999999999, + "estimated_cost": 0.0001182, "prompt_cache_creation_tokens": 0, "prompt_cached_tokens": 0, - "prompt_tokens": 770, - "tokens": 774 + "prompt_tokens": 772, + "tokens": 776 } } ], @@ -506,7 +991,7 @@ "type": "task", "children": [], "input": { - "estimatedTokens": 2901, + "estimatedTokens": 2915, "reason": "manual" }, "output": { @@ -527,6 +1012,33 @@ "prompt_tokens": 0, "tokens": 0 } + }, + { + "name": "openai.responses.create", + "type": "llm", + "children": [], + "input": [ + { + "content": "You are a context summarization assistant. Your task is to read a conversation between a user and an AI coding assistant, then produce a structured summary following the exact format specified.\n\nDo NOT continue the conversation. Do NOT respond to any questions in the conversation. ONLY output the structured summary.", + "role": "system" + }, + { + "content": [ + { + "text": "\n[User]: Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.\n\n[Assistant thinking]: The user wants me to complete a specific instrumented research flow with these steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url and call summarize_source\n4. After summarize_source returns, reply with exactly \"PROMPT_DONE\" and no other text\n\nThe user emphasizes calling exactly one tool per turn and waiting for each result. Let me start with step 1.\n\n[Assistant]: I'll complete this instrumented research flow step by step. Starting with step 1:\n\n[Assistant tool calls]: lookup(query=\"flue instrumentation\")\n\n[Tool result]: {\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}\n\n[Assistant thinking]: Good, I got the lookup result with id \"flue-session-2026\". Now I need to proceed to step 2: call web_search with this lookupId and the query \"Braintrust Flue reasoning stream instrumentation\".\n\n[Assistant]: Now proceeding to step 2:\n\n[Assistant tool calls]: web_search(lookupId=\"flue-session-2026\", query=\"Braintrust Flue reasoning stream instrumentation\")\n\n[Tool result]: {\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\",\"results\":[{\"title\":\"Flue reasoning stream instrumentation\",\"url\":\"https://example.test/flue/reasoning-streams\"}]}\n\n[Assistant thinking]: Perfect! I got the web_search results. There's one result with the URL \"https://example.test/flue/reasoning-streams\". Now I need to proceed to step 3: call summarize_source with this URL.\n\n[Assistant]: Now proceeding to step 3:\n\n[Assistant tool calls]: summarize_source(url=\"https://example.test/flue/reasoning-streams\")\n\n[Tool result]: {\"summary\":\"Flue emits reasoning, tool execution, and LLM turn events separately.\",\"url\":\"https://example.test/flue/reasoning-streams\"}\n\n\nThis is the PREFIX of a turn that was too large to keep. The SUFFIX (recent work) is retained.\n\nSummarize the prefix to provide context for the retained suffix:\n\n## Original Request\n[What did the user ask for in this turn?]\n\n## Early Progress\n- [Key decisions and work done in the prefix]\n\n## Context for Suffix\n- [Information needed to understand the retained recent work]\n\nBe concise. Focus on what's needed to understand the kept suffix.", + "type": "input_text" + } + ], + "role": "user" + } + ], + "metadata": { + "model": "gpt-4o-mini", + "provider": "openai" + }, + "metrics": { + "time_to_first_token": 0 + } } ], "metadata": { diff --git a/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-auto-hook.span-tree.txt b/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-auto-hook.span-tree.txt index 5a000aebd..995b14244 100644 --- a/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-auto-hook.span-tree.txt +++ b/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-auto-hook.span-tree.txt @@ -20,22 +20,53 @@ span_tree: │ "provider": "flue" │ } │ metrics: { - │ "completion_tokens": 534, + │ "completion_tokens": 546, │ "duration_ms": 0, - │ "estimated_cost": 0.013451250000000001, - │ "prompt_cache_creation_tokens": 657, - │ "prompt_cached_tokens": 9435, + │ "estimated_cost": 0.0136893, + │ "prompt_cache_creation_tokens": 670, + │ "prompt_cached_tokens": 9466, │ "prompt_tokens": 49, - │ "tokens": 10675 + │ "tokens": 10731 │ } + │ ├── anthropic.messages.create [llm] + │ │ input: [ + │ │ { + │ │ "content": [ + │ │ { + │ │ "cache_control": { + │ │ "type": "ephemeral" + │ │ }, + │ │ "text": "Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.", + │ │ "type": "text" + │ │ } + │ │ ], + │ │ "role": "user" + │ │ }, + │ │ { + │ │ "content": [ + │ │ { + │ │ "cache_control": { + │ │ "type": "ephemeral" + │ │ }, + │ │ "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /e2e/scenarios/flue-instrumentation/\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + │ │ "type": "text" + │ │ } + │ │ ], + │ │ "role": "system" + │ │ } + │ │ ] + │ │ metadata: { + │ │ "model": "claude-sonnet-4-5-20250929", + │ │ "provider": "anthropic" + │ │ } │ ├── flue.turn [llm] │ │ output: [ │ │ { │ │ "finish_reason": "toolUse", │ │ "index": 0, │ │ "message": { - │ │ "content": "I'll complete this instrumented research flow step by step. Starting with Step 1:", - │ │ "reasoning": "The user wants me to complete a specific instrumented research flow with three steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id to call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url to call summarize_source\n4. Reply with exactly \"PROMPT_DONE\" after summarize_source returns\n\nThe user emphasizes calling exactly one tool per turn and waiting for each result. Let me start with step 1.", + │ │ "content": "I'll complete this instrumented research flow step by step. Starting with step 1:", + │ │ "reasoning": "The user wants me to complete a specific instrumented research flow with these steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url and call summarize_source\n4. After summarize_source returns, reply with exactly \"PROMPT_DONE\" and no other text\n\nThe user emphasizes calling exactly one tool per turn and waiting for each result. Let me start with step 1.", │ │ "role": "assistant", │ │ "tool_calls": [ │ │ { @@ -58,13 +89,13 @@ span_tree: │ │ "provider": "flue" │ │ } │ │ metrics: { - │ │ "completion_tokens": 199, + │ │ "completion_tokens": 208, │ │ "duration_ms": 0, - │ │ "estimated_cost": 0.0036696000000000003, + │ │ "estimated_cost": 0.0038052, │ │ "prompt_cache_creation_tokens": 0, - │ │ "prompt_cached_tokens": 2182, + │ │ "prompt_cached_tokens": 2184, │ │ "prompt_tokens": 10, - │ │ "tokens": 2391 + │ │ "tokens": 2402 │ │ } │ ├── tool: lookup [tool] │ │ input: { @@ -89,14 +120,78 @@ span_tree: │ │ metrics: { │ │ "duration_ms": 0 │ │ } + │ ├── anthropic.messages.create [llm] + │ │ input: [ + │ │ { + │ │ "content": [ + │ │ { + │ │ "text": "Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.", + │ │ "type": "text" + │ │ } + │ │ ], + │ │ "role": "user" + │ │ }, + │ │ { + │ │ "content": [ + │ │ { + │ │ "signature": "EtYFCm4IDRgCKkC/lJUT/EhYE72Jr10vREWOZ4vwSSugL9RsNrhJg9wjli7iCBt2/hEandW2KZpRqluVbV3ehHY/n0Mge6VmWF1cMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMHcfwfYOEmmJZGyBBGgyYm8sT/W36vQdF0dQiMFC5CVRWmqhR2r90pB0R8Wjbq0ITTIN0abxhOezE1NDsrj6CM4/DXLaOsJp4TD5DNCqVBEgEEzFdeaRrRB0CeXdlWoo+wf7yR9EMOVhLmyRf3nItrqN/cb30rpaexhXDm0/Hj3WxQH+o0K73Oyr6qtiDVe9xGNt6v5DrUz31HcE+GJ0Yw8ThoufXvqNyFQV3lLhpZExUDX6hwlmKvaRpj5YH+q5TTx3jAIgzD+zGkgUS0vC7Muftm2VZcuI/2wVsbtWo6hYdvbbdxr+8FzJsCOWc3ptVaUBimC5//HRSNBXFJ9zlkt6l7YxnUeKWiesSdE6h1EJ08Rp4OrAP+oaYWU4v6IODdnJmsqGKbN//i6gGCnAHBBAZr/pnnmEyUOsBGc6ARMOtcwjFIN3/B1YkJi8r8QbbtGHJHfH/v102MSZG8UJk2RXxt1fTQUWNbp0DjA7gUn00H3dnmSAQyqFjKLIFncnhiH5PSSgdvErNB7y/2UBk2CY2i4dpevr+7uvHZDLPjSBcovpvgJ4ihdUM9S080xCm1NNkjs+QP+AQAh20t33t7EN6aZS0+CZcfJxf1QV6mGIkL7BKAPeIXjD8TKuW/at4pqwrvvesI2cZY5RDjC7v7tz/+tqiEkob1s8J3jx2dbIgPBFOR5PFFwPby0H9Guv4ZB63YAlP3sXX+F5fC6fQifQeJK8fuWK+FKe3v+gK/hZcuBuU/Jfhrst4CsEWeaBhmPktZOHu5f85KZ/layh4Pp39yxR0FiHY5eXibsTh2SfDN3K6GAE=", + │ │ "thinking": "The user wants me to complete a specific instrumented research flow with these steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url and call summarize_source\n4. After summarize_source returns, reply with exactly \"PROMPT_DONE\" and no other text\n\nThe user emphasizes calling exactly one tool per turn and waiting for each result. Let me start with step 1.", + │ │ "type": "thinking" + │ │ }, + │ │ { + │ │ "text": "I'll complete this instrumented research flow step by step. Starting with step 1:", + │ │ "type": "text" + │ │ }, + │ │ { + │ │ "id": "", + │ │ "input": { + │ │ "query": "flue instrumentation" + │ │ }, + │ │ "name": "lookup", + │ │ "type": "tool_use" + │ │ } + │ │ ], + │ │ "role": "assistant" + │ │ }, + │ │ { + │ │ "content": [ + │ │ { + │ │ "cache_control": { + │ │ "type": "ephemeral" + │ │ }, + │ │ "content": "{\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}", + │ │ "is_error": false, + │ │ "tool_use_id": "toolu_01QHXkUBddKx6pexY4WSjMR1", + │ │ "type": "tool_result" + │ │ } + │ │ ], + │ │ "role": "user" + │ │ }, + │ │ { + │ │ "content": [ + │ │ { + │ │ "cache_control": { + │ │ "type": "ephemeral" + │ │ }, + │ │ "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /e2e/scenarios/flue-instrumentation/\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + │ │ "type": "text" + │ │ } + │ │ ], + │ │ "role": "system" + │ │ } + │ │ ] + │ │ metadata: { + │ │ "model": "claude-sonnet-4-5-20250929", + │ │ "provider": "anthropic" + │ │ } │ ├── flue.turn [llm] │ │ output: [ │ │ { │ │ "finish_reason": "toolUse", │ │ "index": 0, │ │ "message": { - │ │ "content": "Now proceeding to Step 2:", - │ │ "reasoning": "Good, I got the lookup result with id \"flue-session-2026\". Now I'll proceed to step 2 and use this id as the lookupId parameter in the web_search call with the specified query.", + │ │ "content": "Now proceeding to step 2:", + │ │ "reasoning": "Good, I got the lookup result with id \"flue-session-2026\". Now I need to proceed to step 2: call web_search with this lookupId and the query \"Braintrust Flue reasoning stream instrumentation\".", │ │ "role": "assistant", │ │ "tool_calls": [ │ │ { @@ -119,13 +214,13 @@ span_tree: │ │ "provider": "flue" │ │ } │ │ metrics: { - │ │ "completion_tokens": 153, + │ │ "completion_tokens": 158, │ │ "duration_ms": 0, - │ │ "estimated_cost": 0.00388485, - │ │ "prompt_cache_creation_tokens": 239, - │ │ "prompt_cached_tokens": 2182, + │ │ "estimated_cost": 0.0039942, + │ │ "prompt_cache_creation_tokens": 248, + │ │ "prompt_cached_tokens": 2184, │ │ "prompt_tokens": 13, - │ │ "tokens": 2587 + │ │ "tokens": 2603 │ │ } │ ├── tool: web_search [tool] │ │ input: { @@ -151,14 +246,112 @@ span_tree: │ │ metrics: { │ │ "duration_ms": 0 │ │ } + │ ├── anthropic.messages.create [llm] + │ │ input: [ + │ │ { + │ │ "content": [ + │ │ { + │ │ "text": "Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.", + │ │ "type": "text" + │ │ } + │ │ ], + │ │ "role": "user" + │ │ }, + │ │ { + │ │ "content": [ + │ │ { + │ │ "signature": "EtYFCm4IDRgCKkC/lJUT/EhYE72Jr10vREWOZ4vwSSugL9RsNrhJg9wjli7iCBt2/hEandW2KZpRqluVbV3ehHY/n0Mge6VmWF1cMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMHcfwfYOEmmJZGyBBGgyYm8sT/W36vQdF0dQiMFC5CVRWmqhR2r90pB0R8Wjbq0ITTIN0abxhOezE1NDsrj6CM4/DXLaOsJp4TD5DNCqVBEgEEzFdeaRrRB0CeXdlWoo+wf7yR9EMOVhLmyRf3nItrqN/cb30rpaexhXDm0/Hj3WxQH+o0K73Oyr6qtiDVe9xGNt6v5DrUz31HcE+GJ0Yw8ThoufXvqNyFQV3lLhpZExUDX6hwlmKvaRpj5YH+q5TTx3jAIgzD+zGkgUS0vC7Muftm2VZcuI/2wVsbtWo6hYdvbbdxr+8FzJsCOWc3ptVaUBimC5//HRSNBXFJ9zlkt6l7YxnUeKWiesSdE6h1EJ08Rp4OrAP+oaYWU4v6IODdnJmsqGKbN//i6gGCnAHBBAZr/pnnmEyUOsBGc6ARMOtcwjFIN3/B1YkJi8r8QbbtGHJHfH/v102MSZG8UJk2RXxt1fTQUWNbp0DjA7gUn00H3dnmSAQyqFjKLIFncnhiH5PSSgdvErNB7y/2UBk2CY2i4dpevr+7uvHZDLPjSBcovpvgJ4ihdUM9S080xCm1NNkjs+QP+AQAh20t33t7EN6aZS0+CZcfJxf1QV6mGIkL7BKAPeIXjD8TKuW/at4pqwrvvesI2cZY5RDjC7v7tz/+tqiEkob1s8J3jx2dbIgPBFOR5PFFwPby0H9Guv4ZB63YAlP3sXX+F5fC6fQifQeJK8fuWK+FKe3v+gK/hZcuBuU/Jfhrst4CsEWeaBhmPktZOHu5f85KZ/layh4Pp39yxR0FiHY5eXibsTh2SfDN3K6GAE=", + │ │ "thinking": "The user wants me to complete a specific instrumented research flow with these steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url and call summarize_source\n4. After summarize_source returns, reply with exactly \"PROMPT_DONE\" and no other text\n\nThe user emphasizes calling exactly one tool per turn and waiting for each result. Let me start with step 1.", + │ │ "type": "thinking" + │ │ }, + │ │ { + │ │ "text": "I'll complete this instrumented research flow step by step. Starting with step 1:", + │ │ "type": "text" + │ │ }, + │ │ { + │ │ "id": "", + │ │ "input": { + │ │ "query": "flue instrumentation" + │ │ }, + │ │ "name": "lookup", + │ │ "type": "tool_use" + │ │ } + │ │ ], + │ │ "role": "assistant" + │ │ }, + │ │ { + │ │ "content": [ + │ │ { + │ │ "content": "{\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}", + │ │ "is_error": false, + │ │ "tool_use_id": "toolu_01QHXkUBddKx6pexY4WSjMR1", + │ │ "type": "tool_result" + │ │ } + │ │ ], + │ │ "role": "user" + │ │ }, + │ │ { + │ │ "content": [ + │ │ { + │ │ "signature": "EpEDCm4IDRgCKkAMahve1kB1j4njp1ZSzO8eCK4bb5Ex7MB6tjdoOXfuUDRfkBqvIGdwVly8GiA8GGYC7Y/RVfREXF6A6OXHTwFyMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMI25UM/xFQ9Bh625NGgyP2lwn3SKJlMxLUwciMH3VyS+uXCYaj8hlEdHVLz3HDLA5DCge72pzSyECwbUqqdxyZgtWjWYo/v0qA6XIsirQAQUbwyS/JWdGjeoTVbN2wMlsvu6j2cZmYMhk2HDKvmRIKpFTX5Ha82HBMwuM+f/7faDeQM5ldk8a5Tnm6iWFUj5jOoNqCYa+lBzhWor1vuZ5ieA569nGcMa0z1QmEP8WC3zNkI+kDazdS9FcuJP8KltHVfNr/wf/5AgAYFMt8fIaolvtJmN7uZ0yJKVfuJ58yx0nlQyEkxK8siXz7in2ulTuflohdD37ZErfxQNM3iYlCEfBOfa6kuJhwOwQ+HWJA1LXmUxzR/9AHRq0f3euNXkYAQ==", + │ │ "thinking": "Good, I got the lookup result with id \"flue-session-2026\". Now I need to proceed to step 2: call web_search with this lookupId and the query \"Braintrust Flue reasoning stream instrumentation\".", + │ │ "type": "thinking" + │ │ }, + │ │ { + │ │ "text": "Now proceeding to step 2:", + │ │ "type": "text" + │ │ }, + │ │ { + │ │ "id": "", + │ │ "input": { + │ │ "lookupId": "flue-session-2026", + │ │ "query": "Braintrust Flue reasoning stream instrumentation" + │ │ }, + │ │ "name": "web_search", + │ │ "type": "tool_use" + │ │ } + │ │ ], + │ │ "role": "assistant" + │ │ }, + │ │ { + │ │ "content": [ + │ │ { + │ │ "cache_control": { + │ │ "type": "ephemeral" + │ │ }, + │ │ "content": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\",\"results\":[{\"title\":\"Flue reasoning stream instrumentation\",\"url\":\"https://example.test/flue/reasoning-streams\"}]}", + │ │ "is_error": false, + │ │ "tool_use_id": "toolu_01CvT1mSWwETua7LWwSQiyq6", + │ │ "type": "tool_result" + │ │ } + │ │ ], + │ │ "role": "user" + │ │ }, + │ │ { + │ │ "content": [ + │ │ { + │ │ "cache_control": { + │ │ "type": "ephemeral" + │ │ }, + │ │ "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /e2e/scenarios/flue-instrumentation/\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + │ │ "type": "text" + │ │ } + │ │ ], + │ │ "role": "system" + │ │ } + │ │ ] + │ │ metadata: { + │ │ "model": "claude-sonnet-4-5-20250929", + │ │ "provider": "anthropic" + │ │ } │ ├── flue.turn [llm] │ │ output: [ │ │ { │ │ "finish_reason": "toolUse", │ │ "index": 0, │ │ "message": { - │ │ "content": "Now proceeding to Step 3:", - │ │ "reasoning": "Perfect! I got the web_search results. There's one result with the URL \"https://example.test/flue/reasoning-streams\". Now I need to proceed to step 3 and call summarize_source with this URL.", + │ │ "content": "Now proceeding to step 3:", + │ │ "reasoning": "Perfect! I got the web_search results. There's one result with the URL \"https://example.test/flue/reasoning-streams\". Now I need to proceed to step 3: call summarize_source with this URL.", │ │ "role": "assistant", │ │ "tool_calls": [ │ │ { @@ -181,13 +374,13 @@ span_tree: │ │ "provider": "flue" │ │ } │ │ metrics: { - │ │ "completion_tokens": 133, + │ │ "completion_tokens": 132, │ │ "duration_ms": 0, - │ │ "estimated_cost": 0.0036190500000000004, - │ │ "prompt_cache_creation_tokens": 229, - │ │ "prompt_cached_tokens": 2421, + │ │ "estimated_cost": 0.0036261, + │ │ "prompt_cache_creation_tokens": 234, + │ │ "prompt_cached_tokens": 2432, │ │ "prompt_tokens": 13, - │ │ "tokens": 2796 + │ │ "tokens": 2811 │ │ } │ ├── tool: summarize_source [tool] │ │ input: { @@ -212,6 +405,137 @@ span_tree: │ │ metrics: { │ │ "duration_ms": 0 │ │ } + │ ├── anthropic.messages.create [llm] + │ │ input: [ + │ │ { + │ │ "content": [ + │ │ { + │ │ "text": "Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.", + │ │ "type": "text" + │ │ } + │ │ ], + │ │ "role": "user" + │ │ }, + │ │ { + │ │ "content": [ + │ │ { + │ │ "signature": "EtYFCm4IDRgCKkC/lJUT/EhYE72Jr10vREWOZ4vwSSugL9RsNrhJg9wjli7iCBt2/hEandW2KZpRqluVbV3ehHY/n0Mge6VmWF1cMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMHcfwfYOEmmJZGyBBGgyYm8sT/W36vQdF0dQiMFC5CVRWmqhR2r90pB0R8Wjbq0ITTIN0abxhOezE1NDsrj6CM4/DXLaOsJp4TD5DNCqVBEgEEzFdeaRrRB0CeXdlWoo+wf7yR9EMOVhLmyRf3nItrqN/cb30rpaexhXDm0/Hj3WxQH+o0K73Oyr6qtiDVe9xGNt6v5DrUz31HcE+GJ0Yw8ThoufXvqNyFQV3lLhpZExUDX6hwlmKvaRpj5YH+q5TTx3jAIgzD+zGkgUS0vC7Muftm2VZcuI/2wVsbtWo6hYdvbbdxr+8FzJsCOWc3ptVaUBimC5//HRSNBXFJ9zlkt6l7YxnUeKWiesSdE6h1EJ08Rp4OrAP+oaYWU4v6IODdnJmsqGKbN//i6gGCnAHBBAZr/pnnmEyUOsBGc6ARMOtcwjFIN3/B1YkJi8r8QbbtGHJHfH/v102MSZG8UJk2RXxt1fTQUWNbp0DjA7gUn00H3dnmSAQyqFjKLIFncnhiH5PSSgdvErNB7y/2UBk2CY2i4dpevr+7uvHZDLPjSBcovpvgJ4ihdUM9S080xCm1NNkjs+QP+AQAh20t33t7EN6aZS0+CZcfJxf1QV6mGIkL7BKAPeIXjD8TKuW/at4pqwrvvesI2cZY5RDjC7v7tz/+tqiEkob1s8J3jx2dbIgPBFOR5PFFwPby0H9Guv4ZB63YAlP3sXX+F5fC6fQifQeJK8fuWK+FKe3v+gK/hZcuBuU/Jfhrst4CsEWeaBhmPktZOHu5f85KZ/layh4Pp39yxR0FiHY5eXibsTh2SfDN3K6GAE=", + │ │ "thinking": "The user wants me to complete a specific instrumented research flow with these steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url and call summarize_source\n4. After summarize_source returns, reply with exactly \"PROMPT_DONE\" and no other text\n\nThe user emphasizes calling exactly one tool per turn and waiting for each result. Let me start with step 1.", + │ │ "type": "thinking" + │ │ }, + │ │ { + │ │ "text": "I'll complete this instrumented research flow step by step. Starting with step 1:", + │ │ "type": "text" + │ │ }, + │ │ { + │ │ "id": "", + │ │ "input": { + │ │ "query": "flue instrumentation" + │ │ }, + │ │ "name": "lookup", + │ │ "type": "tool_use" + │ │ } + │ │ ], + │ │ "role": "assistant" + │ │ }, + │ │ { + │ │ "content": [ + │ │ { + │ │ "content": "{\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}", + │ │ "is_error": false, + │ │ "tool_use_id": "toolu_01QHXkUBddKx6pexY4WSjMR1", + │ │ "type": "tool_result" + │ │ } + │ │ ], + │ │ "role": "user" + │ │ }, + │ │ { + │ │ "content": [ + │ │ { + │ │ "signature": "EpEDCm4IDRgCKkAMahve1kB1j4njp1ZSzO8eCK4bb5Ex7MB6tjdoOXfuUDRfkBqvIGdwVly8GiA8GGYC7Y/RVfREXF6A6OXHTwFyMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMI25UM/xFQ9Bh625NGgyP2lwn3SKJlMxLUwciMH3VyS+uXCYaj8hlEdHVLz3HDLA5DCge72pzSyECwbUqqdxyZgtWjWYo/v0qA6XIsirQAQUbwyS/JWdGjeoTVbN2wMlsvu6j2cZmYMhk2HDKvmRIKpFTX5Ha82HBMwuM+f/7faDeQM5ldk8a5Tnm6iWFUj5jOoNqCYa+lBzhWor1vuZ5ieA569nGcMa0z1QmEP8WC3zNkI+kDazdS9FcuJP8KltHVfNr/wf/5AgAYFMt8fIaolvtJmN7uZ0yJKVfuJ58yx0nlQyEkxK8siXz7in2ulTuflohdD37ZErfxQNM3iYlCEfBOfa6kuJhwOwQ+HWJA1LXmUxzR/9AHRq0f3euNXkYAQ==", + │ │ "thinking": "Good, I got the lookup result with id \"flue-session-2026\". Now I need to proceed to step 2: call web_search with this lookupId and the query \"Braintrust Flue reasoning stream instrumentation\".", + │ │ "type": "thinking" + │ │ }, + │ │ { + │ │ "text": "Now proceeding to step 2:", + │ │ "type": "text" + │ │ }, + │ │ { + │ │ "id": "", + │ │ "input": { + │ │ "lookupId": "flue-session-2026", + │ │ "query": "Braintrust Flue reasoning stream instrumentation" + │ │ }, + │ │ "name": "web_search", + │ │ "type": "tool_use" + │ │ } + │ │ ], + │ │ "role": "assistant" + │ │ }, + │ │ { + │ │ "content": [ + │ │ { + │ │ "content": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\",\"results\":[{\"title\":\"Flue reasoning stream instrumentation\",\"url\":\"https://example.test/flue/reasoning-streams\"}]}", + │ │ "is_error": false, + │ │ "tool_use_id": "toolu_01CvT1mSWwETua7LWwSQiyq6", + │ │ "type": "tool_result" + │ │ } + │ │ ], + │ │ "role": "user" + │ │ }, + │ │ { + │ │ "content": [ + │ │ { + │ │ "signature": "EowDCm4IDRgCKkCpqmoUHjbaZYvB4bWm+hVDlxgU/iOCEn0v3xAMT4QsjKM7cIZMOWD2eEF8ENjGq0ttAvO8ZNI9YpiASikG2gnNMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMI5+VQnffadMSNsXEGgy1YAi10m6jJ39wq2UiMAUy8rg67GdkT4VUKix3ULTWnPfKucap7VLRPGDqK7ZhF0nDl2pcYGshMviSbzOjuyrLAXh3IPAAc3rvDuYAAHaWed6JE7/4gg/gzWhfVeAb0qXzXoiIHh8Z9KyHDfDDfpesr4TzmJHT/T8mhem3UfZc87ZLzFom8Vi+76Y2eVWcoI/EyPuyj+KVxU5kPh030LYWxUeSTUViRu9NAd+Wzz/5ZAgD+TiEmCnpNMI3eGqOiBPtwK7y/JIvxZRWvsJ1ghXNaEVShN3h8OUk9zmzIhBuUujWVZtc5wuM28726mOqMLwKckegl+q2vNrR+U+AqbMSYWUVlWLKZvd1LXiZGAE=", + │ │ "thinking": "Perfect! I got the web_search results. There's one result with the URL \"https://example.test/flue/reasoning-streams\". Now I need to proceed to step 3: call summarize_source with this URL.", + │ │ "type": "thinking" + │ │ }, + │ │ { + │ │ "text": "Now proceeding to step 3:", + │ │ "type": "text" + │ │ }, + │ │ { + │ │ "id": "", + │ │ "input": { + │ │ "url": "https://example.test/flue/reasoning-streams" + │ │ }, + │ │ "name": "summarize_source", + │ │ "type": "tool_use" + │ │ } + │ │ ], + │ │ "role": "assistant" + │ │ }, + │ │ { + │ │ "content": [ + │ │ { + │ │ "cache_control": { + │ │ "type": "ephemeral" + │ │ }, + │ │ "content": "{\"summary\":\"Flue emits reasoning, tool execution, and LLM turn events separately.\",\"url\":\"https://example.test/flue/reasoning-streams\"}", + │ │ "is_error": false, + │ │ "tool_use_id": "toolu_01NHkkJuQNXyRuWk58FCecye", + │ │ "type": "tool_result" + │ │ } + │ │ ], + │ │ "role": "user" + │ │ }, + │ │ { + │ │ "content": [ + │ │ { + │ │ "cache_control": { + │ │ "type": "ephemeral" + │ │ }, + │ │ "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /e2e/scenarios/flue-instrumentation/\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + │ │ "type": "text" + │ │ } + │ │ ], + │ │ "role": "system" + │ │ } + │ │ ] + │ │ metadata: { + │ │ "model": "claude-sonnet-4-5-20250929", + │ │ "provider": "anthropic" + │ │ } │ └── flue.turn [llm] │ output: [ │ { @@ -219,7 +543,7 @@ span_tree: │ "index": 0, │ "message": { │ "content": "PROMPT_DONE", - │ "reasoning": "Perfect! The summarize_source has returned. According to the instructions, I should now reply with exactly \"PROMPT_DONE\" and no other text.", + │ "reasoning": "The summarize_source has returned successfully. According to the instructions, I should now reply with exactly \"PROMPT_DONE\" and no other text.", │ "role": "assistant" │ } │ } @@ -232,13 +556,13 @@ span_tree: │ "provider": "flue" │ } │ metrics: { - │ "completion_tokens": 49, + │ "completion_tokens": 48, │ "duration_ms": 0, - │ "estimated_cost": 0.00227775, - │ "prompt_cache_creation_tokens": 189, - │ "prompt_cached_tokens": 2650, + │ "estimated_cost": 0.0022638, + │ "prompt_cache_creation_tokens": 188, + │ "prompt_cached_tokens": 2666, │ "prompt_tokens": 13, - │ "tokens": 2901 + │ "tokens": 2915 │ } ├── flue-skill-operation │ metadata: { @@ -263,21 +587,52 @@ span_tree: │ "provider": "flue" │ } │ metrics: { - │ "completion_tokens": 97, + │ "completion_tokens": 91, │ "duration_ms": 0, - │ "estimated_cost": 0.0026133, - │ "prompt_cache_creation_tokens": 0, - │ "prompt_cached_tokens": 3771, + │ "estimated_cost": 0.0030298499999999997, + │ "prompt_cache_creation_tokens": 147, + │ "prompt_cached_tokens": 3622, │ "prompt_tokens": 9, - │ "tokens": 3877 + │ "tokens": 3869 │ } + │ ├── anthropic.messages.create [llm] + │ │ input: [ + │ │ { + │ │ "content": [ + │ │ { + │ │ "cache_control": { + │ │ "type": "ephemeral" + │ │ }, + │ │ "text": "Run the skill named \"e2e-flue-skill\".\n\nArguments:\n{\n \"marker\": \"SKILL_DONE\"\n}", + │ │ "type": "text" + │ │ } + │ │ ], + │ │ "role": "user" + │ │ }, + │ │ { + │ │ "content": [ + │ │ { + │ │ "cache_control": { + │ │ "type": "ephemeral" + │ │ }, + │ │ "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /e2e/scenarios/flue-instrumentation/\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts\n\n\nNever call the task tool. Do not delegate e2e-flue-skill to another session. If you need the skill body, read .agents/skills/e2e-flue-skill/SKILL.md yourself with the read tool. Return the marker from the Arguments object exactly, with no other text.\n", + │ │ "type": "text" + │ │ } + │ │ ], + │ │ "role": "system" + │ │ } + │ │ ] + │ │ metadata: { + │ │ "model": "claude-sonnet-4-5-20250929", + │ │ "provider": "anthropic" + │ │ } │ ├── flue.turn [llm] │ │ output: [ │ │ { │ │ "finish_reason": "toolUse", │ │ "index": 0, │ │ "message": { - │ │ "content": "I'll run the e2e-flue-skill by reading its instructions and following them.", + │ │ "content": "I'll read the skill file and execute it according to its instructions.", │ │ "role": "assistant", │ │ "tool_calls": [ │ │ { @@ -299,13 +654,13 @@ span_tree: │ │ "provider": "flue" │ │ } │ │ metrics: { - │ │ "completion_tokens": 89, + │ │ "completion_tokens": 83, │ │ "duration_ms": 0, - │ │ "estimated_cost": 0.0018866999999999998, + │ │ "estimated_cost": 0.0017973, │ │ "prompt_cache_creation_tokens": 0, - │ │ "prompt_cached_tokens": 1809, + │ │ "prompt_cached_tokens": 1811, │ │ "prompt_tokens": 3, - │ │ "tokens": 1901 + │ │ "tokens": 1897 │ │ } │ ├── tool: read [tool] │ │ input: { @@ -331,6 +686,65 @@ span_tree: │ │ metrics: { │ │ "duration_ms": 0 │ │ } + │ ├── anthropic.messages.create [llm] + │ │ input: [ + │ │ { + │ │ "content": [ + │ │ { + │ │ "text": "Run the skill named \"e2e-flue-skill\".\n\nArguments:\n{\n \"marker\": \"SKILL_DONE\"\n}", + │ │ "type": "text" + │ │ } + │ │ ], + │ │ "role": "user" + │ │ }, + │ │ { + │ │ "content": [ + │ │ { + │ │ "text": "I'll read the skill file and execute it according to its instructions.", + │ │ "type": "text" + │ │ }, + │ │ { + │ │ "id": "", + │ │ "input": { + │ │ "path": ".agents/skills/e2e-flue-skill/SKILL.md" + │ │ }, + │ │ "name": "read", + │ │ "type": "tool_use" + │ │ } + │ │ ], + │ │ "role": "assistant" + │ │ }, + │ │ { + │ │ "content": [ + │ │ { + │ │ "cache_control": { + │ │ "type": "ephemeral" + │ │ }, + │ │ "content": "---\nname: e2e-flue-skill\ndescription: Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n---\n\nReturn the marker from the provided args exactly once. Output no other text.\n", + │ │ "is_error": false, + │ │ "tool_use_id": "toolu_01HmmsNYZUC67GqVoKKLbfiQ", + │ │ "type": "tool_result" + │ │ } + │ │ ], + │ │ "role": "user" + │ │ }, + │ │ { + │ │ "content": [ + │ │ { + │ │ "cache_control": { + │ │ "type": "ephemeral" + │ │ }, + │ │ "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /e2e/scenarios/flue-instrumentation/\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts\n\n\nNever call the task tool. Do not delegate e2e-flue-skill to another session. If you need the skill body, read .agents/skills/e2e-flue-skill/SKILL.md yourself with the read tool. Return the marker from the Arguments object exactly, with no other text.\n", + │ │ "type": "text" + │ │ } + │ │ ], + │ │ "role": "system" + │ │ } + │ │ ] + │ │ metadata: { + │ │ "model": "claude-sonnet-4-5-20250929", + │ │ "provider": "anthropic" + │ │ } │ └── flue.turn [llm] │ output: [ │ { @@ -351,11 +765,11 @@ span_tree: │ metrics: { │ "completion_tokens": 8, │ "duration_ms": 0, - │ "estimated_cost": 0.0007266, - │ "prompt_cache_creation_tokens": 0, - │ "prompt_cached_tokens": 1962, + │ "estimated_cost": 0.0012325499999999998, + │ "prompt_cache_creation_tokens": 147, + │ "prompt_cached_tokens": 1811, │ "prompt_tokens": 6, - │ "tokens": 1976 + │ "tokens": 1972 │ } ├── flue-task-operation │ metadata: { @@ -375,48 +789,92 @@ span_tree: │ metrics: { │ "completion_tokens": 4, │ "duration_ms": 0, - │ "estimated_cost": 0.00011789999999999999, + │ "estimated_cost": 0.0001182, │ "prompt_cache_creation_tokens": 0, │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 770, - │ "tokens": 774 + │ "prompt_tokens": 772, + │ "tokens": 776 │ } - │ └── flue.task [task] - │ input: "Reply with exactly TASK_DONE and no other text." - │ output: "TASK_DONE" + │ ├── flue.task [task] + │ │ input: "Reply with exactly TASK_DONE and no other text." + │ │ output: "TASK_DONE" + │ │ metadata: { + │ │ "flue.session": "task", + │ │ "provider": "flue" + │ │ } + │ │ metrics: { + │ │ "duration_ms": 0 + │ │ } + │ ├── openai.responses.create [llm] + │ │ input: [ + │ │ { + │ │ "content": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /e2e/scenarios/flue-instrumentation/\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + │ │ "role": "system" + │ │ }, + │ │ { + │ │ "content": [ + │ │ { + │ │ "text": "Reply with exactly TASK_DONE and no other text.", + │ │ "type": "input_text" + │ │ } + │ │ ], + │ │ "role": "user" + │ │ } + │ │ ] + │ │ output: [ + │ │ { + │ │ "content": [ + │ │ { + │ │ "annotations": [], + │ │ "logprobs": [], + │ │ "text": "TASK_DONE", + │ │ "type": "output_text" + │ │ } + │ │ ], + │ │ "id": "", + │ │ "role": "assistant", + │ │ "status": "completed", + │ │ "type": "message" + │ │ } + │ │ ] + │ │ metadata: { + │ │ "model": "gpt-4o-mini-2024-07-18", + │ │ "provider": "openai" + │ │ } + │ │ metrics: { + │ │ "completion_reasoning_tokens": 0, + │ │ "completion_tokens": 4, + │ │ "prompt_cached_tokens": 0, + │ │ "prompt_tokens": 772, + │ │ "time_to_first_token": 0, + │ │ "tokens": 776 + │ │ } + │ └── flue.turn [llm] + │ output: [ + │ { + │ "finish_reason": "stop", + │ "index": 0, + │ "message": { + │ "content": "TASK_DONE", + │ "role": "assistant" + │ } + │ } + │ ] │ metadata: { - │ "flue.session": "task", + │ "flue.model": "gpt-4o-mini", + │ "flue.session": "task:task:", + │ "model": "gpt-4o-mini", │ "provider": "flue" │ } │ metrics: { - │ "duration_ms": 0 + │ "completion_tokens": 4, + │ "duration_ms": 0, + │ "estimated_cost": 0.0001182, + │ "prompt_cache_creation_tokens": 0, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 772, + │ "tokens": 776 │ } - │ └── flue.turn [llm] - │ output: [ - │ { - │ "finish_reason": "stop", - │ "index": 0, - │ "message": { - │ "content": "TASK_DONE", - │ "role": "assistant" - │ } - │ } - │ ] - │ metadata: { - │ "flue.model": "gpt-4o-mini", - │ "flue.session": "task:task:", - │ "model": "gpt-4o-mini", - │ "provider": "flue" - │ } - │ metrics: { - │ "completion_tokens": 4, - │ "duration_ms": 0, - │ "estimated_cost": 0.00011789999999999999, - │ "prompt_cache_creation_tokens": 0, - │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 770, - │ "tokens": 774 - │ } └── flue-compact-operation metadata: { "operation": "compact" @@ -430,26 +888,49 @@ span_tree: metrics: { "duration_ms": 0 } - └── flue.compaction [task] - input: { - "estimatedTokens": 2901, - "reason": "manual" - } - output: { - "messagesAfter": 2, - "messagesBefore": 8 - } + ├── flue.compaction [task] + │ input: { + │ "estimatedTokens": 2915, + │ "reason": "manual" + │ } + │ output: { + │ "messagesAfter": 2, + │ "messagesBefore": 8 + │ } + │ metadata: { + │ "flue.compaction_reason": "manual", + │ "flue.session": "main", + │ "provider": "flue" + │ } + │ metrics: { + │ "completion_tokens": 0, + │ "duration_ms": 0, + │ "estimated_cost": 0, + │ "prompt_cache_creation_tokens": 0, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 0, + │ "tokens": 0 + │ } + └── openai.responses.create [llm] + input: [ + { + "content": "You are a context summarization assistant. Your task is to read a conversation between a user and an AI coding assistant, then produce a structured summary following the exact format specified.\n\nDo NOT continue the conversation. Do NOT respond to any questions in the conversation. ONLY output the structured summary.", + "role": "system" + }, + { + "content": [ + { + "text": "\n[User]: Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.\n\n[Assistant thinking]: The user wants me to complete a specific instrumented research flow with these steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url and call summarize_source\n4. After summarize_source returns, reply with exactly \"PROMPT_DONE\" and no other text\n\nThe user emphasizes calling exactly one tool per turn and waiting for each result. Let me start with step 1.\n\n[Assistant]: I'll complete this instrumented research flow step by step. Starting with step 1:\n\n[Assistant tool calls]: lookup(query=\"flue instrumentation\")\n\n[Tool result]: {\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}\n\n[Assistant thinking]: Good, I got the lookup result with id \"flue-session-2026\". Now I need to proceed to step 2: call web_search with this lookupId and the query \"Braintrust Flue reasoning stream instrumentation\".\n\n[Assistant]: Now proceeding to step 2:\n\n[Assistant tool calls]: web_search(lookupId=\"flue-session-2026\", query=\"Braintrust Flue reasoning stream instrumentation\")\n\n[Tool result]: {\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\",\"results\":[{\"title\":\"Flue reasoning stream instrumentation\",\"url\":\"https://example.test/flue/reasoning-streams\"}]}\n\n[Assistant thinking]: Perfect! I got the web_search results. There's one result with the URL \"https://example.test/flue/reasoning-streams\". Now I need to proceed to step 3: call summarize_source with this URL.\n\n[Assistant]: Now proceeding to step 3:\n\n[Assistant tool calls]: summarize_source(url=\"https://example.test/flue/reasoning-streams\")\n\n[Tool result]: {\"summary\":\"Flue emits reasoning, tool execution, and LLM turn events separately.\",\"url\":\"https://example.test/flue/reasoning-streams\"}\n\n\nThis is the PREFIX of a turn that was too large to keep. The SUFFIX (recent work) is retained.\n\nSummarize the prefix to provide context for the retained suffix:\n\n## Original Request\n[What did the user ask for in this turn?]\n\n## Early Progress\n- [Key decisions and work done in the prefix]\n\n## Context for Suffix\n- [Information needed to understand the retained recent work]\n\nBe concise. Focus on what's needed to understand the kept suffix.", + "type": "input_text" + } + ], + "role": "user" + } + ] metadata: { - "flue.compaction_reason": "manual", - "flue.session": "main", - "provider": "flue" + "model": "gpt-4o-mini", + "provider": "openai" } metrics: { - "completion_tokens": 0, - "duration_ms": 0, - "estimated_cost": 0, - "prompt_cache_creation_tokens": 0, - "prompt_cached_tokens": 0, - "prompt_tokens": 0, - "tokens": 0 + "time_to_first_token": 0 } diff --git a/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-openai-auto-hook.span-tree.json b/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-openai-auto-hook.span-tree.json new file mode 100644 index 000000000..194112ac7 --- /dev/null +++ b/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-openai-auto-hook.span-tree.json @@ -0,0 +1,962 @@ +{ + "span_tree": [ + { + "name": "flue-root", + "type": "task", + "children": [ + { + "name": "flue-prompt-operation", + "children": [ + { + "name": "flue.session.prompt", + "type": "task", + "children": [ + { + "name": "openai.responses.create", + "type": "llm", + "children": [], + "input": [ + { + "content": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /e2e/scenarios/flue-instrumentation/\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + "role": "system" + }, + { + "content": [ + { + "text": "Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.", + "type": "input_text" + } + ], + "role": "user" + } + ], + "output": [ + { + "arguments": "{\"query\":\"flue instrumentation\"}", + "call_id": "call_xELft1kjhTSvPWAp3Z3i4zWk", + "id": "", + "name": "lookup", + "status": "completed", + "type": "function_call" + } + ], + "metadata": { + "model": "gpt-4o-mini-2024-07-18", + "provider": "openai" + }, + "metrics": { + "completion_reasoning_tokens": 0, + "completion_tokens": 16, + "prompt_cached_tokens": 0, + "prompt_tokens": 946, + "time_to_first_token": 0, + "tokens": 962 + } + }, + { + "name": "flue.turn", + "type": "llm", + "children": [], + "output": [ + { + "finish_reason": "toolUse", + "index": 0, + "message": { + "content": "", + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"query\":\"flue instrumentation\"}", + "name": "lookup" + }, + "id": "", + "type": "function" + } + ] + } + } + ], + "metadata": { + "flue.model": "gpt-4o-mini", + "flue.session": "main", + "model": "gpt-4o-mini", + "provider": "flue" + }, + "metrics": { + "completion_tokens": 16, + "duration_ms": 0, + "estimated_cost": 0.0001515, + "prompt_cache_creation_tokens": 0, + "prompt_cached_tokens": 0, + "prompt_tokens": 946, + "tokens": 962 + } + }, + { + "name": "tool: lookup", + "type": "tool", + "children": [], + "input": { + "query": "flue instrumentation" + }, + "output": { + "content": [ + { + "text": "{\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}", + "type": "text" + } + ], + "details": { + "customTool": "lookup" + } + }, + "metadata": { + "flue.session": "main", + "flue.tool_name": "lookup", + "provider": "flue" + }, + "metrics": { + "duration_ms": 0 + } + }, + { + "name": "openai.responses.create", + "type": "llm", + "children": [], + "input": [ + { + "content": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /e2e/scenarios/flue-instrumentation/\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + "role": "system" + }, + { + "content": [ + { + "text": "Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.", + "type": "input_text" + } + ], + "role": "user" + }, + { + "arguments": "{\"query\":\"flue instrumentation\"}", + "call_id": "call_xELft1kjhTSvPWAp3Z3i4zWk", + "id": "", + "name": "lookup", + "type": "function_call" + }, + { + "call_id": "call_xELft1kjhTSvPWAp3Z3i4zWk", + "output": "{\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}", + "type": "function_call_output" + } + ], + "output": [ + { + "arguments": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\"}", + "call_id": "call_F7zI4fCOw4jk7rTwqbi8umo7", + "id": "", + "name": "web_search", + "status": "completed", + "type": "function_call" + } + ], + "metadata": { + "model": "gpt-4o-mini-2024-07-18", + "provider": "openai" + }, + "metrics": { + "completion_reasoning_tokens": 0, + "completion_tokens": 31, + "prompt_cached_tokens": 0, + "prompt_tokens": 987, + "time_to_first_token": 0, + "tokens": 1018 + } + }, + { + "name": "flue.turn", + "type": "llm", + "children": [], + "output": [ + { + "finish_reason": "toolUse", + "index": 0, + "message": { + "content": "", + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\"}", + "name": "web_search" + }, + "id": "", + "type": "function" + } + ] + } + } + ], + "metadata": { + "flue.model": "gpt-4o-mini", + "flue.session": "main", + "model": "gpt-4o-mini", + "provider": "flue" + }, + "metrics": { + "completion_tokens": 31, + "duration_ms": 0, + "estimated_cost": 0.00016664999999999998, + "prompt_cache_creation_tokens": 0, + "prompt_cached_tokens": 0, + "prompt_tokens": 987, + "tokens": 1018 + } + }, + { + "name": "tool: web_search", + "type": "tool", + "children": [], + "input": { + "lookupId": "flue-session-2026", + "query": "Braintrust Flue reasoning stream instrumentation" + }, + "output": { + "content": [ + { + "text": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\",\"results\":[{\"title\":\"Flue reasoning stream instrumentation\",\"url\":\"https://example.test/flue/reasoning-streams\"}]}", + "type": "text" + } + ], + "details": { + "customTool": "web_search" + } + }, + "metadata": { + "flue.session": "main", + "flue.tool_name": "web_search", + "provider": "flue" + }, + "metrics": { + "duration_ms": 0 + } + }, + { + "name": "openai.responses.create", + "type": "llm", + "children": [], + "input": [ + { + "content": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /e2e/scenarios/flue-instrumentation/\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + "role": "system" + }, + { + "content": [ + { + "text": "Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.", + "type": "input_text" + } + ], + "role": "user" + }, + { + "arguments": "{\"query\":\"flue instrumentation\"}", + "call_id": "call_xELft1kjhTSvPWAp3Z3i4zWk", + "id": "", + "name": "lookup", + "type": "function_call" + }, + { + "call_id": "call_xELft1kjhTSvPWAp3Z3i4zWk", + "output": "{\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}", + "type": "function_call_output" + }, + { + "arguments": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\"}", + "call_id": "call_F7zI4fCOw4jk7rTwqbi8umo7", + "id": "", + "name": "web_search", + "type": "function_call" + }, + { + "call_id": "call_F7zI4fCOw4jk7rTwqbi8umo7", + "output": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\",\"results\":[{\"title\":\"Flue reasoning stream instrumentation\",\"url\":\"https://example.test/flue/reasoning-streams\"}]}", + "type": "function_call_output" + } + ], + "output": [ + { + "arguments": "{\"url\":\"https://example.test/flue/reasoning-streams\"}", + "call_id": "call_0yinp9edeamv8mKgyhkpaCmG", + "id": "", + "name": "summarize_source", + "status": "completed", + "type": "function_call" + } + ], + "metadata": { + "model": "gpt-4o-mini-2024-07-18", + "provider": "openai" + }, + "metrics": { + "completion_reasoning_tokens": 0, + "completion_tokens": 27, + "prompt_cached_tokens": 0, + "prompt_tokens": 1070, + "time_to_first_token": 0, + "tokens": 1097 + } + }, + { + "name": "flue.turn", + "type": "llm", + "children": [], + "output": [ + { + "finish_reason": "toolUse", + "index": 0, + "message": { + "content": "", + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"url\":\"https://example.test/flue/reasoning-streams\"}", + "name": "summarize_source" + }, + "id": "", + "type": "function" + } + ] + } + } + ], + "metadata": { + "flue.model": "gpt-4o-mini", + "flue.session": "main", + "model": "gpt-4o-mini", + "provider": "flue" + }, + "metrics": { + "completion_tokens": 27, + "duration_ms": 0, + "estimated_cost": 0.0001767, + "prompt_cache_creation_tokens": 0, + "prompt_cached_tokens": 0, + "prompt_tokens": 1070, + "tokens": 1097 + } + }, + { + "name": "tool: summarize_source", + "type": "tool", + "children": [], + "input": { + "url": "https://example.test/flue/reasoning-streams" + }, + "output": { + "content": [ + { + "text": "{\"summary\":\"Flue emits reasoning, tool execution, and LLM turn events separately.\",\"url\":\"https://example.test/flue/reasoning-streams\"}", + "type": "text" + } + ], + "details": { + "customTool": "summarize_source" + } + }, + "metadata": { + "flue.session": "main", + "flue.tool_name": "summarize_source", + "provider": "flue" + }, + "metrics": { + "duration_ms": 0 + } + }, + { + "name": "openai.responses.create", + "type": "llm", + "children": [], + "input": [ + { + "content": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /e2e/scenarios/flue-instrumentation/\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + "role": "system" + }, + { + "content": [ + { + "text": "Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.", + "type": "input_text" + } + ], + "role": "user" + }, + { + "arguments": "{\"query\":\"flue instrumentation\"}", + "call_id": "call_xELft1kjhTSvPWAp3Z3i4zWk", + "id": "", + "name": "lookup", + "type": "function_call" + }, + { + "call_id": "call_xELft1kjhTSvPWAp3Z3i4zWk", + "output": "{\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}", + "type": "function_call_output" + }, + { + "arguments": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\"}", + "call_id": "call_F7zI4fCOw4jk7rTwqbi8umo7", + "id": "", + "name": "web_search", + "type": "function_call" + }, + { + "call_id": "call_F7zI4fCOw4jk7rTwqbi8umo7", + "output": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\",\"results\":[{\"title\":\"Flue reasoning stream instrumentation\",\"url\":\"https://example.test/flue/reasoning-streams\"}]}", + "type": "function_call_output" + }, + { + "arguments": "{\"url\":\"https://example.test/flue/reasoning-streams\"}", + "call_id": "call_0yinp9edeamv8mKgyhkpaCmG", + "id": "", + "name": "summarize_source", + "type": "function_call" + }, + { + "call_id": "call_0yinp9edeamv8mKgyhkpaCmG", + "output": "{\"summary\":\"Flue emits reasoning, tool execution, and LLM turn events separately.\",\"url\":\"https://example.test/flue/reasoning-streams\"}", + "type": "function_call_output" + } + ], + "output": [ + { + "content": [ + { + "annotations": [], + "logprobs": [], + "text": "PROMPT_DONE", + "type": "output_text" + } + ], + "id": "", + "role": "assistant", + "status": "completed", + "type": "message" + } + ], + "metadata": { + "model": "gpt-4o-mini-2024-07-18", + "provider": "openai" + }, + "metrics": { + "completion_reasoning_tokens": 0, + "completion_tokens": 5, + "prompt_cached_tokens": 1024, + "prompt_tokens": 1136, + "time_to_first_token": 0, + "tokens": 1141 + } + }, + { + "name": "flue.turn", + "type": "llm", + "children": [], + "output": [ + { + "finish_reason": "stop", + "index": 0, + "message": { + "content": "PROMPT_DONE", + "role": "assistant" + } + } + ], + "metadata": { + "flue.model": "gpt-4o-mini", + "flue.session": "main", + "model": "gpt-4o-mini", + "provider": "flue" + }, + "metrics": { + "completion_tokens": 5, + "duration_ms": 0, + "estimated_cost": 0.00010172, + "prompt_cache_creation_tokens": 0, + "prompt_cached_tokens": 1024, + "prompt_tokens": 112, + "tokens": 1141 + } + } + ], + "input": "Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.", + "output": "PROMPT_DONE", + "metadata": { + "flue.model": "gpt-4o-mini", + "flue.operation": "prompt", + "flue.session": "main", + "flue.thinking_level": "off", + "flue.tools_count": 3, + "model": "gpt-4o-mini", + "provider": "flue" + }, + "metrics": { + "completion_tokens": 79, + "duration_ms": 0, + "estimated_cost": 0.00059657, + "prompt_cache_creation_tokens": 0, + "prompt_cached_tokens": 1024, + "prompt_tokens": 3115, + "tokens": 4218 + } + } + ], + "metadata": { + "operation": "prompt" + } + }, + { + "name": "flue-skill-operation", + "children": [ + { + "name": "flue.session.skill", + "type": "task", + "children": [ + { + "name": "anthropic.messages.create", + "type": "llm", + "children": [], + "input": [ + { + "content": [ + { + "cache_control": { + "type": "ephemeral" + }, + "text": "Run the skill named \"e2e-flue-skill\".\n\nArguments:\n{\n \"marker\": \"SKILL_DONE\"\n}", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "cache_control": { + "type": "ephemeral" + }, + "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /e2e/scenarios/flue-instrumentation/\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts\n\n\nNever call the task tool. Do not delegate e2e-flue-skill to another session. If you need the skill body, read .agents/skills/e2e-flue-skill/SKILL.md yourself with the read tool. Return the marker from the Arguments object exactly, with no other text.\n", + "type": "text" + } + ], + "role": "system" + } + ], + "metadata": { + "model": "claude-sonnet-4-5-20250929", + "provider": "anthropic" + } + }, + { + "name": "flue.turn", + "type": "llm", + "children": [], + "output": [ + { + "finish_reason": "toolUse", + "index": 0, + "message": { + "content": "I'll run the e2e-flue-skill by reading its instructions and following them.", + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\"path\":\".agents/skills/e2e-flue-skill/SKILL.md\"}", + "name": "read" + }, + "id": "", + "type": "function" + } + ] + } + } + ], + "metadata": { + "flue.model": "claude-sonnet-4-5-20250929", + "flue.session": "skill", + "model": "claude-sonnet-4-5-20250929", + "provider": "flue" + }, + "metrics": { + "completion_tokens": 89, + "duration_ms": 0, + "estimated_cost": 0.0018872999999999997, + "prompt_cache_creation_tokens": 0, + "prompt_cached_tokens": 1811, + "prompt_tokens": 3, + "tokens": 1903 + } + }, + { + "name": "tool: read", + "type": "tool", + "children": [], + "input": { + "path": ".agents/skills/e2e-flue-skill/SKILL.md" + }, + "output": { + "content": [ + { + "text": "---\nname: e2e-flue-skill\ndescription: Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n---\n\nReturn the marker from the provided args exactly once. Output no other text.\n", + "type": "text" + } + ], + "details": { + "lines": 7, + "path": ".agents/skills/e2e-flue-skill/SKILL.md" + } + }, + "metadata": { + "flue.session": "skill", + "flue.tool_name": "read", + "provider": "flue" + }, + "metrics": { + "duration_ms": 0 + } + }, + { + "name": "anthropic.messages.create", + "type": "llm", + "children": [], + "input": [ + { + "content": [ + { + "text": "Run the skill named \"e2e-flue-skill\".\n\nArguments:\n{\n \"marker\": \"SKILL_DONE\"\n}", + "type": "text" + } + ], + "role": "user" + }, + { + "content": [ + { + "text": "I'll run the e2e-flue-skill by reading its instructions and following them.", + "type": "text" + }, + { + "id": "", + "input": { + "path": ".agents/skills/e2e-flue-skill/SKILL.md" + }, + "name": "read", + "type": "tool_use" + } + ], + "role": "assistant" + }, + { + "content": [ + { + "cache_control": { + "type": "ephemeral" + }, + "content": "---\nname: e2e-flue-skill\ndescription: Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n---\n\nReturn the marker from the provided args exactly once. Output no other text.\n", + "is_error": false, + "tool_use_id": "toolu_01M5rfFBDvwquiyfz2B1GNYz", + "type": "tool_result" + } + ], + "role": "user" + }, + { + "content": [ + { + "cache_control": { + "type": "ephemeral" + }, + "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /e2e/scenarios/flue-instrumentation/\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts\n\n\nNever call the task tool. Do not delegate e2e-flue-skill to another session. If you need the skill body, read .agents/skills/e2e-flue-skill/SKILL.md yourself with the read tool. Return the marker from the Arguments object exactly, with no other text.\n", + "type": "text" + } + ], + "role": "system" + } + ], + "metadata": { + "model": "claude-sonnet-4-5-20250929", + "provider": "anthropic" + } + }, + { + "name": "flue.turn", + "type": "llm", + "children": [], + "output": [ + { + "finish_reason": "stop", + "index": 0, + "message": { + "content": "SKILL_DONE", + "role": "assistant" + } + } + ], + "metadata": { + "flue.model": "claude-sonnet-4-5-20250929", + "flue.session": "skill", + "model": "claude-sonnet-4-5-20250929", + "provider": "flue" + }, + "metrics": { + "completion_tokens": 8, + "duration_ms": 0, + "estimated_cost": 0.0007272, + "prompt_cache_creation_tokens": 0, + "prompt_cached_tokens": 1964, + "prompt_tokens": 6, + "tokens": 1978 + } + } + ], + "input": { + "args": { + "marker": "SKILL_DONE" + }, + "name": "e2e-flue-skill" + }, + "output": "SKILL_DONE", + "metadata": { + "flue.model": "claude-sonnet-4-5-20250929", + "flue.operation": "skill", + "flue.role": "skillRunner", + "flue.session": "skill", + "flue.skill_name": "e2e-flue-skill", + "flue.thinking_level": "off", + "model": "claude-sonnet-4-5-20250929", + "provider": "flue" + }, + "metrics": { + "completion_tokens": 97, + "duration_ms": 0, + "estimated_cost": 0.0026144999999999996, + "prompt_cache_creation_tokens": 0, + "prompt_cached_tokens": 3775, + "prompt_tokens": 9, + "tokens": 3881 + } + } + ], + "metadata": { + "operation": "skill" + } + }, + { + "name": "flue-task-operation", + "children": [ + { + "name": "flue.session.task", + "type": "task", + "children": [ + { + "name": "flue.task", + "type": "task", + "children": [], + "input": "Reply with exactly TASK_DONE and no other text.", + "output": "TASK_DONE", + "metadata": { + "flue.session": "task", + "provider": "flue" + }, + "metrics": { + "duration_ms": 0 + } + }, + { + "name": "openai.responses.create", + "type": "llm", + "children": [], + "input": [ + { + "content": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /e2e/scenarios/flue-instrumentation/\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + "role": "system" + }, + { + "content": [ + { + "text": "Reply with exactly TASK_DONE and no other text.", + "type": "input_text" + } + ], + "role": "user" + } + ], + "output": [ + { + "content": [ + { + "annotations": [], + "logprobs": [], + "text": "TASK_DONE", + "type": "output_text" + } + ], + "id": "", + "role": "assistant", + "status": "completed", + "type": "message" + } + ], + "metadata": { + "model": "gpt-4o-mini-2024-07-18", + "provider": "openai" + }, + "metrics": { + "completion_reasoning_tokens": 0, + "completion_tokens": 4, + "prompt_cached_tokens": 0, + "prompt_tokens": 772, + "time_to_first_token": 0, + "tokens": 776 + } + }, + { + "name": "flue.turn", + "type": "llm", + "children": [], + "output": [ + { + "finish_reason": "stop", + "index": 0, + "message": { + "content": "TASK_DONE", + "role": "assistant" + } + } + ], + "metadata": { + "flue.model": "gpt-4o-mini", + "flue.session": "task:task:", + "model": "gpt-4o-mini", + "provider": "flue" + }, + "metrics": { + "completion_tokens": 4, + "duration_ms": 0, + "estimated_cost": 0.0001182, + "prompt_cache_creation_tokens": 0, + "prompt_cached_tokens": 0, + "prompt_tokens": 772, + "tokens": 776 + } + } + ], + "input": "Reply with exactly TASK_DONE and no other text.", + "output": "TASK_DONE", + "metadata": { + "flue.model": "gpt-4o-mini", + "flue.operation": "task", + "flue.session": "task", + "flue.thinking_level": "off", + "model": "gpt-4o-mini", + "provider": "flue" + }, + "metrics": { + "completion_tokens": 4, + "duration_ms": 0, + "estimated_cost": 0.0001182, + "prompt_cache_creation_tokens": 0, + "prompt_cached_tokens": 0, + "prompt_tokens": 772, + "tokens": 776 + } + } + ], + "metadata": { + "operation": "task" + } + }, + { + "name": "flue-compact-operation", + "children": [ + { + "name": "flue.session.compact", + "type": "task", + "children": [ + { + "name": "flue.compaction", + "type": "task", + "children": [], + "input": { + "estimatedTokens": 1141, + "reason": "manual" + }, + "output": { + "messagesAfter": 2, + "messagesBefore": 8 + }, + "metadata": { + "flue.compaction_reason": "manual", + "flue.session": "main", + "provider": "flue" + }, + "metrics": { + "completion_tokens": 0, + "duration_ms": 0, + "estimated_cost": 0, + "prompt_cache_creation_tokens": 0, + "prompt_cached_tokens": 0, + "prompt_tokens": 0, + "tokens": 0 + } + }, + { + "name": "openai.responses.create", + "type": "llm", + "children": [], + "input": [ + { + "content": "You are a context summarization assistant. Your task is to read a conversation between a user and an AI coding assistant, then produce a structured summary following the exact format specified.\n\nDo NOT continue the conversation. Do NOT respond to any questions in the conversation. ONLY output the structured summary.", + "role": "system" + }, + { + "content": [ + { + "text": "\n[User]: Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.\n\n[Assistant tool calls]: lookup(query=\"flue instrumentation\")\n\n[Tool result]: {\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}\n\n[Assistant tool calls]: web_search(lookupId=\"flue-session-2026\", query=\"Braintrust Flue reasoning stream instrumentation\")\n\n[Tool result]: {\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\",\"results\":[{\"title\":\"Flue reasoning stream instrumentation\",\"url\":\"https://example.test/flue/reasoning-streams\"}]}\n\n[Assistant tool calls]: summarize_source(url=\"https://example.test/flue/reasoning-streams\")\n\n[Tool result]: {\"summary\":\"Flue emits reasoning, tool execution, and LLM turn events separately.\",\"url\":\"https://example.test/flue/reasoning-streams\"}\n\n\nThis is the PREFIX of a turn that was too large to keep. The SUFFIX (recent work) is retained.\n\nSummarize the prefix to provide context for the retained suffix:\n\n## Original Request\n[What did the user ask for in this turn?]\n\n## Early Progress\n- [Key decisions and work done in the prefix]\n\n## Context for Suffix\n- [Information needed to understand the retained recent work]\n\nBe concise. Focus on what's needed to understand the kept suffix.", + "type": "input_text" + } + ], + "role": "user" + } + ], + "metadata": { + "model": "gpt-4o-mini", + "provider": "openai" + }, + "metrics": { + "time_to_first_token": 0 + } + } + ], + "metadata": { + "flue.operation": "compact", + "flue.session": "main", + "provider": "flue" + }, + "metrics": { + "duration_ms": 0 + } + } + ], + "metadata": { + "operation": "compact" + } + } + ], + "metadata": { + "scenario": "flue-instrumentation" + } + } + ] +} diff --git a/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-openai-auto-hook.span-tree.txt b/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-openai-auto-hook.span-tree.txt new file mode 100644 index 000000000..55d1342c6 --- /dev/null +++ b/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-openai-auto-hook.span-tree.txt @@ -0,0 +1,834 @@ +span_tree: +└── flue-root [task] + metadata: { + "scenario": "flue-instrumentation" + } + ├── flue-prompt-operation + │ metadata: { + │ "operation": "prompt" + │ } + │ └── flue.session.prompt [task] + │ input: "Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text." + │ output: "PROMPT_DONE" + │ metadata: { + │ "flue.model": "gpt-4o-mini", + │ "flue.operation": "prompt", + │ "flue.session": "main", + │ "flue.thinking_level": "off", + │ "flue.tools_count": 3, + │ "model": "gpt-4o-mini", + │ "provider": "flue" + │ } + │ metrics: { + │ "completion_tokens": 79, + │ "duration_ms": 0, + │ "estimated_cost": 0.00059657, + │ "prompt_cache_creation_tokens": 0, + │ "prompt_cached_tokens": 1024, + │ "prompt_tokens": 3115, + │ "tokens": 4218 + │ } + │ ├── openai.responses.create [llm] + │ │ input: [ + │ │ { + │ │ "content": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /e2e/scenarios/flue-instrumentation/\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + │ │ "role": "system" + │ │ }, + │ │ { + │ │ "content": [ + │ │ { + │ │ "text": "Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.", + │ │ "type": "input_text" + │ │ } + │ │ ], + │ │ "role": "user" + │ │ } + │ │ ] + │ │ output: [ + │ │ { + │ │ "arguments": "{\"query\":\"flue instrumentation\"}", + │ │ "call_id": "call_xELft1kjhTSvPWAp3Z3i4zWk", + │ │ "id": "", + │ │ "name": "lookup", + │ │ "status": "completed", + │ │ "type": "function_call" + │ │ } + │ │ ] + │ │ metadata: { + │ │ "model": "gpt-4o-mini-2024-07-18", + │ │ "provider": "openai" + │ │ } + │ │ metrics: { + │ │ "completion_reasoning_tokens": 0, + │ │ "completion_tokens": 16, + │ │ "prompt_cached_tokens": 0, + │ │ "prompt_tokens": 946, + │ │ "time_to_first_token": 0, + │ │ "tokens": 962 + │ │ } + │ ├── flue.turn [llm] + │ │ output: [ + │ │ { + │ │ "finish_reason": "toolUse", + │ │ "index": 0, + │ │ "message": { + │ │ "content": "", + │ │ "role": "assistant", + │ │ "tool_calls": [ + │ │ { + │ │ "function": { + │ │ "arguments": "{\"query\":\"flue instrumentation\"}", + │ │ "name": "lookup" + │ │ }, + │ │ "id": "", + │ │ "type": "function" + │ │ } + │ │ ] + │ │ } + │ │ } + │ │ ] + │ │ metadata: { + │ │ "flue.model": "gpt-4o-mini", + │ │ "flue.session": "main", + │ │ "model": "gpt-4o-mini", + │ │ "provider": "flue" + │ │ } + │ │ metrics: { + │ │ "completion_tokens": 16, + │ │ "duration_ms": 0, + │ │ "estimated_cost": 0.0001515, + │ │ "prompt_cache_creation_tokens": 0, + │ │ "prompt_cached_tokens": 0, + │ │ "prompt_tokens": 946, + │ │ "tokens": 962 + │ │ } + │ ├── tool: lookup [tool] + │ │ input: { + │ │ "query": "flue instrumentation" + │ │ } + │ │ output: { + │ │ "content": [ + │ │ { + │ │ "text": "{\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}", + │ │ "type": "text" + │ │ } + │ │ ], + │ │ "details": { + │ │ "customTool": "lookup" + │ │ } + │ │ } + │ │ metadata: { + │ │ "flue.session": "main", + │ │ "flue.tool_name": "lookup", + │ │ "provider": "flue" + │ │ } + │ │ metrics: { + │ │ "duration_ms": 0 + │ │ } + │ ├── openai.responses.create [llm] + │ │ input: [ + │ │ { + │ │ "content": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /e2e/scenarios/flue-instrumentation/\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + │ │ "role": "system" + │ │ }, + │ │ { + │ │ "content": [ + │ │ { + │ │ "text": "Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.", + │ │ "type": "input_text" + │ │ } + │ │ ], + │ │ "role": "user" + │ │ }, + │ │ { + │ │ "arguments": "{\"query\":\"flue instrumentation\"}", + │ │ "call_id": "call_xELft1kjhTSvPWAp3Z3i4zWk", + │ │ "id": "", + │ │ "name": "lookup", + │ │ "type": "function_call" + │ │ }, + │ │ { + │ │ "call_id": "call_xELft1kjhTSvPWAp3Z3i4zWk", + │ │ "output": "{\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}", + │ │ "type": "function_call_output" + │ │ } + │ │ ] + │ │ output: [ + │ │ { + │ │ "arguments": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\"}", + │ │ "call_id": "call_F7zI4fCOw4jk7rTwqbi8umo7", + │ │ "id": "", + │ │ "name": "web_search", + │ │ "status": "completed", + │ │ "type": "function_call" + │ │ } + │ │ ] + │ │ metadata: { + │ │ "model": "gpt-4o-mini-2024-07-18", + │ │ "provider": "openai" + │ │ } + │ │ metrics: { + │ │ "completion_reasoning_tokens": 0, + │ │ "completion_tokens": 31, + │ │ "prompt_cached_tokens": 0, + │ │ "prompt_tokens": 987, + │ │ "time_to_first_token": 0, + │ │ "tokens": 1018 + │ │ } + │ ├── flue.turn [llm] + │ │ output: [ + │ │ { + │ │ "finish_reason": "toolUse", + │ │ "index": 0, + │ │ "message": { + │ │ "content": "", + │ │ "role": "assistant", + │ │ "tool_calls": [ + │ │ { + │ │ "function": { + │ │ "arguments": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\"}", + │ │ "name": "web_search" + │ │ }, + │ │ "id": "", + │ │ "type": "function" + │ │ } + │ │ ] + │ │ } + │ │ } + │ │ ] + │ │ metadata: { + │ │ "flue.model": "gpt-4o-mini", + │ │ "flue.session": "main", + │ │ "model": "gpt-4o-mini", + │ │ "provider": "flue" + │ │ } + │ │ metrics: { + │ │ "completion_tokens": 31, + │ │ "duration_ms": 0, + │ │ "estimated_cost": 0.00016664999999999998, + │ │ "prompt_cache_creation_tokens": 0, + │ │ "prompt_cached_tokens": 0, + │ │ "prompt_tokens": 987, + │ │ "tokens": 1018 + │ │ } + │ ├── tool: web_search [tool] + │ │ input: { + │ │ "lookupId": "flue-session-2026", + │ │ "query": "Braintrust Flue reasoning stream instrumentation" + │ │ } + │ │ output: { + │ │ "content": [ + │ │ { + │ │ "text": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\",\"results\":[{\"title\":\"Flue reasoning stream instrumentation\",\"url\":\"https://example.test/flue/reasoning-streams\"}]}", + │ │ "type": "text" + │ │ } + │ │ ], + │ │ "details": { + │ │ "customTool": "web_search" + │ │ } + │ │ } + │ │ metadata: { + │ │ "flue.session": "main", + │ │ "flue.tool_name": "web_search", + │ │ "provider": "flue" + │ │ } + │ │ metrics: { + │ │ "duration_ms": 0 + │ │ } + │ ├── openai.responses.create [llm] + │ │ input: [ + │ │ { + │ │ "content": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /e2e/scenarios/flue-instrumentation/\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + │ │ "role": "system" + │ │ }, + │ │ { + │ │ "content": [ + │ │ { + │ │ "text": "Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.", + │ │ "type": "input_text" + │ │ } + │ │ ], + │ │ "role": "user" + │ │ }, + │ │ { + │ │ "arguments": "{\"query\":\"flue instrumentation\"}", + │ │ "call_id": "call_xELft1kjhTSvPWAp3Z3i4zWk", + │ │ "id": "", + │ │ "name": "lookup", + │ │ "type": "function_call" + │ │ }, + │ │ { + │ │ "call_id": "call_xELft1kjhTSvPWAp3Z3i4zWk", + │ │ "output": "{\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}", + │ │ "type": "function_call_output" + │ │ }, + │ │ { + │ │ "arguments": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\"}", + │ │ "call_id": "call_F7zI4fCOw4jk7rTwqbi8umo7", + │ │ "id": "", + │ │ "name": "web_search", + │ │ "type": "function_call" + │ │ }, + │ │ { + │ │ "call_id": "call_F7zI4fCOw4jk7rTwqbi8umo7", + │ │ "output": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\",\"results\":[{\"title\":\"Flue reasoning stream instrumentation\",\"url\":\"https://example.test/flue/reasoning-streams\"}]}", + │ │ "type": "function_call_output" + │ │ } + │ │ ] + │ │ output: [ + │ │ { + │ │ "arguments": "{\"url\":\"https://example.test/flue/reasoning-streams\"}", + │ │ "call_id": "call_0yinp9edeamv8mKgyhkpaCmG", + │ │ "id": "", + │ │ "name": "summarize_source", + │ │ "status": "completed", + │ │ "type": "function_call" + │ │ } + │ │ ] + │ │ metadata: { + │ │ "model": "gpt-4o-mini-2024-07-18", + │ │ "provider": "openai" + │ │ } + │ │ metrics: { + │ │ "completion_reasoning_tokens": 0, + │ │ "completion_tokens": 27, + │ │ "prompt_cached_tokens": 0, + │ │ "prompt_tokens": 1070, + │ │ "time_to_first_token": 0, + │ │ "tokens": 1097 + │ │ } + │ ├── flue.turn [llm] + │ │ output: [ + │ │ { + │ │ "finish_reason": "toolUse", + │ │ "index": 0, + │ │ "message": { + │ │ "content": "", + │ │ "role": "assistant", + │ │ "tool_calls": [ + │ │ { + │ │ "function": { + │ │ "arguments": "{\"url\":\"https://example.test/flue/reasoning-streams\"}", + │ │ "name": "summarize_source" + │ │ }, + │ │ "id": "", + │ │ "type": "function" + │ │ } + │ │ ] + │ │ } + │ │ } + │ │ ] + │ │ metadata: { + │ │ "flue.model": "gpt-4o-mini", + │ │ "flue.session": "main", + │ │ "model": "gpt-4o-mini", + │ │ "provider": "flue" + │ │ } + │ │ metrics: { + │ │ "completion_tokens": 27, + │ │ "duration_ms": 0, + │ │ "estimated_cost": 0.0001767, + │ │ "prompt_cache_creation_tokens": 0, + │ │ "prompt_cached_tokens": 0, + │ │ "prompt_tokens": 1070, + │ │ "tokens": 1097 + │ │ } + │ ├── tool: summarize_source [tool] + │ │ input: { + │ │ "url": "https://example.test/flue/reasoning-streams" + │ │ } + │ │ output: { + │ │ "content": [ + │ │ { + │ │ "text": "{\"summary\":\"Flue emits reasoning, tool execution, and LLM turn events separately.\",\"url\":\"https://example.test/flue/reasoning-streams\"}", + │ │ "type": "text" + │ │ } + │ │ ], + │ │ "details": { + │ │ "customTool": "summarize_source" + │ │ } + │ │ } + │ │ metadata: { + │ │ "flue.session": "main", + │ │ "flue.tool_name": "summarize_source", + │ │ "provider": "flue" + │ │ } + │ │ metrics: { + │ │ "duration_ms": 0 + │ │ } + │ ├── openai.responses.create [llm] + │ │ input: [ + │ │ { + │ │ "content": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /e2e/scenarios/flue-instrumentation/\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + │ │ "role": "system" + │ │ }, + │ │ { + │ │ "content": [ + │ │ { + │ │ "text": "Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.", + │ │ "type": "input_text" + │ │ } + │ │ ], + │ │ "role": "user" + │ │ }, + │ │ { + │ │ "arguments": "{\"query\":\"flue instrumentation\"}", + │ │ "call_id": "call_xELft1kjhTSvPWAp3Z3i4zWk", + │ │ "id": "", + │ │ "name": "lookup", + │ │ "type": "function_call" + │ │ }, + │ │ { + │ │ "call_id": "call_xELft1kjhTSvPWAp3Z3i4zWk", + │ │ "output": "{\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}", + │ │ "type": "function_call_output" + │ │ }, + │ │ { + │ │ "arguments": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\"}", + │ │ "call_id": "call_F7zI4fCOw4jk7rTwqbi8umo7", + │ │ "id": "", + │ │ "name": "web_search", + │ │ "type": "function_call" + │ │ }, + │ │ { + │ │ "call_id": "call_F7zI4fCOw4jk7rTwqbi8umo7", + │ │ "output": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\",\"results\":[{\"title\":\"Flue reasoning stream instrumentation\",\"url\":\"https://example.test/flue/reasoning-streams\"}]}", + │ │ "type": "function_call_output" + │ │ }, + │ │ { + │ │ "arguments": "{\"url\":\"https://example.test/flue/reasoning-streams\"}", + │ │ "call_id": "call_0yinp9edeamv8mKgyhkpaCmG", + │ │ "id": "", + │ │ "name": "summarize_source", + │ │ "type": "function_call" + │ │ }, + │ │ { + │ │ "call_id": "call_0yinp9edeamv8mKgyhkpaCmG", + │ │ "output": "{\"summary\":\"Flue emits reasoning, tool execution, and LLM turn events separately.\",\"url\":\"https://example.test/flue/reasoning-streams\"}", + │ │ "type": "function_call_output" + │ │ } + │ │ ] + │ │ output: [ + │ │ { + │ │ "content": [ + │ │ { + │ │ "annotations": [], + │ │ "logprobs": [], + │ │ "text": "PROMPT_DONE", + │ │ "type": "output_text" + │ │ } + │ │ ], + │ │ "id": "", + │ │ "role": "assistant", + │ │ "status": "completed", + │ │ "type": "message" + │ │ } + │ │ ] + │ │ metadata: { + │ │ "model": "gpt-4o-mini-2024-07-18", + │ │ "provider": "openai" + │ │ } + │ │ metrics: { + │ │ "completion_reasoning_tokens": 0, + │ │ "completion_tokens": 5, + │ │ "prompt_cached_tokens": 1024, + │ │ "prompt_tokens": 1136, + │ │ "time_to_first_token": 0, + │ │ "tokens": 1141 + │ │ } + │ └── flue.turn [llm] + │ output: [ + │ { + │ "finish_reason": "stop", + │ "index": 0, + │ "message": { + │ "content": "PROMPT_DONE", + │ "role": "assistant" + │ } + │ } + │ ] + │ metadata: { + │ "flue.model": "gpt-4o-mini", + │ "flue.session": "main", + │ "model": "gpt-4o-mini", + │ "provider": "flue" + │ } + │ metrics: { + │ "completion_tokens": 5, + │ "duration_ms": 0, + │ "estimated_cost": 0.00010172, + │ "prompt_cache_creation_tokens": 0, + │ "prompt_cached_tokens": 1024, + │ "prompt_tokens": 112, + │ "tokens": 1141 + │ } + ├── flue-skill-operation + │ metadata: { + │ "operation": "skill" + │ } + │ └── flue.session.skill [task] + │ input: { + │ "args": { + │ "marker": "SKILL_DONE" + │ }, + │ "name": "e2e-flue-skill" + │ } + │ output: "SKILL_DONE" + │ metadata: { + │ "flue.model": "claude-sonnet-4-5-20250929", + │ "flue.operation": "skill", + │ "flue.role": "skillRunner", + │ "flue.session": "skill", + │ "flue.skill_name": "e2e-flue-skill", + │ "flue.thinking_level": "off", + │ "model": "claude-sonnet-4-5-20250929", + │ "provider": "flue" + │ } + │ metrics: { + │ "completion_tokens": 97, + │ "duration_ms": 0, + │ "estimated_cost": 0.0026144999999999996, + │ "prompt_cache_creation_tokens": 0, + │ "prompt_cached_tokens": 3775, + │ "prompt_tokens": 9, + │ "tokens": 3881 + │ } + │ ├── anthropic.messages.create [llm] + │ │ input: [ + │ │ { + │ │ "content": [ + │ │ { + │ │ "cache_control": { + │ │ "type": "ephemeral" + │ │ }, + │ │ "text": "Run the skill named \"e2e-flue-skill\".\n\nArguments:\n{\n \"marker\": \"SKILL_DONE\"\n}", + │ │ "type": "text" + │ │ } + │ │ ], + │ │ "role": "user" + │ │ }, + │ │ { + │ │ "content": [ + │ │ { + │ │ "cache_control": { + │ │ "type": "ephemeral" + │ │ }, + │ │ "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /e2e/scenarios/flue-instrumentation/\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts\n\n\nNever call the task tool. Do not delegate e2e-flue-skill to another session. If you need the skill body, read .agents/skills/e2e-flue-skill/SKILL.md yourself with the read tool. Return the marker from the Arguments object exactly, with no other text.\n", + │ │ "type": "text" + │ │ } + │ │ ], + │ │ "role": "system" + │ │ } + │ │ ] + │ │ metadata: { + │ │ "model": "claude-sonnet-4-5-20250929", + │ │ "provider": "anthropic" + │ │ } + │ ├── flue.turn [llm] + │ │ output: [ + │ │ { + │ │ "finish_reason": "toolUse", + │ │ "index": 0, + │ │ "message": { + │ │ "content": "I'll run the e2e-flue-skill by reading its instructions and following them.", + │ │ "role": "assistant", + │ │ "tool_calls": [ + │ │ { + │ │ "function": { + │ │ "arguments": "{\"path\":\".agents/skills/e2e-flue-skill/SKILL.md\"}", + │ │ "name": "read" + │ │ }, + │ │ "id": "", + │ │ "type": "function" + │ │ } + │ │ ] + │ │ } + │ │ } + │ │ ] + │ │ metadata: { + │ │ "flue.model": "claude-sonnet-4-5-20250929", + │ │ "flue.session": "skill", + │ │ "model": "claude-sonnet-4-5-20250929", + │ │ "provider": "flue" + │ │ } + │ │ metrics: { + │ │ "completion_tokens": 89, + │ │ "duration_ms": 0, + │ │ "estimated_cost": 0.0018872999999999997, + │ │ "prompt_cache_creation_tokens": 0, + │ │ "prompt_cached_tokens": 1811, + │ │ "prompt_tokens": 3, + │ │ "tokens": 1903 + │ │ } + │ ├── tool: read [tool] + │ │ input: { + │ │ "path": ".agents/skills/e2e-flue-skill/SKILL.md" + │ │ } + │ │ output: { + │ │ "content": [ + │ │ { + │ │ "text": "---\nname: e2e-flue-skill\ndescription: Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n---\n\nReturn the marker from the provided args exactly once. Output no other text.\n", + │ │ "type": "text" + │ │ } + │ │ ], + │ │ "details": { + │ │ "lines": 7, + │ │ "path": ".agents/skills/e2e-flue-skill/SKILL.md" + │ │ } + │ │ } + │ │ metadata: { + │ │ "flue.session": "skill", + │ │ "flue.tool_name": "read", + │ │ "provider": "flue" + │ │ } + │ │ metrics: { + │ │ "duration_ms": 0 + │ │ } + │ ├── anthropic.messages.create [llm] + │ │ input: [ + │ │ { + │ │ "content": [ + │ │ { + │ │ "text": "Run the skill named \"e2e-flue-skill\".\n\nArguments:\n{\n \"marker\": \"SKILL_DONE\"\n}", + │ │ "type": "text" + │ │ } + │ │ ], + │ │ "role": "user" + │ │ }, + │ │ { + │ │ "content": [ + │ │ { + │ │ "text": "I'll run the e2e-flue-skill by reading its instructions and following them.", + │ │ "type": "text" + │ │ }, + │ │ { + │ │ "id": "", + │ │ "input": { + │ │ "path": ".agents/skills/e2e-flue-skill/SKILL.md" + │ │ }, + │ │ "name": "read", + │ │ "type": "tool_use" + │ │ } + │ │ ], + │ │ "role": "assistant" + │ │ }, + │ │ { + │ │ "content": [ + │ │ { + │ │ "cache_control": { + │ │ "type": "ephemeral" + │ │ }, + │ │ "content": "---\nname: e2e-flue-skill\ndescription: Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n---\n\nReturn the marker from the provided args exactly once. Output no other text.\n", + │ │ "is_error": false, + │ │ "tool_use_id": "toolu_01M5rfFBDvwquiyfz2B1GNYz", + │ │ "type": "tool_result" + │ │ } + │ │ ], + │ │ "role": "user" + │ │ }, + │ │ { + │ │ "content": [ + │ │ { + │ │ "cache_control": { + │ │ "type": "ephemeral" + │ │ }, + │ │ "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /e2e/scenarios/flue-instrumentation/\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts\n\n\nNever call the task tool. Do not delegate e2e-flue-skill to another session. If you need the skill body, read .agents/skills/e2e-flue-skill/SKILL.md yourself with the read tool. Return the marker from the Arguments object exactly, with no other text.\n", + │ │ "type": "text" + │ │ } + │ │ ], + │ │ "role": "system" + │ │ } + │ │ ] + │ │ metadata: { + │ │ "model": "claude-sonnet-4-5-20250929", + │ │ "provider": "anthropic" + │ │ } + │ └── flue.turn [llm] + │ output: [ + │ { + │ "finish_reason": "stop", + │ "index": 0, + │ "message": { + │ "content": "SKILL_DONE", + │ "role": "assistant" + │ } + │ } + │ ] + │ metadata: { + │ "flue.model": "claude-sonnet-4-5-20250929", + │ "flue.session": "skill", + │ "model": "claude-sonnet-4-5-20250929", + │ "provider": "flue" + │ } + │ metrics: { + │ "completion_tokens": 8, + │ "duration_ms": 0, + │ "estimated_cost": 0.0007272, + │ "prompt_cache_creation_tokens": 0, + │ "prompt_cached_tokens": 1964, + │ "prompt_tokens": 6, + │ "tokens": 1978 + │ } + ├── flue-task-operation + │ metadata: { + │ "operation": "task" + │ } + │ └── flue.session.task [task] + │ input: "Reply with exactly TASK_DONE and no other text." + │ output: "TASK_DONE" + │ metadata: { + │ "flue.model": "gpt-4o-mini", + │ "flue.operation": "task", + │ "flue.session": "task", + │ "flue.thinking_level": "off", + │ "model": "gpt-4o-mini", + │ "provider": "flue" + │ } + │ metrics: { + │ "completion_tokens": 4, + │ "duration_ms": 0, + │ "estimated_cost": 0.0001182, + │ "prompt_cache_creation_tokens": 0, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 772, + │ "tokens": 776 + │ } + │ ├── flue.task [task] + │ │ input: "Reply with exactly TASK_DONE and no other text." + │ │ output: "TASK_DONE" + │ │ metadata: { + │ │ "flue.session": "task", + │ │ "provider": "flue" + │ │ } + │ │ metrics: { + │ │ "duration_ms": 0 + │ │ } + │ ├── openai.responses.create [llm] + │ │ input: [ + │ │ { + │ │ "content": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /e2e/scenarios/flue-instrumentation/\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + │ │ "role": "system" + │ │ }, + │ │ { + │ │ "content": [ + │ │ { + │ │ "text": "Reply with exactly TASK_DONE and no other text.", + │ │ "type": "input_text" + │ │ } + │ │ ], + │ │ "role": "user" + │ │ } + │ │ ] + │ │ output: [ + │ │ { + │ │ "content": [ + │ │ { + │ │ "annotations": [], + │ │ "logprobs": [], + │ │ "text": "TASK_DONE", + │ │ "type": "output_text" + │ │ } + │ │ ], + │ │ "id": "", + │ │ "role": "assistant", + │ │ "status": "completed", + │ │ "type": "message" + │ │ } + │ │ ] + │ │ metadata: { + │ │ "model": "gpt-4o-mini-2024-07-18", + │ │ "provider": "openai" + │ │ } + │ │ metrics: { + │ │ "completion_reasoning_tokens": 0, + │ │ "completion_tokens": 4, + │ │ "prompt_cached_tokens": 0, + │ │ "prompt_tokens": 772, + │ │ "time_to_first_token": 0, + │ │ "tokens": 776 + │ │ } + │ └── flue.turn [llm] + │ output: [ + │ { + │ "finish_reason": "stop", + │ "index": 0, + │ "message": { + │ "content": "TASK_DONE", + │ "role": "assistant" + │ } + │ } + │ ] + │ metadata: { + │ "flue.model": "gpt-4o-mini", + │ "flue.session": "task:task:", + │ "model": "gpt-4o-mini", + │ "provider": "flue" + │ } + │ metrics: { + │ "completion_tokens": 4, + │ "duration_ms": 0, + │ "estimated_cost": 0.0001182, + │ "prompt_cache_creation_tokens": 0, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 772, + │ "tokens": 776 + │ } + └── flue-compact-operation + metadata: { + "operation": "compact" + } + └── flue.session.compact [task] + metadata: { + "flue.operation": "compact", + "flue.session": "main", + "provider": "flue" + } + metrics: { + "duration_ms": 0 + } + ├── flue.compaction [task] + │ input: { + │ "estimatedTokens": 1141, + │ "reason": "manual" + │ } + │ output: { + │ "messagesAfter": 2, + │ "messagesBefore": 8 + │ } + │ metadata: { + │ "flue.compaction_reason": "manual", + │ "flue.session": "main", + │ "provider": "flue" + │ } + │ metrics: { + │ "completion_tokens": 0, + │ "duration_ms": 0, + │ "estimated_cost": 0, + │ "prompt_cache_creation_tokens": 0, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 0, + │ "tokens": 0 + │ } + └── openai.responses.create [llm] + input: [ + { + "content": "You are a context summarization assistant. Your task is to read a conversation between a user and an AI coding assistant, then produce a structured summary following the exact format specified.\n\nDo NOT continue the conversation. Do NOT respond to any questions in the conversation. ONLY output the structured summary.", + "role": "system" + }, + { + "content": [ + { + "text": "\n[User]: Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.\n\n[Assistant tool calls]: lookup(query=\"flue instrumentation\")\n\n[Tool result]: {\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}\n\n[Assistant tool calls]: web_search(lookupId=\"flue-session-2026\", query=\"Braintrust Flue reasoning stream instrumentation\")\n\n[Tool result]: {\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\",\"results\":[{\"title\":\"Flue reasoning stream instrumentation\",\"url\":\"https://example.test/flue/reasoning-streams\"}]}\n\n[Assistant tool calls]: summarize_source(url=\"https://example.test/flue/reasoning-streams\")\n\n[Tool result]: {\"summary\":\"Flue emits reasoning, tool execution, and LLM turn events separately.\",\"url\":\"https://example.test/flue/reasoning-streams\"}\n\n\nThis is the PREFIX of a turn that was too large to keep. The SUFFIX (recent work) is retained.\n\nSummarize the prefix to provide context for the retained suffix:\n\n## Original Request\n[What did the user ask for in this turn?]\n\n## Early Progress\n- [Key decisions and work done in the prefix]\n\n## Context for Suffix\n- [Information needed to understand the retained recent work]\n\nBe concise. Focus on what's needed to understand the kept suffix.", + "type": "input_text" + } + ], + "role": "user" + } + ] + metadata: { + "model": "gpt-4o-mini", + "provider": "openai" + } + metrics: { + "time_to_first_token": 0 + } diff --git a/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-wrapped.span-tree.json b/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-wrapped.span-tree.json index 241cd79aa..1ce6af8fb 100644 --- a/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-wrapped.span-tree.json +++ b/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-wrapped.span-tree.json @@ -21,7 +21,7 @@ "index": 0, "message": { "content": "I'll complete this instrumented research flow step by step. Starting with Step 1:", - "reasoning": "The user wants me to complete an instrumented research flow with exactly three steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id to call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url to call summarize_source\n4. After that, reply with exactly \"PROMPT_DONE\"\n\nThe user also emphasizes that I should call exactly one tool per turn and wait for each tool result before choosing the next tool.\n\nLet me start with Step 1: calling lookup with query \"flue instrumentation\".", + "reasoning": "The user wants me to complete an instrumented research flow with specific steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id to call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url to call summarize_source\n4. After summarize_source returns, reply with exactly \"PROMPT_DONE\"\n\nI need to call exactly one tool per turn and wait for each result. Let me start with step 1.", "role": "assistant", "tool_calls": [ { @@ -44,13 +44,13 @@ "provider": "flue" }, "metrics": { - "completion_tokens": 217, + "completion_tokens": 198, "duration_ms": 0, - "estimated_cost": 0.00699285, - "prompt_cache_creation_tokens": 885, + "estimated_cost": 0.00671535, + "prompt_cache_creation_tokens": 887, "prompt_cached_tokens": 1297, "prompt_tokens": 10, - "tokens": 2409 + "tokens": 2392 } }, { @@ -89,8 +89,8 @@ "finish_reason": "toolUse", "index": 0, "message": { - "content": "Now proceeding to Step 2:", - "reasoning": "Good, I got the lookup result with id \"flue-session-2026\". Now I need to proceed to Step 2: call web_search using this lookupId and the query \"Braintrust Flue reasoning stream instrumentation\".", + "content": "Now proceeding to Step 2 with the lookup ID:", + "reasoning": "Good, I got the lookup result with id \"flue-session-2026\". Now I need to proceed to Step 2 and use this id as the lookupId parameter when calling web_search with the query \"Braintrust Flue reasoning stream instrumentation\".", "role": "assistant", "tool_calls": [ { @@ -113,13 +113,13 @@ "provider": "flue" }, "metrics": { - "completion_tokens": 158, + "completion_tokens": 169, "duration_ms": 0, - "estimated_cost": 0.00402735, - "prompt_cache_creation_tokens": 257, - "prompt_cached_tokens": 2182, + "estimated_cost": 0.0041217, + "prompt_cache_creation_tokens": 238, + "prompt_cached_tokens": 2184, "prompt_tokens": 13, - "tokens": 2610 + "tokens": 2604 } }, { @@ -159,8 +159,8 @@ "finish_reason": "toolUse", "index": 0, "message": { - "content": "Now proceeding to Step 3:", - "reasoning": "Perfect! I got the web_search results. There's one result with the URL \"https://example.test/flue/reasoning-streams\". Now I need to proceed to Step 3: call summarize_source with this URL.", + "content": "Now proceeding to Step 3 with the first result URL:", + "reasoning": "Perfect! I got the web_search results. There's one result with the URL \"https://example.test/flue/reasoning-streams\". Now I need to proceed to Step 3 and call summarize_source with this URL.", "role": "assistant", "tool_calls": [ { @@ -183,13 +183,13 @@ "provider": "flue" }, "metrics": { - "completion_tokens": 132, + "completion_tokens": 139, "duration_ms": 0, - "estimated_cost": 0.0036282, - "prompt_cache_creation_tokens": 234, - "prompt_cached_tokens": 2439, + "estimated_cost": 0.00376935, + "prompt_cache_creation_tokens": 245, + "prompt_cached_tokens": 2422, "prompt_tokens": 13, - "tokens": 2818 + "tokens": 2819 } }, { @@ -229,7 +229,7 @@ "index": 0, "message": { "content": "PROMPT_DONE", - "reasoning": "Great! The summarize_source call has completed successfully. According to the instructions, I should now reply with exactly \"PROMPT_DONE\" and no other text.", + "reasoning": "The summarize_source call has returned successfully. According to the instructions, I now need to reply with exactly \"PROMPT_DONE\" and no other text.", "role": "assistant" } } @@ -242,11 +242,11 @@ "provider": "flue" }, "metrics": { - "completion_tokens": 51, + "completion_tokens": 50, "duration_ms": 0, - "estimated_cost": 0.0023109, - "prompt_cache_creation_tokens": 188, - "prompt_cached_tokens": 2673, + "estimated_cost": 0.00232035, + "prompt_cache_creation_tokens": 195, + "prompt_cached_tokens": 2667, "prompt_tokens": 13, "tokens": 2925 } @@ -264,13 +264,13 @@ "provider": "flue" }, "metrics": { - "completion_tokens": 558, + "completion_tokens": 556, "duration_ms": 0, - "estimated_cost": 0.0169593, - "prompt_cache_creation_tokens": 1564, - "prompt_cached_tokens": 8591, + "estimated_cost": 0.01692675, + "prompt_cache_creation_tokens": 1565, + "prompt_cached_tokens": 8570, "prompt_tokens": 49, - "tokens": 10762 + "tokens": 10740 } } ], @@ -318,11 +318,11 @@ "metrics": { "completion_tokens": 89, "duration_ms": 0, - "estimated_cost": 0.0043569, - "prompt_cache_creation_tokens": 716, + "estimated_cost": 0.0043644, + "prompt_cache_creation_tokens": 718, "prompt_cached_tokens": 1093, "prompt_tokens": 3, - "tokens": 1901 + "tokens": 1903 } }, { @@ -376,11 +376,11 @@ "metrics": { "completion_tokens": 8, "duration_ms": 0, - "estimated_cost": 0.00125445, + "estimated_cost": 0.00125505, "prompt_cache_creation_tokens": 153, - "prompt_cached_tokens": 1809, + "prompt_cached_tokens": 1811, "prompt_tokens": 6, - "tokens": 1976 + "tokens": 1978 } } ], @@ -404,11 +404,11 @@ "metrics": { "completion_tokens": 97, "duration_ms": 0, - "estimated_cost": 0.00561135, - "prompt_cache_creation_tokens": 869, - "prompt_cached_tokens": 2902, + "estimated_cost": 0.00561945, + "prompt_cache_creation_tokens": 871, + "prompt_cached_tokens": 2904, "prompt_tokens": 9, - "tokens": 3877 + "tokens": 3881 } } ], @@ -426,38 +426,7 @@ { "name": "flue.task", "type": "task", - "children": [ - { - "name": "flue.turn", - "type": "llm", - "children": [], - "output": [ - { - "finish_reason": "stop", - "index": 0, - "message": { - "content": "TASK_DONE", - "role": "assistant" - } - } - ], - "metadata": { - "flue.model": "gpt-4o-mini", - "flue.session": "task:task:", - "model": "gpt-4o-mini", - "provider": "flue" - }, - "metrics": { - "completion_tokens": 4, - "duration_ms": 0, - "estimated_cost": 0.00011789999999999999, - "prompt_cache_creation_tokens": 0, - "prompt_cached_tokens": 0, - "prompt_tokens": 770, - "tokens": 774 - } - } - ], + "children": [], "input": "Reply with exactly TASK_DONE and no other text.", "output": "TASK_DONE", "metadata": { @@ -467,6 +436,36 @@ "metrics": { "duration_ms": 0 } + }, + { + "name": "flue.turn", + "type": "llm", + "children": [], + "output": [ + { + "finish_reason": "stop", + "index": 0, + "message": { + "content": "TASK_DONE", + "role": "assistant" + } + } + ], + "metadata": { + "flue.model": "gpt-4o-mini", + "flue.session": "task:task:", + "model": "gpt-4o-mini", + "provider": "flue" + }, + "metrics": { + "completion_tokens": 4, + "duration_ms": 0, + "estimated_cost": 0.0001182, + "prompt_cache_creation_tokens": 0, + "prompt_cached_tokens": 0, + "prompt_tokens": 772, + "tokens": 776 + } } ], "input": "Reply with exactly TASK_DONE and no other text.", @@ -482,11 +481,11 @@ "metrics": { "completion_tokens": 4, "duration_ms": 0, - "estimated_cost": 0.00011789999999999999, + "estimated_cost": 0.0001182, "prompt_cache_creation_tokens": 0, "prompt_cached_tokens": 0, - "prompt_tokens": 770, - "tokens": 774 + "prompt_tokens": 772, + "tokens": 776 } } ], diff --git a/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-wrapped.span-tree.txt b/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-wrapped.span-tree.txt index 0bbfd3d1b..2fd3e69cd 100644 --- a/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-wrapped.span-tree.txt +++ b/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-wrapped.span-tree.txt @@ -20,13 +20,13 @@ span_tree: │ "provider": "flue" │ } │ metrics: { - │ "completion_tokens": 558, + │ "completion_tokens": 556, │ "duration_ms": 0, - │ "estimated_cost": 0.0169593, - │ "prompt_cache_creation_tokens": 1564, - │ "prompt_cached_tokens": 8591, + │ "estimated_cost": 0.01692675, + │ "prompt_cache_creation_tokens": 1565, + │ "prompt_cached_tokens": 8570, │ "prompt_tokens": 49, - │ "tokens": 10762 + │ "tokens": 10740 │ } │ ├── flue.turn [llm] │ │ output: [ @@ -35,7 +35,7 @@ span_tree: │ │ "index": 0, │ │ "message": { │ │ "content": "I'll complete this instrumented research flow step by step. Starting with Step 1:", - │ │ "reasoning": "The user wants me to complete an instrumented research flow with exactly three steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id to call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url to call summarize_source\n4. After that, reply with exactly \"PROMPT_DONE\"\n\nThe user also emphasizes that I should call exactly one tool per turn and wait for each tool result before choosing the next tool.\n\nLet me start with Step 1: calling lookup with query \"flue instrumentation\".", + │ │ "reasoning": "The user wants me to complete an instrumented research flow with specific steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id to call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url to call summarize_source\n4. After summarize_source returns, reply with exactly \"PROMPT_DONE\"\n\nI need to call exactly one tool per turn and wait for each result. Let me start with step 1.", │ │ "role": "assistant", │ │ "tool_calls": [ │ │ { @@ -58,13 +58,13 @@ span_tree: │ │ "provider": "flue" │ │ } │ │ metrics: { - │ │ "completion_tokens": 217, + │ │ "completion_tokens": 198, │ │ "duration_ms": 0, - │ │ "estimated_cost": 0.00699285, - │ │ "prompt_cache_creation_tokens": 885, + │ │ "estimated_cost": 0.00671535, + │ │ "prompt_cache_creation_tokens": 887, │ │ "prompt_cached_tokens": 1297, │ │ "prompt_tokens": 10, - │ │ "tokens": 2409 + │ │ "tokens": 2392 │ │ } │ ├── tool: lookup [tool] │ │ input: { @@ -95,8 +95,8 @@ span_tree: │ │ "finish_reason": "toolUse", │ │ "index": 0, │ │ "message": { - │ │ "content": "Now proceeding to Step 2:", - │ │ "reasoning": "Good, I got the lookup result with id \"flue-session-2026\". Now I need to proceed to Step 2: call web_search using this lookupId and the query \"Braintrust Flue reasoning stream instrumentation\".", + │ │ "content": "Now proceeding to Step 2 with the lookup ID:", + │ │ "reasoning": "Good, I got the lookup result with id \"flue-session-2026\". Now I need to proceed to Step 2 and use this id as the lookupId parameter when calling web_search with the query \"Braintrust Flue reasoning stream instrumentation\".", │ │ "role": "assistant", │ │ "tool_calls": [ │ │ { @@ -119,13 +119,13 @@ span_tree: │ │ "provider": "flue" │ │ } │ │ metrics: { - │ │ "completion_tokens": 158, + │ │ "completion_tokens": 169, │ │ "duration_ms": 0, - │ │ "estimated_cost": 0.00402735, - │ │ "prompt_cache_creation_tokens": 257, - │ │ "prompt_cached_tokens": 2182, + │ │ "estimated_cost": 0.0041217, + │ │ "prompt_cache_creation_tokens": 238, + │ │ "prompt_cached_tokens": 2184, │ │ "prompt_tokens": 13, - │ │ "tokens": 2610 + │ │ "tokens": 2604 │ │ } │ ├── tool: web_search [tool] │ │ input: { @@ -157,8 +157,8 @@ span_tree: │ │ "finish_reason": "toolUse", │ │ "index": 0, │ │ "message": { - │ │ "content": "Now proceeding to Step 3:", - │ │ "reasoning": "Perfect! I got the web_search results. There's one result with the URL \"https://example.test/flue/reasoning-streams\". Now I need to proceed to Step 3: call summarize_source with this URL.", + │ │ "content": "Now proceeding to Step 3 with the first result URL:", + │ │ "reasoning": "Perfect! I got the web_search results. There's one result with the URL \"https://example.test/flue/reasoning-streams\". Now I need to proceed to Step 3 and call summarize_source with this URL.", │ │ "role": "assistant", │ │ "tool_calls": [ │ │ { @@ -181,13 +181,13 @@ span_tree: │ │ "provider": "flue" │ │ } │ │ metrics: { - │ │ "completion_tokens": 132, + │ │ "completion_tokens": 139, │ │ "duration_ms": 0, - │ │ "estimated_cost": 0.0036282, - │ │ "prompt_cache_creation_tokens": 234, - │ │ "prompt_cached_tokens": 2439, + │ │ "estimated_cost": 0.00376935, + │ │ "prompt_cache_creation_tokens": 245, + │ │ "prompt_cached_tokens": 2422, │ │ "prompt_tokens": 13, - │ │ "tokens": 2818 + │ │ "tokens": 2819 │ │ } │ ├── tool: summarize_source [tool] │ │ input: { @@ -219,7 +219,7 @@ span_tree: │ "index": 0, │ "message": { │ "content": "PROMPT_DONE", - │ "reasoning": "Great! The summarize_source call has completed successfully. According to the instructions, I should now reply with exactly \"PROMPT_DONE\" and no other text.", + │ "reasoning": "The summarize_source call has returned successfully. According to the instructions, I now need to reply with exactly \"PROMPT_DONE\" and no other text.", │ "role": "assistant" │ } │ } @@ -232,11 +232,11 @@ span_tree: │ "provider": "flue" │ } │ metrics: { - │ "completion_tokens": 51, + │ "completion_tokens": 50, │ "duration_ms": 0, - │ "estimated_cost": 0.0023109, - │ "prompt_cache_creation_tokens": 188, - │ "prompt_cached_tokens": 2673, + │ "estimated_cost": 0.00232035, + │ "prompt_cache_creation_tokens": 195, + │ "prompt_cached_tokens": 2667, │ "prompt_tokens": 13, │ "tokens": 2925 │ } @@ -265,11 +265,11 @@ span_tree: │ metrics: { │ "completion_tokens": 97, │ "duration_ms": 0, - │ "estimated_cost": 0.00561135, - │ "prompt_cache_creation_tokens": 869, - │ "prompt_cached_tokens": 2902, + │ "estimated_cost": 0.00561945, + │ "prompt_cache_creation_tokens": 871, + │ "prompt_cached_tokens": 2904, │ "prompt_tokens": 9, - │ "tokens": 3877 + │ "tokens": 3881 │ } │ ├── flue.turn [llm] │ │ output: [ @@ -301,11 +301,11 @@ span_tree: │ │ metrics: { │ │ "completion_tokens": 89, │ │ "duration_ms": 0, - │ │ "estimated_cost": 0.0043569, - │ │ "prompt_cache_creation_tokens": 716, + │ │ "estimated_cost": 0.0043644, + │ │ "prompt_cache_creation_tokens": 718, │ │ "prompt_cached_tokens": 1093, │ │ "prompt_tokens": 3, - │ │ "tokens": 1901 + │ │ "tokens": 1903 │ │ } │ ├── tool: read [tool] │ │ input: { @@ -351,11 +351,11 @@ span_tree: │ metrics: { │ "completion_tokens": 8, │ "duration_ms": 0, - │ "estimated_cost": 0.00125445, + │ "estimated_cost": 0.00125505, │ "prompt_cache_creation_tokens": 153, - │ "prompt_cached_tokens": 1809, + │ "prompt_cached_tokens": 1811, │ "prompt_tokens": 6, - │ "tokens": 1976 + │ "tokens": 1978 │ } ├── flue-task-operation │ metadata: { @@ -375,48 +375,48 @@ span_tree: │ metrics: { │ "completion_tokens": 4, │ "duration_ms": 0, - │ "estimated_cost": 0.00011789999999999999, + │ "estimated_cost": 0.0001182, │ "prompt_cache_creation_tokens": 0, │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 770, - │ "tokens": 774 + │ "prompt_tokens": 772, + │ "tokens": 776 │ } - │ └── flue.task [task] - │ input: "Reply with exactly TASK_DONE and no other text." - │ output: "TASK_DONE" + │ ├── flue.task [task] + │ │ input: "Reply with exactly TASK_DONE and no other text." + │ │ output: "TASK_DONE" + │ │ metadata: { + │ │ "flue.session": "task", + │ │ "provider": "flue" + │ │ } + │ │ metrics: { + │ │ "duration_ms": 0 + │ │ } + │ └── flue.turn [llm] + │ output: [ + │ { + │ "finish_reason": "stop", + │ "index": 0, + │ "message": { + │ "content": "TASK_DONE", + │ "role": "assistant" + │ } + │ } + │ ] │ metadata: { - │ "flue.session": "task", + │ "flue.model": "gpt-4o-mini", + │ "flue.session": "task:task:", + │ "model": "gpt-4o-mini", │ "provider": "flue" │ } │ metrics: { - │ "duration_ms": 0 + │ "completion_tokens": 4, + │ "duration_ms": 0, + │ "estimated_cost": 0.0001182, + │ "prompt_cache_creation_tokens": 0, + │ "prompt_cached_tokens": 0, + │ "prompt_tokens": 772, + │ "tokens": 776 │ } - │ └── flue.turn [llm] - │ output: [ - │ { - │ "finish_reason": "stop", - │ "index": 0, - │ "message": { - │ "content": "TASK_DONE", - │ "role": "assistant" - │ } - │ } - │ ] - │ metadata: { - │ "flue.model": "gpt-4o-mini", - │ "flue.session": "task:task:", - │ "model": "gpt-4o-mini", - │ "provider": "flue" - │ } - │ metrics: { - │ "completion_tokens": 4, - │ "duration_ms": 0, - │ "estimated_cost": 0.00011789999999999999, - │ "prompt_cache_creation_tokens": 0, - │ "prompt_cached_tokens": 0, - │ "prompt_tokens": 770, - │ "tokens": 774 - │ } └── flue-compact-operation metadata: { "operation": "compact" diff --git a/e2e/scenarios/flue-instrumentation/assertions.ts b/e2e/scenarios/flue-instrumentation/assertions.ts index 7e1770e69..9632a9ac4 100644 --- a/e2e/scenarios/flue-instrumentation/assertions.ts +++ b/e2e/scenarios/flue-instrumentation/assertions.ts @@ -22,6 +22,7 @@ import { ROOT_NAME, SCENARIO_NAME } from "./constants.mjs"; type RunFlueScenario = (harness: { runNodeScenarioDir: (options: { entry: string; + env?: Record; nodeArgs: string[]; runContext?: ScenarioRunContext; scenarioDir: string; @@ -29,6 +30,7 @@ type RunFlueScenario = (harness: { }) => Promise; runScenarioDir: (options: { entry: string; + env?: Record; runContext?: ScenarioRunContext; scenarioDir: string; timeoutMs: number; @@ -171,6 +173,18 @@ function isFlueChildSpan(event: CapturedLogEvent): boolean { ); } +function isProviderSpan(event: CapturedLogEvent): boolean { + return ( + event.span.name === "anthropic.messages.create" || + event.span.name === "openai.responses.create" || + event.span.name === "openai.responses.compact" + ); +} + +function isOperationChildSpan(event: CapturedLogEvent): boolean { + return isFlueChildSpan(event) || isProviderSpan(event); +} + function expectToolsAndTurnsShareParent( parent: CapturedLogEvent | undefined, turns: CapturedLogEvent[], @@ -231,25 +245,25 @@ function buildSpanTree(events: CapturedLogEvent[]): SpanTreeEntry[] { events, promptSpan, promptOperation, - isFlueChildSpan, + isOperationChildSpan, ); const skillChildren = findFlueDescendants( events, skillSpan, skillOperation, - isFlueChildSpan, + isOperationChildSpan, ); const taskChildren = findFlueDescendants( events, taskSpan, taskOperation, - isFlueChildSpan, + isOperationChildSpan, ); const compactChildren = findFlueDescendants( events, compactSpan, compactOperation, - isFlueChildSpan, + isOperationChildSpan, ); return [ @@ -272,6 +286,8 @@ function buildSpanTree(events: CapturedLogEvent[]): SpanTreeEntry[] { } export function defineFlueInstrumentationAssertions(options: { + expectedPromptProviderSpanName?: string; + expectThinking?: boolean; name: string; runScenario: RunFlueScenario; snapshotName: string; @@ -339,7 +355,7 @@ export function defineFlueInstrumentationAssertions(options: { events, promptSpan, promptOperation, - isFlueChildSpan, + isOperationChildSpan, ); const promptTurns = promptChildren.filter( (event) => event.span.name === "flue.turn", @@ -363,7 +379,7 @@ export function defineFlueInstrumentationAssertions(options: { events, skillSpan, skillOperation, - isFlueChildSpan, + isOperationChildSpan, ); const skillTurns = skillChildren.filter( (event) => event.span.name === "flue.turn", @@ -409,15 +425,17 @@ export function defineFlueInstrumentationAssertions(options: { ); expectToolsAndTurnsShareParent(promptSpan, promptTurns, promptTools); expectToolsAndTurnsShareParent(skillSpan, skillTurns, skillTools); - expect(reasoningTurn?.span.type).toBe("llm"); - expect(reasoningTurn?.output).toBeDefined(); - const reasoningOutput = JSON.stringify(reasoningTurn?.output); - expect(reasoningOutput).not.toContain(""); - expect(reasoningOutput).not.toContain("content unavailable"); - expect(reasoningOutput).not.toContain("[Reasoning redacted]"); - expect(reasoningTurn?.metadata).toMatchObject({ - "flue.thinking": true, - }); + if (options.expectThinking !== false) { + expect(reasoningTurn?.span.type).toBe("llm"); + expect(reasoningTurn?.output).toBeDefined(); + const reasoningOutput = JSON.stringify(reasoningTurn?.output); + expect(reasoningOutput).not.toContain(""); + expect(reasoningOutput).not.toContain("content unavailable"); + expect(reasoningOutput).not.toContain("[Reasoning redacted]"); + expect(reasoningTurn?.metadata).toMatchObject({ + "flue.thinking": true, + }); + } expect(promptTurns[0]?.metrics).toMatchObject({ completion_tokens: expect.any(Number), prompt_tokens: expect.any(Number), @@ -446,6 +464,32 @@ export function defineFlueInstrumentationAssertions(options: { expect(findAllSpans(events, "flue.session.shell")).toHaveLength(0); }); + test("nests provider spans inside Flue operations", testConfig, () => { + const promptSpan = findFlueOperation( + events, + "flue-prompt-operation", + "flue.session.prompt", + ); + const promptProviders = findMatchingDescendants( + events, + promptSpan, + isProviderSpan, + ); + + if (options.expectedPromptProviderSpanName) { + const provider = promptProviders.find( + (event) => event.span.name === options.expectedPromptProviderSpanName, + ); + expect(provider).toBeDefined(); + expect(provider?.input).toBeDefined(); + expect(JSON.stringify(provider?.input)).toContain( + "Complete this instrumented research flow", + ); + } else { + expect(promptProviders).toHaveLength(0); + } + }); + test("matches the span tree snapshot", testConfig, async () => { await matchSpanTreeSnapshot(buildSpanTree(events), snapshotPath); }); diff --git a/e2e/scenarios/flue-instrumentation/scenario.impl.mjs b/e2e/scenarios/flue-instrumentation/scenario.impl.mjs index 04c77c4c5..7d38abebf 100644 --- a/e2e/scenarios/flue-instrumentation/scenario.impl.mjs +++ b/e2e/scenarios/flue-instrumentation/scenario.impl.mjs @@ -33,6 +33,28 @@ if (anthropicBaseUrl) { }); } +function flueModel() { + return process.env.FLUE_E2E_MODEL ?? FLUE_MODEL; +} + +function flueReasoningModel() { + return process.env.FLUE_E2E_REASONING_MODEL ?? FLUE_REASONING_MODEL; +} + +function fluePromptModel() { + return process.env.FLUE_E2E_PROMPT_MODEL ?? flueReasoningModel(); +} + +function fluePromptThinkingLevel() { + return ( + process.env.FLUE_E2E_PROMPT_THINKING_LEVEL ?? flueReasoningThinkingLevel() + ); +} + +function flueReasoningThinkingLevel() { + return process.env.FLUE_E2E_REASONING_THINKING_LEVEL ?? "medium"; +} + function makeContext() { const sandbox = local({ cwd: process.cwd() }); return createFlueContext({ @@ -41,7 +63,7 @@ function makeContext() { keepRecentTokens: 1, reserveTokens: 64, }, - model: resolveModel(FLUE_MODEL), + model: resolveModel(flueModel()), resolveModel, roles: { skillRunner: { @@ -142,7 +164,7 @@ export async function runFlueInstrumentationScenario({ wrapContext }) { reserveTokens: 64, }, cwd: process.cwd(), - model: FLUE_MODEL, + model: flueModel(), sandbox: local({ cwd: process.cwd() }), }); const session = await harness.session("main"); @@ -162,8 +184,8 @@ export async function runFlueInstrumentationScenario({ wrapContext }) { { cacheRetention: "none", maxTokens: 2048, - model: FLUE_REASONING_MODEL, - thinkingLevel: "medium", + model: fluePromptModel(), + thinkingLevel: fluePromptThinkingLevel(), tools: [lookupTool, webSearchTool, summarizeSourceTool], }, ); @@ -174,7 +196,7 @@ export async function runFlueInstrumentationScenario({ wrapContext }) { args: { marker: "SKILL_DONE" }, cacheRetention: "none", maxTokens: 128, - model: FLUE_REASONING_MODEL, + model: flueReasoningModel(), role: "skillRunner", thinkingLevel: "off", }); diff --git a/e2e/scenarios/flue-instrumentation/scenario.test.ts b/e2e/scenarios/flue-instrumentation/scenario.test.ts index 717c1743f..0f7113821 100644 --- a/e2e/scenarios/flue-instrumentation/scenario.test.ts +++ b/e2e/scenarios/flue-instrumentation/scenario.test.ts @@ -17,6 +17,12 @@ const flueVersion = await readInstalledPackageVersion( const TIMEOUT_MS = 120_000; const wrappedVariantKey = "flue-v0-7-0-wrapped"; const autoHookVariantKey = "flue-v0-7-0-auto-hook"; +const openAIAutoHookVariantKey = "flue-v0-7-0-openai-auto-hook"; + +const openAIPromptEnv = { + FLUE_E2E_PROMPT_MODEL: "openai/gpt-4o-mini", + FLUE_E2E_PROMPT_THINKING_LEVEL: "off", +}; describe(`flue ${flueVersion}`, () => { defineFlueInstrumentationAssertions({ @@ -38,6 +44,7 @@ describe(`flue ${flueVersion}`, () => { }); defineFlueInstrumentationAssertions({ + expectedPromptProviderSpanName: "anthropic.messages.create", name: "auto-hook instrumentation", runScenario: async ({ runNodeScenarioDir }) => { await runNodeScenarioDir({ @@ -55,4 +62,26 @@ describe(`flue ${flueVersion}`, () => { testFileUrl: import.meta.url, timeoutMs: TIMEOUT_MS, }); + + defineFlueInstrumentationAssertions({ + expectedPromptProviderSpanName: "openai.responses.create", + expectThinking: false, + name: "auto-hook instrumentation with OpenAI prompt model", + runScenario: async ({ runNodeScenarioDir }) => { + await runNodeScenarioDir({ + entry: "scenario.mjs", + env: openAIPromptEnv, + nodeArgs: ["--import", "braintrust/hook.mjs"], + runContext: { + originalScenarioDir, + variantKey: openAIAutoHookVariantKey, + }, + scenarioDir, + timeoutMs: TIMEOUT_MS, + }); + }, + snapshotName: "flue-v0-7-0-openai-auto-hook", + testFileUrl: import.meta.url, + timeoutMs: TIMEOUT_MS, + }); }); diff --git a/js/src/instrumentation/plugins/flue-plugin.test.ts b/js/src/instrumentation/plugins/flue-plugin.test.ts index 26864deaa..5b41261ae 100644 --- a/js/src/instrumentation/plugins/flue-plugin.test.ts +++ b/js/src/instrumentation/plugins/flue-plugin.test.ts @@ -1,10 +1,27 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest"; -const { mockCurrentParentSpan, mockStartSpan } = vi.hoisted(() => ({ +const { + mockContextManager, + mockCurrentParentSpan, + mockCurrentSpanStore, + mockStartSpan, +} = vi.hoisted(() => ({ + mockContextManager: { + wrapSpanForStore: vi.fn((span: unknown) => span), + [Symbol.for("braintrust.currentSpanStore")]: undefined as unknown, + }, mockCurrentParentSpan: { current: undefined as any }, + mockCurrentSpanStore: { + enterWith: vi.fn(), + getStore: vi.fn(), + run: vi.fn(), + }, mockStartSpan: vi.fn(), })); +mockContextManager[Symbol.for("braintrust.currentSpanStore")] = + mockCurrentSpanStore; + vi.mock("../../isomorph", () => ({ default: { newTracingChannel: vi.fn(), @@ -12,6 +29,10 @@ vi.mock("../../isomorph", () => ({ })); vi.mock("../../logger", () => ({ + BRAINTRUST_CURRENT_SPAN_STORE: Symbol.for("braintrust.currentSpanStore"), + _internalGetGlobalState: () => ({ + contextManager: mockContextManager, + }), startSpan: (...args: unknown[]) => mockStartSpan(...args), withCurrent: (span: unknown, callback: () => unknown) => { const previous = mockCurrentParentSpan.current; @@ -30,6 +51,7 @@ import { FluePlugin } from "./flue-plugin"; const mockNewTracingChannel = iso.newTracingChannel as ReturnType; describe("FluePlugin", () => { + let boundStoreTransformsByName: Map unknown>; let handlersByName: Map; let spans: Array<{ end: ReturnType; @@ -42,10 +64,19 @@ describe("FluePlugin", () => { }>; beforeEach(() => { + boundStoreTransformsByName = new Map(); handlersByName = new Map(); spans = []; mockCurrentParentSpan.current = undefined; + mockContextManager.wrapSpanForStore.mockClear(); mockNewTracingChannel.mockImplementation((name: string) => ({ + start: { + bindStore: vi.fn((_store, transform) => { + boundStoreTransformsByName.set(name, transform); + }), + publish: vi.fn(), + unbindStore: vi.fn(), + }, subscribe: vi.fn((handlers) => handlersByName.set(name, handlers)), tracePromise: vi.fn((fn) => fn()), traceSync: vi.fn((fn) => fn()), @@ -107,6 +138,34 @@ describe("FluePlugin", () => { ).toBe(true); }); + it("binds operation spans into the traced execution context", () => { + const plugin = new FluePlugin(); + plugin.enable(); + + const promptEvent = { + arguments: ["Use a tool", { model: "pi/test" }], + operation: "prompt", + session: { name: "main" }, + }; + const bindTransform = boundStoreTransformsByName.get( + "orchestrion:@flue/runtime:session.prompt", + ); + + const storeValue = bindTransform?.(promptEvent); + handlersByName + .get("orchestrion:@flue/runtime:session.prompt") + .start(promptEvent); + + const operationSpans = spans.filter( + (span) => span.name === "flue.session.prompt", + ); + expect(operationSpans).toHaveLength(1); + expect(mockContextManager.wrapSpanForStore).toHaveBeenCalledWith( + operationSpans[0], + ); + expect(storeValue).toBe(operationSpans[0]); + }); + it("patches contexts and sessions returned by auto-instrumented entrypoints", async () => { const plugin = new FluePlugin(); plugin.enable(); @@ -534,6 +593,64 @@ describe("FluePlugin", () => { }), ); }); + + it("ends compaction spans from compact operation completion when no final compaction event arrives", () => { + const plugin = new FluePlugin(); + plugin.enable(); + + const contextHandlers = handlersByName.get( + "orchestrion:@flue/runtime:context.event", + ); + const compactHandlers = handlersByName.get( + "orchestrion:@flue/runtime:session.compact", + ); + const compactEvent = { + arguments: [], + operation: "compact", + session: { name: "main" }, + }; + + compactHandlers.start(compactEvent); + contextHandlers.start({ + arguments: [ + { + operationId: "op_1", + operationKind: "compact", + session: "main", + type: "operation_start", + }, + ], + }); + contextHandlers.start({ + arguments: [ + { + estimatedTokens: 100, + operationId: "op_1", + reason: "manual", + session: "main", + type: "compaction_start", + }, + ], + }); + compactHandlers.asyncEnd(compactEvent); + + const operationSpan = spans.find( + (span) => span.name === "flue.session.compact", + ); + const compactionSpan = spans.find( + (span) => span.name === "flue.compaction", + ); + + expect(compactionSpan?.end).toHaveBeenCalledTimes(1); + expect(operationSpan?.end).toHaveBeenCalledTimes(1); + expect(compactionSpan?.log).toHaveBeenCalledWith( + expect.objectContaining({ + metrics: expect.objectContaining({ + duration_ms: expect.any(Number), + }), + }), + ); + }); }); function makeSession() { diff --git a/js/src/instrumentation/plugins/flue-plugin.ts b/js/src/instrumentation/plugins/flue-plugin.ts index bdac30735..6a497c640 100644 --- a/js/src/instrumentation/plugins/flue-plugin.ts +++ b/js/src/instrumentation/plugins/flue-plugin.ts @@ -1,8 +1,13 @@ import { BasePlugin } from "../core"; import type { ChannelMessage } from "../core/channel-definitions"; import type { IsoChannelHandlers } from "../../isomorph"; -import { startSpan, withCurrent } from "../../logger"; -import type { Span } from "../../logger"; +import { + _internalGetGlobalState, + BRAINTRUST_CURRENT_SPAN_STORE, + startSpan, + withCurrent, +} from "../../logger"; +import type { CurrentSpanStore, Span } from "../../logger"; import { getCurrentUnixTimestamp, isObject } from "../../util"; import { SpanTypeAttribute } from "../../../util/index"; import { @@ -46,6 +51,7 @@ type OperationState = { type SpanState = { metadata: Record; + operationState?: OperationState; span: Span; startTime: number; }; @@ -153,18 +159,32 @@ export class FluePlugin extends BasePlugin { ): void { const tracingChannel = channel.tracingChannel(); const states = new WeakMap(); + const ensureState = ( + event: ChannelMessage, + ): OperationState => { + const existing = states.get(event); + if (existing) { + return existing; + } + const state = this.startOperationState({ + args: event.arguments, + moduleVersion: + typeof event.moduleVersion === "string" + ? event.moduleVersion + : undefined, + operation: event.operation, + session: event.session, + }); + states.set(event, state); + return state; + }; + const unbindCurrentSpanStore = this.bindCurrentSpanStoreToOperationStart( + tracingChannel, + ensureState, + ); const handlers: IsoChannelHandlers> = { start: (event) => { - const state = this.startOperationState({ - args: event.arguments, - moduleVersion: - typeof event.moduleVersion === "string" - ? event.moduleVersion - : undefined, - operation: event.operation, - session: event.session, - }); - states.set(event, state); + ensureState(event); }, asyncEnd: (event) => { this.endOperationState(states.get(event), event.result); @@ -182,6 +202,7 @@ export class FluePlugin extends BasePlugin { tracingChannel.subscribe(handlers); this.unsubscribers.push(() => { + unbindCurrentSpanStore?.(); tracingChannel.unsubscribe(handlers); }); } @@ -189,20 +210,34 @@ export class FluePlugin extends BasePlugin { private subscribeToCompact(): void { const tracingChannel = flueChannels.compact.tracingChannel(); const states = new WeakMap(); + const ensureState = ( + event: ChannelMessage, + ): OperationState => { + const existing = states.get(event); + if (existing) { + return existing; + } + const state = this.startOperationState({ + args: [], + moduleVersion: + typeof event.moduleVersion === "string" + ? event.moduleVersion + : undefined, + operation: event.operation, + session: event.session, + }); + states.set(event, state); + return state; + }; + const unbindCurrentSpanStore = this.bindCurrentSpanStoreToOperationStart( + tracingChannel, + ensureState, + ); const handlers: IsoChannelHandlers< ChannelMessage > = { start: (event) => { - const state = this.startOperationState({ - args: [], - moduleVersion: - typeof event.moduleVersion === "string" - ? event.moduleVersion - : undefined, - operation: event.operation, - session: event.session, - }); - states.set(event, state); + ensureState(event); }, asyncEnd: (event) => { this.endOperationState(states.get(event), undefined); @@ -220,6 +255,7 @@ export class FluePlugin extends BasePlugin { tracingChannel.subscribe(handlers); this.unsubscribers.push(() => { + unbindCurrentSpanStore?.(); tracingChannel.unsubscribe(handlers); }); } @@ -250,6 +286,43 @@ export class FluePlugin extends BasePlugin { }); } + private bindCurrentSpanStoreToOperationStart( + tracingChannel: { + start?: { + bindStore( + store: CurrentSpanStore, + transform: (event: TEvent) => T, + ): void; + unbindStore(store: CurrentSpanStore): boolean; + }; + }, + ensureState: (event: TEvent) => OperationState, + ): (() => void) | undefined { + const state = _internalGetGlobalState(); + const startChannel = tracingChannel.start; + const contextManager = state?.contextManager; + const currentSpanStore = contextManager + ? ( + contextManager as { + [BRAINTRUST_CURRENT_SPAN_STORE]?: CurrentSpanStore; + } + )[BRAINTRUST_CURRENT_SPAN_STORE] + : undefined; + + if (!currentSpanStore || !startChannel) { + return undefined; + } + + startChannel.bindStore(currentSpanStore, (event: TEvent) => { + const operationState = ensureState(event); + return contextManager!.wrapSpanForStore(operationState.span); + }); + + return () => { + startChannel.unbindStore(currentSpanStore); + }; + } + private startOperationState(args: { args: ArrayLike; moduleVersion?: string; @@ -315,6 +388,9 @@ export class FluePlugin extends BasePlugin { metrics, output: extractOperationOutput(result), }); + if (state.operation === "compact") { + this.finishCompactionsForOperation(state); + } this.finishOperationState(state); } @@ -630,7 +706,8 @@ export class FluePlugin extends BasePlugin { } private handleCompactionStart(event: FlueCompactionStartEvent): void { - const parent = this.parentSpanForEvent(event); + const operationState = this.operationStateForEvent(event); + const parent = operationState?.span ?? this.parentSpanForEvent(event); const metadata = { ...extractEventMetadata(event), ...(event.reason ? { "flue.compaction_reason": event.reason } : {}), @@ -649,6 +726,7 @@ export class FluePlugin extends BasePlugin { }); this.compactionsByScope.set(scopeKey(event), { metadata, + operationState, span, startTime: getCurrentUnixTimestamp(), }); @@ -656,7 +734,8 @@ export class FluePlugin extends BasePlugin { private handleCompaction(event: FlueCompactionEvent): void { const key = scopeKey(event); - const state = this.compactionsByScope.get(key); + const state = + this.compactionsByScope.get(key) ?? this.findCompactionState(event); if (!state) { return; } @@ -682,7 +761,43 @@ export class FluePlugin extends BasePlugin { }, }); state.span.end(); - this.compactionsByScope.delete(key); + this.deleteCompactionState(state); + } + + private findCompactionState(event: FlueBaseEvent): SpanState | undefined { + const operationState = this.operationStateForEvent(event); + for (const state of this.compactionsByScope.values()) { + if (operationState && state.operationState === operationState) { + return state; + } + } + return undefined; + } + + private finishCompactionsForOperation(operationState: OperationState): void { + for (const state of [...this.compactionsByScope.values()]) { + if (state.operationState !== operationState) { + continue; + } + safeLog(state.span, { + metadata: state.metadata, + metrics: { + ...buildDurationMetrics(state.startTime), + }, + }); + state.span.end(); + this.deleteCompactionState(state); + } + } + + private deleteCompactionState(state: SpanState): void { + for (const [key, candidate] of this.compactionsByScope) { + if (candidate !== state) { + continue; + } + this.compactionsByScope.delete(key); + return; + } } private startSyntheticToolState( @@ -704,11 +819,26 @@ export class FluePlugin extends BasePlugin { return { metadata, span, startTime: getCurrentUnixTimestamp() }; } - private parentSpanForEvent(event: FlueBaseEvent): Span | undefined { + private operationStateForEvent( + event: FlueBaseEvent, + ): OperationState | undefined { if (event.operationId) { const operation = this.activeOperationsById.get(event.operationId) ?? this.promotePendingOperationForEvent(event); + if (operation) { + return operation; + } + } + return ( + this.activeOperationForEventScope(event) ?? + this.pendingOperationForEventScope(event) + ); + } + + private parentSpanForEvent(event: FlueBaseEvent): Span | undefined { + if (event.operationId) { + const operation = this.operationStateForEvent(event); if (operation) { return operation.span; } @@ -716,10 +846,7 @@ export class FluePlugin extends BasePlugin { if (event.taskId) { return this.tasksById.get(event.taskId)?.span; } - return ( - this.activeOperationForEventScope(event)?.span ?? - this.pendingOperationForEventScope(event)?.span - ); + return this.operationStateForEvent(event)?.span; } private promotePendingOperationForEvent( diff --git a/js/src/wrappers/flue.test.ts b/js/src/wrappers/flue.test.ts index 27b252b57..743530793 100644 --- a/js/src/wrappers/flue.test.ts +++ b/js/src/wrappers/flue.test.ts @@ -5,12 +5,29 @@ const { publishAsyncStart, publishEnd, publishStart, + tracePromise, traceSync, } = vi.hoisted(() => ({ publishAsyncEnd: vi.fn(), publishAsyncStart: vi.fn(), publishEnd: vi.fn(), publishStart: vi.fn(), + tracePromise: vi.fn( + async (fn: () => Promise, context: Record) => { + publishStart(context); + try { + const result = fn(); + publishEnd(context); + const resolved = await result; + context.result = resolved; + publishAsyncStart(context); + publishAsyncEnd(context); + return resolved; + } catch (error) { + throw error; + } + }, + ), traceSync: vi.fn((fn: () => unknown) => fn()), })); @@ -31,8 +48,13 @@ vi.mock("../isomorph", () => ({ }, start: { publish: publishStart, + runStores: vi.fn((context, fn) => { + publishStart(context); + return fn(); + }), }, subscribe: vi.fn(), + tracePromise, traceSync, unsubscribe: vi.fn(), })), diff --git a/js/src/wrappers/flue.ts b/js/src/wrappers/flue.ts index 170348c55..c238140fb 100644 --- a/js/src/wrappers/flue.ts +++ b/js/src/wrappers/flue.ts @@ -27,6 +27,7 @@ type FlueOperationChannel = | typeof flueChannels.compact; type PublishChannel = { publish(message: unknown): void; + runStores?(message: unknown, fn: () => T): T; }; type ManualTracingChannel = { asyncEnd?: PublishChannel; @@ -259,14 +260,12 @@ function patchCompact(session: FlueSessionRecord): void { Object.defineProperty(session, "compact", { configurable: true, value() { - return traceFlueOperation(flueChannels.compact, { - context: { - arguments: [], - operation: "compact", - session, - } as never, - run: () => bound(), - }).traced; + const context = { + arguments: [], + operation: "compact", + session, + } as Parameters[1]; + return flueChannels.compact.tracePromise(() => bound(), context); }, writable: true, }); @@ -285,35 +284,44 @@ function traceFlueOperation( const tracingChannel = channel.tracingChannel() as ManualTracingChannel; const context = args.context as Record; - tracingChannel.start?.publish(context); let originalResult: PromiseLike; - try { - originalResult = args.run(); - tracingChannel.end?.publish(context); - } catch (error) { - context.error = normalizeError(error); - tracingChannel.error?.publish(context); - tracingChannel.end?.publish(context); - throw error; - } - - const traced = Promise.resolve(originalResult).then( - (result) => { - context.result = result; - tracingChannel.asyncStart?.publish(context); - tracingChannel.asyncEnd?.publish(context); - return result; - }, - (error: unknown) => { + let traced: Promise; + const run = () => { + try { + originalResult = args.run(); + tracingChannel.end?.publish(context); + } catch (error) { context.error = normalizeError(error); tracingChannel.error?.publish(context); - tracingChannel.asyncStart?.publish(context); - tracingChannel.asyncEnd?.publish(context); + tracingChannel.end?.publish(context); throw error; - }, - ); + } + + traced = Promise.resolve(originalResult).then( + (result) => { + context.result = result; + tracingChannel.asyncStart?.publish(context); + tracingChannel.asyncEnd?.publish(context); + return result; + }, + (error: unknown) => { + context.error = normalizeError(error); + tracingChannel.error?.publish(context); + tracingChannel.asyncStart?.publish(context); + tracingChannel.asyncEnd?.publish(context); + throw error; + }, + ); + }; + + if (tracingChannel.start?.runStores) { + tracingChannel.start.runStores(context, run); + } else { + tracingChannel.start?.publish(context); + run(); + } - return { originalResult, traced }; + return { originalResult: originalResult!, traced: traced! }; } function normalizeError(error: unknown): Error { From ec3a2f040281c23c2c7776680afb56f3873fe266 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Fri, 22 May 2026 11:16:07 +0200 Subject: [PATCH 5/6] smol clean --- js/src/wrappers/flue.ts | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/js/src/wrappers/flue.ts b/js/src/wrappers/flue.ts index c238140fb..804fb0ae5 100644 --- a/js/src/wrappers/flue.ts +++ b/js/src/wrappers/flue.ts @@ -1,4 +1,5 @@ import { flueChannels } from "../instrumentation/plugins/flue-channels"; +import type { IsoTracingChannelCollection } from "../isomorph"; import type { FlueCallHandle, FlueCallOptions, @@ -25,17 +26,13 @@ type FlueOperationChannel = | typeof flueChannels.skill | typeof flueChannels.task | typeof flueChannels.compact; -type PublishChannel = { - publish(message: unknown): void; - runStores?(message: unknown, fn: () => T): T; -}; -type ManualTracingChannel = { - asyncEnd?: PublishChannel; - asyncStart?: PublishChannel; - end?: PublishChannel; - error?: PublishChannel; - start?: PublishChannel; -}; +type FlueOperationTraceContext = Parameters< + FlueOperationChannel["tracePromise"] +>[1] & + Partial<{ + error: Error; + result: TResult; + }>; /** * Wraps a Flue context with Braintrust tracing. Context wrapping subscribes to @@ -281,8 +278,11 @@ function traceFlueOperation( originalResult: PromiseLike; traced: Promise; } { - const tracingChannel = channel.tracingChannel() as ManualTracingChannel; - const context = args.context as Record; + const tracingChannel = + channel.tracingChannel() as IsoTracingChannelCollection< + FlueOperationTraceContext + >; + const context = args.context as FlueOperationTraceContext; let originalResult: PromiseLike; let traced: Promise; From be5464d3921252d6378b664fa7bcfb9cae024e26 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Fri, 22 May 2026 12:34:02 +0200 Subject: [PATCH 6/6] fix double llm spans --- .../flue-v0-7-0-auto-hook.span-tree.json | 258 ------- .../flue-v0-7-0-auto-hook.span-tree.txt | 650 ++++++------------ ...lue-v0-7-0-openai-auto-hook.span-tree.json | 250 ------- ...flue-v0-7-0-openai-auto-hook.span-tree.txt | 530 +++++--------- .../flue-instrumentation/assertions.ts | 45 +- .../flue-instrumentation/scenario.test.ts | 2 + .../instrumentation/plugins/flue-channels.ts | 1 + .../plugins/flue-plugin.test.ts | 89 ++- js/src/instrumentation/plugins/flue-plugin.ts | 58 +- js/src/wrappers/flue.test.ts | 62 +- js/src/wrappers/flue.ts | 49 +- 11 files changed, 627 insertions(+), 1367 deletions(-) diff --git a/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-auto-hook.span-tree.json b/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-auto-hook.span-tree.json index 08670e291..828d13d2a 100644 --- a/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-auto-hook.span-tree.json +++ b/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-auto-hook.span-tree.json @@ -46,48 +46,6 @@ "provider": "anthropic" } }, - { - "name": "flue.turn", - "type": "llm", - "children": [], - "output": [ - { - "finish_reason": "toolUse", - "index": 0, - "message": { - "content": "I'll complete this instrumented research flow step by step. Starting with step 1:", - "reasoning": "The user wants me to complete a specific instrumented research flow with these steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url and call summarize_source\n4. After summarize_source returns, reply with exactly \"PROMPT_DONE\" and no other text\n\nThe user emphasizes calling exactly one tool per turn and waiting for each result. Let me start with step 1.", - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"query\":\"flue instrumentation\"}", - "name": "lookup" - }, - "id": "", - "type": "function" - } - ] - } - } - ], - "metadata": { - "flue.model": "claude-sonnet-4-5-20250929", - "flue.session": "main", - "flue.thinking": true, - "model": "claude-sonnet-4-5-20250929", - "provider": "flue" - }, - "metrics": { - "completion_tokens": 208, - "duration_ms": 0, - "estimated_cost": 0.0038052, - "prompt_cache_creation_tokens": 0, - "prompt_cached_tokens": 2184, - "prompt_tokens": 10, - "tokens": 2402 - } - }, { "name": "tool: lookup", "type": "tool", @@ -183,48 +141,6 @@ "provider": "anthropic" } }, - { - "name": "flue.turn", - "type": "llm", - "children": [], - "output": [ - { - "finish_reason": "toolUse", - "index": 0, - "message": { - "content": "Now proceeding to step 2:", - "reasoning": "Good, I got the lookup result with id \"flue-session-2026\". Now I need to proceed to step 2: call web_search with this lookupId and the query \"Braintrust Flue reasoning stream instrumentation\".", - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\"}", - "name": "web_search" - }, - "id": "", - "type": "function" - } - ] - } - } - ], - "metadata": { - "flue.model": "claude-sonnet-4-5-20250929", - "flue.session": "main", - "flue.thinking": true, - "model": "claude-sonnet-4-5-20250929", - "provider": "flue" - }, - "metrics": { - "completion_tokens": 158, - "duration_ms": 0, - "estimated_cost": 0.0039942, - "prompt_cache_creation_tokens": 248, - "prompt_cached_tokens": 2184, - "prompt_tokens": 13, - "tokens": 2603 - } - }, { "name": "tool: web_search", "type": "tool", @@ -355,48 +271,6 @@ "provider": "anthropic" } }, - { - "name": "flue.turn", - "type": "llm", - "children": [], - "output": [ - { - "finish_reason": "toolUse", - "index": 0, - "message": { - "content": "Now proceeding to step 3:", - "reasoning": "Perfect! I got the web_search results. There's one result with the URL \"https://example.test/flue/reasoning-streams\". Now I need to proceed to step 3: call summarize_source with this URL.", - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"url\":\"https://example.test/flue/reasoning-streams\"}", - "name": "summarize_source" - }, - "id": "", - "type": "function" - } - ] - } - } - ], - "metadata": { - "flue.model": "claude-sonnet-4-5-20250929", - "flue.session": "main", - "flue.thinking": true, - "model": "claude-sonnet-4-5-20250929", - "provider": "flue" - }, - "metrics": { - "completion_tokens": 132, - "duration_ms": 0, - "estimated_cost": 0.0036261, - "prompt_cache_creation_tokens": 234, - "prompt_cached_tokens": 2432, - "prompt_tokens": 13, - "tokens": 2811 - } - }, { "name": "tool: summarize_source", "type": "tool", @@ -558,38 +432,6 @@ "model": "claude-sonnet-4-5-20250929", "provider": "anthropic" } - }, - { - "name": "flue.turn", - "type": "llm", - "children": [], - "output": [ - { - "finish_reason": "stop", - "index": 0, - "message": { - "content": "PROMPT_DONE", - "reasoning": "The summarize_source has returned successfully. According to the instructions, I should now reply with exactly \"PROMPT_DONE\" and no other text.", - "role": "assistant" - } - } - ], - "metadata": { - "flue.model": "claude-sonnet-4-5-20250929", - "flue.session": "main", - "flue.thinking": true, - "model": "claude-sonnet-4-5-20250929", - "provider": "flue" - }, - "metrics": { - "completion_tokens": 48, - "duration_ms": 0, - "estimated_cost": 0.0022638, - "prompt_cache_creation_tokens": 188, - "prompt_cached_tokens": 2666, - "prompt_tokens": 13, - "tokens": 2915 - } } ], "input": "Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.", @@ -660,46 +502,6 @@ "provider": "anthropic" } }, - { - "name": "flue.turn", - "type": "llm", - "children": [], - "output": [ - { - "finish_reason": "toolUse", - "index": 0, - "message": { - "content": "I'll read the skill file and execute it according to its instructions.", - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"path\":\".agents/skills/e2e-flue-skill/SKILL.md\"}", - "name": "read" - }, - "id": "", - "type": "function" - } - ] - } - } - ], - "metadata": { - "flue.model": "claude-sonnet-4-5-20250929", - "flue.session": "skill", - "model": "claude-sonnet-4-5-20250929", - "provider": "flue" - }, - "metrics": { - "completion_tokens": 83, - "duration_ms": 0, - "estimated_cost": 0.0017973, - "prompt_cache_creation_tokens": 0, - "prompt_cached_tokens": 1811, - "prompt_tokens": 3, - "tokens": 1897 - } - }, { "name": "tool: read", "type": "tool", @@ -790,36 +592,6 @@ "model": "claude-sonnet-4-5-20250929", "provider": "anthropic" } - }, - { - "name": "flue.turn", - "type": "llm", - "children": [], - "output": [ - { - "finish_reason": "stop", - "index": 0, - "message": { - "content": "SKILL_DONE", - "role": "assistant" - } - } - ], - "metadata": { - "flue.model": "claude-sonnet-4-5-20250929", - "flue.session": "skill", - "model": "claude-sonnet-4-5-20250929", - "provider": "flue" - }, - "metrics": { - "completion_tokens": 8, - "duration_ms": 0, - "estimated_cost": 0.0012325499999999998, - "prompt_cache_creation_tokens": 147, - "prompt_cached_tokens": 1811, - "prompt_tokens": 6, - "tokens": 1972 - } } ], "input": { @@ -922,36 +694,6 @@ "time_to_first_token": 0, "tokens": 776 } - }, - { - "name": "flue.turn", - "type": "llm", - "children": [], - "output": [ - { - "finish_reason": "stop", - "index": 0, - "message": { - "content": "TASK_DONE", - "role": "assistant" - } - } - ], - "metadata": { - "flue.model": "gpt-4o-mini", - "flue.session": "task:task:", - "model": "gpt-4o-mini", - "provider": "flue" - }, - "metrics": { - "completion_tokens": 4, - "duration_ms": 0, - "estimated_cost": 0.0001182, - "prompt_cache_creation_tokens": 0, - "prompt_cached_tokens": 0, - "prompt_tokens": 772, - "tokens": 776 - } } ], "input": "Reply with exactly TASK_DONE and no other text.", diff --git a/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-auto-hook.span-tree.txt b/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-auto-hook.span-tree.txt index 995b14244..d7a9a88b2 100644 --- a/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-auto-hook.span-tree.txt +++ b/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-auto-hook.span-tree.txt @@ -59,44 +59,6 @@ span_tree: │ │ "model": "claude-sonnet-4-5-20250929", │ │ "provider": "anthropic" │ │ } - │ ├── flue.turn [llm] - │ │ output: [ - │ │ { - │ │ "finish_reason": "toolUse", - │ │ "index": 0, - │ │ "message": { - │ │ "content": "I'll complete this instrumented research flow step by step. Starting with step 1:", - │ │ "reasoning": "The user wants me to complete a specific instrumented research flow with these steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url and call summarize_source\n4. After summarize_source returns, reply with exactly \"PROMPT_DONE\" and no other text\n\nThe user emphasizes calling exactly one tool per turn and waiting for each result. Let me start with step 1.", - │ │ "role": "assistant", - │ │ "tool_calls": [ - │ │ { - │ │ "function": { - │ │ "arguments": "{\"query\":\"flue instrumentation\"}", - │ │ "name": "lookup" - │ │ }, - │ │ "id": "", - │ │ "type": "function" - │ │ } - │ │ ] - │ │ } - │ │ } - │ │ ] - │ │ metadata: { - │ │ "flue.model": "claude-sonnet-4-5-20250929", - │ │ "flue.session": "main", - │ │ "flue.thinking": true, - │ │ "model": "claude-sonnet-4-5-20250929", - │ │ "provider": "flue" - │ │ } - │ │ metrics: { - │ │ "completion_tokens": 208, - │ │ "duration_ms": 0, - │ │ "estimated_cost": 0.0038052, - │ │ "prompt_cache_creation_tokens": 0, - │ │ "prompt_cached_tokens": 2184, - │ │ "prompt_tokens": 10, - │ │ "tokens": 2402 - │ │ } │ ├── tool: lookup [tool] │ │ input: { │ │ "query": "flue instrumentation" @@ -184,44 +146,6 @@ span_tree: │ │ "model": "claude-sonnet-4-5-20250929", │ │ "provider": "anthropic" │ │ } - │ ├── flue.turn [llm] - │ │ output: [ - │ │ { - │ │ "finish_reason": "toolUse", - │ │ "index": 0, - │ │ "message": { - │ │ "content": "Now proceeding to step 2:", - │ │ "reasoning": "Good, I got the lookup result with id \"flue-session-2026\". Now I need to proceed to step 2: call web_search with this lookupId and the query \"Braintrust Flue reasoning stream instrumentation\".", - │ │ "role": "assistant", - │ │ "tool_calls": [ - │ │ { - │ │ "function": { - │ │ "arguments": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\"}", - │ │ "name": "web_search" - │ │ }, - │ │ "id": "", - │ │ "type": "function" - │ │ } - │ │ ] - │ │ } - │ │ } - │ │ ] - │ │ metadata: { - │ │ "flue.model": "claude-sonnet-4-5-20250929", - │ │ "flue.session": "main", - │ │ "flue.thinking": true, - │ │ "model": "claude-sonnet-4-5-20250929", - │ │ "provider": "flue" - │ │ } - │ │ metrics: { - │ │ "completion_tokens": 158, - │ │ "duration_ms": 0, - │ │ "estimated_cost": 0.0039942, - │ │ "prompt_cache_creation_tokens": 248, - │ │ "prompt_cached_tokens": 2184, - │ │ "prompt_tokens": 13, - │ │ "tokens": 2603 - │ │ } │ ├── tool: web_search [tool] │ │ input: { │ │ "lookupId": "flue-session-2026", @@ -344,44 +268,6 @@ span_tree: │ │ "model": "claude-sonnet-4-5-20250929", │ │ "provider": "anthropic" │ │ } - │ ├── flue.turn [llm] - │ │ output: [ - │ │ { - │ │ "finish_reason": "toolUse", - │ │ "index": 0, - │ │ "message": { - │ │ "content": "Now proceeding to step 3:", - │ │ "reasoning": "Perfect! I got the web_search results. There's one result with the URL \"https://example.test/flue/reasoning-streams\". Now I need to proceed to step 3: call summarize_source with this URL.", - │ │ "role": "assistant", - │ │ "tool_calls": [ - │ │ { - │ │ "function": { - │ │ "arguments": "{\"url\":\"https://example.test/flue/reasoning-streams\"}", - │ │ "name": "summarize_source" - │ │ }, - │ │ "id": "", - │ │ "type": "function" - │ │ } - │ │ ] - │ │ } - │ │ } - │ │ ] - │ │ metadata: { - │ │ "flue.model": "claude-sonnet-4-5-20250929", - │ │ "flue.session": "main", - │ │ "flue.thinking": true, - │ │ "model": "claude-sonnet-4-5-20250929", - │ │ "provider": "flue" - │ │ } - │ │ metrics: { - │ │ "completion_tokens": 132, - │ │ "duration_ms": 0, - │ │ "estimated_cost": 0.0036261, - │ │ "prompt_cache_creation_tokens": 234, - │ │ "prompt_cached_tokens": 2432, - │ │ "prompt_tokens": 13, - │ │ "tokens": 2811 - │ │ } │ ├── tool: summarize_source [tool] │ │ input: { │ │ "url": "https://example.test/flue/reasoning-streams" @@ -405,164 +291,136 @@ span_tree: │ │ metrics: { │ │ "duration_ms": 0 │ │ } - │ ├── anthropic.messages.create [llm] - │ │ input: [ - │ │ { - │ │ "content": [ - │ │ { - │ │ "text": "Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.", - │ │ "type": "text" - │ │ } - │ │ ], - │ │ "role": "user" - │ │ }, - │ │ { - │ │ "content": [ - │ │ { - │ │ "signature": "EtYFCm4IDRgCKkC/lJUT/EhYE72Jr10vREWOZ4vwSSugL9RsNrhJg9wjli7iCBt2/hEandW2KZpRqluVbV3ehHY/n0Mge6VmWF1cMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMHcfwfYOEmmJZGyBBGgyYm8sT/W36vQdF0dQiMFC5CVRWmqhR2r90pB0R8Wjbq0ITTIN0abxhOezE1NDsrj6CM4/DXLaOsJp4TD5DNCqVBEgEEzFdeaRrRB0CeXdlWoo+wf7yR9EMOVhLmyRf3nItrqN/cb30rpaexhXDm0/Hj3WxQH+o0K73Oyr6qtiDVe9xGNt6v5DrUz31HcE+GJ0Yw8ThoufXvqNyFQV3lLhpZExUDX6hwlmKvaRpj5YH+q5TTx3jAIgzD+zGkgUS0vC7Muftm2VZcuI/2wVsbtWo6hYdvbbdxr+8FzJsCOWc3ptVaUBimC5//HRSNBXFJ9zlkt6l7YxnUeKWiesSdE6h1EJ08Rp4OrAP+oaYWU4v6IODdnJmsqGKbN//i6gGCnAHBBAZr/pnnmEyUOsBGc6ARMOtcwjFIN3/B1YkJi8r8QbbtGHJHfH/v102MSZG8UJk2RXxt1fTQUWNbp0DjA7gUn00H3dnmSAQyqFjKLIFncnhiH5PSSgdvErNB7y/2UBk2CY2i4dpevr+7uvHZDLPjSBcovpvgJ4ihdUM9S080xCm1NNkjs+QP+AQAh20t33t7EN6aZS0+CZcfJxf1QV6mGIkL7BKAPeIXjD8TKuW/at4pqwrvvesI2cZY5RDjC7v7tz/+tqiEkob1s8J3jx2dbIgPBFOR5PFFwPby0H9Guv4ZB63YAlP3sXX+F5fC6fQifQeJK8fuWK+FKe3v+gK/hZcuBuU/Jfhrst4CsEWeaBhmPktZOHu5f85KZ/layh4Pp39yxR0FiHY5eXibsTh2SfDN3K6GAE=", - │ │ "thinking": "The user wants me to complete a specific instrumented research flow with these steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url and call summarize_source\n4. After summarize_source returns, reply with exactly \"PROMPT_DONE\" and no other text\n\nThe user emphasizes calling exactly one tool per turn and waiting for each result. Let me start with step 1.", - │ │ "type": "thinking" - │ │ }, - │ │ { - │ │ "text": "I'll complete this instrumented research flow step by step. Starting with step 1:", - │ │ "type": "text" - │ │ }, - │ │ { - │ │ "id": "", - │ │ "input": { - │ │ "query": "flue instrumentation" - │ │ }, - │ │ "name": "lookup", - │ │ "type": "tool_use" - │ │ } - │ │ ], - │ │ "role": "assistant" - │ │ }, - │ │ { - │ │ "content": [ - │ │ { - │ │ "content": "{\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}", - │ │ "is_error": false, - │ │ "tool_use_id": "toolu_01QHXkUBddKx6pexY4WSjMR1", - │ │ "type": "tool_result" - │ │ } - │ │ ], - │ │ "role": "user" - │ │ }, - │ │ { - │ │ "content": [ - │ │ { - │ │ "signature": "EpEDCm4IDRgCKkAMahve1kB1j4njp1ZSzO8eCK4bb5Ex7MB6tjdoOXfuUDRfkBqvIGdwVly8GiA8GGYC7Y/RVfREXF6A6OXHTwFyMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMI25UM/xFQ9Bh625NGgyP2lwn3SKJlMxLUwciMH3VyS+uXCYaj8hlEdHVLz3HDLA5DCge72pzSyECwbUqqdxyZgtWjWYo/v0qA6XIsirQAQUbwyS/JWdGjeoTVbN2wMlsvu6j2cZmYMhk2HDKvmRIKpFTX5Ha82HBMwuM+f/7faDeQM5ldk8a5Tnm6iWFUj5jOoNqCYa+lBzhWor1vuZ5ieA569nGcMa0z1QmEP8WC3zNkI+kDazdS9FcuJP8KltHVfNr/wf/5AgAYFMt8fIaolvtJmN7uZ0yJKVfuJ58yx0nlQyEkxK8siXz7in2ulTuflohdD37ZErfxQNM3iYlCEfBOfa6kuJhwOwQ+HWJA1LXmUxzR/9AHRq0f3euNXkYAQ==", - │ │ "thinking": "Good, I got the lookup result with id \"flue-session-2026\". Now I need to proceed to step 2: call web_search with this lookupId and the query \"Braintrust Flue reasoning stream instrumentation\".", - │ │ "type": "thinking" - │ │ }, - │ │ { - │ │ "text": "Now proceeding to step 2:", - │ │ "type": "text" - │ │ }, - │ │ { - │ │ "id": "", - │ │ "input": { - │ │ "lookupId": "flue-session-2026", - │ │ "query": "Braintrust Flue reasoning stream instrumentation" - │ │ }, - │ │ "name": "web_search", - │ │ "type": "tool_use" - │ │ } - │ │ ], - │ │ "role": "assistant" - │ │ }, - │ │ { - │ │ "content": [ - │ │ { - │ │ "content": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\",\"results\":[{\"title\":\"Flue reasoning stream instrumentation\",\"url\":\"https://example.test/flue/reasoning-streams\"}]}", - │ │ "is_error": false, - │ │ "tool_use_id": "toolu_01CvT1mSWwETua7LWwSQiyq6", - │ │ "type": "tool_result" - │ │ } - │ │ ], - │ │ "role": "user" - │ │ }, - │ │ { - │ │ "content": [ - │ │ { - │ │ "signature": "EowDCm4IDRgCKkCpqmoUHjbaZYvB4bWm+hVDlxgU/iOCEn0v3xAMT4QsjKM7cIZMOWD2eEF8ENjGq0ttAvO8ZNI9YpiASikG2gnNMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMI5+VQnffadMSNsXEGgy1YAi10m6jJ39wq2UiMAUy8rg67GdkT4VUKix3ULTWnPfKucap7VLRPGDqK7ZhF0nDl2pcYGshMviSbzOjuyrLAXh3IPAAc3rvDuYAAHaWed6JE7/4gg/gzWhfVeAb0qXzXoiIHh8Z9KyHDfDDfpesr4TzmJHT/T8mhem3UfZc87ZLzFom8Vi+76Y2eVWcoI/EyPuyj+KVxU5kPh030LYWxUeSTUViRu9NAd+Wzz/5ZAgD+TiEmCnpNMI3eGqOiBPtwK7y/JIvxZRWvsJ1ghXNaEVShN3h8OUk9zmzIhBuUujWVZtc5wuM28726mOqMLwKckegl+q2vNrR+U+AqbMSYWUVlWLKZvd1LXiZGAE=", - │ │ "thinking": "Perfect! I got the web_search results. There's one result with the URL \"https://example.test/flue/reasoning-streams\". Now I need to proceed to step 3: call summarize_source with this URL.", - │ │ "type": "thinking" - │ │ }, - │ │ { - │ │ "text": "Now proceeding to step 3:", - │ │ "type": "text" - │ │ }, - │ │ { - │ │ "id": "", - │ │ "input": { - │ │ "url": "https://example.test/flue/reasoning-streams" - │ │ }, - │ │ "name": "summarize_source", - │ │ "type": "tool_use" - │ │ } - │ │ ], - │ │ "role": "assistant" - │ │ }, - │ │ { - │ │ "content": [ - │ │ { - │ │ "cache_control": { - │ │ "type": "ephemeral" - │ │ }, - │ │ "content": "{\"summary\":\"Flue emits reasoning, tool execution, and LLM turn events separately.\",\"url\":\"https://example.test/flue/reasoning-streams\"}", - │ │ "is_error": false, - │ │ "tool_use_id": "toolu_01NHkkJuQNXyRuWk58FCecye", - │ │ "type": "tool_result" - │ │ } - │ │ ], - │ │ "role": "user" - │ │ }, - │ │ { - │ │ "content": [ - │ │ { - │ │ "cache_control": { - │ │ "type": "ephemeral" - │ │ }, - │ │ "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /e2e/scenarios/flue-instrumentation/\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", - │ │ "type": "text" - │ │ } - │ │ ], - │ │ "role": "system" - │ │ } - │ │ ] - │ │ metadata: { - │ │ "model": "claude-sonnet-4-5-20250929", - │ │ "provider": "anthropic" - │ │ } - │ └── flue.turn [llm] - │ output: [ + │ └── anthropic.messages.create [llm] + │ input: [ │ { - │ "finish_reason": "stop", - │ "index": 0, - │ "message": { - │ "content": "PROMPT_DONE", - │ "reasoning": "The summarize_source has returned successfully. According to the instructions, I should now reply with exactly \"PROMPT_DONE\" and no other text.", - │ "role": "assistant" - │ } + │ "content": [ + │ { + │ "text": "Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ }, + │ { + │ "content": [ + │ { + │ "signature": "EtYFCm4IDRgCKkC/lJUT/EhYE72Jr10vREWOZ4vwSSugL9RsNrhJg9wjli7iCBt2/hEandW2KZpRqluVbV3ehHY/n0Mge6VmWF1cMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMHcfwfYOEmmJZGyBBGgyYm8sT/W36vQdF0dQiMFC5CVRWmqhR2r90pB0R8Wjbq0ITTIN0abxhOezE1NDsrj6CM4/DXLaOsJp4TD5DNCqVBEgEEzFdeaRrRB0CeXdlWoo+wf7yR9EMOVhLmyRf3nItrqN/cb30rpaexhXDm0/Hj3WxQH+o0K73Oyr6qtiDVe9xGNt6v5DrUz31HcE+GJ0Yw8ThoufXvqNyFQV3lLhpZExUDX6hwlmKvaRpj5YH+q5TTx3jAIgzD+zGkgUS0vC7Muftm2VZcuI/2wVsbtWo6hYdvbbdxr+8FzJsCOWc3ptVaUBimC5//HRSNBXFJ9zlkt6l7YxnUeKWiesSdE6h1EJ08Rp4OrAP+oaYWU4v6IODdnJmsqGKbN//i6gGCnAHBBAZr/pnnmEyUOsBGc6ARMOtcwjFIN3/B1YkJi8r8QbbtGHJHfH/v102MSZG8UJk2RXxt1fTQUWNbp0DjA7gUn00H3dnmSAQyqFjKLIFncnhiH5PSSgdvErNB7y/2UBk2CY2i4dpevr+7uvHZDLPjSBcovpvgJ4ihdUM9S080xCm1NNkjs+QP+AQAh20t33t7EN6aZS0+CZcfJxf1QV6mGIkL7BKAPeIXjD8TKuW/at4pqwrvvesI2cZY5RDjC7v7tz/+tqiEkob1s8J3jx2dbIgPBFOR5PFFwPby0H9Guv4ZB63YAlP3sXX+F5fC6fQifQeJK8fuWK+FKe3v+gK/hZcuBuU/Jfhrst4CsEWeaBhmPktZOHu5f85KZ/layh4Pp39yxR0FiHY5eXibsTh2SfDN3K6GAE=", + │ "thinking": "The user wants me to complete a specific instrumented research flow with these steps:\n1. Call lookup with query \"flue instrumentation\"\n2. Use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\"\n3. Use the first web_search result url and call summarize_source\n4. After summarize_source returns, reply with exactly \"PROMPT_DONE\" and no other text\n\nThe user emphasizes calling exactly one tool per turn and waiting for each result. Let me start with step 1.", + │ "type": "thinking" + │ }, + │ { + │ "text": "I'll complete this instrumented research flow step by step. Starting with step 1:", + │ "type": "text" + │ }, + │ { + │ "id": "", + │ "input": { + │ "query": "flue instrumentation" + │ }, + │ "name": "lookup", + │ "type": "tool_use" + │ } + │ ], + │ "role": "assistant" + │ }, + │ { + │ "content": [ + │ { + │ "content": "{\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}", + │ "is_error": false, + │ "tool_use_id": "toolu_01QHXkUBddKx6pexY4WSjMR1", + │ "type": "tool_result" + │ } + │ ], + │ "role": "user" + │ }, + │ { + │ "content": [ + │ { + │ "signature": "EpEDCm4IDRgCKkAMahve1kB1j4njp1ZSzO8eCK4bb5Ex7MB6tjdoOXfuUDRfkBqvIGdwVly8GiA8GGYC7Y/RVfREXF6A6OXHTwFyMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMI25UM/xFQ9Bh625NGgyP2lwn3SKJlMxLUwciMH3VyS+uXCYaj8hlEdHVLz3HDLA5DCge72pzSyECwbUqqdxyZgtWjWYo/v0qA6XIsirQAQUbwyS/JWdGjeoTVbN2wMlsvu6j2cZmYMhk2HDKvmRIKpFTX5Ha82HBMwuM+f/7faDeQM5ldk8a5Tnm6iWFUj5jOoNqCYa+lBzhWor1vuZ5ieA569nGcMa0z1QmEP8WC3zNkI+kDazdS9FcuJP8KltHVfNr/wf/5AgAYFMt8fIaolvtJmN7uZ0yJKVfuJ58yx0nlQyEkxK8siXz7in2ulTuflohdD37ZErfxQNM3iYlCEfBOfa6kuJhwOwQ+HWJA1LXmUxzR/9AHRq0f3euNXkYAQ==", + │ "thinking": "Good, I got the lookup result with id \"flue-session-2026\". Now I need to proceed to step 2: call web_search with this lookupId and the query \"Braintrust Flue reasoning stream instrumentation\".", + │ "type": "thinking" + │ }, + │ { + │ "text": "Now proceeding to step 2:", + │ "type": "text" + │ }, + │ { + │ "id": "", + │ "input": { + │ "lookupId": "flue-session-2026", + │ "query": "Braintrust Flue reasoning stream instrumentation" + │ }, + │ "name": "web_search", + │ "type": "tool_use" + │ } + │ ], + │ "role": "assistant" + │ }, + │ { + │ "content": [ + │ { + │ "content": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\",\"results\":[{\"title\":\"Flue reasoning stream instrumentation\",\"url\":\"https://example.test/flue/reasoning-streams\"}]}", + │ "is_error": false, + │ "tool_use_id": "toolu_01CvT1mSWwETua7LWwSQiyq6", + │ "type": "tool_result" + │ } + │ ], + │ "role": "user" + │ }, + │ { + │ "content": [ + │ { + │ "signature": "EowDCm4IDRgCKkCpqmoUHjbaZYvB4bWm+hVDlxgU/iOCEn0v3xAMT4QsjKM7cIZMOWD2eEF8ENjGq0ttAvO8ZNI9YpiASikG2gnNMhpjbGF1ZGUtc29ubmV0LTQtNS0yMDI1MDkyOTgAQgh0aGlua2luZxIMI5+VQnffadMSNsXEGgy1YAi10m6jJ39wq2UiMAUy8rg67GdkT4VUKix3ULTWnPfKucap7VLRPGDqK7ZhF0nDl2pcYGshMviSbzOjuyrLAXh3IPAAc3rvDuYAAHaWed6JE7/4gg/gzWhfVeAb0qXzXoiIHh8Z9KyHDfDDfpesr4TzmJHT/T8mhem3UfZc87ZLzFom8Vi+76Y2eVWcoI/EyPuyj+KVxU5kPh030LYWxUeSTUViRu9NAd+Wzz/5ZAgD+TiEmCnpNMI3eGqOiBPtwK7y/JIvxZRWvsJ1ghXNaEVShN3h8OUk9zmzIhBuUujWVZtc5wuM28726mOqMLwKckegl+q2vNrR+U+AqbMSYWUVlWLKZvd1LXiZGAE=", + │ "thinking": "Perfect! I got the web_search results. There's one result with the URL \"https://example.test/flue/reasoning-streams\". Now I need to proceed to step 3: call summarize_source with this URL.", + │ "type": "thinking" + │ }, + │ { + │ "text": "Now proceeding to step 3:", + │ "type": "text" + │ }, + │ { + │ "id": "", + │ "input": { + │ "url": "https://example.test/flue/reasoning-streams" + │ }, + │ "name": "summarize_source", + │ "type": "tool_use" + │ } + │ ], + │ "role": "assistant" + │ }, + │ { + │ "content": [ + │ { + │ "cache_control": { + │ "type": "ephemeral" + │ }, + │ "content": "{\"summary\":\"Flue emits reasoning, tool execution, and LLM turn events separately.\",\"url\":\"https://example.test/flue/reasoning-streams\"}", + │ "is_error": false, + │ "tool_use_id": "toolu_01NHkkJuQNXyRuWk58FCecye", + │ "type": "tool_result" + │ } + │ ], + │ "role": "user" + │ }, + │ { + │ "content": [ + │ { + │ "cache_control": { + │ "type": "ephemeral" + │ }, + │ "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /e2e/scenarios/flue-instrumentation/\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + │ "type": "text" + │ } + │ ], + │ "role": "system" │ } │ ] │ metadata: { - │ "flue.model": "claude-sonnet-4-5-20250929", - │ "flue.session": "main", - │ "flue.thinking": true, │ "model": "claude-sonnet-4-5-20250929", - │ "provider": "flue" - │ } - │ metrics: { - │ "completion_tokens": 48, - │ "duration_ms": 0, - │ "estimated_cost": 0.0022638, - │ "prompt_cache_creation_tokens": 188, - │ "prompt_cached_tokens": 2666, - │ "prompt_tokens": 13, - │ "tokens": 2915 + │ "provider": "anthropic" │ } ├── flue-skill-operation │ metadata: { @@ -626,42 +484,6 @@ span_tree: │ │ "model": "claude-sonnet-4-5-20250929", │ │ "provider": "anthropic" │ │ } - │ ├── flue.turn [llm] - │ │ output: [ - │ │ { - │ │ "finish_reason": "toolUse", - │ │ "index": 0, - │ │ "message": { - │ │ "content": "I'll read the skill file and execute it according to its instructions.", - │ │ "role": "assistant", - │ │ "tool_calls": [ - │ │ { - │ │ "function": { - │ │ "arguments": "{\"path\":\".agents/skills/e2e-flue-skill/SKILL.md\"}", - │ │ "name": "read" - │ │ }, - │ │ "id": "", - │ │ "type": "function" - │ │ } - │ │ ] - │ │ } - │ │ } - │ │ ] - │ │ metadata: { - │ │ "flue.model": "claude-sonnet-4-5-20250929", - │ │ "flue.session": "skill", - │ │ "model": "claude-sonnet-4-5-20250929", - │ │ "provider": "flue" - │ │ } - │ │ metrics: { - │ │ "completion_tokens": 83, - │ │ "duration_ms": 0, - │ │ "estimated_cost": 0.0017973, - │ │ "prompt_cache_creation_tokens": 0, - │ │ "prompt_cached_tokens": 1811, - │ │ "prompt_tokens": 3, - │ │ "tokens": 1897 - │ │ } │ ├── tool: read [tool] │ │ input: { │ │ "path": ".agents/skills/e2e-flue-skill/SKILL.md" @@ -686,90 +508,64 @@ span_tree: │ │ metrics: { │ │ "duration_ms": 0 │ │ } - │ ├── anthropic.messages.create [llm] - │ │ input: [ - │ │ { - │ │ "content": [ - │ │ { - │ │ "text": "Run the skill named \"e2e-flue-skill\".\n\nArguments:\n{\n \"marker\": \"SKILL_DONE\"\n}", - │ │ "type": "text" - │ │ } - │ │ ], - │ │ "role": "user" - │ │ }, - │ │ { - │ │ "content": [ - │ │ { - │ │ "text": "I'll read the skill file and execute it according to its instructions.", - │ │ "type": "text" - │ │ }, - │ │ { - │ │ "id": "", - │ │ "input": { - │ │ "path": ".agents/skills/e2e-flue-skill/SKILL.md" - │ │ }, - │ │ "name": "read", - │ │ "type": "tool_use" - │ │ } - │ │ ], - │ │ "role": "assistant" - │ │ }, - │ │ { - │ │ "content": [ - │ │ { - │ │ "cache_control": { - │ │ "type": "ephemeral" - │ │ }, - │ │ "content": "---\nname: e2e-flue-skill\ndescription: Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n---\n\nReturn the marker from the provided args exactly once. Output no other text.\n", - │ │ "is_error": false, - │ │ "tool_use_id": "toolu_01HmmsNYZUC67GqVoKKLbfiQ", - │ │ "type": "tool_result" - │ │ } - │ │ ], - │ │ "role": "user" - │ │ }, - │ │ { - │ │ "content": [ - │ │ { - │ │ "cache_control": { - │ │ "type": "ephemeral" - │ │ }, - │ │ "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /e2e/scenarios/flue-instrumentation/\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts\n\n\nNever call the task tool. Do not delegate e2e-flue-skill to another session. If you need the skill body, read .agents/skills/e2e-flue-skill/SKILL.md yourself with the read tool. Return the marker from the Arguments object exactly, with no other text.\n", - │ │ "type": "text" - │ │ } - │ │ ], - │ │ "role": "system" - │ │ } - │ │ ] - │ │ metadata: { - │ │ "model": "claude-sonnet-4-5-20250929", - │ │ "provider": "anthropic" - │ │ } - │ └── flue.turn [llm] - │ output: [ + │ └── anthropic.messages.create [llm] + │ input: [ + │ { + │ "content": [ + │ { + │ "text": "Run the skill named \"e2e-flue-skill\".\n\nArguments:\n{\n \"marker\": \"SKILL_DONE\"\n}", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ }, + │ { + │ "content": [ + │ { + │ "text": "I'll read the skill file and execute it according to its instructions.", + │ "type": "text" + │ }, + │ { + │ "id": "", + │ "input": { + │ "path": ".agents/skills/e2e-flue-skill/SKILL.md" + │ }, + │ "name": "read", + │ "type": "tool_use" + │ } + │ ], + │ "role": "assistant" + │ }, │ { - │ "finish_reason": "stop", - │ "index": 0, - │ "message": { - │ "content": "SKILL_DONE", - │ "role": "assistant" - │ } + │ "content": [ + │ { + │ "cache_control": { + │ "type": "ephemeral" + │ }, + │ "content": "---\nname: e2e-flue-skill\ndescription: Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n---\n\nReturn the marker from the provided args exactly once. Output no other text.\n", + │ "is_error": false, + │ "tool_use_id": "toolu_01HmmsNYZUC67GqVoKKLbfiQ", + │ "type": "tool_result" + │ } + │ ], + │ "role": "user" + │ }, + │ { + │ "content": [ + │ { + │ "cache_control": { + │ "type": "ephemeral" + │ }, + │ "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /e2e/scenarios/flue-instrumentation/\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts\n\n\nNever call the task tool. Do not delegate e2e-flue-skill to another session. If you need the skill body, read .agents/skills/e2e-flue-skill/SKILL.md yourself with the read tool. Return the marker from the Arguments object exactly, with no other text.\n", + │ "type": "text" + │ } + │ ], + │ "role": "system" │ } │ ] │ metadata: { - │ "flue.model": "claude-sonnet-4-5-20250929", - │ "flue.session": "skill", │ "model": "claude-sonnet-4-5-20250929", - │ "provider": "flue" - │ } - │ metrics: { - │ "completion_tokens": 8, - │ "duration_ms": 0, - │ "estimated_cost": 0.0012325499999999998, - │ "prompt_cache_creation_tokens": 147, - │ "prompt_cached_tokens": 1811, - │ "prompt_tokens": 6, - │ "tokens": 1972 + │ "provider": "anthropic" │ } ├── flue-task-operation │ metadata: { @@ -805,74 +601,48 @@ span_tree: │ │ metrics: { │ │ "duration_ms": 0 │ │ } - │ ├── openai.responses.create [llm] - │ │ input: [ - │ │ { - │ │ "content": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /e2e/scenarios/flue-instrumentation/\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", - │ │ "role": "system" - │ │ }, - │ │ { - │ │ "content": [ - │ │ { - │ │ "text": "Reply with exactly TASK_DONE and no other text.", - │ │ "type": "input_text" - │ │ } - │ │ ], - │ │ "role": "user" - │ │ } - │ │ ] - │ │ output: [ - │ │ { - │ │ "content": [ - │ │ { - │ │ "annotations": [], - │ │ "logprobs": [], - │ │ "text": "TASK_DONE", - │ │ "type": "output_text" - │ │ } - │ │ ], - │ │ "id": "", - │ │ "role": "assistant", - │ │ "status": "completed", - │ │ "type": "message" - │ │ } - │ │ ] - │ │ metadata: { - │ │ "model": "gpt-4o-mini-2024-07-18", - │ │ "provider": "openai" - │ │ } - │ │ metrics: { - │ │ "completion_reasoning_tokens": 0, - │ │ "completion_tokens": 4, - │ │ "prompt_cached_tokens": 0, - │ │ "prompt_tokens": 772, - │ │ "time_to_first_token": 0, - │ │ "tokens": 776 - │ │ } - │ └── flue.turn [llm] + │ └── openai.responses.create [llm] + │ input: [ + │ { + │ "content": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /e2e/scenarios/flue-instrumentation/\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + │ "role": "system" + │ }, + │ { + │ "content": [ + │ { + │ "text": "Reply with exactly TASK_DONE and no other text.", + │ "type": "input_text" + │ } + │ ], + │ "role": "user" + │ } + │ ] │ output: [ │ { - │ "finish_reason": "stop", - │ "index": 0, - │ "message": { - │ "content": "TASK_DONE", - │ "role": "assistant" - │ } + │ "content": [ + │ { + │ "annotations": [], + │ "logprobs": [], + │ "text": "TASK_DONE", + │ "type": "output_text" + │ } + │ ], + │ "id": "", + │ "role": "assistant", + │ "status": "completed", + │ "type": "message" │ } │ ] │ metadata: { - │ "flue.model": "gpt-4o-mini", - │ "flue.session": "task:task:", - │ "model": "gpt-4o-mini", - │ "provider": "flue" + │ "model": "gpt-4o-mini-2024-07-18", + │ "provider": "openai" │ } │ metrics: { + │ "completion_reasoning_tokens": 0, │ "completion_tokens": 4, - │ "duration_ms": 0, - │ "estimated_cost": 0.0001182, - │ "prompt_cache_creation_tokens": 0, │ "prompt_cached_tokens": 0, │ "prompt_tokens": 772, + │ "time_to_first_token": 0, │ "tokens": 776 │ } └── flue-compact-operation diff --git a/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-openai-auto-hook.span-tree.json b/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-openai-auto-hook.span-tree.json index 194112ac7..c8ecd0bf8 100644 --- a/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-openai-auto-hook.span-tree.json +++ b/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-openai-auto-hook.span-tree.json @@ -53,46 +53,6 @@ "tokens": 962 } }, - { - "name": "flue.turn", - "type": "llm", - "children": [], - "output": [ - { - "finish_reason": "toolUse", - "index": 0, - "message": { - "content": "", - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"query\":\"flue instrumentation\"}", - "name": "lookup" - }, - "id": "", - "type": "function" - } - ] - } - } - ], - "metadata": { - "flue.model": "gpt-4o-mini", - "flue.session": "main", - "model": "gpt-4o-mini", - "provider": "flue" - }, - "metrics": { - "completion_tokens": 16, - "duration_ms": 0, - "estimated_cost": 0.0001515, - "prompt_cache_creation_tokens": 0, - "prompt_cached_tokens": 0, - "prompt_tokens": 946, - "tokens": 962 - } - }, { "name": "tool: lookup", "type": "tool", @@ -174,46 +134,6 @@ "tokens": 1018 } }, - { - "name": "flue.turn", - "type": "llm", - "children": [], - "output": [ - { - "finish_reason": "toolUse", - "index": 0, - "message": { - "content": "", - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\"}", - "name": "web_search" - }, - "id": "", - "type": "function" - } - ] - } - } - ], - "metadata": { - "flue.model": "gpt-4o-mini", - "flue.session": "main", - "model": "gpt-4o-mini", - "provider": "flue" - }, - "metrics": { - "completion_tokens": 31, - "duration_ms": 0, - "estimated_cost": 0.00016664999999999998, - "prompt_cache_creation_tokens": 0, - "prompt_cached_tokens": 0, - "prompt_tokens": 987, - "tokens": 1018 - } - }, { "name": "tool: web_search", "type": "tool", @@ -308,46 +228,6 @@ "tokens": 1097 } }, - { - "name": "flue.turn", - "type": "llm", - "children": [], - "output": [ - { - "finish_reason": "toolUse", - "index": 0, - "message": { - "content": "", - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"url\":\"https://example.test/flue/reasoning-streams\"}", - "name": "summarize_source" - }, - "id": "", - "type": "function" - } - ] - } - } - ], - "metadata": { - "flue.model": "gpt-4o-mini", - "flue.session": "main", - "model": "gpt-4o-mini", - "provider": "flue" - }, - "metrics": { - "completion_tokens": 27, - "duration_ms": 0, - "estimated_cost": 0.0001767, - "prompt_cache_creation_tokens": 0, - "prompt_cached_tokens": 0, - "prompt_tokens": 1070, - "tokens": 1097 - } - }, { "name": "tool: summarize_source", "type": "tool", @@ -458,36 +338,6 @@ "time_to_first_token": 0, "tokens": 1141 } - }, - { - "name": "flue.turn", - "type": "llm", - "children": [], - "output": [ - { - "finish_reason": "stop", - "index": 0, - "message": { - "content": "PROMPT_DONE", - "role": "assistant" - } - } - ], - "metadata": { - "flue.model": "gpt-4o-mini", - "flue.session": "main", - "model": "gpt-4o-mini", - "provider": "flue" - }, - "metrics": { - "completion_tokens": 5, - "duration_ms": 0, - "estimated_cost": 0.00010172, - "prompt_cache_creation_tokens": 0, - "prompt_cached_tokens": 1024, - "prompt_tokens": 112, - "tokens": 1141 - } } ], "input": "Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.", @@ -558,46 +408,6 @@ "provider": "anthropic" } }, - { - "name": "flue.turn", - "type": "llm", - "children": [], - "output": [ - { - "finish_reason": "toolUse", - "index": 0, - "message": { - "content": "I'll run the e2e-flue-skill by reading its instructions and following them.", - "role": "assistant", - "tool_calls": [ - { - "function": { - "arguments": "{\"path\":\".agents/skills/e2e-flue-skill/SKILL.md\"}", - "name": "read" - }, - "id": "", - "type": "function" - } - ] - } - } - ], - "metadata": { - "flue.model": "claude-sonnet-4-5-20250929", - "flue.session": "skill", - "model": "claude-sonnet-4-5-20250929", - "provider": "flue" - }, - "metrics": { - "completion_tokens": 89, - "duration_ms": 0, - "estimated_cost": 0.0018872999999999997, - "prompt_cache_creation_tokens": 0, - "prompt_cached_tokens": 1811, - "prompt_tokens": 3, - "tokens": 1903 - } - }, { "name": "tool: read", "type": "tool", @@ -688,36 +498,6 @@ "model": "claude-sonnet-4-5-20250929", "provider": "anthropic" } - }, - { - "name": "flue.turn", - "type": "llm", - "children": [], - "output": [ - { - "finish_reason": "stop", - "index": 0, - "message": { - "content": "SKILL_DONE", - "role": "assistant" - } - } - ], - "metadata": { - "flue.model": "claude-sonnet-4-5-20250929", - "flue.session": "skill", - "model": "claude-sonnet-4-5-20250929", - "provider": "flue" - }, - "metrics": { - "completion_tokens": 8, - "duration_ms": 0, - "estimated_cost": 0.0007272, - "prompt_cache_creation_tokens": 0, - "prompt_cached_tokens": 1964, - "prompt_tokens": 6, - "tokens": 1978 - } } ], "input": { @@ -820,36 +600,6 @@ "time_to_first_token": 0, "tokens": 776 } - }, - { - "name": "flue.turn", - "type": "llm", - "children": [], - "output": [ - { - "finish_reason": "stop", - "index": 0, - "message": { - "content": "TASK_DONE", - "role": "assistant" - } - } - ], - "metadata": { - "flue.model": "gpt-4o-mini", - "flue.session": "task:task:", - "model": "gpt-4o-mini", - "provider": "flue" - }, - "metrics": { - "completion_tokens": 4, - "duration_ms": 0, - "estimated_cost": 0.0001182, - "prompt_cache_creation_tokens": 0, - "prompt_cached_tokens": 0, - "prompt_tokens": 772, - "tokens": 776 - } } ], "input": "Reply with exactly TASK_DONE and no other text.", diff --git a/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-openai-auto-hook.span-tree.txt b/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-openai-auto-hook.span-tree.txt index 55d1342c6..8d9716823 100644 --- a/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-openai-auto-hook.span-tree.txt +++ b/e2e/scenarios/flue-instrumentation/__snapshots__/flue-v0-7-0-openai-auto-hook.span-tree.txt @@ -66,42 +66,6 @@ span_tree: │ │ "time_to_first_token": 0, │ │ "tokens": 962 │ │ } - │ ├── flue.turn [llm] - │ │ output: [ - │ │ { - │ │ "finish_reason": "toolUse", - │ │ "index": 0, - │ │ "message": { - │ │ "content": "", - │ │ "role": "assistant", - │ │ "tool_calls": [ - │ │ { - │ │ "function": { - │ │ "arguments": "{\"query\":\"flue instrumentation\"}", - │ │ "name": "lookup" - │ │ }, - │ │ "id": "", - │ │ "type": "function" - │ │ } - │ │ ] - │ │ } - │ │ } - │ │ ] - │ │ metadata: { - │ │ "flue.model": "gpt-4o-mini", - │ │ "flue.session": "main", - │ │ "model": "gpt-4o-mini", - │ │ "provider": "flue" - │ │ } - │ │ metrics: { - │ │ "completion_tokens": 16, - │ │ "duration_ms": 0, - │ │ "estimated_cost": 0.0001515, - │ │ "prompt_cache_creation_tokens": 0, - │ │ "prompt_cached_tokens": 0, - │ │ "prompt_tokens": 946, - │ │ "tokens": 962 - │ │ } │ ├── tool: lookup [tool] │ │ input: { │ │ "query": "flue instrumentation" @@ -175,42 +139,6 @@ span_tree: │ │ "time_to_first_token": 0, │ │ "tokens": 1018 │ │ } - │ ├── flue.turn [llm] - │ │ output: [ - │ │ { - │ │ "finish_reason": "toolUse", - │ │ "index": 0, - │ │ "message": { - │ │ "content": "", - │ │ "role": "assistant", - │ │ "tool_calls": [ - │ │ { - │ │ "function": { - │ │ "arguments": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\"}", - │ │ "name": "web_search" - │ │ }, - │ │ "id": "", - │ │ "type": "function" - │ │ } - │ │ ] - │ │ } - │ │ } - │ │ ] - │ │ metadata: { - │ │ "flue.model": "gpt-4o-mini", - │ │ "flue.session": "main", - │ │ "model": "gpt-4o-mini", - │ │ "provider": "flue" - │ │ } - │ │ metrics: { - │ │ "completion_tokens": 31, - │ │ "duration_ms": 0, - │ │ "estimated_cost": 0.00016664999999999998, - │ │ "prompt_cache_creation_tokens": 0, - │ │ "prompt_cached_tokens": 0, - │ │ "prompt_tokens": 987, - │ │ "tokens": 1018 - │ │ } │ ├── tool: web_search [tool] │ │ input: { │ │ "lookupId": "flue-session-2026", @@ -297,42 +225,6 @@ span_tree: │ │ "time_to_first_token": 0, │ │ "tokens": 1097 │ │ } - │ ├── flue.turn [llm] - │ │ output: [ - │ │ { - │ │ "finish_reason": "toolUse", - │ │ "index": 0, - │ │ "message": { - │ │ "content": "", - │ │ "role": "assistant", - │ │ "tool_calls": [ - │ │ { - │ │ "function": { - │ │ "arguments": "{\"url\":\"https://example.test/flue/reasoning-streams\"}", - │ │ "name": "summarize_source" - │ │ }, - │ │ "id": "", - │ │ "type": "function" - │ │ } - │ │ ] - │ │ } - │ │ } - │ │ ] - │ │ metadata: { - │ │ "flue.model": "gpt-4o-mini", - │ │ "flue.session": "main", - │ │ "model": "gpt-4o-mini", - │ │ "provider": "flue" - │ │ } - │ │ metrics: { - │ │ "completion_tokens": 27, - │ │ "duration_ms": 0, - │ │ "estimated_cost": 0.0001767, - │ │ "prompt_cache_creation_tokens": 0, - │ │ "prompt_cached_tokens": 0, - │ │ "prompt_tokens": 1070, - │ │ "tokens": 1097 - │ │ } │ ├── tool: summarize_source [tool] │ │ input: { │ │ "url": "https://example.test/flue/reasoning-streams" @@ -356,110 +248,84 @@ span_tree: │ │ metrics: { │ │ "duration_ms": 0 │ │ } - │ ├── openai.responses.create [llm] - │ │ input: [ - │ │ { - │ │ "content": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /e2e/scenarios/flue-instrumentation/\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", - │ │ "role": "system" - │ │ }, - │ │ { - │ │ "content": [ - │ │ { - │ │ "text": "Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.", - │ │ "type": "input_text" - │ │ } - │ │ ], - │ │ "role": "user" - │ │ }, - │ │ { - │ │ "arguments": "{\"query\":\"flue instrumentation\"}", - │ │ "call_id": "call_xELft1kjhTSvPWAp3Z3i4zWk", - │ │ "id": "", - │ │ "name": "lookup", - │ │ "type": "function_call" - │ │ }, - │ │ { - │ │ "call_id": "call_xELft1kjhTSvPWAp3Z3i4zWk", - │ │ "output": "{\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}", - │ │ "type": "function_call_output" - │ │ }, - │ │ { - │ │ "arguments": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\"}", - │ │ "call_id": "call_F7zI4fCOw4jk7rTwqbi8umo7", - │ │ "id": "", - │ │ "name": "web_search", - │ │ "type": "function_call" - │ │ }, - │ │ { - │ │ "call_id": "call_F7zI4fCOw4jk7rTwqbi8umo7", - │ │ "output": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\",\"results\":[{\"title\":\"Flue reasoning stream instrumentation\",\"url\":\"https://example.test/flue/reasoning-streams\"}]}", - │ │ "type": "function_call_output" - │ │ }, - │ │ { - │ │ "arguments": "{\"url\":\"https://example.test/flue/reasoning-streams\"}", - │ │ "call_id": "call_0yinp9edeamv8mKgyhkpaCmG", - │ │ "id": "", - │ │ "name": "summarize_source", - │ │ "type": "function_call" - │ │ }, - │ │ { - │ │ "call_id": "call_0yinp9edeamv8mKgyhkpaCmG", - │ │ "output": "{\"summary\":\"Flue emits reasoning, tool execution, and LLM turn events separately.\",\"url\":\"https://example.test/flue/reasoning-streams\"}", - │ │ "type": "function_call_output" - │ │ } - │ │ ] - │ │ output: [ - │ │ { - │ │ "content": [ - │ │ { - │ │ "annotations": [], - │ │ "logprobs": [], - │ │ "text": "PROMPT_DONE", - │ │ "type": "output_text" - │ │ } - │ │ ], - │ │ "id": "", - │ │ "role": "assistant", - │ │ "status": "completed", - │ │ "type": "message" - │ │ } - │ │ ] - │ │ metadata: { - │ │ "model": "gpt-4o-mini-2024-07-18", - │ │ "provider": "openai" - │ │ } - │ │ metrics: { - │ │ "completion_reasoning_tokens": 0, - │ │ "completion_tokens": 5, - │ │ "prompt_cached_tokens": 1024, - │ │ "prompt_tokens": 1136, - │ │ "time_to_first_token": 0, - │ │ "tokens": 1141 - │ │ } - │ └── flue.turn [llm] + │ └── openai.responses.create [llm] + │ input: [ + │ { + │ "content": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /e2e/scenarios/flue-instrumentation/\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + │ "role": "system" + │ }, + │ { + │ "content": [ + │ { + │ "text": "Complete this instrumented research flow. Call exactly one tool per turn and wait for each tool result before choosing the next tool. Step 1: call lookup with query \"flue instrumentation\". Step 2: use the lookup result id as lookupId and call web_search with query \"Braintrust Flue reasoning stream instrumentation\". Step 3: use the first web_search result url and call summarize_source. After summarize_source returns, reply with exactly PROMPT_DONE and no other text.", + │ "type": "input_text" + │ } + │ ], + │ "role": "user" + │ }, + │ { + │ "arguments": "{\"query\":\"flue instrumentation\"}", + │ "call_id": "call_xELft1kjhTSvPWAp3Z3i4zWk", + │ "id": "", + │ "name": "lookup", + │ "type": "function_call" + │ }, + │ { + │ "call_id": "call_xELft1kjhTSvPWAp3Z3i4zWk", + │ "output": "{\"id\":\"flue-session-2026\",\"query\":\"flue instrumentation\",\"topic\":\"session instrumentation\"}", + │ "type": "function_call_output" + │ }, + │ { + │ "arguments": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\"}", + │ "call_id": "call_F7zI4fCOw4jk7rTwqbi8umo7", + │ "id": "", + │ "name": "web_search", + │ "type": "function_call" + │ }, + │ { + │ "call_id": "call_F7zI4fCOw4jk7rTwqbi8umo7", + │ "output": "{\"lookupId\":\"flue-session-2026\",\"query\":\"Braintrust Flue reasoning stream instrumentation\",\"results\":[{\"title\":\"Flue reasoning stream instrumentation\",\"url\":\"https://example.test/flue/reasoning-streams\"}]}", + │ "type": "function_call_output" + │ }, + │ { + │ "arguments": "{\"url\":\"https://example.test/flue/reasoning-streams\"}", + │ "call_id": "call_0yinp9edeamv8mKgyhkpaCmG", + │ "id": "", + │ "name": "summarize_source", + │ "type": "function_call" + │ }, + │ { + │ "call_id": "call_0yinp9edeamv8mKgyhkpaCmG", + │ "output": "{\"summary\":\"Flue emits reasoning, tool execution, and LLM turn events separately.\",\"url\":\"https://example.test/flue/reasoning-streams\"}", + │ "type": "function_call_output" + │ } + │ ] │ output: [ │ { - │ "finish_reason": "stop", - │ "index": 0, - │ "message": { - │ "content": "PROMPT_DONE", - │ "role": "assistant" - │ } + │ "content": [ + │ { + │ "annotations": [], + │ "logprobs": [], + │ "text": "PROMPT_DONE", + │ "type": "output_text" + │ } + │ ], + │ "id": "", + │ "role": "assistant", + │ "status": "completed", + │ "type": "message" │ } │ ] │ metadata: { - │ "flue.model": "gpt-4o-mini", - │ "flue.session": "main", - │ "model": "gpt-4o-mini", - │ "provider": "flue" + │ "model": "gpt-4o-mini-2024-07-18", + │ "provider": "openai" │ } │ metrics: { + │ "completion_reasoning_tokens": 0, │ "completion_tokens": 5, - │ "duration_ms": 0, - │ "estimated_cost": 0.00010172, - │ "prompt_cache_creation_tokens": 0, │ "prompt_cached_tokens": 1024, - │ "prompt_tokens": 112, + │ "prompt_tokens": 1136, + │ "time_to_first_token": 0, │ "tokens": 1141 │ } ├── flue-skill-operation @@ -524,42 +390,6 @@ span_tree: │ │ "model": "claude-sonnet-4-5-20250929", │ │ "provider": "anthropic" │ │ } - │ ├── flue.turn [llm] - │ │ output: [ - │ │ { - │ │ "finish_reason": "toolUse", - │ │ "index": 0, - │ │ "message": { - │ │ "content": "I'll run the e2e-flue-skill by reading its instructions and following them.", - │ │ "role": "assistant", - │ │ "tool_calls": [ - │ │ { - │ │ "function": { - │ │ "arguments": "{\"path\":\".agents/skills/e2e-flue-skill/SKILL.md\"}", - │ │ "name": "read" - │ │ }, - │ │ "id": "", - │ │ "type": "function" - │ │ } - │ │ ] - │ │ } - │ │ } - │ │ ] - │ │ metadata: { - │ │ "flue.model": "claude-sonnet-4-5-20250929", - │ │ "flue.session": "skill", - │ │ "model": "claude-sonnet-4-5-20250929", - │ │ "provider": "flue" - │ │ } - │ │ metrics: { - │ │ "completion_tokens": 89, - │ │ "duration_ms": 0, - │ │ "estimated_cost": 0.0018872999999999997, - │ │ "prompt_cache_creation_tokens": 0, - │ │ "prompt_cached_tokens": 1811, - │ │ "prompt_tokens": 3, - │ │ "tokens": 1903 - │ │ } │ ├── tool: read [tool] │ │ input: { │ │ "path": ".agents/skills/e2e-flue-skill/SKILL.md" @@ -584,90 +414,64 @@ span_tree: │ │ metrics: { │ │ "duration_ms": 0 │ │ } - │ ├── anthropic.messages.create [llm] - │ │ input: [ - │ │ { - │ │ "content": [ - │ │ { - │ │ "text": "Run the skill named \"e2e-flue-skill\".\n\nArguments:\n{\n \"marker\": \"SKILL_DONE\"\n}", - │ │ "type": "text" - │ │ } - │ │ ], - │ │ "role": "user" - │ │ }, - │ │ { - │ │ "content": [ - │ │ { - │ │ "text": "I'll run the e2e-flue-skill by reading its instructions and following them.", - │ │ "type": "text" - │ │ }, - │ │ { - │ │ "id": "", - │ │ "input": { - │ │ "path": ".agents/skills/e2e-flue-skill/SKILL.md" - │ │ }, - │ │ "name": "read", - │ │ "type": "tool_use" - │ │ } - │ │ ], - │ │ "role": "assistant" - │ │ }, - │ │ { - │ │ "content": [ - │ │ { - │ │ "cache_control": { - │ │ "type": "ephemeral" - │ │ }, - │ │ "content": "---\nname: e2e-flue-skill\ndescription: Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n---\n\nReturn the marker from the provided args exactly once. Output no other text.\n", - │ │ "is_error": false, - │ │ "tool_use_id": "toolu_01M5rfFBDvwquiyfz2B1GNYz", - │ │ "type": "tool_result" - │ │ } - │ │ ], - │ │ "role": "user" - │ │ }, - │ │ { - │ │ "content": [ - │ │ { - │ │ "cache_control": { - │ │ "type": "ephemeral" - │ │ }, - │ │ "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /e2e/scenarios/flue-instrumentation/\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts\n\n\nNever call the task tool. Do not delegate e2e-flue-skill to another session. If you need the skill body, read .agents/skills/e2e-flue-skill/SKILL.md yourself with the read tool. Return the marker from the Arguments object exactly, with no other text.\n", - │ │ "type": "text" - │ │ } - │ │ ], - │ │ "role": "system" - │ │ } - │ │ ] - │ │ metadata: { - │ │ "model": "claude-sonnet-4-5-20250929", - │ │ "provider": "anthropic" - │ │ } - │ └── flue.turn [llm] - │ output: [ + │ └── anthropic.messages.create [llm] + │ input: [ + │ { + │ "content": [ + │ { + │ "text": "Run the skill named \"e2e-flue-skill\".\n\nArguments:\n{\n \"marker\": \"SKILL_DONE\"\n}", + │ "type": "text" + │ } + │ ], + │ "role": "user" + │ }, │ { - │ "finish_reason": "stop", - │ "index": 0, - │ "message": { - │ "content": "SKILL_DONE", - │ "role": "assistant" - │ } + │ "content": [ + │ { + │ "text": "I'll run the e2e-flue-skill by reading its instructions and following them.", + │ "type": "text" + │ }, + │ { + │ "id": "", + │ "input": { + │ "path": ".agents/skills/e2e-flue-skill/SKILL.md" + │ }, + │ "name": "read", + │ "type": "tool_use" + │ } + │ ], + │ "role": "assistant" + │ }, + │ { + │ "content": [ + │ { + │ "cache_control": { + │ "type": "ephemeral" + │ }, + │ "content": "---\nname: e2e-flue-skill\ndescription: Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n---\n\nReturn the marker from the provided args exactly once. Output no other text.\n", + │ "is_error": false, + │ "tool_use_id": "toolu_01M5rfFBDvwquiyfz2B1GNYz", + │ "type": "tool_result" + │ } + │ ], + │ "role": "user" + │ }, + │ { + │ "content": [ + │ { + │ "cache_control": { + │ "type": "ephemeral" + │ }, + │ "text": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /e2e/scenarios/flue-instrumentation/\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts\n\n\nNever call the task tool. Do not delegate e2e-flue-skill to another session. If you need the skill body, read .agents/skills/e2e-flue-skill/SKILL.md yourself with the read tool. Return the marker from the Arguments object exactly, with no other text.\n", + │ "type": "text" + │ } + │ ], + │ "role": "system" │ } │ ] │ metadata: { - │ "flue.model": "claude-sonnet-4-5-20250929", - │ "flue.session": "skill", │ "model": "claude-sonnet-4-5-20250929", - │ "provider": "flue" - │ } - │ metrics: { - │ "completion_tokens": 8, - │ "duration_ms": 0, - │ "estimated_cost": 0.0007272, - │ "prompt_cache_creation_tokens": 0, - │ "prompt_cached_tokens": 1964, - │ "prompt_tokens": 6, - │ "tokens": 1978 + │ "provider": "anthropic" │ } ├── flue-task-operation │ metadata: { @@ -703,74 +507,48 @@ span_tree: │ │ metrics: { │ │ "duration_ms": 0 │ │ } - │ ├── openai.responses.create [llm] - │ │ input: [ - │ │ { - │ │ "content": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /e2e/scenarios/flue-instrumentation/\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", - │ │ "role": "system" - │ │ }, - │ │ { - │ │ "content": [ - │ │ { - │ │ "text": "Reply with exactly TASK_DONE and no other text.", - │ │ "type": "input_text" - │ │ } - │ │ ], - │ │ "role": "user" - │ │ } - │ │ ] - │ │ output: [ - │ │ { - │ │ "content": [ - │ │ { - │ │ "annotations": [], - │ │ "logprobs": [], - │ │ "text": "TASK_DONE", - │ │ "type": "output_text" - │ │ } - │ │ ], - │ │ "id": "", - │ │ "role": "assistant", - │ │ "status": "completed", - │ │ "type": "message" - │ │ } - │ │ ] - │ │ metadata: { - │ │ "model": "gpt-4o-mini-2024-07-18", - │ │ "provider": "openai" - │ │ } - │ │ metrics: { - │ │ "completion_reasoning_tokens": 0, - │ │ "completion_tokens": 4, - │ │ "prompt_cached_tokens": 0, - │ │ "prompt_tokens": 772, - │ │ "time_to_first_token": 0, - │ │ "tokens": 776 - │ │ } - │ └── flue.turn [llm] + │ └── openai.responses.create [llm] + │ input: [ + │ { + │ "content": "You are running in headless mode with no human operator. Work autonomously — never ask questions, never wait for user input. Make your best judgment and proceed independently.\n\n## Available Skills\n\nEach skill below is documented in a markdown file under `.agents/skills/` (relative to your working directory). The default location is `.agents/skills//SKILL.md`. When asked to run a skill, read its file from disk and follow the instructions there literally — the skill body is not provided inline.\n\n- **e2e-flue-skill** — Deterministic skill used by the Braintrust Flue instrumentation e2e test.\n\nDate: Fri, May 22, 2026\nWorking directory: /e2e/scenarios/flue-instrumentation/\n\nDirectory structure:\n.agents\n__cassettes__\n__snapshots__\nassertions.ts\ncassette-filter.mjs\nconstants.mjs\nnode_modules\npackage.json\npnpm-lock.yaml\nscenario.impl.mjs\nscenario.mjs\nscenario.test.ts\nscenario.ts", + │ "role": "system" + │ }, + │ { + │ "content": [ + │ { + │ "text": "Reply with exactly TASK_DONE and no other text.", + │ "type": "input_text" + │ } + │ ], + │ "role": "user" + │ } + │ ] │ output: [ │ { - │ "finish_reason": "stop", - │ "index": 0, - │ "message": { - │ "content": "TASK_DONE", - │ "role": "assistant" - │ } + │ "content": [ + │ { + │ "annotations": [], + │ "logprobs": [], + │ "text": "TASK_DONE", + │ "type": "output_text" + │ } + │ ], + │ "id": "", + │ "role": "assistant", + │ "status": "completed", + │ "type": "message" │ } │ ] │ metadata: { - │ "flue.model": "gpt-4o-mini", - │ "flue.session": "task:task:", - │ "model": "gpt-4o-mini", - │ "provider": "flue" + │ "model": "gpt-4o-mini-2024-07-18", + │ "provider": "openai" │ } │ metrics: { + │ "completion_reasoning_tokens": 0, │ "completion_tokens": 4, - │ "duration_ms": 0, - │ "estimated_cost": 0.0001182, - │ "prompt_cache_creation_tokens": 0, │ "prompt_cached_tokens": 0, │ "prompt_tokens": 772, + │ "time_to_first_token": 0, │ "tokens": 776 │ } └── flue-compact-operation diff --git a/e2e/scenarios/flue-instrumentation/assertions.ts b/e2e/scenarios/flue-instrumentation/assertions.ts index 9632a9ac4..45df42dd5 100644 --- a/e2e/scenarios/flue-instrumentation/assertions.ts +++ b/e2e/scenarios/flue-instrumentation/assertions.ts @@ -287,6 +287,7 @@ function buildSpanTree(events: CapturedLogEvent[]): SpanTreeEntry[] { export function defineFlueInstrumentationAssertions(options: { expectedPromptProviderSpanName?: string; + expectFlueTurnSpans?: boolean; expectThinking?: boolean; name: string; runScenario: RunFlueScenario; @@ -414,8 +415,8 @@ export function defineFlueInstrumentationAssertions(options: { compactOperation, (event) => event.span.name === "flue.compaction", )[0]; + const expectFlueTurnSpans = options.expectFlueTurnSpans ?? true; - expect(promptTurns.length).toBeGreaterThanOrEqual(3); expect(promptTools.map((event) => event.span.name)).toEqual( expect.arrayContaining([ "tool: lookup", @@ -423,9 +424,33 @@ export function defineFlueInstrumentationAssertions(options: { "tool: summarize_source", ]), ); - expectToolsAndTurnsShareParent(promptSpan, promptTurns, promptTools); - expectToolsAndTurnsShareParent(skillSpan, skillTurns, skillTools); - if (options.expectThinking !== false) { + if (expectFlueTurnSpans) { + expect(promptTurns.length).toBeGreaterThanOrEqual(3); + expectToolsAndTurnsShareParent(promptSpan, promptTurns, promptTools); + expectToolsAndTurnsShareParent(skillSpan, skillTurns, skillTools); + } else { + expect(promptTurns).toHaveLength(0); + expect(skillTurns).toHaveLength(0); + expect(promptSpan).toBeDefined(); + expect(skillSpan).toBeDefined(); + const promptSpanId = promptSpan?.span.id; + const skillSpanId = skillSpan?.span.id; + if (promptSpanId) { + expect( + promptTools.every((event) => + event.span.parentIds.includes(promptSpanId), + ), + ).toBe(true); + } + if (skillSpanId) { + expect( + skillTools.every((event) => + event.span.parentIds.includes(skillSpanId), + ), + ).toBe(true); + } + } + if (expectFlueTurnSpans && options.expectThinking !== false) { expect(reasoningTurn?.span.type).toBe("llm"); expect(reasoningTurn?.output).toBeDefined(); const reasoningOutput = JSON.stringify(reasoningTurn?.output); @@ -436,11 +461,13 @@ export function defineFlueInstrumentationAssertions(options: { "flue.thinking": true, }); } - expect(promptTurns[0]?.metrics).toMatchObject({ - completion_tokens: expect.any(Number), - prompt_tokens: expect.any(Number), - tokens: expect.any(Number), - }); + if (expectFlueTurnSpans) { + expect(promptTurns[0]?.metrics).toMatchObject({ + completion_tokens: expect.any(Number), + prompt_tokens: expect.any(Number), + tokens: expect.any(Number), + }); + } expect(lookupToolSpan?.span.type).toBe("tool"); expect(lookupToolSpan?.input).toMatchObject({ query: "flue instrumentation", diff --git a/e2e/scenarios/flue-instrumentation/scenario.test.ts b/e2e/scenarios/flue-instrumentation/scenario.test.ts index 0f7113821..e9b219bee 100644 --- a/e2e/scenarios/flue-instrumentation/scenario.test.ts +++ b/e2e/scenarios/flue-instrumentation/scenario.test.ts @@ -45,6 +45,7 @@ describe(`flue ${flueVersion}`, () => { defineFlueInstrumentationAssertions({ expectedPromptProviderSpanName: "anthropic.messages.create", + expectFlueTurnSpans: false, name: "auto-hook instrumentation", runScenario: async ({ runNodeScenarioDir }) => { await runNodeScenarioDir({ @@ -65,6 +66,7 @@ describe(`flue ${flueVersion}`, () => { defineFlueInstrumentationAssertions({ expectedPromptProviderSpanName: "openai.responses.create", + expectFlueTurnSpans: false, expectThinking: false, name: "auto-hook instrumentation with OpenAI prompt model", runScenario: async ({ runNodeScenarioDir }) => { diff --git a/js/src/instrumentation/plugins/flue-channels.ts b/js/src/instrumentation/plugins/flue-channels.ts index 2ee0ab0c3..f90efc907 100644 --- a/js/src/instrumentation/plugins/flue-channels.ts +++ b/js/src/instrumentation/plugins/flue-channels.ts @@ -33,6 +33,7 @@ export const flueChannels = defineChannels("@flue/runtime", { [FlueEvent], void, { + captureTurnSpans?: boolean; context?: FlueContext; } >({ diff --git a/js/src/instrumentation/plugins/flue-plugin.test.ts b/js/src/instrumentation/plugins/flue-plugin.test.ts index 5b41261ae..23f6aaeba 100644 --- a/js/src/instrumentation/plugins/flue-plugin.test.ts +++ b/js/src/instrumentation/plugins/flue-plugin.test.ts @@ -190,6 +190,69 @@ describe("FluePlugin", () => { }); }); + it("does not create Flue turn spans when context events disable them", () => { + const plugin = new FluePlugin(); + plugin.enable(); + + const contextHandlers = handlersByName.get( + "orchestrion:@flue/runtime:context.event", + ); + const promptHandlers = handlersByName.get( + "orchestrion:@flue/runtime:session.prompt", + ); + const promptEvent = { + arguments: ["Use a tool", { model: "pi/test" }], + operation: "prompt", + session: { name: "main" }, + }; + + promptHandlers.start(promptEvent); + contextHandlers.start({ + arguments: [ + { + operationId: "op_1", + operationKind: "prompt", + session: "main", + type: "operation_start", + }, + ], + captureTurnSpans: false, + }); + contextHandlers.start({ + arguments: [{ operationId: "op_1", text: "Looking", type: "text_delta" }], + captureTurnSpans: false, + }); + contextHandlers.start({ + arguments: [ + { + args: { query: "braintrust" }, + operationId: "op_1", + toolCallId: "tool_1", + toolName: "lookup", + type: "tool_start", + }, + ], + captureTurnSpans: false, + }); + contextHandlers.start({ + arguments: [ + { + durationMs: 10, + isError: false, + model: "pi/test", + operationId: "op_1", + stopReason: "stop", + type: "turn", + usage: usage(), + }, + ], + captureTurnSpans: false, + }); + + expect(spans.filter((span) => span.name === "flue.turn")).toHaveLength(0); + expect(spans.find((span) => span.name === "tool: lookup")).toBeDefined(); + }); + it("correlates operation, turn, tool, task, and compaction spans", () => { const plugin = new FluePlugin(); plugin.enable(); @@ -594,28 +657,28 @@ describe("FluePlugin", () => { ); }); - it("ends compaction spans from compact operation completion when no final compaction event arrives", () => { + it("ends compaction spans from operation completion when no final compaction event arrives", () => { const plugin = new FluePlugin(); plugin.enable(); const contextHandlers = handlersByName.get( "orchestrion:@flue/runtime:context.event", ); - const compactHandlers = handlersByName.get( - "orchestrion:@flue/runtime:session.compact", + const promptHandlers = handlersByName.get( + "orchestrion:@flue/runtime:session.prompt", ); - const compactEvent = { - arguments: [], - operation: "compact", + const promptEvent = { + arguments: ["Trigger a compaction"], + operation: "prompt", session: { name: "main" }, }; - compactHandlers.start(compactEvent); + promptHandlers.start(promptEvent); contextHandlers.start({ arguments: [ { operationId: "op_1", - operationKind: "compact", + operationKind: "prompt", session: "main", type: "operation_start", }, @@ -632,10 +695,11 @@ describe("FluePlugin", () => { }, ], }); - compactHandlers.asyncEnd(compactEvent); + (promptEvent as any).result = { text: "done" }; + promptHandlers.asyncEnd(promptEvent); const operationSpan = spans.find( - (span) => span.name === "flue.session.compact", + (span) => span.name === "flue.session.prompt", ); const compactionSpan = spans.find( (span) => span.name === "flue.compaction", @@ -645,9 +709,14 @@ describe("FluePlugin", () => { expect(operationSpan?.end).toHaveBeenCalledTimes(1); expect(compactionSpan?.log).toHaveBeenCalledWith( expect.objectContaining({ + input: { + estimatedTokens: 100, + reason: "manual", + }, metrics: expect.objectContaining({ duration_ms: expect.any(Number), }), + output: { completed: true }, }), ); }); diff --git a/js/src/instrumentation/plugins/flue-plugin.ts b/js/src/instrumentation/plugins/flue-plugin.ts index 6a497c640..7c4e55ce7 100644 --- a/js/src/instrumentation/plugins/flue-plugin.ts +++ b/js/src/instrumentation/plugins/flue-plugin.ts @@ -11,9 +11,9 @@ import type { CurrentSpanStore, Span } from "../../logger"; import { getCurrentUnixTimestamp, isObject } from "../../util"; import { SpanTypeAttribute } from "../../../util/index"; import { + patchFlueContextInPlace, patchFlueSessionInPlace, subscribeFlueContextEvents, - wrapFlueContext, wrapFlueHarness, } from "../../wrappers/flue"; import { flueChannels } from "./flue-channels"; @@ -50,6 +50,7 @@ type OperationState = { }; type SpanState = { + input?: unknown; metadata: Record; operationState?: OperationState; span: Span; @@ -108,8 +109,8 @@ export class FluePlugin extends BasePlugin { if (!ctx) { return; } - subscribeFlueContextEvents(ctx); - wrapFlueContext(ctx); + subscribeFlueContextEvents(ctx, { captureTurnSpans: false }); + patchFlueContextInPlace(ctx); }, error: () => {}, }; @@ -272,7 +273,9 @@ export class FluePlugin extends BasePlugin { } try { - this.handleFlueEvent(flueEvent); + this.handleFlueEvent(flueEvent, { + captureTurnSpans: event.captureTurnSpans !== false, + }); } catch (error) { logInstrumentationError("Flue event", error); } @@ -388,9 +391,7 @@ export class FluePlugin extends BasePlugin { metrics, output: extractOperationOutput(result), }); - if (state.operation === "compact") { - this.finishCompactionsForOperation(state); - } + this.finishCompactionsForOperation(state); this.finishOperationState(state); } @@ -403,7 +404,10 @@ export class FluePlugin extends BasePlugin { state.span.end(); } - private handleFlueEvent(event: FlueEvent): void { + private handleFlueEvent( + event: FlueEvent, + options: { captureTurnSpans: boolean }, + ): void { switch (event.type) { case "operation_start": this.handleOperationStart(event as FlueOperationStartEvent); @@ -412,24 +416,39 @@ export class FluePlugin extends BasePlugin { this.handleOperation(event as FlueOperationEvent); return; case "text_delta": + if (!options.captureTurnSpans) { + return; + } this.ensureTurnState(event).text.push( typeof event.text === "string" ? event.text : "", ); return; case "thinking_start": + if (!options.captureTurnSpans) { + return; + } this.handleThinkingStart(event); return; case "thinking_delta": + if (!options.captureTurnSpans) { + return; + } this.handleThinkingDelta(event as FlueThinkingDeltaEvent); return; case "thinking_end": + if (!options.captureTurnSpans) { + return; + } this.handleThinkingEnd(event as FlueThinkingEndEvent); return; case "turn": + if (!options.captureTurnSpans) { + return; + } this.handleTurn(event as FlueTurnEvent); return; case "tool_start": - this.handleToolStart(event as FlueToolStartEvent); + this.handleToolStart(event as FlueToolStartEvent, options); return; case "tool_call": this.handleToolCall(event as FlueToolCallEvent); @@ -594,7 +613,10 @@ export class FluePlugin extends BasePlugin { } } - private handleToolStart(event: FlueToolStartEvent): void { + private handleToolStart( + event: FlueToolStartEvent, + options: { captureTurnSpans: boolean }, + ): void { const toolCallId = event.toolCallId; if (!toolCallId) { return; @@ -603,7 +625,7 @@ export class FluePlugin extends BasePlugin { const parent = this.parentSpanForEvent(event); const scope = scopeKey(event); let turnState = this.turnsByScope.get(scope); - if (!turnState && parent) { + if (!turnState && parent && options.captureTurnSpans) { turnState = this.ensureTurnState(event); } const metadata = { @@ -713,18 +735,22 @@ export class FluePlugin extends BasePlugin { ...(event.reason ? { "flue.compaction_reason": event.reason } : {}), provider: "flue", }; + const input = { + ...(typeof event.estimatedTokens === "number" + ? { estimatedTokens: event.estimatedTokens } + : {}), + ...(event.reason ? { reason: event.reason } : {}), + }; const span = startFlueSpan(parent, { name: "flue.compaction", spanAttributes: { type: SpanTypeAttribute.TASK }, }); safeLog(span, { - input: { - estimatedTokens: event.estimatedTokens, - reason: event.reason, - }, + input, metadata, }); this.compactionsByScope.set(scopeKey(event), { + input, metadata, operationState, span, @@ -780,10 +806,12 @@ export class FluePlugin extends BasePlugin { continue; } safeLog(state.span, { + input: state.input, metadata: state.metadata, metrics: { ...buildDurationMetrics(state.startTime), }, + output: { completed: true }, }); state.span.end(); this.deleteCompactionState(state); diff --git a/js/src/wrappers/flue.test.ts b/js/src/wrappers/flue.test.ts index 743530793..a654a30eb 100644 --- a/js/src/wrappers/flue.test.ts +++ b/js/src/wrappers/flue.test.ts @@ -61,7 +61,11 @@ vi.mock("../isomorph", () => ({ }, })); -import { wrapFlueContext, wrapFlueSession } from "./flue"; +import { + subscribeFlueContextEvents, + wrapFlueContext, + wrapFlueSession, +} from "./flue"; describe("wrapFlueSession", () => { afterEach(() => { @@ -171,11 +175,67 @@ describe("wrapFlueContext", () => { expect.any(Function), expect.objectContaining({ arguments: [{ operationId: "op_1", type: "operation_start" }], + captureTurnSpans: true, context: ctx, }), ); }); + it("can subscribe to context events without Flue turn spans", () => { + let subscriber: ((event: unknown) => void) | undefined; + const ctx = { + init: vi.fn(), + subscribeEvent: vi.fn((callback) => { + subscriber = callback; + return vi.fn(); + }), + }; + + subscribeFlueContextEvents(ctx, { captureTurnSpans: false }); + subscriber?.({ operationId: "op_1", type: "turn" }); + + expect(traceSync).toHaveBeenCalledWith( + expect.any(Function), + expect.objectContaining({ + arguments: [{ operationId: "op_1", type: "turn" }], + captureTurnSpans: false, + context: ctx, + }), + ); + }); + + it("upgrades an existing context event subscription for manual wrapping", () => { + let subscriber: ((event: unknown) => void) | undefined; + const firstUnsubscribe = vi.fn(); + const secondUnsubscribe = vi.fn(); + const ctx = { + init: vi.fn(async () => ({ session: vi.fn() })), + subscribeEvent: vi + .fn() + .mockImplementationOnce((callback) => { + subscriber = callback; + return firstUnsubscribe; + }) + .mockImplementationOnce((callback) => { + subscriber = callback; + return secondUnsubscribe; + }), + }; + + subscribeFlueContextEvents(ctx, { captureTurnSpans: false }); + wrapFlueContext(ctx); + subscriber?.({ operationId: "op_1", type: "turn" }); + + expect(firstUnsubscribe).toHaveBeenCalledTimes(1); + expect(ctx.subscribeEvent).toHaveBeenCalledTimes(2); + expect(traceSync).toHaveBeenLastCalledWith( + expect.any(Function), + expect.objectContaining({ + captureTurnSpans: true, + }), + ); + }); + it("returns invalid contexts unchanged", () => { const warnSpy = vi.spyOn(console, "warn").mockImplementation(() => {}); const value = { session: vi.fn() }; diff --git a/js/src/wrappers/flue.ts b/js/src/wrappers/flue.ts index 804fb0ae5..98852f3ad 100644 --- a/js/src/wrappers/flue.ts +++ b/js/src/wrappers/flue.ts @@ -21,6 +21,13 @@ const SUBSCRIBED_FLUE_CONTEXT_EVENTS = Symbol.for( type FlueContextRecord = FlueContext & Record; type FlueHarnessRecord = FlueHarness & Record; type FlueSessionRecord = FlueSession & Record; +type FlueContextEventSubscription = { + captureTurnSpans: boolean; + unsubscribe: () => void; +}; +type FlueContextEventSubscriptionOptions = { + captureTurnSpans?: boolean; +}; type FlueOperationChannel = | typeof flueChannels.prompt | typeof flueChannels.skill @@ -47,7 +54,12 @@ export function wrapFlueContext(ctx: T): T { } const context = ctx as FlueContextRecord; - subscribeFlueContextEvents(context); + subscribeFlueContextEvents(context, { captureTurnSpans: true }); + return patchFlueContextInPlace(context) as T; +} + +export function patchFlueContextInPlace(ctx: T): T { + const context = ctx as FlueContextRecord; if (context[WRAPPED_FLUE_CONTEXT]) { return ctx; } @@ -91,6 +103,7 @@ export function wrapFlueSession(session: T): T { export function subscribeFlueContextEvents( ctx: FlueContext, + options: FlueContextEventSubscriptionOptions = {}, ): (() => void) | undefined { if ( !ctx || @@ -101,22 +114,42 @@ export function subscribeFlueContextEvents( } const context = ctx as FlueContextRecord; - if (context[SUBSCRIBED_FLUE_CONTEXT_EVENTS]) { - return undefined; + const captureTurnSpans = options.captureTurnSpans ?? true; + const existingSubscription = context[SUBSCRIBED_FLUE_CONTEXT_EVENTS] as + | FlueContextEventSubscription + | undefined; + if (existingSubscription) { + if (existingSubscription.captureTurnSpans || !captureTurnSpans) { + return undefined; + } + try { + existingSubscription.unsubscribe(); + } catch { + // Ignore failed cleanup and attempt to replace the subscription below. + } } try { const unsubscribe = ctx.subscribeEvent((event: FlueEvent) => { flueChannels.contextEvent.traceSync(() => undefined, { arguments: [event], + captureTurnSpans, context: ctx, } as never); }); - Object.defineProperty(context, SUBSCRIBED_FLUE_CONTEXT_EVENTS, { - configurable: false, - enumerable: false, - value: true, - }); + if (existingSubscription) { + existingSubscription.captureTurnSpans = captureTurnSpans; + existingSubscription.unsubscribe = unsubscribe; + } else { + Object.defineProperty(context, SUBSCRIBED_FLUE_CONTEXT_EVENTS, { + configurable: false, + enumerable: false, + value: { + captureTurnSpans, + unsubscribe, + } satisfies FlueContextEventSubscription, + }); + } return unsubscribe; } catch { return undefined;