mirror of
https://github.com/ikechan8370/chatgpt-plugin.git
synced 2025-12-16 13:27:08 +00:00
试验性的记忆功能 (#812)
* feat: memory basic * fix: chaite ver * fix: update prompt * fix: memory cursor and extract prompt * fix: memory retrieval bug * fix: memory retrieval bug * fix: one more attempt by codex * fix: messages prompt error * fix: one more time by codex * fix: metrics by codex * fix: memory forward * fix: memory show update time
This commit is contained in:
parent
db386ccaf2
commit
8bfce5402f
19 changed files with 4382 additions and 103 deletions
89
models/chaite/vectorizer.js
Normal file
89
models/chaite/vectorizer.js
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
import { Chaite, ChaiteContext, GeminiClient, OpenAIClient } from 'chaite'
|
||||
|
||||
async function getIClientByChannel (channel) {
|
||||
await channel.ready()
|
||||
const baseLogger = global.logger || console
|
||||
if (channel.options?.setLogger) {
|
||||
channel.options.setLogger(baseLogger)
|
||||
}
|
||||
const context = new ChaiteContext(baseLogger)
|
||||
context.setChaite(Chaite.getInstance())
|
||||
switch (channel.adapterType) {
|
||||
case 'openai':
|
||||
return new OpenAIClient(channel.options, context)
|
||||
case 'gemini':
|
||||
return new GeminiClient(channel.options, context)
|
||||
case 'claude':
|
||||
throw new Error('claude does not support embedding')
|
||||
default:
|
||||
throw new Error(`Unsupported adapter ${channel.adapterType}`)
|
||||
}
|
||||
}
|
||||
|
||||
async function resolveChannelForModel (model) {
|
||||
const manager = Chaite.getInstance().getChannelsManager()
|
||||
const channels = await manager.getChannelByModel(model)
|
||||
if (channels.length === 0) {
|
||||
throw new Error('No channel found for model: ' + model)
|
||||
}
|
||||
return channels[0]
|
||||
}
|
||||
|
||||
export async function getClientForModel (model) {
|
||||
const channel = await resolveChannelForModel(model)
|
||||
const client = await getIClientByChannel(channel)
|
||||
return { client, channel }
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建一个基于Chaite渠道的向量器
|
||||
* @param {string} model
|
||||
* @param {number} dimensions
|
||||
* @returns {{ textToVector: (text: string) => Promise<number[]>, batchTextToVector: (texts: string[]) => Promise<number[][]> }}
|
||||
*/
|
||||
export function createChaiteVectorizer (model, dimensions) {
|
||||
return {
|
||||
async textToVector (text) {
|
||||
const { client } = await getClientForModel(model)
|
||||
const options = { model }
|
||||
if (Number.isFinite(dimensions) && dimensions > 0) {
|
||||
options.dimensions = dimensions
|
||||
}
|
||||
const result = await client.getEmbedding(text, options)
|
||||
return result.embeddings[0]
|
||||
},
|
||||
async batchTextToVector (texts) {
|
||||
const manager = Chaite.getInstance().getChannelsManager()
|
||||
const channels = await manager.getChannelsByModel(model, texts.length)
|
||||
if (channels.length === 0) {
|
||||
throw new Error('No channel found for model: ' + model)
|
||||
}
|
||||
const clients = await Promise.all(channels.map(({ channel }) => getIClientByChannel(channel)))
|
||||
const results = []
|
||||
let startIndex = 0
|
||||
for (let i = 0; i < channels.length; i++) {
|
||||
const { quantity } = channels[i]
|
||||
const slice = texts.slice(startIndex, startIndex + quantity)
|
||||
const options = { model }
|
||||
if (Number.isFinite(dimensions) && dimensions > 0) {
|
||||
options.dimensions = dimensions
|
||||
}
|
||||
const embeddings = await clients[i].getEmbedding(slice, options)
|
||||
results.push(...embeddings.embeddings)
|
||||
startIndex += quantity
|
||||
}
|
||||
return results
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export async function embedTexts (texts, model, dimensions) {
|
||||
if (!texts || texts.length === 0) {
|
||||
return []
|
||||
}
|
||||
const vectorizer = createChaiteVectorizer(model, dimensions)
|
||||
if (texts.length === 1) {
|
||||
return [await vectorizer.textToVector(texts[0])]
|
||||
}
|
||||
return await vectorizer.batchTextToVector(texts)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue