mirror of
https://github.com/sst/opencode.git
synced 2025-08-29 09:24:06 +00:00
This commit is contained in:
parent
7a67fe7dde
commit
0ce7d92a8b
4 changed files with 223 additions and 206 deletions
28
bun.lock
28
bun.lock
|
@ -13,7 +13,7 @@
|
||||||
},
|
},
|
||||||
"cloud/core": {
|
"cloud/core": {
|
||||||
"name": "@opencode/cloud-core",
|
"name": "@opencode/cloud-core",
|
||||||
"version": "0.4.18",
|
"version": "0.4.19",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@aws-sdk/client-sts": "3.782.0",
|
"@aws-sdk/client-sts": "3.782.0",
|
||||||
"drizzle-orm": "0.41.0",
|
"drizzle-orm": "0.41.0",
|
||||||
|
@ -27,7 +27,7 @@
|
||||||
},
|
},
|
||||||
"cloud/function": {
|
"cloud/function": {
|
||||||
"name": "@opencode/cloud-function",
|
"name": "@opencode/cloud-function",
|
||||||
"version": "0.4.18",
|
"version": "0.4.19",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ai-sdk/anthropic": "2.0.0",
|
"@ai-sdk/anthropic": "2.0.0",
|
||||||
"@ai-sdk/openai": "2.0.2",
|
"@ai-sdk/openai": "2.0.2",
|
||||||
|
@ -47,7 +47,7 @@
|
||||||
},
|
},
|
||||||
"cloud/web": {
|
"cloud/web": {
|
||||||
"name": "@opencode/cloud-web",
|
"name": "@opencode/cloud-web",
|
||||||
"version": "0.4.18",
|
"version": "0.4.19",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@kobalte/core": "0.13.9",
|
"@kobalte/core": "0.13.9",
|
||||||
"@openauthjs/solid": "0.0.0-20250322224806",
|
"@openauthjs/solid": "0.0.0-20250322224806",
|
||||||
|
@ -66,7 +66,7 @@
|
||||||
},
|
},
|
||||||
"packages/function": {
|
"packages/function": {
|
||||||
"name": "@opencode/function",
|
"name": "@opencode/function",
|
||||||
"version": "0.4.18",
|
"version": "0.4.19",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@octokit/auth-app": "8.0.1",
|
"@octokit/auth-app": "8.0.1",
|
||||||
"@octokit/rest": "22.0.0",
|
"@octokit/rest": "22.0.0",
|
||||||
|
@ -81,7 +81,7 @@
|
||||||
},
|
},
|
||||||
"packages/opencode": {
|
"packages/opencode": {
|
||||||
"name": "opencode",
|
"name": "opencode",
|
||||||
"version": "0.4.18",
|
"version": "0.4.19",
|
||||||
"bin": {
|
"bin": {
|
||||||
"opencode": "./bin/opencode",
|
"opencode": "./bin/opencode",
|
||||||
},
|
},
|
||||||
|
@ -133,7 +133,7 @@
|
||||||
},
|
},
|
||||||
"packages/plugin": {
|
"packages/plugin": {
|
||||||
"name": "@opencode-ai/plugin",
|
"name": "@opencode-ai/plugin",
|
||||||
"version": "0.4.18",
|
"version": "0.4.19",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@opencode-ai/sdk": "workspace:*",
|
"@opencode-ai/sdk": "workspace:*",
|
||||||
},
|
},
|
||||||
|
@ -145,7 +145,7 @@
|
||||||
},
|
},
|
||||||
"packages/sdk/js": {
|
"packages/sdk/js": {
|
||||||
"name": "@opencode-ai/sdk",
|
"name": "@opencode-ai/sdk",
|
||||||
"version": "0.4.18",
|
"version": "0.4.19",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@hey-api/openapi-ts": "0.80.1",
|
"@hey-api/openapi-ts": "0.80.1",
|
||||||
"@tsconfig/node22": "catalog:",
|
"@tsconfig/node22": "catalog:",
|
||||||
|
@ -154,9 +154,9 @@
|
||||||
},
|
},
|
||||||
"packages/web": {
|
"packages/web": {
|
||||||
"name": "@opencode/web",
|
"name": "@opencode/web",
|
||||||
"version": "0.4.18",
|
"version": "0.4.19",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/cloudflare": "^12.5.4",
|
"@astrojs/cloudflare": "12.6.3",
|
||||||
"@astrojs/markdown-remark": "6.3.1",
|
"@astrojs/markdown-remark": "6.3.1",
|
||||||
"@astrojs/solid-js": "5.1.0",
|
"@astrojs/solid-js": "5.1.0",
|
||||||
"@astrojs/starlight": "0.34.3",
|
"@astrojs/starlight": "0.34.3",
|
||||||
|
@ -229,11 +229,11 @@
|
||||||
|
|
||||||
"@apidevtools/json-schema-ref-parser": ["@apidevtools/json-schema-ref-parser@11.9.3", "", { "dependencies": { "@jsdevtools/ono": "^7.1.3", "@types/json-schema": "^7.0.15", "js-yaml": "^4.1.0" } }, "sha512-60vepv88RwcJtSHrD6MjIL6Ta3SOYbgfnkHb+ppAVK+o9mXprRtulx7VlRl3lN3bbvysAfCS7WMVfhUYemB0IQ=="],
|
"@apidevtools/json-schema-ref-parser": ["@apidevtools/json-schema-ref-parser@11.9.3", "", { "dependencies": { "@jsdevtools/ono": "^7.1.3", "@types/json-schema": "^7.0.15", "js-yaml": "^4.1.0" } }, "sha512-60vepv88RwcJtSHrD6MjIL6Ta3SOYbgfnkHb+ppAVK+o9mXprRtulx7VlRl3lN3bbvysAfCS7WMVfhUYemB0IQ=="],
|
||||||
|
|
||||||
"@astrojs/cloudflare": ["@astrojs/cloudflare@12.6.0", "", { "dependencies": { "@astrojs/internal-helpers": "0.6.1", "@astrojs/underscore-redirects": "1.0.0", "@cloudflare/workers-types": "^4.20250507.0", "tinyglobby": "^0.2.13", "vite": "^6.3.5", "wrangler": "^4.14.1" }, "peerDependencies": { "astro": "^5.0.0" } }, "sha512-pQ8bokC59GEiXvyXpC4swBNoL7C/EknP+82KFzQwgR/Aeo5N1oPiAoPHgJbpPya/YF4E26WODdCQfBQDvLRfuw=="],
|
"@astrojs/cloudflare": ["@astrojs/cloudflare@12.6.3", "", { "dependencies": { "@astrojs/internal-helpers": "0.7.1", "@astrojs/underscore-redirects": "1.0.0", "@cloudflare/workers-types": "^4.20250507.0", "tinyglobby": "^0.2.13", "vite": "^6.3.5", "wrangler": "^4.14.1" }, "peerDependencies": { "astro": "^5.0.0" } }, "sha512-xhJptF5tU2k5eo70nIMyL1Udma0CqmUEnGSlGyFflLqSY82CRQI6nWZ/xZt0ZvmXuErUjIx0YYQNfZsz5CNjLQ=="],
|
||||||
|
|
||||||
"@astrojs/compiler": ["@astrojs/compiler@2.12.2", "", {}, "sha512-w2zfvhjNCkNMmMMOn5b0J8+OmUaBL1o40ipMvqcG6NRpdC+lKxmTi48DT8Xw0SzJ3AfmeFLB45zXZXtmbsjcgw=="],
|
"@astrojs/compiler": ["@astrojs/compiler@2.12.2", "", {}, "sha512-w2zfvhjNCkNMmMMOn5b0J8+OmUaBL1o40ipMvqcG6NRpdC+lKxmTi48DT8Xw0SzJ3AfmeFLB45zXZXtmbsjcgw=="],
|
||||||
|
|
||||||
"@astrojs/internal-helpers": ["@astrojs/internal-helpers@0.6.1", "", {}, "sha512-l5Pqf6uZu31aG+3Lv8nl/3s4DbUzdlxTWDof4pEpto6GUJNhhCbelVi9dEyurOVyqaelwmS9oSyOWOENSfgo9A=="],
|
"@astrojs/internal-helpers": ["@astrojs/internal-helpers@0.7.1", "", {}, "sha512-7dwEVigz9vUWDw3nRwLQ/yH/xYovlUA0ZD86xoeKEBmkz9O6iELG1yri67PgAPW6VLL/xInA4t7H0CK6VmtkKQ=="],
|
||||||
|
|
||||||
"@astrojs/markdown-remark": ["@astrojs/markdown-remark@6.3.1", "", { "dependencies": { "@astrojs/internal-helpers": "0.6.1", "@astrojs/prism": "3.2.0", "github-slugger": "^2.0.0", "hast-util-from-html": "^2.0.3", "hast-util-to-text": "^4.0.2", "import-meta-resolve": "^4.1.0", "js-yaml": "^4.1.0", "mdast-util-definitions": "^6.0.0", "rehype-raw": "^7.0.0", "rehype-stringify": "^10.0.1", "remark-gfm": "^4.0.1", "remark-parse": "^11.0.0", "remark-rehype": "^11.1.1", "remark-smartypants": "^3.0.2", "shiki": "^3.0.0", "smol-toml": "^1.3.1", "unified": "^11.0.5", "unist-util-remove-position": "^5.0.0", "unist-util-visit": "^5.0.0", "unist-util-visit-parents": "^6.0.1", "vfile": "^6.0.3" } }, "sha512-c5F5gGrkczUaTVgmMW9g1YMJGzOtRvjjhw6IfGuxarM6ct09MpwysP10US729dy07gg8y+ofVifezvP3BNsWZg=="],
|
"@astrojs/markdown-remark": ["@astrojs/markdown-remark@6.3.1", "", { "dependencies": { "@astrojs/internal-helpers": "0.6.1", "@astrojs/prism": "3.2.0", "github-slugger": "^2.0.0", "hast-util-from-html": "^2.0.3", "hast-util-to-text": "^4.0.2", "import-meta-resolve": "^4.1.0", "js-yaml": "^4.1.0", "mdast-util-definitions": "^6.0.0", "rehype-raw": "^7.0.0", "rehype-stringify": "^10.0.1", "remark-gfm": "^4.0.1", "remark-parse": "^11.0.0", "remark-rehype": "^11.1.1", "remark-smartypants": "^3.0.2", "shiki": "^3.0.0", "smol-toml": "^1.3.1", "unified": "^11.0.5", "unist-util-remove-position": "^5.0.0", "unist-util-visit": "^5.0.0", "unist-util-visit-parents": "^6.0.1", "vfile": "^6.0.3" } }, "sha512-c5F5gGrkczUaTVgmMW9g1YMJGzOtRvjjhw6IfGuxarM6ct09MpwysP10US729dy07gg8y+ofVifezvP3BNsWZg=="],
|
||||||
|
|
||||||
|
@ -2569,6 +2569,8 @@
|
||||||
|
|
||||||
"@astrojs/cloudflare/vite": ["vite@6.3.5", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "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-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ=="],
|
"@astrojs/cloudflare/vite": ["vite@6.3.5", "", { "dependencies": { "esbuild": "^0.25.0", "fdir": "^6.4.4", "picomatch": "^4.0.2", "postcss": "^8.5.3", "rollup": "^4.34.9", "tinyglobby": "^0.2.13" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "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-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ=="],
|
||||||
|
|
||||||
|
"@astrojs/markdown-remark/@astrojs/internal-helpers": ["@astrojs/internal-helpers@0.6.1", "", {}, "sha512-l5Pqf6uZu31aG+3Lv8nl/3s4DbUzdlxTWDof4pEpto6GUJNhhCbelVi9dEyurOVyqaelwmS9oSyOWOENSfgo9A=="],
|
||||||
|
|
||||||
"@astrojs/mdx/@astrojs/markdown-remark": ["@astrojs/markdown-remark@6.3.3", "", { "dependencies": { "@astrojs/internal-helpers": "0.6.1", "@astrojs/prism": "3.3.0", "github-slugger": "^2.0.0", "hast-util-from-html": "^2.0.3", "hast-util-to-text": "^4.0.2", "import-meta-resolve": "^4.1.0", "js-yaml": "^4.1.0", "mdast-util-definitions": "^6.0.0", "rehype-raw": "^7.0.0", "rehype-stringify": "^10.0.1", "remark-gfm": "^4.0.1", "remark-parse": "^11.0.0", "remark-rehype": "^11.1.2", "remark-smartypants": "^3.0.2", "shiki": "^3.2.1", "smol-toml": "^1.3.4", "unified": "^11.0.5", "unist-util-remove-position": "^5.0.0", "unist-util-visit": "^5.0.0", "unist-util-visit-parents": "^6.0.1", "vfile": "^6.0.3" } }, "sha512-DDRtD1sPvAuA7ms2btc9A7/7DApKqgLMNrE6kh5tmkfy8utD0Z738gqd3p5aViYYdUtHIyEJ1X4mCMxfCfu15w=="],
|
"@astrojs/mdx/@astrojs/markdown-remark": ["@astrojs/markdown-remark@6.3.3", "", { "dependencies": { "@astrojs/internal-helpers": "0.6.1", "@astrojs/prism": "3.3.0", "github-slugger": "^2.0.0", "hast-util-from-html": "^2.0.3", "hast-util-to-text": "^4.0.2", "import-meta-resolve": "^4.1.0", "js-yaml": "^4.1.0", "mdast-util-definitions": "^6.0.0", "rehype-raw": "^7.0.0", "rehype-stringify": "^10.0.1", "remark-gfm": "^4.0.1", "remark-parse": "^11.0.0", "remark-rehype": "^11.1.2", "remark-smartypants": "^3.0.2", "shiki": "^3.2.1", "smol-toml": "^1.3.4", "unified": "^11.0.5", "unist-util-remove-position": "^5.0.0", "unist-util-visit": "^5.0.0", "unist-util-visit-parents": "^6.0.1", "vfile": "^6.0.3" } }, "sha512-DDRtD1sPvAuA7ms2btc9A7/7DApKqgLMNrE6kh5tmkfy8utD0Z738gqd3p5aViYYdUtHIyEJ1X4mCMxfCfu15w=="],
|
||||||
|
|
||||||
"@astrojs/mdx/source-map": ["source-map@0.7.6", "", {}, "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ=="],
|
"@astrojs/mdx/source-map": ["source-map@0.7.6", "", {}, "sha512-i5uvt8C3ikiWeNZSVZNWcfZPItFQOsYTUAOkcUPGd8DqDy1uOUikjt5dG+uRlwyvR108Fb9DOd4GvXfT0N2/uQ=="],
|
||||||
|
@ -2757,6 +2759,8 @@
|
||||||
|
|
||||||
"anymatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
|
"anymatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
|
||||||
|
|
||||||
|
"astro/@astrojs/internal-helpers": ["@astrojs/internal-helpers@0.6.1", "", {}, "sha512-l5Pqf6uZu31aG+3Lv8nl/3s4DbUzdlxTWDof4pEpto6GUJNhhCbelVi9dEyurOVyqaelwmS9oSyOWOENSfgo9A=="],
|
||||||
|
|
||||||
"astro/diff": ["diff@5.2.0", "", {}, "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A=="],
|
"astro/diff": ["diff@5.2.0", "", {}, "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A=="],
|
||||||
|
|
||||||
"astro/esbuild": ["esbuild@0.25.8", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.8", "@esbuild/android-arm": "0.25.8", "@esbuild/android-arm64": "0.25.8", "@esbuild/android-x64": "0.25.8", "@esbuild/darwin-arm64": "0.25.8", "@esbuild/darwin-x64": "0.25.8", "@esbuild/freebsd-arm64": "0.25.8", "@esbuild/freebsd-x64": "0.25.8", "@esbuild/linux-arm": "0.25.8", "@esbuild/linux-arm64": "0.25.8", "@esbuild/linux-ia32": "0.25.8", "@esbuild/linux-loong64": "0.25.8", "@esbuild/linux-mips64el": "0.25.8", "@esbuild/linux-ppc64": "0.25.8", "@esbuild/linux-riscv64": "0.25.8", "@esbuild/linux-s390x": "0.25.8", "@esbuild/linux-x64": "0.25.8", "@esbuild/netbsd-arm64": "0.25.8", "@esbuild/netbsd-x64": "0.25.8", "@esbuild/openbsd-arm64": "0.25.8", "@esbuild/openbsd-x64": "0.25.8", "@esbuild/openharmony-arm64": "0.25.8", "@esbuild/sunos-x64": "0.25.8", "@esbuild/win32-arm64": "0.25.8", "@esbuild/win32-ia32": "0.25.8", "@esbuild/win32-x64": "0.25.8" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-vVC0USHGtMi8+R4Kz8rt6JhEWLxsv9Rnu/lGYbPR8u47B+DCBksq9JarW0zOO7bs37hyOK1l2/oqtbciutL5+Q=="],
|
"astro/esbuild": ["esbuild@0.25.8", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.8", "@esbuild/android-arm": "0.25.8", "@esbuild/android-arm64": "0.25.8", "@esbuild/android-x64": "0.25.8", "@esbuild/darwin-arm64": "0.25.8", "@esbuild/darwin-x64": "0.25.8", "@esbuild/freebsd-arm64": "0.25.8", "@esbuild/freebsd-x64": "0.25.8", "@esbuild/linux-arm": "0.25.8", "@esbuild/linux-arm64": "0.25.8", "@esbuild/linux-ia32": "0.25.8", "@esbuild/linux-loong64": "0.25.8", "@esbuild/linux-mips64el": "0.25.8", "@esbuild/linux-ppc64": "0.25.8", "@esbuild/linux-riscv64": "0.25.8", "@esbuild/linux-s390x": "0.25.8", "@esbuild/linux-x64": "0.25.8", "@esbuild/netbsd-arm64": "0.25.8", "@esbuild/netbsd-x64": "0.25.8", "@esbuild/openbsd-arm64": "0.25.8", "@esbuild/openbsd-x64": "0.25.8", "@esbuild/openharmony-arm64": "0.25.8", "@esbuild/sunos-x64": "0.25.8", "@esbuild/win32-arm64": "0.25.8", "@esbuild/win32-ia32": "0.25.8", "@esbuild/win32-x64": "0.25.8" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-vVC0USHGtMi8+R4Kz8rt6JhEWLxsv9Rnu/lGYbPR8u47B+DCBksq9JarW0zOO7bs37hyOK1l2/oqtbciutL5+Q=="],
|
||||||
|
@ -2933,6 +2937,8 @@
|
||||||
|
|
||||||
"@astrojs/cloudflare/vite/esbuild": ["esbuild@0.25.8", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.8", "@esbuild/android-arm": "0.25.8", "@esbuild/android-arm64": "0.25.8", "@esbuild/android-x64": "0.25.8", "@esbuild/darwin-arm64": "0.25.8", "@esbuild/darwin-x64": "0.25.8", "@esbuild/freebsd-arm64": "0.25.8", "@esbuild/freebsd-x64": "0.25.8", "@esbuild/linux-arm": "0.25.8", "@esbuild/linux-arm64": "0.25.8", "@esbuild/linux-ia32": "0.25.8", "@esbuild/linux-loong64": "0.25.8", "@esbuild/linux-mips64el": "0.25.8", "@esbuild/linux-ppc64": "0.25.8", "@esbuild/linux-riscv64": "0.25.8", "@esbuild/linux-s390x": "0.25.8", "@esbuild/linux-x64": "0.25.8", "@esbuild/netbsd-arm64": "0.25.8", "@esbuild/netbsd-x64": "0.25.8", "@esbuild/openbsd-arm64": "0.25.8", "@esbuild/openbsd-x64": "0.25.8", "@esbuild/openharmony-arm64": "0.25.8", "@esbuild/sunos-x64": "0.25.8", "@esbuild/win32-arm64": "0.25.8", "@esbuild/win32-ia32": "0.25.8", "@esbuild/win32-x64": "0.25.8" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-vVC0USHGtMi8+R4Kz8rt6JhEWLxsv9Rnu/lGYbPR8u47B+DCBksq9JarW0zOO7bs37hyOK1l2/oqtbciutL5+Q=="],
|
"@astrojs/cloudflare/vite/esbuild": ["esbuild@0.25.8", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.8", "@esbuild/android-arm": "0.25.8", "@esbuild/android-arm64": "0.25.8", "@esbuild/android-x64": "0.25.8", "@esbuild/darwin-arm64": "0.25.8", "@esbuild/darwin-x64": "0.25.8", "@esbuild/freebsd-arm64": "0.25.8", "@esbuild/freebsd-x64": "0.25.8", "@esbuild/linux-arm": "0.25.8", "@esbuild/linux-arm64": "0.25.8", "@esbuild/linux-ia32": "0.25.8", "@esbuild/linux-loong64": "0.25.8", "@esbuild/linux-mips64el": "0.25.8", "@esbuild/linux-ppc64": "0.25.8", "@esbuild/linux-riscv64": "0.25.8", "@esbuild/linux-s390x": "0.25.8", "@esbuild/linux-x64": "0.25.8", "@esbuild/netbsd-arm64": "0.25.8", "@esbuild/netbsd-x64": "0.25.8", "@esbuild/openbsd-arm64": "0.25.8", "@esbuild/openbsd-x64": "0.25.8", "@esbuild/openharmony-arm64": "0.25.8", "@esbuild/sunos-x64": "0.25.8", "@esbuild/win32-arm64": "0.25.8", "@esbuild/win32-ia32": "0.25.8", "@esbuild/win32-x64": "0.25.8" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-vVC0USHGtMi8+R4Kz8rt6JhEWLxsv9Rnu/lGYbPR8u47B+DCBksq9JarW0zOO7bs37hyOK1l2/oqtbciutL5+Q=="],
|
||||||
|
|
||||||
|
"@astrojs/mdx/@astrojs/markdown-remark/@astrojs/internal-helpers": ["@astrojs/internal-helpers@0.6.1", "", {}, "sha512-l5Pqf6uZu31aG+3Lv8nl/3s4DbUzdlxTWDof4pEpto6GUJNhhCbelVi9dEyurOVyqaelwmS9oSyOWOENSfgo9A=="],
|
||||||
|
|
||||||
"@astrojs/mdx/@astrojs/markdown-remark/@astrojs/prism": ["@astrojs/prism@3.3.0", "", { "dependencies": { "prismjs": "^1.30.0" } }, "sha512-q8VwfU/fDZNoDOf+r7jUnMC2//H2l0TuQ6FkGJL8vD8nw/q5KiL3DS1KKBI3QhI9UQhpJ5dc7AtqfbXWuOgLCQ=="],
|
"@astrojs/mdx/@astrojs/markdown-remark/@astrojs/prism": ["@astrojs/prism@3.3.0", "", { "dependencies": { "prismjs": "^1.30.0" } }, "sha512-q8VwfU/fDZNoDOf+r7jUnMC2//H2l0TuQ6FkGJL8vD8nw/q5KiL3DS1KKBI3QhI9UQhpJ5dc7AtqfbXWuOgLCQ=="],
|
||||||
|
|
||||||
"@astrojs/solid-js/vite/esbuild": ["esbuild@0.25.8", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.8", "@esbuild/android-arm": "0.25.8", "@esbuild/android-arm64": "0.25.8", "@esbuild/android-x64": "0.25.8", "@esbuild/darwin-arm64": "0.25.8", "@esbuild/darwin-x64": "0.25.8", "@esbuild/freebsd-arm64": "0.25.8", "@esbuild/freebsd-x64": "0.25.8", "@esbuild/linux-arm": "0.25.8", "@esbuild/linux-arm64": "0.25.8", "@esbuild/linux-ia32": "0.25.8", "@esbuild/linux-loong64": "0.25.8", "@esbuild/linux-mips64el": "0.25.8", "@esbuild/linux-ppc64": "0.25.8", "@esbuild/linux-riscv64": "0.25.8", "@esbuild/linux-s390x": "0.25.8", "@esbuild/linux-x64": "0.25.8", "@esbuild/netbsd-arm64": "0.25.8", "@esbuild/netbsd-x64": "0.25.8", "@esbuild/openbsd-arm64": "0.25.8", "@esbuild/openbsd-x64": "0.25.8", "@esbuild/openharmony-arm64": "0.25.8", "@esbuild/sunos-x64": "0.25.8", "@esbuild/win32-arm64": "0.25.8", "@esbuild/win32-ia32": "0.25.8", "@esbuild/win32-x64": "0.25.8" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-vVC0USHGtMi8+R4Kz8rt6JhEWLxsv9Rnu/lGYbPR8u47B+DCBksq9JarW0zOO7bs37hyOK1l2/oqtbciutL5+Q=="],
|
"@astrojs/solid-js/vite/esbuild": ["esbuild@0.25.8", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.8", "@esbuild/android-arm": "0.25.8", "@esbuild/android-arm64": "0.25.8", "@esbuild/android-x64": "0.25.8", "@esbuild/darwin-arm64": "0.25.8", "@esbuild/darwin-x64": "0.25.8", "@esbuild/freebsd-arm64": "0.25.8", "@esbuild/freebsd-x64": "0.25.8", "@esbuild/linux-arm": "0.25.8", "@esbuild/linux-arm64": "0.25.8", "@esbuild/linux-ia32": "0.25.8", "@esbuild/linux-loong64": "0.25.8", "@esbuild/linux-mips64el": "0.25.8", "@esbuild/linux-ppc64": "0.25.8", "@esbuild/linux-riscv64": "0.25.8", "@esbuild/linux-s390x": "0.25.8", "@esbuild/linux-x64": "0.25.8", "@esbuild/netbsd-arm64": "0.25.8", "@esbuild/netbsd-x64": "0.25.8", "@esbuild/openbsd-arm64": "0.25.8", "@esbuild/openbsd-x64": "0.25.8", "@esbuild/openharmony-arm64": "0.25.8", "@esbuild/sunos-x64": "0.25.8", "@esbuild/win32-arm64": "0.25.8", "@esbuild/win32-ia32": "0.25.8", "@esbuild/win32-x64": "0.25.8" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-vVC0USHGtMi8+R4Kz8rt6JhEWLxsv9Rnu/lGYbPR8u47B+DCBksq9JarW0zOO7bs37hyOK1l2/oqtbciutL5+Q=="],
|
||||||
|
|
|
@ -448,7 +448,7 @@ export namespace Provider {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const priority = ["gemini-2.5-pro-preview", "codex-mini", "claude-sonnet-4"]
|
const priority = ["gemini-2.5-pro-preview", "gpt-5", "claude-sonnet-4"]
|
||||||
export function sort(models: ModelsDev.Model[]) {
|
export function sort(models: ModelsDev.Model[]) {
|
||||||
return sortBy(
|
return sortBy(
|
||||||
models,
|
models,
|
||||||
|
|
|
@ -11,7 +11,7 @@
|
||||||
"astro": "astro"
|
"astro": "astro"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@astrojs/cloudflare": "^12.5.4",
|
"@astrojs/cloudflare": "12.6.3",
|
||||||
"@astrojs/markdown-remark": "6.3.1",
|
"@astrojs/markdown-remark": "6.3.1",
|
||||||
"@astrojs/solid-js": "5.1.0",
|
"@astrojs/solid-js": "5.1.0",
|
||||||
"@astrojs/starlight": "0.34.3",
|
"@astrojs/starlight": "0.34.3",
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import { For, Show, onMount, Suspense, onCleanup, createMemo, createSignal, SuspenseList, createEffect } from "solid-js"
|
import { For, Show, onMount, Suspense, onCleanup, createMemo, createSignal, SuspenseList, createEffect } from "solid-js"
|
||||||
import { DateTime } from "luxon"
|
import { DateTime } from "luxon"
|
||||||
import { createStore, reconcile, unwrap } from "solid-js/store"
|
import { createStore, reconcile, unwrap } from "solid-js/store"
|
||||||
import { mapValues } from "remeda"
|
|
||||||
import { IconArrowDown } from "./icons"
|
import { IconArrowDown } from "./icons"
|
||||||
import { IconOpencode } from "./icons/custom"
|
import { IconOpencode } from "./icons/custom"
|
||||||
import styles from "./share.module.css"
|
import styles from "./share.module.css"
|
||||||
|
@ -42,7 +41,6 @@ export default function Share(props: {
|
||||||
id: string
|
id: string
|
||||||
api: string
|
api: string
|
||||||
info: Session.Info
|
info: Session.Info
|
||||||
messages: Record<string, MessageWithParts>
|
|
||||||
}) {
|
}) {
|
||||||
let lastScrollY = 0
|
let lastScrollY = 0
|
||||||
let hasScrolledToAnchor = false
|
let hasScrolledToAnchor = false
|
||||||
|
@ -50,7 +48,6 @@ export default function Share(props: {
|
||||||
let scrollSentinel: HTMLElement | undefined
|
let scrollSentinel: HTMLElement | undefined
|
||||||
let scrollObserver: IntersectionObserver | undefined
|
let scrollObserver: IntersectionObserver | undefined
|
||||||
|
|
||||||
const id = props.id
|
|
||||||
const params = new URLSearchParams(window.location.search)
|
const params = new URLSearchParams(window.location.search)
|
||||||
const debug = params.get("debug") === "true"
|
const debug = params.get("debug") === "true"
|
||||||
|
|
||||||
|
@ -61,17 +58,27 @@ export default function Share(props: {
|
||||||
const [store, setStore] = createStore<{
|
const [store, setStore] = createStore<{
|
||||||
info?: Session.Info
|
info?: Session.Info
|
||||||
messages: Record<string, MessageWithParts>
|
messages: Record<string, MessageWithParts>
|
||||||
}>({ info: props.info, messages: {} })
|
}>({
|
||||||
|
info: {
|
||||||
|
id: props.id,
|
||||||
|
title: props.info.title,
|
||||||
|
version: props.info.version,
|
||||||
|
time: {
|
||||||
|
created: props.info.time.created,
|
||||||
|
updated: props.info.time.updated,
|
||||||
|
},
|
||||||
|
}, messages: {}
|
||||||
|
})
|
||||||
const messages = createMemo(() => Object.values(store.messages).toSorted((a, b) => a.id?.localeCompare(b.id)))
|
const messages = createMemo(() => Object.values(store.messages).toSorted((a, b) => a.id?.localeCompare(b.id)))
|
||||||
const [connectionStatus, setConnectionStatus] = createSignal<[Status, string?]>(["disconnected", "Disconnected"])
|
const [connectionStatus, setConnectionStatus] = createSignal<[Status, string?]>(["disconnected", "Disconnected"])
|
||||||
// createEffect(() => {
|
createEffect(() => {
|
||||||
// console.log(unwrap(store))
|
console.log(unwrap(store))
|
||||||
// })
|
})
|
||||||
|
|
||||||
onMount(() => {
|
onMount(() => {
|
||||||
const apiUrl = props.api
|
const apiUrl = props.api
|
||||||
|
|
||||||
if (!id) {
|
if (!props.id) {
|
||||||
setConnectionStatus(["error", "id not found"])
|
setConnectionStatus(["error", "id not found"])
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -96,7 +103,7 @@ export default function Share(props: {
|
||||||
|
|
||||||
// Always use secure WebSocket protocol (wss)
|
// Always use secure WebSocket protocol (wss)
|
||||||
const wsBaseUrl = apiUrl.replace(/^https?:\/\//, "wss://")
|
const wsBaseUrl = apiUrl.replace(/^https?:\/\//, "wss://")
|
||||||
const wsUrl = `${wsBaseUrl}/share_poll?id=${id}`
|
const wsUrl = `${wsBaseUrl}/share_poll?id=${props.id}`
|
||||||
console.log("Connecting to WebSocket URL:", wsUrl)
|
console.log("Connecting to WebSocket URL:", wsUrl)
|
||||||
|
|
||||||
// Create WebSocket connection
|
// Create WebSocket connection
|
||||||
|
@ -261,7 +268,9 @@ export default function Share(props: {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
result.created = props.info.time.created
|
if (!store.info) return result
|
||||||
|
|
||||||
|
result.created = store.info.time.created
|
||||||
|
|
||||||
const msgs = messages()
|
const msgs = messages()
|
||||||
for (let i = 0; i < msgs.length; i++) {
|
for (let i = 0; i < msgs.length; i++) {
|
||||||
|
@ -290,197 +299,199 @@ export default function Share(props: {
|
||||||
})
|
})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<main classList={{ [styles.root]: true, "not-content": true }}>
|
<Show when={store.info}>
|
||||||
<div data-component="header">
|
<main classList={{ [styles.root]: true, "not-content": true }}>
|
||||||
<h1 data-component="header-title">{store.info?.title}</h1>
|
<div data-component="header">
|
||||||
<div data-component="header-details">
|
<h1 data-component="header-title">{store.info?.title}</h1>
|
||||||
<ul data-component="header-stats">
|
<div data-component="header-details">
|
||||||
<li title="opencode version" data-slot="item">
|
<ul data-component="header-stats">
|
||||||
<div data-slot="icon" title="opencode">
|
<li title="opencode version" data-slot="item">
|
||||||
<IconOpencode width={16} height={16} />
|
<div data-slot="icon" title="opencode">
|
||||||
</div>
|
<IconOpencode width={16} height={16} />
|
||||||
<Show when={store.info?.version} fallback="v0.0.1">
|
</div>
|
||||||
<span>v{store.info?.version}</span>
|
<Show when={store.info?.version} fallback="v0.0.1">
|
||||||
</Show>
|
<span>v{store.info?.version}</span>
|
||||||
</li>
|
</Show>
|
||||||
{Object.values(data().models).length > 0 ? (
|
|
||||||
<For each={Object.values(data().models)}>
|
|
||||||
{([provider, model]) => (
|
|
||||||
<li data-slot="item">
|
|
||||||
<div data-slot="icon" title={provider}>
|
|
||||||
<ProviderIcon model={model} />
|
|
||||||
</div>
|
|
||||||
<span data-slot="model">{model}</span>
|
|
||||||
</li>
|
|
||||||
)}
|
|
||||||
</For>
|
|
||||||
) : (
|
|
||||||
<li>
|
|
||||||
<span data-element-label>Models</span>
|
|
||||||
<span data-placeholder>—</span>
|
|
||||||
</li>
|
</li>
|
||||||
)}
|
{Object.values(data().models).length > 0 ? (
|
||||||
</ul>
|
<For each={Object.values(data().models)}>
|
||||||
<div
|
{([provider, model]) => (
|
||||||
data-component="header-time"
|
<li data-slot="item">
|
||||||
title={DateTime.fromMillis(data().created || 0).toLocaleString(DateTime.DATETIME_FULL_WITH_SECONDS)}
|
<div data-slot="icon" title={provider}>
|
||||||
>
|
<ProviderIcon model={model} />
|
||||||
{DateTime.fromMillis(data().created || 0).toLocaleString(DateTime.DATETIME_MED)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<Show when={data().messages.length > 0} fallback={<p>Waiting for messages...</p>}>
|
|
||||||
<div class={styles.parts}>
|
|
||||||
<SuspenseList revealOrder="forwards">
|
|
||||||
<For each={data().messages}>
|
|
||||||
{(msg, msgIndex) => {
|
|
||||||
const filteredParts = createMemo(() =>
|
|
||||||
msg.parts.filter((x, index) => {
|
|
||||||
if (x.type === "step-start" && index > 0) return false
|
|
||||||
if (x.type === "snapshot") return false
|
|
||||||
if (x.type === "patch") return false
|
|
||||||
if (x.type === "step-finish") return false
|
|
||||||
if (x.type === "text" && x.synthetic === true) return false
|
|
||||||
if (x.type === "tool" && x.tool === "todoread") return false
|
|
||||||
if (x.type === "text" && !x.text) return false
|
|
||||||
if (x.type === "tool" && (x.state.status === "pending" || x.state.status === "running"))
|
|
||||||
return false
|
|
||||||
return true
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Suspense>
|
|
||||||
<For each={filteredParts()}>
|
|
||||||
{(part, partIndex) => {
|
|
||||||
const last = createMemo(
|
|
||||||
() =>
|
|
||||||
data().messages.length === msgIndex() + 1 && filteredParts().length === partIndex() + 1,
|
|
||||||
)
|
|
||||||
|
|
||||||
onMount(() => {
|
|
||||||
const hash = window.location.hash.slice(1)
|
|
||||||
// Wait till all parts are loaded
|
|
||||||
if (
|
|
||||||
hash !== "" &&
|
|
||||||
!hasScrolledToAnchor &&
|
|
||||||
filteredParts().length === partIndex() + 1 &&
|
|
||||||
data().messages.length === msgIndex() + 1
|
|
||||||
) {
|
|
||||||
hasScrolledToAnchor = true
|
|
||||||
scrollToAnchor(hash)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return <Part last={last()} part={part} index={partIndex()} message={msg} />
|
|
||||||
}}
|
|
||||||
</For>
|
|
||||||
</Suspense>
|
|
||||||
)
|
|
||||||
}}
|
|
||||||
</For>
|
|
||||||
</SuspenseList>
|
|
||||||
<div data-section="part" data-part-type="summary">
|
|
||||||
<div data-section="decoration">
|
|
||||||
<span data-status={connectionStatus()[0]}></span>
|
|
||||||
</div>
|
|
||||||
<div data-section="content">
|
|
||||||
<p data-section="copy">{getStatusText(connectionStatus())}</p>
|
|
||||||
<ul data-section="stats">
|
|
||||||
<li>
|
|
||||||
<span data-element-label>Cost</span>
|
|
||||||
{data().cost !== undefined ? (
|
|
||||||
<span>${data().cost.toFixed(2)}</span>
|
|
||||||
) : (
|
|
||||||
<span data-placeholder>—</span>
|
|
||||||
)}
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<span data-element-label>Input Tokens</span>
|
|
||||||
{data().tokens.input ? <span>{data().tokens.input}</span> : <span data-placeholder>—</span>}
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<span data-element-label>Output Tokens</span>
|
|
||||||
{data().tokens.output ? <span>{data().tokens.output}</span> : <span data-placeholder>—</span>}
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<span data-element-label>Reasoning Tokens</span>
|
|
||||||
{data().tokens.reasoning ? (
|
|
||||||
<span>{data().tokens.reasoning}</span>
|
|
||||||
) : (
|
|
||||||
<span data-placeholder>—</span>
|
|
||||||
)}
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</Show>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<Show when={debug}>
|
|
||||||
<div style={{ margin: "2rem 0" }}>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
border: "1px solid #ccc",
|
|
||||||
padding: "1rem",
|
|
||||||
"overflow-y": "auto",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<Show when={data().messages.length > 0} fallback={<p>Waiting for messages...</p>}>
|
|
||||||
<ul style={{ "list-style-type": "none", padding: 0 }}>
|
|
||||||
<For each={data().messages}>
|
|
||||||
{(msg) => (
|
|
||||||
<li
|
|
||||||
style={{
|
|
||||||
padding: "0.75rem",
|
|
||||||
margin: "0.75rem 0",
|
|
||||||
"box-shadow": "0 1px 3px rgba(0,0,0,0.1)",
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div>
|
|
||||||
<strong>Key:</strong> {msg.id}
|
|
||||||
</div>
|
</div>
|
||||||
<pre>{JSON.stringify(msg, null, 2)}</pre>
|
<span data-slot="model">{model}</span>
|
||||||
</li>
|
</li>
|
||||||
)}
|
)}
|
||||||
</For>
|
</For>
|
||||||
</ul>
|
) : (
|
||||||
</Show>
|
<li>
|
||||||
|
<span data-element-label>Models</span>
|
||||||
|
<span data-placeholder>—</span>
|
||||||
|
</li>
|
||||||
|
)}
|
||||||
|
</ul>
|
||||||
|
<div
|
||||||
|
data-component="header-time"
|
||||||
|
title={DateTime.fromMillis(data().created || 0).toLocaleString(DateTime.DATETIME_FULL_WITH_SECONDS)}
|
||||||
|
>
|
||||||
|
{DateTime.fromMillis(data().created || 0).toLocaleString(DateTime.DATETIME_MED)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Show>
|
|
||||||
|
|
||||||
<Show when={showScrollButton()}>
|
<div>
|
||||||
<button
|
<Show when={data().messages.length > 0} fallback={<p>Waiting for messages...</p>}>
|
||||||
type="button"
|
<div class={styles.parts}>
|
||||||
class={styles["scroll-button"]}
|
<SuspenseList revealOrder="forwards">
|
||||||
onClick={() => document.body.scrollIntoView({ behavior: "smooth", block: "end" })}
|
<For each={data().messages}>
|
||||||
onMouseEnter={() => {
|
{(msg, msgIndex) => {
|
||||||
setIsButtonHovered(true)
|
const filteredParts = createMemo(() =>
|
||||||
if (scrollTimeout) {
|
msg.parts.filter((x, index) => {
|
||||||
clearTimeout(scrollTimeout)
|
if (x.type === "step-start" && index > 0) return false
|
||||||
}
|
if (x.type === "snapshot") return false
|
||||||
}}
|
if (x.type === "patch") return false
|
||||||
onMouseLeave={() => {
|
if (x.type === "step-finish") return false
|
||||||
setIsButtonHovered(false)
|
if (x.type === "text" && x.synthetic === true) return false
|
||||||
if (showScrollButton()) {
|
if (x.type === "tool" && x.tool === "todoread") return false
|
||||||
scrollTimeout = window.setTimeout(() => {
|
if (x.type === "text" && !x.text) return false
|
||||||
if (!isButtonHovered()) {
|
if (x.type === "tool" && (x.state.status === "pending" || x.state.status === "running"))
|
||||||
setShowScrollButton(false)
|
return false
|
||||||
}
|
return true
|
||||||
}, 3000)
|
}),
|
||||||
}
|
)
|
||||||
}}
|
|
||||||
title="Scroll to bottom"
|
return (
|
||||||
aria-label="Scroll to bottom"
|
<Suspense>
|
||||||
>
|
<For each={filteredParts()}>
|
||||||
<IconArrowDown width={20} height={20} />
|
{(part, partIndex) => {
|
||||||
</button>
|
const last = createMemo(
|
||||||
</Show>
|
() =>
|
||||||
</main>
|
data().messages.length === msgIndex() + 1 && filteredParts().length === partIndex() + 1,
|
||||||
|
)
|
||||||
|
|
||||||
|
onMount(() => {
|
||||||
|
const hash = window.location.hash.slice(1)
|
||||||
|
// Wait till all parts are loaded
|
||||||
|
if (
|
||||||
|
hash !== "" &&
|
||||||
|
!hasScrolledToAnchor &&
|
||||||
|
filteredParts().length === partIndex() + 1 &&
|
||||||
|
data().messages.length === msgIndex() + 1
|
||||||
|
) {
|
||||||
|
hasScrolledToAnchor = true
|
||||||
|
scrollToAnchor(hash)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
return <Part last={last()} part={part} index={partIndex()} message={msg} />
|
||||||
|
}}
|
||||||
|
</For>
|
||||||
|
</Suspense>
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
</For>
|
||||||
|
</SuspenseList>
|
||||||
|
<div data-section="part" data-part-type="summary">
|
||||||
|
<div data-section="decoration">
|
||||||
|
<span data-status={connectionStatus()[0]}></span>
|
||||||
|
</div>
|
||||||
|
<div data-section="content">
|
||||||
|
<p data-section="copy">{getStatusText(connectionStatus())}</p>
|
||||||
|
<ul data-section="stats">
|
||||||
|
<li>
|
||||||
|
<span data-element-label>Cost</span>
|
||||||
|
{data().cost !== undefined ? (
|
||||||
|
<span>${data().cost.toFixed(2)}</span>
|
||||||
|
) : (
|
||||||
|
<span data-placeholder>—</span>
|
||||||
|
)}
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<span data-element-label>Input Tokens</span>
|
||||||
|
{data().tokens.input ? <span>{data().tokens.input}</span> : <span data-placeholder>—</span>}
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<span data-element-label>Output Tokens</span>
|
||||||
|
{data().tokens.output ? <span>{data().tokens.output}</span> : <span data-placeholder>—</span>}
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<span data-element-label>Reasoning Tokens</span>
|
||||||
|
{data().tokens.reasoning ? (
|
||||||
|
<span>{data().tokens.reasoning}</span>
|
||||||
|
) : (
|
||||||
|
<span data-placeholder>—</span>
|
||||||
|
)}
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Show>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<Show when={debug}>
|
||||||
|
<div style={{ margin: "2rem 0" }}>
|
||||||
|
<div
|
||||||
|
style={{
|
||||||
|
border: "1px solid #ccc",
|
||||||
|
padding: "1rem",
|
||||||
|
"overflow-y": "auto",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Show when={data().messages.length > 0} fallback={<p>Waiting for messages...</p>}>
|
||||||
|
<ul style={{ "list-style-type": "none", padding: 0 }}>
|
||||||
|
<For each={data().messages}>
|
||||||
|
{(msg) => (
|
||||||
|
<li
|
||||||
|
style={{
|
||||||
|
padding: "0.75rem",
|
||||||
|
margin: "0.75rem 0",
|
||||||
|
"box-shadow": "0 1px 3px rgba(0,0,0,0.1)",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<strong>Key:</strong> {msg.id}
|
||||||
|
</div>
|
||||||
|
<pre>{JSON.stringify(msg, null, 2)}</pre>
|
||||||
|
</li>
|
||||||
|
)}
|
||||||
|
</For>
|
||||||
|
</ul>
|
||||||
|
</Show>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Show>
|
||||||
|
|
||||||
|
<Show when={showScrollButton()}>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
class={styles["scroll-button"]}
|
||||||
|
onClick={() => document.body.scrollIntoView({ behavior: "smooth", block: "end" })}
|
||||||
|
onMouseEnter={() => {
|
||||||
|
setIsButtonHovered(true)
|
||||||
|
if (scrollTimeout) {
|
||||||
|
clearTimeout(scrollTimeout)
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onMouseLeave={() => {
|
||||||
|
setIsButtonHovered(false)
|
||||||
|
if (showScrollButton()) {
|
||||||
|
scrollTimeout = window.setTimeout(() => {
|
||||||
|
if (!isButtonHovered()) {
|
||||||
|
setShowScrollButton(false)
|
||||||
|
}
|
||||||
|
}, 3000)
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
title="Scroll to bottom"
|
||||||
|
aria-label="Scroll to bottom"
|
||||||
|
>
|
||||||
|
<IconArrowDown width={20} height={20} />
|
||||||
|
</button>
|
||||||
|
</Show>
|
||||||
|
</main>
|
||||||
|
</Show>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue