Compare commits
4 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5cd21c570f | ||
|
|
c5e97709a5 | ||
|
|
f7adb7b28e | ||
|
|
7964fff175 |
17
README.md
17
README.md
@@ -1,10 +1,13 @@
|
||||
# Claude Code Router
|
||||

|
||||
|
||||
[](README_zh.md)
|
||||
[](https://discord.gg/rdftVMaUcS)
|
||||
[](https://github.com/musistudio/claude-code-router/blob/main/LICENSE)
|
||||
|
||||
<hr>
|
||||
|
||||
I am seeking funding support for this project to better sustain its development. If you have any ideas, feel free to reach out to me: [m@musiiot.top](mailto:m@musiiot.top)
|
||||
|
||||
|
||||
[中文版](README_zh.md)
|
||||
|
||||
> A powerful tool to route Claude Code requests to different models and customize any request.
|
||||
|
||||
> Now you can use models such as `GLM-4.5`, `Kimi-K2`, `Qwen3-Coder-480B-A35B`, and `DeepSeek v3.1` for free through the [iFlow Platform](https://platform.iflow.cn/docs/api-mode).
|
||||
@@ -13,6 +16,8 @@ I am seeking funding support for this project to better sustain its development.
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
## ✨ Features
|
||||
|
||||
- **Model Routing**: Route requests to different models based on your needs (e.g., background tasks, thinking, long context).
|
||||
@@ -572,6 +577,8 @@ A huge thank you to all our sponsors for their generous support!
|
||||
- @\*更
|
||||
- @\*.
|
||||
- @F\*t
|
||||
|
||||
- @\*政
|
||||
- @\*铭
|
||||
- @\*叶
|
||||
|
||||
(If your name is masked, please contact me via my homepage email to update it with your GitHub username.)
|
||||
|
||||
14
README_zh.md
14
README_zh.md
@@ -1,4 +1,10 @@
|
||||
# Claude Code Router
|
||||

|
||||
|
||||
[](README.md)
|
||||
[](https://discord.gg/rdftVMaUcS)
|
||||
[](https://github.com/musistudio/claude-code-router/blob/main/LICENSE)
|
||||
|
||||
<hr>
|
||||
|
||||
我正在为该项目寻求资金支持,以更好地维持其发展。如果您有任何想法,请随时与我联系: [m@musiiot.top](mailto:m@musiiot.top)
|
||||
|
||||
@@ -10,6 +16,9 @@
|
||||
|
||||

|
||||
|
||||

|
||||
|
||||
|
||||
## ✨ 功能
|
||||
|
||||
- **模型路由**: 根据您的需求将请求路由到不同的模型(例如,后台任务、思考、长上下文)。
|
||||
@@ -541,6 +550,9 @@ jobs:
|
||||
- @\*更
|
||||
- @\*.
|
||||
- @F\*t
|
||||
- @\*政
|
||||
- @\*铭
|
||||
- @\*叶
|
||||
|
||||
(如果您的名字被屏蔽,请通过我的主页电子邮件与我联系,以便使用您的 GitHub 用户名进行更新。)
|
||||
|
||||
|
||||
BIN
blog/images/claude-code-router-img.png
Normal file
BIN
blog/images/claude-code-router-img.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 29 KiB |
67
blog/images/roadmap.svg
Normal file
67
blog/images/roadmap.svg
Normal file
@@ -0,0 +1,67 @@
|
||||
<svg viewBox="0 0 1200 420" xmlns="http://www.w3.org/2000/svg">
|
||||
<defs>
|
||||
<style>
|
||||
.road { stroke: #7aa2ff; stroke-width: 6; fill: none; filter: drop-shadow(0 6px 18px rgba(122,162,255,0.25)); }
|
||||
.dash { stroke: rgba(122,162,255,0.25); stroke-width: 6; fill: none; stroke-dasharray: 2 18; }
|
||||
.node { filter: drop-shadow(0 3px 10px rgba(126,240,193,0.35)); }
|
||||
.node-circle { fill: #7ef0c1; }
|
||||
.node-core { fill: #181b22; stroke: white; stroke-width: 1.5; }
|
||||
.label-bg { fill: rgba(24,27,34,0.8); stroke: rgba(255,255,255,0.12); rx: 12; }
|
||||
.label-text { fill: #e8ecf1; font-weight: 700; font-size: 14px; font-family: Arial, sans-serif; }
|
||||
.label-sub { fill: #9aa6b2; font-weight: 500; font-size: 12px; font-family: Arial, sans-serif; }
|
||||
.spark { fill: none; stroke: #ffd36e; stroke-width: 1.6; stroke-linecap: round; }
|
||||
</style>
|
||||
</defs>
|
||||
|
||||
<!-- Background road with dash -->
|
||||
<path class="dash" d="M60,330 C320,260 460,100 720,160 C930,205 990,260 1140,260"/>
|
||||
|
||||
<!-- Main road -->
|
||||
<path class="road" d="M60,330 C320,260 460,100 720,160 C930,205 990,260 1140,260"/>
|
||||
|
||||
<!-- New Documentation Node -->
|
||||
<g class="node" transform="translate(200,280)">
|
||||
<circle class="node-circle" r="10"/>
|
||||
<circle class="node-core" r="6"/>
|
||||
</g>
|
||||
|
||||
<!-- New Documentation Label -->
|
||||
<g transform="translate(80,120)">
|
||||
<rect class="label-bg" width="260" height="92"/>
|
||||
<text class="label-text" x="16" y="34">New Documentation</text>
|
||||
<text class="label-sub" x="16" y="58">Clear structure, examples & best practices</text>
|
||||
</g>
|
||||
|
||||
<!-- Plugin Marketplace Node -->
|
||||
<g class="node" transform="translate(640,150)">
|
||||
<circle class="node-circle" r="10"/>
|
||||
<circle class="node-core" r="6"/>
|
||||
</g>
|
||||
|
||||
<!-- Plugin Marketplace Label -->
|
||||
<g transform="translate(560,20)">
|
||||
<rect class="label-bg" width="320" height="100"/>
|
||||
<text class="label-text" x="16" y="34">Plugin Marketplace</text>
|
||||
<text class="label-sub" x="16" y="58">Community submissions, ratings & version constraints</text>
|
||||
</g>
|
||||
|
||||
<!-- One More Thing Node -->
|
||||
<g class="node" transform="translate(1080,255)">
|
||||
<circle class="node-circle" r="10"/>
|
||||
<circle class="node-core" r="6"/>
|
||||
</g>
|
||||
|
||||
<!-- One More Thing Label -->
|
||||
<g transform="translate(940,300)">
|
||||
<rect class="label-bg" width="250" height="86"/>
|
||||
<text class="label-text" x="16" y="34">One More Thing</text>
|
||||
<text class="label-sub" x="16" y="58">🚀 Confidential project · Revealing soon</text>
|
||||
</g>
|
||||
|
||||
<!-- Spark decorations -->
|
||||
<g transform="translate(1125,290)">
|
||||
<path class="spark" d="M0 0 L8 0 M4 -4 L4 4"/>
|
||||
<path class="spark" d="M14 -2 L22 -2 M18 -6 L18 2"/>
|
||||
<path class="spark" d="M-10 6 L-2 6 M-6 2 L-6 10"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 2.7 KiB |
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@musistudio/claude-code-router",
|
||||
"version": "1.0.47",
|
||||
"version": "1.0.49",
|
||||
"description": "Use Claude Code without an Anthropics account and route it to another LLM provider",
|
||||
"bin": {
|
||||
"ccr": "./dist/cli.js"
|
||||
@@ -22,6 +22,7 @@
|
||||
"@fastify/static": "^8.2.0",
|
||||
"@musistudio/llms": "^1.0.32",
|
||||
"dotenv": "^16.4.7",
|
||||
"find-process": "^2.0.0",
|
||||
"json5": "^2.2.3",
|
||||
"openurl": "^1.1.1",
|
||||
"rotating-file-stream": "^3.2.7",
|
||||
|
||||
48
pnpm-lock.yaml
generated
48
pnpm-lock.yaml
generated
@@ -17,6 +17,9 @@ importers:
|
||||
dotenv:
|
||||
specifier: ^16.4.7
|
||||
version: 16.6.1
|
||||
find-process:
|
||||
specifier: ^2.0.0
|
||||
version: 2.0.0
|
||||
json5:
|
||||
specifier: ^2.2.3
|
||||
version: 2.2.3
|
||||
@@ -338,6 +341,10 @@ packages:
|
||||
buffer-equal-constant-time@1.0.1:
|
||||
resolution: {integrity: sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==}
|
||||
|
||||
chalk@4.1.2:
|
||||
resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==}
|
||||
engines: {node: '>=10'}
|
||||
|
||||
color-convert@2.0.1:
|
||||
resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
|
||||
engines: {node: '>=7.0.0'}
|
||||
@@ -345,6 +352,10 @@ packages:
|
||||
color-name@1.1.4:
|
||||
resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
|
||||
|
||||
commander@12.1.0:
|
||||
resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
content-disposition@0.5.4:
|
||||
resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==}
|
||||
engines: {node: '>= 0.6'}
|
||||
@@ -460,6 +471,10 @@ packages:
|
||||
resolution: {integrity: sha512-eRoFWQw+Yv2tuYlK2pjFS2jGXSxSppAs3hSQjfxVKxM5amECzIgYYc1FEI8ZmhSh/Ig+FrKEz43NLRKJjYCZVg==}
|
||||
engines: {node: '>=20'}
|
||||
|
||||
find-process@2.0.0:
|
||||
resolution: {integrity: sha512-YUBQnteWGASJoEVVsOXy6XtKAY2O1FCsWnnvQ8y0YwgY1rZiKeVptnFvMu6RSELZAJOGklqseTnUGGs5D0bKmg==}
|
||||
hasBin: true
|
||||
|
||||
foreground-child@3.3.1:
|
||||
resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==}
|
||||
engines: {node: '>=14'}
|
||||
@@ -524,6 +539,10 @@ packages:
|
||||
resolution: {integrity: sha512-+CqsMbHPiSTdtSO14O51eMNlrp9N79gmeqmXeouJOhfucAedHw9noVe/n5uJk3tbKE6a+6ZCQg3RPhVhHByAIw==}
|
||||
engines: {node: '>=18'}
|
||||
|
||||
has-flag@4.0.0:
|
||||
resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
hasown@2.0.2:
|
||||
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@@ -609,6 +628,10 @@ packages:
|
||||
light-my-request@6.6.0:
|
||||
resolution: {integrity: sha512-CHYbu8RtboSIoVsHZ6Ye4cj4Aw/yg2oAFimlF7mNvfDV192LR7nDiKtSIfCuLT7KokPSTn/9kfVLm5OGN0A28A==}
|
||||
|
||||
loglevel@1.9.2:
|
||||
resolution: {integrity: sha512-HgMmCqIJSAKqo68l0rS2AanEWfkxaZ5wNiEFb5ggm08lDs9Xl2KxBlX3PTcaD2chBM1gXAYf491/M2Rv8Jwayg==}
|
||||
engines: {node: '>= 0.6.0'}
|
||||
|
||||
lru-cache@11.1.0:
|
||||
resolution: {integrity: sha512-QIXZUBJUx+2zHUdQujWejBkcD9+cs94tLn0+YL8UrCh+D5sCXZ4c7LaEH48pNwRY3MLDgqUFyhlCyjJPf1WP0A==}
|
||||
engines: {node: 20 || >=22}
|
||||
@@ -865,6 +888,10 @@ packages:
|
||||
resolution: {integrity: sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
supports-color@7.2.0:
|
||||
resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
supports-preserve-symlinks-flag@1.0.0:
|
||||
resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==}
|
||||
engines: {node: '>= 0.4'}
|
||||
@@ -1188,12 +1215,19 @@ snapshots:
|
||||
|
||||
buffer-equal-constant-time@1.0.1: {}
|
||||
|
||||
chalk@4.1.2:
|
||||
dependencies:
|
||||
ansi-styles: 4.3.0
|
||||
supports-color: 7.2.0
|
||||
|
||||
color-convert@2.0.1:
|
||||
dependencies:
|
||||
color-name: 1.1.4
|
||||
|
||||
color-name@1.1.4: {}
|
||||
|
||||
commander@12.1.0: {}
|
||||
|
||||
content-disposition@0.5.4:
|
||||
dependencies:
|
||||
safe-buffer: 5.2.1
|
||||
@@ -1351,6 +1385,12 @@ snapshots:
|
||||
fast-querystring: 1.1.2
|
||||
safe-regex2: 5.0.0
|
||||
|
||||
find-process@2.0.0:
|
||||
dependencies:
|
||||
chalk: 4.1.2
|
||||
commander: 12.1.0
|
||||
loglevel: 1.9.2
|
||||
|
||||
foreground-child@3.3.1:
|
||||
dependencies:
|
||||
cross-spawn: 7.0.6
|
||||
@@ -1458,6 +1498,8 @@ snapshots:
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
|
||||
has-flag@4.0.0: {}
|
||||
|
||||
hasown@2.0.2:
|
||||
dependencies:
|
||||
function-bind: 1.1.2
|
||||
@@ -1538,6 +1580,8 @@ snapshots:
|
||||
process-warning: 4.0.1
|
||||
set-cookie-parser: 2.7.1
|
||||
|
||||
loglevel@1.9.2: {}
|
||||
|
||||
lru-cache@11.1.0: {}
|
||||
|
||||
merge2@1.4.1: {}
|
||||
@@ -1741,6 +1785,10 @@ snapshots:
|
||||
|
||||
strip-eof@1.0.0: {}
|
||||
|
||||
supports-color@7.2.0:
|
||||
dependencies:
|
||||
has-flag: 4.0.0
|
||||
|
||||
supports-preserve-symlinks-flag@1.0.0: {}
|
||||
|
||||
thread-stream@3.1.0:
|
||||
|
||||
@@ -45,7 +45,8 @@ async function waitForService(
|
||||
|
||||
const startTime = Date.now();
|
||||
while (Date.now() - startTime < timeout) {
|
||||
if (isServiceRunning()) {
|
||||
const isRunning = await isServiceRunning()
|
||||
if (isRunning) {
|
||||
// Wait for an additional short period to ensure service is fully ready
|
||||
await new Promise((resolve) => setTimeout(resolve, 500));
|
||||
return true;
|
||||
@@ -56,6 +57,7 @@ async function waitForService(
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const isRunning = await isServiceRunning()
|
||||
switch (command) {
|
||||
case "start":
|
||||
run();
|
||||
@@ -108,7 +110,7 @@ async function main() {
|
||||
});
|
||||
break;
|
||||
case "code":
|
||||
if (!isServiceRunning()) {
|
||||
if (!isRunning) {
|
||||
console.log("Service not running, starting service...");
|
||||
const cliPath = join(__dirname, "cli.js");
|
||||
const startProcess = spawn("node", [cliPath, "start"], {
|
||||
@@ -153,7 +155,7 @@ async function main() {
|
||||
break;
|
||||
case "ui":
|
||||
// Check if service is running
|
||||
if (!isServiceRunning()) {
|
||||
if (!isRunning) {
|
||||
console.log("Service not running, starting service...");
|
||||
const cliPath = join(__dirname, "cli.js");
|
||||
const startProcess = spawn("node", [cliPath, "start"], {
|
||||
|
||||
17
src/index.ts
17
src/index.ts
@@ -51,7 +51,8 @@ interface RunOptions {
|
||||
|
||||
async function run(options: RunOptions = {}) {
|
||||
// Check if service is already running
|
||||
if (isServiceRunning()) {
|
||||
const isRunning = await isServiceRunning()
|
||||
if (isRunning) {
|
||||
console.log("✅ Service is already running in the background.");
|
||||
return;
|
||||
}
|
||||
@@ -244,7 +245,6 @@ async function run(options: RunOptions = {}) {
|
||||
req,
|
||||
config
|
||||
});
|
||||
console.log('result', toolResult)
|
||||
toolMessages.push({
|
||||
"tool_use_id": currentToolId,
|
||||
"type": "tool_result",
|
||||
@@ -295,14 +295,12 @@ async function run(options: RunOptions = {}) {
|
||||
|
||||
// 检查流是否仍然可写
|
||||
if (!controller.desiredSize) {
|
||||
console.log('Stream backpressure detected');
|
||||
break;
|
||||
}
|
||||
|
||||
controller.enqueue(value)
|
||||
}catch (readError: any) {
|
||||
if (readError.name === 'AbortError' || readError.code === 'ERR_STREAM_PREMATURE_CLOSE') {
|
||||
console.log('Stream reading aborted due to client disconnect');
|
||||
abortController.abort(); // 中止所有相关操作
|
||||
break;
|
||||
}
|
||||
@@ -318,7 +316,6 @@ async function run(options: RunOptions = {}) {
|
||||
|
||||
// 处理流提前关闭的错误
|
||||
if (error.code === 'ERR_STREAM_PREMATURE_CLOSE') {
|
||||
console.log('Stream prematurely closed, aborting operations');
|
||||
abortController.abort();
|
||||
return undefined;
|
||||
}
|
||||
@@ -349,7 +346,7 @@ async function run(options: RunOptions = {}) {
|
||||
}
|
||||
} catch (readError: any) {
|
||||
if (readError.name === 'AbortError' || readError.code === 'ERR_STREAM_PREMATURE_CLOSE') {
|
||||
console.log('Background read stream closed prematurely');
|
||||
console.error('Background read stream closed prematurely');
|
||||
} else {
|
||||
console.error('Error in background stream reading:', readError);
|
||||
}
|
||||
@@ -361,6 +358,13 @@ async function run(options: RunOptions = {}) {
|
||||
return done(null, originalStream)
|
||||
}
|
||||
sessionUsageCache.put(req.sessionId, payload.usage);
|
||||
if (typeof payload ==='object') {
|
||||
if (payload.error) {
|
||||
return done(payload.error, null)
|
||||
} else {
|
||||
return done(payload, null)
|
||||
}
|
||||
}
|
||||
}
|
||||
if (typeof payload ==='object' && payload.error) {
|
||||
return done(payload.error, null)
|
||||
@@ -368,7 +372,6 @@ async function run(options: RunOptions = {}) {
|
||||
done(null, payload)
|
||||
});
|
||||
server.addHook("onSend", async (req, reply, payload) => {
|
||||
console.log('主应用onSend')
|
||||
event.emit('onSend', req, reply, payload);
|
||||
return payload;
|
||||
})
|
||||
|
||||
@@ -5,8 +5,9 @@ import { join } from 'path';
|
||||
|
||||
export async function closeService() {
|
||||
const PID_FILE = join(HOME_DIR, '.claude-code-router.pid');
|
||||
const isRunning = await isServiceRunning()
|
||||
|
||||
if (!isServiceRunning()) {
|
||||
if (!isRunning) {
|
||||
console.log("No service is currently running.");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,16 @@
|
||||
import { existsSync, readFileSync, writeFileSync } from 'fs';
|
||||
import { PID_FILE, REFERENCE_COUNT_FILE } from '../constants';
|
||||
import { readConfigFile } from '.';
|
||||
import find from 'find-process';
|
||||
|
||||
export async function isProcessRunning(pid: number): Promise<boolean> {
|
||||
try {
|
||||
const processes = await find('pid', pid);
|
||||
return processes.length > 0;
|
||||
} catch (error) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export function incrementReferenceCount() {
|
||||
let count = 0;
|
||||
@@ -27,15 +37,14 @@ export function getReferenceCount(): number {
|
||||
return parseInt(readFileSync(REFERENCE_COUNT_FILE, 'utf-8')) || 0;
|
||||
}
|
||||
|
||||
export function isServiceRunning(): boolean {
|
||||
export async function isServiceRunning(): Promise<boolean> {
|
||||
if (!existsSync(PID_FILE)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
const pid = parseInt(readFileSync(PID_FILE, 'utf-8'));
|
||||
process.kill(pid, 0);
|
||||
return true;
|
||||
return await isProcessRunning(pid);
|
||||
} catch (e) {
|
||||
// Process not running, clean up pid file
|
||||
cleanupPidFile();
|
||||
@@ -73,7 +82,7 @@ export function getServicePid(): number | null {
|
||||
|
||||
export async function getServiceInfo() {
|
||||
const pid = getServicePid();
|
||||
const running = isServiceRunning();
|
||||
const running = await isServiceRunning();
|
||||
const config = await readConfigFile();
|
||||
const port = config.PORT || 3456;
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ import {
|
||||
} from "@anthropic-ai/sdk/resources/messages";
|
||||
import { get_encoding } from "tiktoken";
|
||||
import { sessionUsageCache, Usage } from "./cache";
|
||||
import { readFile } from 'fs/promises'
|
||||
|
||||
const enc = get_encoding("cl100k_base");
|
||||
|
||||
@@ -147,6 +148,11 @@ export const router = async (req: any, _res: any, context: any) => {
|
||||
}
|
||||
const lastMessageUsage = sessionUsageCache.get(req.sessionId);
|
||||
const { messages, system = [], tools }: MessageCreateParamsBase = req.body;
|
||||
if (config.REWRITE_SYSTEM_PROMPT && system.length > 1 && system[1]?.text?.includes('<env>')) {
|
||||
const prompt = await readFile(config.REWRITE_SYSTEM_PROMPT, 'utf-8');
|
||||
system[1].text = `${prompt}<env>${system[1].text.split('<env>').pop()}`
|
||||
}
|
||||
|
||||
try {
|
||||
const tokenCount = calculateTokenCount(
|
||||
messages as MessageParam[],
|
||||
|
||||
Reference in New Issue
Block a user