fix (templates): llm-server almost OK.

This commit is contained in:
Rodrigo Rodriguez 2024-09-13 16:56:04 -03:00
parent 210ad2f885
commit 22141095f0
6 changed files with 102 additions and 81 deletions

View file

@ -35,6 +35,21 @@
"application/xml", "application/xml",
"text/xml" "text/xml"
], ],
"parameters": [
{
"name": "userSystemId",
"in": "query",
"description": "User System ID",
"required": false,
"type": "string"
},{
"name": "userName",
"in": "query",
"description": "User Name",
"required": false,
"type": "string"
}],
"responses": { "responses": {
"200": { "200": {
"description": "The conversation was successfully created, updated, or retrieved.", "description": "The conversation was successfully created, updated, or retrieved.",

View file

@ -48,8 +48,8 @@ import { CollectionUtil, AzureText } from 'pragmatismo-io-framework';
import { GuaribasUser } from '../../security.gbapp/models/index.js'; import { GuaribasUser } from '../../security.gbapp/models/index.js';
import { GBMinService } from './GBMinService.js'; import { GBMinService } from './GBMinService.js';
import urlJoin from 'url-join'; import urlJoin from 'url-join';
import {createWriteStream, createReadStream} from 'fs'; import { createWriteStream, createReadStream } from 'fs';
import fs from 'fs/promises'; import fs from 'fs/promises';
import twilio from 'twilio'; import twilio from 'twilio';
import Nexmo from 'nexmo'; import Nexmo from 'nexmo';
import { join } from 'path'; import { join } from 'path';
@ -452,7 +452,7 @@ export class GBConversationalService {
const waveFilename = `work/tmp${name}.pcm`; const waveFilename = `work/tmp${name}.pcm`;
let audio = await textToSpeech.repairWavHeaderStream(res.result as any); let audio = await textToSpeech.repairWavHeaderStream(res.result as any);
await fs.writeFile(waveFilename, audio); await fs.writeFile(waveFilename, audio);
const oggFilenameOnly = `tmp${name}.ogg`; const oggFilenameOnly = `tmp${name}.ogg`;
const oggFilename = `work/${oggFilenameOnly}`; const oggFilename = `work/${oggFilenameOnly}`;
@ -482,7 +482,7 @@ export class GBConversationalService {
const dest = `work/tmp${name}.wav`; const dest = `work/tmp${name}.wav`;
const src = `work/tmp${name}.ogg`; const src = `work/tmp${name}.ogg`;
await fs.writeFile(src, oggFile.read()); await fs.writeFile(src, oggFile.read());
const makeMp3 = shell([ const makeMp3 = shell([
'node_modules/ffmpeg-static/ffmpeg', // TODO: .exe on MSWin. 'node_modules/ffmpeg-static/ffmpeg', // TODO: .exe on MSWin.
@ -1282,22 +1282,31 @@ export class GBConversationalService {
* Sends a message in a user with an already started conversation (got ConversationReference set) * Sends a message in a user with an already started conversation (got ConversationReference set)
*/ */
public async sendOnConversation(min: GBMinInstance, user: GuaribasUser, message: any) { public async sendOnConversation(min: GBMinInstance, user: GuaribasUser, message: any) {
if (message['buttons'] || message['sections']) { if (GBConfigService.get('STORAGE_NAME')) {
await min['whatsAppDirectLine'].sendToDevice(user.userSystemId, message, user.conversationReference); const ref = JSON.parse(user.conversationReference);
} else if (user.conversationReference.startsWith('spaces')) { MicrosoftAppCredentials.trustServiceUrl(ref.serviceUrl);
await min['googleDirectLine'].sendToDevice(user.userSystemId, null, user.conversationReference, message);
} else {
const ref = JSON.parse(user.conversationReference);
MicrosoftAppCredentials.trustServiceUrl(ref.serviceUrl);
try {
await min.bot['continueConversation'](ref, async t1 => { await min.bot['continueConversation'](ref, async t1 => {
const ref2 = TurnContext.getConversationReference(t1.activity); const ref2 = TurnContext.getConversationReference(t1.activity);
await min.bot.continueConversation(ref2, async t2 => { await min.bot.continueConversation(ref2, async t2 => {
await t2.sendActivity(message); await t2.sendActivity(message);
}); });
}); });
} catch (error) {
console.log(error); } else {
const ref = JSON.parse(user.conversationReference);
await min.bot['continueConversation'](ref, async (t1) => {
const ref2 = TurnContext.getConversationReference(t1.activity);
await min.bot.continueConversation(ref2, async (t2) => {
await t2.sendActivity(message);
});
});
if (message['buttons'] || message['sections']) {
await min['whatsAppDirectLine'].sendToDevice(user.userSystemId, message, user.conversationReference);
}
else if (user.conversationReference && user.conversationReference.startsWith('spaces')) {
await min['googleDirectLine'].sendToDevice(user.userSystemId, null, user.conversationReference, message);
} }
} }
} }

View file

@ -151,8 +151,6 @@ export class GBMinService {
this.deployer = deployer; this.deployer = deployer;
} }
public async enableAPI(min: GBMinInstance) {}
/** /**
* Constructs a new minimal instance for each bot. * Constructs a new minimal instance for each bot.
*/ */
@ -400,7 +398,8 @@ export class GBMinService {
res.end(); res.end();
}); });
await GBMinService.ensureAPI(min); await this.ensureAPI();
GBLog.verbose(`GeneralBots(${instance.engineName}) listening on: ${url}.`); GBLog.verbose(`GeneralBots(${instance.engineName}) listening on: ${url}.`);
// Generates MS Teams manifest. // Generates MS Teams manifest.
@ -1032,12 +1031,13 @@ export class GBMinService {
const member = context.activity.from; const member = context.activity.from;
const sec = new SecService(); const sec = new SecService();
const user = await sec.ensureUser(min, member.id, member.name, '', 'web', member.name, null); let user = await sec.ensureUser(min, member.id, member.name, '', 'web', member.name, null);
const userId = user.userId; const userId = user.userId;
const params = user.params ? JSON.parse(user.params) : {}; const params = user.params ? JSON.parse(user.params) : {};
try { try {
const conversationReference = JSON.stringify(TurnContext.getConversationReference(context.activity)); const conversationReference = JSON.stringify(TurnContext.getConversationReference(context.activity));
user = await sec.updateConversationReferenceById(user.userId, conversationReference);
// First time processing. // First time processing.
@ -1648,15 +1648,9 @@ export class GBMinService {
} }
} }
public static async ensureAPI(min: GBMinInstance) { public async ensureAPI() {
const api = min.core.getParam(min.instance, 'Server API', null); const mins = GBServer.globals.minInstances;
if (!api) {
return;
}
GBLogEx.info(min, `Enabling API...`);
function getRemoteId(ctx: Koa.Context) { function getRemoteId(ctx: Koa.Context) {
return '1'; // Each bot has its own API. return '1'; // Each bot has its own API.
} }
@ -1669,7 +1663,7 @@ export class GBMinService {
}); });
} else { } else {
resolve(true); resolve(true);
GBLogEx.info(0, 'Loading General Bots API...');
} }
}); });
}; };
@ -1677,45 +1671,47 @@ export class GBMinService {
await close(); await close();
let proxies = {}; let proxies = {};
let dialogs = {}; await CollectionUtil.asyncForEach(mins, async min => {
await CollectionUtil.asyncForEach(Object.values(min.scriptMap), async script => { let dialogs = {};
dialogs[script] = async data => {
if (!data.userSystemId){ await CollectionUtil.asyncForEach(Object.values(min.scriptMap), async script => {
throw new Error('UserSystemId is required.'); const api = min.core.getParam(min.instance, 'Server API', null);
} if (api) {
dialogs[script] = async data => {
let sec = new SecService();
const user = await sec.ensureUser(
min,
data.userSystemId,
data.userName ? data.userName : 'apiuser',
'',
'api',
data.userSystemId,
null
);
let pid = data?.pid;
if (script === 'start') {
pid = GBVMService.createProcessInfo(user, min, 'api', null);
let sec = new SecService(); const client = await GBUtil.getDirectLineClient(min);
const user = await sec.ensureUser( const response = await client.apis.Conversations.Conversations_StartConversation({
min, userSystemId: user.userSystemId,
data.userSystemId, userName: user.userName
data.userSystemId, });
'',
'api', min['apiConversations'][pid] = { conversation: response.obj, client: client };
data.userSystemId, min['conversationWelcomed'][response.obj.id] = true;
null }
);
let pid = data?.pid; let ret = await GBVMService.callVM(script, min, null, pid, false, data);
if (script === 'start') {
pid = GBVMService.createProcessInfo(user, min, 'api', null);
const client = await GBUtil.getDirectLineClient(min); if (script === 'start') {
const response = await client.apis.Conversations.Conversations_StartConversation(); ret = pid;
}
min['apiConversations'][pid] = { conversation: response.obj, client: client }; return ret;
min['conversationWelcomed'][response.obj.id] = true; };
} }
});
let ret = await GBVMService.callVM(script, min, null, pid, false, data);
if (script === 'start') {
ret = pid;
}
return ret;
};
const proxy = { const proxy = {
dk: new DialogKeywords(), dk: new DialogKeywords(),

View file

@ -12,6 +12,7 @@ const conversationsCleanupInterval = 10000;
const conversations: { [key: string]: IConversation } = {}; const conversations: { [key: string]: IConversation } = {};
const botDataStore: { [key: string]: IBotData } = {}; const botDataStore: { [key: string]: IBotData } = {};
export const getRouter = ( export const getRouter = (
serviceUrl: string, serviceUrl: string,
botUrl: string, botUrl: string,
@ -46,7 +47,10 @@ export const getRouter = (
}; };
console.log('Created conversation with conversationId: ' + conversationId); console.log('Created conversation with conversationId: ' + conversationId);
const activity = createConversationUpdateActivity(serviceUrl, conversationId); const activity = createConversationUpdateActivity
(serviceUrl, conversationId, req.query?.userSystemId,
req.query?.userName
);
fetch(botUrl, { fetch(botUrl, {
method: 'POST', method: 'POST',
body: JSON.stringify(activity), body: JSON.stringify(activity),
@ -61,10 +65,10 @@ export const getRouter = (
}); });
}; };
router.post('/v3/directline/conversations', reqs); router.post('/v3/directline/conversations/', reqs);
router.post(`/api/messages/${botId}/v3/directline/conversations`, reqs); router.post(`/api/messages/${botId}/v3/directline/conversations/`, reqs);
router.post(`/directline/${botId}/conversations`, reqs); router.post(`/directline/${botId}/conversations/`, reqs);
router.post(`/directline/conversations`, reqs); router.post(`/directline/conversations/`, reqs);
// Reconnect API // Reconnect API
router.get('/v3/directline/conversations/:conversationId', (req, res) => { router.get('/v3/directline/conversations/:conversationId', (req, res) => {
@ -329,7 +333,7 @@ const createMessageActivity = (
}; };
}; };
const createConversationUpdateActivity = (serviceUrl: string, conversationId: string): IConversationUpdateActivity => { const createConversationUpdateActivity = (serviceUrl: string, conversationId: string, userSystemId, userName): IConversationUpdateActivity => {
const activity: IConversationUpdateActivity = { const activity: IConversationUpdateActivity = {
type: 'conversationUpdate', type: 'conversationUpdate',
channelId: 'emulator', channelId: 'emulator',
@ -338,7 +342,7 @@ const createConversationUpdateActivity = (serviceUrl: string, conversationId: st
id: uuidv4.v4(), id: uuidv4.v4(),
membersAdded: [], membersAdded: [],
membersRemoved: [], membersRemoved: [],
from: { id: 'offline-directline', name: 'Offline Directline Server' } from: { id: userSystemId, name: userName }
}; };
return activity; return activity;
}; };

View file

@ -80,7 +80,7 @@ export class SecService extends GBService {
user.conversationReference = conversationReference; user.conversationReference = conversationReference;
GBServer.globals.users [user.userId] = user; GBServer.globals.users [user.userId] = user;
await user.save(); return await user.save();
} }
public async updateConversationReferenceById(userId: number, conversationReference: string) { public async updateConversationReferenceById(userId: number, conversationReference: string) {
@ -89,7 +89,7 @@ export class SecService extends GBService {
user.conversationReference = conversationReference; user.conversationReference = conversationReference;
GBServer.globals.users [user.userId] = user; GBServer.globals.users [user.userId] = user;
await user.save(); return await user.save();
} }
public async updateUserLocale(userId: number, locale: any): Promise<GuaribasUser> { public async updateUserLocale(userId: number, locale: any): Promise<GuaribasUser> {

View file

@ -19,9 +19,9 @@ Here is an example of the Order JSON, clear the items and send one with the orde
orderedItems: [ orderedItems: [
{ {
item: { item: {
id: 23872, id: 102,
price: 20, price: 0.30,
name: Guaraná name: Banana
}, },
sideItems: [ sideItems: [
{ {
@ -35,9 +35,9 @@ Here is an example of the Order JSON, clear the items and send one with the orde
}, },
{ {
item: { item: {
id: 25510, id: 103,
price: 12, price: 0.30,
name: Orange Can 350ml name: Carrot
}, },
sideItems: [], sideItems: [],
quantity: 1, quantity: 1,
@ -46,9 +46,6 @@ Here is an example of the Order JSON, clear the items and send one with the orde
], ],
userId: ${operator}, userId: ${operator},
accountIdentifier: Areia, accountIdentifier: Areia,
deliveryTypeId: 2, deliveryTypeId: 2
deliveryTypeFields: {
Table: 5
}
} }
END SYSTEM PROMPT END SYSTEM PROMPT