Skip to content

Commit

Permalink
Support embeddings
Browse files Browse the repository at this point in the history
To use model other then default (text-embedding-004)
specify the name with leading "models/".

Ref:
* https://ai.google.dev/api/embeddings#method:-models.batchembedcontents
* https://platform.openai.com/docs/api-reference/embeddings
  • Loading branch information
johnd0e committed Nov 26, 2024
1 parent 951f88d commit 50db26d
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 1 deletion.
2 changes: 1 addition & 1 deletion readme.MD
Original file line number Diff line number Diff line change
Expand Up @@ -146,5 +146,5 @@ the default [model] `gemini-1.5-pro` will be used.

</details>
- [ ] `completions`
- [ ] `embeddings`
- [x] `embeddings`
- [x] `models`
50 changes: 50 additions & 0 deletions src/worker.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ export default {
assert(request.method === "POST");
return handleCompletions(await request.json(), apiKey)
.catch(errHandler);
case pathname.endsWith("/embeddings"):
assert(request.method === "POST");
return handleEmbeddings(await request.json(), apiKey)
.catch(errHandler);
case pathname.endsWith("/models"):
assert(request.method === "GET");
return handleModels(apiKey)
Expand Down Expand Up @@ -92,6 +96,52 @@ async function handleModels (apiKey) {
return new Response(body, { ...response, headers: fixCors(response.headers) });
}

const DEFAULT_EMBEDDINGS_MODEL = "text-embedding-004";
async function handleEmbeddings (req, apiKey) {
if (typeof req.model !== "string") {
throw new HttpError("model is not specified", 400);
}
if (!Array.isArray(req.input)) {
req.input = [ req.input ];
}
let model;
if (req.model.startsWith("models/")) {
model = req.model;
} else {
req.model = DEFAULT_EMBEDDINGS_MODEL;
model = "models/" + req.model;
}
const response = await fetch(`${BASE_URL}/${API_VERSION}/${model}:batchEmbedContents`, {
method: "POST",
headers: {
"Content-Type": "application/json",
"x-goog-api-key": apiKey,
"x-goog-api-client": API_CLIENT,
},
body: JSON.stringify({
"requests": req.input.map(text => ({
model,
content: { parts: { text } },
outputDimensionality: req.dimensions,
}))
})
});
let { body } = response;
if (response.ok) {
const { embeddings } = JSON.parse(await response.text());
body = JSON.stringify({
object: "list",
data: embeddings.map(({ values }, index) => ({
object: "embedding",
index,
embedding: values,
})),
model: req.model,
}, null, " ");
}
return new Response(body, { ...response, headers: fixCors(response.headers) });
}

const DEFAULT_MODEL = "gemini-1.5-pro-latest";
async function handleCompletions (req, apiKey) {
const model = req.model?.startsWith("gemini-") ? req.model : DEFAULT_MODEL;
Expand Down

0 comments on commit 50db26d

Please sign in to comment.