smgc commited on
Commit
9b628b5
·
verified ·
1 Parent(s): 5d9ae68

Update app.js

Browse files
Files changed (1) hide show
  1. app.js +68 -131
app.js CHANGED
@@ -1,5 +1,4 @@
1
- const http = require('http');
2
- const url = require('url');
3
  const fetch = require('node-fetch');
4
 
5
  const MODEL = 'claude-3-5-sonnet@20240620';
@@ -46,6 +45,7 @@ async function getAccessToken() {
46
  });
47
 
48
  const data = await response.json();
 
49
  tokenCache.accessToken = data.access_token;
50
  tokenCache.expiry = now + data.expires_in;
51
  } finally {
@@ -63,150 +63,87 @@ function getLocation() {
63
  }
64
 
65
  function constructApiUrl(location) {
66
- const url = `https://${location}-aiplatform.googleapis.com/v1/projects/${PROJECT_ID}/locations/${location}/publishers/anthropic/models/${MODEL}:streamRawPredict`;
67
- console.log('Constructed URL:', url); // 打印URL以验证其正确性
68
- return url;
69
  }
70
 
71
- async function handleRequest(request) {
72
- try {
73
- if (request.method === 'OPTIONS') {
74
- return handleOptions();
75
- }
76
-
77
- const apiKey = request.headers['x-api-key'];
78
- if (apiKey !== API_KEY) {
79
- return handleErrorResponse(403, {
80
- type: "error",
81
- error: {
82
- type: "permission_error",
83
- message: "Your API key does not have permission to use the specified resource."
84
- }
85
- });
86
- }
87
-
88
- const accessToken = await getAccessToken();
89
- const location = getLocation();
90
- const apiUrl = constructApiUrl(location);
91
 
92
- let requestBody = JSON.parse(request.body);
93
-
94
- if (requestBody.anthropic_version) {
95
- delete requestBody.anthropic_version;
96
- }
97
-
98
- if (requestBody.model) {
99
- delete requestBody.model;
100
- }
101
-
102
- requestBody.anthropic_version = "vertex-2023-10-16";
103
-
104
- const modifiedHeaders = {
105
- ...request.headers,
106
- 'Authorization': `Bearer ${accessToken}`,
107
- 'Content-Type': 'application/json; charset=utf-8'
108
- };
109
- delete modifiedHeaders['anthropic-version'];
110
-
111
- const modifiedRequest = {
112
- headers: modifiedHeaders,
113
- method: request.method,
114
- body: JSON.stringify(requestBody),
115
- redirect: 'manual'
116
- };
117
-
118
- const response = await fetch(apiUrl, modifiedRequest);
119
- if (response.status === 301 || response.status === 302) {
120
- const location = response.headers.get('location');
121
- console.log('Redirected to:', location);
122
- const redirectedResponse = await fetch(location, modifiedRequest);
123
- return handleResponse(redirectedResponse);
124
- }
125
- return handleResponse(response);
126
- } catch (error) {
127
- console.error('Error handling request:', error);
128
- return handleErrorResponse(500, {
129
  type: "error",
130
  error: {
131
- type: "internal_error",
132
- message: "Internal server error."
133
  }
134
  });
 
135
  }
136
- }
137
 
138
- function handleResponse(response) {
139
- return {
140
- status: response.status,
141
- headers: {
142
- ...response.headers,
143
- 'Access-Control-Allow-Origin': '*',
144
- 'Access-Control-Allow-Methods': 'POST, GET, OPTIONS',
145
- 'Access-Control-Allow-Headers': 'Content-Type, Authorization, x-api-key, anthropic-version, model'
146
- },
147
- body: response.body
148
- };
149
- }
150
-
151
- function handleErrorResponse(status, body) {
152
- return {
153
- status: status,
154
- headers: {
155
- 'Content-Type': 'application/json',
156
- 'Access-Control-Allow-Origin': '*',
157
- 'Access-Control-Allow-Methods': 'POST, GET, OPTIONS, DELETE, HEAD',
158
- 'Access-Control-Allow-Headers': 'Content-Type, Authorization, x-api-key, anthropic-version, model'
159
- },
160
- body: JSON.stringify(body)
161
- };
162
- }
163
 
164
- function handleOptions() {
165
- const headers = {
166
- 'Access-Control-Allow-Origin': '*',
167
- 'Access-Control-Allow-Methods': 'POST, GET, OPTIONS',
168
- 'Access-Control-Allow-Headers': 'Content-Type, Authorization, x-api-key, anthropic-version, model'
169
- };
170
-
171
- return {
172
- status: 204,
173
- headers: headers
174
- };
175
- }
176
-
177
- const server = http.createServer(async (req, res) => {
178
- const parsedUrl = url.parse(req.url, true);
179
- if (parsedUrl.pathname === '/ai/v1/messages') {
180
- const request = {
181
- method: req.method,
182
- headers: req.headers,
183
- body: await getRequestBody(req)
184
- };
185
-
186
- const response = await handleRequest(request);
187
- res.writeHead(response.status, response.headers);
188
- res.end(response.body);
189
- } else {
190
- res.writeHead(404, { 'Content-Type': 'application/json' });
191
- res.end(JSON.stringify({ error: 'Not Found' }));
192
  }
193
- });
 
 
 
 
 
194
 
195
- function getRequestBody(req) {
196
- return new Promise((resolve, reject) => {
197
- let body = '';
198
- req.on('data', chunk => {
199
- body += chunk.toString();
 
 
 
200
  });
201
- req.on('end', () => {
202
- resolve(body);
 
 
203
  });
204
- req.on('error', err => {
205
- reject(err);
 
 
 
 
 
 
 
 
 
 
 
206
  });
207
- });
208
  }
209
 
210
- server.listen(8080, () => {
211
- console.log('Server is running on port 8080');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
212
  });
 
1
+ const express = require('express');
 
2
  const fetch = require('node-fetch');
3
 
4
  const MODEL = 'claude-3-5-sonnet@20240620';
 
45
  });
