@convo-lang/convo-lang-aws-cdk
Version:
The language of AI
105 lines • 3.6 kB
JavaScript
import { convoRoles, convoTags, unknownConvoTokenPrice } from "@convo-lang/convo-lang";
import { createConvoLangApiRoutes } from "@convo-lang/convo-lang-api-routes";
import { NotFoundError, asArrayItem, createFnHandler, queryParamsToObject } from '@iyio/common';
import { getHttpRoute } from '@iyio/node-common';
import { initBackend } from "../convo-lang-aws-cdk-lib";
import { checkTokenQuotaAsync, getTokenQuotaAsync, storeTokenUsageAsync } from '../price-capping';
initBackend();
class TokenLimitError extends Error {
}
let currentRemoteAddress = '0.0.0.0';
let routes = null;
const getRoutes = () => {
return routes ?? (routes = createConvoLangApiRoutes({
enableMockRoute: true,
prefix: '',
onCompletion: async ({ result, flat }) => {
if (flat.apiKeyUsedForCompletion) {
return;
}
let price = 0;
for (const m of result) {
if (m.tokenPrice) {
price += m.tokenPrice;
}
else {
price += ((m.inputTokens ?? 0) * unknownConvoTokenPrice) + ((m.outputTokens ?? 0) * unknownConvoTokenPrice);
}
}
await storeTokenUsageAsync(price, { remoteAddress: currentRemoteAddress });
},
completionCtx: {
beforeComplete: async (service, input, flat) => {
if (flat.apiKeyUsedForCompletion) {
return;
}
const quota = await checkTokenQuotaAsync({ remoteAddress: currentRemoteAddress });
if (!quota.allow) {
throw new TokenLimitError('Token limit reached');
}
},
},
getUsage: async () => {
return await getTokenQuotaAsync({ remoteAddress: currentRemoteAddress });
}
}));
};
const ConvoLangAPi = async (fnEvt, input) => {
const routes = getRoutes();
const method = fnEvt.method;
let path = fnEvt.path;
if (path.startsWith('/api/')) {
path = path.substring(4);
}
currentRemoteAddress = fnEvt.remoteAddress || '0.0.0.0';
const qi = path.indexOf('?');
const query = qi === -1 ? {} : queryParamsToObject(path.substring(qi));
if (qi !== -1) {
path = path.substring(0, qi);
}
const route = getHttpRoute(path, method, routes);
if (!route) {
throw new NotFoundError('Route not found');
}
const regex = asArrayItem(route.match);
if (regex) {
const match = regex.exec(path);
if (match) {
for (let i = 1; i < match.length; i++) {
const value = match[i];
query[i.toString()] = decodeURIComponent(value ?? '');
}
}
}
try {
return await route.handler({
req: {}, // convo-lang routes do not use the req object
res: {}, // convo-lang routes do not use the res object
path,
filePath: '.',
body: input,
method,
query
});
}
catch (ex) {
if (ex instanceof TokenLimitError) {
const msg = {
tags: {
[convoTags.tokenLimit]: ''
},
role: convoRoles.assistant,
content: ex.message
};
return [msg];
}
else {
throw ex;
}
}
finally {
currentRemoteAddress = '0.0.0.0';
}
};
export const handler = createFnHandler(ConvoLangAPi, {});
//# sourceMappingURL=ConvoLangApi.js.map