Add bots files handling logic

This commit is contained in:
2026-10-21 17:56:09 +01:00
parent b0af4db1bf
commit d17a4a7bdd
97 changed files with 5843 additions and 41 deletions
@@ -0,0 +1,68 @@
import { AppData } from "@/src/data/app-data";
import HarnessError from "../../harness-error";
import type { HarnessAdapter } from "../../types";
import grabProviderPreset from "../grab-provider-preset";
import providerRequest from "./provider-request";
/**
* Embeddings at the provider's `embeddings_path` (the OpenAI `/embeddings`
* shape). Batched, since a large file's chunks would otherwise go in one
* request the provider may refuse.
*/
const embed: HarnessAdapter["embed"] = async ({ candidate, input, signal }) => {
const { provider, model } = candidate;
const preset = grabProviderPreset({ kind: provider.kind });
const vectors: number[][] = [];
/**
* Every OpenAI-compatible API puts embeddings at `/embeddings`.
*/
const path = "/embeddings";
for (let start = 0; start < input.length; start += AppData.EmbeddingBatchSize) {
const batch = input
.slice(start, start + AppData.EmbeddingBatchSize)
.map((text) => text.slice(0, AppData.EmbeddingMaxInputChars));
const res = await providerRequest({
provider,
path,
json: { model: model.slug, input: batch },
signal,
candidate_key: candidate.key,
});
const json = await res.json().catch(() => null);
const items: any[] = Array.isArray(json?.data)
? json.data
: Array.isArray(json?.embeddings)
? json.embeddings
: [];
if (items.length != batch.length) {
throw new HarnessError({
message: `${provider.name || preset.title}: ${items.length} of ${batch.length} texts got a vector.`,
retryable: true,
candidate_key: candidate.key,
});
}
for (const item of items) {
const vector = Array.isArray(item) ? item : item?.embedding;
if (!Array.isArray(vector) || !vector.length) {
throw new HarnessError({
message: `${provider.name || preset.title} sent no embedding back.`,
retryable: true,
candidate_key: candidate.key,
});
}
vectors.push(vector.map(Number));
}
}
return { vectors };
};
export default embed;