feat: 后端代理层(Jev 透传 + ASR 预留端点),前端支持代理模式
This commit is contained in:
+23
-11
@@ -64,21 +64,30 @@ export interface JevClient {
|
||||
|
||||
const API_URL = 'https://api.typesafe.ai/v1/systemone';
|
||||
|
||||
/** 直连 REST 的实现。浏览器调用可能遇到 CORS,正式环境需走后端代理(见 README)。 */
|
||||
/**
|
||||
* REST 实现,两种模式:
|
||||
* - 代理模式(优先):传 proxyUrl,请求发到 `${proxyUrl}/api/jev`,key 在服务端,
|
||||
* 前端不带 Authorization(见 server/ 子包);
|
||||
* - 直连模式(fallback):传 apiKey,直连 api.typesafe.ai,浏览器可能遇到 CORS。
|
||||
*/
|
||||
export class HttpJevClient implements JevClient {
|
||||
private apiKey: string;
|
||||
private apiKey?: string;
|
||||
private proxyUrl?: string;
|
||||
|
||||
constructor(apiKey: string) {
|
||||
constructor(apiKey?: string, proxyUrl?: string) {
|
||||
this.apiKey = apiKey;
|
||||
this.proxyUrl = proxyUrl;
|
||||
}
|
||||
|
||||
async ask(state: unknown, questions: Record<string, JevQuestion>): Promise<Record<string, JevAnswer>> {
|
||||
const res = await fetch(API_URL, {
|
||||
const url = this.proxyUrl ? `${this.proxyUrl}/api/jev` : API_URL;
|
||||
const headers: Record<string, string> = { 'Content-Type': 'application/json' };
|
||||
if (!this.proxyUrl && this.apiKey) {
|
||||
headers.Authorization = `Bearer ${this.apiKey}`;
|
||||
}
|
||||
const res = await fetch(url, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
Authorization: `Bearer ${this.apiKey}`,
|
||||
},
|
||||
headers,
|
||||
body: JSON.stringify({ model: 'jev-latest', state, questions } satisfies JevRequest),
|
||||
});
|
||||
if (!res.ok) {
|
||||
@@ -156,14 +165,17 @@ export class MockJevClient implements JevClient {
|
||||
|
||||
let singleton: JevClient | null = null;
|
||||
|
||||
/** key 缺失时自动降级 Mock 并提示。 */
|
||||
/** 有代理走代理,有 key 直连,两者都缺时降级 Mock 并提示。 */
|
||||
export function getJevClient(): JevClient {
|
||||
if (singleton) return singleton;
|
||||
const proxyUrl = import.meta.env.VITE_JEV_PROXY_URL;
|
||||
const key = import.meta.env.VITE_TYPESAFE_API_KEY;
|
||||
if (key) {
|
||||
if (proxyUrl) {
|
||||
singleton = new HttpJevClient(undefined, proxyUrl);
|
||||
} else if (key) {
|
||||
singleton = new HttpJevClient(key);
|
||||
} else {
|
||||
console.warn('[jev] 未配置 VITE_TYPESAFE_API_KEY,降级为 MockJevClient(确定性伪随机返分)');
|
||||
console.warn('[jev] 未配置 VITE_JEV_PROXY_URL / VITE_TYPESAFE_API_KEY,降级为 MockJevClient(确定性伪随机返分)');
|
||||
singleton = new MockJevClient();
|
||||
}
|
||||
return singleton;
|
||||
|
||||
Reference in New Issue
Block a user