Spaces:
Running
Running
Update app.js
Browse files
app.js
CHANGED
@@ -63,81 +63,102 @@ function getLocation() {
|
|
63 |
}
|
64 |
|
65 |
function constructApiUrl(location) {
|
66 |
-
|
|
|
|
|
67 |
}
|
68 |
|
69 |
async function handleRequest(request) {
|
70 |
-
|
71 |
-
|
72 |
-
|
|
|
73 |
|
74 |
-
|
75 |
-
|
76 |
-
|
77 |
-
status: 403,
|
78 |
-
headers: {
|
79 |
-
'Content-Type': 'application/json',
|
80 |
-
'Access-Control-Allow-Origin': '*',
|
81 |
-
'Access-Control-Allow-Methods': 'POST, GET, OPTIONS, DELETE, HEAD',
|
82 |
-
'Access-Control-Allow-Headers': 'Content-Type, Authorization, x-api-key, anthropic-version, model'
|
83 |
-
},
|
84 |
-
body: JSON.stringify({
|
85 |
type: "error",
|
86 |
error: {
|
87 |
type: "permission_error",
|
88 |
message: "Your API key does not have permission to use the specified resource."
|
89 |
}
|
90 |
-
})
|
91 |
-
}
|
92 |
|
93 |
-
|
94 |
-
|
|
|
95 |
|
96 |
-
|
97 |
-
|
98 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
99 |
|
100 |
-
|
101 |
-
|
102 |
-
|
103 |
-
|
104 |
-
|
105 |
-
|
106 |
-
if (requestBody.model) {
|
107 |
-
delete requestBody.model;
|
108 |
-
}
|
109 |
-
|
110 |
-
requestBody.anthropic_version = "vertex-2023-10-16";
|
111 |
|
112 |
-
|
113 |
-
|
114 |
-
|
115 |
-
|
116 |
-
|
117 |
-
|
118 |
|
119 |
-
|
120 |
-
|
121 |
-
|
122 |
-
|
123 |
-
|
124 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
125 |
|
126 |
-
|
127 |
-
|
128 |
-
const modifiedResponse = {
|
129 |
status: response.status,
|
130 |
-
statusText: response.statusText,
|
131 |
headers: {
|
132 |
...response.headers,
|
133 |
'Access-Control-Allow-Origin': '*',
|
134 |
'Access-Control-Allow-Methods': 'POST, GET, OPTIONS',
|
135 |
'Access-Control-Allow-Headers': 'Content-Type, Authorization, x-api-key, anthropic-version, model'
|
136 |
},
|
137 |
-
body:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
138 |
};
|
139 |
-
|
140 |
-
return modifiedResponse;
|
141 |
}
|
142 |
|
143 |
function handleOptions() {
|
@@ -163,7 +184,7 @@ const server = http.createServer(async (req, res) => {
|
|
163 |
};
|
164 |
|
165 |
const response = await handleRequest(request);
|
166 |
-
res.writeHead(response.status, response.
|
167 |
res.end(response.body);
|
168 |
} else {
|
169 |
res.writeHead(404, { 'Content-Type': 'application/json' });
|
|
|
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() {
|
|
|
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' });
|