Add support for custom embedding URL in Playground (#391)
# PR Checklist - [x] Did you check if it works normally in all models? *ignore this when it dosen't uses models* - [ ] Did you check if it works normally in all of web, local and node hosted versions? if it dosen't, did you blocked it in those versions? - [ ] Did you added a type def? # Description Add support Openai-compatible custom embedding server on the playground. Openai-compatible embedding servers: https://github.com/toshsan/embedding-server https://github.com/limcheekin/open-text-embeddings https://github.com/michaelfeil/infinity I only tested it with infinity. there is also a feature that If url does not end in /embeddings, automatically adds /embeddings. I think I need to test it with more local embedding servers, but I think it'll be okay since it's only Playground
This commit is contained in:
@@ -8,6 +8,7 @@
|
||||
|
||||
let query = "";
|
||||
let model = "MiniLM";
|
||||
let customEmbeddingUrl = "";
|
||||
let data:string[] = [];
|
||||
let dataresult:[string, number][] = [];
|
||||
let running = false;
|
||||
@@ -15,7 +16,7 @@
|
||||
const run = async () => {
|
||||
if(running) return;
|
||||
running = true;
|
||||
const processer = new HypaProcesser(model as any);
|
||||
const processer = new HypaProcesser(model as any, customEmbeddingUrl);
|
||||
await processer.addText(data);
|
||||
console.log(processer.vectors)
|
||||
dataresult = await processer.similaritySearchScored(query);
|
||||
@@ -29,8 +30,14 @@
|
||||
<SelectInput bind:value={model}>
|
||||
<OptionInput value="MiniLM">MiniLM L6 v2</OptionInput>
|
||||
<OptionInput value="nomic">Nomic Embed Text v1.5</OptionInput>
|
||||
<OptionInput value="custom">Custom (OpenAI-compatible)</OptionInput>
|
||||
</SelectInput>
|
||||
|
||||
{#if model === "custom"}
|
||||
<span class="text-textcolor text-lg">Custom Server URL</span>
|
||||
<TextInput bind:value={customEmbeddingUrl} size="lg" fullwidth />
|
||||
{/if}
|
||||
|
||||
<span class="text-textcolor text-lg">Query</span>
|
||||
<TextInput bind:value={query} size="lg" fullwidth />
|
||||
|
||||
|
||||
@@ -1,20 +1,24 @@
|
||||
import localforage from "localforage";
|
||||
import { globalFetch } from "src/ts/storage/globalApi";
|
||||
import { runEmbedding } from "../transformers";
|
||||
import { alertError } from "src/ts/alert";
|
||||
import { appendLastPath } from "src/ts/util";
|
||||
|
||||
|
||||
export class HypaProcesser{
|
||||
oaikey:string
|
||||
vectors:memoryVector[]
|
||||
forage:LocalForage
|
||||
model:'ada'|'MiniLM'|'nomic'
|
||||
model:'ada'|'MiniLM'|'nomic'|'custom'
|
||||
customEmbeddingUrl:string
|
||||
|
||||
constructor(model:'ada'|'MiniLM'|'nomic'){
|
||||
constructor(model:'ada'|'MiniLM'|'nomic'|'custom',customEmbeddingUrl?:string){
|
||||
this.forage = localforage.createInstance({
|
||||
name: "hypaVector"
|
||||
})
|
||||
this.vectors = []
|
||||
this.model = model
|
||||
this.customEmbeddingUrl = customEmbeddingUrl
|
||||
}
|
||||
|
||||
async embedDocuments(texts: string[]): Promise<VectorArray[]> {
|
||||
@@ -40,15 +44,32 @@ export class HypaProcesser{
|
||||
let results:Float32Array[] = await runEmbedding(inputs, this.model === 'nomic' ? 'nomic-ai/nomic-embed-text-v1.5' : 'Xenova/all-MiniLM-L6-v2')
|
||||
return results
|
||||
}
|
||||
const gf = await globalFetch("https://api.openai.com/v1/embeddings", {
|
||||
headers: {
|
||||
"Authorization": "Bearer " + this.oaikey
|
||||
},
|
||||
body: {
|
||||
"input": input,
|
||||
"model": "text-embedding-ada-002"
|
||||
let gf = null;
|
||||
if(this.model === 'custom'){
|
||||
if(!this.customEmbeddingUrl){
|
||||
alertError('Custom model requires a Custom Server URL')
|
||||
return [0]
|
||||
}
|
||||
})
|
||||
const {customEmbeddingUrl} = this
|
||||
const replaceUrl = customEmbeddingUrl.endsWith('/embeddings')?customEmbeddingUrl:appendLastPath(customEmbeddingUrl,'embeddings')
|
||||
|
||||
gf = await globalFetch(replaceUrl.toString(), {
|
||||
body:{
|
||||
"input": input
|
||||
},
|
||||
})
|
||||
}
|
||||
if(this.model === 'ada'){
|
||||
gf = await globalFetch("https://api.openai.com/v1/embeddings", {
|
||||
headers: {
|
||||
"Authorization": "Bearer " + this.oaikey
|
||||
},
|
||||
body: {
|
||||
"input": input,
|
||||
"model": "text-embedding-ada-002"
|
||||
}
|
||||
})
|
||||
}
|
||||
const data = gf.data
|
||||
|
||||
|
||||
|
||||
@@ -492,4 +492,34 @@ export function trimUntilPunctuation(s:string){
|
||||
result = result.slice(0, -1)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends the given last path to the provided URL.
|
||||
*
|
||||
* @param {string} url - The base URL to which the last path will be appended.
|
||||
* @param {string} lastPath - The path to be appended to the URL.
|
||||
* @returns {string} The modified URL with the last path appended.
|
||||
*
|
||||
* @example
|
||||
* appendLastPath("https://github.com/kwaroran/RisuAI","/commits/main")
|
||||
* return 'https://github.com/kwaroran/RisuAI/commits/main'
|
||||
*
|
||||
* @example
|
||||
* appendLastPath("https://github.com/kwaroran/RisuAI/","/commits/main")
|
||||
* return 'https://github.com/kwaroran/RisuAI/commits/main
|
||||
*
|
||||
* @example
|
||||
* appendLastPath("http://127.0.0.1:7997","embeddings")
|
||||
* return 'http://127.0.0.1:7997/embeddings'
|
||||
*/
|
||||
export function appendLastPath(url, lastPath) {
|
||||
// Remove trailing slash from url if exists
|
||||
url = url.replace(/\/$/, '');
|
||||
|
||||
// Remove leading slash from lastPath if exists
|
||||
lastPath = lastPath.replace(/^\//, '');
|
||||
|
||||
// Concat the url and lastPath
|
||||
return url + '/' + lastPath;
|
||||
}
|
||||
Reference in New Issue
Block a user