fix (templates): llm-server almost OK.
This commit is contained in:
parent
22141095f0
commit
bf9886e763
4 changed files with 74 additions and 83 deletions
|
@ -42,7 +42,7 @@ import { GBAdminService } from '../../admin.gbapp/services/GBAdminService.js';
|
||||||
import { Messages } from '../strings.js';
|
import { Messages } from '../strings.js';
|
||||||
import { CollectionUtil } from 'pragmatismo-io-framework';
|
import { CollectionUtil } from 'pragmatismo-io-framework';
|
||||||
import { GBConversationalService } from '../../core.gbapp/services/GBConversationalService.js';
|
import { GBConversationalService } from '../../core.gbapp/services/GBConversationalService.js';
|
||||||
import fs from 'fs/promises';
|
import fs from 'fs/promises';
|
||||||
import libphonenumber from 'google-libphonenumber';
|
import libphonenumber from 'google-libphonenumber';
|
||||||
import * as df from 'date-diff';
|
import * as df from 'date-diff';
|
||||||
import tesseract from 'node-tesseract-ocr';
|
import tesseract from 'node-tesseract-ocr';
|
||||||
|
@ -66,7 +66,7 @@ import puppeteer from 'puppeteer';
|
||||||
* Default check interval for user replay
|
* Default check interval for user replay
|
||||||
*/
|
*/
|
||||||
const DEFAULT_HEAR_POLL_INTERVAL = 500;
|
const DEFAULT_HEAR_POLL_INTERVAL = 500;
|
||||||
const API_RETRIES = 120;
|
const POOLING_COUNT = 120;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Base services of conversation to be called by BASIC.
|
* Base services of conversation to be called by BASIC.
|
||||||
|
@ -1314,11 +1314,9 @@ export class DialogKeywords {
|
||||||
GBLogEx.info(min, `MESSAGE BOT: ${text}.`);
|
GBLogEx.info(min, `MESSAGE BOT: ${text}.`);
|
||||||
|
|
||||||
const { conversation, client } = min['apiConversations'][pid];
|
const { conversation, client } = min['apiConversations'][pid];
|
||||||
|
|
||||||
await client.apis.Conversations.Conversations_PostActivity({
|
await client.apis.Conversations.Conversations_PostActivity({
|
||||||
conversationId: conversation.conversationId,
|
conversationId: conversation.conversationId,
|
||||||
activity: {
|
activity: {
|
||||||
pid: pid,
|
|
||||||
textFormat: 'plain',
|
textFormat: 'plain',
|
||||||
text: text,
|
text: text,
|
||||||
type: 'message',
|
type: 'message',
|
||||||
|
@ -1332,7 +1330,7 @@ export class DialogKeywords {
|
||||||
let messages = [];
|
let messages = [];
|
||||||
GBLogEx.info(min, `MessageBot: Starting message polling ${conversation.conversationId}).`);
|
GBLogEx.info(min, `MessageBot: Starting message polling ${conversation.conversationId}).`);
|
||||||
|
|
||||||
let count = API_RETRIES;
|
let count = POOLING_COUNT;
|
||||||
while (count--) {
|
while (count--) {
|
||||||
await GBUtil.sleep(DEFAULT_HEAR_POLL_INTERVAL);
|
await GBUtil.sleep(DEFAULT_HEAR_POLL_INTERVAL);
|
||||||
|
|
||||||
|
@ -1345,28 +1343,23 @@ export class DialogKeywords {
|
||||||
let activities = response.obj.activities;
|
let activities = response.obj.activities;
|
||||||
|
|
||||||
if (activities && activities.length) {
|
if (activities && activities.length) {
|
||||||
activities = activities.filter(m => m.from.id === min.botId && m.type === 'message');
|
activities = activities.filter(m => m.from.id !== user.userSystemId && m.type === 'message');
|
||||||
if (activities.length) {
|
if (activities.length) {
|
||||||
activities.forEach(activity => {
|
activities.forEach(activity => {
|
||||||
messages.push(activity.text);
|
messages.push(activity.text);
|
||||||
GBLogEx.info(min, `MESSAGE BOT answer from bot: ${activity.text}`);
|
GBLogEx.info(min, `MESSAGE BOT answer from bot: ${activity.text}`);
|
||||||
});
|
});
|
||||||
|
return messages.join('\n');
|
||||||
}
|
}
|
||||||
return messages.join('\n');
|
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
GBLog.error(
|
GBLog.error(`API Message Pooling error: ${GBUtil.toYAML(err)}`);
|
||||||
`Error calling printMessages in messageBot API ${err.data === undefined ? err : err.data} ${
|
|
||||||
err.errObj ? err.errObj.message : ''
|
|
||||||
}`
|
|
||||||
);
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async start({ botId, botApiKey, userSystemId, text }) {
|
public async start({ botId, botApiKey, userSystemId, text }) {
|
||||||
|
|
||||||
let min: GBMinInstance = GBServer.globals.minInstances.filter(p => p.instance.botId === botId)[0];
|
let min: GBMinInstance = GBServer.globals.minInstances.filter(p => p.instance.botId === botId)[0];
|
||||||
let sec = new SecService();
|
let sec = new SecService();
|
||||||
let user = await sec.getUserFromSystemId(userSystemId);
|
let user = await sec.getUserFromSystemId(userSystemId);
|
||||||
|
@ -1500,7 +1493,7 @@ export class DialogKeywords {
|
||||||
'cache',
|
'cache',
|
||||||
`${fileOnly.replace(/\s/gi, '')}-${GBAdminService.getNumberIdentifier()}.${ext}`
|
`${fileOnly.replace(/\s/gi, '')}-${GBAdminService.getNumberIdentifier()}.${ext}`
|
||||||
);
|
);
|
||||||
await fs.writeFile(localName1, buf, { encoding: null });
|
await fs.writeFile(localName1, buf, { encoding: null });
|
||||||
|
|
||||||
url = urlJoin(GBServer.globals.publicAddress, min.botId, 'cache', path.basename(localName1));
|
url = urlJoin(GBServer.globals.publicAddress, min.botId, 'cache', path.basename(localName1));
|
||||||
}
|
}
|
||||||
|
@ -1513,7 +1506,7 @@ export class DialogKeywords {
|
||||||
const buf = await fs.readFile(filename);
|
const buf = await fs.readFile(filename);
|
||||||
const gbaiName = GBUtil.getGBAIPath(min.botId);
|
const gbaiName = GBUtil.getGBAIPath(min.botId);
|
||||||
const localName = path.join('work', gbaiName, 'cache', `tmp${GBAdminService.getRndReadableIdentifier()}.${ext}`);
|
const localName = path.join('work', gbaiName, 'cache', `tmp${GBAdminService.getRndReadableIdentifier()}.${ext}`);
|
||||||
await fs.writeFile(localName, buf, { encoding: null });
|
await fs.writeFile(localName, buf, { encoding: null });
|
||||||
url = urlJoin(GBServer.globals.publicAddress, min.botId, 'cache', path.basename(localName));
|
url = urlJoin(GBServer.globals.publicAddress, min.botId, 'cache', path.basename(localName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1546,7 +1539,7 @@ export class DialogKeywords {
|
||||||
|
|
||||||
const gbaiName = GBUtil.getGBAIPath(min.botId);
|
const gbaiName = GBUtil.getGBAIPath(min.botId);
|
||||||
const localName = path.join('work', gbaiName, 'cache', `qr${GBAdminService.getRndReadableIdentifier()}.png`);
|
const localName = path.join('work', gbaiName, 'cache', `qr${GBAdminService.getRndReadableIdentifier()}.png`);
|
||||||
await fs.writeFile(localName, buf, { encoding: null });
|
await fs.writeFile(localName, buf, { encoding: null });
|
||||||
const url = urlJoin(GBServer.globals.publicAddress, min.botId, 'cache', path.basename(localName));
|
const url = urlJoin(GBServer.globals.publicAddress, min.botId, 'cache', path.basename(localName));
|
||||||
|
|
||||||
return { data: data, localName: localName, url: url };
|
return { data: data, localName: localName, url: url };
|
||||||
|
|
|
@ -84,7 +84,7 @@ export const getRouter = (
|
||||||
});
|
});
|
||||||
|
|
||||||
// Gets activities from store (local history array for now)
|
// Gets activities from store (local history array for now)
|
||||||
router.get(`/directline/${botId}/conversations/:conversationId/activities`, (req, res) => {
|
router.get(`/api/messages/${botId}/v3/directline/conversations/:conversationId/activities`, (req, res) => {
|
||||||
const watermark = req.query.watermark && req.query.watermark !== 'null' ? Number(req.query.watermark) : 0;
|
const watermark = req.query.watermark && req.query.watermark !== 'null' ? Number(req.query.watermark) : 0;
|
||||||
|
|
||||||
const conversation = getConversation(req.params.conversationId, conversationInitRequired);
|
const conversation = getConversation(req.params.conversationId, conversationInitRequired);
|
||||||
|
@ -146,14 +146,12 @@ export const getRouter = (
|
||||||
router.post('/v3/conversations', (req, res) => {
|
router.post('/v3/conversations', (req, res) => {
|
||||||
console.warn('/v3/conversations not implemented');
|
console.warn('/v3/conversations not implemented');
|
||||||
});
|
});
|
||||||
|
|
||||||
router.post('/v3/conversations/:conversationId/activities', (req, res) => {
|
router.post(`/api/messages/${botId}/v3/directline/conversations/:conversationId/activities`, (req, res) => {
|
||||||
let activity: IActivity;
|
let activity: IActivity;
|
||||||
|
|
||||||
activity = req.body;
|
activity = req.body;
|
||||||
activity.id = uuidv4.v4();
|
|
||||||
activity.from = { id: 'id', name: 'Bot' };
|
|
||||||
|
|
||||||
const conversation = getConversation(req.params.conversationId, conversationInitRequired);
|
const conversation = getConversation(req.params.conversationId, conversationInitRequired);
|
||||||
if (conversation) {
|
if (conversation) {
|
||||||
conversation.history.push(activity);
|
conversation.history.push(activity);
|
||||||
|
@ -164,7 +162,7 @@ export const getRouter = (
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
router.post('/v3/conversations/:conversationId/activities/:activityId', (req, res) => {
|
router.post(`/api/messages/${botId}/v3/conversations/:conversationId/activities/:activityId`, (req, res) => {
|
||||||
let activity: IActivity;
|
let activity: IActivity;
|
||||||
|
|
||||||
activity = req.body;
|
activity = req.body;
|
||||||
|
|
118
src/util.ts
118
src/util.ts
|
@ -75,22 +75,26 @@ export class GBUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async getDirectLineClient(min) {
|
public static async getDirectLineClient(min) {
|
||||||
let config = {
|
let config;
|
||||||
spec: JSON.parse(await fs.readFile('directline-3.0.json', 'utf8')),
|
|
||||||
requestInterceptor: req => {
|
|
||||||
req.headers['Authorization'] = `Bearer ${min.instance.webchatKey}`;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
if (!GBConfigService.get('STORAGE_NAME')) {
|
if (!GBConfigService.get('STORAGE_NAME')) {
|
||||||
(config['spec'].url = `http://127.0.0.1:${GBConfigService.getServerPort()}/api/messages/${min.botId}`),
|
config = {
|
||||||
(config['spec'].servers = [
|
spec: JSON.parse(await fs.readFile('directline-v2.json', 'utf8')),
|
||||||
{ url: `http://127.0.0.1:${GBConfigService.getServerPort()}/api/messages/${min.botId}` }
|
requestInterceptor: req => {
|
||||||
]);
|
req.headers['Authorization'] = `Bearer ${min.instance.webchatKey}`;
|
||||||
config['spec'].openapi = '3.0.0';
|
}
|
||||||
delete config['spec'].host;
|
};
|
||||||
delete config['spec'].swagger;
|
config.spec['host'] = `127.0.0.1:${GBConfigService.getServerPort()}`;
|
||||||
}
|
config.spec['basePath'] = `/api/messages/${min.botId}`;
|
||||||
|
config.spec['schemes'] = ["http"];
|
||||||
|
|
||||||
|
} else {
|
||||||
|
config = {
|
||||||
|
spec: JSON.parse(await fs.readFile('directline-v2.json', 'utf8')),
|
||||||
|
requestInterceptor: req => {
|
||||||
|
req.headers['Authorization'] = `Bearer ${min.instance.webchatKey}`;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
return await new SwaggerClient(config);
|
return await new SwaggerClient(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,33 +128,29 @@ export class GBUtil {
|
||||||
if (!listOrRow || typeof listOrRow !== 'object') {
|
if (!listOrRow || typeof listOrRow !== 'object') {
|
||||||
return listOrRow;
|
return listOrRow;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper function to convert property names to lowercase
|
// Helper function to convert property names to lowercase
|
||||||
const lowercase = key => typeof key === 'string' ? key.toLowerCase() : key;
|
const lowercase = key => (typeof key === 'string' ? key.toLowerCase() : key);
|
||||||
|
|
||||||
// Create a proxy that maps property accesses to lowercase property names
|
// Create a proxy that maps property accesses to lowercase property names
|
||||||
const createCaseInsensitiveProxy = obj => {
|
const createCaseInsensitiveProxy = obj => {
|
||||||
const propertiesMap = new Map(
|
const propertiesMap = new Map(Object.keys(obj).map(propKey => [lowercase(propKey), obj[propKey]]));
|
||||||
Object.keys(obj).map(propKey => [lowercase(propKey), obj[propKey]])
|
|
||||||
);
|
|
||||||
|
|
||||||
const caseInsensitiveGetHandler = {
|
const caseInsensitiveGetHandler = {
|
||||||
get: (target, property) => propertiesMap.get(lowercase(property))
|
get: (target, property) => propertiesMap.get(lowercase(property))
|
||||||
};
|
};
|
||||||
|
|
||||||
return new Proxy(obj, caseInsensitiveGetHandler);
|
return new Proxy(obj, caseInsensitiveGetHandler);
|
||||||
};
|
};
|
||||||
|
|
||||||
// Handle arrays by mapping each element to a case-insensitive proxy
|
// Handle arrays by mapping each element to a case-insensitive proxy
|
||||||
if (Array.isArray(listOrRow)) {
|
if (Array.isArray(listOrRow)) {
|
||||||
return listOrRow.map(row =>
|
return listOrRow.map(row => (typeof row === 'object' && row !== null ? createCaseInsensitiveProxy(row) : row));
|
||||||
typeof row === 'object' && row !== null ? createCaseInsensitiveProxy(row) : row
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
return createCaseInsensitiveProxy(listOrRow);
|
return createCaseInsensitiveProxy(listOrRow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static async exists(filePath: string): Promise<boolean> {
|
public static async exists(filePath: string): Promise<boolean> {
|
||||||
try {
|
try {
|
||||||
await fs.access(filePath);
|
await fs.access(filePath);
|
||||||
|
@ -163,43 +163,43 @@ export class GBUtil {
|
||||||
public static async copyIfNewerRecursive(src, dest) {
|
public static async copyIfNewerRecursive(src, dest) {
|
||||||
// Check if the source exists
|
// Check if the source exists
|
||||||
if (!(await GBUtil.exists(src))) {
|
if (!(await GBUtil.exists(src))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if the source is a directory
|
// Check if the source is a directory
|
||||||
if ((await fs.stat(src)).isDirectory()) {
|
if ((await fs.stat(src)).isDirectory()) {
|
||||||
// Create the destination directory if it doesn't exist
|
// Create the destination directory if it doesn't exist
|
||||||
if (!(await GBUtil.exists(dest))) {
|
if (!(await GBUtil.exists(dest))) {
|
||||||
await fs.mkdir(dest, { recursive: true });
|
await fs.mkdir(dest, { recursive: true });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read all files and directories in the source directory
|
// Read all files and directories in the source directory
|
||||||
const entries = await fs.readdir(src);
|
const entries = await fs.readdir(src);
|
||||||
|
|
||||||
for (let entry of entries) {
|
for (let entry of entries) {
|
||||||
const srcEntry = path.join(src, entry);
|
const srcEntry = path.join(src, entry);
|
||||||
const destEntry = path.join(dest, entry);
|
const destEntry = path.join(dest, entry);
|
||||||
|
|
||||||
// Recursively copy each entry
|
// Recursively copy each entry
|
||||||
await this.copyIfNewerRecursive(srcEntry, destEntry);
|
await this.copyIfNewerRecursive(srcEntry, destEntry);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Source is a file, check if we need to copy it
|
// Source is a file, check if we need to copy it
|
||||||
if (await GBUtil.exists(dest)) {
|
if (await GBUtil.exists(dest)) {
|
||||||
const srcStat = await fs.stat(src);
|
const srcStat = await fs.stat(src);
|
||||||
const destStat = await fs.stat(dest);
|
const destStat = await fs.stat(dest);
|
||||||
|
|
||||||
// Copy only if the source file is newer than the destination file
|
// Copy only if the source file is newer than the destination file
|
||||||
if (srcStat.mtime > destStat.mtime) {
|
if (srcStat.mtime > destStat.mtime) {
|
||||||
await fs.cp(src, dest, { force: true });
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Destination file doesn't exist, so copy it
|
|
||||||
await fs.cp(src, dest, { force: true });
|
await fs.cp(src, dest, { force: true });
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
// Destination file doesn't exist, so copy it
|
||||||
|
await fs.cp(src, dest, { force: true });
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// Check if is a tree or flat object.
|
// Check if is a tree or flat object.
|
||||||
|
|
||||||
public static hasSubObject(t) {
|
public static hasSubObject(t) {
|
||||||
for (var key in t) {
|
for (var key in t) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue