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 query = "";
|
||||||
let model = "MiniLM";
|
let model = "MiniLM";
|
||||||
|
let customEmbeddingUrl = "";
|
||||||
let data:string[] = [];
|
let data:string[] = [];
|
||||||
let dataresult:[string, number][] = [];
|
let dataresult:[string, number][] = [];
|
||||||
let running = false;
|
let running = false;
|
||||||
@@ -15,7 +16,7 @@
|
|||||||
const run = async () => {
|
const run = async () => {
|
||||||
if(running) return;
|
if(running) return;
|
||||||
running = true;
|
running = true;
|
||||||
const processer = new HypaProcesser(model as any);
|
const processer = new HypaProcesser(model as any, customEmbeddingUrl);
|
||||||
await processer.addText(data);
|
await processer.addText(data);
|
||||||
console.log(processer.vectors)
|
console.log(processer.vectors)
|
||||||
dataresult = await processer.similaritySearchScored(query);
|
dataresult = await processer.similaritySearchScored(query);
|
||||||
@@ -29,8 +30,14 @@
|
|||||||
<SelectInput bind:value={model}>
|
<SelectInput bind:value={model}>
|
||||||
<OptionInput value="MiniLM">MiniLM L6 v2</OptionInput>
|
<OptionInput value="MiniLM">MiniLM L6 v2</OptionInput>
|
||||||
<OptionInput value="nomic">Nomic Embed Text v1.5</OptionInput>
|
<OptionInput value="nomic">Nomic Embed Text v1.5</OptionInput>
|
||||||
|
<OptionInput value="custom">Custom (OpenAI-compatible)</OptionInput>
|
||||||
</SelectInput>
|
</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>
|
<span class="text-textcolor text-lg">Query</span>
|
||||||
<TextInput bind:value={query} size="lg" fullwidth />
|
<TextInput bind:value={query} size="lg" fullwidth />
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,24 @@
|
|||||||
import localforage from "localforage";
|
import localforage from "localforage";
|
||||||
import { globalFetch } from "src/ts/storage/globalApi";
|
import { globalFetch } from "src/ts/storage/globalApi";
|
||||||
import { runEmbedding } from "../transformers";
|
import { runEmbedding } from "../transformers";
|
||||||
|
import { alertError } from "src/ts/alert";
|
||||||
|
import { appendLastPath } from "src/ts/util";
|
||||||
|
|
||||||
|
|
||||||
export class HypaProcesser{
|
export class HypaProcesser{
|
||||||
oaikey:string
|
oaikey:string
|
||||||
vectors:memoryVector[]
|
vectors:memoryVector[]
|
||||||
forage:LocalForage
|
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({
|
this.forage = localforage.createInstance({
|
||||||
name: "hypaVector"
|
name: "hypaVector"
|
||||||
})
|
})
|
||||||
this.vectors = []
|
this.vectors = []
|
||||||
this.model = model
|
this.model = model
|
||||||
|
this.customEmbeddingUrl = customEmbeddingUrl
|
||||||
}
|
}
|
||||||
|
|
||||||
async embedDocuments(texts: string[]): Promise<VectorArray[]> {
|
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')
|
let results:Float32Array[] = await runEmbedding(inputs, this.model === 'nomic' ? 'nomic-ai/nomic-embed-text-v1.5' : 'Xenova/all-MiniLM-L6-v2')
|
||||||
return results
|
return results
|
||||||
}
|
}
|
||||||
const gf = await globalFetch("https://api.openai.com/v1/embeddings", {
|
let gf = null;
|
||||||
headers: {
|
if(this.model === 'custom'){
|
||||||
"Authorization": "Bearer " + this.oaikey
|
if(!this.customEmbeddingUrl){
|
||||||
},
|
alertError('Custom model requires a Custom Server URL')
|
||||||
body: {
|
return [0]
|
||||||
"input": input,
|
|
||||||
"model": "text-embedding-ada-002"
|
|
||||||
}
|
}
|
||||||
})
|
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
|
const data = gf.data
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -492,4 +492,34 @@ export function trimUntilPunctuation(s:string){
|
|||||||
result = result.slice(0, -1)
|
result = result.slice(0, -1)
|
||||||
}
|
}
|
||||||
return result
|
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