From 93ff7a418ed2b4777bb1f9bd1aaebc6f9bda6383 Mon Sep 17 00:00:00 2001 From: Rodrigo Rodriguez Date: Sat, 14 Sep 2024 21:26:54 -0300 Subject: [PATCH] fix (templates): llm-server almost OK. --- .../basic.gblib/services/DialogKeywords.ts | 9 ++- packages/core.gbapp/services/GBMinService.ts | 16 +++--- packages/core.gbapp/services/router/bridge.ts | 44 ++++++++------- packages/kb.gbapp/dialogs/AskDialog.ts | 44 +++++---------- .../llm-server.gbdialog/start.bas | 56 ++++++++----------- 5 files changed, 77 insertions(+), 92 deletions(-) diff --git a/packages/basic.gblib/services/DialogKeywords.ts b/packages/basic.gblib/services/DialogKeywords.ts index b396370d..d245c75e 100644 --- a/packages/basic.gblib/services/DialogKeywords.ts +++ b/packages/basic.gblib/services/DialogKeywords.ts @@ -1311,15 +1311,16 @@ export class DialogKeywords { public async messageBot({ pid, text }) { const { min, user } = await DialogKeywords.getProcessInfo(pid); - GBLogEx.info(min, `MESSAGE BOT: ${text}.`); - const { conversation, client } = min['apiConversations'][pid]; + GBLogEx.info(min, `API messaged bot (Conversation Id: ${conversation.conversationId}): ${text} .`); + await client.apis.Conversations.Conversations_PostActivity({ conversationId: conversation.conversationId, activity: { textFormat: 'plain', text: text, type: 'message', + pid: pid, from: { id: user.userSystemId, name: user.userName @@ -1327,8 +1328,9 @@ export class DialogKeywords { } }); + min['conversationWelcomed'][conversation.conversationId] = true; let messages = []; - GBLogEx.info(min, `MessageBot: Starting message polling ${conversation.conversationId}).`); + GBLogEx.info(min, `Start API message pooling: ${conversation.conversationId})...`); let count = POOLING_COUNT; while (count--) { @@ -1353,6 +1355,7 @@ export class DialogKeywords { } } } catch (err) { + count = 0; GBLog.error(`API Message Pooling error: ${GBUtil.toYAML(err)}`); } } diff --git a/packages/core.gbapp/services/GBMinService.ts b/packages/core.gbapp/services/GBMinService.ts index d9254fba..f36f4edb 100644 --- a/packages/core.gbapp/services/GBMinService.ts +++ b/packages/core.gbapp/services/GBMinService.ts @@ -210,13 +210,17 @@ export class GBMinService { GBServer.globals.debugConversationId = conversationId; const steps = process.env.TEST_MESSAGE.split(';'); + const sec = new SecService(); + const user = await sec.ensureUser(min, 'testuser', 'testuser', '', 'test', 'testuser', null); + const pid = GBVMService.createProcessInfo(user, min, 'api', null); await CollectionUtil.asyncForEach(steps, async step => { client.apis.Conversations.Conversations_PostActivity({ conversationId: conversationId, activity: { textFormat: 'plain', text: step, + pid: pid, type: 'message', from: { id: 'test', @@ -1197,10 +1201,7 @@ export class GBMinService { await this.processEventActivity(min, user, context, step); } } catch (error) { - const msg = `ERROR: ${error.message} ${error.stack} ${error.error ? error.error.body : ''} ${ - error.error ? (error.error.stack ? error.error.stack : '') : '' - }`; - GBLog.error(msg); + GBLog.error(`Receiver: ${GBUtil.toYAML(error)}`); await min.conversationalService.sendText( min, @@ -1682,7 +1683,7 @@ export class GBMinService { const user = await sec.ensureUser( min, data.userSystemId, - data.userName ? data.userName : 'apiuser', + data.userName ? data.userName : 'apiuser', '', 'api', data.userSystemId, @@ -1696,9 +1697,10 @@ export class GBMinService { const client = await GBUtil.getDirectLineClient(min); const response = await client.apis.Conversations.Conversations_StartConversation({ userSystemId: user.userSystemId, - userName: user.userName + userName: user.userName, + pid: pid }); - + min['apiConversations'][pid] = { conversation: response.obj, client: client }; min['conversationWelcomed'][response.obj.id] = true; } diff --git a/packages/core.gbapp/services/router/bridge.ts b/packages/core.gbapp/services/router/bridge.ts index a0d7d40e..7f147fec 100644 --- a/packages/core.gbapp/services/router/bridge.ts +++ b/packages/core.gbapp/services/router/bridge.ts @@ -49,7 +49,7 @@ export const getRouter = ( const activity = createConversationUpdateActivity (serviceUrl, conversationId, req.query?.userSystemId, - req.query?.userName + req.query?.userName, req.query.pid ); fetch(botUrl, { method: 'POST', @@ -110,10 +110,12 @@ export const getRouter = ( }); // Sends message to bot. Assumes message activities - router.post(`/directline/${botId}/conversations/:conversationId/activities`, (req, res) => { + + router.post(`/api/messages/${botId}/v3/directline/conversations/:conversationId/activities`, (req, res) => { const incomingActivity = req.body; // Make copy of activity. Add required fields - const activity = createMessageActivity(incomingActivity, serviceUrl, req.params.conversationId); + const activity = createMessageActivity(incomingActivity, serviceUrl, req.params.conversationId, + req.params['pid']); const conversation = getConversation(req.params.conversationId, conversationInitRequired); @@ -147,20 +149,20 @@ export const getRouter = ( console.warn('/v3/conversations not implemented'); }); - router.post(`/api/messages/${botId}/v3/directline/conversations/:conversationId/activities`, (req, res) => { - let activity: IActivity; + // TODO: Check duplicate. router.post(`/api/messages/${botId}/v3/directline/conversations/:conversationId/activities`, (req, res) => { + // let activity: IActivity; - activity = req.body; + // activity = req.body; - const conversation = getConversation(req.params.conversationId, conversationInitRequired); - if (conversation) { - conversation.history.push(activity); - res.status(200).send(); - } else { - // Conversation was never initialized - res.status(400).send(); - } - }); + // const conversation = getConversation(req.params.conversationId, conversationInitRequired); + // if (conversation) { + // conversation.history.push(activity); + // res.status(200).send(); + // } else { + // // Conversation was never initialized + // res.status(400).send(); + // } + // }); router.post(`/api/messages/${botId}/v3/conversations/:conversationId/activities/:activityId`, (req, res) => { let activity: IActivity; @@ -320,21 +322,22 @@ const deleteStateForUser = (req: express.Request, res: express.Response) => { const createMessageActivity = ( incomingActivity: IMessageActivity, serviceUrl: string, - conversationId: string + conversationId: string, pid ): IMessageActivity => { - return { + const obj = { ...incomingActivity, - channelId: 'emulator', + channelId: 'api', serviceUrl, conversation: { id: conversationId }, id: uuidv4.v4() }; + return obj; }; -const createConversationUpdateActivity = (serviceUrl: string, conversationId: string, userSystemId, userName): IConversationUpdateActivity => { +const createConversationUpdateActivity = (serviceUrl: string, conversationId: string, userSystemId, userName, pid): IConversationUpdateActivity => { const activity: IConversationUpdateActivity = { type: 'conversationUpdate', - channelId: 'emulator', + channelId: 'api', serviceUrl, conversation: { id: conversationId }, id: uuidv4.v4(), @@ -342,6 +345,7 @@ const createConversationUpdateActivity = (serviceUrl: string, conversationId: st membersRemoved: [], from: { id: userSystemId, name: userName } }; + activity['pid'] = pid; return activity; }; diff --git a/packages/kb.gbapp/dialogs/AskDialog.ts b/packages/kb.gbapp/dialogs/AskDialog.ts index 211f0d60..ca8ea571 100644 --- a/packages/kb.gbapp/dialogs/AskDialog.ts +++ b/packages/kb.gbapp/dialogs/AskDialog.ts @@ -109,9 +109,7 @@ export class AskDialog extends IGBDialog { const askForMore = min.core.getParam(min.instance, 'Ask For More', null); if (askForMore) { text = askForMore; - } - else { - + } else { return await step.endDialog(null); } } else if (step.context.activity.group || (step.options && step.options.emptyPrompt)) { @@ -131,15 +129,7 @@ export class AskDialog extends IGBDialog { let sec = new SecService(); const member = step.context.activity.from; - const user = await sec.ensureUser( - min, - member.id, - member.name, - '', - 'web', - member.name, - null - ); + const user = await sec.ensureUser(min, member.id, member.name, '', 'web', member.name, null); let handled = false; let nextDialog = null; @@ -210,7 +200,7 @@ export class AskDialog extends IGBDialog { const locale = step.context.activity.locale; // Stops any content on projector. - if (step.context.activity.channelId !== 'msteams') { + if (step.context.activity.channelId === 'web') { await min.conversationalService.sendEvent(min, step, 'stop', undefined); } // Handle extra text from FAQ. @@ -236,14 +226,21 @@ export class AskDialog extends IGBDialog { return; } - const results: any = await service.ask(min, user, step, step.context.activity['pid'], text, searchScore, null /* user.subjects */); + const results: any = await service.ask( + min, + user, + step, + step.context.activity['pid'], + text, + searchScore, + null /* user.subjects */ + ); // If there is some result, answer immediately. if (results !== undefined && results.answer !== undefined) { let urls = []; if (results.sources) { - for (const key in results.sources) { const source = results.sources[key]; const packagePath = GBUtil.getGBAIPath(min.botId, `gbkb`); @@ -253,8 +250,7 @@ export class AskDialog extends IGBDialog { } if (urls.length > 0) { - await min.conversationalService.sendEvent( - min, step, 'play', { + await min.conversationalService.sendEvent(min, step, 'play', { playerType: 'multiurl', data: urls }); @@ -268,8 +264,6 @@ export class AskDialog extends IGBDialog { return await AskDialog.handleAnswer(service, min, step, user, answer); } - - GBLogEx.info(min, `SEARCH called but NO answer could be found (zero results).`); // Not found. @@ -284,7 +278,7 @@ export class AskDialog extends IGBDialog { } private static async handleAnswer(service: KBService, min: GBMinInstance, step: any, user, answer: GuaribasAnswer) { - let text = typeof (answer) === 'string' ? answer : answer.content; + let text = typeof answer === 'string' ? answer : answer.content; text = text.trim(); if (text.endsWith('.docx')) { const mainName = GBVMService.getMethodNameFromVBSFilename(text); @@ -381,15 +375,7 @@ export class AskDialog extends IGBDialog { let sec = new SecService(); const member = step.context.activity.from; - const user = await sec.ensureUser( - min, - member.id, - member.name, - '', - 'web', - member.name, - null - ); + const user = await sec.ensureUser(min, member.id, member.name, '', 'web', member.name, null); await step.endDialog(); const pid = step.context.activity['pid']; diff --git a/templates/llm-server.gbai/llm-server.gbdialog/start.bas b/templates/llm-server.gbai/llm-server.gbdialog/start.bas index a932a19c..989e87ef 100644 --- a/templates/llm-server.gbai/llm-server.gbdialog/start.bas +++ b/templates/llm-server.gbai/llm-server.gbdialog/start.bas @@ -14,38 +14,28 @@ For each order placed, return a JSON containing the product name, the table, and Keep orderedItems with only one item and keep sideItems only with the sides that were specified. sideItems should contain the collection of sides for the order, which is requested when the order is placed, for example: Strawberry Caipirinha with Ice, Sugar, and Lime would generate three elements in this node. -Here is an example of the Order JSON, clear the items and send one with the order made by the person, this is just an example: -{ - orderedItems: [ - { - item: { - id: 102, - price: 0.30, - name: Banana - }, - sideItems: [ - { - id: 0, - price: 0, - quantity: 1 - } - ], - quantity: 1, - notes: a - }, - { - item: { - id: 103, - price: 0.30, - name: Carrot - }, - sideItems: [], - quantity: 1, - notes: none - } - ], - userId: ${operator}, - accountIdentifier: Areia, +Here is an example of the Order YAML, clear the items and send one with the order made by the person, this is just an example: + + orderedItems: + - item: + id: 102 + price: 0.30 + name: Banana + sideItems: + - id: 0 + price: 0 + quantity: 1 + quantity: 1 + notes: a + - item: + id: 103 + price: 0.30 + name: Carrot + sideItems: [] + quantity: 1 + notes: none + userId: ${operator} + accountIdentifier: Areia deliveryTypeId: 2 -} + END SYSTEM PROMPT