@microsoft/teams-ai
Version:
SDK focused on building AI based applications for Microsoft Teams.
128 lines • 5.67 kB
JavaScript
;
/**
* @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