更换渲染工具。添加llm流支持和工具调用【未完成】。
This commit is contained in:
parent
ed574f4ca0
commit
6a8312e1ce
1
.gitignore
vendored
1
.gitignore
vendored
@ -32,3 +32,4 @@ report.[0-9]_.[0-9]_.[0-9]_.[0-9]_.json
|
|||||||
|
|
||||||
# Finder (MacOS) folder config
|
# Finder (MacOS) folder config
|
||||||
.DS_Store
|
.DS_Store
|
||||||
|
.data
|
||||||
@ -9,7 +9,7 @@ bun install
|
|||||||
To run:
|
To run:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
bun run index.ts
|
bun run index.tsx
|
||||||
```
|
```
|
||||||
|
|
||||||
This project was created using `bun init` in bun v1.3.13. [Bun](https://bun.com) is a fast all-in-one JavaScript runtime.
|
This project was created using `bun init` in bun v1.3.13. [Bun](https://bun.com) is a fast all-in-one JavaScript runtime.
|
||||||
|
|||||||
101
bun.lock
101
bun.lock
@ -5,13 +5,18 @@
|
|||||||
"": {
|
"": {
|
||||||
"name": "icoder",
|
"name": "icoder",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@clack/prompts": "^1.3.0",
|
|
||||||
"@vscode/ripgrep": "^1.17.1",
|
"@vscode/ripgrep": "^1.17.1",
|
||||||
"axios": "^1.15.2",
|
"axios": "^1.15.2",
|
||||||
|
"dayjs": "^1.11.20",
|
||||||
|
"ink": "^7.0.2",
|
||||||
|
"ink-spinner": "^5.0.0",
|
||||||
|
"ink-text-input": "^6.0.0",
|
||||||
"picocolors": "^1.1.1",
|
"picocolors": "^1.1.1",
|
||||||
|
"react": "^19.2.6",
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/bun": "latest",
|
"@types/bun": "latest",
|
||||||
|
"@types/react": "^19.2.14",
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"typescript": "^5",
|
"typescript": "^5",
|
||||||
@ -19,20 +24,28 @@
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
"packages": {
|
"packages": {
|
||||||
"@clack/core": ["@clack/core@1.3.0", "https://registry.npmmirror.com/@clack/core/-/core-1.3.0.tgz", { "dependencies": { "fast-wrap-ansi": "^0.2.0", "sisteransi": "^1.0.5" } }, "sha512-xJPHpAmEQUBrXSLx0gF+q5K/IyihXpsHZcha+jB+tyahsKRK3Dxo4D0coZDewHo12NhiuzC3dTtMPbm53GEAAA=="],
|
"@alcalzone/ansi-tokenize": ["@alcalzone/ansi-tokenize@0.3.0", "https://registry.npmmirror.com/@alcalzone/ansi-tokenize/-/ansi-tokenize-0.3.0.tgz", { "dependencies": { "ansi-styles": "^6.2.1", "is-fullwidth-code-point": "^5.0.0" } }, "sha512-p+CMKJ93HFmLkjXKlXiVGlMQEuRb6H0MokBSwUsX+S6BRX8eV5naFZpQJFfJHjRZY0Hmnqy1/r6UWl3x+19zYA=="],
|
||||||
|
|
||||||
"@clack/prompts": ["@clack/prompts@1.3.0", "https://registry.npmmirror.com/@clack/prompts/-/prompts-1.3.0.tgz", { "dependencies": { "@clack/core": "1.3.0", "fast-string-width": "^3.0.2", "fast-wrap-ansi": "^0.2.0", "sisteransi": "^1.0.5" } }, "sha512-GgcWwRCs/xPtaqlMy8qRhPnZf9vlWcWZNHAitnVQ3yk7JmSralSiq5q07yaffYE8SogtDm7zFeKccx1QNVARpw=="],
|
|
||||||
|
|
||||||
"@types/bun": ["@types/bun@1.3.13", "https://registry.npmmirror.com/@types/bun/-/bun-1.3.13.tgz", { "dependencies": { "bun-types": "1.3.13" } }, "sha512-9fqXWk5YIHGGnUau9TEi+qdlTYDAnOj+xLCmSTwXfAIqXr2x4tytJb43E9uCvt09zJURKXwAtkoH4nLQfzeTXw=="],
|
"@types/bun": ["@types/bun@1.3.13", "https://registry.npmmirror.com/@types/bun/-/bun-1.3.13.tgz", { "dependencies": { "bun-types": "1.3.13" } }, "sha512-9fqXWk5YIHGGnUau9TEi+qdlTYDAnOj+xLCmSTwXfAIqXr2x4tytJb43E9uCvt09zJURKXwAtkoH4nLQfzeTXw=="],
|
||||||
|
|
||||||
"@types/node": ["@types/node@25.6.0", "https://registry.npmmirror.com/@types/node/-/node-25.6.0.tgz", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ=="],
|
"@types/node": ["@types/node@25.6.0", "https://registry.npmmirror.com/@types/node/-/node-25.6.0.tgz", { "dependencies": { "undici-types": "~7.19.0" } }, "sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ=="],
|
||||||
|
|
||||||
|
"@types/react": ["@types/react@19.2.14", "https://registry.npmmirror.com/@types/react/-/react-19.2.14.tgz", { "dependencies": { "csstype": "^3.2.2" } }, "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w=="],
|
||||||
|
|
||||||
"@vscode/ripgrep": ["@vscode/ripgrep@1.17.1", "https://registry.npmmirror.com/@vscode/ripgrep/-/ripgrep-1.17.1.tgz", { "dependencies": { "https-proxy-agent": "^7.0.2", "proxy-from-env": "^1.1.0", "yauzl": "^2.9.2" } }, "sha512-xTs7DGyAO3IsJYOCTBP8LnTvPiYVKEuyv8s0xyJDBXfs8rhBfqnZPvb6xDT+RnwWzcXqW27xLS/aGrkjX7lNWw=="],
|
"@vscode/ripgrep": ["@vscode/ripgrep@1.17.1", "https://registry.npmmirror.com/@vscode/ripgrep/-/ripgrep-1.17.1.tgz", { "dependencies": { "https-proxy-agent": "^7.0.2", "proxy-from-env": "^1.1.0", "yauzl": "^2.9.2" } }, "sha512-xTs7DGyAO3IsJYOCTBP8LnTvPiYVKEuyv8s0xyJDBXfs8rhBfqnZPvb6xDT+RnwWzcXqW27xLS/aGrkjX7lNWw=="],
|
||||||
|
|
||||||
"agent-base": ["agent-base@7.1.4", "https://registry.npmmirror.com/agent-base/-/agent-base-7.1.4.tgz", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="],
|
"agent-base": ["agent-base@7.1.4", "https://registry.npmmirror.com/agent-base/-/agent-base-7.1.4.tgz", {}, "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ=="],
|
||||||
|
|
||||||
|
"ansi-escapes": ["ansi-escapes@7.3.0", "https://registry.npmmirror.com/ansi-escapes/-/ansi-escapes-7.3.0.tgz", { "dependencies": { "environment": "^1.0.0" } }, "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg=="],
|
||||||
|
|
||||||
|
"ansi-regex": ["ansi-regex@6.2.2", "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-6.2.2.tgz", {}, "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg=="],
|
||||||
|
|
||||||
|
"ansi-styles": ["ansi-styles@6.2.3", "https://registry.npmmirror.com/ansi-styles/-/ansi-styles-6.2.3.tgz", {}, "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg=="],
|
||||||
|
|
||||||
"asynckit": ["asynckit@0.4.0", "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz", {}, "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="],
|
"asynckit": ["asynckit@0.4.0", "https://registry.npmmirror.com/asynckit/-/asynckit-0.4.0.tgz", {}, "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="],
|
||||||
|
|
||||||
|
"auto-bind": ["auto-bind@5.0.1", "https://registry.npmmirror.com/auto-bind/-/auto-bind-5.0.1.tgz", {}, "sha512-ooviqdwwgfIfNmDwo94wlshcdzfO64XV0Cg6oDsDYBJfITDz1EngD2z7DkbvCWn+XIMsIqW27sEVF6qcpJrRcg=="],
|
||||||
|
|
||||||
"axios": ["axios@1.15.2", "https://registry.npmmirror.com/axios/-/axios-1.15.2.tgz", { "dependencies": { "follow-redirects": "^1.15.11", "form-data": "^4.0.5", "proxy-from-env": "^2.1.0" } }, "sha512-wLrXxPtcrPTsNlJmKjkPnNPK2Ihe0hn0wGSaTEiHRPxwjvJwT3hKmXF4dpqxmPO9SoNb2FsYXj/xEo0gHN+D5A=="],
|
"axios": ["axios@1.15.2", "https://registry.npmmirror.com/axios/-/axios-1.15.2.tgz", { "dependencies": { "follow-redirects": "^1.15.11", "form-data": "^4.0.5", "proxy-from-env": "^2.1.0" } }, "sha512-wLrXxPtcrPTsNlJmKjkPnNPK2Ihe0hn0wGSaTEiHRPxwjvJwT3hKmXF4dpqxmPO9SoNb2FsYXj/xEo0gHN+D5A=="],
|
||||||
|
|
||||||
"buffer-crc32": ["buffer-crc32@0.2.13", "https://registry.npmmirror.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz", {}, "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ=="],
|
"buffer-crc32": ["buffer-crc32@0.2.13", "https://registry.npmmirror.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz", {}, "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ=="],
|
||||||
@ -41,14 +54,34 @@
|
|||||||
|
|
||||||
"call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "https://registry.npmmirror.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="],
|
"call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "https://registry.npmmirror.com/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="],
|
||||||
|
|
||||||
|
"chalk": ["chalk@5.6.2", "https://registry.npmmirror.com/chalk/-/chalk-5.6.2.tgz", {}, "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA=="],
|
||||||
|
|
||||||
|
"cli-boxes": ["cli-boxes@4.0.1", "https://registry.npmmirror.com/cli-boxes/-/cli-boxes-4.0.1.tgz", {}, "sha512-5IOn+jcCEHEraYolBPs/sT4BxYCe2nHg374OPiItB1O96KZFseS2gthU4twyYzeDcFew4DaUM/xwc5BQf08JJw=="],
|
||||||
|
|
||||||
|
"cli-cursor": ["cli-cursor@4.0.0", "https://registry.npmmirror.com/cli-cursor/-/cli-cursor-4.0.0.tgz", { "dependencies": { "restore-cursor": "^4.0.0" } }, "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg=="],
|
||||||
|
|
||||||
|
"cli-spinners": ["cli-spinners@2.9.2", "https://registry.npmmirror.com/cli-spinners/-/cli-spinners-2.9.2.tgz", {}, "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg=="],
|
||||||
|
|
||||||
|
"cli-truncate": ["cli-truncate@6.0.0", "https://registry.npmmirror.com/cli-truncate/-/cli-truncate-6.0.0.tgz", { "dependencies": { "slice-ansi": "^9.0.0", "string-width": "^8.2.0" } }, "sha512-3+YKIUFsohD9MIoOFPFBldjAlnfCmCDcqe6aYGFqlDTRKg80p4wg35L+j83QQ63iOlKRccEkbn8IuM++HsgEjA=="],
|
||||||
|
|
||||||
|
"code-excerpt": ["code-excerpt@4.0.0", "https://registry.npmmirror.com/code-excerpt/-/code-excerpt-4.0.0.tgz", { "dependencies": { "convert-to-spaces": "^2.0.1" } }, "sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA=="],
|
||||||
|
|
||||||
"combined-stream": ["combined-stream@1.0.8", "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz", { "dependencies": { "delayed-stream": "~1.0.0" } }, "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg=="],
|
"combined-stream": ["combined-stream@1.0.8", "https://registry.npmmirror.com/combined-stream/-/combined-stream-1.0.8.tgz", { "dependencies": { "delayed-stream": "~1.0.0" } }, "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg=="],
|
||||||
|
|
||||||
|
"convert-to-spaces": ["convert-to-spaces@2.0.1", "https://registry.npmmirror.com/convert-to-spaces/-/convert-to-spaces-2.0.1.tgz", {}, "sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ=="],
|
||||||
|
|
||||||
|
"csstype": ["csstype@3.2.3", "https://registry.npmmirror.com/csstype/-/csstype-3.2.3.tgz", {}, "sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ=="],
|
||||||
|
|
||||||
|
"dayjs": ["dayjs@1.11.20", "https://registry.npmmirror.com/dayjs/-/dayjs-1.11.20.tgz", {}, "sha512-YbwwqR/uYpeoP4pu043q+LTDLFBLApUP6VxRihdfNTqu4ubqMlGDLd6ErXhEgsyvY0K6nCs7nggYumAN+9uEuQ=="],
|
||||||
|
|
||||||
"debug": ["debug@4.4.3", "https://registry.npmmirror.com/debug/-/debug-4.4.3.tgz", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
|
"debug": ["debug@4.4.3", "https://registry.npmmirror.com/debug/-/debug-4.4.3.tgz", { "dependencies": { "ms": "^2.1.3" } }, "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA=="],
|
||||||
|
|
||||||
"delayed-stream": ["delayed-stream@1.0.0", "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz", {}, "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="],
|
"delayed-stream": ["delayed-stream@1.0.0", "https://registry.npmmirror.com/delayed-stream/-/delayed-stream-1.0.0.tgz", {}, "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="],
|
||||||
|
|
||||||
"dunder-proto": ["dunder-proto@1.0.1", "https://registry.npmmirror.com/dunder-proto/-/dunder-proto-1.0.1.tgz", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="],
|
"dunder-proto": ["dunder-proto@1.0.1", "https://registry.npmmirror.com/dunder-proto/-/dunder-proto-1.0.1.tgz", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="],
|
||||||
|
|
||||||
|
"environment": ["environment@1.1.0", "https://registry.npmmirror.com/environment/-/environment-1.1.0.tgz", {}, "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q=="],
|
||||||
|
|
||||||
"es-define-property": ["es-define-property@1.0.1", "https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.1.tgz", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="],
|
"es-define-property": ["es-define-property@1.0.1", "https://registry.npmmirror.com/es-define-property/-/es-define-property-1.0.1.tgz", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="],
|
||||||
|
|
||||||
"es-errors": ["es-errors@1.3.0", "https://registry.npmmirror.com/es-errors/-/es-errors-1.3.0.tgz", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="],
|
"es-errors": ["es-errors@1.3.0", "https://registry.npmmirror.com/es-errors/-/es-errors-1.3.0.tgz", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="],
|
||||||
@ -57,11 +90,9 @@
|
|||||||
|
|
||||||
"es-set-tostringtag": ["es-set-tostringtag@2.1.0", "https://registry.npmmirror.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", { "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA=="],
|
"es-set-tostringtag": ["es-set-tostringtag@2.1.0", "https://registry.npmmirror.com/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz", { "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA=="],
|
||||||
|
|
||||||
"fast-string-truncated-width": ["fast-string-truncated-width@3.0.3", "https://registry.npmmirror.com/fast-string-truncated-width/-/fast-string-truncated-width-3.0.3.tgz", {}, "sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g=="],
|
"es-toolkit": ["es-toolkit@1.46.1", "https://registry.npmmirror.com/es-toolkit/-/es-toolkit-1.46.1.tgz", {}, "sha512-5eNtXOs3tbfxXOj04tjjseeWkRWaoCjdEI+96DgwzZoe6c9juL49pXlzAFTI72aWC9Y8p7168g6XIKjh7k6pyQ=="],
|
||||||
|
|
||||||
"fast-string-width": ["fast-string-width@3.0.2", "https://registry.npmmirror.com/fast-string-width/-/fast-string-width-3.0.2.tgz", { "dependencies": { "fast-string-truncated-width": "^3.0.2" } }, "sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg=="],
|
"escape-string-regexp": ["escape-string-regexp@2.0.0", "https://registry.npmmirror.com/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", {}, "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w=="],
|
||||||
|
|
||||||
"fast-wrap-ansi": ["fast-wrap-ansi@0.2.0", "https://registry.npmmirror.com/fast-wrap-ansi/-/fast-wrap-ansi-0.2.0.tgz", { "dependencies": { "fast-string-width": "^3.0.2" } }, "sha512-rLV8JHxTyhVmFYhBJuMujcrHqOT2cnO5Zxj37qROj23CP39GXubJRBUFF0z8KFK77Uc0SukZUf7JZhsVEQ6n8w=="],
|
|
||||||
|
|
||||||
"fd-slicer": ["fd-slicer@1.1.0", "https://registry.npmmirror.com/fd-slicer/-/fd-slicer-1.1.0.tgz", { "dependencies": { "pend": "~1.2.0" } }, "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g=="],
|
"fd-slicer": ["fd-slicer@1.1.0", "https://registry.npmmirror.com/fd-slicer/-/fd-slicer-1.1.0.tgz", { "dependencies": { "pend": "~1.2.0" } }, "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g=="],
|
||||||
|
|
||||||
@ -71,6 +102,8 @@
|
|||||||
|
|
||||||
"function-bind": ["function-bind@1.1.2", "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
|
"function-bind": ["function-bind@1.1.2", "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.2.tgz", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
|
||||||
|
|
||||||
|
"get-east-asian-width": ["get-east-asian-width@1.5.0", "https://registry.npmmirror.com/get-east-asian-width/-/get-east-asian-width-1.5.0.tgz", {}, "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA=="],
|
||||||
|
|
||||||
"get-intrinsic": ["get-intrinsic@1.3.0", "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="],
|
"get-intrinsic": ["get-intrinsic@1.3.0", "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.3.0.tgz", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="],
|
||||||
|
|
||||||
"get-proto": ["get-proto@1.0.1", "https://registry.npmmirror.com/get-proto/-/get-proto-1.0.1.tgz", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="],
|
"get-proto": ["get-proto@1.0.1", "https://registry.npmmirror.com/get-proto/-/get-proto-1.0.1.tgz", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="],
|
||||||
@ -85,28 +118,78 @@
|
|||||||
|
|
||||||
"https-proxy-agent": ["https-proxy-agent@7.0.6", "https://registry.npmmirror.com/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="],
|
"https-proxy-agent": ["https-proxy-agent@7.0.6", "https://registry.npmmirror.com/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz", { "dependencies": { "agent-base": "^7.1.2", "debug": "4" } }, "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw=="],
|
||||||
|
|
||||||
|
"indent-string": ["indent-string@5.0.0", "https://registry.npmmirror.com/indent-string/-/indent-string-5.0.0.tgz", {}, "sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg=="],
|
||||||
|
|
||||||
|
"ink": ["ink@7.0.2", "https://registry.npmmirror.com/ink/-/ink-7.0.2.tgz", { "dependencies": { "@alcalzone/ansi-tokenize": "^0.3.0", "ansi-escapes": "^7.3.0", "ansi-styles": "^6.2.3", "auto-bind": "^5.0.1", "chalk": "^5.6.2", "cli-boxes": "^4.0.1", "cli-cursor": "^4.0.0", "cli-truncate": "^6.0.0", "code-excerpt": "^4.0.0", "es-toolkit": "^1.45.1", "indent-string": "^5.0.0", "is-in-ci": "^2.0.0", "patch-console": "^2.0.0", "react-reconciler": "^0.33.0", "scheduler": "^0.27.0", "signal-exit": "^3.0.7", "slice-ansi": "^9.0.0", "stack-utils": "^2.0.6", "string-width": "^8.2.0", "terminal-size": "^4.0.1", "type-fest": "^5.5.0", "widest-line": "^6.0.0", "wrap-ansi": "^10.0.0", "ws": "^8.20.0", "yoga-layout": "~3.2.1" }, "peerDependencies": { "@types/react": ">=19.2.0", "react": ">=19.2.0", "react-devtools-core": ">=6.1.2" }, "optionalPeers": ["@types/react", "react-devtools-core"] }, "sha512-cnkE2SsDC/gieJ+BD8+gWpXrZPMInv7agBYN5gcKVlQZYp+IKa/FKM5bp1OIuJFp3ZIuRK7ZNxY4MZR3tUzyfQ=="],
|
||||||
|
|
||||||
|
"ink-spinner": ["ink-spinner@5.0.0", "https://registry.npmmirror.com/ink-spinner/-/ink-spinner-5.0.0.tgz", { "dependencies": { "cli-spinners": "^2.7.0" }, "peerDependencies": { "ink": ">=4.0.0", "react": ">=18.0.0" } }, "sha512-EYEasbEjkqLGyPOUc8hBJZNuC5GvXGMLu0w5gdTNskPc7Izc5vO3tdQEYnzvshucyGCBXc86ig0ujXPMWaQCdA=="],
|
||||||
|
|
||||||
|
"ink-text-input": ["ink-text-input@6.0.0", "https://registry.npmmirror.com/ink-text-input/-/ink-text-input-6.0.0.tgz", { "dependencies": { "chalk": "^5.3.0", "type-fest": "^4.18.2" }, "peerDependencies": { "ink": ">=5", "react": ">=18" } }, "sha512-Fw64n7Yha5deb1rHY137zHTAbSTNelUKuB5Kkk2HACXEtwIHBCf9OH2tP/LQ9fRYTl1F0dZgbW0zPnZk6FA9Lw=="],
|
||||||
|
|
||||||
|
"is-fullwidth-code-point": ["is-fullwidth-code-point@5.1.0", "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz", { "dependencies": { "get-east-asian-width": "^1.3.1" } }, "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ=="],
|
||||||
|
|
||||||
|
"is-in-ci": ["is-in-ci@2.0.0", "https://registry.npmmirror.com/is-in-ci/-/is-in-ci-2.0.0.tgz", { "bin": { "is-in-ci": "cli.js" } }, "sha512-cFeerHriAnhrQSbpAxL37W1wcJKUUX07HyLWZCW1URJT/ra3GyUTzBgUnh24TMVfNTV2Hij2HLxkPHFZfOZy5w=="],
|
||||||
|
|
||||||
"math-intrinsics": ["math-intrinsics@1.1.0", "https://registry.npmmirror.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="],
|
"math-intrinsics": ["math-intrinsics@1.1.0", "https://registry.npmmirror.com/math-intrinsics/-/math-intrinsics-1.1.0.tgz", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="],
|
||||||
|
|
||||||
"mime-db": ["mime-db@1.52.0", "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="],
|
"mime-db": ["mime-db@1.52.0", "https://registry.npmmirror.com/mime-db/-/mime-db-1.52.0.tgz", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="],
|
||||||
|
|
||||||
"mime-types": ["mime-types@2.1.35", "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="],
|
"mime-types": ["mime-types@2.1.35", "https://registry.npmmirror.com/mime-types/-/mime-types-2.1.35.tgz", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="],
|
||||||
|
|
||||||
|
"mimic-fn": ["mimic-fn@2.1.0", "https://registry.npmmirror.com/mimic-fn/-/mimic-fn-2.1.0.tgz", {}, "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="],
|
||||||
|
|
||||||
"ms": ["ms@2.1.3", "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
|
"ms": ["ms@2.1.3", "https://registry.npmmirror.com/ms/-/ms-2.1.3.tgz", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
|
||||||
|
|
||||||
|
"onetime": ["onetime@5.1.2", "https://registry.npmmirror.com/onetime/-/onetime-5.1.2.tgz", { "dependencies": { "mimic-fn": "^2.1.0" } }, "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg=="],
|
||||||
|
|
||||||
|
"patch-console": ["patch-console@2.0.0", "https://registry.npmmirror.com/patch-console/-/patch-console-2.0.0.tgz", {}, "sha512-0YNdUceMdaQwoKce1gatDScmMo5pu/tfABfnzEqeG0gtTmd7mh/WcwgUjtAeOU7N8nFFlbQBnFK2gXW5fGvmMA=="],
|
||||||
|
|
||||||
"pend": ["pend@1.2.0", "https://registry.npmmirror.com/pend/-/pend-1.2.0.tgz", {}, "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg=="],
|
"pend": ["pend@1.2.0", "https://registry.npmmirror.com/pend/-/pend-1.2.0.tgz", {}, "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg=="],
|
||||||
|
|
||||||
"picocolors": ["picocolors@1.1.1", "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
|
"picocolors": ["picocolors@1.1.1", "https://registry.npmmirror.com/picocolors/-/picocolors-1.1.1.tgz", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
|
||||||
|
|
||||||
"proxy-from-env": ["proxy-from-env@1.1.0", "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz", {}, "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="],
|
"proxy-from-env": ["proxy-from-env@1.1.0", "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-1.1.0.tgz", {}, "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg=="],
|
||||||
|
|
||||||
"sisteransi": ["sisteransi@1.0.5", "https://registry.npmmirror.com/sisteransi/-/sisteransi-1.0.5.tgz", {}, "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg=="],
|
"react": ["react@19.2.6", "https://registry.npmmirror.com/react/-/react-19.2.6.tgz", {}, "sha512-sfWGGfavi0xr8Pg0sVsyHMAOziVYKgPLNrS7ig+ivMNb3wbCBw3KxtflsGBAwD3gYQlE/AEZsTLgToRrSCjb0Q=="],
|
||||||
|
|
||||||
|
"react-reconciler": ["react-reconciler@0.33.0", "https://registry.npmmirror.com/react-reconciler/-/react-reconciler-0.33.0.tgz", { "dependencies": { "scheduler": "^0.27.0" }, "peerDependencies": { "react": "^19.2.0" } }, "sha512-KetWRytFv1epdpJc3J4G75I4WrplZE5jOL7Yq0p34+OVOKF4Se7WrdIdVC45XsSSmUTlht2FM/fM1FZb1mfQeA=="],
|
||||||
|
|
||||||
|
"restore-cursor": ["restore-cursor@4.0.0", "https://registry.npmmirror.com/restore-cursor/-/restore-cursor-4.0.0.tgz", { "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" } }, "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg=="],
|
||||||
|
|
||||||
|
"scheduler": ["scheduler@0.27.0", "https://registry.npmmirror.com/scheduler/-/scheduler-0.27.0.tgz", {}, "sha512-eNv+WrVbKu1f3vbYJT/xtiF5syA5HPIMtf9IgY/nKg0sWqzAUEvqY/xm7OcZc/qafLx/iO9FgOmeSAp4v5ti/Q=="],
|
||||||
|
|
||||||
|
"signal-exit": ["signal-exit@3.0.7", "https://registry.npmmirror.com/signal-exit/-/signal-exit-3.0.7.tgz", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="],
|
||||||
|
|
||||||
|
"slice-ansi": ["slice-ansi@9.0.0", "https://registry.npmmirror.com/slice-ansi/-/slice-ansi-9.0.0.tgz", { "dependencies": { "ansi-styles": "^6.2.3", "is-fullwidth-code-point": "^5.1.0" } }, "sha512-SO/3iYL5S3W57LLEniscOGPZgOqZUPCx6d3dB+52B80yJ0XstzsC/eV8gnA4tM3MHDrKz+OCFSLNjswdSC+/bA=="],
|
||||||
|
|
||||||
|
"stack-utils": ["stack-utils@2.0.6", "https://registry.npmmirror.com/stack-utils/-/stack-utils-2.0.6.tgz", { "dependencies": { "escape-string-regexp": "^2.0.0" } }, "sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ=="],
|
||||||
|
|
||||||
|
"string-width": ["string-width@8.2.1", "https://registry.npmmirror.com/string-width/-/string-width-8.2.1.tgz", { "dependencies": { "get-east-asian-width": "^1.5.0", "strip-ansi": "^7.1.2" } }, "sha512-IIaP0g3iy9Cyy18w3M9YcaDudujEAVHKt3a3QJg1+sr/oX96TbaGUubG0hJyCjCBThFH+tFpcIyoUHUn1ogaLA=="],
|
||||||
|
|
||||||
|
"strip-ansi": ["strip-ansi@7.2.0", "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-7.2.0.tgz", { "dependencies": { "ansi-regex": "^6.2.2" } }, "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w=="],
|
||||||
|
|
||||||
|
"tagged-tag": ["tagged-tag@1.0.0", "https://registry.npmmirror.com/tagged-tag/-/tagged-tag-1.0.0.tgz", {}, "sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng=="],
|
||||||
|
|
||||||
|
"terminal-size": ["terminal-size@4.0.1", "https://registry.npmmirror.com/terminal-size/-/terminal-size-4.0.1.tgz", {}, "sha512-avMLDQpUI9I5XFrklECw1ZEUPJhqzcwSWsyyI8blhRLT+8N1jLJWLWWYQpB2q2xthq8xDvjZPISVh53T/+CLYQ=="],
|
||||||
|
|
||||||
|
"type-fest": ["type-fest@5.6.0", "https://registry.npmmirror.com/type-fest/-/type-fest-5.6.0.tgz", { "dependencies": { "tagged-tag": "^1.0.0" } }, "sha512-8ZiHFm91orbSAe2PSAiSVBVko18pbhbiB3U9GglSzF/zCGkR+rxpHx6sEMCUm4kxY4LjDIUGgCfUMtwfZfjfUA=="],
|
||||||
|
|
||||||
"typescript": ["typescript@5.9.3", "https://registry.npmmirror.com/typescript/-/typescript-5.9.3.tgz", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
|
"typescript": ["typescript@5.9.3", "https://registry.npmmirror.com/typescript/-/typescript-5.9.3.tgz", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
|
||||||
|
|
||||||
"undici-types": ["undici-types@7.19.2", "https://registry.npmmirror.com/undici-types/-/undici-types-7.19.2.tgz", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="],
|
"undici-types": ["undici-types@7.19.2", "https://registry.npmmirror.com/undici-types/-/undici-types-7.19.2.tgz", {}, "sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg=="],
|
||||||
|
|
||||||
|
"widest-line": ["widest-line@6.0.0", "https://registry.npmmirror.com/widest-line/-/widest-line-6.0.0.tgz", { "dependencies": { "string-width": "^8.1.0" } }, "sha512-U89AsyEeAsyoF0zVJBkG9zBgekjgjK7yk9sje3F4IQpXBJ10TF6ByLlIfjMhcmHMJgHZI4KHt4rdNfktzxIAMA=="],
|
||||||
|
|
||||||
|
"wrap-ansi": ["wrap-ansi@10.0.0", "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-10.0.0.tgz", { "dependencies": { "ansi-styles": "^6.2.3", "string-width": "^8.2.0", "strip-ansi": "^7.1.2" } }, "sha512-SGcvg80f0wUy2/fXES19feHMz8E0JoXv2uNgHOu4Dgi2OrCy1lqwFYEJz1BLbDI0exjPMe/ZdzZ/YpGECBG/aQ=="],
|
||||||
|
|
||||||
|
"ws": ["ws@8.20.0", "https://registry.npmmirror.com/ws/-/ws-8.20.0.tgz", { "peerDependencies": { "bufferutil": "^4.0.1", "utf-8-validate": ">=5.0.2" }, "optionalPeers": ["bufferutil", "utf-8-validate"] }, "sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA=="],
|
||||||
|
|
||||||
"yauzl": ["yauzl@2.10.0", "https://registry.npmmirror.com/yauzl/-/yauzl-2.10.0.tgz", { "dependencies": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" } }, "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g=="],
|
"yauzl": ["yauzl@2.10.0", "https://registry.npmmirror.com/yauzl/-/yauzl-2.10.0.tgz", { "dependencies": { "buffer-crc32": "~0.2.3", "fd-slicer": "~1.1.0" } }, "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g=="],
|
||||||
|
|
||||||
|
"yoga-layout": ["yoga-layout@3.2.1", "https://registry.npmmirror.com/yoga-layout/-/yoga-layout-3.2.1.tgz", {}, "sha512-0LPOt3AxKqMdFBZA3HBAt/t/8vIKq7VaQYbuA8WxCgung+p9TVyKRYdpvCb80HcdTN2NkbIKbhNwKUfm3tQywQ=="],
|
||||||
|
|
||||||
"axios/proxy-from-env": ["proxy-from-env@2.1.0", "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-2.1.0.tgz", {}, "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA=="],
|
"axios/proxy-from-env": ["proxy-from-env@2.1.0", "https://registry.npmmirror.com/proxy-from-env/-/proxy-from-env-2.1.0.tgz", {}, "sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA=="],
|
||||||
|
|
||||||
|
"ink-text-input/type-fest": ["type-fest@4.41.0", "https://registry.npmmirror.com/type-fest/-/type-fest-4.41.0.tgz", {}, "sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA=="],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
49
index.ts
49
index.ts
@ -1,49 +0,0 @@
|
|||||||
import * as p from '@clack/prompts';
|
|
||||||
import {sendMessage} from "./src/llm.ts";
|
|
||||||
import color from 'picocolors';
|
|
||||||
|
|
||||||
async function chat() {
|
|
||||||
console.clear();
|
|
||||||
p.intro(color.bgCyan(color.black(' AI 助手已就绪 ')));
|
|
||||||
|
|
||||||
while (true) {
|
|
||||||
// 1. 获取输入
|
|
||||||
const prompt = await p.text({
|
|
||||||
message: '你:',
|
|
||||||
placeholder: '说点什么... (输入 exit 退出)',
|
|
||||||
validate: (value) => value ? undefined : '请输入内容'
|
|
||||||
});
|
|
||||||
|
|
||||||
// 2. 退出判定
|
|
||||||
if (p.isCancel(prompt) || prompt.toLowerCase() === 'exit') {
|
|
||||||
p.outro(color.dim('对话结束'));
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. 模拟回复逻辑
|
|
||||||
const s = p.spinner();
|
|
||||||
s.start('助手正在思考...');
|
|
||||||
|
|
||||||
// 这里替换成你真实的 AI 请求
|
|
||||||
const response = await sendMessage(prompt);
|
|
||||||
|
|
||||||
s.stop('助手回复:');
|
|
||||||
|
|
||||||
// 4. 使用 p.note 来承载回复内容,它会自动处理边框和宽度
|
|
||||||
// p.note(
|
|
||||||
// response.choices[0].message.reasoning_content,
|
|
||||||
// '✨ '
|
|
||||||
// );
|
|
||||||
p.log.message(color.white(
|
|
||||||
response.choices[0].message.reasoning_content
|
|
||||||
))
|
|
||||||
p.log.success(color.white(
|
|
||||||
response.choices[0].message.content
|
|
||||||
));
|
|
||||||
|
|
||||||
// 5. 打印一个空行,防止下一轮对话的 "你:" 贴得太近
|
|
||||||
console.log('');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
chat();
|
|
||||||
153
index.tsx
Normal file
153
index.tsx
Normal file
@ -0,0 +1,153 @@
|
|||||||
|
import React, {useState} from 'react';
|
||||||
|
import {Box, render, Text, useInput} from 'ink';
|
||||||
|
import TextInput from 'ink-text-input';
|
||||||
|
import Spinner from 'ink-spinner';
|
||||||
|
|
||||||
|
import {addMessage, callTools, type ChatMessage, findMessages, getMessages, requestLLMStream} from "./src/llm.ts";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
|
||||||
|
|
||||||
|
const App = () => {
|
||||||
|
const [input, setInput] = useState(''); // 当前输入框内容
|
||||||
|
const [isChatting, setIsChatting] = useState(false); // 是否正在对话
|
||||||
|
const [history, setHistory] = useState<ChatMessage[]>(getMessages()); // 对话历史
|
||||||
|
const [currentResponse, setCurrentResponse] = useState(''); // 当前流式输出的内容
|
||||||
|
const [currentReasoningResponse, setCurrentReasoningResponse] = useState(''); // 当前流式输出的内容
|
||||||
|
|
||||||
|
// 处理提交
|
||||||
|
const handleSubmit = async (value: string) => {
|
||||||
|
if (!value) return;
|
||||||
|
setIsChatting(true);
|
||||||
|
await addMessage("now is " + dayjs().format("YYYY-MM-DD HH:mm:ss"), "system");
|
||||||
|
await addMessage(value);
|
||||||
|
setHistory(getMessages());
|
||||||
|
setInput('');
|
||||||
|
|
||||||
|
await dealRequest();
|
||||||
|
};
|
||||||
|
|
||||||
|
const dealRequest = async () => {
|
||||||
|
let request_id = "";
|
||||||
|
let fullText = '';
|
||||||
|
let reasoningFullText = '';
|
||||||
|
for await (const token of requestLLMStream(false)) {
|
||||||
|
fullText += token.content || "";
|
||||||
|
reasoningFullText += token.reasoning_content || "";
|
||||||
|
setCurrentResponse(fullText);
|
||||||
|
setCurrentReasoningResponse(reasoningFullText);
|
||||||
|
if (token.id) {
|
||||||
|
request_id = token.id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const lastMsg = findMessages(request_id);
|
||||||
|
|
||||||
|
if (lastMsg && lastMsg.finish_reason === "tool_calls") {
|
||||||
|
// 处理工具调用
|
||||||
|
if (lastMsg.tool_call_id && lastMsg.tool_call_name) {
|
||||||
|
await callTools(
|
||||||
|
lastMsg.tool_call_id,
|
||||||
|
lastMsg.tool_call_name,
|
||||||
|
lastMsg.tool_call_arguments
|
||||||
|
)
|
||||||
|
await dealRequest()
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
// 流结束,归档到历史
|
||||||
|
setHistory(getMessages());
|
||||||
|
setCurrentResponse('');
|
||||||
|
setCurrentReasoningResponse('');
|
||||||
|
setIsChatting(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 监听退出快捷键 (Ctrl+C)
|
||||||
|
useInput((input, key) => {
|
||||||
|
if (input === 'q' || (key.ctrl && input === 'c')) {
|
||||||
|
process.exit();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Box flexDirection="column">
|
||||||
|
{/* 1. 标题栏 */}
|
||||||
|
<Box marginBottom={1}>
|
||||||
|
<Text color="black" bold>🤖 iCoder </Text>
|
||||||
|
</Box>
|
||||||
|
|
||||||
|
{/* 2. 渲染历史记录 */}
|
||||||
|
{history.map((msg) => (
|
||||||
|
<Box key={msg.id} flexDirection="column" marginBottom={msg.role == "assistant" ? 2 : 1}>
|
||||||
|
<Box marginTop={1}>
|
||||||
|
<Text color={"gray"}>{msg.reasoning_content ?? ""}</Text>
|
||||||
|
</Box>
|
||||||
|
<Box marginTop={1}>
|
||||||
|
<Text>{msg.content ?? ""}</Text>
|
||||||
|
|
||||||
|
<Text>
|
||||||
|
{msg.finish_reason}
|
||||||
|
{msg.tool_call_id}
|
||||||
|
{msg.tool_call_name}
|
||||||
|
{msg.tool_call_arguments}
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
|
{
|
||||||
|
msg.role === "user" ? (
|
||||||
|
<Box marginTop={1}>
|
||||||
|
<Text color={"gray"}>{msg.createdAt ?? ""}</Text>
|
||||||
|
</Box>
|
||||||
|
) : null
|
||||||
|
}
|
||||||
|
</Box>
|
||||||
|
))}
|
||||||
|
|
||||||
|
{/* 3. 渲染当前正在生成的流 */}
|
||||||
|
{isChatting && currentResponse && (
|
||||||
|
<Box flexDirection="column" marginBottom={1}>
|
||||||
|
<Box marginBottom={1}>
|
||||||
|
<Text color="green">
|
||||||
|
<Spinner type="dots"/> 正在工作...
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
|
<Box>
|
||||||
|
<Text color="gray">{currentReasoningResponse}</Text>
|
||||||
|
</Box>
|
||||||
|
<Box>
|
||||||
|
<Text>{currentResponse}</Text>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* 4. 加载状态 */}
|
||||||
|
{isChatting && !currentResponse && (
|
||||||
|
<Box>
|
||||||
|
<Text color="yellow">
|
||||||
|
<Spinner type="dots"/> 正在思考...
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{/* 5. 输入区 */}
|
||||||
|
{!isChatting && (
|
||||||
|
<Box>
|
||||||
|
<Box marginRight={2}>
|
||||||
|
<Text color="green">🎨</Text>
|
||||||
|
</Box>
|
||||||
|
<Box>
|
||||||
|
<TextInput
|
||||||
|
value={input}
|
||||||
|
onChange={setInput}
|
||||||
|
onSubmit={handleSubmit}
|
||||||
|
placeholder="输入问题并回车..."
|
||||||
|
/>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<Box marginTop={1}>
|
||||||
|
<Text dimColor>按 Ctrl+C 退出</Text>
|
||||||
|
</Box>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
render(<App/>);
|
||||||
13
package.json
13
package.json
@ -1,18 +1,23 @@
|
|||||||
{
|
{
|
||||||
"name": "icoder",
|
"name": "icoder",
|
||||||
"module": "index.ts",
|
"module": "index.tsx",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"private": true,
|
"private": true,
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/bun": "latest"
|
"@types/bun": "latest",
|
||||||
|
"@types/react": "^19.2.14"
|
||||||
},
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"typescript": "^5"
|
"typescript": "^5"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@clack/prompts": "^1.3.0",
|
|
||||||
"@vscode/ripgrep": "^1.17.1",
|
"@vscode/ripgrep": "^1.17.1",
|
||||||
"axios": "^1.15.2",
|
"axios": "^1.15.2",
|
||||||
"picocolors": "^1.1.1"
|
"dayjs": "^1.11.20",
|
||||||
|
"ink": "^7.0.2",
|
||||||
|
"ink-spinner": "^5.0.0",
|
||||||
|
"ink-text-input": "^6.0.0",
|
||||||
|
"picocolors": "^1.1.1",
|
||||||
|
"react": "^19.2.6"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
272
src/llm.ts
272
src/llm.ts
@ -1,54 +1,253 @@
|
|||||||
import axios from "axios";
|
import axios, {type AxiosRequestConfig} from "axios";
|
||||||
|
import dayjs from "dayjs";
|
||||||
|
import {mkdir, readdir} from "node:fs/promises";
|
||||||
|
|
||||||
const apiKey = Bun.env.API_KEY;
|
export type Role = "user" | "assistant" | "system" | "tool";
|
||||||
|
|
||||||
interface Message {
|
export interface ChatMessage {
|
||||||
|
id?: string;
|
||||||
|
role?: Role;
|
||||||
content?: string;
|
content?: string;
|
||||||
role: "user" | "assistant" | "system";
|
reasoning_content?: string;
|
||||||
|
extra?: string;
|
||||||
|
createdAt?: string;
|
||||||
|
tool_call_id?: string;
|
||||||
|
tool_call_name?: string;
|
||||||
|
tool_call_arguments?: string;
|
||||||
|
finish_reason?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
await mkdir("./.data", {recursive: true});
|
||||||
|
await mkdir("./.data/sessions", {recursive: true});
|
||||||
|
await mkdir("./.data/requests", {recursive: true});
|
||||||
|
|
||||||
|
|
||||||
|
const baseUrl = Bun.env.BASE_URL;
|
||||||
|
const apiKey = Bun.env.API_KEY;
|
||||||
|
const model = Bun.env.MODEL_NAME;
|
||||||
|
|
||||||
|
|
||||||
const headers = {
|
const headers = {
|
||||||
'Content-Type': 'application/json',
|
"Content-Type": "application/json",
|
||||||
'Accept': 'application/json',
|
"Accept": "application/json",
|
||||||
'Authorization': 'Bearer ' + apiKey
|
"Authorization": "Bearer " + apiKey
|
||||||
};
|
};
|
||||||
|
|
||||||
const messageList: Message[] = [
|
const messageList: ChatMessage[] = [
|
||||||
{
|
{
|
||||||
content: "你是一个专业的代码助手",
|
content: "你是一个专业的代码助手",
|
||||||
role: "system"
|
role: "system",
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const tools: object[] = [
|
||||||
|
{
|
||||||
|
"type": "function",
|
||||||
|
"function": {
|
||||||
|
"name": "file_list",
|
||||||
|
"description": "查看给定目录下的所有文件列表",
|
||||||
|
"parameters": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"directory": {
|
||||||
|
"type": "string",
|
||||||
|
"description": "要查看文件列表的目录"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
export function getMessages() {
|
||||||
|
return messageList.filter((message) => message.role === "user" || message.role === "assistant");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function findMessages(id?: string) {
|
||||||
|
return messageList.find((message) => message.id === id);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
export async function sendMessage(content: string) {
|
export async function sendMessage(content: string) {
|
||||||
messageList.push({
|
messageList.push({
|
||||||
content: content,
|
content: "now time is " + Date(),
|
||||||
role: "user"
|
role: "system"
|
||||||
|
});
|
||||||
|
messageList.push({
|
||||||
|
content: content,
|
||||||
|
role: "user",
|
||||||
|
createdAt: dayjs().format('HH:mm:ss')
|
||||||
});
|
});
|
||||||
let config = {
|
|
||||||
method: 'post',
|
|
||||||
maxBodyLength: Infinity,
|
|
||||||
url: 'https://api.deepseek.com/chat/completions',
|
|
||||||
headers: headers,
|
|
||||||
data: JSON.stringify(getBody())
|
|
||||||
};
|
|
||||||
|
|
||||||
const response = await axios(config);
|
return await requestLLM()
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function requestLLM(): Promise<ChatMessage> {
|
||||||
|
const response = await generateRequest(false);
|
||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
messageList.push({
|
const message = response.data?.choices?.[0]?.message;
|
||||||
content: response.data.choices[0].message.content,
|
let content = message?.content ?? "";
|
||||||
role: "assistant"
|
let reasoning_content = message?.reasoning_content ?? "";
|
||||||
});
|
await addMessage(content, "assistant");
|
||||||
|
return {content, reasoning_content};
|
||||||
}
|
}
|
||||||
return response.data;
|
return {content: response.data?.choices?.[0]?.message?.content ?? "请求失败", reasoning_content: ""};
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function addMessage(content: string, role: Role = "user") {
|
||||||
|
messageList.push({
|
||||||
|
content: content,
|
||||||
|
role: role,
|
||||||
|
createdAt: dayjs().format('HH:mm:ss'),
|
||||||
|
id: Date.now() + Math.random().toString(),
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
function getBody() {
|
export async function* sendMessageStream(content: string) {
|
||||||
|
messageList.push({
|
||||||
|
content: "now time is " + Date(),
|
||||||
|
role: "system"
|
||||||
|
});
|
||||||
|
messageList.push({
|
||||||
|
content: content,
|
||||||
|
role: "user",
|
||||||
|
createdAt: dayjs().format('HH:mm:ss')
|
||||||
|
});
|
||||||
|
for await (const result of requestLLMStream(false)) {
|
||||||
|
yield result;
|
||||||
|
}
|
||||||
|
return {}
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function* requestLLMStream(logs: boolean = false): AsyncGenerator<ChatMessage> {
|
||||||
|
const response = await generateRequest(true)
|
||||||
|
if (response.status === 200) {
|
||||||
|
let request_id: string | undefined = undefined;
|
||||||
|
let result_data = ""
|
||||||
|
|
||||||
|
// let content = ""
|
||||||
|
// let reasoning_content = ""
|
||||||
|
// let tool_calls_name = ""
|
||||||
|
// let tool_calls_arguments = ""
|
||||||
|
const messageData: ChatMessage = {
|
||||||
|
content: "",
|
||||||
|
reasoning_content: "",
|
||||||
|
tool_call_id: "",
|
||||||
|
tool_call_name: "",
|
||||||
|
tool_call_arguments: "",
|
||||||
|
finish_reason: "",
|
||||||
|
}
|
||||||
|
|
||||||
|
for await (const chunk of response.data) {
|
||||||
|
const lines = chunk.toString().split("\n")
|
||||||
|
for (const line of lines) {
|
||||||
|
if (line.startsWith("data:")) {
|
||||||
|
if (result_data !== "") {
|
||||||
|
result_data += "\n"
|
||||||
|
}
|
||||||
|
result_data += line;
|
||||||
|
}
|
||||||
|
if (logs) console.log(line);
|
||||||
|
if (line.trim() === "") continue;
|
||||||
|
if (line.includes("[DONE]")) {
|
||||||
|
if (request_id != undefined && line.trim() !== "") {
|
||||||
|
await Bun.write("./.data/requests/" + request_id + ".log", result_data);
|
||||||
|
}
|
||||||
|
if (messageData.content !== "") {
|
||||||
|
messageList.push({
|
||||||
|
content: messageData.content,
|
||||||
|
reasoning_content: messageData.reasoning_content,
|
||||||
|
role: "assistant",
|
||||||
|
id: request_id,
|
||||||
|
});
|
||||||
|
// if (messageData?.tool_call_id && messageData?.tool_call_name && messageData?.tool_call_arguments) {
|
||||||
|
// await callTools(messageData.tool_call_id, messageData.tool_call_name, messageData.tool_call_arguments);
|
||||||
|
// return requestLLMStream(false);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
if (line.startsWith("data: ")) {
|
||||||
|
try {
|
||||||
|
const data = JSON.parse(line.replace("data: ", ""));
|
||||||
|
if (request_id === undefined) {
|
||||||
|
request_id = data.id
|
||||||
|
}
|
||||||
|
const chunkDelta = data.choices[0].delta
|
||||||
|
if (chunkDelta.id) {
|
||||||
|
messageData.id = chunkDelta.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
messageData.content += chunkDelta.content ?? ""
|
||||||
|
messageData.reasoning_content += chunkDelta.reasoning_content ?? ""
|
||||||
|
|
||||||
|
if (chunkDelta.tool_calls != null && chunkDelta.tool_calls.length > 0) {
|
||||||
|
const tool_call = chunkDelta.tool_calls[0];
|
||||||
|
if (tool_call.id) {
|
||||||
|
messageData.tool_call_id = tool_call.id;
|
||||||
|
}
|
||||||
|
if (tool_call.name) {
|
||||||
|
messageData.tool_call_name += tool_call.name;
|
||||||
|
}
|
||||||
|
if (tool_call.arguments) {
|
||||||
|
messageData.tool_call_arguments += tool_call.arguments;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (chunkDelta.finish_reason) {
|
||||||
|
messageData.finish_reason = chunkDelta.finish_reason;
|
||||||
|
}
|
||||||
|
|
||||||
|
yield {
|
||||||
|
id: request_id,
|
||||||
|
content: chunkDelta?.content || "",
|
||||||
|
reasoning_content: chunkDelta?.reasoning_content || ""
|
||||||
|
};
|
||||||
|
} catch (e) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function callTools(tool_call_id: string, tool_calls_name: string, tool_calls_arguments?: string) {
|
||||||
|
if (tool_calls_name === "file_list") {
|
||||||
|
const args = JSON.parse(tool_calls_arguments || "{}");
|
||||||
|
const files = await readdir(args.directory);
|
||||||
|
await addMessage(files.join(","), "tool");
|
||||||
|
messageList.push({
|
||||||
|
tool_call_id: tool_call_id,
|
||||||
|
content: files.join(","),
|
||||||
|
role: "tool"
|
||||||
|
});
|
||||||
|
return files.join(",");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async function generateRequest(stream: boolean) {
|
||||||
|
let config: AxiosRequestConfig = {
|
||||||
|
method: "post",
|
||||||
|
maxBodyLength: Infinity,
|
||||||
|
url: baseUrl + "/chat/completions",
|
||||||
|
headers: headers,
|
||||||
|
data: JSON.stringify(getBody(stream)),
|
||||||
|
responseType: stream ? "stream" : "json"
|
||||||
|
};
|
||||||
|
return await axios(config);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function getBody(stream: boolean) {
|
||||||
return {
|
return {
|
||||||
"messages": messageList,
|
"messages": messageList,
|
||||||
"model": "deepseek-v4-flash",
|
"model": model ?? "deepseek-v4-flash",
|
||||||
"thinking": {
|
"thinking": {
|
||||||
"type": "enabled"
|
"type": "enabled"
|
||||||
},
|
},
|
||||||
@ -60,28 +259,13 @@ function getBody() {
|
|||||||
"type": "text"
|
"type": "text"
|
||||||
},
|
},
|
||||||
"stop": null,
|
"stop": null,
|
||||||
"stream": false,
|
"stream": stream,
|
||||||
"stream_options": null,
|
|
||||||
"temperature": 1,
|
"temperature": 1,
|
||||||
"top_p": 1,
|
"top_p": 1,
|
||||||
"tools": null,
|
"tools": tools,
|
||||||
"tool_choice": "none",
|
"tool_choice": "auto",
|
||||||
"logprobs": false,
|
"logprobs": false,
|
||||||
"top_logprobs": null
|
"top_logprobs": null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function getMessageList() {
|
|
||||||
if (!messageList) {
|
|
||||||
return "[]"
|
|
||||||
}
|
|
||||||
let messageListStr = "["
|
|
||||||
for (let message of messageList) {
|
|
||||||
if (messageListStr == "[") {
|
|
||||||
messageListStr += ","
|
|
||||||
}
|
|
||||||
messageListStr += "{\"" + message.content + "\"," + "\"" + message.role + "\"}"
|
|
||||||
}
|
|
||||||
messageListStr = messageListStr.slice(0, -1) + "]"
|
|
||||||
return messageListStr;
|
|
||||||
}
|
|
||||||
|
|||||||
3
src/tools/list_files.ts
Normal file
3
src/tools/list_files.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import { readdir } from "node:fs/promises";
|
||||||
|
const files = await readdir("./src");
|
||||||
|
console.log(files);
|
||||||
59
src/types/message.ts
Normal file
59
src/types/message.ts
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
|
||||||
|
export interface MessageResponse {
|
||||||
|
id?: string;
|
||||||
|
object?: string;
|
||||||
|
created?: number;
|
||||||
|
model?: string;
|
||||||
|
system_fingerprint?: string;
|
||||||
|
choices?: Choice[];
|
||||||
|
usage?: Usage;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Choice {
|
||||||
|
index?: number;
|
||||||
|
delta?: Delta;
|
||||||
|
message?: Message;
|
||||||
|
finish_reason?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Message {
|
||||||
|
content?: string;
|
||||||
|
reasoning_content?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Delta {
|
||||||
|
content?: string;
|
||||||
|
reasoning_content?: string;
|
||||||
|
tool_calls?: ToolCall[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ToolCall {
|
||||||
|
index?: number;
|
||||||
|
id?: string;
|
||||||
|
type?: string;
|
||||||
|
function?: FunctionCall;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export interface FunctionCall {
|
||||||
|
name?: string;
|
||||||
|
arguments?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Usage {
|
||||||
|
prompt_tokens?: number;
|
||||||
|
completion_tokens?: number;
|
||||||
|
total_tokens?: number;
|
||||||
|
prompt_tokens_details?: PromptTokensDetails;
|
||||||
|
completion_tokens_details?: CompletionTokensDetails;
|
||||||
|
prompt_cache_hit_tokens?: number;
|
||||||
|
prompt_cache_miss_tokens?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface PromptTokensDetails {
|
||||||
|
cached_tokens?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CompletionTokensDetails {
|
||||||
|
reasoning_tokens?: number;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user