UNPKG

@microsoft/teams-ai

Version:

SDK focused on building AI based applications for Microsoft Teams.

128 lines 5.67 kB
"use strict"; /** * @module teams-ai */ /** * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. */ Object.defineProperty(exports, "__esModule", { value: true }); exports.SequenceAugmentation = void 0; const types_1 = require("../types"); const validators_1 = require("../validators"); const ActionAugmentationSection_1 = require("./ActionAugmentationSection"); /** * The 'sequence' augmentation. * @remarks * This augmentation allows the model to return a sequence of actions to perform. */ class SequenceAugmentation { _section; _planValidator = new validators_1.JSONResponseValidator(types_1.PlanSchema, `Return a JSON object that uses the SAY command to say what you're thinking.`); _actionValidator; constructor(actions) { this._section = new ActionAugmentationSection_1.ActionAugmentationSection(actions, [ `Use the actions above to create a plan in the following JSON format:`, `{"type":"plan","commands":[{"type":"DO","action":"<name>","parameters":{"<name>":<value>}},{"type":"SAY","response":"<response>"}]}` ].join('\n')); this._actionValidator = new validators_1.ActionResponseValidator(actions, true); } /** * Creates an optional prompt section for the augmentation. * @returns {PromptSection | undefined} The new PromptSection or undefined. */ createPromptSection() { return this._section; } /** * Validates a response to a prompt. * @param {TurnContext} context - Context for the current turn of conversation with the user. * @param {Memory} memory - An interface for accessing state values. * @param {Tokenizer} tokenizer - Tokenizer to use for encoding and decoding text. * @param {PromptResponse<string>} response - Response to validate. * @param {number} remaining_attempts - Number of remaining attempts to validate the response. * @returns {Validation} A `Validation` object. */ async validateResponse(context, memory, tokenizer, response, remaining_attempts) { // Validate that we got a well-formed plan const validationResult = await this._planValidator.validateResponse(context, memory, tokenizer, response, remaining_attempts); if (!validationResult.valid) { return validationResult; } // Validate that the plan is structurally correct const plan = validationResult.value; for (let i = 0; i < plan.commands.length; i++) { const command = plan.commands[i]; if (command.type === 'DO') { // Ensure that the model specified an action const doCommand = command; const action = doCommand.action; if (!action) { return { type: 'Validation', valid: false, feedback: `The plan JSON is missing the DO "action" for command[${i}]. Return the name of the action to DO.` }; } // Ensure that the action is valid const parameters = JSON.stringify(doCommand.parameters ?? {}); const message = { role: 'assistant', content: undefined, function_call: { name: doCommand.action, arguments: parameters } }; const actionValidation = await this._actionValidator.validateResponse(context, memory, tokenizer, { status: 'success', message }, remaining_attempts); if (!actionValidation.valid) { return actionValidation; } } else if (command.type === 'SAY') { // Ensure that the model specified a response const sayCommand = command; const response = sayCommand.response; if (!response) { return { type: 'Validation', valid: false, feedback: `The plan JSON is missing the SAY "response" for command[${i}]. Return the response to SAY.` }; } } else { return { type: 'Validation', valid: false, feedback: `The plan JSON contains an unknown command type of ${command.type}. Only use DO or SAY commands.` }; } } // Return the validated monologue return validationResult; } /** * Creates a plan given validated response value. * @param {TurnContext} context - Context for the current turn of conversation. * @param {Memory} memory - An interface for accessing state variables. * @param {PromptResponse<Plan|undefined>} response - The validated and transformed response for the prompt. * @returns {Promise<Plan>} The created plan. */ createPlanFromResponse(context, memory, response) { const plan = response.message.content; plan.commands = plan.commands.map((c) => { if (c.type === 'SAY') { return { ...c, response: { ...response.message, role: 'assistant', content: c.response } }; } return c; }); return Promise.resolve(response.message.content); } } exports.SequenceAugmentation = SequenceAugmentation; //# sourceMappingURL=SequenceAugmentation.js.map