UNPKG

@convo-lang/convo-lang

Version:
101 lines 3.93 kB
import { NotFoundError, aryRandomize, defineStringParam, httpClient, joinPaths } from "@iyio/common"; import { getSerializableFlatConvoConversation, passthroughConvoInputType, passthroughConvoOutputType } from "./convo-lib.js"; import { convoRagService } from "./convo-rag-lib.js"; import { convoCompletionService } from "./convo.deps.js"; export const defaultConvoHttpEndpointPrefix = '/convo-lang'; export const defaultConvoHttpApiEndpointPrefix = '/api' + defaultConvoHttpEndpointPrefix; export const httpConvoCompletionEndpointParam = defineStringParam('httpConvoCompletionEndpoint', defaultConvoHttpApiEndpointPrefix); export const convoHttpRelayModule = (scope) => { scope.implementService(convoCompletionService, scope => HttpConvoCompletionService.fromScope(scope)); scope.implementService(convoRagService, scope => HttpConvoCompletionService.fromScope(scope)); }; /** * Forwards messages to an convo-lang api endpoint or pool of convo-lang api endpoints. * * ## Endpoint structure * * ### POST /completion (flat:FlatConvoConversationBase) => ConvoCompletionMessage[] * Completes a posted flat conversation and returns the completed messages. * * ### POST /convo (convo:string) => string * Completes a convo conversation as a string and returns the completed messages as a string * * ### GET /models ()=>ConvoModelInfo[] * Returns all models known to the server */ export class HttpConvoCompletionService { static fromScope(scope, endpoint) { if (!endpoint) { const ep = httpConvoCompletionEndpointParam().split(',').map(e => e.trim()).filter(e => e); endpoint = ep.length === 1 ? ep[0] : ep; } if (!endpoint) { throw new Error('Empty HttpConvoCompletionService provided'); } return new HttpConvoCompletionService({ endpoint }); } constructor({ endpoint }) { this.serviceId = 'http'; this.inputType = passthroughConvoInputType; this.outputType = passthroughConvoOutputType; this.endpointIndex = 0; if (Array.isArray(endpoint)) { endpoint = [...endpoint]; aryRandomize(endpoint); } this.endpoint = endpoint; } canComplete(model, flat) { return true; } getEndpoint() { if (Array.isArray(this.endpoint)) { const e = this.endpoint[this.endpointIndex]; this.endpointIndex++; if (this.endpointIndex >= this.endpoint.length) { this.endpointIndex = 0; aryRandomize(this.endpoint); } return e ?? ''; } else { return this.endpoint; } } async completeConvoAsync(flat) { const r = await httpClient().postAsync(joinPaths(this.getEndpoint(), '/completion'), getSerializableFlatConvoConversation(flat)); if (!r) { throw new Error('convo-lang ai endpoint returned empty response'); } if (!Array.isArray(r) && r.messages) { return r.messages; } else { return r; } } getModelsAsync() { return httpClient().getAsync(joinPaths(this.getEndpoint(), '/models')); } async relayConvertConvoToInputAsync(flat, inputType) { const request = { flat: getSerializableFlatConvoConversation(flat), inputType }; const r = await httpClient().postAsync(joinPaths(this.getEndpoint(), '/convert'), request); if (!r) { throw new NotFoundError(); } return r; } async searchAsync(search) { const r = await httpClient().postAsync(joinPaths(this.getEndpoint(), '/rag/search'), search); if (!r) { throw new Error('convo-lang ai endpoint returned empty response'); } return r; } } //# sourceMappingURL=HttpConvoCompletionService.js.map