@convo-lang/convo-lang
Version:
The language of AI
101 lines • 3.93 kB
JavaScript
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