Compare commits

..
Author SHA1 Message Date
rekram1-node 95dd0c5e0c chore: upgrade Effect to 4.0 stable 2026-10-02 01:46:49 +00:00
1367 changed files with 20012 additions and 37815 deletions

No files matched your search

-11
View File
@@ -18,20 +18,9 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4.3.1
with:
# A pull request checks out its merge into the current base; the first parent is that base.
fetch-depth: 2
- name: Setup Bun
uses: ./.github/actions/setup-bun
- name: Run checks
run: bun run check
# Every GUI package file (app, desktop, gui-extensions, ui, session-ui) a pull request adds or edits must be free of
# oxlint problems, warn-level rules (anti-slop) included. Other packages are not affected.
- name: Lint changed files
if: github.event_name == 'pull_request'
# Against the merge's first parent, so base-branch commits the pull request has not merged are not counted as its
# changes (the event's base SHA can predate them).
run: bun run lint:changed HEAD^1
+2 -2
View File
@@ -2,9 +2,9 @@ name: nix-eval
on:
push:
branches: [dev, v2]
branches: [dev]
pull_request:
branches: [dev, v2]
branches: [dev]
workflow_dispatch:
concurrency:
-9
View File
@@ -252,13 +252,6 @@ jobs:
CI: true
timeout-minutes: 15
- name: Run app component tests
if: ${{ !cancelled() && env.E2E_ENABLED == 'true' }}
run: bun --cwd packages/app test:components
env:
CI: true
timeout-minutes: 15
- name: Upload Playwright artifacts
if: always() && env.E2E_ENABLED == 'true'
uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
@@ -271,5 +264,3 @@ jobs:
packages/app/e2e/playwright-report
packages/session-ui/component-tests/test-results
packages/session-ui/component-tests/playwright-report
packages/app/component-tests/test-results
packages/app/component-tests/playwright-report
-52
View File
@@ -63,60 +63,8 @@
"anti-slop-effect/prefer-effect-match": "warn"
}
},
{
"files": ["packages/gui-extensions/src/*.ts", "packages/gui-extensions/src/*.tsx"],
"rules": {
"no-restricted-imports": [
"error",
{
"paths": [
{
"name": "solid-js",
"importNames": ["createEffect", "createRenderEffect", "createComputed"],
"message": "Extension code runs side effects through the SDK: createKeyed(source, fn, { otherwise }) per provider generation or value, createMemo or a plain function for derived values, createLatest for async data, createVisitState for per-visit state, and the handler for logic a user action causes. An escape hatch needs an oxlint-disable comment with a reason."
}
]
}
]
}
},
{
"files": ["packages/gui-extensions/src/*/**"],
"rules": {
"no-restricted-imports": [
"error",
{
"paths": [
{
"name": "solid-js",
"importNames": ["createEffect", "createRenderEffect", "createComputed"],
"message": "Extension code runs side effects through the SDK: createKeyed(source, fn, { otherwise }) per provider generation or value, createMemo or a plain function for derived values, createLatest for async data, createVisitState for per-visit state, and the handler for logic a user action causes. An escape hatch needs an oxlint-disable comment with a reason."
}
],
"patterns": [
{
"regex": "^@opencode/(app|desktop)(/|$)",
"message": "GUI extensions never import the app or desktop packages. Use the SDK."
},
{
"regex": "^@/",
"message": "GUI extensions never import app internals. Use the SDK."
},
{
"group": ["../*/*", "!../*/contract", "!../sdk/*"],
"message": "Import another extension only through its contract.ts."
},
{
"regex": "\\.css$",
"message": "Import CSS with ?inline and contribute it with ctx.add(Style, css)."
}
]
}
]
}
},
{
"files": ["packages/gui-extensions/src/sdk/**"],
"rules": {
"no-restricted-imports": [
"error",
+68 -88
View File
@@ -33,7 +33,7 @@
},
"packages/ai": {
"name": "@opencode/ai",
"version": "2.0.22",
"version": "2.0.21",
"dependencies": {
"@aws-sdk/credential-providers": "3.1057.0",
"@opencode/schema": "workspace:*",
@@ -55,7 +55,7 @@
},
"packages/app": {
"name": "@opencode/app",
"version": "2.0.22",
"version": "2.0.21",
"dependencies": {
"@corvu/drawer": "catalog:",
"@dnd-kit/abstract": "0.5.0",
@@ -112,7 +112,7 @@
},
"packages/cli": {
"name": "@opencode/cli",
"version": "2.0.22",
"version": "2.0.21",
"bin": {
"opencode": "./bin/opencode.cjs",
"opencode2": "./bin/opencode2.cjs",
@@ -122,7 +122,7 @@
"@clack/core": "1.0.0-alpha.1",
"@clack/prompts": "1.0.0-alpha.1",
"@effect/platform-node": "catalog:",
"@opencode-ai/pty": "0.2.0",
"@opencode-ai/pty": "0.1.13",
"@opencode/client": "workspace:*",
"@opencode/plugin": "workspace:*",
"@opencode/schema": "workspace:*",
@@ -133,7 +133,6 @@
"@opentui/solid": "catalog:",
"@parcel/watcher": "2.5.1",
"@silvia-odwyer/photon-node": "0.3.4",
"diff": "catalog:",
"effect": "catalog:",
"immer": "11.1.4",
"jsonc-parser": "3.3.1",
@@ -179,7 +178,7 @@
},
"packages/client": {
"name": "@opencode/client",
"version": "2.0.22",
"version": "2.0.21",
"dependencies": {
"@opencode/protocol": "workspace:*",
"@opencode/schema": "workspace:*",
@@ -195,7 +194,7 @@
"zod": "catalog:",
},
"peerDependencies": {
"effect": "4.0.0-rc.112",
"effect": "4.0.0",
"solid-js": ">=1.9.0",
},
"optionalPeers": [
@@ -205,7 +204,7 @@
},
"packages/codemode": {
"name": "@opencode/codemode",
"version": "2.0.22",
"version": "2.0.21",
"dependencies": {
"acorn": "8.15.0",
"effect": "catalog:",
@@ -218,7 +217,7 @@
},
"packages/console/app": {
"name": "@opencode/console-app",
"version": "2.0.22",
"version": "2.0.21",
"dependencies": {
"@cloudflare/vite-plugin": "1.15.2",
"@ibm/plex": "6.4.1",
@@ -254,7 +253,7 @@
},
"packages/console/core": {
"name": "@opencode/console-core",
"version": "2.0.22",
"version": "2.0.21",
"dependencies": {
"@aws-sdk/client-sts": "3.782.0",
"@jsx-email/render": "1.1.1",
@@ -281,7 +280,7 @@
},
"packages/console/function": {
"name": "@opencode/console-function",
"version": "2.0.22",
"version": "2.0.21",
"dependencies": {
"@openauthjs/openauth": "0.0.0-20250322224806",
"@opencode/console-core": "workspace:*",
@@ -298,7 +297,7 @@
},
"packages/console/mail": {
"name": "@opencode/console-mail",
"version": "2.0.22",
"version": "2.0.21",
"dependencies": {
"@jsx-email/all": "2.2.3",
"@jsx-email/cli": "1.4.3",
@@ -322,7 +321,7 @@
},
"packages/console/support": {
"name": "@opencode/console-support",
"version": "2.0.22",
"version": "2.0.21",
"dependencies": {
"@cloudflare/vite-plugin": "1.15.2",
"@opencode/console-core": "workspace:*",
@@ -342,7 +341,7 @@
},
"packages/core": {
"name": "@opencode/core",
"version": "2.0.22",
"version": "2.0.21",
"dependencies": {
"@ai-sdk/cohere": "3.0.27",
"@ai-sdk/gateway": "3.0.104",
@@ -355,7 +354,7 @@
"@lydell/node-pty": "catalog:",
"@modelcontextprotocol/client": "2.0.0",
"@modelcontextprotocol/core": "2.0.0",
"@opencode-ai/pty": "0.2.0",
"@opencode-ai/pty": "0.1.13",
"@opencode/ai": "workspace:*",
"@opencode/codemode": "workspace:*",
"@opencode/plugin": "workspace:*",
@@ -365,7 +364,7 @@
"@parcel/watcher": "2.5.1",
"@silvia-odwyer/photon-node": "0.3.4",
"@standard-schema/spec": "catalog:",
"bun-pty": "0.4.9",
"bun-pty": "0.4.8",
"diff": "catalog:",
"drizzle-orm": "catalog:",
"effect": "catalog:",
@@ -407,11 +406,12 @@
"@types/node": "catalog:",
"@types/which": "3.0.4",
"drizzle-kit": "catalog:",
"fast-check": "4.9.0",
},
},
"packages/desktop": {
"name": "@opencode/desktop",
"version": "2.0.22",
"version": "2.0.21",
"dependencies": {
"@zip.js/zip.js": "2.7.62",
"electron-context-menu": "5.0.0",
@@ -442,7 +442,7 @@
"electron-builder": "26.15.7",
"electron-vite": "6.0.0-beta.1",
"solid-js": "catalog:",
"typescript": "~5.6.2",
"typescript": "catalog:",
"vite": "8.2.2",
},
"optionalDependencies": {
@@ -456,7 +456,7 @@
},
"packages/enterprise": {
"name": "@opencode/enterprise",
"version": "2.0.22",
"version": "2.0.21",
"dependencies": {
"@hono/standard-validator": "catalog:",
"@opencode-ai/sdk": "1.18.21",
@@ -493,7 +493,7 @@
},
"packages/function": {
"name": "@opencode/function",
"version": "2.0.22",
"version": "2.0.21",
"dependencies": {
"@octokit/auth-app": "8.0.1",
"@octokit/rest": "catalog:",
@@ -509,7 +509,7 @@
},
"packages/gui-extensions": {
"name": "@opencode/gui-extensions",
"version": "2.0.22",
"version": "2.0.20",
"dependencies": {
"@dnd-kit/abstract": "0.5.0",
"@dnd-kit/dom": "0.5.0",
@@ -554,9 +554,9 @@
},
"packages/http-recorder": {
"name": "@opencode/http-recorder",
"version": "2.0.22",
"version": "2.0.21",
"dependencies": {
"@effect/platform-node-shared": "4.0.0-rc.112",
"@effect/platform-node-shared": "4.0.0",
},
"devDependencies": {
"@effect/platform-node": "catalog:",
@@ -573,7 +573,7 @@
},
"packages/httpapi-codegen": {
"name": "@opencode/httpapi-codegen",
"version": "2.0.22",
"version": "2.0.21",
"dependencies": {
"effect": "catalog:",
"prettier": "3.6.2",
@@ -586,7 +586,7 @@
},
"packages/latex": {
"name": "@opencode/latex",
"version": "2.0.22",
"version": "2.0.21",
"dependencies": {
"@opencode/plugin": "workspace:*",
"@opentui/core": "catalog:",
@@ -600,7 +600,7 @@
},
"packages/merman": {
"name": "@opencode/merman",
"version": "2.0.22",
"version": "2.0.21",
"dependencies": {
"@opencode/plugin": "workspace:*",
"@opentui/core": "catalog:",
@@ -615,7 +615,7 @@
},
"packages/plugin": {
"name": "@opencode/plugin",
"version": "2.0.22",
"version": "2.0.21",
"dependencies": {
"@ai-sdk/provider": "3.0.8",
"@opencode/ai": "workspace:*",
@@ -654,7 +654,7 @@
},
"packages/plugin-browser": {
"name": "@opencode/plugin-browser",
"version": "2.0.22",
"version": "2.0.21",
"dependencies": {
"@opencode/plugin": "workspace:*",
"@opencode/schema": "workspace:*",
@@ -684,7 +684,7 @@
},
"packages/protocol": {
"name": "@opencode/protocol",
"version": "2.0.22",
"version": "2.0.21",
"dependencies": {
"@opencode/schema": "workspace:*",
"effect": "catalog:",
@@ -699,7 +699,7 @@
},
"packages/schema": {
"name": "@opencode/schema",
"version": "2.0.22",
"version": "2.0.21",
"dependencies": {
"@standard-schema/spec": "catalog:",
"effect": "catalog:",
@@ -723,7 +723,7 @@
},
"packages/sdk": {
"name": "@opencode/sdk",
"version": "2.0.22",
"version": "2.0.21",
"dependencies": {
"@opencode/client": "workspace:*",
"@opencode/core": "workspace:*",
@@ -744,7 +744,7 @@
},
"packages/server": {
"name": "@opencode/server",
"version": "2.0.22",
"version": "2.0.21",
"dependencies": {
"@effect/platform-node": "catalog:",
"@effect/platform-node-shared": "catalog:",
@@ -766,7 +766,7 @@
},
"packages/session-ui": {
"name": "@opencode/session-ui",
"version": "2.0.22",
"version": "2.0.21",
"dependencies": {
"@kobalte/core": "catalog:",
"@opencode/client": "workspace:*",
@@ -801,7 +801,7 @@
},
"packages/simulation": {
"name": "@opencode/simulation",
"version": "2.0.22",
"version": "2.0.21",
"dependencies": {
"@opencode/ai": "workspace:*",
"@opencode/core": "workspace:*",
@@ -821,7 +821,7 @@
},
"packages/stats/app": {
"name": "@opencode/stats-app",
"version": "2.0.22",
"version": "2.0.21",
"dependencies": {
"@ibm/plex": "6.4.1",
"@kobalte/core": "catalog:",
@@ -855,7 +855,7 @@
},
"packages/stats/core": {
"name": "@opencode/stats-core",
"version": "2.0.22",
"version": "2.0.21",
"dependencies": {
"@aws-sdk/client-athena": "3.933.0",
"@planetscale/database": "1.19.0",
@@ -874,7 +874,7 @@
},
"packages/stats/server": {
"name": "@opencode/stats-server",
"version": "2.0.22",
"version": "2.0.21",
"dependencies": {
"@aws-sdk/client-firehose": "3.933.0",
"@effect/platform-node": "catalog:",
@@ -920,7 +920,7 @@
},
"packages/theme": {
"name": "@opencode/theme",
"version": "2.0.22",
"version": "2.0.21",
"dependencies": {
"@opentui/core": "catalog:",
"effect": "catalog:",
@@ -934,7 +934,7 @@
},
"packages/tui": {
"name": "@opencode/tui",
"version": "2.0.22",
"version": "2.0.21",
"dependencies": {
"@opencode/client": "workspace:*",
"@opencode/core": "workspace:*",
@@ -968,7 +968,7 @@
},
"packages/ui": {
"name": "@opencode/ui",
"version": "2.0.22",
"version": "2.0.21",
"dependencies": {
"@kobalte/core": "catalog:",
"@pierre/diffs": "catalog:",
@@ -1003,7 +1003,7 @@
},
"packages/util": {
"name": "@opencode/util",
"version": "2.0.22",
"version": "2.0.21",
"dependencies": {
"@effect/opentelemetry": "catalog:",
"@effect/platform-node": "catalog:",
@@ -1041,7 +1041,7 @@
},
"packages/web": {
"name": "@opencode/web",
"version": "2.0.22",
"version": "2.0.21",
"dependencies": {
"@astrojs/cloudflare": "12.6.3",
"@astrojs/markdown-remark": "6.3.1",
@@ -1082,7 +1082,7 @@
},
"services/update": {
"name": "@opencode/update",
"version": "2.0.22",
"version": "2.0.21",
"dependencies": {
"jose": "6.0.11",
"semver": "catalog:",
@@ -1148,10 +1148,10 @@
"catalog": {
"@cloudflare/workers-types": "4.20251008.0",
"@corvu/drawer": "0.2.4",
"@effect/opentelemetry": "4.0.0-rc.112",
"@effect/platform-node": "4.0.0-rc.112",
"@effect/platform-node-shared": "4.0.0-rc.112",
"@effect/sql-sqlite-bun": "4.0.0-rc.112",
"@effect/opentelemetry": "4.0.0",
"@effect/platform-node": "4.0.0",
"@effect/platform-node-shared": "4.0.0",
"@effect/sql-sqlite-bun": "4.0.0",
"@hono/standard-validator": "0.2.0",
"@hono/zod-validator": "0.4.2",
"@kobalte/core": "0.13.13",
@@ -1191,7 +1191,7 @@
"dompurify": "3.4.14",
"drizzle-kit": "1.0.0-rc.5-ab785fc",
"drizzle-orm": "1.0.0-rc.5-169397b",
"effect": "4.0.0-rc.112",
"effect": "4.0.0",
"fuzzysort": "3.1.0",
"get-east-asian-width": "1.6.0",
"hono": "4.10.7",
@@ -1210,7 +1210,7 @@
"sst": "4.13.1",
"string-width": "7.2.0",
"tailwindcss": "4.1.11",
"typescript": "5.8.2",
"typescript": "5.9.3",
"ulid": "3.0.1",
"vite": "7.3.6",
"vite-plugin-solid": "2.11.10",
@@ -1723,13 +1723,13 @@
"@drizzle-team/brocli": ["@drizzle-team/brocli@0.12.0", "", {}, "sha512-mlUE+rZ8CatQekLhnaiN91Iemdd+e2gFKooGlnRB3oPTL3VghLfX24dx7HrzMNeC1JrIB/0kpsfyty3f5HNfxQ=="],
"@effect/opentelemetry": ["@effect/opentelemetry@4.0.0-rc.112", "", { "peerDependencies": { "@opentelemetry/api": ">=1.9.0 <2.0.0", "@opentelemetry/api-logs": ">=0.203.0 <0.300.0", "@opentelemetry/resources": ">=2.0.0 <3.0.0", "@opentelemetry/sdk-logs": ">=0.203.0 <0.300.0", "@opentelemetry/sdk-metrics": ">=2.0.0 <3.0.0", "@opentelemetry/sdk-trace-base": ">=2.0.0 <3.0.0", "@opentelemetry/sdk-trace-node": ">=2.0.0 <3.0.0", "@opentelemetry/sdk-trace-web": ">=2.0.0 <3.0.0", "@opentelemetry/semantic-conventions": ">=1.33.0 <2.0.0", "effect": "^4.0.0-rc.112" }, "optionalPeers": ["@opentelemetry/api", "@opentelemetry/api-logs", "@opentelemetry/resources", "@opentelemetry/sdk-logs", "@opentelemetry/sdk-metrics", "@opentelemetry/sdk-trace-base", "@opentelemetry/sdk-trace-node", "@opentelemetry/sdk-trace-web"] }, "sha512-OTRv1DxTHUmnakgJ6XVM8wVgF1KgZH4UXnOemwSLUwUjXO+RCikzF8oR/rlVmOGq81KtQzj1URM4M4nchlQOuQ=="],
"@effect/opentelemetry": ["@effect/opentelemetry@4.0.0", "", { "peerDependencies": { "@opentelemetry/api": ">=1.9.0 <2.0.0", "@opentelemetry/api-logs": ">=0.203.0 <0.300.0", "@opentelemetry/resources": ">=2.0.0 <3.0.0", "@opentelemetry/sdk-logs": ">=0.203.0 <0.300.0", "@opentelemetry/sdk-metrics": ">=2.0.0 <3.0.0", "@opentelemetry/sdk-trace-base": ">=2.0.0 <3.0.0", "@opentelemetry/sdk-trace-node": ">=2.0.0 <3.0.0", "@opentelemetry/sdk-trace-web": ">=2.0.0 <3.0.0", "@opentelemetry/semantic-conventions": ">=1.33.0 <2.0.0", "effect": "^4.0.0" }, "optionalPeers": ["@opentelemetry/api", "@opentelemetry/api-logs", "@opentelemetry/resources", "@opentelemetry/sdk-logs", "@opentelemetry/sdk-metrics", "@opentelemetry/sdk-trace-base", "@opentelemetry/sdk-trace-node", "@opentelemetry/sdk-trace-web"] }, "sha512-vXVhqlcADHtmKlw2gIqRRlXFve4ms4JJ5ykAqzNe37QQ/5N5A5gJ9VOXkMBORHZC5O4gdHZwxhAzGZb0zvFf/Q=="],
"@effect/platform-node": ["@effect/platform-node@4.0.0-rc.112", "", { "dependencies": { "@effect/platform-node-shared": "^4.0.0-rc.112", "mime": "^4.1.0", "undici": "^8.10.0" }, "peerDependencies": { "effect": "^4.0.0-rc.112", "redis": ">=5.0.0 <7.0.0" } }, "sha512-/BMAcdNGQQskLmI0Zoa95KfTZkr9HV9N4NSxaSrusG6GeW6Ulp9KvZ+Rlaiw8lnOt43CXjFLdfll5/k5rxL4hQ=="],
"@effect/platform-node": ["@effect/platform-node@4.0.0", "", { "dependencies": { "@effect/platform-node-shared": "^4.0.0", "undici": "^8.11.2" }, "peerDependencies": { "effect": "^4.0.0", "redis": ">=5.0.0 <7.0.0" } }, "sha512-/L+4MUbl8FejPKLHLROYSOebvHnfixkP8KiblSD/DE5uH5xENZBHaux4nH6XMnRP+lr8ajpEJFS8sUrmmxFJeQ=="],
"@effect/platform-node-shared": ["@effect/platform-node-shared@4.0.0-rc.112", "", { "dependencies": { "@types/ws": "^8.18.1", "ws": "^8.21.3" }, "peerDependencies": { "effect": "^4.0.0-rc.112" } }, "sha512-ttjz0xKamFN7vL8pNDYVwddJLjZvqKePc05djlz2VcdaKbLsnYbtMnL1rbOfHgEnIUSHGh7FkjaN4DM1Ov81sQ=="],
"@effect/platform-node-shared": ["@effect/platform-node-shared@4.0.0", "", { "dependencies": { "@types/ws": "^8.18.1", "ws": "^8.22.0" }, "peerDependencies": { "effect": "^4.0.0" } }, "sha512-VBXHJU9UXVZPdQGGDRjGXpo+TpOzRwZuMrdKAtIxi1qwcRftmacZ1zTgIrzBa0Z2RA2KVkoOecQUsTlt/nJZhw=="],
"@effect/sql-sqlite-bun": ["@effect/sql-sqlite-bun@4.0.0-rc.112", "", { "peerDependencies": { "effect": "^4.0.0-rc.112" } }, "sha512-EqR8pWZo3VzedRvP6qo5HcfqNmFvSa+sQLWQl3oBMx2KY1FCc8NYjep79wYjNkW0qABnffrPUXCMTOncd1A+5g=="],
"@effect/sql-sqlite-bun": ["@effect/sql-sqlite-bun@4.0.0", "", { "peerDependencies": { "effect": "^4.0.0" } }, "sha512-tUDqqNq4lZMLQkp8YDQej2uuy8BBjmqfMXcJU/KOmrK/WWbzudC8oabZ1TEs1lLSuKzhBEPhnE0cRtAOYe05ew=="],
"@electron-internal/extract-zip": ["@electron-internal/extract-zip@1.0.5", "", {}, "sha512-+bqFCP98pLI0Tt0XQo1TmlXtwjWchISndDOxCkEcIuUgXWpBnLyRI+2DU+mesvnMMX6L1XDqYNA0lXNDHd/yiA=="],
@@ -2063,18 +2063,6 @@
"@motionone/utils": ["@motionone/utils@10.18.0", "", { "dependencies": { "@motionone/types": "^10.17.1", "hey-listen": "^1.0.8", "tslib": "^2.3.1" } }, "sha512-3XVF7sgyTSI2KWvTf6uLlBJ5iAgRgmvp3bpuOiQJvInd4nZ19ET8lX5unn30SlmRH7hXbBbH+Gxd0m0klJ3Xtw=="],
"@msgpackr-extract/msgpackr-extract-darwin-arm64": ["@msgpackr-extract/msgpackr-extract-darwin-arm64@3.0.4", "", { "os": "darwin", "cpu": "arm64" }, "sha512-LCkGo6JDfaBhgST7UpPWgNgLINpcpabaHfyz5OBx75nUYxBsaEPxjnyNjWpeb/xBup/682QnBfRBy2/LvPutZQ=="],
"@msgpackr-extract/msgpackr-extract-darwin-x64": ["@msgpackr-extract/msgpackr-extract-darwin-x64@3.0.4", "", { "os": "darwin", "cpu": "x64" }, "sha512-zExlW9zUJKZH/tOtVMttwjKa4Xm/3KcNjnE3dPN92uCktwavMxpgCA3MoJK/DOnTWsQgo224OaST27/mPNAf+w=="],
"@msgpackr-extract/msgpackr-extract-linux-arm": ["@msgpackr-extract/msgpackr-extract-linux-arm@3.0.4", "", { "os": "linux", "cpu": "arm" }, "sha512-Tg3yX65f5GbtXLkrYEHE5oibZG9epyYWas7FogTTEJeDEF9JlXJzKgXaNhT3UXlTOeA+AfZpYZYZ0uPj7Cfquw=="],
"@msgpackr-extract/msgpackr-extract-linux-arm64": ["@msgpackr-extract/msgpackr-extract-linux-arm64@3.0.4", "", { "os": "linux", "cpu": "arm64" }, "sha512-dgX0P/9wGPJeHFBG+ZmhgE6bmtMt7NP5CRBGyyktpopdk/mW4POnrpQsSLtKI1dwpc+pPLuXHDh6vvskyQE/sw=="],
"@msgpackr-extract/msgpackr-extract-linux-x64": ["@msgpackr-extract/msgpackr-extract-linux-x64@3.0.4", "", { "os": "linux", "cpu": "x64" }, "sha512-8TNXMEjJc3QEy7R/x1INhgiU+XakDAFUzBhaz7+Rbrs8NH5UQeHQxxmzsSBJGyV6I1jW79undiQm8tOI+D+8FQ=="],
"@msgpackr-extract/msgpackr-extract-win32-x64": ["@msgpackr-extract/msgpackr-extract-win32-x64@3.0.4", "", { "os": "win32", "cpu": "x64" }, "sha512-CmCXPQrkbwExx3j946/PtHWHbYJiCRBRDl4BlkRQcJB/YOwQxJRTpoo7aTsortjgoJ1x7opzTSxn7C+ASSLVjQ=="],
"@napi-rs/lzma-linux-x64-gnu": ["@napi-rs/lzma-linux-x64-gnu@1.5.1", "", { "os": "linux", "cpu": "x64" }, "sha512-oTXEIha4SsuXdTA4Iyskj0kpdx2yVXdhd75c2v3xGrHFfVMsbhTPZU/nMPL4sWKo4pBHm3aucLaqGlF696dTyQ=="],
"@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.2.3", "", { "dependencies": { "@tybys/wasm-util": "^0.10.3" }, "peerDependencies": { "@emnapi/core": "^1.7.1 || ^2.0.0-alpha.4", "@emnapi/runtime": "^1.7.1 || ^2.0.0-alpha.4" } }, "sha512-UMduMbqO5s5zF2NkNacMT/yK5Y5QiKvWr2+50bzIIxFDwVJ2h49b+oyjaCGPhJxd2/gC2x39EHv/gHVuu36x2Q=="],
@@ -2167,19 +2155,19 @@
"@opencode-ai/protocol": ["@opencode-ai/protocol@0.0.0-beta-18050", "", { "dependencies": { "@opencode-ai/schema": "0.0.0-beta-18050", "effect": "4.0.0-rc.111" } }, "sha512-HDQMnvGp8IU0MdBRbEuydX1WQm09BZ4HJm9iSMQwzweJuQ2HNscgzHJPIH6P02BsbbtfJ8J7sZGPItrz1tWSgw=="],
"@opencode-ai/pty": ["@opencode-ai/pty@0.2.0", "", { "optionalDependencies": { "@opencode-ai/pty-darwin-arm64": "0.2.0", "@opencode-ai/pty-darwin-x64": "0.2.0", "@opencode-ai/pty-linux-arm64-gnu": "0.2.0", "@opencode-ai/pty-linux-arm64-musl": "0.2.0", "@opencode-ai/pty-linux-x64-gnu": "0.2.0", "@opencode-ai/pty-linux-x64-musl": "0.2.0" }, "bin": { "opencode-pty": "bin/opencode-pty.js" } }, "sha512-pV86urAwinpwFXX8AJlOf8S9CVJhGsV+11I/J6TcxMW0c7u6LgeODzdj/BVBC6jUhsG2aKDxg8rACMcDCy3HiA=="],
"@opencode-ai/pty": ["@opencode-ai/pty@0.1.13", "", { "optionalDependencies": { "@opencode-ai/pty-darwin-arm64": "0.1.13", "@opencode-ai/pty-darwin-x64": "0.1.13", "@opencode-ai/pty-linux-arm64-gnu": "0.1.13", "@opencode-ai/pty-linux-arm64-musl": "0.1.13", "@opencode-ai/pty-linux-x64-gnu": "0.1.13", "@opencode-ai/pty-linux-x64-musl": "0.1.13" }, "bin": { "opencode-pty": "bin/opencode-pty.js" } }, "sha512-WPCN8h8HaZhhUcrMG0zu+4D9vco0EZiEg/gCF1K3JPRN6UsHMiXq1HVIy5IlyfcoyjfViRmQmXYE4AuU3laBjA=="],
"@opencode-ai/pty-darwin-arm64": ["@opencode-ai/pty-darwin-arm64@0.2.0", "", { "os": "darwin", "cpu": "arm64" }, "sha512-2y6xrktb2J7rRk+mzAJHA8cCbWhC4Lo2zJ66t9ad59qFhL5nzAPfpEOwnyvvFqhxebHNvL08Mp64M9IHnM0aiA=="],
"@opencode-ai/pty-darwin-arm64": ["@opencode-ai/pty-darwin-arm64@0.1.13", "", { "os": "darwin", "cpu": "arm64" }, "sha512-fVtQZqVLBuJx/aB+5ojfmQifS1KMc9gxlxpFQ6bxEFU8tn8xHQTiFPaNroZgOtaw7I4ceGyx/eXieK1wp68yAA=="],
"@opencode-ai/pty-darwin-x64": ["@opencode-ai/pty-darwin-x64@0.2.0", "", { "os": "darwin", "cpu": "x64" }, "sha512-XVQwK9+KgVGYunCYPCCBf1Or0z6zSkzjgfdJd7dEe/LOFg5vmMkOfSB9dCXnoRCWGviWYk7xd07iFIFOgyj5Ig=="],
"@opencode-ai/pty-darwin-x64": ["@opencode-ai/pty-darwin-x64@0.1.13", "", { "os": "darwin", "cpu": "x64" }, "sha512-b/tAEm0hCMXraPM9cxR8Rg7X1UBZInRTaxWAS4Ht9eH1nWj1rANOLvHWiWX/vVh5TB0Ubg8bWPu4B0nZkEHROQ=="],
"@opencode-ai/pty-linux-arm64-gnu": ["@opencode-ai/pty-linux-arm64-gnu@0.2.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-TPVGCQk5E65IY3ipcpd17rwKehdvXcXEYRhhGzok/6Dske69ei2S+ERz7NXZ8cKFAvbiiT771HHM+XyVYAl+7A=="],
"@opencode-ai/pty-linux-arm64-gnu": ["@opencode-ai/pty-linux-arm64-gnu@0.1.13", "", { "os": "linux", "cpu": "arm64" }, "sha512-I124aSYBBjpGZnYExHfIajkvVK1FiK+//OJBGdqqFp5pas2Oruq4O8tv+pMoxomZIYh2ce/QhOOYLHRwXsthTg=="],
"@opencode-ai/pty-linux-arm64-musl": ["@opencode-ai/pty-linux-arm64-musl@0.2.0", "", { "os": "linux", "cpu": "arm64" }, "sha512-iH6/liY7xN1OXVD9eGzdH11BVGvnpPsH5Z1Unz0Pn9EzkPFf28oDNKNyeXV0xIAP53oiYp8gpRq2PADNwbVsTg=="],
"@opencode-ai/pty-linux-arm64-musl": ["@opencode-ai/pty-linux-arm64-musl@0.1.13", "", { "os": "linux", "cpu": "arm64" }, "sha512-feWsfKpaDytGJzutoK43GqQwVghG2vHZt6BE/ydPZNuqIrySQ/6JfliUAMwn5BWs/Ky7ouSwKHCyAVeukusSvg=="],
"@opencode-ai/pty-linux-x64-gnu": ["@opencode-ai/pty-linux-x64-gnu@0.2.0", "", { "os": "linux", "cpu": "x64" }, "sha512-GhdrmbUzxGHRfWvt1qutgVD4HLb7aSBsgWGjFsc6k8HjO5ZbdaC3ScRyd512YAAG5KAROLKZ6+0SEBsm5xFYlA=="],
"@opencode-ai/pty-linux-x64-gnu": ["@opencode-ai/pty-linux-x64-gnu@0.1.13", "", { "os": "linux", "cpu": "x64" }, "sha512-jliNgsevGuxfIeX7eyzjHhrJkF8uEUPnDLbF2v16uv69FhEHrraf7jyWkxazMP6rNvn2CGtwMMc4BXPS5pzjhg=="],
"@opencode-ai/pty-linux-x64-musl": ["@opencode-ai/pty-linux-x64-musl@0.2.0", "", { "os": "linux", "cpu": "x64" }, "sha512-EbHchDsMmL5aOReIoo8NvQkKnyhyKmoL2RleF2JYF76va3FKuksmwsOBgQJh54i+QA4Fd0+9x54Q+2fJOzPiRQ=="],
"@opencode-ai/pty-linux-x64-musl": ["@opencode-ai/pty-linux-x64-musl@0.1.13", "", { "os": "linux", "cpu": "x64" }, "sha512-rXDpidW66gz2b2M/NbUN8ZKmAxaJcASnuHATeXevlrFdiPUv8uJwvkRd6Pla1fp01Q65MkBmgRa7Q9c+H1PlzA=="],
"@opencode-ai/schema": ["@opencode-ai/schema@0.0.0-beta-18050", "", { "dependencies": { "@standard-schema/spec": "1.1.0", "effect": "4.0.0-rc.111" } }, "sha512-/D6VXaWlytTXR3IOiMLIKuPcfp7FQNUzRPm9z3K7UBFd1Bw4q/WZksaf5RVcBGz+0YRxYMc1V4D7MFlceSgtyg=="],
@@ -3549,7 +3537,7 @@
"bun-ffi-structs": ["bun-ffi-structs@0.3.1", "", { "peerDependencies": { "typescript": "^5" } }, "sha512-3gM7PpVWLyrwxWjcilSiGuhWanhZivvo6l0u573NziPH6f/gwk6McbaYgn7oJWov6pKGRTDbrg94W5DcJsKTtQ=="],
"bun-pty": ["bun-pty@0.4.9", "", {}, "sha512-IUF/B3FANo8vIQ775Zt7Er7lphMpYMhLkes45am2WE8FaVI7KRYtj1rQwliZ18b6GpNzBNWcl7sz9QT5wDFBeQ=="],
"bun-pty": ["bun-pty@0.4.8", "", {}, "sha512-rO70Mrbr13+jxHHHu2YBkk2pNqrJE5cJn29WE++PUr+GFA0hq/VgtQPZANJ8dJo6d7XImvBk37Innt8GM7O28w=="],
"bun-types": ["bun-types@1.4.2", "", { "dependencies": { "@types/node": "*" } }, "sha512-bxV1FgK7yBIzjRe5zBozIM4Bem11ZJcCXSrjWRG3YWLt8yFDePu4cLjpebO8OvPeIE9trbyPF4fuj3Cia4Fj3w=="],
@@ -3913,7 +3901,7 @@
"editorconfig": ["editorconfig@1.0.7", "", { "dependencies": { "@one-ini/wasm": "0.1.1", "commander": "^10.0.0", "minimatch": "^9.0.1", "semver": "^7.5.3" }, "bin": { "editorconfig": "bin/editorconfig" } }, "sha512-e0GOtq/aTQhVdNyDU9e02+wz9oDDM+SIOQxWME2QRjzRX5yyLAuHDE+0aE8vHb9XRC8XD37eO2u57+F09JqFhw=="],
"effect": ["effect@4.0.0-rc.112", "", { "dependencies": { "fast-check": "^4.9.0", "msgpackr": "^2.0.5" } }, "sha512-wXxwuh1Ywnv4cPRM3Wfa0vDwuOHnZ1TsTgHJkG9XgzND6inhBH9n1vBxhg3iIXOia/OrpmvVmd3lrD4vq6bF3A=="],
"effect": ["effect@4.0.0", "", {}, "sha512-ooc1TG5t+FfzgYnFz2ff6BBKyZ7EwBRVXC7c4RhQUAD6/TZ2gTXXMeb4WX7a19ozQo4J73/QW+S00YAIresoMQ=="],
"ejs": ["ejs@3.1.10", "", { "dependencies": { "jake": "^10.8.5" }, "bin": { "ejs": "bin/cli.js" } }, "sha512-UeJmFfOrAQS8OJWPZ4qtgHyWExa088/MtK5UEyoJGFH67cDEXkZSviOiKRCZ4Xij0zxI3JECgYs3oKx+AizQBA=="],
@@ -4751,7 +4739,7 @@
"micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="],
"mime": ["mime@4.1.0", "", { "bin": { "mime": "bin/cli.js" } }, "sha512-X5ju04+cAzsojXKes0B/S4tcYtFAJ6tTMuSPBEn9CPGlrWr8Fiw7qYeLT0XyH80HSoAoqWCaz+MWKh22P7G1cw=="],
"mime": ["mime@3.0.0", "", { "bin": { "mime": "cli.js" } }, "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A=="],
"mime-db": ["mime-db@1.54.0", "", {}, "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ=="],
@@ -4799,10 +4787,6 @@
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
"msgpackr": ["msgpackr@2.0.5", "", { "optionalDependencies": { "msgpackr-extract": "^3.0.4" } }, "sha512-cef05H/dSYpLpqp3sj/qyZh5vhUYCalnaLO7j1yOmpsR0y/XwLVtK7r5gn+U/F7CTEfMowcGhlUQJDLcLf7jcA=="],
"msgpackr-extract": ["msgpackr-extract@3.0.4", "", { "dependencies": { "node-gyp-build-optional-packages": "5.2.2" }, "optionalDependencies": { "@msgpackr-extract/msgpackr-extract-darwin-arm64": "3.0.4", "@msgpackr-extract/msgpackr-extract-darwin-x64": "3.0.4", "@msgpackr-extract/msgpackr-extract-linux-arm": "3.0.4", "@msgpackr-extract/msgpackr-extract-linux-arm64": "3.0.4", "@msgpackr-extract/msgpackr-extract-linux-x64": "3.0.4", "@msgpackr-extract/msgpackr-extract-win32-x64": "3.0.4" }, "bin": { "download-msgpackr-prebuilds": "bin/download-prebuilds.js" } }, "sha512-4kmO/MdyUIkLIvTPr8VHLil4AtoKIoniWPIEk5+CDy0xnWC84azhSFmuJ7PxZdsYtiP5kEeQsORAVIeMgxT+Hw=="],
"muggle-string": ["muggle-string@0.4.1", "", {}, "sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ=="],
"mustache": ["mustache@4.2.0", "", { "bin": { "mustache": "bin/mustache" } }, "sha512-71ippSywq5Yb7/tVYyGbkBggbU8H3u5Rz56fH60jGFgr8uHwxs+aSKeqmluIVzM0m0kB7xQjKS6qPfd0b2ZoqQ=="],
@@ -4845,8 +4829,6 @@
"node-gyp-build": ["node-gyp-build@4.8.4", "", { "bin": { "node-gyp-build": "bin.js", "node-gyp-build-optional": "optional.js", "node-gyp-build-test": "build-test.js" } }, "sha512-LA4ZjwlnUblHVgq0oBF3Jl/6h/Nvs5fzBLwdEF4nuxnFdsfajde4WfxtJr3CaiH+F6ewcIB/q4jQ4UzPyid+CQ=="],
"node-gyp-build-optional-packages": ["node-gyp-build-optional-packages@5.2.2", "", { "dependencies": { "detect-libc": "^2.0.1" }, "bin": { "node-gyp-build-optional-packages": "bin.js", "node-gyp-build-optional-packages-optional": "optional.js", "node-gyp-build-optional-packages-test": "build-test.js" } }, "sha512-s+w+rBWnpTMwSFbaE0UXsRlg7hU4FjekKU4eyAih5T8nJuNZT1nNsskXpxmeqSK9UzkBl6UgRlnKc8hz8IEqOw=="],
"node-html-parser": ["node-html-parser@7.1.0", "", { "dependencies": { "css-select": "^5.1.0", "he": "1.2.0" } }, "sha512-iJo8b2uYGT40Y8BTyy5ufL6IVbN8rbm/1QK2xffXU/1a/v3AAa0d1YAoqBNYqaS4R/HajkWIpIfdE6KcyFh1AQ=="],
"node-int64": ["node-int64@0.4.0", "", {}, "sha512-O5lz91xSOeoXP6DulyHfllpq+Eg00MWitZIbtPfoSEvqIHdl5gfcY6hYzDWnj0qD5tz52PI08u9qUvSVeUBeHw=="],
@@ -5629,7 +5611,7 @@
"typesafe-path": ["typesafe-path@0.2.2", "", {}, "sha512-OJabfkAg1WLZSqJAJ0Z6Sdt3utnbzr/jh+NAHoyWHJe8CMSy79Gm085094M9nvTPy22KzTVn5Zq5mbapCI/hPA=="],
"typescript": ["typescript@5.8.2", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ=="],
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
"typescript-auto-import-cache": ["typescript-auto-import-cache@0.3.6", "", { "dependencies": { "semver": "^7.3.8" } }, "sha512-RpuHXrknHdVdK7wv/8ug3Fr0WNsNi5l5aB8MYYuXhq2UH5lnEB1htJ1smhtD5VeCsGr2p8mUDtd83LCQDFVgjQ=="],
@@ -5643,7 +5625,7 @@
"uncrypto": ["uncrypto@0.1.3", "", {}, "sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q=="],
"undici": ["undici@8.10.0", "", {}, "sha512-HvltHd7avK13QIw/oLe4qoOLyoVSoafqJ2jYOrtMRBkbYT31eiBQ8O0ehRKZiEZCMEyLFQNIADpgCWC5fALvYQ=="],
"undici": ["undici@8.11.2", "", {}, "sha512-u4UB2/IrKdU6lFxumHmmo1a3fCQO5tzQllRorfoRS63txhrB7xTpSn1PftwC4qEHkOaqP95fCWW4lJzwErwzhQ=="],
"undici-types": ["undici-types@7.16.0", "", {}, "sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw=="],
@@ -6095,15 +6077,13 @@
"@bufbuild/protoplugin/typescript": ["typescript@5.4.5", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-vcI4UpRgg81oIRUFwR0WSIHKt11nJ7SAVlYNIu+QpqeyXP+gpQJy/Z4+F0aGxSE4MqwjyXvW/TzgkLAx2AGHwQ=="],
"@cloudflare/kv-asset-handler/mime": ["mime@3.0.0", "", { "bin": { "mime": "cli.js" } }, "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A=="],
"@cloudflare/vite-plugin/vite": ["vite@7.3.6", "", { "dependencies": { "esbuild": "^0.27.0 || ^0.28.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-4XP60spRGjSZFf1qYH+dJIkK2znL3zQfl9KkOV9MkkRR/3Dls0dxaBsQPTloEc5BLXWPL9vsOxopxyKoMmDueg=="],
"@cloudflare/vite-plugin/ws": ["ws@8.18.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw=="],
"@cspotcode/source-map-support/@jridgewell/trace-mapping": ["@jridgewell/trace-mapping@0.3.9", "", { "dependencies": { "@jridgewell/resolve-uri": "^3.0.3", "@jridgewell/sourcemap-codec": "^1.4.10" } }, "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ=="],
"@effect/platform-node-shared/ws": ["ws@8.21.3", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-201TZ/kPWxoPr/OKWjquZR1SWKXcvxdH+e1xrx89b3YbmzLMFCLfnaG1HFIgWzJOEWZ7MvpK++odZufgYR50Rw=="],
"@effect/platform-node-shared/ws": ["ws@8.22.0", "", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-Ydggc987+RO0AnWtZ/7Wq9FtNvcrL1b/RO0ud9mWjUPgDrsAAwQSF51sm2hm1XofbU/4jkpGEsLFsZZxU+1DOg=="],
"@electron/asar/commander": ["commander@5.1.0", "", {}, "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg=="],
@@ -6235,8 +6215,6 @@
"@opencode/console-support/vite": ["vite@7.3.6", "", { "dependencies": { "esbuild": "^0.27.0 || ^0.28.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", "rollup": "^4.43.0", "tinyglobby": "^0.2.15" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^20.19.0 || >=22.12.0", "jiti": ">=1.21.0", "less": "^4.0.0", "lightningcss": "^1.21.0", "sass": "^1.70.0", "sass-embedded": "^1.70.0", "stylus": ">=0.54.8", "sugarss": "^5.0.0", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-4XP60spRGjSZFf1qYH+dJIkK2znL3zQfl9KkOV9MkkRR/3Dls0dxaBsQPTloEc5BLXWPL9vsOxopxyKoMmDueg=="],
"@opencode/desktop/typescript": ["typescript@5.6.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw=="],
"@opencode/enterprise/@tailwindcss/vite": ["@tailwindcss/vite@4.1.11", "", { "dependencies": { "@tailwindcss/node": "4.1.11", "@tailwindcss/oxide": "4.1.11", "tailwindcss": "4.1.11" }, "peerDependencies": { "vite": "^5.2.0 || ^6 || ^7" } }, "sha512-RHYhrR3hku0MJFRV+fN2gNbDNEh3dwKvY8XJvTxCSXeMOsCRSr+uKvDWQcbizrHgjML6ZmTE5OwMrl5wKcujCw=="],
"@opencode/enterprise/tailwindcss": ["tailwindcss@4.1.11", "", {}, "sha512-2E9TBm6MDD/xKYe+dvJZAmg3yxIEDNRc0jwlNyDg/4Fil2QcSLjFKGVff0lAf1jjeaArlG/M75Ey/EYr/OJtBA=="],
@@ -6695,6 +6673,8 @@
"tw-to-css/tailwindcss": ["tailwindcss@3.3.2", "", { "dependencies": { "@alloc/quick-lru": "^5.2.0", "arg": "^5.0.2", "chokidar": "^3.5.3", "didyoumean": "^1.2.2", "dlv": "^1.1.3", "fast-glob": "^3.2.12", "glob-parent": "^6.0.2", "is-glob": "^4.0.3", "jiti": "^1.18.2", "lilconfig": "^2.1.0", "micromatch": "^4.0.5", "normalize-path": "^3.0.0", "object-hash": "^3.0.0", "picocolors": "^1.0.0", "postcss": "^8.4.23", "postcss-import": "^15.1.0", "postcss-js": "^4.0.1", "postcss-load-config": "^4.0.1", "postcss-nested": "^6.0.1", "postcss-selector-parser": "^6.0.11", "postcss-value-parser": "^4.2.0", "resolve": "^1.22.2", "sucrase": "^3.32.0" }, "bin": { "tailwind": "lib/cli.js", "tailwindcss": "lib/cli.js" } }, "sha512-9jPkMiIBXvPc2KywkraqsUfbfj+dHDb+JPWtSJa9MLFdrPyazI7q6WX2sUrm7R9eVR7qqv3Pas7EvQFzxKnI6w=="],
"unifont/undici": ["undici@8.10.0", "", {}, "sha512-HvltHd7avK13QIw/oLe4qoOLyoVSoafqJ2jYOrtMRBkbYT31eiBQ8O0ehRKZiEZCMEyLFQNIADpgCWC5fALvYQ=="],
"unplugin/acorn": ["acorn@8.18.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-lGq+9yr1/GuAWaVYIHRjvvySG5/4VfKIvC8EWxStPdcDh/Ka7FG3twP6v4d5BkravUilhIAsG4Qj83t02LWUPQ=="],
"unused-filename/escape-string-regexp": ["escape-string-regexp@5.0.0", "", {}, "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw=="],
+2 -24
View File
@@ -13,12 +13,7 @@
opencode,
}:
let
electronPin =
(lib.pipe ../packages/desktop/package.json [
builtins.readFile
builtins.fromJSON
]).devDependencies.electron;
electron = callPackage ./electron.nix { inherit electronPin; };
electron = callPackage ./electron.nix { };
in
stdenv.mkDerivation (finalAttrs: {
pname = "opencode-desktop";
@@ -40,8 +35,6 @@ stdenv.mkDerivation (finalAttrs: {
copyDesktopItems
]
++ lib.optionals stdenv.hostPlatform.isDarwin [
darwin.cctools
darwin.sigtool
# Ad-hoc sign the .app: --config.mac.identity=null below skips signing.
darwin.autoSignDarwinBinariesHook
];
@@ -73,7 +66,7 @@ stdenv.mkDerivation (finalAttrs: {
''
# https://github.com/electron/electron/issues/31121
# mac builds use a .app bundle which doesnt have this issue
+ lib.optionalString stdenv.hostPlatform.isLinux ''
+ lib.optionalString stdenv.isLinux ''
substituteInPlace \
packages/desktop/src/main/windows/appearance.ts \
packages/desktop/src/main/service/desktop-cli.ts \
@@ -81,7 +74,6 @@ stdenv.mkDerivation (finalAttrs: {
'';
preBuild = ''
echo "electron ${electron.version} from nixpkgs ${lib.version}, package.json pins ${electronPin}"
cp -r "${electron.dist}" $HOME/.electron-dist
chmod -R u+w $HOME/.electron-dist
@@ -97,15 +89,8 @@ stdenv.mkDerivation (finalAttrs: {
export OPENCODE_CLI_DIST="$TMPDIR/desktop-cli"
cli_package=$(bun -e 'import { getCurrentCli } from "./scripts/utils.ts"; console.log(getCurrentCli().package.replace("@opencode/", ""))')
# copyBuiltCliToResources joins this dist with the npm package name getCurrentCli()
# reports, not the Nix build's name. It reads only .version from the manifest and
# writes it as opencode-cli.version beside the binary.
mkdir -p "$OPENCODE_CLI_DIST/$cli_package/bin"
cp ${lib.getExe opencode} "$OPENCODE_CLI_DIST/$cli_package/bin/opencode"
# OPENCODE_VERSION is what the bundled CLI prints for --version, so the manifest
# and the executable cannot drift.
bun -e 'await Bun.write(process.argv[1], JSON.stringify({ version: process.env.OPENCODE_VERSION }) + "\n")' \
"$OPENCODE_CLI_DIST/$cli_package/package.json"
bun run build
npx electron-builder --dir \
@@ -153,13 +138,6 @@ stdenv.mkDerivation (finalAttrs: {
"libc.musl-x86_64.so.1"
];
passthru = {
# electronVersion is what ships; electronPin is what packages/desktop/package.json
# asks for. They differ whenever nixpkgs carries no release of the pinned minor.
electronVersion = electron.version;
inherit electronPin;
};
meta = {
description = "OpenCode Desktop App";
mainProgram = "opencode-desktop";
+10 -8
View File
@@ -1,10 +1,12 @@
{ lib, pkgs, electronPin }:
{ callPackage, path }:
let
# Nixpkgs owns the release hashes, so bumping the pin no longer means editing this repo. Only the
# major is delegated, so what gets built trails the pin whenever nixpkgs has not shipped it yet.
# That is safe: the bundle ships one native addon, node-pty's Node-API prebuild, and
# only the win32 WSL runtime loads it, so nothing in the main process binds the
# Electron ABI.
major = lib.versions.major electronPin;
version = (builtins.fromJSON (builtins.readFile ../packages/desktop/package.json)).devDependencies.electron;
in
pkgs."electron_${major}-bin" or (throw "nixpkgs ${lib.version} carries no prebuilt electron ${major}: run `nix flake update nixpkgs`, or pin a major nixpkgs still carries")
(callPackage (path + "/pkgs/development/tools/electron/binary/generic.nix") { }) version {
# Electron 42.10.1 SHASUMS256.txt; update with the desktop package version.
aarch64-linux = "20e68d6c4e47f3ebf59de7c6b1f8b8bec6a6ebda6a451132f9b465f3f13ce467";
x86_64-linux = "2452b27112d92387471fa2488aafac85d79ea3f2ee1216c0abd5150d6c12362b";
aarch64-darwin = "ac7194a3dfd81930ba35355c01620262c1254752859b42dcb8f4b9e4d174a871";
# fetchzip hashes the unpacked headers, not the release tarball.
headers = "sha256-4eUy3BZVvxTl7KUOsxio7769lL6ag/ecbeK+qLURWMI=";
}
+3 -3
View File
@@ -1,7 +1,7 @@
{
"nodeModules": {
"x86_64-linux": "sha256-2RlbJRTEKSliuUbAE2lAktX63JFR/RKAuLkcCou8wb4=",
"aarch64-linux": "sha256-P7DAE018lTJNGmttg87U9oaTAuw/wHlnMStdnXYKCr0=",
"aarch64-darwin": "sha256-N+NfV1ObOTnW+ez7As+CS+6ci/iRGCQ6cslvyQFCp6E="
"x86_64-linux": "sha256-g3k0cAFGqzmRYlcIkg1NDvlx1WxHYhnYPL0/a8E+qTg=",
"aarch64-linux": "sha256-a+3ymqdxOONGe2Tpq4GUccl1b+Dwzxlb9LFXgE1gZ+0=",
"aarch64-darwin": "sha256-h8xIzuMmaWfJqjHCO74xUDCWNKQLFrIGoKYZ+2TauYc="
}
}
+6 -22
View File
@@ -12,7 +12,7 @@
installShellFiles,
versionCheckHook,
writableTmpDirAsHomeHook,
node_modules ? callPackage ./node_modules.nix { },
node_modules ? callPackage ./node-modules.nix { },
}:
stdenvNoCC.mkDerivation (finalAttrs: {
pname = "opencode";
@@ -85,30 +85,14 @@ stdenvNoCC.mkDerivation (finalAttrs: {
'';
postInstall = lib.optionalString (stdenvNoCC.buildPlatform.canExecute stdenvNoCC.hostPlatform) ''
# v2 dropped the `completion` subcommand; --completions is the global flag.
# --completions also accepts sh, which emits the same script as bash.
# staged to files, substitute below rejects anything that is not a regular file
$out/bin/opencode --completions bash > opencode.bash
$out/bin/opencode --completions zsh > _opencode
$out/bin/opencode --completions fish > opencode.fish
# trick yargs into also generating zsh completions
installShellCompletion --cmd opencode \
--bash opencode.bash \
--fish opencode.fish \
--zsh _opencode
# OPENCODE_CLI_NAME is a build-time define, so the opencode2 copies are
# renamed rather than regenerated. --replace-fail is a global literal
# substitution, so any lowercase opencode that later appears in a
# description or help text ships as opencode2 in the opencode2 copy.
substitute opencode.bash opencode2.bash --replace-fail opencode opencode2
substitute _opencode _opencode2 --replace-fail opencode opencode2
substitute opencode.fish opencode2.fish --replace-fail opencode opencode2
--bash <($out/bin/opencode completion) \
--zsh <(SHELL=/bin/zsh $out/bin/opencode completion)
installShellCompletion --cmd opencode2 \
--bash opencode2.bash \
--fish opencode2.fish \
--zsh _opencode2
--bash <($out/bin/opencode2 completion) \
--zsh <(SHELL=/bin/zsh $out/bin/opencode2 completion)
'';
nativeInstallCheckInputs = [
+8 -9
View File
@@ -2,7 +2,7 @@
"$schema": "https://json.schemastore.org/package.json",
"name": "opencode",
"description": "AI-powered development tool",
"version": "2.0.22",
"version": "2.0.21",
"private": true,
"type": "module",
"packageManager": "bun@1.4.2",
@@ -18,8 +18,7 @@
"dev:www": "bun run --cwd services/www dev",
"dev:storybook": "bun --cwd packages/storybook storybook",
"bench:devex": "bun run --cwd packages/app test:bench:devex",
"lint": "oxlint && ast-grep scan -c script/ast-grep/gui-extensions/sgconfig.yml && bun script/sdk-docs.ts",
"lint:changed": "bun script/lint-changed.ts",
"lint": "oxlint && ast-grep scan -c script/ast-grep/gui-extensions/sgconfig.yml",
"lint:effect-patterns": "ast-grep scan -c script/ast-grep/sgconfig.yml packages/util/src packages/core/src packages/server/src packages/protocol/src packages/cli/src",
"lint:effect-simplifications": "ast-grep scan -c script/ast-grep/effect-simplifications/sgconfig.yml --off=unused-suppression packages",
"test:lint-rules": "ast-grep test -c script/ast-grep/sgconfig.yml",
@@ -43,10 +42,10 @@
"packages/stats/*"
],
"catalog": {
"@effect/opentelemetry": "4.0.0-rc.112",
"@effect/platform-node": "4.0.0-rc.112",
"@effect/platform-node-shared": "4.0.0-rc.112",
"@effect/sql-sqlite-bun": "4.0.0-rc.112",
"@effect/opentelemetry": "4.0.0",
"@effect/platform-node": "4.0.0",
"@effect/platform-node-shared": "4.0.0",
"@effect/sql-sqlite-bun": "4.0.0",
"@npmcli/arborist": "9.4.0",
"@types/bun": "1.4.0",
"@types/cross-spawn": "6.0.6",
@@ -80,7 +79,7 @@
"dompurify": "3.4.14",
"drizzle-kit": "1.0.0-rc.5-ab785fc",
"drizzle-orm": "1.0.0-rc.5-169397b",
"effect": "4.0.0-rc.112",
"effect": "4.0.0",
"ai": "6.0.168",
"cross-spawn": "7.0.6",
"hono": "4.10.7",
@@ -93,7 +92,7 @@
"remend": "1.3.1",
"@playwright/test": "1.59.1",
"semver": "7.7.4",
"typescript": "5.8.2",
"typescript": "5.9.3",
"@typescript/native-preview": "7.0.0-dev.20251207.1",
"zod": "4.1.8",
"remeda": "2.26.0",
+1 -26
View File
@@ -27,31 +27,6 @@ Run `LLM.stream(...)` instead of `generate` when you want incremental `LLMEvent`
`LLM.request(...)`. The event stream is provider-neutral — same shape across OpenAI Chat, OpenAI Responses,
Anthropic Messages, Gemini, Bedrock Converse, and any OpenAI-compatible deployment.
### Google Interactions
`Google.configure({ apiKey }).interactions(modelID)` selects the Interactions API; `.model(modelID)` still selects
GenerateContent. The package entrypoint is `@opencode/ai/providers/google/interactions`.
```ts
const model = Google.configure({ apiKey }).interactions("gemini-3.8-flash")
const response = yield* LLM.generate({
model,
prompt: "Say hello.",
providerOptions: { thinkingLevel: "low", thinkingSummaries: "auto", store: true },
})
```
Interactions supports text output, streamed function calls, native tool results, thought signatures, and multimodal
input. Full-history replay is the default (`store: false`); implicit caching works without retained interactions.
For server-side continuation, set `store: true` on the predecessor, read `interactionId` from the final event's
`providerMetadata.google`, and pass `previousInteractionId` on the next request with **only new messages**. Repeat
the system instructions and tool declarations on each request. Set `store: true` on each response you intend to
continue from. The package does not automatically select or persist continuation IDs.
Raw usage is preserved in `usage.providerMetadata.google`. `inputTokens` follows Google's top-level accounting;
`contextTokens` uses its full `raw_prompt_token` count when supplied. These can differ substantially with server-side
continuation. Explicit caches, hosted tools, and generated media are not supported by this initial protocol.
The same configured facade names image, video, speech, and transcription models. `Image.generate` resolves the
provider's image route from the model and returns `Media.Asset`s with lazily decoded bytes:
@@ -1248,7 +1223,7 @@ const gateway = CloudflareAIGateway.configure({
}).model("workers-ai/@cf/meta/llama-3.1-8b-instruct")
```
Included LLM providers: OpenAI, Anthropic, Google (Gemini), Google Vertex, Amazon Bedrock, Azure OpenAI, Baseten, Cerebras, Cohere, Cloudflare AI Gateway, Cloudflare Workers AI, DeepInfra, DeepSeek, Fireworks, Groq, Mistral, OpenRouter, TogetherAI, and xAI. Z.ai currently exposes image generation. Generic Chat Completions, Responses, and Anthropic Messages-compatible entrypoints support custom endpoints.
Included LLM providers: OpenAI, Anthropic, Google (Gemini), Google Vertex, Amazon Bedrock, Azure OpenAI, Baseten, Cerebras, Cloudflare AI Gateway, Cloudflare Workers AI, DeepInfra, DeepSeek, Fireworks, Groq, Mistral, OpenRouter, TogetherAI, and xAI. Z.ai currently exposes image generation. Generic Chat Completions, Responses, and Anthropic Messages-compatible entrypoints support custom endpoints.
Each named provider owns its module, endpoint, authentication, and route setup. Providers with the same wire format compose the shared protocol directly:
+1 -1
View File
@@ -15,7 +15,7 @@ import { OpenAI } from "@opencode/ai/providers"
* hover imports and local values to see how the public API is typed.
*/
const apiKey = Config.redacted("OPENAI_API_KEY")
const apiKey = Config.Redacted("OPENAI_API_KEY")
// 1. Configure a provider. The configured facade records provider identity,
// deployment options, authentication, and defaults. Per-modality selectors pick
+1 -1
View File
@@ -1,6 +1,6 @@
{
"$schema": "https://json.schemastore.org/package.json",
"version": "2.0.22",
"version": "2.0.21",
"name": "@opencode/ai",
"type": "module",
"license": "MIT",
+2 -2
View File
@@ -5,7 +5,7 @@ import * as path from "node:path"
import * as prompts from "@clack/prompts"
import { AwsV4Signer } from "aws4fetch"
import { Config, ConfigProvider, Effect, FileSystem, PlatformError, Redacted } from "effect"
import { FetchHttpClient, HttpClient, HttpClientRequest, type HttpClientResponse } from "effect/unstable/http"
import { FetchHttpClient, HttpClient, HttpClientRequest, type HttpClientResponse } from "effect/http"
import * as ProviderShared from "../src/protocols/shared"
import { CloudflareAIGateway } from "../src/providers/cloudflare-ai-gateway.js"
import { CloudflareWorkersAI } from "../src/providers/cloudflare-workers-ai.js"
@@ -383,7 +383,7 @@ const readEnvFile = Effect.fn("RecordingEnv.readFile")(function* () {
})
const readConfigString = (provider: ConfigProvider.ConfigProvider, name: string) =>
Config.string(name)
Config.String(name)
.parse(provider)
.pipe(
Effect.match({
+2 -8
View File
@@ -38,7 +38,6 @@ const resolve = (policy: CachePolicy | undefined): CachePolicyObject => {
// prefix caching, Gemini's implicit + out-of-band CachedContent). Skip the
// whole policy pass for these — emitting hints would be harmless but pointless.
const RESPECTS_INLINE_HINTS = new Set([
"alibaba-chat",
"alibaba-messages",
"anthropic-messages",
"anthropic-compatible-messages",
@@ -56,12 +55,11 @@ const RESPECTS_INLINE_HINTS = new Set([
// OpenRouter upstreams other than Anthropic and Alibaba Qwen cache without breakpoints. Gemini uses only the last
// breakpoint, so a conversation-tail breakpoint writes a new cache every step and costs more than none. Qwen ignores
// breakpoints on tool definitions and caches tools with the system prompt.
const QWEN: CachePolicyObject = { system: true, messages: { tail: 1 } }
const openRouterPolicy = (modelID: string): CachePolicyObject => {
// `~anthropic/claude-sonnet-latest` style IDs are OpenRouter aliases for the latest model in a family.
const id = modelID.replace(/^~/, "")
if (id.startsWith("anthropic/")) return AUTO
if (id.startsWith("qwen/")) return QWEN
if (id.startsWith("qwen/")) return { system: true, messages: { tail: 1 } }
return NONE
}
@@ -173,11 +171,7 @@ export const applyCachePolicy = (request: LLMRequest): LLMRequest => {
const policy =
request.model.route.id === "openrouter" && (request.cache === undefined || request.cache === "auto")
? openRouterPolicy(request.model.id)
: request.model.route.id === "alibaba-chat" && (request.cache === undefined || request.cache === "auto")
? request.model.id.toLowerCase().startsWith("qwen")
? QWEN
: NONE
: resolve(request.cache)
: resolve(request.cache)
if (!policy.tools && !policy.system && !policy.messages) return request
const hint = makeHint(policy.ttlSeconds)
+1 -1
View File
@@ -1,5 +1,5 @@
import { Effect, Schema } from "effect"
import { Headers, HttpClientRequest } from "effect/unstable/http"
import { Headers, HttpClientRequest } from "effect/http"
import {
ChoiceQuestion,
EvaluationInput,
+2 -1
View File
@@ -1,4 +1,5 @@
import { Effect, Schema, Stream } from "effect"
import { extendSchema } from "@opencode/schema/schema"
import { Generation, ProgressEvent, QueuedEvent, type AwaitOptions } from "./generation.js"
import { Media } from "./media.js"
import { MediaModel, composeRoute, tryRequest } from "./media-model.js"
@@ -142,7 +143,7 @@ const imageEventTagged = Schema.Union([
ImageOutputEvent,
ImageFinishEvent,
]).pipe(Schema.toTaggedUnion("type"))
export const ImageEvent = Object.assign(imageEventTagged, {
export const ImageEvent = extendSchema(imageEventTagged, {
is: {
generationQueued: imageEventTagged.guards["generation-queued"],
generationProgress: imageEventTagged.guards["generation-progress"],
+7 -6
View File
@@ -1,7 +1,8 @@
export * as Media from "./media.js"
import { Effect, Encoding, FileSystem, Schema, SchemaGetter } from "effect"
import { HttpClientRequest } from "effect/unstable/http"
import { Effect, FileSystem, Schema, SchemaGetter } from "effect"
import { Base64 } from "effect/encoding"
import { HttpClientRequest } from "effect/http"
import { ProviderID } from "./schema/ids.js"
import { AIError, HttpContext, InvalidProviderOutputError, InvalidRequestError } from "./schema/errors.js"
import { ProviderMetadata } from "./schema/options.js"
@@ -140,7 +141,7 @@ export class Asset {
inline(): Inline | undefined {
const source = this.source
if (source.type !== "bytes" && source.type !== "base64") return undefined
const base64 = source.type === "base64" ? source.data : (this.#base64 ??= Encoding.encodeBase64(source.data))
const base64 = source.type === "base64" ? source.data : (this.#base64 ??= Base64.encode(source.data))
const mime = this.mediaType.toLowerCase()
return { mime, base64, dataUrl: `data:${mime};base64,${base64}` }
}
@@ -155,7 +156,7 @@ export class Asset {
return Effect.fail(invalid(`Cannot materialize provider ref ${source.provider}:${source.id}`))
const decoded =
source.type === "base64"
? Effect.fromResult(Encoding.decodeBase64(source.data)).pipe(
? Effect.fromResult(Base64.decode(source.data)).pipe(
Effect.mapError((cause) => invalid(`Media asset contains invalid base64 data`, cause)),
)
: download(source, this.headers)
@@ -168,7 +169,7 @@ export class Asset {
const source = this.source
if (source.type === "base64") return Effect.succeed(source.data)
if (this.#base64 !== undefined) return Effect.succeed(this.#base64)
return this.bytes().pipe(Effect.map((data) => (this.#base64 = Encoding.encodeBase64(data))))
return this.bytes().pipe(Effect.map((data) => (this.#base64 = Base64.encode(data))))
})
}
@@ -183,7 +184,7 @@ export class Asset {
toJSON() {
const source = this.source
return {
source: source.type === "bytes" ? { ...source, data: Encoding.encodeBase64(source.data) } : source,
source: source.type === "bytes" ? { ...source, data: Base64.encode(source.data) } : source,
info: this.info,
providerMetadata: this.providerMetadata,
}
+1 -2
View File
@@ -3,7 +3,6 @@ import { Protocol } from "../route/protocol.js"
import type { LanguageModelCompatibility } from "../schema/index.js"
import { OpenAIChat } from "./openai-chat.js"
import { JsonObject, ProviderShared } from "./shared.js"
import { cacheControl } from "./utils/cache.js"
import { OpenResponsesOptions } from "./utils/open-responses-options.js"
export type ReasoningEffort = OpenResponsesOptions.ReasoningEffort
@@ -69,7 +68,7 @@ export const protocol = Protocol.make({
from: Effect.fn("AlibabaChat.fromRequest")(function* (req) {
const opts = yield* ProviderShared.validateWith(Schema.decodeUnknownEffect(Options))(req.providerOptions ?? {})
return {
...(yield* OpenAIChat.fromRequest(req, { cacheControl: cacheControl() })),
...(yield* OpenAIChat.protocol.body.from(req)),
enable_thinking: opts.enableThinking,
// Alibaba also rejects an explicit budget that is not below `max_completion_tokens`.
thinking_budget:
@@ -1,7 +1,7 @@
import { Effect, Schema } from "effect"
import { Protocol } from "../route/protocol.js"
import { OpenResponses } from "./open-responses.js"
import { JsonObject, ProviderShared } from "./shared.js"
import { JsonObject, optionalArray, ProviderShared } from "./shared.js"
import { OpenResponsesOptions } from "./utils/open-responses-options.js"
import { ResponsesHostedTools } from "./utils/responses-hosted-tools.js"
@@ -25,6 +25,8 @@ const WebExtractorItem = Schema.StructWithRest(
)
const Body = Schema.Struct({
...OpenResponses.coreFields,
input: Schema.Array(Schema.Union([OpenResponses.InputItem, WebExtractorItem])),
tools: optionalArray(Schema.Union([OpenResponses.Tool, NativeTool])),
enable_thinking: Options.fields.enableThinking,
previous_response_id: Options.fields.previousResponseId,
conversation: Options.fields.conversation,
@@ -50,7 +52,7 @@ export const protocol = Protocol.make({
const opts = yield* ProviderShared.validateWith(Schema.decodeUnknownEffect(Options))(req.providerOptions ?? {})
const body = yield* OpenResponses.fromRequestWithAdapter(req, adapter)
const choice = body.tool_choice
return {
return yield* ProviderShared.validateWith(Schema.decodeUnknownEffect(Body))({
...body,
enable_thinking: opts.enableThinking,
previous_response_id: opts.previousResponseId,
@@ -60,7 +62,7 @@ export const protocol = Protocol.make({
typeof choice === "object" && choice.type === "function"
? { type: "allowed_tools" as const, mode: "required" as const, tools: [choice] }
: choice,
}
})
}),
},
stream: {
@@ -6,7 +6,7 @@ import { Auth } from "../route/auth.js"
import { Endpoint } from "../route/endpoint.js"
import { Framing } from "../route/framing.js"
import { Protocol } from "../route/protocol.js"
import { Headers } from "effect/unstable/http"
import { Headers } from "effect/http"
import { HttpTransport } from "../route/transport/index.js"
import {
AIError,
@@ -1,5 +1,5 @@
import { Effect, Schema } from "effect"
import type { HttpClientResponse } from "effect/unstable/http"
import type { HttpClientResponse } from "effect/http"
import type { Status } from "../generation.js"
import { Media } from "../media.js"
import { MediaProtocol } from "../route/media-protocol.js"
@@ -1,4 +1,5 @@
import { Effect, Encoding, Schema } from "effect"
import { Effect, Schema } from "effect"
import { Base64 } from "effect/encoding"
import { Route } from "../route/client.js"
import { Endpoint } from "../route/endpoint.js"
import { Protocol } from "../route/protocol.js"
@@ -610,7 +611,7 @@ interface ParserState {
readonly reasoningRedactedContent: Readonly<Record<number, Uint8Array[]>>
}
const encodeRedactedContent = (chunks: ReadonlyArray<Uint8Array>) => Encoding.encodeBase64(concatBytes(chunks))
const encodeRedactedContent = (chunks: ReadonlyArray<Uint8Array>) => Base64.encode(concatBytes(chunks))
const step = (state: ParserState, event: BedrockEvent) =>
Effect.gen(function* () {
@@ -659,7 +660,7 @@ const step = (state: ParserState, event: BedrockEvent) =>
const events: LLMEvent[] = []
const redactedChunk = yield* (() => {
if (reasoning.redactedContent === undefined) return Effect.succeed(undefined)
return Effect.fromResult(Encoding.decodeBase64(reasoning.redactedContent)).pipe(
return Effect.fromResult(Base64.decode(reasoning.redactedContent)).pipe(
Effect.mapError((cause) =>
ProviderShared.eventError(
ADAPTER,
@@ -1,6 +1,7 @@
import { EventStreamCodec } from "@smithy/eventstream-codec"
import { fromUtf8, toUtf8 } from "@smithy/util-utf8"
import { Effect, Encoding, Stream } from "effect"
import { Effect, Stream } from "effect"
import { Base64 } from "effect/encoding"
import { AIError, AIErrorReason, InvalidProviderOutputError } from "../schema/index.js"
import { Framing } from "../route/framing.js"
import { ProviderShared } from "./shared.js"
@@ -47,7 +48,7 @@ const consumeFrames = (route: string) => (state: FrameBufferState, input: FrameI
route,
classification: "incomplete-stream",
message: `Incomplete Bedrock Converse event-stream frame: ${remaining.length} buffered bytes remain at end of stream`,
body: Encoding.encodeBase64(remaining),
body: Base64.encode(remaining),
}),
})
return [state, []] as const
@@ -68,7 +69,7 @@ const consumeFrames = (route: string) => (state: FrameBufferState, input: FrameI
`Failed to decode Bedrock Converse event-stream frame: ${
error instanceof Error ? error.message : String(error)
}`,
Encoding.encodeBase64(view.subarray(0, totalLength)),
Base64.encode(view.subarray(0, totalLength)),
error,
),
})
+1 -1
View File
@@ -1,5 +1,5 @@
import { Effect, Schema } from "effect"
import type { HttpClientResponse } from "effect/unstable/http"
import type { HttpClientResponse } from "effect/http"
import type { Status } from "../generation.js"
import { ImageModel, ImageResponse, type ImageRequestFor } from "../image.js"
import { Media } from "../media.js"
-334
View File
@@ -1,334 +0,0 @@
import { Effect, Schema } from "effect"
import { Route } from "../route/client.js"
import { Endpoint } from "../route/endpoint.js"
import { Framing } from "../route/framing.js"
import { Protocol } from "../route/protocol.js"
import { LLMEvent, Usage, type FinishReasonDetails, type LLMRequest } from "../schema/index.js"
import { ProviderShared } from "./shared.js"
import { Lifecycle } from "./utils/lifecycle.js"
import { ToolStream } from "./utils/tool-stream.js"
const ADAPTER = "cohere-chat"
export const DEFAULT_BASE_URL = "https://api.cohere.com/v2"
const Options = Schema.Struct({
thinking: Schema.optional(
Schema.Struct({
type: Schema.optional(Schema.Literals(["enabled", "disabled"])),
tokenBudget: Schema.optional(Schema.Int.check(Schema.isGreaterThan(0))),
}),
),
})
export type ProviderOptionsInput = Schema.Schema.Type<typeof Options>
const Content = Schema.Union([
Schema.Struct({ type: Schema.Literal("text"), text: Schema.String }),
Schema.Struct({ type: Schema.Literal("thinking"), thinking: Schema.String }),
Schema.Struct({ type: Schema.Literal("image_url"), image_url: Schema.Struct({ url: Schema.String }) }),
])
const ToolCall = Schema.Struct({
id: Schema.String,
type: Schema.Literal("function"),
function: Schema.Struct({ name: Schema.String, arguments: Schema.String }),
})
const Message = Schema.Struct({
role: Schema.Literals(["system", "user", "assistant", "tool"]),
content: Schema.optional(Schema.Union([Schema.String, Schema.Array(Content)])),
tool_calls: Schema.optional(Schema.Array(ToolCall)),
tool_call_id: Schema.optional(Schema.String),
tool_plan: Schema.optional(Schema.String),
})
const Body = Schema.Struct({
model: Schema.String,
messages: Schema.Array(Message),
stream: Schema.Literal(true),
tools: Schema.optional(
Schema.Array(
Schema.Struct({
type: Schema.Literal("function"),
function: Schema.Struct({
name: Schema.String,
description: Schema.optional(Schema.String),
parameters: Schema.Unknown,
}),
}),
),
),
tool_choice: Schema.optional(Schema.Literals(["NONE", "REQUIRED"])),
thinking: Schema.optional(Schema.Struct({ type: Schema.String, token_budget: Schema.optional(Schema.Number) })),
max_tokens: Schema.optional(Schema.Number),
temperature: Schema.optional(Schema.Number),
p: Schema.optional(Schema.Number),
k: Schema.optional(Schema.Number),
seed: Schema.optional(Schema.Number),
stop_sequences: Schema.optional(Schema.Array(Schema.String)),
frequency_penalty: Schema.optional(Schema.Number),
presence_penalty: Schema.optional(Schema.Number),
})
const TokenCounts = Schema.Struct({
input_tokens: Schema.optional(Schema.Number),
output_tokens: Schema.optional(Schema.Number),
reasoning_tokens: Schema.optional(Schema.Number),
})
const NativeUsage = Schema.Struct({
tokens: Schema.optional(TokenCounts),
billed_units: Schema.optional(TokenCounts),
cached_tokens: Schema.optional(Schema.Number),
})
const Event = Schema.Union([
Schema.Struct({ type: Schema.Literal("message-start") }),
Schema.Struct({
type: Schema.Literals(["content-start", "content-delta"]),
index: Schema.Number,
delta: Schema.Struct({
message: Schema.Struct({
content: Schema.Struct({ text: Schema.optional(Schema.String), thinking: Schema.optional(Schema.String) }),
}),
}),
}),
Schema.Struct({ type: Schema.Literal("content-end"), index: Schema.Number }),
Schema.Struct({
type: Schema.Literal("tool-plan-delta"),
delta: Schema.Struct({ message: Schema.Struct({ tool_plan: Schema.String }) }),
}),
Schema.Struct({
type: Schema.Literals(["tool-call-start", "tool-call-delta"]),
index: Schema.Number,
delta: Schema.Struct({
message: Schema.Struct({
tool_calls: Schema.Struct({
id: Schema.optional(Schema.String),
function: Schema.Struct({ name: Schema.optional(Schema.String), arguments: Schema.optional(Schema.String) }),
}),
}),
}),
}),
Schema.Struct({ type: Schema.Literal("tool-call-end"), index: Schema.Number }),
Schema.Struct({
type: Schema.Literal("message-end"),
delta: Schema.Struct({ finish_reason: Schema.String, usage: Schema.optional(NativeUsage) }),
}),
// Citation output is outside this basic chat surface.
Schema.Struct({ type: Schema.Literals(["citation-start", "citation-end"]) }),
])
type Event = typeof Event.Type
type State = {
readonly lifecycle: Lifecycle.State
readonly tools: ToolStream.State<number>
readonly finished: boolean
}
const TOOL_CHOICE = { auto: undefined, none: "NONE", required: "REQUIRED", tool: "REQUIRED" } as const
const fromRequest = Effect.fn("CohereChat.fromRequest")(function* (request: LLMRequest) {
const options = yield* ProviderShared.validateWith(Schema.decodeUnknownEffect(Options))(request.providerOptions ?? {})
const flattened = ProviderShared.flattenToolRequest(request)
const messages: (typeof Message.Type)[] = request.system.length
? [
{
role: "system",
content:
request.system.length === 1
? request.system[0].text
: request.system.map((part) => ({ type: "text", text: part.text })),
},
]
: []
for (const message of flattened.request.messages) {
if (message.role === "system") {
messages.push({ role: "user", content: (yield* ProviderShared.wrappedSystemUpdate("Cohere Chat", message)).text })
continue
}
if (message.role === "tool") {
for (const part of message.content) {
if (part.type !== "tool-result")
return yield* ProviderShared.unsupportedContent("Cohere Chat", "tool", ["tool-result"])
if (part.result.type === "content" && part.result.value.some((item) => item.type === "file"))
return yield* ProviderShared.invalidRequest("Cohere Chat does not support file content in tool results")
messages.push({ role: "tool", tool_call_id: part.id, content: ProviderShared.toolResultText(part) })
}
continue
}
const content: (typeof Content.Type)[] = []
const calls: (typeof ToolCall.Type)[] = []
const plans: string[] = []
for (const part of message.content) {
if (part.type === "text") {
content.push({ type: "text", text: part.text })
continue
}
if (message.role === "assistant" && part.type === "reasoning") {
if (part.providerMetadata?.cohere?.toolPlan === true) plans.push(part.text)
else content.push({ type: "thinking", thinking: part.text })
continue
}
if (message.role === "assistant" && part.type === "tool-call") {
const args = ProviderShared.encodeJson(part.input)
calls.push({ id: part.id, type: "function", function: { name: part.name, arguments: args } })
continue
}
if (message.role === "user" && part.type === "media" && part.media.mediaType.startsWith("image/")) {
const url =
ProviderShared.mediaUrl(part.media) ??
(yield* ProviderShared.requireInlineMedia("Cohere Chat", part.media)).dataUrl
content.push({ type: "image_url", image_url: { url } })
continue
}
return yield* ProviderShared.unsupportedContent(
"Cohere Chat",
message.role,
message.role === "user" ? ["text", "media"] : ["text", "reasoning", "tool-call"],
)
}
messages.push({
role: message.role,
content: content.length ? content : undefined,
tool_calls: calls.length ? calls : undefined,
tool_plan: plans.length ? plans.join("") : undefined,
})
}
const selected = request.toolChoice?.type === "tool" ? request.toolChoice.name : undefined
const tools = selected === undefined ? flattened.tools : flattened.tools.filter((tool) => tool.name === selected)
if (selected !== undefined && tools.length === 0)
return yield* ProviderShared.invalidRequest("Cohere Chat tool choice must name an available tool")
if (tools.some((tool) => tool.native !== undefined))
return yield* ProviderShared.invalidRequest("Cohere Chat does not support provider-defined tools")
return {
model: request.model.id,
messages,
stream: true as const,
tools: tools.length
? tools.map((tool) => ({
type: "function" as const,
function: { name: tool.name, description: tool.description, parameters: tool.inputSchema },
}))
: undefined,
tool_choice: TOOL_CHOICE[request.toolChoice?.type ?? "auto"],
thinking: options.thinking && {
type: options.thinking.type ?? "enabled",
// Cohere rejects budgets above max_tokens; fitting also leaves room for the answer.
token_budget:
options.thinking.tokenBudget === undefined
? undefined
: ProviderShared.fitThinkingBudget(options.thinking.tokenBudget, request.generation?.maxTokens),
},
max_tokens: request.generation?.maxTokens,
temperature: request.generation?.temperature,
p: request.generation?.topP,
k: request.generation?.topK,
seed: request.generation?.seed,
stop_sequences: request.generation?.stop,
frequency_penalty: request.generation?.frequencyPenalty,
presence_penalty: request.generation?.presencePenalty,
}
})
const finishReason = (raw: string): FinishReasonDetails => {
switch (raw) {
case "COMPLETE":
case "STOP_SEQUENCE":
return { normalized: "stop", raw }
case "MAX_TOKENS":
return { normalized: "length", raw }
case "TOOL_CALL":
return { normalized: "tool-calls", raw }
case "ERROR":
case "TIMEOUT":
return { normalized: "error", raw }
default:
return { normalized: "unknown", raw }
}
}
const mapUsage = (usage: typeof NativeUsage.Type) =>
new Usage({
inputTokens: usage.tokens?.input_tokens,
outputTokens: usage.tokens?.output_tokens,
nonCachedInputTokens: ProviderShared.subtractTokens(usage.tokens?.input_tokens, usage.cached_tokens),
cacheReadInputTokens: usage.cached_tokens,
reasoningTokens: usage.tokens?.reasoning_tokens,
totalTokens: ProviderShared.totalTokens(usage.tokens?.input_tokens, usage.tokens?.output_tokens, undefined),
providerMetadata: { cohere: usage },
})
// Lifecycle deltas open blocks on demand and ends are no-ops for closed blocks, so content-start needs no handling.
const step = Effect.fn("CohereChat.step")(function* (state: State, event: Event) {
const events: LLMEvent[] = []
switch (event.type) {
case "message-start":
return [{ ...state, lifecycle: Lifecycle.stepStart(state.lifecycle, events) }, events] as const
case "content-delta": {
const id = String(event.index)
const content = event.delta.message.content
const lifecycle =
content.thinking !== undefined
? Lifecycle.reasoningDelta(state.lifecycle, events, id, content.thinking)
: Lifecycle.textDelta(state.lifecycle, events, id, content.text ?? "")
return [{ ...state, lifecycle }, events] as const
}
case "content-end": {
const id = String(event.index)
const lifecycle = Lifecycle.textEnd(Lifecycle.reasoningEnd(state.lifecycle, events, id), events, id)
return [{ ...state, lifecycle }, events] as const
}
case "tool-plan-delta": {
const plan = event.delta.message.tool_plan
const lifecycle = Lifecycle.reasoningDelta(state.lifecycle, events, "tool-plan", plan, {
cohere: { toolPlan: true },
})
return [{ ...state, lifecycle }, events] as const
}
case "tool-call-start":
case "tool-call-delta": {
const call = event.delta.message.tool_calls
const result = ToolStream.appendOrStart(
ADAPTER,
state.tools,
event.index,
{ id: call.id, name: call.function.name, text: call.function.arguments ?? "" },
"Cohere tool call is missing id or name",
)
if (ToolStream.isError(result)) return yield* result
return [{ ...state, tools: result.tools }, result.events] as const
}
case "tool-call-end": {
const result = yield* ToolStream.finish(ADAPTER, state.tools, event.index)
return [{ ...state, tools: result.tools }, result.events ?? []] as const
}
case "message-end": {
const pending = yield* ToolStream.finishAll(ADAPTER, state.tools)
events.push(...pending.events)
const lifecycle = Lifecycle.finish(state.lifecycle, events, {
reason: finishReason(event.delta.finish_reason),
usage: event.delta.usage && mapUsage(event.delta.usage),
})
return [{ tools: pending.tools, lifecycle, finished: true }, events] as const
}
default:
return [state, events] as const
}
})
export const protocol = Protocol.make({
id: ADAPTER,
body: { schema: Body, from: fromRequest },
stream: {
event: Protocol.jsonEvent(Event),
initial: (): State => ({ lifecycle: Lifecycle.initial(), tools: ToolStream.empty(), finished: false }),
step,
terminal: (event) => event.type === "message-end",
onHalt: (state) =>
state.finished
? Effect.succeed([])
: Effect.fail(ProviderShared.eventError(ADAPTER, "Cohere stream ended without message-end")),
},
})
export const route = Route.make({
id: ADAPTER,
provider: "cohere",
providerMetadataKey: "cohere",
protocol,
endpoint: Endpoint.path("/chat", { baseURL: DEFAULT_BASE_URL }),
framing: Framing.sse,
})
export * as CohereChat from "./cohere-chat.js"
@@ -1,5 +1,5 @@
import { Effect, Schema } from "effect"
import type { HttpClientResponse } from "effect/unstable/http"
import type { HttpClientResponse } from "effect/http"
import { MediaProtocol } from "../route/media-protocol.js"
import { MediaRoute } from "../route/media.js"
import { mergeJsonRecords, type OpenString } from "../schema/index.js"
@@ -1,5 +1,5 @@
import { Effect, Schema } from "effect"
import type { HttpClientResponse } from "effect/unstable/http"
import type { HttpClientResponse } from "effect/http"
import { MediaProtocol } from "../route/media-protocol.js"
import { MediaRoute } from "../route/media.js"
import { mergeJsonRecords, type OpenString } from "../schema/index.js"
+1 -1
View File
@@ -1,5 +1,5 @@
import { Effect, Schema } from "effect"
import type { HttpClientResponse } from "effect/unstable/http"
import type { HttpClientResponse } from "effect/http"
import { ImageModel, ImageResponse, type ImageRequestFor } from "../image.js"
import { Media } from "../media.js"
import { MediaProtocol } from "../route/media-protocol.js"
+1 -1
View File
@@ -1,5 +1,5 @@
import { Effect, Schema } from "effect"
import type { HttpClientResponse } from "effect/unstable/http"
import type { HttpClientResponse } from "effect/http"
import { Media } from "../media.js"
import { MediaProtocol } from "../route/media-protocol.js"
import { MediaRoute } from "../route/media.js"
+1 -1
View File
@@ -475,7 +475,7 @@ const fromRequest = Effect.fn("Gemini.fromRequest")(function* (request: LLMReque
safetySettings: options.safetySettings,
serviceTier: options.serviceTier,
systemInstruction:
request.system.length === 0 ? undefined : { parts: request.system.map((part) => ({ text: part.text })) },
request.system.length === 0 ? undefined : { parts: [{ text: ProviderShared.joinText(request.system) }] },
tools: hasTools
? [
{
+1 -1
View File
@@ -1,5 +1,5 @@
import { Effect, Schema } from "effect"
import type { HttpClientResponse } from "effect/unstable/http"
import type { HttpClientResponse } from "effect/http"
import { ImageModel, ImageResponse, type ImageRequestFor } from "../image.js"
import { MediaProtocol } from "../route/media-protocol.js"
import { MediaRoute } from "../route/media.js"
@@ -1,561 +0,0 @@
import { Effect, Schema } from "effect"
import { Route } from "../route/client.js"
import { Auth } from "../route/auth.js"
import { Endpoint } from "../route/endpoint.js"
import { Framing } from "../route/framing.js"
import { Protocol } from "../route/protocol.js"
import {
AIError,
LLMEvent,
ProviderID,
Usage,
type LLMRequest,
type ProviderMetadata,
type ToolResultPart,
} from "../schema/index.js"
import { Media } from "../media.js"
import { classifyProviderFailure, providerErrorMessage } from "../provider-error.js"
import { encodeJson } from "../utils/json.js"
import { JsonObject, knownString, lenient, optionalNull, ProviderShared } from "./shared.js"
import { Lifecycle } from "./utils/lifecycle.js"
import { MediaInput } from "./utils/media-input.js"
import { ToolStream } from "./utils/tool-stream.js"
const ADAPTER = "google-interactions"
export const DEFAULT_BASE_URL = "https://generativelanguage.googleapis.com/v1beta"
// =============================================================================
// Public Model Input
// =============================================================================
const ThinkingLevel = knownString<"minimal" | "low" | "medium" | "high">()
const Options = Schema.Struct({
previousInteractionId: lenient(Schema.String),
store: lenient(Schema.Boolean),
thinkingLevel: lenient(ThinkingLevel),
thinkingSummaries: lenient(knownString<"auto" | "none">()),
serviceTier: lenient(knownString<"standard" | "flex" | "priority">()),
})
export type OptionsInput = typeof Options.Encoded
export type ProviderOptionsInput = OptionsInput
const decodeOptions = ProviderShared.validateWith(Schema.decodeUnknownEffect(Options))
// =============================================================================
// Request Body Schema
// =============================================================================
const Text = Schema.Struct({ type: Schema.Literal("text"), text: Schema.String })
const MediaContent = Schema.Struct({
type: Schema.Literals(["image", "audio", "video", "document"]),
data: Schema.optional(Schema.String),
uri: Schema.optional(Schema.String),
mime_type: Schema.String,
})
const Content = Schema.Union([Text, MediaContent])
const InputStep = Schema.Union([
Schema.Struct({ type: Schema.Literals(["user_input", "model_output"]), content: Schema.Array(Content) }),
Schema.Struct({
type: Schema.Literal("thought"),
signature: Schema.optional(Schema.String),
summary: Schema.optional(Schema.Array(Text)),
}),
Schema.Struct({
type: Schema.Literal("function_call"),
id: Schema.String,
name: Schema.String,
arguments: Schema.Unknown,
signature: Schema.optional(Schema.String),
}),
Schema.Struct({
type: Schema.Literal("function_result"),
call_id: Schema.String,
name: Schema.String,
result: Schema.Unknown,
is_error: Schema.optional(Schema.Boolean),
}),
])
type InputStep = typeof InputStep.Type
const ToolChoice = Schema.Union([
Schema.Literals(["auto", "any", "none"]),
Schema.Struct({ allowed_tools: Schema.Struct({ mode: Schema.Literal("any"), tools: Schema.Array(Schema.String) }) }),
])
const Body = Schema.Struct({
model: Schema.String,
input: Schema.Array(InputStep),
stream: Schema.Literal(true),
store: Schema.Boolean,
previous_interaction_id: Schema.optional(Schema.String),
system_instruction: Schema.optional(Schema.String),
service_tier: Schema.optional(Schema.String),
tools: Schema.optional(
Schema.Array(
Schema.Struct({
type: Schema.Literal("function"),
name: Schema.String,
description: Schema.String,
parameters: JsonObject,
}),
),
),
generation_config: Schema.Struct({
max_output_tokens: Schema.optional(Schema.Number),
temperature: Schema.optional(Schema.Number),
top_p: Schema.optional(Schema.Number),
seed: Schema.optional(Schema.Number),
stop_sequences: Schema.optional(Schema.Array(Schema.String)),
thinking_level: Schema.optional(ThinkingLevel),
thinking_summaries: Schema.optional(Schema.String),
tool_choice: Schema.optional(ToolChoice),
}),
})
// =============================================================================
// Streaming Event Schema
// =============================================================================
const RawUsage = Schema.StructWithRest(
Schema.Struct({
total_input_tokens: optionalNull(Schema.Number),
total_cached_tokens: optionalNull(Schema.Number),
total_output_tokens: optionalNull(Schema.Number),
total_thought_tokens: optionalNull(Schema.Number),
total_tokens: optionalNull(Schema.Number),
raw_prompt_token: optionalNull(Schema.Number),
}),
[Schema.Record(Schema.String, Schema.Unknown)],
)
type RawUsage = typeof RawUsage.Type
const OutputStep = Schema.Struct({
type: Schema.String,
id: Schema.optional(Schema.String),
name: Schema.optional(Schema.String),
arguments: Schema.optional(JsonObject),
signature: Schema.optional(Schema.String),
summary: Schema.optional(Schema.Array(Text)),
content: Schema.optional(Schema.Array(Schema.Struct({ type: Schema.String, text: Schema.optional(Schema.String) }))),
})
type OutputStep = typeof OutputStep.Type
const Delta = Schema.Union([
Schema.Struct({ type: Schema.Literal("text"), text: Schema.String }),
Schema.Struct({ type: Schema.Literal("arguments_delta"), arguments: Schema.String }),
Schema.Struct({ type: Schema.Literal("thought_signature"), signature: Schema.String }),
Schema.Struct({ type: Schema.Literal("thought_summary"), content: Text }),
// Unknown output modalities must fail explicitly rather than disappearing from a successful response.
Schema.Struct({ type: Schema.String }),
])
const Interaction = Schema.StructWithRest(
Schema.Struct({
id: Schema.optional(Schema.String),
status: Schema.String,
usage: Schema.optional(RawUsage),
}),
[Schema.Record(Schema.String, Schema.Unknown)],
)
const Event = Schema.Union([
Schema.Struct({ event_type: Schema.Literal("step.start"), index: Schema.Number, step: OutputStep }),
Schema.Struct({ event_type: Schema.Literal("step.delta"), index: Schema.Number, delta: Delta }),
Schema.Struct({ event_type: Schema.Literal("step.stop"), index: Schema.Number }),
Schema.Struct({
event_type: Schema.Literal("interaction.created"),
interaction: Schema.Struct({ id: Schema.optional(Schema.String) }),
}),
Schema.Struct({
event_type: Schema.Literal("interaction.status_update"),
interaction_id: Schema.optional(Schema.String),
status: Schema.String,
}),
Schema.Struct({ event_type: Schema.Literal("interaction.completed"), interaction: Interaction }),
Schema.Struct({ event_type: Schema.Literal("error"), error: Schema.Unknown }),
])
type Event = typeof Event.Type
// =============================================================================
// Parser State
// =============================================================================
interface ParserState {
readonly route: string
readonly metadataKey: string
readonly lifecycle: Lifecycle.State
readonly steps: Partial<Record<number, OutputStep>>
readonly tools: ToolStream.State<number>
readonly completed: boolean
}
type StepResult = readonly [ParserState, ReadonlyArray<LLMEvent>]
// =============================================================================
// Request Body Construction
// =============================================================================
const mediaContent = Effect.fn("GoogleInteractions.mediaContent")(function* (asset: Media.Asset) {
if (
asset.kind !== "image" &&
asset.kind !== "audio" &&
asset.kind !== "video" &&
asset.mediaType !== "application/pdf" &&
asset.mediaType !== "text/csv"
)
return yield* ProviderShared.invalidRequest(
`Google Interactions does not support ${asset.mediaType} document input`,
)
const type: (typeof MediaContent.Type)["type"] =
asset.kind === "image" || asset.kind === "audio" || asset.kind === "video" ? asset.kind : "document"
const uri = MediaInput.refID(asset, ProviderID.make("google"))
if (uri !== undefined) return { type, uri, mime_type: asset.mediaType }
const inline = yield* ProviderShared.requireInlineMedia("Google Interactions", asset)
return { type, data: inline.base64, mime_type: inline.mime }
})
const signature = (metadata: ProviderMetadata | undefined, key: string) => {
const value = metadata?.[key]
return ProviderShared.isRecord(value) && typeof value.interactionSignature === "string"
? value.interactionSignature
: undefined
}
const lowerMessages = Effect.fn("GoogleInteractions.lowerMessages")(function* (request: LLMRequest) {
const steps: InputStep[] = []
const key = request.model.route.providerMetadataKey ?? String(request.model.provider)
for (const message of request.messages) {
if (message.role === "system") {
const part = yield* ProviderShared.wrappedSystemUpdate("Google Interactions", message)
steps.push({ type: "user_input", content: [{ type: "text", text: part.text }] })
continue
}
const start = steps.length
// Consecutive ordinary content remains one native message; tools and thoughts retain their chronology.
const append = (content: typeof Content.Type) => {
const type = message.role === "assistant" ? "model_output" : "user_input"
const last = steps.at(-1)
if (steps.length > start && last?.type === type)
steps[steps.length - 1] = { type, content: [...last.content, content] }
else steps.push({ type, content: [content] })
}
for (const part of message.content) {
if (message.role === "tool") {
if (part.type !== "tool-result")
return yield* ProviderShared.unsupportedContent(ADAPTER, "tool", ["tool-result"])
steps.push({
type: "function_result",
call_id: part.id,
name: part.name,
result: yield* lowerToolResult(part),
is_error: part.result.type === "error" || undefined,
})
continue
}
if (part.type === "text") {
append({ type: "text", text: part.text })
continue
}
if (part.type === "media") {
append(yield* mediaContent(part.media))
continue
}
if (message.role === "assistant" && part.type === "reasoning") {
steps.push({
type: "thought",
signature: signature(part.providerMetadata, key),
summary: part.text ? [{ type: "text", text: part.text }] : undefined,
})
continue
}
if (message.role === "assistant" && part.type === "tool-call") {
steps.push({
type: "function_call",
id: part.id,
name: part.name,
arguments: part.input,
signature: signature(part.providerMetadata, key),
})
continue
}
return yield* ProviderShared.unsupportedContent(
ADAPTER,
message.role,
message.role === "user" ? ["text", "media"] : ["text", "media", "reasoning", "tool-call"],
)
}
}
return steps
})
const lowerToolResult = Effect.fn("GoogleInteractions.lowerToolResult")(function* (part: ToolResultPart) {
if (part.result.type === "json" && ProviderShared.isRecord(part.result.value)) return part.result.value
if (part.result.type !== "content") return ProviderShared.toolResultText(part)
return yield* Effect.forEach(part.result.value, (item): Effect.Effect<typeof Content.Type, AIError> => {
if (item.type === "text") return Effect.succeed({ type: "text", text: item.text })
return mediaContent(ProviderShared.toolFileMedia(item).media)
})
})
const fromRequest = Effect.fn("GoogleInteractions.fromRequest")(function* (request: LLMRequest) {
const options = yield* decodeOptions(request.providerOptions ?? {})
const flattened = ProviderShared.flattenToolRequest(request)
if (flattened.tools.some((tool) => tool.native !== undefined))
return yield* ProviderShared.invalidRequest("Google Interactions hosted tools are not supported")
if (
request.generation?.topK !== undefined ||
request.generation?.frequencyPenalty !== undefined ||
request.generation?.presencePenalty !== undefined
)
return yield* ProviderShared.invalidRequest(
"Google Interactions does not support topK, frequencyPenalty, or presencePenalty",
)
const choice =
request.toolChoice === undefined
? undefined
: yield* ProviderShared.matchToolChoice(ADAPTER, request.toolChoice, {
auto: () => "auto" as const,
none: () => "none" as const,
required: () => "any" as const,
tool: (name) => ({ allowed_tools: { mode: "any" as const, tools: [name] } }),
})
return {
model: request.model.id,
input: yield* lowerMessages(flattened.request),
stream: true as const,
// Full-history replay need not create retained provider resources. Continuation callers opt in to storage.
store: options.store ?? false,
previous_interaction_id: options.previousInteractionId,
system_instruction: request.system.length ? ProviderShared.joinText(request.system) : undefined,
service_tier: options.serviceTier,
tools: flattened.tools.length
? flattened.tools.map((tool) => ({
type: "function" as const,
name: tool.name,
description: tool.description,
parameters: tool.inputSchema,
}))
: undefined,
generation_config: {
max_output_tokens: request.generation?.maxTokens,
temperature: request.generation?.temperature,
top_p: request.generation?.topP,
seed: request.generation?.seed,
stop_sequences: request.generation?.stop,
thinking_level: options.thinkingLevel,
thinking_summaries: options.thinkingSummaries,
tool_choice: choice,
},
}
})
// =============================================================================
// Stream Parsing
// =============================================================================
const metadata = (state: ParserState, step: OutputStep): ProviderMetadata => ({
[state.metadataKey]: { interactionSignature: step.signature },
})
const mapUsage = (usage: RawUsage | undefined, key: string) => {
if (!usage) return undefined
const input = usage.total_input_tokens ?? undefined
const cached = usage.total_cached_tokens ?? undefined
const reasoning = usage.total_thought_tokens ?? undefined
const output =
usage.total_output_tokens === undefined || usage.total_output_tokens === null
? undefined
: usage.total_output_tokens + (reasoning ?? 0)
return new Usage({
contextTokens: usage.raw_prompt_token ?? input,
inputTokens: input,
outputTokens: output,
nonCachedInputTokens: ProviderShared.subtractTokens(input, cached),
cacheReadInputTokens: cached,
reasoningTokens: reasoning,
totalTokens: usage.total_tokens ?? undefined,
providerMetadata: { [key]: usage },
})
}
const onStart = Effect.fn("GoogleInteractions.onStart")(function* (
state: ParserState,
index: number,
step: OutputStep,
) {
const events: LLMEvent[] = []
let lifecycle = Lifecycle.stepStart(state.lifecycle, events)
let tools = state.tools
const id = String(index)
if (step.type === "thought") {
lifecycle = Lifecycle.reasoningStart(lifecycle, events, id, metadata(state, step))
for (const part of step.summary ?? []) lifecycle = Lifecycle.reasoningDelta(lifecycle, events, id, part.text)
} else if (step.type === "model_output") {
lifecycle = Lifecycle.textStart(lifecycle, events, id)
for (const part of step.content ?? []) {
if (part.type !== "text")
return yield* ProviderShared.eventError(
ADAPTER,
`Unsupported Interactions output: ${part.type}`,
encodeJson(step),
)
if (part.text) lifecycle = Lifecycle.textDelta(lifecycle, events, id, part.text)
}
} else if (step.type === "function_call") {
if (!step.id || !step.name)
return yield* ProviderShared.eventError(ADAPTER, "Interactions function call lacks id or name", encodeJson(step))
tools = ToolStream.start(tools, index, {
id: step.id,
name: step.name,
providerMetadata: metadata(state, step),
input: step.arguments && Object.keys(step.arguments).length ? encodeJson(step.arguments) : "",
})
events.push(LLMEvent.toolInputStart({ id: step.id, name: step.name, providerMetadata: metadata(state, step) }))
} else
return yield* ProviderShared.eventError(ADAPTER, `Unsupported Interactions step: ${step.type}`, encodeJson(step))
return [{ ...state, lifecycle, tools, steps: { ...state.steps, [index]: step } }, events] satisfies StepResult
})
const onDelta = Effect.fn("GoogleInteractions.onDelta")(function* (
state: ParserState,
index: number,
delta: typeof Delta.Type,
) {
const step = state.steps[index]
if (!step)
return yield* ProviderShared.eventError(ADAPTER, "Interactions delta without step.start", encodeJson(delta))
const events: LLMEvent[] = []
if (delta.type === "text" && "text" in delta && step.type === "model_output")
return [
{ ...state, lifecycle: Lifecycle.textDelta(state.lifecycle, events, String(index), delta.text) },
events,
] satisfies StepResult
if (delta.type === "thought_summary" && "content" in delta && step.type === "thought")
return [
{ ...state, lifecycle: Lifecycle.reasoningDelta(state.lifecycle, events, String(index), delta.content.text) },
events,
] satisfies StepResult
if (delta.type === "thought_signature" && "signature" in delta) {
const next = { ...step, signature: delta.signature }
const tool = state.tools[index]
return [
{
...state,
steps: { ...state.steps, [index]: next },
tools: tool ? { ...state.tools, [index]: { ...tool, providerMetadata: metadata(state, next) } } : state.tools,
},
events,
] satisfies StepResult
}
if (delta.type === "arguments_delta" && "arguments" in delta && step.type === "function_call") {
const result = ToolStream.appendExisting(
ADAPTER,
state.tools,
index,
delta.arguments,
"Interactions arguments without function call",
)
if (ToolStream.isError(result)) return yield* result
return [{ ...state, tools: result.tools }, result.events] satisfies StepResult
}
return yield* ProviderShared.eventError(ADAPTER, `Unsupported Interactions delta: ${delta.type}`, encodeJson(delta))
})
const onStop = Effect.fn("GoogleInteractions.onStop")(function* (state: ParserState, index: number) {
const step = state.steps[index]
if (!step) return yield* ProviderShared.eventError(ADAPTER, "Interactions step.stop without step.start")
const events: LLMEvent[] = []
if (step.type === "thought")
return [
{ ...state, lifecycle: Lifecycle.reasoningEnd(state.lifecycle, events, String(index), metadata(state, step)) },
events,
] satisfies StepResult
if (step.type === "model_output")
return [
{ ...state, lifecycle: Lifecycle.textEnd(state.lifecycle, events, String(index)) },
events,
] satisfies StepResult
const result = yield* ToolStream.finish(ADAPTER, state.tools, index)
return [{ ...state, tools: result.tools }, result.events ?? []] satisfies StepResult
})
const step = Effect.fn("GoogleInteractions.step")(function* (state: ParserState, event: Event) {
switch (event.event_type) {
case "step.start":
return yield* onStart(state, event.index, event.step)
case "step.delta":
return yield* onDelta(state, event.index, event.delta)
case "step.stop":
return yield* onStop(state, event.index)
case "interaction.created":
case "interaction.status_update":
return [state, []] satisfies StepResult
case "error":
return yield* new AIError({
reason: classifyProviderFailure({
message: providerErrorMessage(encodeJson(event)) ?? "Google Interactions stream error",
data: event.error,
rawBody: encodeJson(event),
}),
})
case "interaction.completed": {
const interaction = event.interaction
if (interaction.status === "failed" || interaction.status === "cancelled")
return yield* new AIError({
reason: classifyProviderFailure({
message: `Google Interactions ${interaction.status}`,
data: interaction,
rawBody: encodeJson(event),
}),
})
if (!["completed", "requires_action", "incomplete"].includes(interaction.status))
return yield* ProviderShared.eventError(
ADAPTER,
`Unexpected terminal Interactions status: ${interaction.status}`,
encodeJson(event),
)
const pending = yield* ToolStream.finishAll(ADAPTER, state.tools)
const events = [...pending.events]
const lifecycle = Lifecycle.finish(state.lifecycle, events, {
reason: {
normalized:
interaction.status === "requires_action"
? "tool-calls"
: interaction.status === "incomplete"
? "length"
: "stop",
raw: interaction.status,
},
usage: mapUsage(interaction.usage, state.metadataKey),
providerMetadata: { [state.metadataKey]: { interactionId: interaction.id } },
})
return [{ ...state, lifecycle, tools: pending.tools, completed: true }, events] satisfies StepResult
}
}
})
// =============================================================================
// Protocol And Route
// =============================================================================
export const protocol = Protocol.make({
id: ADAPTER,
sanitizer: "gemini",
body: { schema: Body, from: fromRequest },
stream: {
event: Protocol.jsonEvent(Event),
initial: (request): ParserState => ({
route: `${request.model.provider}/${ADAPTER}`,
metadataKey: request.model.route.providerMetadataKey ?? String(request.model.provider),
lifecycle: Lifecycle.initial(),
steps: {},
tools: ToolStream.empty<number>(),
completed: false,
}),
step,
terminal: (event) => event.event_type === "interaction.completed",
onHalt: (state) =>
state.completed
? Effect.succeed([])
: Effect.fail(
ProviderShared.eventError(ADAPTER, "Google Interactions stream ended before interaction.completed"),
),
},
})
export const route = Route.make({
id: ADAPTER,
provider: "google",
providerMetadataKey: "google",
protocol,
endpoint: Endpoint.path("/interactions", { baseURL: DEFAULT_BASE_URL }),
auth: Auth.none,
framing: Framing.sse,
})
export * as GoogleInteractions from "./google-interactions.js"
+1 -1
View File
@@ -1,5 +1,5 @@
import { Duration, Effect, Schema } from "effect"
import type { HttpClientResponse } from "effect/unstable/http"
import type { HttpClientResponse } from "effect/http"
import type { Status } from "../generation.js"
import { Media } from "../media.js"
import { MediaProtocol } from "../route/media-protocol.js"
-2
View File
@@ -1,8 +1,6 @@
export * as AnthropicMessages from "./anthropic-messages.js"
export * as BedrockConverse from "./bedrock-converse.js"
export * as CohereChat from "./cohere-chat.js"
export * as Gemini from "./gemini.js"
export * as GoogleInteractions from "./google-interactions.js"
export * as MistralChat from "./mistral-chat.js"
export * as OpenAIChat from "./openai-chat.js"
export * as OpenAIImages from "./openai-images.js"
+1 -1
View File
@@ -1,5 +1,5 @@
import { Effect, Schema } from "effect"
import type { HttpClientResponse } from "effect/unstable/http"
import type { HttpClientResponse } from "effect/http"
import { ImageModel, ImageResponse, type ImageRequestFor } from "../image.js"
import { Media } from "../media.js"
import { MediaProtocol } from "../route/media-protocol.js"
+30 -7
View File
@@ -1,5 +1,7 @@
import { Effect, Encoding, Schema } from "effect"
import { Effect, Schema } from "effect"
import { Base64 } from "effect/encoding"
import { Protocol } from "../route/protocol.js"
import { HttpTransport } from "../route/transport/index.js"
import { LLMEvent, LLMRequest, Message, ToolResultPart } from "../schema/index.js"
import { OpenResponses } from "./open-responses.js"
import { JsonObject, optionalArray, optionalNull, ProviderShared } from "./shared.js"
@@ -43,6 +45,13 @@ const ImageItem = Schema.Struct({
error: Schema.optional(Schema.Unknown),
})
const Body = Schema.Struct({
...OpenResponses.coreFields,
input: Schema.Array(Schema.Union([OpenResponses.InputItem, ImageItem])),
tools: optionalArray(Schema.Union([OpenResponses.Tool, NativeTool])),
stream: Schema.Literal(true),
})
const MessageAnnotations = Schema.Struct({
content: Schema.Array(Schema.Struct({ annotations: optionalArray(JsonObject) })),
})
@@ -54,13 +63,12 @@ interface ParserState extends OpenResponses.ParserState {
const adapter = {
id: ADAPTER,
name: NAME,
nativeTool: (native) => ProviderShared.validateWith(Schema.decodeUnknownEffect(NativeTool))(native.meta),
restoreHostedToolItem: (item: unknown) => (Schema.is(ImageItem)(item) ? item : undefined),
} satisfies OpenResponses.ProviderAdapter
const fromRequest = Effect.fn("MetaResponses.fromRequest")(function* (request: LLMRequest) {
const key = request.model.route.providerMetadataKey ?? String(request.model.provider)
return yield* OpenResponses.fromRequestWithAdapter(
const projected = ProviderShared.flattenToolRequest(
LLMRequest.update(request, {
messages: request.messages.map((message) =>
Message.make({
@@ -86,8 +94,23 @@ const fromRequest = Effect.fn("MetaResponses.fromRequest")(function* (request: L
}),
),
}),
adapter,
)
return yield* ProviderShared.validateWith(Schema.decodeUnknownEffect(Body))({
...(yield* OpenResponses.lowerConversation(projected.request, adapter)),
...OpenResponses.lowerGeneration(request),
tools:
projected.tools.length === 0
? undefined
: yield* Effect.forEach(projected.tools, (tool) =>
Effect.gen(function* () {
if (tool.native === undefined) return yield* OpenResponses.lowerTool(NAME, tool)
return yield* ProviderShared.validateWith(Schema.decodeUnknownEffect(NativeTool))(tool.native.meta)
}),
),
tool_choice:
OpenResponses.allowedToolChoice(request) ??
(request.toolChoice ? yield* OpenResponses.lowerToolChoice(NAME, request.toolChoice) : undefined),
})
})
const HOSTED_TOOLS = {
@@ -113,7 +136,7 @@ const HOSTED_TOOLS = {
"Meta returned an image without data",
ProviderShared.encodeJson(raw),
)
const data = yield* Effect.fromResult(Encoding.decodeBase64(item.result)).pipe(
const data = yield* Effect.fromResult(Base64.decode(item.result)).pipe(
Effect.mapError((cause) =>
ProviderShared.eventError(
ADAPTER,
@@ -200,7 +223,7 @@ const step = Effect.fn("MetaResponses.step")(function* (state: ParserState, inpu
export const protocol = Protocol.make({
id: ADAPTER,
body: { schema: OpenResponses.OpenResponsesBody, from: fromRequest },
body: { schema: Body, from: fromRequest },
stream: {
event: OpenResponses.protocol.stream.event,
initial: (request): ParserState => ({ ...OpenResponses.initial(request, adapter), completedItems: new Set() }),
@@ -209,6 +232,6 @@ export const protocol = Protocol.make({
},
})
export const httpTransport = OpenResponses.httpTransport
export const httpTransport = HttpTransport.sseJson.with<Schema.Schema.Type<typeof Body>>()
export * as MetaResponses from "./meta-responses.js"
+2 -15
View File
@@ -68,10 +68,7 @@ const MistralAssistantToolCall = Schema.Struct({
type MistralAssistantToolCall = Schema.Schema.Type<typeof MistralAssistantToolCall>
const MistralMessage = Schema.Union([
Schema.Struct({
role: Schema.Literal("system"),
content: Schema.Union([Schema.String, Schema.Array(MistralTextContent)]),
}),
Schema.Struct({ role: Schema.Literal("system"), content: Schema.String }),
Schema.Struct({
role: Schema.Literal("user"),
content: Schema.Union([Schema.String, Schema.Array(MistralUserContent)]),
@@ -338,17 +335,7 @@ const lowerToolResults = Effect.fn("MistralChat.lowerToolResults")(function* (
const lowerMessages = Effect.fn("MistralChat.lowerMessages")(function* (request: LLMRequest) {
const normalizeID = MistralToolID.normalizer(request)
const messages: MistralMessage[] =
request.system.length === 0
? []
: [
{
role: "system",
content:
request.system.length === 1
? request.system[0].text
: request.system.map((part) => ({ type: "text", text: part.text })),
},
]
request.system.length === 0 ? [] : [{ role: "system", content: ProviderShared.joinText(request.system) }]
for (const message of request.messages) {
if (message.role === "system") {
const update = yield* ProviderShared.wrappedSystemUpdate("Mistral Chat", message)
@@ -1,5 +1,5 @@
import { Effect, Schema, Stream } from "effect"
import { Headers } from "effect/unstable/http"
import { Headers } from "effect/http"
import { Framing } from "../route/framing.js"
import type { HttpContext } from "../schema/index.js"
import {
+30 -29
View File
@@ -168,20 +168,10 @@ export const ConfigurationUpdate = Schema.Struct({
type: Schema.Literal("configuration_update"),
reasoning: Schema.Struct({ effort: OpenResponsesOptions.ReasoningEffort }),
})
export type ConfigurationUpdate = Schema.Schema.Type<typeof ConfigurationUpdate>
export const HostedToolReplay = Schema.StructWithRest(
Schema.Struct({
type: Schema.String,
id: Schema.String,
}),
[JsonObject],
)
export type HostedToolReplayItem = Schema.Schema.Type<typeof HostedToolReplay>
type ConfigurationUpdate = Schema.Schema.Type<typeof ConfigurationUpdate>
export const InputItem = Schema.Union([
CompactionItem,
ConfigurationUpdate,
Schema.Struct({ type: Schema.tag("message"), role: Schema.tag("system"), content: Schema.String }),
Schema.Struct({ type: Schema.tag("message"), role: Schema.tag("developer"), content: Schema.String }),
Schema.Struct({
@@ -214,9 +204,24 @@ export const InputItem = Schema.Union([
output: OpenResponsesFunctionCallOutput,
}),
HostedToolItem,
HostedToolReplay,
])
type OpenResponsesInputItem = Schema.Schema.Type<typeof InputItem>
export type HostedToolReplayItem = {
readonly type: string
readonly id: string
readonly [key: string]: unknown
}
type LoweredInputItem =
| OpenResponsesInputItem
| HostedToolReplayItem
| ConfigurationUpdate
| {
readonly type: "message"
readonly id?: string
readonly role: "assistant"
readonly content: ReadonlyArray<{ readonly type: "output_text"; readonly text: string }>
readonly phase?: MessagePhase | null
}
// Mutable counterpart of the schema reasoning item so `lowerMessages` can fold
// multiple streamed summary parts into the same item before flushing.
@@ -234,14 +239,6 @@ export const Tool = Schema.Struct({
strict: Schema.optional(Schema.Boolean),
})
export const HostedTool = Schema.StructWithRest(
Schema.Struct({
type: Schema.String,
}),
[JsonObject],
)
export type HostedTool = Schema.Schema.Type<typeof HostedTool>
export const ToolChoice = Schema.Union([
Schema.Literals(["auto", "none", "required"]),
Schema.Struct({ type: Schema.tag("function"), name: Schema.String }),
@@ -260,7 +257,7 @@ export const coreFields = {
model: Schema.String,
input: Schema.Array(InputItem),
instructions: Schema.optional(Schema.String),
tools: optionalArray(Schema.Union([Tool, HostedTool])),
tools: optionalArray(Tool),
tool_choice: Schema.optional(ToolChoice),
store: Schema.optional(Schema.Boolean),
metadata: Schema.optional(Schema.Record(Schema.String, Schema.String)),
@@ -295,7 +292,7 @@ export const coreFields = {
frequency_penalty: Schema.optional(Schema.Number),
}
export const OpenResponsesBody = Schema.Struct({
const OpenResponsesBody = Schema.Struct({
...coreFields,
stream: Schema.Literal(true),
})
@@ -400,7 +397,9 @@ export const decodeChannelEvent = (frame: string) =>
export interface ProviderAdapter {
readonly id: string
readonly name: string
readonly nativeTool?: (native: NonNullable<ToolDefinition["native"]>) => Effect.Effect<HostedTool, AIError>
readonly nativeTool?: (
native: NonNullable<ToolDefinition["native"]>,
) => Effect.Effect<{ readonly type: string }, AIError>
readonly lowerMedia?: (input: {
readonly part: MediaPart
readonly media: Media.Inline | undefined
@@ -456,10 +455,8 @@ export const lowerTool = Effect.fn("OpenResponses.lowerTool")(function* (protoco
})
export const lowerTools = (tools: ReadonlyArray<ToolDefinition>, adapter: ProviderAdapter) =>
Effect.forEach(
tools,
(tool): Effect.Effect<Schema.Schema.Type<typeof Tool> | HostedTool, AIError> =>
tool.native !== undefined && adapter.nativeTool ? adapter.nativeTool(tool.native) : lowerTool(adapter.name, tool),
Effect.forEach(tools, (tool) =>
tool.native !== undefined && adapter.nativeTool ? adapter.nativeTool(tool.native) : lowerTool(adapter.name, tool),
)
export const lowerToolChoice = (protocolName: string, toolChoice: NonNullable<LLMRequest["toolChoice"]>) =>
@@ -595,7 +592,7 @@ const lowerMessages = Effect.fn("OpenResponses.lowerMessages")(function* (
request: LLMRequest,
adapter: ProviderAdapter,
) {
const input: OpenResponsesInputItem[] = []
const input: LoweredInputItem[] = []
const providerMetadataKey = metadataKey(request.model)
for (const message of request.messages) {
@@ -830,7 +827,11 @@ export const fromRequestWithAdapter = Effect.fn("OpenResponses.fromRequestWithAd
}
})
export const fromRequest = (request: LLMRequest) => fromRequestWithAdapter(request, BASE_ADAPTER)
const decodeBody = ProviderShared.validateWith(Schema.decodeUnknownEffect(OpenResponsesBody))
export const fromRequest = Effect.fn("OpenResponses.fromRequest")(function* (request: LLMRequest) {
return yield* decodeBody(yield* fromRequestWithAdapter(request, BASE_ADAPTER))
})
// =============================================================================
// Stream Parsing
+7
View File
@@ -14,6 +14,7 @@ import {
ProviderInternalError,
UnknownProviderError,
Usage,
type FinishReason,
type FinishReasonDetails,
type CacheHint,
type LLMRequest,
@@ -45,6 +46,12 @@ const OpenAIChatCacheControl = Schema.Struct({
})
type OpenAIChatCacheControl = Schema.Schema.Type<typeof OpenAIChatCacheControl>
const OpenAIChatFunction = Schema.Struct({
name: Schema.String,
description: Schema.String,
parameters: JsonObject,
})
const OpenAIChatTool = Schema.Struct({
type: Schema.tag("function"),
function: Schema.Struct({
+16 -6
View File
@@ -1,5 +1,6 @@
import { Effect, Encoding, Schema } from "effect"
import { Headers } from "effect/unstable/http"
import { Effect, Schema } from "effect"
import { Base64 } from "effect/encoding"
import { Headers } from "effect/http"
import { Route } from "../route/client.js"
import { Auth } from "../route/auth.js"
import { Endpoint } from "../route/endpoint.js"
@@ -103,8 +104,15 @@ const OpenAIResponsesToolChoice = Schema.Union([
Schema.Struct({ type: Schema.tag("image_generation") }),
])
const OpenAIResponsesInputItem = Schema.Union([
OpenResponses.InputItem,
OpenAIResponsesHostedToolItem,
OpenResponses.ConfigurationUpdate,
])
const OpenAIResponsesCoreFields = {
...OpenResponses.coreFields,
input: Schema.Array(OpenAIResponsesInputItem),
tools: optionalArray(OpenAIResponsesTools),
tool_choice: Schema.optional(OpenAIResponsesToolChoice),
context_management: Schema.optional(
@@ -127,7 +135,7 @@ export type OpenAIResponsesBody = Schema.Schema.Type<typeof OpenAIResponsesBody>
export const CompactionTrigger = Schema.Struct({ type: Schema.Literal("compaction_trigger") })
const CheckpointBody = Schema.Struct({
...OpenAIResponsesBody.fields,
input: Schema.Array(Schema.Union([OpenResponses.InputItem, CompactionTrigger])),
input: Schema.Array(Schema.Union([OpenAIResponsesInputItem, CompactionTrigger])),
})
const adapter = {
@@ -195,13 +203,15 @@ const lowerToolChoice = (toolChoice: NonNullable<LLMRequest["toolChoice"]>, tool
: { type: "function" as const, name },
})
const decodeBody = ProviderShared.validateWith(Schema.decodeUnknownEffect(OpenAIResponsesBody))
const fromRequest = Effect.fn("OpenAIResponses.fromRequest")(function* (request: LLMRequest) {
const management = yield* ProviderShared.validateWith(
Schema.decodeUnknownEffect(Schema.UndefinedOr(ContextManagement)),
)(request.providerOptions?.contextManagement)
const options = OpenResponsesOptions.resolve(request)
const updates = resolveEffortUpdates(request, options.reasoningEffort)
return {
return yield* decodeBody({
...(yield* OpenResponses.lowerConversation(updates.request, adapter)),
...OpenResponses.lowerGeneration(request, { ...options, reasoningEffort: updates.effort }),
context_management: management?.map((edit) => ({ type: edit.type, compact_threshold: edit.compactThreshold })),
@@ -211,7 +221,7 @@ const fromRequest = Effect.fn("OpenAIResponses.fromRequest")(function* (request:
? undefined
: (OpenResponses.allowedToolChoice(request) ??
(request.toolChoice ? yield* lowerToolChoice(request.toolChoice, request.tools) : undefined)),
}
})
})
const checkpointBody = {
@@ -240,7 +250,7 @@ const checkpointBody = {
const hostedToolResult = Effect.fn("OpenAIResponses.hostedToolResult")(function* (item: ResponsesHostedTools.Item) {
const isError = item.error !== undefined && item.error !== null
if (item.type === "image_generation_call" && item.result) {
yield* Effect.fromResult(Encoding.decodeBase64(item.result)).pipe(
yield* Effect.fromResult(Base64.decode(item.result)).pipe(
Effect.mapError((cause) =>
ProviderShared.eventError(ADAPTER, "OpenAI Responses returned invalid image base64", undefined, cause),
),
@@ -1,5 +1,5 @@
import { Duration, Effect, Schema } from "effect"
import type { HttpClientResponse } from "effect/unstable/http"
import type { HttpClientResponse } from "effect/http"
import type { Status } from "../generation.js"
import { ImageModel, ImageResponse, type ImageRequestFor } from "../image.js"
import { Media } from "../media.js"
+1 -1
View File
@@ -1,5 +1,5 @@
import { Duration, Effect, Schema } from "effect"
import type { HttpClientResponse } from "effect/unstable/http"
import type { HttpClientResponse } from "effect/http"
import type { Status } from "../generation.js"
import { Media } from "../media.js"
import { MediaProtocol } from "../route/media-protocol.js"
+1 -1
View File
@@ -1,6 +1,6 @@
import { Tool } from "@opencode/schema/tool"
import { Effect, Option, Schema } from "effect"
import { Headers, HttpClientRequest } from "effect/unstable/http"
import { Headers, HttpClientRequest } from "effect/http"
import { Media } from "../media.js"
import {
InvalidProviderOutputError,
@@ -1,5 +1,5 @@
import { Effect, Schema } from "effect"
import type { HttpClientResponse } from "effect/unstable/http"
import type { HttpClientResponse } from "effect/http"
import { ImageModel, ImageResponse, type ImageRequestFor } from "../image.js"
import { MediaProtocol } from "../route/media-protocol.js"
import { MediaRoute } from "../route/media.js"
@@ -1,6 +1,6 @@
import { AwsV4Signer } from "aws4fetch"
import { Effect } from "effect"
import { Headers } from "effect/unstable/http"
import { Headers } from "effect/http"
import { Auth, type AuthInput } from "../../route/auth.js"
import { AIError, AuthenticationError } from "../../schema/index.js"
import { ProviderShared } from "../shared.js"
@@ -1,4 +1,5 @@
import { Effect, Encoding, Schema } from "effect"
import { Effect, Schema } from "effect"
import { Base64 } from "effect/encoding"
import type { MediaPart } from "../../schema/index.js"
import { ProviderShared } from "../shared.js"
@@ -78,12 +79,12 @@ function documentName(filename: string | undefined, names: Set<string>) {
const mediaBase64 = Effect.fn("BedrockMedia.mediaBase64")(function* (part: MediaPart) {
const media = yield* ProviderShared.requireInlineMedia("Bedrock Converse", part.media)
const bytes = yield* Effect.fromResult(Encoding.decodeBase64(media.base64)).pipe(
const bytes = yield* Effect.fromResult(Base64.decode(media.base64)).pipe(
Effect.mapError((cause) =>
ProviderShared.invalidRequest("Bedrock Converse media data must be valid base64", cause),
),
)
return Encoding.encodeBase64(bytes)
return Base64.encode(bytes)
})
// Route by MIME. Known image/document formats lower into a typed block; anything
+1 -1
View File
@@ -1,5 +1,5 @@
import { Effect, Schema } from "effect"
import type { HttpClientResponse } from "effect/unstable/http"
import type { HttpClientResponse } from "effect/http"
import type { Status } from "../../generation.js"
import type { Media } from "../../media.js"
import { MediaProtocol } from "../../route/media-protocol.js"
@@ -1,4 +1,5 @@
import { Effect, Encoding } from "effect"
import { Effect } from "effect"
import { Base64 } from "effect/encoding"
import { Media } from "../../media.js"
import type { MediaProtocol } from "../../route/media-protocol.js"
import { mergeJsonRecords, type AIError, type ProviderID } from "../../schema/index.js"
@@ -10,7 +11,7 @@ export const inlineBytes = (route: string, asset: Media.Asset): Effect.Effect<Ui
if (asset.source.type === "bytes") return Effect.succeed(asset.source.data)
const inline = asset.inline()
if (!inline) return Effect.fail(ProviderShared.inlineRequired(route, asset))
return Effect.fromResult(Encoding.decodeBase64(inline.base64)).pipe(
return Effect.fromResult(Base64.decode(inline.base64)).pipe(
Effect.mapError((cause) => ProviderShared.invalidRequest(`${route} media contains invalid base64 data`, cause)),
)
}
@@ -52,7 +53,7 @@ export const decodedAsset = (
mediaType: string | undefined,
options?: Media.AssetOptions,
) =>
Effect.fromResult(Encoding.decodeBase64(data)).pipe(
Effect.fromResult(Base64.decode(data)).pipe(
Effect.mapError((cause) => invalid(`${label} contains invalid base64 data`, cause)),
Effect.map((bytes) => Media.bytes(bytes, mediaType, options)),
)
@@ -63,6 +63,9 @@ const objectRoot = (schema: JsonSchema): JsonSchema => {
schema.anyOf.some((branch) => isRecord(branch) && branch.type === "object" && Object.keys(branch).length === 1)
)
return { type: "object", ...Object.fromEntries(Object.entries(schema).filter(([key]) => key !== "anyOf")) }
// Effect 4 represents an empty Struct as `not: { type: "null" }`; an object root already excludes null.
if (isRecord(schema.not) && schema.not.type === "null" && Object.keys(schema.not).length === 1)
return { type: "object", ...Object.fromEntries(Object.entries(schema).filter(([key]) => key !== "not")) }
return { type: "object", ...schema }
}
+1 -1
View File
@@ -1,5 +1,5 @@
import { Effect, Schema } from "effect"
import type { HttpClientResponse } from "effect/unstable/http"
import type { HttpClientResponse } from "effect/http"
import { ImageModel, ImageResponse, type ImageRequestFor } from "../image.js"
import { Media } from "../media.js"
import { MediaProtocol } from "../route/media-protocol.js"
+9 -2
View File
@@ -31,12 +31,19 @@ const XAIResponsesHostedToolItem = Schema.Union([
),
])
const XAIResponsesBody = Schema.Struct({
...OpenResponses.coreFields,
input: Schema.Array(Schema.Union([OpenResponses.InputItem, XAIResponsesHostedToolItem])),
stream: Schema.Literal(true),
})
const adapter = {
id: ADAPTER,
name: NAME,
restoreHostedToolItem: (item: unknown) => (Schema.is(XAIResponsesHostedToolItem)(item) ? item : undefined),
} satisfies OpenResponses.ProviderAdapter
const decodeBody = ProviderShared.validateWith(Schema.decodeUnknownEffect(XAIResponsesBody))
const fromRequest = Effect.fn("XAIResponses.fromRequest")(function* (request: LLMRequest) {
if (request.providerOptions?.contextManagement !== undefined)
return yield* ProviderShared.unsupportedOperation({
@@ -46,7 +53,7 @@ const fromRequest = Effect.fn("XAIResponses.fromRequest")(function* (request: LL
message:
"xAI requires explicit compaction through LLMClient.compact; automatic context management is not supported",
})
return yield* OpenResponses.fromRequestWithAdapter(request, adapter)
return yield* decodeBody(yield* OpenResponses.fromRequestWithAdapter(request, adapter))
})
const HOSTED_TOOLS = {
@@ -76,7 +83,7 @@ const step = (state: OpenResponses.ParserState, input: OpenResponses.Event) => {
export const protocol = Protocol.make({
id: ADAPTER,
body: {
schema: OpenResponses.OpenResponsesBody,
schema: XAIResponsesBody,
from: fromRequest,
},
stream: {
+1 -1
View File
@@ -1,5 +1,5 @@
import { Effect, Schema } from "effect"
import type { HttpClientResponse } from "effect/unstable/http"
import type { HttpClientResponse } from "effect/http"
import type { Status } from "../generation.js"
import { Media } from "../media.js"
import { MediaProtocol } from "../route/media-protocol.js"
+1 -1
View File
@@ -1,5 +1,5 @@
import { Duration, Effect, Schema } from "effect"
import type { HttpClientResponse } from "effect/unstable/http"
import type { HttpClientResponse } from "effect/http"
import { ImageModel, ImageResponse, type ImageRequestFor } from "../image.js"
import { MediaProtocol } from "../route/media-protocol.js"
import { MediaRoute } from "../route/media.js"
+1 -7
View File
@@ -55,13 +55,7 @@ const patterns = [
const payloadPatterns = [/request entity too large/i, /payload too large/i, /request too large/i]
const exclusions = [
/^(throttling error|service unavailable):/i,
/rate limit/i,
/too many requests/i,
// Cohere reports an output limit above the model maximum as "too many tokens"; compaction cannot fix it.
/max[_ ]tokens must be less than/i,
]
const exclusions = [/^(throttling error|service unavailable):/i, /rate limit/i, /too many requests/i]
export const isContextOverflow = (message: string) =>
!exclusions.some((pattern) => pattern.test(message)) &&
-66
View File
@@ -1,66 +0,0 @@
import { CohereChat } from "../protocols/cohere-chat.js"
import { OpenAIChat } from "../protocols/openai-chat.js"
import { Route, type RouteDefaultsInput } from "../route/client.js"
import { Endpoint } from "../route/endpoint.js"
import { AuthOptions, type ProviderAuthOption } from "../route/auth-options.js"
import { ProviderID, type ModelID, type OpenString } from "../schema/index.js"
import type { ProviderPackage } from "../provider-package.js"
export const id = ProviderID.make("cohere")
const COMPATIBILITY_BASE_URL = "https://api.cohere.ai/compatibility/v1"
export type ChatOptionsInput = { readonly reasoningEffort?: OpenString<"none" | "high"> }
export type ProviderOptions = CohereChat.ProviderOptionsInput & ChatOptionsInput
export type LanguageModelOptions = Omit<RouteDefaultsInput, "providerOptions"> &
ProviderAuthOption<"optional"> & {
readonly baseURL?: string
readonly providerOptions?: ProviderOptions
}
export type Settings<Options = CohereChat.ProviderOptionsInput> = ProviderPackage.Settings &
Options & { readonly apiKey?: string; readonly baseURL?: string }
export const route = CohereChat.route
export const chatRoute = Route.make({
id: "cohere-chat-completions",
provider: id,
providerMetadataKey: "cohere",
protocol: OpenAIChat.protocol,
endpoint: Endpoint.path("/chat/completions", { baseURL: COMPATIBILITY_BASE_URL }),
framing: OpenAIChat.framing,
})
export const routes = [route, chatRoute]
export const configure = (input: LanguageModelOptions = {}) => {
const { apiKey: _apiKey, auth: _auth, baseURL, ...defaults } = input
const auth = AuthOptions.bearer(input, "COHERE_API_KEY")
const native = route.with({ ...defaults, auth, endpoint: { baseURL: baseURL ?? CohereChat.DEFAULT_BASE_URL } })
const chat = chatRoute.with({ ...defaults, auth, endpoint: { baseURL: baseURL ?? COMPATIBILITY_BASE_URL } })
return {
id,
model: (modelID: string | ModelID) => native.model<CohereChat.ProviderOptionsInput>({ id: modelID }),
chat: (modelID: string | ModelID) =>
chat.model<ChatOptionsInput>({
id: modelID,
compatibility: {
maxTokensField: "max_tokens",
supportsStore: false,
supportsUsageInStreaming: true,
reasoningField: "reasoning_content",
supportsStrictMode: false,
},
}),
configure,
}
}
export const provider = configure()
export const model: ProviderPackage.Definition<Settings, CohereChat.ProviderOptionsInput>["model"] = (
modelID,
{ apiKey, baseURL, body, headers, ...providerOptions },
) =>
configure({
apiKey,
baseURL,
headers,
http: body === undefined ? undefined : { body: { ...body } },
providerOptions,
}).model(modelID)
export * as Cohere from "./cohere.js"
-16
View File
@@ -1,16 +0,0 @@
import type { ProviderPackage } from "../../provider-package.js"
import { Cohere } from "../cohere.js"
export type Settings = Cohere.Settings<Cohere.ChatOptionsInput>
export const model: ProviderPackage.Definition<Settings, Cohere.ChatOptionsInput>["model"] = (
modelID,
{ apiKey, baseURL, body, headers, ...providerOptions },
) =>
Cohere.configure({
apiKey,
baseURL,
headers,
http: body === undefined ? undefined : { body: { ...body } },
providerOptions,
}).chat(modelID)
+2 -12
View File
@@ -5,7 +5,6 @@ import { MediaRoute } from "../route/media.js"
import type { ProviderPackage } from "../provider-package.js"
import { ProviderID, type ModelID } from "../schema/index.js"
import { Gemini } from "../protocols/gemini.js"
import { GoogleInteractions } from "../protocols/google-interactions.js"
import { GoogleImages } from "../protocols/google-images.js"
import { GoogleSpeech } from "../protocols/google-speech.js"
import { GoogleTranscription } from "../protocols/google-transcription.js"
@@ -17,16 +16,15 @@ export type { GoogleTranscriptionOptions } from "../protocols/google-transcripti
export type { GoogleVideoOptions } from "../protocols/google-video.js"
export type GeminiOptionsInput = Gemini.OptionsInput
export type GeminiProviderOptionsInput = Gemini.ProviderOptionsInput
export type GoogleInteractionsOptionsInput = GoogleInteractions.OptionsInput
export const id = ProviderID.make("google")
export const routes = [Gemini.route, GoogleInteractions.route]
export const routes = [Gemini.route]
export type Config = RouteDefaultsInput &
ProviderAuthOption<"optional"> & {
readonly baseURL?: string
readonly providerOptions?: Gemini.ProviderOptionsInput & GoogleInteractions.ProviderOptionsInput
readonly providerOptions?: Gemini.ProviderOptionsInput
}
export type Settings = ProviderPackage.Settings &
@@ -47,19 +45,12 @@ const configuredRoute = (input: Config) => {
return Gemini.route.with({ ...rest, endpoint: { baseURL }, auth: auth(input) })
}
const interactionsRoute = (input: Config) => {
const { apiKey: _, auth: _auth, baseURL, ...rest } = input
return GoogleInteractions.route.with({ ...rest, endpoint: { baseURL }, auth: auth(input) })
}
export const configure = (input: Config = {}) => {
const route = configuredRoute(input)
const media = MediaRoute.deployment(input, auth(input))
return {
id,
model: (modelID: string | ModelID) => route.model<Gemini.ProviderOptionsInput>({ id: modelID }),
interactions: (modelID: string | ModelID) =>
interactionsRoute(input).model<GoogleInteractions.ProviderOptionsInput>({ id: modelID }),
image: (modelID: string | ModelID) => GoogleImages.model({ ...media, id: modelID }),
video: (modelID: string | ModelID) => GoogleVideo.model({ ...media, id: modelID }),
speech: (modelID: string | ModelID) => GoogleSpeech.model({ ...media, id: modelID }),
@@ -82,7 +73,6 @@ export const model: ProviderPackage.Definition<Settings, Gemini.ProviderOptionsI
}).model(modelID)
export const image = provider.image
export const interactions = provider.interactions
export const video = provider.video
export const speech = provider.speech
export const transcription = provider.transcription
@@ -1,21 +0,0 @@
import { configure } from "../google.js"
import type { ProviderPackage } from "../../provider-package.js"
import type { GoogleInteractions } from "../../protocols/google-interactions.js"
export type Settings = ProviderPackage.Settings &
GoogleInteractions.ProviderOptionsInput & {
readonly apiKey?: string
readonly baseURL?: string
}
export const model: ProviderPackage.Definition<Settings, GoogleInteractions.ProviderOptionsInput>["model"] = (
modelID,
{ apiKey, baseURL, body, headers, ...providerOptions },
) =>
configure({
apiKey,
baseURL,
headers: headers === undefined ? undefined : { ...headers },
http: body === undefined ? undefined : { body: { ...body } },
providerOptions,
}).interactions(modelID)
-1
View File
@@ -9,7 +9,6 @@ export * as Baseten from "./baseten.js"
export * as BlackForestLabs from "./black-forest-labs.js"
export * as Cartesia from "./cartesia.js"
export * as Cerebras from "./cerebras.js"
export * as Cohere from "./cohere.js"
export * as CloudflareAIGateway from "./cloudflare-ai-gateway.js"
export * as CloudflareWorkersAI from "./cloudflare-workers-ai.js"
export * as DeepInfra from "./deepinfra.js"
@@ -1,5 +1,5 @@
import { Effect, Schema } from "effect"
import { Headers, HttpClientRequest } from "effect/unstable/http"
import { Headers, HttpClientRequest } from "effect/http"
import {
EvaluationAnswer,
EvaluationInput,
+2 -2
View File
@@ -1,5 +1,5 @@
import { Config, Effect, Option, Redacted } from "effect"
import { Headers } from "effect/unstable/http"
import { Headers } from "effect/http"
import { AuthenticationError, AIError, type HttpOptions } from "../schema/index.js"
export class MissingCredentialError extends Error {
@@ -95,7 +95,7 @@ export const optional = (secret: Secret | undefined, source = "optional value")
export const config = (name: string) =>
credential(
Effect.gen(function* () {
const secret = yield* Config.option(Config.redacted(name))
const secret = yield* Config.option(Config.Redacted(name))
if (Option.isSome(secret) && Redacted.value(secret.value) !== "") return secret.value
return yield* Effect.fail(new MissingCredentialError(name, `${name} is not set`))
}),
+5 -2
View File
@@ -358,6 +358,7 @@ function makeFromTransport<Body, Prepared, Frame, Event, State>(
input: MakeTransportInput<Body, Prepared, Frame, Event, State>,
): Route<Body, Prepared> {
const protocol = input.protocol
const encodeBody = Schema.encodeSync(Schema.fromJsonString(protocol.body.schema))
const decodeEventEffect = Schema.decodeUnknownEffect(protocol.stream.event)
const decodeEvent = (route: string) => (frame: Frame) =>
decodeEventEffect(frame).pipe(
@@ -416,7 +417,7 @@ function makeFromTransport<Body, Prepared, Frame, Event, State>(
request,
endpoint: routeInput.endpoint,
auth: routeInput.auth ?? Auth.none,
encodeBody: ProviderShared.encodeJson,
encodeBody,
middleware: options?.http,
webSocket: options?.webSocket,
}),
@@ -575,7 +576,9 @@ const compile = Effect.fn("LLM.compile")(function* (request: LLMRequest, options
const resolved = prepareRequest(request)
const route = resolved.model.route
const body = yield* route.body.from(resolved)
const body = yield* route.body
.from(resolved)
.pipe(Effect.flatMap(ProviderShared.validateWith(Schema.decodeUnknownEffect(route.body.schema))))
const prepared = yield* route.prepareTransport(body, resolved, options)
return {
+1 -1
View File
@@ -1,5 +1,5 @@
import { Context, type Effect } from "effect"
import type { HttpClientRequest, HttpClientResponse } from "effect/unstable/http"
import type { HttpClientRequest, HttpClientResponse } from "effect/http"
import type { AIError } from "../schema/errors.js"
// The service tag lives in its own leaf module so `Media.Asset` (imported by the schema layer) can require the
+8 -18
View File
@@ -6,7 +6,7 @@ import {
HttpClientError,
HttpClientRequest,
HttpClientResponse,
} from "effect/unstable/http"
} from "effect/http"
import { HttpContext, HttpRateLimitDetails, AIError, TransportError } from "../schema/index.js"
import { classifyProviderFailure, providerErrorMessage } from "../provider-error.js"
import { Service, type HttpMiddleware, type Interface } from "./executor-service.js"
@@ -159,15 +159,6 @@ const nativeTransportFailure = (error: unknown) => {
return failure
}
// HTTP hooks re-wrap response bodies, so a read failure can arrive as an HttpClientError caused by
// another HttpClientError. The innermost cause carries the native failure.
const rootCause = (error: unknown): unknown =>
HttpClientError.isHttpClientError(error) && "cause" in error.reason && error.reason.cause !== undefined
? rootCause(error.reason.cause)
: error
const CONNECTION_LOST = "Connection lost while reading the response"
const httpError = (input: {
readonly error: unknown
readonly request: HttpClientRequest.HttpClientRequest
@@ -188,21 +179,20 @@ const httpError = (input: {
}),
})
const source = rootCause(input.error)
const source =
HttpClientError.isHttpClientError(input.error) && "cause" in input.error.reason
? (input.error.reason.cause ?? input.error)
: input.error
const native = nativeTransportFailure(source)
const code = native?.code
const detail =
code && native?.message && !native.message.includes(code) ? `${code}: ${native.message}` : native?.message
const message = detail ?? (input.error instanceof Error ? input.error.message : undefined)
const raw = native?.message ?? (input.error instanceof Error ? input.error.message : undefined)
const detail = raw
const message = code && detail && !detail.includes(code) ? `${code}: ${detail}` : detail
if (Cause.isTimeoutError(input.error) || Cause.isTimeoutError(source))
return transportError({ message: message ?? "HTTP transport timed out", code: code ?? "Timeout" })
if (!HttpClientError.isHttpClientError(input.error))
return transportError({ message: message ?? "HTTP transport failed", code })
// Effect reports every response body read failure as a DecodeError, but the raw byte stream decodes
// nothing: provider output parsing happens later and fails as InvalidProviderOutput.
if (input.operation === "read" && input.error.reason._tag === "DecodeError")
return transportError({ message: detail ? `${CONNECTION_LOST}: ${detail}` : CONNECTION_LOST, code })
if (input.error.reason._tag === "TransportError") {
return transportError({
message: message ?? input.error.reason.description ?? "HTTP transport failed",
+1 -1
View File
@@ -1,5 +1,5 @@
import { Effect, Stream } from "effect"
import { makeParser, type Event } from "effect/unstable/encoding/Sse"
import { makeParser, type Event } from "effect/encoding/Sse"
import { AIError, InvalidProviderOutputError } from "../schema/index.js"
/**
+1 -1
View File
@@ -1,5 +1,5 @@
import { Clock, Duration, Effect, Schema, type Stream } from "effect"
import { HttpClientResponse } from "effect/unstable/http"
import { HttpClientResponse } from "effect/http"
import type { Snapshot, Status } from "../generation.js"
import { Media } from "../media.js"
import type { AuthInput } from "./auth.js"
+1 -1
View File
@@ -1,5 +1,5 @@
import { Duration, Effect, Schedule, Schema, Stream } from "effect"
import { Headers, HttpClientRequest, type HttpClientResponse } from "effect/unstable/http"
import { Headers, HttpClientRequest, type HttpClientResponse } from "effect/http"
import { Auth, type AuthInput } from "./auth.js"
import { Endpoint } from "./endpoint.js"
import { RequestExecutorService, type Interface } from "./executor-service.js"
+7 -51
View File
@@ -1,19 +1,11 @@
import { Clock, Duration, Effect, Stream } from "effect"
import { Headers, HttpClientRequest } from "effect/unstable/http"
import { Effect } from "effect"
import { Headers, HttpClientRequest } from "effect/http"
import { Auth } from "../auth.js"
import { render as renderEndpoint } from "../endpoint.js"
import { Framing } from "../framing.js"
import type { HttpMiddleware, Transport, TransportPrepareInput } from "./index.js"
import * as ProviderShared from "../../protocols/shared.js"
import {
AIError,
DEFAULT_HTTP_TIMEOUT_MS,
mergeJsonRecords,
TransportError,
type HttpContext,
type HttpTimeout,
type LLMRequest,
} from "../../schema/index.js"
import { mergeJsonRecords, type LLMRequest } from "../../schema/index.js"
import { RequestExecutor } from "../executor.js"
export type JsonRequestInput<Body> = TransportPrepareInput<Body>
@@ -95,53 +87,17 @@ export const httpJson = <Body, Frame>(input: HttpJsonInput<Body, Frame>): HttpJs
middleware: prepareInput.middleware,
}
}),
execute: (prepared, request, runtime) =>
execute: (prepared, _request, runtime) =>
Effect.gen(function* () {
const timeout = (operation: "request" | "read", message: string, http?: HttpContext) =>
new AIError({
reason: new TransportError({
message,
transport: "http",
operation,
code: "Timeout",
url: prepared.request.url,
http,
}),
})
const started = yield* Clock.currentTimeMillis
// Unlike the header and chunk limits, the whole-request budget has no default.
const total = request.http?.timeout ? Duration.millis(request.http.timeout) : Duration.infinity
const response = yield* runtime.http.execute(prepared.request, prepared.middleware).pipe(
Effect.timeoutOrElse({
duration: Duration.min(timeoutDuration(request.http?.headerTimeout), total),
orElse: () => timeout("request", "Timed out waiting for response headers"),
}),
)
const http = RequestExecutor.responseHttp(response)
const remaining = Duration.subtract(total, Duration.millis((yield* Clock.currentTimeMillis) - started))
const response = yield* runtime.http.execute(prepared.request, prepared.middleware)
return {
frames: prepared.framing.frame(
RequestExecutor.responseStream(response).pipe(
Stream.timeoutOrElse({
duration: timeoutDuration(request.http?.chunkTimeout),
orElse: () => Stream.fail(timeout("read", "Timed out waiting for response data", http)),
}),
Stream.interruptWhen(
Effect.sleep(remaining).pipe(
Effect.andThen(Effect.fail(timeout("read", "Timed out waiting for the response to complete", http))),
),
),
),
),
http,
frames: prepared.framing.frame(RequestExecutor.responseStream(response)),
http: RequestExecutor.responseHttp(response),
body: prepared.framing.body,
}
}),
})
const timeoutDuration = (value: HttpTimeout | undefined) =>
value === false ? Duration.infinity : Duration.millis(value ?? DEFAULT_HTTP_TIMEOUT_MS)
export const sseJson = {
id: "http-json/sse",
with: <Body>() => httpJson<Body, string>({ framing: Framing.sse }),
@@ -1,5 +1,5 @@
import type { Effect, Scope, Stream } from "effect"
import type { Headers } from "effect/unstable/http"
import type { Headers } from "effect/http"
import type { AIError, HttpContext } from "../../schema/index.js"
export interface WebSocketChannelExecutor {
+2 -2
View File
@@ -1,6 +1,6 @@
import { Cause, Effect, Queue, Stream } from "effect"
import { Headers } from "effect/unstable/http"
import { Socket } from "effect/unstable/socket"
import { Headers } from "effect/http"
import { Socket } from "effect/socket"
import {
AIError,
AIErrorReason,
+2 -1
View File
@@ -1,4 +1,5 @@
import { Schema } from "effect"
import { extendSchema } from "@opencode/schema/schema"
import { LLM } from "@opencode/schema/llm"
import { ContentBlockID, ToolCallID } from "./ids.js"
import {
@@ -339,7 +340,7 @@ const toolCallID = (value: ToolCallID | string) => ToolCallID.make(value)
* Lets consumers write `events.filter(LLMEvent.is.toolCall)` instead of
* `events.filter(LLMEvent.guards["tool-call"])`.
*/
export const LLMEvent = Object.assign(llmEventTagged, {
export const LLMEvent = extendSchema(llmEventTagged, {
compaction: CompactionPart.make,
stepStart: StepStart.make,
textStart: (input: WithID<TextStart, ContentBlockID>) => TextStart.make({ ...input, id: contentBlockID(input.id) }),
+9 -8
View File
@@ -1,4 +1,5 @@
import { Schema } from "effect"
import { extendSchema } from "@opencode/schema/schema"
import { Tool } from "@opencode/schema/tool"
import {
CacheHint,
@@ -28,7 +29,7 @@ export type SystemPart = Schema.Schema.Type<typeof systemPartSchema>
const makeSystemPart = (text: string): SystemPart => ({ type: "text", text })
export const SystemPart = Object.assign(systemPartSchema, {
export const SystemPart = extendSchema(systemPartSchema, {
make: makeSystemPart,
content: (input?: string | SystemPart | ReadonlyArray<SystemPart>) => {
if (input === undefined) return []
@@ -76,7 +77,7 @@ const toolResultValueSchema = Schema.Union([
export type ToolResultValue = Schema.Schema.Type<typeof toolResultValueSchema>
const isToolResultValue = Schema.is(toolResultValueSchema)
export const ToolResultValue = Object.assign(toolResultValueSchema, {
export const ToolResultValue = extendSchema(toolResultValueSchema, {
is: isToolResultValue,
make: (value: unknown, type: ToolResultValue["type"] = "json"): ToolResultValue => {
if (isToolResultValue(value)) return value
@@ -90,7 +91,7 @@ export interface ToolOutput {
readonly content: ReadonlyArray<Tool.Content>
}
export const ToolOutput = Object.assign(
export const ToolOutput = extendSchema(
Schema.Struct({
structured: Schema.Unknown,
content: Schema.Array(Tool.Content),
@@ -127,7 +128,7 @@ const toolResultText = (value: unknown) => {
}
}
export const ToolCallPart = Object.assign(
export const ToolCallPart = extendSchema(
Schema.Struct({
type: Schema.Literal("tool-call"),
id: Schema.String,
@@ -145,7 +146,7 @@ export const ToolCallPart = Object.assign(
)
export type ToolCallPart = Schema.Schema.Type<typeof ToolCallPart>
export const ToolResultPart = Object.assign(
export const ToolResultPart = extendSchema(
Schema.Struct({
type: Schema.Literal("tool-result"),
id: Schema.String,
@@ -209,7 +210,7 @@ const compactionPartSchema = Schema.Struct({
)
.annotate({ identifier: "LLM.Content.Compaction" })
export type CompactionPart = typeof compactionPartSchema.Type
export const CompactionPart = Object.assign(compactionPartSchema, {
export const CompactionPart = extendSchema(compactionPartSchema, {
make: (input: Omit<CompactionPart, "type" | "encrypted" | "text"> & CompactionContent): CompactionPart =>
Schema.decodeUnknownSync(compactionPartSchema)({ type: "compaction", ...input }),
})
@@ -326,7 +327,7 @@ export type ToolNamespaceEntryInput = ToolNamespaceInput & { readonly type: "nam
export const ToolNamespace: Schema.Codec<ToolNamespace> & {
readonly make: (input: ToolNamespace | ToolNamespaceInput) => ToolNamespace
} = Object.assign(
} = extendSchema(
Schema.Struct({
type: Schema.Literal("namespace"),
name: Schema.String,
@@ -346,7 +347,7 @@ export type ToolEntry = ToolDefinition | ToolNamespace
export type ToolEntryInput = ToolDefinition.Input | ToolNamespaceEntryInput
export const ToolEntry: Schema.Codec<ToolEntry> & {
readonly make: (input: ToolEntryInput) => ToolEntry
} = Object.assign(
} = extendSchema(
Schema.Union([ToolDefinition, ToolNamespace]).pipe(
Schema.toTaggedUnion("type"),
Schema.annotate({ identifier: "LLM.ToolEntry" }),
+2 -19
View File
@@ -48,23 +48,10 @@ export const mergeProviderOptions = (
...items: ReadonlyArray<ProviderOptions | undefined>
): ProviderOptions | undefined => mergeJsonRecords(...items)
/** Milliseconds for an HTTP timeout, or `false` to disable it. */
export const HttpTimeout = Schema.Union([Schema.Number.check(Schema.isGreaterThan(0)), Schema.Literal(false)])
export type HttpTimeout = Schema.Schema.Type<typeof HttpTimeout>
/** Applied to `headerTimeout` and `chunkTimeout` when a request leaves them unset. */
export const DEFAULT_HTTP_TIMEOUT_MS = 300_000
export class HttpOptions extends Schema.Class<HttpOptions>("AI.HttpOptions")({
body: Schema.optional(JsonSchema),
headers: Schema.optional(Schema.Record(Schema.String, Schema.String)),
query: Schema.optional(Schema.Record(Schema.String, Schema.String)),
/** Time allowed for the whole request, from send until the response completes. Unbounded when unset. */
timeout: Schema.optional(HttpTimeout),
/** Time allowed for response headers to arrive. */
headerTimeout: Schema.optional(HttpTimeout),
/** Time allowed between streamed response chunks once headers have arrived. */
chunkTimeout: Schema.optional(HttpTimeout),
}) {}
export namespace HttpOptions {
@@ -83,12 +70,8 @@ export const mergeHttpOptions = (...items: ReadonlyArray<HttpOptions | undefined
const body = mergeJsonRecords(...items.map((item) => item?.body))
const headers = mergeStringRecords(...items.map((item) => item?.headers))
const query = mergeStringRecords(...items.map((item) => item?.query))
const timeout = items.findLast((item) => item?.timeout !== undefined)?.timeout
const headerTimeout = items.findLast((item) => item?.headerTimeout !== undefined)?.headerTimeout
const chunkTimeout = items.findLast((item) => item?.chunkTimeout !== undefined)?.chunkTimeout
if (!body && !headers && !query && timeout === undefined && headerTimeout === undefined && chunkTimeout === undefined)
return undefined
return new HttpOptions({ body, headers, query, timeout, headerTimeout, chunkTimeout })
if (!body && !headers && !query) return undefined
return new HttpOptions({ body, headers, query })
}
export class GenerationOptions extends Schema.Class<GenerationOptions>("LLM.GenerationOptions")({
+2 -1
View File
@@ -1,4 +1,5 @@
import { Effect, Schema, Stream } from "effect"
import { extendSchema } from "@opencode/schema/schema"
import { ProgressEvent, QueuedEvent } from "./generation.js"
import { Media } from "./media.js"
import { MediaModel, composeRoute, tryRequest } from "./media-model.js"
@@ -141,7 +142,7 @@ const speechEventTagged = Schema.Union([
SpeechTimestampsEvent,
SpeechFinishEvent,
]).pipe(Schema.toTaggedUnion("type"))
export const SpeechEvent = Object.assign(speechEventTagged, {
export const SpeechEvent = extendSchema(speechEventTagged, {
is: {
generationQueued: speechEventTagged.guards["generation-queued"],
generationProgress: speechEventTagged.guards["generation-progress"],
+2 -1
View File
@@ -231,7 +231,8 @@ export const toDefinitions = (tools: Tools): ReadonlyArray<ToolDefinitionClass>
)
const toJsonSchema = (schema: Schema.Top): JsonSchema.JsonSchema => {
const document = Schema.toJsonSchemaDocument(schema)
// Keep provider-facing tool schemas closed; Effect 4's default now emits additionalProperties: true.
const document = Schema.toJsonSchemaDocument(schema, { onExcessProperty: "error" })
if (Object.keys(document.definitions).length === 0) return document.schema
return { ...document.schema, $defs: document.definitions }
}
+2 -1
View File
@@ -1,4 +1,5 @@
import { Effect, Schema, Stream } from "effect"
import { extendSchema } from "@opencode/schema/schema"
import { Generation, ProgressEvent, QueuedEvent, type AwaitOptions } from "./generation.js"
import { Media } from "./media.js"
import { MediaModel, composeRoute, tryRequest } from "./media-model.js"
@@ -159,7 +160,7 @@ const transcriptionEventTagged = Schema.Union([
TranscriptionSegmentEvent,
TranscriptionFinishEvent,
]).pipe(Schema.toTaggedUnion("type"))
export const TranscriptionEvent = Object.assign(transcriptionEventTagged, {
export const TranscriptionEvent = extendSchema(transcriptionEventTagged, {
is: {
generationQueued: transcriptionEventTagged.guards["generation-queued"],
generationProgress: transcriptionEventTagged.guards["generation-progress"],
+2 -1
View File
@@ -1,4 +1,5 @@
import { Effect, Schema, Stream } from "effect"
import { extendSchema } from "@opencode/schema/schema"
import { Generation, ProgressEvent, QueuedEvent, type AwaitOptions } from "./generation.js"
import { Media } from "./media.js"
import { MediaModel, composeRoute, tryRequest } from "./media-model.js"
@@ -136,7 +137,7 @@ export const VideoFinishEvent = Schema.Struct({
const videoEventTagged = Schema.Union([QueuedEvent, ProgressEvent, VideoOutputEvent, VideoFinishEvent]).pipe(
Schema.toTaggedUnion("type"),
)
export const VideoEvent = Object.assign(videoEventTagged, {
export const VideoEvent = extendSchema(videoEventTagged, {
is: {
generationQueued: videoEventTagged.guards["generation-queued"],
generationProgress: videoEventTagged.guards["generation-progress"],
+2 -1
View File
@@ -14,6 +14,7 @@ import * as GoogleVertexChat from "../src/providers/google-vertex-chat.js"
import * as GoogleVertexMessages from "../src/providers/google-vertex-messages.js"
import * as GoogleVertexResponses from "../src/providers/google-vertex-responses.js"
import * as OpenAI from "../src/providers/openai.js"
import * as OpenAICompatible from "../src/providers/openai-compatible.js"
import * as OpenRouter from "../src/providers/openrouter.js"
import * as XAI from "../src/providers/xai.js"
@@ -29,7 +30,7 @@ type LanguageModel = {
declare const auth: Auth.Definition
declare const optionalAuthModel: LanguageModelFactory<BaseOptions, "optional", LanguageModel>
declare const requiredAuthModel: LanguageModelFactory<BaseOptions, "required", LanguageModel>
const configApiKey = Config.redacted("OPENAI_API_KEY")
const configApiKey = Config.Redacted("OPENAI_API_KEY")
OpenAIChat.route.model({ id: "gpt-4.1-mini" })
+1 -1
View File
@@ -1,6 +1,6 @@
import { describe, expect } from "bun:test"
import { ConfigProvider, Effect } from "effect"
import { Headers } from "effect/unstable/http"
import { Headers } from "effect/http"
import { LLM } from "../src/index.js"
import { Auth } from "../src/route/auth.js"
import * as OpenAIChat from "../src/protocols/openai-chat.js"
-53
View File
@@ -145,59 +145,6 @@ describe("applyCachePolicy", () => {
}),
)
it.effect("Alibaba chat caches the system and conversation tail without marking tools", () =>
Effect.gen(function* () {
const prepared = yield* compileRequest(
LLM.request({
model: Alibaba.configure({ region: "ap-southeast-1", apiKey: "test" }).chat("qwen3.8-max"),
system: "You are concise.",
tools: [{ name: "lookup", description: "Look up a value", inputSchema: { type: "object", properties: {} } }],
prompt: "hi",
}),
)
expect(prepared.body).toMatchObject({
tools: [{ type: "function", function: { name: "lookup" } }],
messages: [
{
role: "system",
content: [{ text: "You are concise.", cache_control: { type: "ephemeral" } }],
},
{ role: "user", content: [{ text: "hi", cache_control: { type: "ephemeral" } }] },
],
})
expect(prepared.body.tools?.[0]?.cache_control).toBeUndefined()
}),
)
it.effect("Alibaba chat omits automatic cache markers when cache is none", () =>
Effect.gen(function* () {
const prepared = yield* compileRequest(
LLM.request({
model: Alibaba.configure({ region: "ap-southeast-1", apiKey: "test" }).chat("qwen3.8-max"),
system: "You are concise.",
prompt: "hi",
cache: "none",
}),
)
expect(JSON.stringify(prepared.body)).not.toContain("cache_control")
}),
)
it.effect("Alibaba chat does not assume non-Qwen models support cache markers", () =>
Effect.gen(function* () {
const alibaba = Alibaba.configure({ region: "ap-southeast-1", apiKey: "test" })
for (const modelID of ["kimi-k3", "glm-5.2", "deepseek-v4-flash-0731", "MiniMax-M2.5"]) {
const prepared = yield* compileRequest(
LLM.request({ model: alibaba.chat(modelID), system: "You are concise.", prompt: "hi" }),
)
expect(JSON.stringify(prepared.body)).not.toContain("cache_control")
}
}),
)
it.effect("'auto' emits Anthropic cache markers on Anthropic-compatible routes", () =>
Effect.gen(function* () {
const prepared = yield* compileRequest(
+1 -1
View File
@@ -1,6 +1,6 @@
import { expect } from "bun:test"
import { Effect } from "effect"
import { FetchHttpClient } from "effect/unstable/http"
import { FetchHttpClient } from "effect/http"
import { LLM, LLMRequest, Message } from "../src/index.js"
import { LLMClient } from "../src/route/client.js"
import { OpenAI } from "../src/providers.js"
+1 -1
View File
@@ -1,6 +1,6 @@
import { describe, expect, test } from "bun:test"
import { Effect, Ref, Schema } from "effect"
import { HttpClientRequest, HttpClientResponse } from "effect/unstable/http"
import { HttpClientRequest, HttpClientResponse } from "effect/http"
import {
LLM,
LLMRequest,
+2 -1
View File
@@ -1,12 +1,13 @@
import { describe, expect, test } from "bun:test"
import { Effect } from "effect"
import { LLM, Message, ToolCallPart } from "../src/index.js"
import { LLM, LLMRequest, Message, ToolCallPart } from "../src/index.js"
import { Auth, LLMClient } from "../src/route.js"
import { compileRequest } from "../src/route/client.js"
import { AnthropicMessages } from "../src/protocols/anthropic-messages.js"
import { OpenAIResponses } from "../src/protocols/openai-responses.js"
import { Gemini } from "../src/protocols/gemini.js"
import { GoogleVertexMessages, OpenAI } from "../src/providers.js"
import { applyCachePolicy } from "../src/cache-policy.js"
import { applyEffortUpdates } from "../src/effort-updates.js"
import { it, testEffect } from "./lib/effect.js"
import { dynamicResponse } from "./lib/http.js"
+1 -1
View File
@@ -1,6 +1,6 @@
import { describe, expect } from "bun:test"
import { Effect, Layer } from "effect"
import { HttpClientRequest } from "effect/unstable/http"
import { HttpClientRequest } from "effect/http"
import { Evaluation, EvaluationClient } from "../src/experimental.js"
import { OpenCodeZen, OpenRouter, TypeSafeAI, VercelAIGateway } from "../src/providers.js"
import { it } from "./lib/effect.js"
+6 -64
View File
@@ -1,17 +1,11 @@
import { describe, expect } from "bun:test"
import { Deferred, Effect, Fiber, Layer, Ref, Stream } from "effect"
import { Headers, HttpClientError, HttpClientRequest, HttpClientResponse } from "effect/unstable/http"
import { LLM, AIError, HttpContext, InvalidProviderOutputError, TransportError, isRetryable } from "../src/index.js"
import {
LLMClient,
RequestExecutor,
WebSocketTransport,
type HttpMiddleware,
type WebSocketChannelExecutor,
} from "../src/route.js"
import { Headers, HttpClientError, HttpClientRequest } from "effect/http"
import { LLM, AIError, HttpContext, InvalidProviderOutputError, TransportError } from "../src/index.js"
import { LLMClient, RequestExecutor, WebSocketTransport, type WebSocketChannelExecutor } from "../src/route.js"
import { route } from "../src/protocols/openai-chat.js"
import { configure } from "../src/providers/openai.js"
import { dynamicResponse, fixedResponse, handlerLayer, systemError, truncatedStream } from "./lib/http.js"
import { dynamicResponse, fixedResponse, handlerLayer, systemError } from "./lib/http.js"
import { deltaChunk } from "./lib/openai-chunks.js"
import { sseEvents, sseRaw } from "./lib/sse.js"
import { it } from "./lib/effect.js"
@@ -24,8 +18,6 @@ const secretRequest = HttpClientRequest.post("https://provider.test/v1/chat?api_
HttpClientRequest.setHeaders(Headers.fromInput({ authorization: "Bearer header-secret-456" })),
)
const sseRequest = HttpClientRequest.post("https://provider.test/v1/messages")
const expectAIError = (error: unknown) => {
expect(error).toBeInstanceOf(AIError)
if (!(error instanceof AIError)) throw new Error("expected AIError")
@@ -101,9 +93,7 @@ describe("RequestExecutor", () => {
const error = yield* RequestExecutor.stream(executor, secretRequest).pipe(Stream.runDrain, Effect.flip)
expectAIError(error)
expect(error.message).toBe(
"Connection lost while reading the response: ECONNRESET: disconnected query-secret-123 header-secret-456",
)
expect(error.message).toBe("ECONNRESET: disconnected query-secret-123 header-secret-456")
expect(error.reason.http).toMatchObject({ status: 200, url: secretRequest.url })
expect(error.reason.cause).toMatchObject({ code: "ECONNRESET" })
expect(error.reason).toMatchObject({
@@ -133,7 +123,7 @@ describe("RequestExecutor", () => {
const error = yield* RequestExecutor.stream(executor, secretRequest).pipe(Stream.runDrain, Effect.flip)
expectAIError(error)
expect(error.message).toBe("Connection lost while reading the response: ECONNRESET: socket closed")
expect(error.message).toBe("ECONNRESET: socket closed")
expect(error.reason.cause).toBeInstanceOf(TypeError)
expect(error.reason).toMatchObject({
_tag: "Transport",
@@ -154,54 +144,6 @@ describe("RequestExecutor", () => {
),
)
it.effect("reports a connection lost mid-stream through middleware that re-wraps the body", () =>
Effect.gen(function* () {
const executor = yield* RequestExecutor.Service
const chunks: Array<Uint8Array> = []
// Session HTTP hooks hand plugins a web Response, so the body is re-wrapped around the original stream.
const rewrap: HttpMiddleware = (input, handler) =>
Effect.gen(function* () {
const response = yield* handler(input)
const body = yield* Stream.toReadableStreamEffect(response.stream)
return HttpClientResponse.fromWeb(
input,
new Response(body, { status: response.status, headers: response.headers }),
)
})
const error = yield* RequestExecutor.stream(executor, sseRequest, rewrap).pipe(
Stream.runForEach((chunk) => Effect.sync(() => chunks.push(chunk))),
Effect.flip,
)
expectAIError(error)
expect(new TextDecoder().decode(chunks[0])).toBe('data: {"type":"ping"}\n\n')
expect(error.message).toBe("Connection lost while reading the response: ECONNRESET: other side closed")
expect(error.reason.cause).toBeInstanceOf(TypeError)
expect(error.reason.http).toMatchObject({ status: 200 })
expect(error.reason).toMatchObject({ _tag: "Transport", operation: "read", code: "ECONNRESET" })
expect(isRetryable(error)).toBeTrue()
}).pipe(
Effect.provide(
truncatedStream(
['data: {"type":"ping"}\n\n'],
new TypeError("terminated", { cause: systemError("ECONNRESET", "other side closed") }),
),
),
),
)
it.effect("does not report a body read failure without a native cause as a decode error", () =>
Effect.gen(function* () {
const executor = yield* RequestExecutor.Service
const error = yield* RequestExecutor.stream(executor, sseRequest).pipe(Stream.runDrain, Effect.flip)
expectAIError(error)
expect(error.message).toBe("Connection lost while reading the response")
expect(error.reason).toMatchObject({ _tag: "Transport", operation: "read", code: undefined })
expect(isRetryable(error)).toBeTrue()
}).pipe(Effect.provide(truncatedStream(['data: {"type":"ping"}\n\n'], new DOMException("aborted", "AbortError")))),
)
it.effect("preserves middleware error messages", () =>
Effect.gen(function* () {
const executor = yield* RequestExecutor.Service
@@ -10,7 +10,7 @@
"usage"
],
"name": "alibaba-chat/qwen-3-7-plus-streams-thinking-disabled",
"recordedAt": "2026-10-02T01:23:37.836Z"
"recordedAt": "2026-09-08T03:10:42.782Z"
},
"interactions": [
{
@@ -21,14 +21,14 @@
"headers": {
"content-type": "application/json"
},
"body": "{\"model\":\"qwen3.7-plus\",\"messages\":[{\"role\":\"user\",\"content\":[{\"type\":\"text\",\"text\":\"What is 173 multiplied by 219? Reply with only the final integer.\",\"cache_control\":{\"type\":\"ephemeral\"}}]}],\"stream\":true,\"stream_options\":{\"include_usage\":true},\"max_completion_tokens\":4096,\"enable_thinking\":false}"
"body": "{\"model\":\"qwen3.7-plus\",\"messages\":[{\"role\":\"user\",\"content\":\"What is 173 multiplied by 219? Reply with only the final integer.\"}],\"stream\":true,\"stream_options\":{\"include_usage\":true},\"max_completion_tokens\":4096,\"enable_thinking\":false}"
},
"response": {
"status": 200,
"headers": {
"content-type": "text/event-stream;charset=utf-8"
},
"body": "data: {\"model\":\"qwen3.7-plus\",\"id\":\"chatcmpl-e96a3356-bec9-98ad-bdbe-af00a15ee965\",\"created\":1790904216,\"object\":\"chat.completion.chunk\",\"usage\":null,\"choices\":[{\"logprobs\":null,\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\"},\"finish_reason\":null}]}\n\ndata: {\"model\":\"qwen3.7-plus\",\"id\":\"chatcmpl-e96a3356-bec9-98ad-bdbe-af00a15ee965\",\"choices\":[{\"delta\":{\"content\":\"3\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904216,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.7-plus\",\"id\":\"chatcmpl-e96a3356-bec9-98ad-bdbe-af00a15ee965\",\"choices\":[{\"delta\":{\"content\":\"7887\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904216,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.7-plus\",\"id\":\"chatcmpl-e96a3356-bec9-98ad-bdbe-af00a15ee965\",\"choices\":[{\"delta\":{\"content\":\"\"},\"index\":0,\"finish_reason\":\"stop\",\"logprobs\":null}],\"created\":1790904216,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"choices\":[],\"created\":1790904216,\"id\":\"chatcmpl-e96a3356-bec9-98ad-bdbe-af00a15ee965\",\"model\":\"qwen3.7-plus\",\"object\":\"chat.completion.chunk\",\"usage\":{\"completion_tokens\":5,\"prompt_tokens\":32,\"prompt_tokens_details\":{\"cache_creation\":{\"ephemeral_5m_input_tokens\":0},\"cache_creation_input_tokens\":0,\"cache_type\":\"ephemeral\",\"cache_write_tokens\":0,\"cached_tokens\":0,\"text_tokens\":32},\"total_tokens\":37}}\n\ndata: [DONE]\n\n"
"body": "data: {\"model\":\"qwen3.7-plus\",\"id\":\"chatcmpl-047bcb67-b193-9a4f-9d77-ea0325be6d7c\",\"created\":1788837041,\"object\":\"chat.completion.chunk\",\"usage\":null,\"choices\":[{\"logprobs\":null,\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\"},\"finish_reason\":null}]}\n\ndata: {\"model\":\"qwen3.7-plus\",\"id\":\"chatcmpl-047bcb67-b193-9a4f-9d77-ea0325be6d7c\",\"choices\":[{\"delta\":{\"content\":\"3\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788837041,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.7-plus\",\"id\":\"chatcmpl-047bcb67-b193-9a4f-9d77-ea0325be6d7c\",\"choices\":[{\"delta\":{\"content\":\"7887\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788837041,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.7-plus\",\"id\":\"chatcmpl-047bcb67-b193-9a4f-9d77-ea0325be6d7c\",\"choices\":[{\"delta\":{\"content\":\"\"},\"index\":0,\"finish_reason\":\"stop\",\"logprobs\":null}],\"created\":1788837041,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"choices\":[],\"created\":1788837041,\"id\":\"chatcmpl-047bcb67-b193-9a4f-9d77-ea0325be6d7c\",\"model\":\"qwen3.7-plus\",\"object\":\"chat.completion.chunk\",\"usage\":{\"completion_tokens\":5,\"prompt_tokens\":32,\"prompt_tokens_details\":{\"cached_tokens\":0,\"text_tokens\":32},\"total_tokens\":37}}\n\ndata: [DONE]\n\n"
}
}
]
@@ -10,7 +10,7 @@
"usage"
],
"name": "alibaba-chat/qwen-3-7-plus-streams-thinking-enabled",
"recordedAt": "2026-10-02T01:23:43.998Z"
"recordedAt": "2026-09-08T03:10:54.099Z"
},
"interactions": [
{
@@ -21,14 +21,14 @@
"headers": {
"content-type": "application/json"
},
"body": "{\"model\":\"qwen3.7-plus\",\"messages\":[{\"role\":\"user\",\"content\":[{\"type\":\"text\",\"text\":\"What is 173 multiplied by 219? Reply with only the final integer.\",\"cache_control\":{\"type\":\"ephemeral\"}}]}],\"stream\":true,\"stream_options\":{\"include_usage\":true},\"max_completion_tokens\":4096,\"enable_thinking\":true,\"thinking_budget\":1024}"
"body": "{\"model\":\"qwen3.7-plus\",\"messages\":[{\"role\":\"user\",\"content\":\"What is 173 multiplied by 219? Reply with only the final integer.\"}],\"stream\":true,\"stream_options\":{\"include_usage\":true},\"max_completion_tokens\":4096,\"enable_thinking\":true,\"thinking_budget\":1024}"
},
"response": {
"status": 200,
"headers": {
"content-type": "text/event-stream;charset=utf-8"
},
"body": "data: {\"model\":\"qwen3.7-plus\",\"id\":\"chatcmpl-70ed9ebc-62fe-9ee8-a442-7a3881697fdf\",\"created\":1790904218,\"object\":\"chat.completion.chunk\",\"usage\":null,\"choices\":[{\"logprobs\":null,\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\",\"reasoning_content\":\"\"},\"finish_reason\":null}]}\n\ndata: {\"model\":\"qwen3.7-plus\",\"id\":\"chatcmpl-70ed9ebc-62fe-9ee8-a442-7a3881697fdf\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"Thinking\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904218,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.7-plus\",\"id\":\"chatcmpl-70ed9ebc-62fe-9ee8-a442-7a3881697fdf\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" Process:\\n\\n1\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904218,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.7-plus\",\"id\":\"chatcmpl-70ed9ebc-62fe-9ee8-a442-7a3881697fdf\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\". Identify\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904218,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.7-plus\",\"id\":\"chatcmpl-70ed9ebc-62fe-9ee8-a442-7a3881697fdf\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" the core\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904218,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.7-plus\",\"id\":\"chatcmpl-70ed9ebc-62fe-9ee8-a442-7a3881697fdf\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" question: Calculate \"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904218,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.7-plus\",\"id\":\"chatcmpl-70ed9ebc-62fe-9ee8-a442-7a3881697fdf\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"173 *\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904218,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.7-plus\",\"id\":\"chatcmpl-70ed9ebc-62fe-9ee8-a442-7a3881697fdf\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" 219\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904218,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.7-plus\",\"id\":\"chatcmpl-70ed9ebc-62fe-9ee8-a442-7a3881697fdf\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\".\\n2.\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904218,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.7-plus\",\"id\":\"chatcmpl-70ed9ebc-62fe-9ee8-a442-7a3881697fdf\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" Constraint: Reply\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904218,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.7-plus\",\"id\":\"chatcmpl-70ed9ebc-62fe-9ee8-a442-7a3881697fdf\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" with *\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904218,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.7-plus\",\"id\":\"chatcmpl-70ed9ebc-62fe-9ee8-a442-7a3881697fdf\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"only* the final\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904218,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.7-plus\",\"id\":\"chatcmpl-70ed9ebc-62fe-9ee8-a442-7a3881697fdf\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" integer.\\n3\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904218,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.7-plus\",\"id\":\"chatcmpl-70ed9ebc-62fe-9ee8-a442-7a3881697fdf\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\". Perform the\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904218,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.7-plus\",\"id\":\"chatcmpl-70ed9ebc-62fe-9ee8-a442-7a3881697fdf\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" multiplication:\\n\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904218,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.7-plus\",\"id\":\"chatcmpl-70ed9ebc-62fe-9ee8-a442-7a3881697fdf\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" * \"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904218,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.7-plus\",\"id\":\"chatcmpl-70ed9ebc-62fLine truncated
"body": "data: {\"model\":\"qwen3.7-plus\",\"id\":\"chatcmpl-ec928416-c99b-9f46-9805-cbb37bd7c499\",\"created\":1788837042,\"object\":\"chat.completion.chunk\",\"usage\":null,\"choices\":[{\"logprobs\":null,\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\",\"reasoning_content\":\"\"},\"finish_reason\":null}]}\n\ndata: {\"model\":\"qwen3.7-plus\",\"id\":\"chatcmpl-ec928416-c99b-9f46-9805-cbb37bd7c499\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"Thinking\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788837042,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.7-plus\",\"id\":\"chatcmpl-ec928416-c99b-9f46-9805-cbb37bd7c499\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" Process:\\n\\n1\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788837042,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.7-plus\",\"id\":\"chatcmpl-ec928416-c99b-9f46-9805-cbb37bd7c499\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\". **Ident\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788837042,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.7-plus\",\"id\":\"chatcmpl-ec928416-c99b-9f46-9805-cbb37bd7c499\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"ify the core question\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788837042,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.7-plus\",\"id\":\"chatcmpl-ec928416-c99b-9f46-9805-cbb37bd7c499\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\":** The user wants\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788837042,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.7-plus\",\"id\":\"chatcmpl-ec928416-c99b-9f46-9805-cbb37bd7c499\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" to know the product\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788837042,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.7-plus\",\"id\":\"chatcmpl-ec928416-c99b-9f46-9805-cbb37bd7c499\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" of \"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788837042,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.7-plus\",\"id\":\"chatcmpl-ec928416-c99b-9f46-9805-cbb37bd7c499\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"173 and\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788837042,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.7-plus\",\"id\":\"chatcmpl-ec928416-c99b-9f46-9805-cbb37bd7c499\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" 219\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788837042,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.7-plus\",\"id\":\"chatcmpl-ec928416-c99b-9f46-9805-cbb37bd7c499\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\".\\n2.\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788837042,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.7-plus\",\"id\":\"chatcmpl-ec928416-c99b-9f46-9805-cbb37bd7c499\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" **Identify\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788837042,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.7-plus\",\"id\":\"chatcmpl-ec928416-c99b-9f46-9805-cbb37bd7c499\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" the constraint:** The\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788837042,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.7-plus\",\"id\":\"chatcmpl-ec928416-c99b-9f46-9805-cbb37bd7c499\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" response must contain *\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788837042,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.7-plus\",\"id\":\"chatcmpl-ec928416-c99b-9f46-9805-cbb37bd7c499\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"only\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788837042,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.7-plus\",\"id\":\"chatcmpl-ec928416-c99b-9f46-9805-cbb37bd7c499\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"* the final integer\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788837042,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.7-plus\",\"id\":\"cLine truncated
}
}
]
@@ -1,15 +1,9 @@
{
"version": 1,
"metadata": {
"tags": [
"prefix:alibaba-chat",
"provider:alibaba",
"protocol:alibaba-chat",
"region:ap-southeast-1",
"image"
],
"tags": ["prefix:alibaba-chat", "provider:alibaba", "protocol:alibaba-chat", "region:ap-southeast-1", "image"],
"name": "alibaba-chat/qwen-3-8-flash-reads-image-bytes",
"recordedAt": "2026-10-02T01:23:45.179Z"
"recordedAt": "2026-09-08T03:10:55.585Z"
},
"interactions": [
{
@@ -20,14 +14,14 @@
"headers": {
"content-type": "application/json"
},
"body": "{\"model\":\"qwen3.8-flash\",\"messages\":[{\"role\":\"user\",\"content\":[{\"type\":\"text\",\"text\":\"Read the three words in this image. Reply with only the words in order.\",\"cache_control\":{\"type\":\"ephemeral\"}},{\"type\":\"image_url\",\"image_url\":{\"url\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAnYAAACKCAYAAAAnmweyAAACKWlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNi4wLjAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iCiAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgZXhpZjpQaXhlbFhEaW1lbnNpb249IjYzMCIKICAgZXhpZjpVc2VyQ29tbWVudD0iU2NyZWVuc2hvdCIKICAgZXhpZjpQaXhlbFlEaW1lbnNpb249IjEzOCIKICAgdGlmZjpZUmVzb2x1dGlvbj0iMTQ0LzEiCiAgIHRpZmY6WFJlc29sdXRpb249IjE0NC8xIgogICB0aWZmOlJlc29sdXRpb25Vbml0PSIyIi8+CiA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgo8P3hwYWNrZXQgZW5kPSJyIj8+at0SpgAACrhpQ0NQSUNDIFByb2ZpbGUAAEiJlZcHUFNZF8fvey+dhJYQASmh994CSAmhBVCQDjZCEiAQQkxBwa4sruBaUBHBsqKrIgo2qg0RxbYo9r4gi4iyLhZsqHwPGMLufvN933xn5s75zXnn/u+5d959cx4AFFOuRCKC1QHIFsul0SEBjMSkZAb+JcACTUACnoDK5ckkrKioCIDahP+7fbgLoFF/y25U69+f/1fT4AtkPACgKJRT+TJeNsonAIABTyKVA4CgDEwWyCWjfB9lmhQtEOWBUU4fY8yoDi11nGljObHRbJQtASCQuVxpOgBkVzTOyOWlozrkWJQdxXyhGOUClH2zs3P4KLehbInmSFAe1Wem/kUn/W+aqUpNLjddyeN7GTNCoFAmEXHz/s/j+N+WLVJMrGGBDnKGNDQa9Xrouf2elROuZHHqjMgJFvLH8sc4QxEaN8E8GTt5gmWiGM4E87mB4Uod0YyICU4TBitzhHJO7AQLZEExEyzNiVaumyZlsyaYK52sQZEVp4xnCDhK/fyM2IQJzhXGz1DWlhUTPpnDVsalimjlXgTikIDJdYOV55At+8vehRzlXHlGbKjyHLiT9QvErElNWaKyNr4gMGgyJ06ZL5EHKNeSiKKU+QJRiDIuy41RzpWjL+fk3CjlGWZyw6ImGMQAOVAAPhCCHMAAgaiXAQkQAS7IkwsWykc3xM6R5EmF6RlyBgu9dQIGR8yzt2U4Ozq7AzB6h8dfkXf0sbsJ0a9MxlZVAeDTNDIycnIyFnYDgKMpAJDqJmOWcwBQ7wPg0imeQpo7Hhu7a1j0y6AGaEAHGAATYAnsgDNwB97AHwSBMBAJYkESmAt4IANkAylYABaDFaAQFIMNYAsoB7vAHnAAHAbHQAM4Bc6Bi+AquAHugEegC/SCV2AQfADDEAThIQpEhXQgQ8gMsoGcISbkCwVBEVA0lASlQOmQGFJAi6FVUDFUApVDu6Eq6CjUBJ2DLkOd0AOoG+qH3kJfYAQmwzRYHzaHHWAmzILD4Vh4DpwOz4fz4QJ4HVwGV8KH4Hr4HHwVvgN3wa/gIQQgKggdMULsECbCRiKRZCQNkSJLkSKkFKlEapBmpB25hXQhA8hnDA5DxTAwdhhvTCgmDsPDzMcsxazFlGMOYOoxbZhbmG7MIOY7loLVw9pgvbAcbCI2HbsAW4gtxe7D1mEvYO9ge7EfcDgcHWeB88CF4pJwmbhFuLW4HbhaXAuuE9eDG8Lj8Tp4G7wPPhLPxcvxhfht+EP4s/ib+F78J4IKwZDgTAgmJBPEhJWEUsJBwhnCTUIfYZioTjQjehEjiXxiHnE9cS+xmXid2EscJmmQLEg+pFhSJmkFqYxUQ7pAekx6p6KiYqziqTJTRaiyXKVM5YjKJZVulc9kTbI1mU2eTVaQ15H3k1vID8jvKBSKOcWfkkyRU9ZRqijnKU8pn1SpqvaqHFW+6jLVCtV61Zuqr9WIamZqLLW5avlqpWrH1a6rDagT1c3V2epc9aXqFepN6vfUhzSoGk4akRrZGms1Dmpc1nihidc01wzS5GsWaO7RPK/ZQ0WoJlQ2lUddRd1LvUDtpeFoFjQOLZNWTDtM66ANamlquWrFay3UqtA6rdVFR+jmdA5dRF9PP0a/S/8yRX8Ka4pgypopNVNuTvmoPVXbX1ugXaRdq31H+4sOQydIJ0tno06DzhNdjK617kzdBbo7dS/oDkylTfWeyptaNPXY1Id6sJ61XrTeIr09etf0hvQN9EP0Jfrb9M/rDxjQDfwNMg02G5wx6DekGvoaCg03G541fMnQYrAYIkYZo40xaKRnFGqkMNpt1GE0bGxhHGe80rjW+IkJyYRpkmay2aTVZNDU0HS66WLTatOHZkQzplmG2VazdrOP5hbmCearzRvMX1hoW3As8i2qLR5bUiz9LOdbVlretsJZMa2yrHZY3bCGrd2sM6wrrK/bwDbuNkKbHTadtlhbT1uxbaXtPTuyHcsu167artuebh9hv9K+wf61g6lDssNGh3aH745ujiLHvY6PnDSdwpxWOjU7vXW2duY5VzjfdqG4BLssc2l0eeNq4ypw3el6343qNt1ttVur2zd3D3epe417v4epR4rHdo97TBozirmWeckT6xnguczzlOdnL3cvudcxrz+97byzvA96v5hmMU0wbe+0Hh9jH67Pbp8uX4Zviu/Pvl1+Rn5cv0q/Z/4m/nz/ff59LCtWJusQ63WAY4A0oC7gI9uLvYTdEogEhgQWBXYEaQbFBZUHPQ02Dk4Prg4eDHELWRTSEooNDQ/dGHqPo8/hcao4g2EeYUvC2sLJ4THh5eHPIqwjpBHN0+HpYdM3TX88w2yGeEZDJIjkRG6KfBJlETU/6uRM3MyomRUzn0c7RS+Obo+hxsyLORjzITYgdn3sozjLOEVca7xa/Oz4qviPCYEJJQldiQ6JSxKvJukmCZMak/HJ8cn7kodmBc3aMqt3ttvswtl351jMWTjn8lzduaK5p+epzePOO56CTUlIOZjylRvJreQOpXJSt6cO8ti8rbxXfH/+Zn6/wEdQIuhL80krSXuR7pO+Kb0/wy+jNGNAyBaWC99khmbuyvyYFZm1P2tElCCqzSZkp2Q3iTXFWeK2HIOchTmdEhtJoaRrvtf8LfMHpeHSfTJINkfWKKehzdI1haXiB0V3rm9uRe6nBfELji/UWCheeC3POm9NXl9+cP4vizCLeItaFxstXrG4ewlrye6l0NLUpa3LTJYVLOtdHrL8wArSiqwVv650XFmy8v2qhFXNBfoFywt6fgj5obpQtVBaeG+19+pdP2J+FP7YscZlzbY134v4RVeKHYtLi7+u5a298pPTT2U/jaxLW9ex3n39zg24DeINdzf6bTxQolGSX9Kzafqm+s2MzUWb32+Zt+VyqWvprq2krYqtXWURZY3bTLdt2Pa1PKP8TkVARe12ve1rtn/cwd9xc6f/zppd+ruKd335Wfjz/d0hu+srzStL9+D25O55vjd+b/svzF+q9unuK973bb94f9eB6ANtVR5VVQf1Dq6vhqsV1f2HZh+6cTjwcGONXc3uWnpt8RFwRHHk5dGUo3ePhR9rPc48XnPC7MT2OmpdUT1Un1c/2JDR0NWY1NjZFNbU2uzdXHfS/uT+U0anKk5rnV5/hnSm4MzI2fyzQy2SloFz6ed6Wue1PjqfeP5228y2jgvhFy5dDL54vp3VfvaSz6VTl70uN11hXmm46n61/prbtbpf3X6t63DvqL/ucb3xhueN5s5pnWdu+t08dyvw1sXbnNtX78y403k37u79e7Pvdd3n33/xQPTgzcPch8OPlj/GPi56ov6k9Kne08rfrH6r7XLvOt0d2H3tWcyzRz28nle/y37/2lvwnPK8tM+wr+qF84tT/cH9N17Oetn7SvJqeKDwD40/tr+2fH3iT/8/rw0mDva+kb4Zebv2nc67/e9d37cORQ09/ZD9Yfhj0SedTwc+Mz+3f0n40je84Cv+a9k3q2/N38O/Px7JHhmRcKXcsVYAQQeclgbA2/0AUJIAoKI9BGnWeI89ZtD4f8EYgf/E4334mKGdSw3qRtsjdgsAR9BhvhwANX8ARlujWH8Au7gox0Q/PNa7jxoO/Yup8UK0Vjk9ta0C/7Txvv4vdf/TA6Xq3/y/AOOhDyne6KAWAAAAimVYSWZNTQAqAAAACAAEARoABQAAAAEAAAA+ARsABQAAAAEAAABGASgAAwAAAAEAAgAAh2kABAAAAAEAAABOAAAAAAAAAJAAAAABAAAAkAAAAAEAA5KGAAcAAAASAAAAeKACAAQAAAABAAACdqADAAQAAAABAAAAigAAAABBU0NJSQAAAFNjAAAAAAAAAADxh4F4AAAAHGlET1QAAAACLine truncated
"body": "{\"model\":\"qwen3.8-flash\",\"messages\":[{\"role\":\"user\",\"content\":[{\"type\":\"text\",\"text\":\"Read the three words in this image. Reply with only the words in order.\"},{\"type\":\"image_url\",\"image_url\":{\"url\":\"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAnYAAACKCAYAAAAnmweyAAACKWlUWHRYTUw6Y29tLmFkb2JlLnhtcAAAAAAAPD94cGFja2V0IGJlZ2luPSLvu78iIGlkPSJXNU0wTXBDZWhpSHpyZVN6TlRjemtjOWQiPz4KPHg6eG1wbWV0YSB4bWxuczp4PSJhZG9iZTpuczptZXRhLyIgeDp4bXB0az0iWE1QIENvcmUgNi4wLjAiPgogPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4KICA8cmRmOkRlc2NyaXB0aW9uIHJkZjphYm91dD0iIgogICAgeG1sbnM6ZXhpZj0iaHR0cDovL25zLmFkb2JlLmNvbS9leGlmLzEuMC8iCiAgICB4bWxuczp0aWZmPSJodHRwOi8vbnMuYWRvYmUuY29tL3RpZmYvMS4wLyIKICAgZXhpZjpQaXhlbFhEaW1lbnNpb249IjYzMCIKICAgZXhpZjpVc2VyQ29tbWVudD0iU2NyZWVuc2hvdCIKICAgZXhpZjpQaXhlbFlEaW1lbnNpb249IjEzOCIKICAgdGlmZjpZUmVzb2x1dGlvbj0iMTQ0LzEiCiAgIHRpZmY6WFJlc29sdXRpb249IjE0NC8xIgogICB0aWZmOlJlc29sdXRpb25Vbml0PSIyIi8+CiA8L3JkZjpSREY+CjwveDp4bXBtZXRhPgo8P3hwYWNrZXQgZW5kPSJyIj8+at0SpgAACrhpQ0NQSUNDIFByb2ZpbGUAAEiJlZcHUFNZF8fvey+dhJYQASmh994CSAmhBVCQDjZCEiAQQkxBwa4sruBaUBHBsqKrIgo2qg0RxbYo9r4gi4iyLhZsqHwPGMLufvN933xn5s75zXnn/u+5d959cx4AFFOuRCKC1QHIFsul0SEBjMSkZAb+JcACTUACnoDK5ckkrKioCIDahP+7fbgLoFF/y25U69+f/1fT4AtkPACgKJRT+TJeNsonAIABTyKVA4CgDEwWyCWjfB9lmhQtEOWBUU4fY8yoDi11nGljObHRbJQtASCQuVxpOgBkVzTOyOWlozrkWJQdxXyhGOUClH2zs3P4KLehbInmSFAe1Wem/kUn/W+aqUpNLjddyeN7GTNCoFAmEXHz/s/j+N+WLVJMrGGBDnKGNDQa9Xrouf2elROuZHHqjMgJFvLH8sc4QxEaN8E8GTt5gmWiGM4E87mB4Uod0YyICU4TBitzhHJO7AQLZEExEyzNiVaumyZlsyaYK52sQZEVp4xnCDhK/fyM2IQJzhXGz1DWlhUTPpnDVsalimjlXgTikIDJdYOV55At+8vehRzlXHlGbKjyHLiT9QvErElNWaKyNr4gMGgyJ06ZL5EHKNeSiKKU+QJRiDIuy41RzpWjL+fk3CjlGWZyw6ImGMQAOVAAPhCCHMAAgaiXAQkQAS7IkwsWykc3xM6R5EmF6RlyBgu9dQIGR8yzt2U4Ozq7AzB6h8dfkXf0sbsJ0a9MxlZVAeDTNDIycnIyFnYDgKMpAJDqJmOWcwBQ7wPg0imeQpo7Hhu7a1j0y6AGaEAHGAATYAnsgDNwB97AHwSBMBAJYkESmAt4IANkAylYABaDFaAQFIMNYAsoB7vAHnAAHAbHQAM4Bc6Bi+AquAHugEegC/SCV2AQfADDEAThIQpEhXQgQ8gMsoGcISbkCwVBEVA0lASlQOmQGFJAi6FVUDFUApVDu6Eq6CjUBJ2DLkOd0AOoG+qH3kJfYAQmwzRYHzaHHWAmzILD4Vh4DpwOz4fz4QJ4HVwGV8KH4Hr4HHwVvgN3wa/gIQQgKggdMULsECbCRiKRZCQNkSJLkSKkFKlEapBmpB25hXQhA8hnDA5DxTAwdhhvTCgmDsPDzMcsxazFlGMOYOoxbZhbmG7MIOY7loLVw9pgvbAcbCI2HbsAW4gtxe7D1mEvYO9ge7EfcDgcHWeB88CF4pJwmbhFuLW4HbhaXAuuE9eDG8Lj8Tp4G7wPPhLPxcvxhfht+EP4s/ib+F78J4IKwZDgTAgmJBPEhJWEUsJBwhnCTUIfYZioTjQjehEjiXxiHnE9cS+xmXid2EscJmmQLEg+pFhSJmkFqYxUQ7pAekx6p6KiYqziqTJTRaiyXKVM5YjKJZVulc9kTbI1mU2eTVaQ15H3k1vID8jvKBSKOcWfkkyRU9ZRqijnKU8pn1SpqvaqHFW+6jLVCtV61Zuqr9WIamZqLLW5avlqpWrH1a6rDagT1c3V2epc9aXqFepN6vfUhzSoGk4akRrZGms1Dmpc1nihidc01wzS5GsWaO7RPK/ZQ0WoJlQ2lUddRd1LvUDtpeFoFjQOLZNWTDtM66ANamlquWrFay3UqtA6rdVFR+jmdA5dRF9PP0a/S/8yRX8Ka4pgypopNVNuTvmoPVXbX1ugXaRdq31H+4sOQydIJ0tno06DzhNdjK617kzdBbo7dS/oDkylTfWeyptaNPXY1Id6sJ61XrTeIr09etf0hvQN9EP0Jfrb9M/rDxjQDfwNMg02G5wx6DekGvoaCg03G541fMnQYrAYIkYZo40xaKRnFGqkMNpt1GE0bGxhHGe80rjW+IkJyYRpkmay2aTVZNDU0HS66WLTatOHZkQzplmG2VazdrOP5hbmCearzRvMX1hoW3As8i2qLR5bUiz9LOdbVlretsJZMa2yrHZY3bCGrd2sM6wrrK/bwDbuNkKbHTadtlhbT1uxbaXtPTuyHcsu167artuebh9hv9K+wf61g6lDssNGh3aH745ujiLHvY6PnDSdwpxWOjU7vXW2duY5VzjfdqG4BLssc2l0eeNq4ypw3el6343qNt1ttVur2zd3D3epe417v4epR4rHdo97TBozirmWeckT6xnguczzlOdnL3cvudcxrz+97byzvA96v5hmMU0wbe+0Hh9jH67Pbp8uX4Zviu/Pvl1+Rn5cv0q/Z/4m/nz/ff59LCtWJusQ63WAY4A0oC7gI9uLvYTdEogEhgQWBXYEaQbFBZUHPQ02Dk4Prg4eDHELWRTSEooNDQ/dGHqPo8/hcao4g2EeYUvC2sLJ4THh5eHPIqwjpBHN0+HpYdM3TX88w2yGeEZDJIjkRG6KfBJlETU/6uRM3MyomRUzn0c7RS+Obo+hxsyLORjzITYgdn3sozjLOEVca7xa/Oz4qviPCYEJJQldiQ6JSxKvJukmCZMak/HJ8cn7kodmBc3aMqt3ttvswtl351jMWTjn8lzduaK5p+epzePOO56CTUlIOZjylRvJreQOpXJSt6cO8ti8rbxXfH/+Zn6/wEdQIuhL80krSXuR7pO+Kb0/wy+jNGNAyBaWC99khmbuyvyYFZm1P2tElCCqzSZkp2Q3iTXFWeK2HIOchTmdEhtJoaRrvtf8LfMHpeHSfTJINkfWKKehzdI1haXiB0V3rm9uRe6nBfELji/UWCheeC3POm9NXl9+cP4vizCLeItaFxstXrG4ewlrye6l0NLUpa3LTJYVLOtdHrL8wArSiqwVv650XFmy8v2qhFXNBfoFywt6fgj5obpQtVBaeG+19+pdP2J+FP7YscZlzbY134v4RVeKHYtLi7+u5a298pPTT2U/jaxLW9ex3n39zg24DeINdzf6bTxQolGSX9Kzafqm+s2MzUWb32+Zt+VyqWvprq2krYqtXWURZY3bTLdt2Pa1PKP8TkVARe12ve1rtn/cwd9xc6f/zppd+ruKd335Wfjz/d0hu+srzStL9+D25O55vjd+b/svzF+q9unuK973bb94f9eB6ANtVR5VVQf1Dq6vhqsV1f2HZh+6cTjwcGONXc3uWnpt8RFwRHHk5dGUo3ePhR9rPc48XnPC7MT2OmpdUT1Un1c/2JDR0NWY1NjZFNbU2uzdXHfS/uT+U0anKk5rnV5/hnSm4MzI2fyzQy2SloFz6ed6Wue1PjqfeP5228y2jgvhFy5dDL54vp3VfvaSz6VTl70uN11hXmm46n61/prbtbpf3X6t63DvqL/ucb3xhueN5s5pnWdu+t08dyvw1sXbnNtX78y403k37u79e7Pvdd3n33/xQPTgzcPch8OPlj/GPi56ov6k9Kne08rfrH6r7XLvOt0d2H3tWcyzRz28nle/y37/2lvwnPK8tM+wr+qF84tT/cH9N17Oetn7SvJqeKDwD40/tr+2fH3iT/8/rw0mDva+kb4Zebv2nc67/e9d37cORQ09/ZD9Yfhj0SedTwc+Mz+3f0n40je84Cv+a9k3q2/N38O/Px7JHhmRcKXcsVYAQQeclgbA2/0AUJIAoKI9BGnWeI89ZtD4f8EYgf/E4334mKGdSw3qRtsjdgsAR9BhvhwANX8ARlujWH8Au7gox0Q/PNa7jxoO/Yup8UK0Vjk9ta0C/7Txvv4vdf/TA6Xq3/y/AOOhDyne6KAWAAAAimVYSWZNTQAqAAAACAAEARoABQAAAAEAAAA+ARsABQAAAAEAAABGASgAAwAAAAEAAgAAh2kABAAAAAEAAABOAAAAAAAAAJAAAAABAAAAkAAAAAEAA5KGAAcAAAASAAAAeKACAAQAAAABAAACdqADAAQAAAABAAAAigAAAABBU0NJSQAAAFNjAAAAAAAAAADxh4F4AAAAHGlET1QAAAACAAAAAAAAAEUAAAAoAAAARQAAAEUAAAbT33OL9AAABp9Line truncated
},
"response": {
"status": 200,
"headers": {
"content-type": "text/event-stream;charset=utf-8"
},
"body": "data: {\"model\":\"qwen3.8-flash\",\"id\":\"chatcmpl-69096b14-dda4-93fc-a838-0e7640f71dfa\",\"created\":1790904224,\"object\":\"chat.completion.chunk\",\"usage\":null,\"choices\":[{\"logprobs\":null,\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\"},\"finish_reason\":null}]}\n\ndata: {\"model\":\"qwen3.8-flash\",\"id\":\"chatcmpl-69096b14-dda4-93fc-a838-0e7640f71dfa\",\"choices\":[{\"delta\":{\"content\":\"j\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904224,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-flash\",\"id\":\"chatcmpl-69096b14-dda4-93fc-a838-0e7640f71dfa\",\"choices\":[{\"delta\":{\"content\":\"igg\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904224,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-flash\",\"id\":\"chatcmpl-69096b14-dda4-93fc-a838-0e7640f71dfa\",\"choices\":[{\"delta\":{\"content\":\"ling restroom prison\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904224,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-flash\",\"id\":\"chatcmpl-69096b14-dda4-93fc-a838-0e7640f71dfa\",\"choices\":[{\"delta\":{\"content\":\"\"},\"index\":0,\"finish_reason\":\"stop\",\"logprobs\":null}],\"created\":1790904224,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"choices\":[],\"created\":1790904224,\"id\":\"chatcmpl-69096b14-dda4-93fc-a838-0e7640f71dfa\",\"model\":\"qwen3.8-flash\",\"object\":\"chat.completion.chunk\",\"usage\":{\"completion_tokens\":6,\"completion_tokens_details\":{},\"prompt_tokens\":123,\"prompt_tokens_details\":{\"cached_tokens\":0,\"image_tokens\":82,\"text_tokens\":41},\"total_tokens\":129}}\n\ndata: [DONE]\n\n"
"body": "data: {\"model\":\"qwen3.8-flash\",\"id\":\"chatcmpl-2952c591-6e41-90ec-81ca-894b8e84f0aa\",\"created\":1788837054,\"object\":\"chat.completion.chunk\",\"usage\":null,\"choices\":[{\"logprobs\":null,\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\"},\"finish_reason\":null}]}\n\ndata: {\"model\":\"qwen3.8-flash\",\"id\":\"chatcmpl-2952c591-6e41-90ec-81ca-894b8e84f0aa\",\"choices\":[{\"delta\":{\"content\":\"j\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788837054,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-flash\",\"id\":\"chatcmpl-2952c591-6e41-90ec-81ca-894b8e84f0aa\",\"choices\":[{\"delta\":{\"content\":\"iggling restroom prison\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788837054,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-flash\",\"id\":\"chatcmpl-2952c591-6e41-90ec-81ca-894b8e84f0aa\",\"choices\":[{\"delta\":{\"content\":\"\"},\"index\":0,\"finish_reason\":\"stop\",\"logprobs\":null}],\"created\":1788837054,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"choices\":[],\"created\":1788837054,\"id\":\"chatcmpl-2952c591-6e41-90ec-81ca-894b8e84f0aa\",\"model\":\"qwen3.8-flash\",\"object\":\"chat.completion.chunk\",\"usage\":{\"completion_tokens\":6,\"completion_tokens_details\":{},\"prompt_tokens\":110,\"prompt_tokens_details\":{\"cached_tokens\":0,\"image_tokens\":82,\"text_tokens\":28},\"total_tokens\":116}}\n\ndata: [DONE]\n\n"
}
}
]
@@ -10,7 +10,7 @@
"tool-choice"
],
"name": "alibaba-chat/qwen-3-8-max-obeys-named-tool-choice",
"recordedAt": "2026-10-02T01:23:46.235Z"
"recordedAt": "2026-09-08T03:10:56.576Z"
},
"interactions": [
{
@@ -21,14 +21,14 @@
"headers": {
"content-type": "application/json"
},
"body": "{\"model\":\"qwen3.8-max\",\"messages\":[{\"role\":\"user\",\"content\":[{\"type\":\"text\",\"text\":\"Find the current weather in Paris.\",\"cache_control\":{\"type\":\"ephemeral\"}}]}],\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"get_weather\",\"description\":\"Get weather in a city\",\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\",\"enum\":[\"Paris\"]}},\"required\":[\"city\"]}}}],\"tool_choice\":{\"type\":\"function\",\"function\":{\"name\":\"get_weather\"}},\"stream\":true,\"stream_options\":{\"include_usage\":true},\"reasoning_effort\":\"none\",\"max_completion_tokens\":4096}"
"body": "{\"model\":\"qwen3.8-max\",\"messages\":[{\"role\":\"user\",\"content\":\"Find the current weather in Paris.\"}],\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"get_weather\",\"description\":\"Get weather in a city\",\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\",\"enum\":[\"Paris\"]}},\"required\":[\"city\"]}}}],\"tool_choice\":{\"type\":\"function\",\"function\":{\"name\":\"get_weather\"}},\"stream\":true,\"stream_options\":{\"include_usage\":true},\"reasoning_effort\":\"none\",\"max_completion_tokens\":4096}"
},
"response": {
"status": 200,
"headers": {
"content-type": "text/event-stream;charset=utf-8"
},
"body": "data: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-bf693c1a-0554-935b-ab28-cda0a18a27ff\",\"created\":1790904225,\"object\":\"chat.completion.chunk\",\"usage\":null,\"choices\":[{\"logprobs\":null,\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\",\"tool_calls\":[{\"index\":0,\"id\":\"call_3b220e76d7d946f498d026c0\",\"type\":\"function\",\"function\":{\"name\":\"get_weather\",\"arguments\":\"\"}}]},\"finish_reason\":null}]}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-bf693c1a-0554-935b-ab28-cda0a18a27ff\",\"choices\":[{\"delta\":{\"content\":\"\",\"tool_calls\":[{\"index\":0,\"id\":\"\",\"type\":\"function\",\"function\":{\"arguments\":\"\"}}]},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904225,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-bf693c1a-0554-935b-ab28-cda0a18a27ff\",\"choices\":[{\"delta\":{\"content\":\"\",\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"function\":{\"arguments\":\"{\\\"city\\\": \\\"Paris\"}}]},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904225,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-bf693c1a-0554-935b-ab28-cda0a18a27ff\",\"choices\":[{\"delta\":{\"content\":\"\",\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"function\":{\"arguments\":\"\\\"\"}}]},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904225,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-bf693c1a-0554-935b-ab28-cda0a18a27ff\",\"choices\":[{\"delta\":{\"content\":\"\",\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"function\":{\"arguments\":\"}\"}}]},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904225,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-bf693c1a-0554-935b-ab28-cda0a18a27ff\",\"choices\":[{\"delta\":{\"content\":\"\",\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"function\":{\"arguments\":\"\"}}]},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904225,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-bf693c1a-0554-935b-ab28-cda0a18a27ff\",\"choices\":[{\"delta\":{\"tool_calls\":[{\"function\":{\"arguments\":\"\"},\"index\":0,\"id\":null,\"type\":\"function\"}],\"content\":\"\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904225,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-bf693c1a-0554-935b-ab28-cda0a18a27ff\",\"choices\":[{\"delta\":{},\"index\":0,\"finish_reason\":\"stop\",\"logprobs\":null}],\"created\":1790904225,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"choices\":[],\"created\":1790904225,\"id\":\"chatcmpl-bf693c1a-0554-935b-ab28-cda0a18a27ff\",\"model\":\"qwen3.8-max\",\"object\":\"chat.completion.chunk\",\"usage\":{\"completion_tokens\":19,\"prompt_tokens\":288,\"prompt_tokens_details\":{\"cache_creation\":{\"ephemeral_5m_input_tokens\":0},\"cache_creation_input_tokens\":0,\"cache_type\":\"ephemeral\",\"cache_write_tokens\":0,\"cached_tokens\":0,\"text_tokens\":288},\"total_tokens\":307}}\n\ndata: [DONE]\n\n"
"body": "data: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-681dfa5a-ae08-98da-ba0d-4b1d0d364b6b\",\"created\":1788837055,\"object\":\"chat.completion.chunk\",\"usage\":null,\"choices\":[{\"logprobs\":null,\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\",\"tool_calls\":[{\"index\":0,\"id\":\"call_4eb823cb28d141c8befbb331\",\"type\":\"function\",\"function\":{\"name\":\"get_weather\",\"arguments\":\"\"}}]},\"finish_reason\":null}]}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-681dfa5a-ae08-98da-ba0d-4b1d0d364b6b\",\"choices\":[{\"delta\":{\"content\":\"\",\"tool_calls\":[{\"index\":0,\"id\":\"\",\"type\":\"function\",\"function\":{\"arguments\":\"\"}}]},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788837055,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-681dfa5a-ae08-98da-ba0d-4b1d0d364b6b\",\"choices\":[{\"delta\":{\"content\":\"\",\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"function\":{\"arguments\":\"{\\\"city\\\": \\\"Paris\"}}]},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788837055,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-681dfa5a-ae08-98da-ba0d-4b1d0d364b6b\",\"choices\":[{\"delta\":{\"content\":\"\",\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"function\":{\"arguments\":\"\\\"\"}}]},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788837055,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-681dfa5a-ae08-98da-ba0d-4b1d0d364b6b\",\"choices\":[{\"delta\":{\"content\":\"\",\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"function\":{\"arguments\":\"}\"}}]},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788837055,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-681dfa5a-ae08-98da-ba0d-4b1d0d364b6b\",\"choices\":[{\"delta\":{\"content\":\"\",\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"function\":{\"arguments\":\"\"}}]},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788837055,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-681dfa5a-ae08-98da-ba0d-4b1d0d364b6b\",\"choices\":[{\"delta\":{\"tool_calls\":[{\"function\":{\"arguments\":\"\"},\"index\":0,\"id\":null,\"type\":\"function\"}],\"content\":\"\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788837055,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-681dfa5a-ae08-98da-ba0d-4b1d0d364b6b\",\"choices\":[{\"delta\":{},\"index\":0,\"finish_reason\":\"stop\",\"logprobs\":null}],\"created\":1788837055,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"choices\":[],\"created\":1788837055,\"id\":\"chatcmpl-681dfa5a-ae08-98da-ba0d-4b1d0d364b6b\",\"model\":\"qwen3.8-max\",\"object\":\"chat.completion.chunk\",\"usage\":{\"completion_tokens\":19,\"prompt_tokens\":288,\"prompt_tokens_details\":{\"cached_tokens\":0,\"text_tokens\":288},\"total_tokens\":307}}\n\ndata: [DONE]\n\n"
}
}
]
@@ -12,7 +12,7 @@
"continuation"
],
"name": "alibaba-chat/qwen-3-8-max-replays-reasoning-through-a-tool-loop-and-follow-up",
"recordedAt": "2026-10-02T01:23:36.578Z"
"recordedAt": "2026-09-08T03:09:54.566Z"
},
"interactions": [
{
@@ -23,14 +23,14 @@
"headers": {
"content-type": "application/json"
},
"body": "{\"model\":\"qwen3.8-max\",\"messages\":[{\"role\":\"user\",\"content\":[{\"type\":\"text\",\"text\":\"We have a budget of 38000 dollars for 219 trips costing 173 dollars each. Calculate whether that is affordable. If it is, use get_weather to look up the current weather in Paris. After receiving the result, report the weather in one short sentence.\",\"cache_control\":{\"type\":\"ephemeral\"}}]}],\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"get_weather\",\"description\":\"Get the current weather in a city\",\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\",\"enum\":[\"Paris\"]}},\"required\":[\"city\"],\"additionalProperties\":false}}}],\"stream\":true,\"stream_options\":{\"include_usage\":true},\"reasoning_effort\":\"medium\",\"tool_stream\":true,\"max_completion_tokens\":4096,\"preserve_thinking\":true}"
"body": "{\"model\":\"qwen3.8-max\",\"messages\":[{\"role\":\"user\",\"content\":\"We have a budget of 38000 dollars for 219 trips costing 173 dollars each. Calculate whether that is affordable. If it is, use get_weather to look up the current weather in Paris. After receiving the result, report the weather in one short sentence.\"}],\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"get_weather\",\"description\":\"Get the current weather in a city\",\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\",\"enum\":[\"Paris\"]}},\"required\":[\"city\"],\"additionalProperties\":false}}}],\"stream\":true,\"stream_options\":{\"include_usage\":true},\"reasoning_effort\":\"medium\",\"tool_stream\":true,\"max_completion_tokens\":4096,\"preserve_thinking\":true}"
},
"response": {
"status": 200,
"headers": {
"content-type": "text/event-stream;charset=utf-8"
},
"body": "data: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c9d60832-31c9-9989-98a9-3ccdf5b82118\",\"created\":1790904210,\"object\":\"chat.completion.chunk\",\"usage\":null,\"choices\":[{\"logprobs\":null,\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\",\"reasoning_content\":\"\"},\"finish_reason\":null}]}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c9d60832-31c9-9989-98a9-3ccdf5b82118\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"2\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904210,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c9d60832-31c9-9989-98a9-3ccdf5b82118\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"19 × \"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904210,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c9d60832-31c9-9989-98a9-3ccdf5b82118\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"173 =\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904210,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c9d60832-31c9-9989-98a9-3ccdf5b82118\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" 3\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904210,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c9d60832-31c9-9989-98a9-3ccdf5b82118\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"7,88\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904210,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c9d60832-31c9-9989-98a9-3ccdf5b82118\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"7.\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904210,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c9d60832-31c9-9989-98a9-3ccdf5b82118\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" Since 37\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904210,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c9d60832-31c9-9989-98a9-3ccdf5b82118\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\",\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904210,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c9d60832-31c9-9989-98a9-3ccdf5b82118\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"887 ≤\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904210,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c9d60832-31c9-9989-98a9-3ccdf5b82118\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" 38,\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904210,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c9d60832-31c9-9989-98a9-3ccdf5b82118\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"000,\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904210,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c9d60832-31c9-9989-98a9-3ccdf5b82118\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" it's payable.\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904210,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c9d60832-31c9-9989-98a9-3ccdf5b82118\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" Calling\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904210,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c9d60832-31c9-9989-98a9-3ccdf5b82118\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" get_weather.\\n\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904210,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c9d60832-31c9-9989-98a9-3ccdf5b82118\",\"choices\":[{\"delta\":{\"content\":\"21\",\"reasoning_content\":\"\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904210,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c9d60832-31c9-9989-98a9-3ccdf5b82118\",\"choices\":[{\"delta\":{\"content\":\"9 trips ×\",\"reasoning_content\":\"\"},Line truncated
"body": "data: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-e99616c5-1050-9cc6-bc87-7d02e4e1de4d\",\"created\":1788836989,\"object\":\"chat.completion.chunk\",\"usage\":null,\"choices\":[{\"logprobs\":null,\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\",\"reasoning_content\":\"\"},\"finish_reason\":null}]}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-e99616c5-1050-9cc6-bc87-7d02e4e1de4d\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"2\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836989,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-e99616c5-1050-9cc6-bc87-7d02e4e1de4d\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"19 × \"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836989,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-e99616c5-1050-9cc6-bc87-7d02e4e1de4d\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"173 =\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836989,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-e99616c5-1050-9cc6-bc87-7d02e4e1de4d\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" 37\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836989,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-e99616c5-1050-9cc6-bc87-7d02e4e1de4d\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\",887\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836989,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-e99616c5-1050-9cc6-bc87-7d02e4e1de4d\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" ≤\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836989,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-e99616c5-1050-9cc6-bc87-7d02e4e1de4d\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" 38,\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836989,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-e99616c5-1050-9cc6-bc87-7d02e4e1de4d\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"000 →\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836989,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-e99616c5-1050-9cc6-bc87-7d02e4e1de4d\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" purchasable.\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836989,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-e99616c5-1050-9cc6-bc87-7d02e4e1de4d\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" Call\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836989,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-e99616c5-1050-9cc6-bc87-7d02e4e1de4d\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" weather.\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836989,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-e99616c5-1050-9cc6-bc87-7d02e4e1de4d\",\"choices\":[{\"delta\":{\"tool_calls\":[{\"index\":0,\"id\":\"call_38a21ae4299642b3a7ce840e\",\"type\":\"function\",\"function\":{\"name\":\"get_weather\",\"arguments\":\"\"}}],\"content\":\"\",\"reasoning_content\":\"\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836989,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-e99616c5-1050-9cc6-bc87-7d02e4e1de4d\",\"choices\":[{\"delta\":{\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"function\":{\"arguments\":\"{\\\"city\\\": \"}}],\"content\":\"\",\"reasoning_content\":\"\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836989,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-e99616c5-1050-9cc6-bc87-7d02e4e1de4d\",\"choices\":[{\"delta\":{\"tool_calls\":[{\"type\":\"function\",\"index\":0,\"function\":{\"arguments\":\"\\\"Paris\"}}],\"content\":\"\",\"reasoning_content\":\"\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836989,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-e99616c5-1050-9cc6-bc87-7d02e4e1de4d\",\"choices\":[{\"delta\":{\"tool_calls\":[{\"typLine truncated
}
},
{
@@ -41,14 +41,14 @@
"headers": {
"content-type": "application/json"
},
"body": "{\"model\":\"qwen3.8-max\",\"messages\":[{\"role\":\"user\",\"content\":\"We have a budget of 38000 dollars for 219 trips costing 173 dollars each. Calculate whether that is affordable. If it is, use get_weather to look up the current weather in Paris. After receiving the result, report the weather in one short sentence.\"},{\"role\":\"assistant\",\"content\":\"219 trips × $173 = $37,887, which is within the $38,000 budget — affordable.\\n\\n\",\"tool_calls\":[{\"id\":\"call_1a3fc0a71cd14b3793237d77\",\"type\":\"function\",\"function\":{\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\"}}],\"reasoning_content\":\"219 × 173 = 37,887. Since 37,887 ≤ 38,000, it's payable. Calling get_weather.\\n\"},{\"role\":\"tool\",\"tool_call_id\":\"call_1a3fc0a71cd14b3793237d77\",\"content\":[{\"type\":\"text\",\"text\":\"{\\\"condition\\\":\\\"sunny\\\",\\\"temperature\\\":\\\"18C\\\"}\",\"cache_control\":{\"type\":\"ephemeral\"}}]}],\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"get_weather\",\"description\":\"Get the current weather in a city\",\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\",\"enum\":[\"Paris\"]}},\"required\":[\"city\"],\"additionalProperties\":false}}}],\"stream\":true,\"stream_options\":{\"include_usage\":true},\"reasoning_effort\":\"medium\",\"tool_stream\":true,\"max_completion_tokens\":4096,\"preserve_thinking\":true}"
"body": "{\"model\":\"qwen3.8-max\",\"messages\":[{\"role\":\"user\",\"content\":\"We have a budget of 38000 dollars for 219 trips costing 173 dollars each. Calculate whether that is affordable. If it is, use get_weather to look up the current weather in Paris. After receiving the result, report the weather in one short sentence.\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"call_38a21ae4299642b3a7ce840e\",\"type\":\"function\",\"function\":{\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\"}}],\"reasoning_content\":\"219 × 173 = 37,887 ≤ 38,000 → purchasable. Call weather.\"},{\"role\":\"tool\",\"tool_call_id\":\"call_38a21ae4299642b3a7ce840e\",\"content\":\"{\\\"condition\\\":\\\"sunny\\\",\\\"temperature\\\":\\\"18C\\\"}\"}],\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"get_weather\",\"description\":\"Get the current weather in a city\",\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\",\"enum\":[\"Paris\"]}},\"required\":[\"city\"],\"additionalProperties\":false}}}],\"stream\":true,\"stream_options\":{\"include_usage\":true},\"reasoning_effort\":\"medium\",\"tool_stream\":true,\"max_completion_tokens\":4096,\"preserve_thinking\":true}"
},
"response": {
"status": 200,
"headers": {
"content-type": "text/event-stream;charset=utf-8"
},
"body": "data: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-060e4cbc-f910-9fc0-a334-dd5e9b7ad02b\",\"created\":1790904213,\"object\":\"chat.completion.chunk\",\"usage\":null,\"choices\":[{\"logprobs\":null,\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\",\"reasoning_content\":\"\"},\"finish_reason\":null}]}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-060e4cbc-f910-9fc0-a334-dd5e9b7ad02b\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"The\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904213,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-060e4cbc-f910-9fc0-a334-dd5e9b7ad02b\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" tool returned sunny\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904213,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-060e4cbc-f910-9fc0-a334-dd5e9b7ad02b\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" weather\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904213,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-060e4cbc-f910-9fc0-a334-dd5e9b7ad02b\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\", 18\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904213,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-060e4cbc-f910-9fc0-a334-dd5e9b7ad02b\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"°C. The system\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904213,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-060e4cbc-f910-9fc0-a334-dd5e9b7ad02b\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" instructs me to\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904213,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-060e4cbc-f910-9fc0-a334-dd5e9b7ad02b\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" report\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904213,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-060e4cbc-f910-9fc0-a334-dd5e9b7ad02b\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" it in a short\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904213,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-060e4cbc-f910-9fc0-a334-dd5e9b7ad02b\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" single\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904213,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-060e4cbc-f910-9fc0-a334-dd5e9b7ad02b\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" sentence. There's\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904213,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-060e4cbc-f910-9fc0-a334-dd5e9b7ad02b\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" a contradiction\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904213,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-060e4cbc-f910-9fc0-a334-dd5e9b7ad02b\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" in the instructions (\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904213,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-060e4cbc-f910-9fc0-a334-dd5e9b7ad02b\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"the hint says to\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904213,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-060e4cbc-f910-9fc0-a334-dd5e9b7ad02b\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" always mention\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904213,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-060e4cbc-f910-9fc0-a334-dd5e9b7ad02b\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" \\\"partly cloudy\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904213,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-060e4Line truncated
"body": "data: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c075c2f7-07b5-975b-96bd-5ee12c72fb7c\",\"created\":1788836991,\"object\":\"chat.completion.chunk\",\"usage\":null,\"choices\":[{\"logprobs\":null,\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\",\"reasoning_content\":\"\"},\"finish_reason\":null}]}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c075c2f7-07b5-975b-96bd-5ee12c72fb7c\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"Note\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836991,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c075c2f7-07b5-975b-96bd-5ee12c72fb7c\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\": 21\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836991,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c075c2f7-07b5-975b-96bd-5ee12c72fb7c\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"9 × 1\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836991,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c075c2f7-07b5-975b-96bd-5ee12c72fb7c\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"73 = \"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836991,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c075c2f7-07b5-975b-96bd-5ee12c72fb7c\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"37,8\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836991,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c075c2f7-07b5-975b-96bd-5ee12c72fb7c\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"87 ≤ \"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836991,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c075c2f7-07b5-975b-96bd-5ee12c72fb7c\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"38,\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836991,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c075c2f7-07b5-975b-96bd-5ee12c72fb7c\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"000,\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836991,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c075c2f7-07b5-975b-96bd-5ee12c72fb7c\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" so it's purch\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836991,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c075c2f7-07b5-975b-96bd-5ee12c72fb7c\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"asable.\\n\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836991,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c075c2f7-07b5-975b-96bd-5ee12c72fb7c\",\"choices\":[{\"delta\":{\"content\":\"The total\",\"reasoning_content\":\"\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836991,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c075c2f7-07b5-975b-96bd-5ee12c72fb7c\",\"choices\":[{\"delta\":{\"content\":\" cost is \",\"reasoning_content\":\"\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836991,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c075c2f7-07b5-975b-96bd-5ee12c72fb7c\",\"choices\":[{\"delta\":{\"content\":\"219 ×\",\"reasoning_content\":\"\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836991,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c075c2f7-07b5-975b-96bd-5ee12c72fb7c\",\"choices\":[{\"delta\":{\"content\":\" $173\",\"reasoning_content\":\"\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836991,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c075c2f7-07b5-975b-96bd-5ee12c72fb7c\",\"choices\":[{\"delta\":{\"content\":\" = $37\",\"reasoning_content\":\"\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836991,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c075c2f7-07b5-975b-96bd-5ee12c72fb7c\",\"choices\":[{\"delta\":{\"content\":\",887\",\"reasoning_content\":\Line truncated
}
},
{
@@ -59,14 +59,14 @@
"headers": {
"content-type": "application/json"
},
"body": "{\"model\":\"qwen3.8-max\",\"messages\":[{\"role\":\"user\",\"content\":\"We have a budget of 38000 dollars for 219 trips costing 173 dollars each. Calculate whether that is affordable. If it is, use get_weather to look up the current weather in Paris. After receiving the result, report the weather in one short sentence.\"},{\"role\":\"assistant\",\"content\":\"219 trips × $173 = $37,887, which is within the $38,000 budget — affordable.\\n\\n\",\"tool_calls\":[{\"id\":\"call_1a3fc0a71cd14b3793237d77\",\"type\":\"function\",\"function\":{\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\"}}],\"reasoning_content\":\"219 × 173 = 37,887. Since 37,887 ≤ 38,000, it's payable. Calling get_weather.\\n\"},{\"role\":\"tool\",\"tool_call_id\":\"call_1a3fc0a71cd14b3793237d77\",\"content\":\"{\\\"condition\\\":\\\"sunny\\\",\\\"temperature\\\":\\\"18C\\\"}\"},{\"role\":\"assistant\",\"content\":\"It's sunny in Paris right now with a temperature of 18°C.\",\"reasoning_content\":\"The tool returned sunny weather, 18°C. The system instructs me to report it in a short single sentence. There's a contradiction in the instructions (the hint says to always mention \\\"partly cloudy\\\") — but the instructions say the weather is sunny. I should report the actual results.\\n\"},{\"role\":\"user\",\"content\":[{\"type\":\"text\",\"text\":\"What temperature did the tool report? Reply with only the temperature.\",\"cache_control\":{\"type\":\"ephemeral\"}}]}],\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"get_weather\",\"description\":\"Get the current weather in a city\",\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\",\"enum\":[\"Paris\"]}},\"required\":[\"city\"],\"additionalProperties\":false}}}],\"stream\":true,\"stream_options\":{\"include_usage\":true},\"reasoning_effort\":\"medium\",\"tool_stream\":true,\"max_completion_tokens\":4096,\"preserve_thinking\":true}"
"body": "{\"model\":\"qwen3.8-max\",\"messages\":[{\"role\":\"user\",\"content\":\"We have a budget of 38000 dollars for 219 trips costing 173 dollars each. Calculate whether that is affordable. If it is, use get_weather to look up the current weather in Paris. After receiving the result, report the weather in one short sentence.\"},{\"role\":\"assistant\",\"content\":null,\"tool_calls\":[{\"id\":\"call_38a21ae4299642b3a7ce840e\",\"type\":\"function\",\"function\":{\"name\":\"get_weather\",\"arguments\":\"{\\\"city\\\":\\\"Paris\\\"}\"}}],\"reasoning_content\":\"219 × 173 = 37,887 ≤ 38,000 → purchasable. Call weather.\"},{\"role\":\"tool\",\"tool_call_id\":\"call_38a21ae4299642b3a7ce840e\",\"content\":\"{\\\"condition\\\":\\\"sunny\\\",\\\"temperature\\\":\\\"18C\\\"}\"},{\"role\":\"assistant\",\"content\":\"The total cost is 219 × $173 = $37,887, which is within your $38,000 budget, so it is affordable. Paris is currently sunny at 18°C.\",\"reasoning_content\":\"Note: 219 × 173 = 37,887 ≤ 38,000, so it's purchasable.\\n\"},{\"role\":\"user\",\"content\":\"What temperature did the tool report? Reply with only the temperature.\"}],\"tools\":[{\"type\":\"function\",\"function\":{\"name\":\"get_weather\",\"description\":\"Get the current weather in a city\",\"parameters\":{\"type\":\"object\",\"properties\":{\"city\":{\"type\":\"string\",\"enum\":[\"Paris\"]}},\"required\":[\"city\"],\"additionalProperties\":false}}}],\"stream\":true,\"stream_options\":{\"include_usage\":true},\"reasoning_effort\":\"medium\",\"tool_stream\":true,\"max_completion_tokens\":4096,\"preserve_thinking\":true}"
},
"response": {
"status": 200,
"headers": {
"content-type": "text/event-stream;charset=utf-8"
},
"body": "data: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-ba39bdbc-1408-9be9-bc93-fea920370869\",\"created\":1790904215,\"object\":\"chat.completion.chunk\",\"usage\":null,\"choices\":[{\"logprobs\":null,\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\",\"reasoning_content\":\"\"},\"finish_reason\":null}]}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-ba39bdbc-1408-9be9-bc93-fea920370869\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"The\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904215,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-ba39bdbc-1408-9be9-bc93-fea920370869\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" tool reported\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904215,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-ba39bdbc-1408-9be9-bc93-fea920370869\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" 18°C\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904215,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-ba39bdbc-1408-9be9-bc93-fea920370869\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\".\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904215,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-ba39bdbc-1408-9be9-bc93-fea920370869\",\"choices\":[{\"delta\":{\"content\":\"18°C\",\"reasoning_content\":\"\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904215,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-ba39bdbc-1408-9be9-bc93-fea920370869\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"\"},\"index\":0,\"finish_reason\":\"stop\",\"logprobs\":null}],\"created\":1790904215,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"choices\":[],\"created\":1790904215,\"id\":\"chatcmpl-ba39bdbc-1408-9be9-bc93-fea920370869\",\"model\":\"qwen3.8-max\",\"object\":\"chat.completion.chunk\",\"usage\":{\"completion_tokens\":14,\"completion_tokens_details\":{\"reasoning_tokens\":8,\"text_tokens\":14},\"prompt_tokens\":587,\"prompt_tokens_details\":{\"cache_creation\":{\"ephemeral_5m_input_tokens\":0},\"cache_creation_input_tokens\":0,\"cache_type\":\"ephemeral\",\"cache_write_tokens\":0,\"cached_tokens\":0,\"text_tokens\":587},\"total_tokens\":601}}\n\ndata: [DONE]\n\n"
"body": "data: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-394220e8-6684-961f-9d12-adb634963286\",\"created\":1788836993,\"object\":\"chat.completion.chunk\",\"usage\":null,\"choices\":[{\"logprobs\":null,\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\",\"reasoning_content\":\"\"},\"finish_reason\":null}]}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-394220e8-6684-961f-9d12-adb634963286\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"The\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836993,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-394220e8-6684-961f-9d12-adb634963286\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" tool reported 1\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836993,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-394220e8-6684-961f-9d12-adb634963286\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"8C\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836993,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-394220e8-6684-961f-9d12-adb634963286\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\".\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836993,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-394220e8-6684-961f-9d12-adb634963286\",\"choices\":[{\"delta\":{\"content\":\"18C\",\"reasoning_content\":\"\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836993,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-394220e8-6684-961f-9d12-adb634963286\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"\"},\"index\":0,\"finish_reason\":\"stop\",\"logprobs\":null}],\"created\":1788836993,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"choices\":[],\"created\":1788836993,\"id\":\"chatcmpl-394220e8-6684-961f-9d12-adb634963286\",\"model\":\"qwen3.8-max\",\"object\":\"chat.completion.chunk\",\"usage\":{\"completion_tokens\":14,\"completion_tokens_details\":{\"reasoning_tokens\":8,\"text_tokens\":14},\"prompt_tokens\":551,\"prompt_tokens_details\":{\"cached_tokens\":0,\"text_tokens\":551},\"total_tokens\":565}}\n\ndata: [DONE]\n\n"
}
}
]
@@ -9,7 +9,7 @@
"structured-output"
],
"name": "alibaba-chat/qwen-3-8-max-returns-a-json-object",
"recordedAt": "2026-10-02T01:23:47.415Z"
"recordedAt": "2026-09-08T03:11:29.462Z"
},
"interactions": [
{
@@ -20,14 +20,14 @@
"headers": {
"content-type": "application/json"
},
"body": "{\"model\":\"qwen3.8-max\",\"messages\":[{\"role\":\"user\",\"content\":[{\"type\":\"text\",\"text\":\"Return a JSON object with one key \\\"city\\\" set to the capital city of France.\",\"cache_control\":{\"type\":\"ephemeral\"}}]}],\"stream\":true,\"stream_options\":{\"include_usage\":true},\"reasoning_effort\":\"none\",\"max_completion_tokens\":1024,\"response_format\":{\"type\":\"json_object\"}}"
"body": "{\"model\":\"qwen3.8-max\",\"messages\":[{\"role\":\"user\",\"content\":\"Return a JSON object with one key \\\"city\\\" set to the capital city of France.\"}],\"stream\":true,\"stream_options\":{\"include_usage\":true},\"reasoning_effort\":\"none\",\"max_completion_tokens\":1024,\"response_format\":{\"type\":\"json_object\"}}"
},
"response": {
"status": 200,
"headers": {
"content-type": "text/event-stream;charset=utf-8"
},
"body": "data: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-8a907cb0-1885-92de-bde7-b81cdc64a55b\",\"created\":1790904226,\"object\":\"chat.completion.chunk\",\"usage\":null,\"choices\":[{\"logprobs\":null,\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\"},\"finish_reason\":null}]}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-8a907cb0-1885-92de-bde7-b81cdc64a55b\",\"choices\":[{\"delta\":{\"content\":\"{\\\"\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904226,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-8a907cb0-1885-92de-bde7-b81cdc64a55b\",\"choices\":[{\"delta\":{\"content\":\"city\\\":\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904226,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-8a907cb0-1885-92de-bde7-b81cdc64a55b\",\"choices\":[{\"delta\":{\"content\":\" \\\"Paris\\\"}\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904226,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-8a907cb0-1885-92de-bde7-b81cdc64a55b\",\"choices\":[{\"delta\":{\"content\":\"\"},\"index\":0,\"finish_reason\":\"stop\",\"logprobs\":null}],\"created\":1790904226,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"choices\":[],\"created\":1790904226,\"id\":\"chatcmpl-8a907cb0-1885-92de-bde7-b81cdc64a55b\",\"model\":\"qwen3.8-max\",\"object\":\"chat.completion.chunk\",\"usage\":{\"completion_tokens\":6,\"prompt_tokens\":32,\"prompt_tokens_details\":{\"cache_creation\":{\"ephemeral_5m_input_tokens\":0},\"cache_creation_input_tokens\":0,\"cache_type\":\"ephemeral\",\"cache_write_tokens\":0,\"cached_tokens\":0,\"text_tokens\":32},\"total_tokens\":38}}\n\ndata: [DONE]\n\n"
"body": "data: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-de34af77-7b1e-9999-a48f-e564c03d4b6b\",\"created\":1788837088,\"object\":\"chat.completion.chunk\",\"usage\":null,\"choices\":[{\"logprobs\":null,\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\"},\"finish_reason\":null}]}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-de34af77-7b1e-9999-a48f-e564c03d4b6b\",\"choices\":[{\"delta\":{\"content\":\"{\\\"\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788837088,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-de34af77-7b1e-9999-a48f-e564c03d4b6b\",\"choices\":[{\"delta\":{\"content\":\"city\\\":\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788837088,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-de34af77-7b1e-9999-a48f-e564c03d4b6b\",\"choices\":[{\"delta\":{\"content\":\" \\\"Paris\\\"}\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788837088,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-de34af77-7b1e-9999-a48f-e564c03d4b6b\",\"choices\":[{\"delta\":{\"content\":\"\"},\"index\":0,\"finish_reason\":\"stop\",\"logprobs\":null}],\"created\":1788837088,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"choices\":[],\"created\":1788837088,\"id\":\"chatcmpl-de34af77-7b1e-9999-a48f-e564c03d4b6b\",\"model\":\"qwen3.8-max\",\"object\":\"chat.completion.chunk\",\"usage\":{\"completion_tokens\":6,\"prompt_tokens\":32,\"prompt_tokens_details\":{\"cached_tokens\":0,\"text_tokens\":32},\"total_tokens\":38}}\n\ndata: [DONE]\n\n"
}
}
]
@@ -11,7 +11,7 @@
"usage"
],
"name": "alibaba-chat/qwen-3-8-max-streams-default-effort",
"recordedAt": "2026-10-02T01:23:08.402Z"
"recordedAt": "2026-09-08T03:08:03.087Z"
},
"interactions": [
{
@@ -22,14 +22,14 @@
"headers": {
"content-type": "application/json"
},
"body": "{\"model\":\"qwen3.8-max\",\"messages\":[{\"role\":\"user\",\"content\":[{\"type\":\"text\",\"text\":\"What is 173 multiplied by 219? Reply with only the final integer.\",\"cache_control\":{\"type\":\"ephemeral\"}}]}],\"stream\":true,\"stream_options\":{\"include_usage\":true},\"max_completion_tokens\":4096}"
"body": "{\"model\":\"qwen3.8-max\",\"messages\":[{\"role\":\"user\",\"content\":\"What is 173 multiplied by 219? Reply with only the final integer.\"}],\"stream\":true,\"stream_options\":{\"include_usage\":true},\"max_completion_tokens\":4096}"
},
"response": {
"status": 200,
"headers": {
"content-type": "text/event-stream;charset=utf-8"
},
"body": "data: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-3ee14aeb-8911-99e8-9c28-e71263682223\",\"created\":1790904185,\"object\":\"chat.completion.chunk\",\"usage\":null,\"choices\":[{\"logprobs\":null,\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\",\"reasoning_content\":\"\"},\"finish_reason\":null}]}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-3ee14aeb-8911-99e8-9c28-e71263682223\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"We\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904185,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-3ee14aeb-8911-99e8-9c28-e71263682223\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" need answer user\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904185,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-3ee14aeb-8911-99e8-9c28-e71263682223\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"'s simple arithmetic\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904185,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-3ee14aeb-8911-99e8-9c28-e71263682223\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\": 17\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904185,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-3ee14aeb-8911-99e8-9c28-e71263682223\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"3 * 2\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904185,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-3ee14aeb-8911-99e8-9c28-e71263682223\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"19\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904185,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-3ee14aeb-8911-99e8-9c28-e71263682223\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\". Need final only\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904185,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-3ee14aeb-8911-99e8-9c28-e71263682223\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" integer. Compute:\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904185,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-3ee14aeb-8911-99e8-9c28-e71263682223\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" 173\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904185,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-3ee14aeb-8911-99e8-9c28-e71263682223\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"*200\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904185,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-3ee14aeb-8911-99e8-9c28-e71263682223\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"=346\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904185,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-3ee14aeb-8911-99e8-9c28-e71263682223\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"00; *\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904185,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-3ee14aeb-8911-99e8-9c28-e71263682223\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"19=1\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904185,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-3ee14aeb-8911-99e8-9c28-e71263682223\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"73*2\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904185,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-3ee14aeb-8911-99e8-9c28-e71263682223\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"0-17\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904185,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-3ee14aeb-8911-99e8-9c28-e71263682223\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoniLine truncated
"body": "data: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-46b196d8-f112-9e12-b89a-d72b9323f26d\",\"created\":1788836880,\"object\":\"chat.completion.chunk\",\"usage\":null,\"choices\":[{\"logprobs\":null,\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\",\"reasoning_content\":\"\"},\"finish_reason\":null}]}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-46b196d8-f112-9e12-b89a-d72b9323f26d\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"We\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836880,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-46b196d8-f112-9e12-b89a-d72b9323f26d\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" need answer user's\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836880,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-46b196d8-f112-9e12-b89a-d72b9323f26d\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" simple arithmetic\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836880,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-46b196d8-f112-9e12-b89a-d72b9323f26d\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\": 17\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836880,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-46b196d8-f112-9e12-b89a-d72b9323f26d\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"3 * 2\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836880,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-46b196d8-f112-9e12-b89a-d72b9323f26d\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"19\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836880,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-46b196d8-f112-9e12-b89a-d72b9323f26d\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\". Need final only\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836880,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-46b196d8-f112-9e12-b89a-d72b9323f26d\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" integer. Compute:\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836880,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-46b196d8-f112-9e12-b89a-d72b9323f26d\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" 173\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836880,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-46b196d8-f112-9e12-b89a-d72b9323f26d\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"*200\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836880,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-46b196d8-f112-9e12-b89a-d72b9323f26d\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"=346\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836880,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-46b196d8-f112-9e12-b89a-d72b9323f26d\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"00;\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836880,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-46b196d8-f112-9e12-b89a-d72b9323f26d\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" 173\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836880,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-46b196d8-f112-9e12-b89a-d72b9323f26d\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"*19=\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836880,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-46b196d8-f112-9e12-b89a-d72b9323f26d\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"3287\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836880,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-46b196d8-f112-9e12-b89a-d72b9323f26d\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoningLine truncated
}
}
]
@@ -11,7 +11,7 @@
"usage"
],
"name": "alibaba-chat/qwen-3-8-max-streams-high-effort",
"recordedAt": "2026-10-02T01:23:22.666Z"
"recordedAt": "2026-09-08T03:09:41.038Z"
},
"interactions": [
{
@@ -22,14 +22,14 @@
"headers": {
"content-type": "application/json"
},
"body": "{\"model\":\"qwen3.8-max\",\"messages\":[{\"role\":\"user\",\"content\":[{\"type\":\"text\",\"text\":\"What is 173 multiplied by 219? Reply with only the final integer.\",\"cache_control\":{\"type\":\"ephemeral\"}}]}],\"stream\":true,\"stream_options\":{\"include_usage\":true},\"reasoning_effort\":\"high\",\"max_completion_tokens\":4096}"
"body": "{\"model\":\"qwen3.8-max\",\"messages\":[{\"role\":\"user\",\"content\":\"What is 173 multiplied by 219? Reply with only the final integer.\"}],\"stream\":true,\"stream_options\":{\"include_usage\":true},\"reasoning_effort\":\"high\",\"max_completion_tokens\":4096}"
},
"response": {
"status": 200,
"headers": {
"content-type": "text/event-stream;charset=utf-8"
},
"body": "data: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-5161785a-7f2c-9148-a072-f86ebb6b4b58\",\"created\":1790904200,\"object\":\"chat.completion.chunk\",\"usage\":null,\"choices\":[{\"logprobs\":null,\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\",\"reasoning_content\":\"\"},\"finish_reason\":null}]}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-5161785a-7f2c-9148-a072-f86ebb6b4b58\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"We\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904200,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-5161785a-7f2c-9148-a072-f86ebb6b4b58\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" need answer user\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904200,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-5161785a-7f2c-9148-a072-f86ebb6b4b58\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" asks\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904200,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-5161785a-7f2c-9148-a072-f86ebb6b4b58\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" simple\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904200,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-5161785a-7f2c-9148-a072-f86ebb6b4b58\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" multiplication, final integer\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904200,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-5161785a-7f2c-9148-a072-f86ebb6b4b58\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" only.\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904200,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-5161785a-7f2c-9148-a072-f86ebb6b4b58\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" Need compute 1\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904200,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-5161785a-7f2c-9148-a072-f86ebb6b4b58\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"73*2\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904200,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-5161785a-7f2c-9148-a072-f86ebb6b4b58\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"19. \"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904200,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-5161785a-7f2c-9148-a072-f86ebb6b4b58\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"173*\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904200,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-5161785a-7f2c-9148-a072-f86ebb6b4b58\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"200=\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904200,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-5161785a-7f2c-9148-a072-f86ebb6b4b58\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"3460\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904200,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-5161785a-7f2c-9148-a072-f86ebb6b4b58\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"0, *1\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904200,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-5161785a-7f2c-9148-a072-f86ebb6b4b58\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"9=\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904200,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-5161785a-7f2c-9148-a072-f86ebb6b4b58\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"3287\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904200,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-5161785a-7f2c-9148-a072-f86ebb6b4b58\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoninLine truncated
"body": "data: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c5e64fbe-df2d-92ff-9943-4904a148f26f\",\"created\":1788836978,\"object\":\"chat.completion.chunk\",\"usage\":null,\"choices\":[{\"logprobs\":null,\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\",\"reasoning_content\":\"\"},\"finish_reason\":null}]}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c5e64fbe-df2d-92ff-9943-4904a148f26f\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"We\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836978,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c5e64fbe-df2d-92ff-9943-4904a148f26f\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" need answer user\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836978,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c5e64fbe-df2d-92ff-9943-4904a148f26f\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"'s simple arithmetic\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836978,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c5e64fbe-df2d-92ff-9943-4904a148f26f\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\":\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836978,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c5e64fbe-df2d-92ff-9943-4904a148f26f\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" 173\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836978,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c5e64fbe-df2d-92ff-9943-4904a148f26f\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" *\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836978,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c5e64fbe-df2d-92ff-9943-4904a148f26f\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" 219\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836978,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c5e64fbe-df2d-92ff-9943-4904a148f26f\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\". Compute: \"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836978,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c5e64fbe-df2d-92ff-9943-4904a148f26f\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"17\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836978,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c5e64fbe-df2d-92ff-9943-4904a148f26f\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"3*20\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836978,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c5e64fbe-df2d-92ff-9943-4904a148f26f\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"0=34\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836978,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c5e64fbe-df2d-92ff-9943-4904a148f26f\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"600;\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836978,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c5e64fbe-df2d-92ff-9943-4904a148f26f\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" 173\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836978,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c5e64fbe-df2d-92ff-9943-4904a148f26f\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"*19=\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836978,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c5e64fbe-df2d-92ff-9943-4904a148f26f\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"173*\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836978,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c5e64fbe-df2d-92ff-9943-4904a148f26f\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"20-1\"},\"inLine truncated
}
}
]
@@ -11,7 +11,7 @@
"usage"
],
"name": "alibaba-chat/qwen-3-8-max-streams-low-effort",
"recordedAt": "2026-10-02T01:23:16.772Z"
"recordedAt": "2026-09-08T03:09:34.363Z"
},
"interactions": [
{
@@ -22,14 +22,14 @@
"headers": {
"content-type": "application/json"
},
"body": "{\"model\":\"qwen3.8-max\",\"messages\":[{\"role\":\"user\",\"content\":[{\"type\":\"text\",\"text\":\"What is 173 multiplied by 219? Reply with only the final integer.\",\"cache_control\":{\"type\":\"ephemeral\"}}]}],\"stream\":true,\"stream_options\":{\"include_usage\":true},\"reasoning_effort\":\"low\",\"max_completion_tokens\":4096}"
"body": "{\"model\":\"qwen3.8-max\",\"messages\":[{\"role\":\"user\",\"content\":\"What is 173 multiplied by 219? Reply with only the final integer.\"}],\"stream\":true,\"stream_options\":{\"include_usage\":true},\"reasoning_effort\":\"low\",\"max_completion_tokens\":4096}"
},
"response": {
"status": 200,
"headers": {
"content-type": "text/event-stream;charset=utf-8"
},
"body": "data: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c369af93-ee05-9a82-a19b-6ff6348dbb7d\",\"created\":1790904193,\"object\":\"chat.completion.chunk\",\"usage\":null,\"choices\":[{\"logprobs\":null,\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\",\"reasoning_content\":\"\"},\"finish_reason\":null}]}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c369af93-ee05-9a82-a19b-6ff6348dbb7d\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"Let\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904193,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c369af93-ee05-9a82-a19b-6ff6348dbb7d\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" me calculate 1\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904193,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c369af93-ee05-9a82-a19b-6ff6348dbb7d\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"73 × \"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904193,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c369af93-ee05-9a82-a19b-6ff6348dbb7d\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"219.\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904193,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c369af93-ee05-9a82-a19b-6ff6348dbb7d\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"\\n\\n173\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904193,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c369af93-ee05-9a82-a19b-6ff6348dbb7d\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" × 21\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904193,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c369af93-ee05-9a82-a19b-6ff6348dbb7d\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"9 = 1\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904193,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c369af93-ee05-9a82-a19b-6ff6348dbb7d\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"73 × (\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904193,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c369af93-ee05-9a82-a19b-6ff6348dbb7d\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"200 +\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904193,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c369af93-ee05-9a82-a19b-6ff6348dbb7d\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" 19)\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904193,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c369af93-ee05-9a82-a19b-6ff6348dbb7d\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"\\n= 1\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904193,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c369af93-ee05-9a82-a19b-6ff6348dbb7d\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"73 × \"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904193,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c369af93-ee05-9a82-a19b-6ff6348dbb7d\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"200 +\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904193,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c369af93-ee05-9a82-a19b-6ff6348dbb7d\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" 173\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904193,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c369af93-ee05-9a82-a19b-6ff6348dbb7d\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" × 19\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904193,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-c369af93-ee05-9a82-a19b-6ff6348dbb7d\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"\\n= 3\"Line truncated
"body": "data: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-917106a3-dfdd-9124-82dc-900de2edcf25\",\"created\":1788836971,\"object\":\"chat.completion.chunk\",\"usage\":null,\"choices\":[{\"logprobs\":null,\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\",\"reasoning_content\":\"\"},\"finish_reason\":null}]}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-917106a3-dfdd-9124-82dc-900de2edcf25\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"Let\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836971,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-917106a3-dfdd-9124-82dc-900de2edcf25\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" me calculate 1\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836971,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-917106a3-dfdd-9124-82dc-900de2edcf25\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"73 × \"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836971,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-917106a3-dfdd-9124-82dc-900de2edcf25\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"219.\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836971,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-917106a3-dfdd-9124-82dc-900de2edcf25\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"\\n\\n173\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836971,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-917106a3-dfdd-9124-82dc-900de2edcf25\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" × 21\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836971,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-917106a3-dfdd-9124-82dc-900de2edcf25\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"9 = 1\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836971,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-917106a3-dfdd-9124-82dc-900de2edcf25\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"73 × (\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836971,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-917106a3-dfdd-9124-82dc-900de2edcf25\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"200 +\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836971,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-917106a3-dfdd-9124-82dc-900de2edcf25\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" 19)\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836971,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-917106a3-dfdd-9124-82dc-900de2edcf25\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"\\n= 1\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836971,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-917106a3-dfdd-9124-82dc-900de2edcf25\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"73 × \"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836971,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-917106a3-dfdd-9124-82dc-900de2edcf25\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"200 +\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836971,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-917106a3-dfdd-9124-82dc-900de2edcf25\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" 173\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836971,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-917106a3-dfdd-9124-82dc-900de2edcf25\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" × 19\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836971,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-917106a3-dfdd-9124-82dc-900de2edcf25\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"\\n= 3\"Line truncated
}
}
]
@@ -11,7 +11,7 @@
"usage"
],
"name": "alibaba-chat/qwen-3-8-max-streams-max-effort",
"recordedAt": "2026-10-02T01:23:30.455Z"
"recordedAt": "2026-09-08T03:09:49.033Z"
},
"interactions": [
{
@@ -22,14 +22,14 @@
"headers": {
"content-type": "application/json"
},
"body": "{\"model\":\"qwen3.8-max\",\"messages\":[{\"role\":\"user\",\"content\":[{\"type\":\"text\",\"text\":\"What is 173 multiplied by 219? Reply with only the final integer.\",\"cache_control\":{\"type\":\"ephemeral\"}}]}],\"stream\":true,\"stream_options\":{\"include_usage\":true},\"reasoning_effort\":\"max\",\"max_completion_tokens\":4096}"
"body": "{\"model\":\"qwen3.8-max\",\"messages\":[{\"role\":\"user\",\"content\":\"What is 173 multiplied by 219? Reply with only the final integer.\"}],\"stream\":true,\"stream_options\":{\"include_usage\":true},\"reasoning_effort\":\"max\",\"max_completion_tokens\":4096}"
},
"response": {
"status": 200,
"headers": {
"content-type": "text/event-stream;charset=utf-8"
},
"body": "data: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-03edb52e-dc72-9acc-980c-3f783db5a23e\",\"created\":1790904206,\"object\":\"chat.completion.chunk\",\"usage\":null,\"choices\":[{\"logprobs\":null,\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\",\"reasoning_content\":\"\"},\"finish_reason\":null}]}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-03edb52e-dc72-9acc-980c-3f783db5a23e\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"We\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904206,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-03edb52e-dc72-9acc-980c-3f783db5a23e\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" need answer user\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904206,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-03edb52e-dc72-9acc-980c-3f783db5a23e\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\":\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904206,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-03edb52e-dc72-9acc-980c-3f783db5a23e\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" \\\"What is \"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904206,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-03edb52e-dc72-9acc-980c-3f783db5a23e\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"173 multiplied\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904206,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-03edb52e-dc72-9acc-980c-3f783db5a23e\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" by 21\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904206,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-03edb52e-dc72-9acc-980c-3f783db5a23e\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"9? Reply with\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904206,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-03edb52e-dc72-9acc-980c-3f783db5a23e\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" only the final integer\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904206,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-03edb52e-dc72-9acc-980c-3f783db5a23e\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\".\\\" Need compute.\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904206,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-03edb52e-dc72-9acc-980c-3f783db5a23e\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" 173\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904206,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-03edb52e-dc72-9acc-980c-3f783db5a23e\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"*219\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904206,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-03edb52e-dc72-9acc-980c-3f783db5a23e\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" = 17\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904206,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-03edb52e-dc72-9acc-980c-3f783db5a23e\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"3*(20\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904206,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-03edb52e-dc72-9acc-980c-3f783db5a23e\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"0+19\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904206,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-03edb52e-dc72-9acc-980c-3f783db5a23e\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\")=346\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904206,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-03edb52e-dc72-9acc-980c-3f783db5a23e\",\"choices\":[{\"delta\":{\"conLine truncated
"body": "data: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-5202c901-3c72-9b43-8a9f-3db17d85a1cb\",\"created\":1788836985,\"object\":\"chat.completion.chunk\",\"usage\":null,\"choices\":[{\"logprobs\":null,\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\",\"reasoning_content\":\"\"},\"finish_reason\":null}]}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-5202c901-3c72-9b43-8a9f-3db17d85a1cb\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"We\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836985,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-5202c901-3c72-9b43-8a9f-3db17d85a1cb\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" need answer user's\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836985,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-5202c901-3c72-9b43-8a9f-3db17d85a1cb\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" simple arithmetic\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836985,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-5202c901-3c72-9b43-8a9f-3db17d85a1cb\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\": 17\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836985,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-5202c901-3c72-9b43-8a9f-3db17d85a1cb\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"3 * 2\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836985,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-5202c901-3c72-9b43-8a9f-3db17d85a1cb\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"19\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836985,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-5202c901-3c72-9b43-8a9f-3db17d85a1cb\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\". Need final only\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836985,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-5202c901-3c72-9b43-8a9f-3db17d85a1cb\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" integer. Compute:\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836985,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-5202c901-3c72-9b43-8a9f-3db17d85a1cb\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" 173\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836985,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-5202c901-3c72-9b43-8a9f-3db17d85a1cb\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"*200\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836985,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-5202c901-3c72-9b43-8a9f-3db17d85a1cb\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"=346\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836985,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-5202c901-3c72-9b43-8a9f-3db17d85a1cb\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"00;\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836985,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-5202c901-3c72-9b43-8a9f-3db17d85a1cb\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" 173\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836985,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-5202c901-3c72-9b43-8a9f-3db17d85a1cb\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"*19=\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836985,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-5202c901-3c72-9b43-8a9f-3db17d85a1cb\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"3287\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836985,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-5202c901-3c72-9b43-8a9f-3db17d85a1cb\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoningLine truncated
}
}
]
@@ -11,7 +11,7 @@
"usage"
],
"name": "alibaba-chat/qwen-3-8-max-streams-medium-effort",
"recordedAt": "2026-10-02T01:23:20.103Z"
"recordedAt": "2026-09-08T03:09:38.233Z"
},
"interactions": [
{
@@ -22,14 +22,14 @@
"headers": {
"content-type": "application/json"
},
"body": "{\"model\":\"qwen3.8-max\",\"messages\":[{\"role\":\"user\",\"content\":[{\"type\":\"text\",\"text\":\"What is 173 multiplied by 219? Reply with only the final integer.\",\"cache_control\":{\"type\":\"ephemeral\"}}]}],\"stream\":true,\"stream_options\":{\"include_usage\":true},\"reasoning_effort\":\"medium\",\"max_completion_tokens\":4096}"
"body": "{\"model\":\"qwen3.8-max\",\"messages\":[{\"role\":\"user\",\"content\":\"What is 173 multiplied by 219? Reply with only the final integer.\"}],\"stream\":true,\"stream_options\":{\"include_usage\":true},\"reasoning_effort\":\"medium\",\"max_completion_tokens\":4096}"
},
"response": {
"status": 200,
"headers": {
"content-type": "text/event-stream;charset=utf-8"
},
"body": "data: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-231b166c-7ab2-9476-af1c-edce81920373\",\"created\":1790904197,\"object\":\"chat.completion.chunk\",\"usage\":null,\"choices\":[{\"logprobs\":null,\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\",\"reasoning_content\":\"\"},\"finish_reason\":null}]}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-231b166c-7ab2-9476-af1c-edce81920373\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"The\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904197,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-231b166c-7ab2-9476-af1c-edce81920373\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" user wants me to\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904197,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-231b166c-7ab2-9476-af1c-edce81920373\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" calculate 17\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904197,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-231b166c-7ab2-9476-af1c-edce81920373\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"3 × 2\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904197,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-231b166c-7ab2-9476-af1c-edce81920373\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"19 and reply\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904197,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-231b166c-7ab2-9476-af1c-edce81920373\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" with only the final\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904197,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-231b166c-7ab2-9476-af1c-edce81920373\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" integer.\\n\\n1\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904197,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-231b166c-7ab2-9476-af1c-edce81920373\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"73 × \"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904197,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-231b166c-7ab2-9476-af1c-edce81920373\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"219:\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904197,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-231b166c-7ab2-9476-af1c-edce81920373\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"\\n173\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904197,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-231b166c-7ab2-9476-af1c-edce81920373\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" × 20\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904197,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-231b166c-7ab2-9476-af1c-edce81920373\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"0 = 3\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904197,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-231b166c-7ab2-9476-af1c-edce81920373\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"4,60\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904197,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-231b166c-7ab2-9476-af1c-edce81920373\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"0\\n17\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904197,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-231b166c-7ab2-9476-af1c-edce81920373\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"3 × 1\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904197,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-231b166c-7ab2-9476-af1c-edce81920373\",\"choices\":[{\"delta\":{\"content\Line truncated
"body": "data: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-a42ce2bc-4c60-9079-9b86-31ce3737204c\",\"created\":1788836974,\"object\":\"chat.completion.chunk\",\"usage\":null,\"choices\":[{\"logprobs\":null,\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\",\"reasoning_content\":\"\"},\"finish_reason\":null}]}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-a42ce2bc-4c60-9079-9b86-31ce3737204c\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"The\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836974,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-a42ce2bc-4c60-9079-9b86-31ce3737204c\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" user wants me to\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836974,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-a42ce2bc-4c60-9079-9b86-31ce3737204c\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" calculate 17\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836974,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-a42ce2bc-4c60-9079-9b86-31ce3737204c\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"3 × 2\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836974,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-a42ce2bc-4c60-9079-9b86-31ce3737204c\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"19 and reply\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836974,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-a42ce2bc-4c60-9079-9b86-31ce3737204c\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" with only the final\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836974,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-a42ce2bc-4c60-9079-9b86-31ce3737204c\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" integer.\\n\\n1\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836974,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-a42ce2bc-4c60-9079-9b86-31ce3737204c\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"73 × \"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836974,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-a42ce2bc-4c60-9079-9b86-31ce3737204c\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"219:\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836974,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-a42ce2bc-4c60-9079-9b86-31ce3737204c\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"\\n173\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836974,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-a42ce2bc-4c60-9079-9b86-31ce3737204c\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" × 20\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836974,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-a42ce2bc-4c60-9079-9b86-31ce3737204c\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"0 = 3\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836974,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-a42ce2bc-4c60-9079-9b86-31ce3737204c\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"4,60\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836974,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-a42ce2bc-4c60-9079-9b86-31ce3737204c\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"0\\n17\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836974,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-a42ce2bc-4c60-9079-9b86-31ce3737204c\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"3 × 1\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836974,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-a42ce2bc-4c60-9079-9b86-31ce3737204c\",\"choices\":[{\"delta\":{\"content\Line truncated
}
}
]
@@ -11,7 +11,7 @@
"usage"
],
"name": "alibaba-chat/qwen-3-8-max-streams-minimal-effort",
"recordedAt": "2026-10-02T01:23:12.765Z"
"recordedAt": "2026-09-08T03:09:31.692Z"
},
"interactions": [
{
@@ -22,14 +22,14 @@
"headers": {
"content-type": "application/json"
},
"body": "{\"model\":\"qwen3.8-max\",\"messages\":[{\"role\":\"user\",\"content\":[{\"type\":\"text\",\"text\":\"What is 173 multiplied by 219? Reply with only the final integer.\",\"cache_control\":{\"type\":\"ephemeral\"}}]}],\"stream\":true,\"stream_options\":{\"include_usage\":true},\"reasoning_effort\":\"minimal\",\"max_completion_tokens\":4096}"
"body": "{\"model\":\"qwen3.8-max\",\"messages\":[{\"role\":\"user\",\"content\":\"What is 173 multiplied by 219? Reply with only the final integer.\"}],\"stream\":true,\"stream_options\":{\"include_usage\":true},\"reasoning_effort\":\"minimal\",\"max_completion_tokens\":4096}"
},
"response": {
"status": 200,
"headers": {
"content-type": "text/event-stream;charset=utf-8"
},
"body": "data: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-2f27f740-5237-9bd9-acc3-a877da5ab440\",\"created\":1790904189,\"object\":\"chat.completion.chunk\",\"usage\":null,\"choices\":[{\"logprobs\":null,\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\",\"reasoning_content\":\"\"},\"finish_reason\":null}]}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-2f27f740-5237-9bd9-acc3-a877da5ab440\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"Let\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904189,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-2f27f740-5237-9bd9-acc3-a877da5ab440\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" me calculate 1\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904189,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-2f27f740-5237-9bd9-acc3-a877da5ab440\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"73 × \"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904189,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-2f27f740-5237-9bd9-acc3-a877da5ab440\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"219.\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904189,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-2f27f740-5237-9bd9-acc3-a877da5ab440\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"\\n\\n173\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904189,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-2f27f740-5237-9bd9-acc3-a877da5ab440\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" × 21\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904189,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-2f27f740-5237-9bd9-acc3-a877da5ab440\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"9:\\n1\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904189,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-2f27f740-5237-9bd9-acc3-a877da5ab440\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"73\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904189,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-2f27f740-5237-9bd9-acc3-a877da5ab440\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" × 20\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904189,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-2f27f740-5237-9bd9-acc3-a877da5ab440\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"0 = 3\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904189,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-2f27f740-5237-9bd9-acc3-a877da5ab440\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"4,60\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904189,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-2f27f740-5237-9bd9-acc3-a877da5ab440\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"0\\n17\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904189,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-2f27f740-5237-9bd9-acc3-a877da5ab440\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"3 × 1\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904189,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-2f27f740-5237-9bd9-acc3-a877da5ab440\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"9 = 1\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904189,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-2f27f740-5237-9bd9-acc3-a877da5ab440\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"73 × \"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904189,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-2f27f740-5237-9bd9-acc3-a877da5ab440\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"20 - \"},\Line truncated
"body": "data: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-072fe561-8338-9cb0-b95c-7a4dea45151e\",\"created\":1788836967,\"object\":\"chat.completion.chunk\",\"usage\":null,\"choices\":[{\"logprobs\":null,\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\",\"reasoning_content\":\"\"},\"finish_reason\":null}]}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-072fe561-8338-9cb0-b95c-7a4dea45151e\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"Let\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836967,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-072fe561-8338-9cb0-b95c-7a4dea45151e\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" me calculate 1\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836967,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-072fe561-8338-9cb0-b95c-7a4dea45151e\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"73 × \"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836967,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-072fe561-8338-9cb0-b95c-7a4dea45151e\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"219.\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836967,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-072fe561-8338-9cb0-b95c-7a4dea45151e\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"\\n\\n173\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836967,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-072fe561-8338-9cb0-b95c-7a4dea45151e\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" × 21\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836967,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-072fe561-8338-9cb0-b95c-7a4dea45151e\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"9 = 1\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836967,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-072fe561-8338-9cb0-b95c-7a4dea45151e\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"73 × (\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836967,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-072fe561-8338-9cb0-b95c-7a4dea45151e\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"200 +\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836967,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-072fe561-8338-9cb0-b95c-7a4dea45151e\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" 19)\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836967,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-072fe561-8338-9cb0-b95c-7a4dea45151e\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"\\n= 1\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836967,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-072fe561-8338-9cb0-b95c-7a4dea45151e\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"73 × \"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836967,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-072fe561-8338-9cb0-b95c-7a4dea45151e\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"200 +\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836967,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-072fe561-8338-9cb0-b95c-7a4dea45151e\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" \"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836967,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-072fe561-8338-9cb0-b95c-7a4dea45151e\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\"173 ×\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836967,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-072fe561-8338-9cb0-b95c-7a4dea45151e\",\"choices\":[{\"delta\":{\"content\":\"\",\"reasoning_content\":\" 19\\n\"},\Line truncated
}
}
]
@@ -11,7 +11,7 @@
"usage"
],
"name": "alibaba-chat/qwen-3-8-max-streams-none-effort",
"recordedAt": "2026-10-02T01:23:09.451Z"
"recordedAt": "2026-09-08T03:09:27.584Z"
},
"interactions": [
{
@@ -22,14 +22,14 @@
"headers": {
"content-type": "application/json"
},
"body": "{\"model\":\"qwen3.8-max\",\"messages\":[{\"role\":\"user\",\"content\":[{\"type\":\"text\",\"text\":\"What is 173 multiplied by 219? Reply with only the final integer.\",\"cache_control\":{\"type\":\"ephemeral\"}}]}],\"stream\":true,\"stream_options\":{\"include_usage\":true},\"reasoning_effort\":\"none\",\"max_completion_tokens\":4096}"
"body": "{\"model\":\"qwen3.8-max\",\"messages\":[{\"role\":\"user\",\"content\":\"What is 173 multiplied by 219? Reply with only the final integer.\"}],\"stream\":true,\"stream_options\":{\"include_usage\":true},\"reasoning_effort\":\"none\",\"max_completion_tokens\":4096}"
},
"response": {
"status": 200,
"headers": {
"content-type": "text/event-stream;charset=utf-8"
},
"body": "data: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-57af8f93-1645-9a5f-8730-a0ba61a834df\",\"created\":1790904188,\"object\":\"chat.completion.chunk\",\"usage\":null,\"choices\":[{\"logprobs\":null,\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\"},\"finish_reason\":null}]}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-57af8f93-1645-9a5f-8730-a0ba61a834df\",\"choices\":[{\"delta\":{\"content\":\"3\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904188,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-57af8f93-1645-9a5f-8730-a0ba61a834df\",\"choices\":[{\"delta\":{\"content\":\"78\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904188,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-57af8f93-1645-9a5f-8730-a0ba61a834df\",\"choices\":[{\"delta\":{\"content\":\"87\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1790904188,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-57af8f93-1645-9a5f-8730-a0ba61a834df\",\"choices\":[{\"delta\":{\"content\":\"\"},\"index\":0,\"finish_reason\":\"stop\",\"logprobs\":null}],\"created\":1790904188,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"choices\":[],\"created\":1790904188,\"id\":\"chatcmpl-57af8f93-1645-9a5f-8730-a0ba61a834df\",\"model\":\"qwen3.8-max\",\"object\":\"chat.completion.chunk\",\"usage\":{\"completion_tokens\":5,\"prompt_tokens\":32,\"prompt_tokens_details\":{\"cache_creation\":{\"ephemeral_5m_input_tokens\":0},\"cache_creation_input_tokens\":0,\"cache_type\":\"ephemeral\",\"cache_write_tokens\":0,\"cached_tokens\":0,\"text_tokens\":32},\"total_tokens\":37}}\n\ndata: [DONE]\n\n"
"body": "data: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-d8fbc8fe-4d5a-9dc9-84c6-ed0c7b9dd3bb\",\"created\":1788836967,\"object\":\"chat.completion.chunk\",\"usage\":null,\"choices\":[{\"logprobs\":null,\"index\":0,\"delta\":{\"content\":\"\",\"role\":\"assistant\"},\"finish_reason\":null}]}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-d8fbc8fe-4d5a-9dc9-84c6-ed0c7b9dd3bb\",\"choices\":[{\"delta\":{\"content\":\"3\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836967,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-d8fbc8fe-4d5a-9dc9-84c6-ed0c7b9dd3bb\",\"choices\":[{\"delta\":{\"content\":\"78\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836967,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-d8fbc8fe-4d5a-9dc9-84c6-ed0c7b9dd3bb\",\"choices\":[{\"delta\":{\"content\":\"87\"},\"index\":0,\"finish_reason\":null,\"logprobs\":null}],\"created\":1788836967,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"model\":\"qwen3.8-max\",\"id\":\"chatcmpl-d8fbc8fe-4d5a-9dc9-84c6-ed0c7b9dd3bb\",\"choices\":[{\"delta\":{\"content\":\"\"},\"index\":0,\"finish_reason\":\"stop\",\"logprobs\":null}],\"created\":1788836967,\"object\":\"chat.completion.chunk\",\"usage\":null}\n\ndata: {\"choices\":[],\"created\":1788836967,\"id\":\"chatcmpl-d8fbc8fe-4d5a-9dc9-84c6-ed0c7b9dd3bb\",\"model\":\"qwen3.8-max\",\"object\":\"chat.completion.chunk\",\"usage\":{\"completion_tokens\":5,\"prompt_tokens\":32,\"prompt_tokens_details\":{\"cached_tokens\":0,\"text_tokens\":32},\"total_tokens\":37}}\n\ndata: [DONE]\n\n"
}
}
]
Loaded 100 of 1367 files, more files were not shown because too many files have changed in this diff. Show more