Skip to content

Commit 8745524

Browse files
committed
👌 IMPROVE: refactor
1 parent 9fea23c commit 8745524

File tree

1 file changed

+114
-30
lines changed

1 file changed

+114
-30
lines changed

packages/langbase/src/common/request.ts

Lines changed: 114 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -16,56 +16,140 @@ interface RequestConfig {
1616
timeout?: number;
1717
}
1818

19+
interface SendOptions extends RequestOptions {
20+
endpoint: string;
21+
}
22+
23+
interface MakeRequestParams {
24+
url: string;
25+
options: RequestOptions;
26+
headers: Record<string, string>;
27+
}
28+
29+
interface HandleGenerateResponseParams {
30+
response: Response;
31+
isChat: boolean;
32+
threadId: string | null;
33+
}
34+
1935
export class Request {
2036
private config: RequestConfig;
2137

2238
constructor(config: RequestConfig) {
2339
this.config = config;
2440
}
2541

26-
private async send<T>(options: RequestOptions): Promise<T> {
27-
const url = `${this.config.baseUrl}${options.endpoint}`;
28-
const headers = {
29-
'Content-Type': 'application/json',
30-
Authorization: `Bearer ${this.config.apiKey}`,
31-
...options.headers,
32-
};
42+
// Main send function
43+
private async send<T>({endpoint, ...options}: SendOptions): Promise<T> {
44+
const url = this.buildUrl({endpoint});
45+
const headers = this.buildHeaders({headers: options.headers});
3346

3447
let response: Response;
3548
try {
36-
response = await fetch(url, {
37-
method: options.method,
38-
headers,
39-
body: JSON.stringify(options.body),
40-
signal: AbortSignal.timeout(this.config.timeout || 30000),
41-
});
49+
response = await this.makeRequest({url, options, headers});
4250
} catch (error) {
4351
throw new APIConnectionError({
4452
cause: error instanceof Error ? error : undefined,
4553
});
4654
}
4755

4856
if (!response.ok) {
49-
let errorBody;
50-
try {
51-
errorBody = await response.json();
52-
} catch {
53-
errorBody = await response.text();
54-
}
55-
throw APIError.generate(
56-
response.status,
57-
errorBody,
58-
response.statusText,
59-
response.headers as unknown as Headers,
60-
);
57+
await this.handleErrorResponse({response});
6158
}
6259

63-
if (options.stream) {
64-
const controller = new AbortController();
65-
return Stream.fromSSEResponse(response, controller) as unknown as T;
66-
} else {
67-
return response.json();
60+
const threadId = response.headers.get('lb-thread-id');
61+
62+
if (options.body.stream) {
63+
return this.handleStreamResponse({response}) as T;
6864
}
65+
66+
return this.handleGenerateResponse({
67+
response,
68+
isChat: options.body.chat,
69+
threadId,
70+
});
71+
}
72+
73+
private buildUrl({endpoint}: {endpoint: string}): string {
74+
return `${this.config.baseUrl}${endpoint}`;
75+
}
76+
77+
private buildHeaders({
78+
headers,
79+
}: {
80+
headers?: Record<string, string>;
81+
}): Record<string, string> {
82+
return {
83+
'Content-Type': 'application/json',
84+
Authorization: `Bearer ${this.config.apiKey}`,
85+
...headers,
86+
};
87+
}
88+
89+
private async makeRequest({
90+
url,
91+
options,
92+
headers,
93+
}: MakeRequestParams): Promise<Response> {
94+
return fetch(url, {
95+
method: options.method,
96+
headers,
97+
body: JSON.stringify(options.body),
98+
signal: AbortSignal.timeout(this.config.timeout || 30000),
99+
});
100+
}
101+
102+
private async handleErrorResponse({
103+
response,
104+
}: {
105+
response: Response;
106+
}): Promise<never> {
107+
let errorBody;
108+
try {
109+
errorBody = await response.json();
110+
} catch {
111+
errorBody = await response.text();
112+
}
113+
throw APIError.generate(
114+
response.status,
115+
errorBody,
116+
response.statusText,
117+
response.headers as unknown as Headers,
118+
);
119+
}
120+
121+
private handleStreamResponse({response}: {response: Response}): {
122+
stream: any;
123+
threadId: string | null;
124+
} {
125+
const controller = new AbortController();
126+
const stream = Stream.fromSSEResponse(response, controller);
127+
return {stream, threadId: response.headers.get('lb-thread-id')};
128+
}
129+
130+
private async handleGenerateResponse({
131+
response,
132+
isChat,
133+
threadId,
134+
}: HandleGenerateResponseParams): Promise<any> {
135+
const generateResponse = await response.json();
136+
const buildResponse = generateResponse.raw
137+
? {
138+
completion: generateResponse.completion,
139+
...generateResponse.raw,
140+
}
141+
: generateResponse;
142+
143+
// Chat.
144+
if (isChat && threadId) {
145+
return {
146+
threadId,
147+
...buildResponse,
148+
};
149+
}
150+
151+
// Generate.
152+
return buildResponse;
69153
}
70154

71155
async post<T>(options: Omit<RequestOptions, 'method'>): Promise<T> {

0 commit comments

Comments
 (0)