@microsoft/teams-ai
Version:
SDK focused on building AI based applications for Microsoft Teams.
95 lines • 3.89 kB
JavaScript
;
/**
* @module teams-ai
*/
/**
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
exports.UserInputMessage = void 0;
const PromptSectionBase_1 = require("./PromptSectionBase");
/**
* A section capable of rendering user input text and images as a user message.
*/
class UserInputMessage extends PromptSectionBase_1.PromptSectionBase {
_inputVariable;
_filesVariable;
/**
* Creates a new 'UserInputMessage' instance.
* @param {number} tokens Optional. Sizing strategy for this section. Defaults to `auto`.
* @param {string} inputVariable Optional. Name of the variable containing the user input text. Defaults to `input`.
* @param {string} filesVariable Optional. Name of the variable containing the user input files. Defaults to `inputFiles`.
*/
constructor(tokens = -1, inputVariable = 'input', filesVariable = 'inputFiles') {
super(tokens, true, '\n', 'user: ');
this._inputVariable = inputVariable;
this._filesVariable = filesVariable;
}
/**
* @private
* @param {TurnContext} context Turn context for the message to be rendered.
* @param {Memory} memory Memory in storage.
* @param {PromptFunctions} functions Prompt functions.
* @param {Tokenizer} tokenizer Tokenizer.
* @param {number} maxTokens Max tokens to be used for rendering.
* @returns {Promise<RenderedPromptSection<Message<any>[]>>} Rendered prompt section.
*/
async renderAsMessages(context, memory, functions, tokenizer, maxTokens) {
// Get input text & images
const inputText = memory.getValue(this._inputVariable) ?? '';
const inputFiles = memory.getValue(this._filesVariable) ?? [];
// Create message
const message = {
role: 'user',
content: []
};
// Append text content part
let length = 0;
let budget = this.getTokenBudget(maxTokens);
if (inputText.length > 0) {
const encoded = tokenizer.encode(inputText);
if (encoded.length <= budget) {
message.content.push({ type: 'text', text: inputText });
length += encoded.length;
budget -= encoded.length;
}
else {
message.content.push({ type: 'text', text: tokenizer.decode(encoded.slice(0, budget)) });
length += budget;
budget = 0;
}
}
// Append image content parts
const images = inputFiles.filter((f) => f.contentType.startsWith('image/'));
for (const image of images) {
// Check for budget to add image
// This accounts for low detail images but not high detail images.
// https://platform.openai.com/docs/guides/vision
// low res mode defaults to a 512x512px image which is budgeted at 85 tokens.
// Additional work is needed to account for high detail images.
if (budget < 85) {
break;
}
let url;
// Add image
if (image.content.toString().startsWith('data:image/png;base64,')) {
url = image.content.toString();
}
else {
url = `data:${image.contentType};base64,${image.content.toString('base64')}`;
}
message.content.push({ type: 'image_url', image_url: { url } });
length += 85;
budget -= 85;
}
const output = [];
if (message.content.length > 0) {
output.push(message);
}
// Return output
return { output, length, tooLong: false };
}
}
exports.UserInputMessage = UserInputMessage;
//# sourceMappingURL=UserInputMessage.js.map