Skip to content

Commit 122c0da

Browse files
committed
chore: batch & fine-tune improvements
1 parent 25f12bd commit 122c0da

22 files changed

+967
-68
lines changed

package-lock.json

Lines changed: 92 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,9 @@
5151
"async-retry": "^1.3.3",
5252
"avsc": "^5.7.7",
5353
"hono": "^4.6.10",
54+
"patch-package": "^8.0.0",
5455
"ws": "^8.18.0",
55-
"zod": "^3.22.4",
56-
"patch-package": "^8.0.0"
56+
"zod": "^3.22.4"
5757
},
5858
"devDependencies": {
5959
"@cloudflare/workers-types": "^4.20230518.0",

src/globals.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,3 +219,9 @@ export const documentMimeTypes = [
219219
fileExtensionMimeTypeMap.md,
220220
fileExtensionMimeTypeMap.txt,
221221
];
222+
223+
export enum BatchEndpoints {
224+
CHAT_COMPLETIONS = '/v1/chat/completions',
225+
COMPLETIONS = '/v1/completions',
226+
EMBEDDINGS = '/v1/embeddings',
227+
}

src/handlers/handlerUtils.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ import { ConditionalRouter } from '../services/conditionalRouter';
3131
import { RouterError } from '../errors/RouterError';
3232
import { GatewayError } from '../errors/GatewayError';
3333
import { HookType } from '../middlewares/hooks/types';
34+
import { Readable } from 'node:stream';
3435

3536
/**
3637
* Constructs the request options for the API call.
@@ -1058,10 +1059,13 @@ export function constructConfigFromRequestHeaders(
10581059
requestHeaders[`x-${POWERED_BY}-vertex-storage-bucket-name`],
10591060
filename: requestHeaders[`x-${POWERED_BY}-provider-file-name`],
10601061
vertexModelName: requestHeaders[`x-${POWERED_BY}-provider-model`],
1062+
vertexBatchEndpoint:
1063+
requestHeaders[`x-${POWERED_BY}-provider-batch-endpoint`],
10611064
};
10621065

10631066
const fireworksConfig = {
10641067
fireworksAccountId: requestHeaders[`x-${POWERED_BY}-fireworks-account-id`],
1068+
fireworksFileLength: requestHeaders[`x-${POWERED_BY}-file-upload-size`],
10651069
};
10661070

10671071
const anthropicConfig = {

src/handlers/streamHandlerUtils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -309,7 +309,7 @@ export function createLineSplitter(): TransformStream {
309309
leftover = lines.pop() || '';
310310
for (const line of lines) {
311311
if (line.trim()) {
312-
controller.enqueue(line);
312+
controller.enqueue(line.trim());
313313
}
314314
}
315315
return;

src/providers/fireworks-ai/api.ts

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,23 @@ const FireworksAIAPIConfig: ProviderAPIConfig = {
2121
Accept: 'application/json',
2222
};
2323
},
24-
getEndpoint: ({ fn, gatewayRequestBodyJSON: gatewayRequestBody, c }) => {
24+
getEndpoint: ({
25+
fn,
26+
gatewayRequestBodyJSON: gatewayRequestBody,
27+
c,
28+
gatewayRequestURL,
29+
}) => {
2530
const model = gatewayRequestBody?.model;
31+
32+
const jobIdIndex = ['cancelFinetune'].includes(fn ?? '') ? -2 : -1;
33+
const jobId = gatewayRequestURL.split('/').at(jobIdIndex);
34+
35+
const url = new URL(gatewayRequestURL);
36+
const params = url.searchParams;
37+
38+
const size = params.get('limit') ?? 50;
39+
const page = params.get('after') ?? '1';
40+
2641
switch (fn) {
2742
case 'complete':
2843
return '/completions';
@@ -33,7 +48,7 @@ const FireworksAIAPIConfig: ProviderAPIConfig = {
3348
case 'imageGenerate':
3449
return `/image_generation/${model}`;
3550
case 'uploadFile':
36-
return `/datasets`;
51+
return '';
3752
case 'retrieveFile': {
3853
const datasetId = c.req.param('id');
3954
return `/datasets/${datasetId}`;
@@ -45,13 +60,13 @@ const FireworksAIAPIConfig: ProviderAPIConfig = {
4560
return `/datasets/${datasetId}`;
4661
}
4762
case 'createFinetune':
48-
return `/fineTuningJobs`;
63+
return `/supervisedFineTuningJobs`;
4964
case 'retrieveFinetune':
50-
return `/fineTuningJobs/${c.req.param('jobId')}`;
65+
return `/supervisedFineTuningJobs/${jobId}`;
5166
case 'listFinetunes':
52-
return `/fineTuningJobs`;
67+
return `/supervisedFineTuningJobs?pageToken=${page}&pageSize=${size}`;
5368
case 'cancelFinetune':
54-
return `/fineTuningJobs/${c.req.param('jobId')}`;
69+
return `/supervisedFineTuningJobs/${jobId}`;
5570
default:
5671
return '';
5772
}
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
import { FIREWORKS_AI } from '../../globals';
2+
import { Params } from '../../types/requestBody';
3+
import { RequestHandler } from '../types';
4+
import FireworksAIAPIConfig from './api';
5+
import { fireworkFinetuneToOpenAIFinetune } from './utils';
6+
7+
export const FireworkCancelFinetuneResponseTransform = (
8+
response: any,
9+
status: number
10+
) => {
11+
if (status !== 200) {
12+
const error = response?.error || 'Failed to cancel finetune';
13+
return new Response(JSON.stringify({ error: { message: error } }), {
14+
status: status || 500,
15+
});
16+
}
17+
18+
return fireworkFinetuneToOpenAIFinetune(response);
19+
};
20+
21+
export const FireworksCancelFinetuneRequestHandler: RequestHandler<
22+
Params
23+
> = async ({ requestBody, requestURL, providerOptions, c }) => {
24+
const headers = await FireworksAIAPIConfig.headers({
25+
c,
26+
fn: 'cancelFinetune',
27+
providerOptions,
28+
transformedRequestUrl: requestURL,
29+
transformedRequestBody: requestBody,
30+
});
31+
32+
const baseURL = await FireworksAIAPIConfig.getBaseURL({
33+
c,
34+
gatewayRequestURL: requestURL,
35+
providerOptions,
36+
});
37+
38+
const endpoint = FireworksAIAPIConfig.getEndpoint({
39+
c,
40+
fn: 'cancelFinetune',
41+
gatewayRequestBodyJSON: requestBody,
42+
gatewayRequestURL: requestURL,
43+
providerOptions,
44+
});
45+
46+
try {
47+
const request = await fetch(baseURL + endpoint, {
48+
method: 'DELETE',
49+
headers,
50+
body: JSON.stringify(requestBody),
51+
});
52+
53+
if (!request.ok) {
54+
const error = await request.json();
55+
return new Response(
56+
JSON.stringify({
57+
error: { message: (error as any).error },
58+
provider: FIREWORKS_AI,
59+
}),
60+
{
61+
status: 500,
62+
headers: {
63+
'Content-Type': 'application/json',
64+
},
65+
}
66+
);
67+
}
68+
69+
const response = await request.json();
70+
71+
const mappedResponse = fireworkFinetuneToOpenAIFinetune(response as any);
72+
73+
return new Response(JSON.stringify(mappedResponse), {
74+
status: 200,
75+
headers: { 'Content-Type': 'application/json' },
76+
});
77+
} catch (error) {
78+
const errorMessage =
79+
error instanceof Error ? error.message : 'Unknown error';
80+
return new Response(JSON.stringify({ error: { message: errorMessage } }), {
81+
status: 500,
82+
});
83+
}
84+
};

0 commit comments

Comments
 (0)