UNPKG

@microsoft/teams-ai

Version:

SDK focused on building AI based applications for Microsoft Teams.

95 lines 3.89 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.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