46
 
47
  const data = await response.json();
48
+
49
  tokenCache.accessToken = data.access_token;
50
  tokenCache.expiry = now + data.expires_in;
51
  } finally {
 
63
  }
64
 
65
  function constructApiUrl(location) {
66
+ return `https://${location}-aiplatform.googleapis.com/v1/projects/${PROJECT_ID}/locations/${location}/publishers/anthropic/models/${MODEL}:streamRawPredict`;
 
 
67
  }
68
 
69
+ async function handleRequest(req, res) {
70
+ if (req.method === 'OPTIONS') {
71
+ return handleOptions(res);
72
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
73
 
74
+ const apiKey = req.headers['x-api-key'];
75
+ if (apiKey !== API_KEY) {
76
+ res.status(403).json({
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
77
  type: "error",
78
  error: {
79
+ type: "permission_error",
80
+ message: "Your API key does not have permission to use the specified resource."
81
  }
82
  });
83
+ return;
84
  }
 
85
 
86
+ const accessToken = await getAccessToken();
87
+ const location = getLocation();
88
+ const apiUrl = constructApiUrl(location);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
89
 
90
+ let requestBody = req.body;
91
+
92
+ if (requestBody.anthropic_version) {
93
+ delete requestBody.anthropic_version;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
94
  }
95
+
96
+ if (requestBody.model) {
97
+ delete requestBody.model;
98
+ }
99
+
100
+ requestBody.anthropic_version = "vertex-2023-10-16";
101
 
102
+ try {
103
+ const response = await fetch(apiUrl, {
104
+ method: 'POST',
105
+ headers: {
106
+ 'Authorization': `Bearer ${accessToken}`,
107
+ 'Content-Type': 'application/json; charset=utf-8'
108
+ },
109
+ body: JSON.stringify(requestBody)
110
  });
111
+
112
+ res.status(response.status);
113
+ response.headers.forEach((value, name) => {
114
+ res.setHeader(name, value);
115
  });
116
+ res.setHeader('Access-Control-Allow-Origin', '*');
117
+ res.setHeader('Access-Control-Allow-Methods', 'POST, GET, OPTIONS');
118
+ res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, x-api-key, anthropic-version, model');
119
+
120
+ response.body.pipe(res);
121
+ } catch (error) {
122
+ console.error('Error:', error);
123
+ res.status(500).json({
124
+ type: "error",
125
+ error: {
126
+ type: "internal_server_error",
127
+ message: "An unexpected error occurred while processing your request."
128
+ }
129
  });
130
+ }
131
  }
132
 
133
+ function handleOptions(res) {
134
+ res.status(204);
135
+ res.setHeader('Access-Control-Allow-Origin', '*');
136
+ res.setHeader('Access-Control-Allow-Methods', 'POST, GET, OPTIONS');
137
+ res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, x-api-key, anthropic-version, model');
138
+ res.end();
139
+ }
140
+
141
+ const app = express();
142
+ app.use(express.json());
143
+
144
+ app.all('/ai/v1/messages', handleRequest);
145
+
146
+ const PORT = 8080;
147
+ app.listen(PORT, () => {
148
+ console.log(`Server is running on port ${PORT}`);
149
  });