Bypass auth
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1 +1,2 @@
|
||||
node_modules
|
||||
node_modules
|
||||
.env
|
||||
@@ -3,6 +3,10 @@
|
||||

|
||||
|
||||
## Usage
|
||||
0. Install Claude Code
|
||||
```shell
|
||||
npm install -g @anthropic-ai/claude-code
|
||||
```
|
||||
1. Clone this repo
|
||||
```shell
|
||||
git clone git@github.com:musistudio/claude-code-reverse.git
|
||||
@@ -23,6 +27,7 @@ node index.mjs
|
||||
5. Set environment variable
|
||||
```shell
|
||||
export DISABLE_PROMPT_CACHING=1
|
||||
export ANTHROPIC_AUTH_TOKEN="test"
|
||||
export ANTHROPIC_BASE_URL="http://127.0.0.1:3456"
|
||||
```
|
||||
|
||||
|
||||
73
index.mjs
73
index.mjs
@@ -1,14 +1,23 @@
|
||||
import express from "express";
|
||||
import { OpenAI } from "openai";
|
||||
import dotenv from 'dotenv';
|
||||
|
||||
// Load environment variables
|
||||
dotenv.config();
|
||||
|
||||
const app = express();
|
||||
const port = 3456;
|
||||
|
||||
app.use(express.json());
|
||||
app.use(express.json({limit:'500mb'}));
|
||||
|
||||
// Read variables from .env file
|
||||
const apiKey = process.env.OPENAI_API_KEY;
|
||||
const baseUrl = process.env.OPENAI_BASE_URL;
|
||||
const defaultModel = process.env.OPENAI_MODEL;
|
||||
|
||||
const chatClient = new OpenAI({
|
||||
apiKey: "",
|
||||
baseURL: "",
|
||||
apiKey: apiKey,
|
||||
baseURL: baseUrl,
|
||||
});
|
||||
|
||||
// Define POST /v1/messages interface
|
||||
@@ -28,12 +37,17 @@ app.post("/v1/messages", async (req, res) => {
|
||||
return {
|
||||
role: item.role,
|
||||
content: item.content.map((it) => {
|
||||
return {
|
||||
const msg = {
|
||||
...it,
|
||||
type: ["tool_result", "tool_use"].includes(it?.type)
|
||||
? "text"
|
||||
: it?.type,
|
||||
text: it?.content || it?.text || "",
|
||||
};
|
||||
if (msg.type === 'text') {
|
||||
msg.text = it?.content ? JSON.stringify(it.content) : it?.text || ""
|
||||
delete msg.content
|
||||
}
|
||||
return msg;
|
||||
}),
|
||||
};
|
||||
}
|
||||
@@ -43,7 +57,7 @@ app.post("/v1/messages", async (req, res) => {
|
||||
};
|
||||
});
|
||||
const data = {
|
||||
model: "qwen-max-2025-01-25",
|
||||
model: defaultModel,
|
||||
messages: [
|
||||
...system.map((item) => ({
|
||||
role: "system",
|
||||
@@ -100,7 +114,6 @@ app.post("/v1/messages", async (req, res) => {
|
||||
|
||||
for await (const chunk of completion) {
|
||||
const delta = chunk.choices[0].delta;
|
||||
|
||||
// Handle tool call response
|
||||
if (delta.tool_calls && delta.tool_calls.length > 0) {
|
||||
const toolCall = delta.tool_calls[0];
|
||||
@@ -237,9 +250,7 @@ app.post("/v1/messages", async (req, res) => {
|
||||
};
|
||||
|
||||
res.write(
|
||||
`event: content_block_stop\ndata: ${JSON.stringify(
|
||||
contentBlockStop
|
||||
)}\n\n`
|
||||
`event: content_block_stop\ndata: ${JSON.stringify(contentBlockStop)}\n\n`
|
||||
);
|
||||
|
||||
// Send message_delta event with appropriate stop_reason
|
||||
@@ -254,9 +265,7 @@ app.post("/v1/messages", async (req, res) => {
|
||||
};
|
||||
|
||||
res.write(
|
||||
`event: message_delta\ndata: ${JSON.stringify(
|
||||
messageDelta
|
||||
)}\n\n`
|
||||
`event: message_delta\ndata: ${JSON.stringify(messageDelta)}\n\n`
|
||||
);
|
||||
|
||||
// Send message_stop event
|
||||
@@ -264,11 +273,7 @@ app.post("/v1/messages", async (req, res) => {
|
||||
type: "message_stop",
|
||||
};
|
||||
|
||||
res.write(
|
||||
`event: message_stop\ndata: ${JSON.stringify(
|
||||
messageStop
|
||||
)}\n\n`
|
||||
);
|
||||
res.write(`event: message_stop\ndata: ${JSON.stringify(messageStop)}\n\n`);
|
||||
res.end();
|
||||
} catch (error) {
|
||||
console.error("Error in streaming response:", error);
|
||||
@@ -279,6 +284,32 @@ app.post("/v1/messages", async (req, res) => {
|
||||
}
|
||||
});
|
||||
|
||||
app.listen(port, () => {
|
||||
console.log(`Example app listening on port ${port}`);
|
||||
});
|
||||
import { existsSync, writeFileSync } from 'fs';
|
||||
|
||||
async function initializeClaudeConfig() {
|
||||
const homeDir = process.env.HOME;
|
||||
const configPath = `${homeDir}/.claude.json`;
|
||||
|
||||
if (!existsSync(configPath)) {
|
||||
const userID = Array.from({ length: 64 }, () => Math.random().toString(16)[2]).join('');
|
||||
const configContent = {
|
||||
numStartups: 184,
|
||||
autoUpdaterStatus: "enabled",
|
||||
userID,
|
||||
hasCompletedOnboarding: true,
|
||||
lastOnboardingVersion: "0.2.9",
|
||||
projects: {}
|
||||
};
|
||||
|
||||
writeFileSync(configPath, JSON.stringify(configContent, null, 2));
|
||||
}
|
||||
}
|
||||
|
||||
async function run() {
|
||||
await initializeClaudeConfig();
|
||||
|
||||
app.listen(port, () => {
|
||||
console.log(`Example app listening on port ${port}`);
|
||||
});
|
||||
}
|
||||
run()
|
||||
12
package-lock.json
generated
12
package-lock.json
generated
@@ -9,6 +9,7 @@
|
||||
"version": "1.0.0",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"dotenv": "^16.4.7",
|
||||
"express": "^4.21.2",
|
||||
"openai": "^4.85.4"
|
||||
}
|
||||
@@ -208,6 +209,17 @@
|
||||
"npm": "1.2.8000 || >= 1.4.16"
|
||||
}
|
||||
},
|
||||
"node_modules/dotenv": {
|
||||
"version": "16.4.7",
|
||||
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.7.tgz",
|
||||
"integrity": "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ==",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://dotenvx.com"
|
||||
}
|
||||
},
|
||||
"node_modules/dunder-proto": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"dotenv": "^16.4.7",
|
||||
"express": "^4.21.2",
|
||||
"openai": "^4.85.4"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user