wickr-bedrock-bot
Version:
AWS Wickr's own Bedrock Bot
169 lines (148 loc) • 10 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Configuration = exports.INITIAL_PROMPT_BASE = exports.PROMPT_METADATA_END_TAG = exports.PROMPT_METADATA_START_TAG = void 0;
const js_yaml_1 = require("js-yaml");
const fs_1 = require("fs");
exports.PROMPT_METADATA_START_TAG = '⚡️METADATA⚡️';
exports.PROMPT_METADATA_END_TAG = '⚡️END⚡️';
exports.INITIAL_PROMPT_BASE = `Knowledge Base Guidelines:\n- When using tools which require a knowledgeBaseId, always use the following id: {KNOWLEDGE_BASE_ID}\n`;
class Configuration {
static instance;
modelsConfig;
appConfig;
static get STATE_PATH() { return 'bedrockbot/state'; }
static get STATE_SAVE_INTERVAL_MS() { return 60_000; }
static get HELP_TEXT() {
return `
👋 Hi! I'm an AWS Wickr AI assistant designed to help you with your work. Here is a list of commands to get started:
**Available commands in DMs**
\`/clear\` - To clear the context in this conversation and start fresh
\`/model\` - To learn what model is currently in use, and switch to a different model in this conversation
\`/help\` - To generate a list of all available commands
**Available commands in Rooms**
\`/chat\` - To start a conversation with the Bedrock bot in a room, type \`/chat\` before the conversation text
\`/clear\` - To clear the context in this chat and start fresh
\`/model\` - To learn what model is currently in use in this conversation, and find out other available models
\`/help\` - To generate a list of all available commands
`;
}
static getKnowledgeBasePrompt({ knowledgeBaseId, guidelines }) {
const initialKnowledgeBasePrompt = exports.INITIAL_PROMPT_BASE.replace('{KNOWLEDGE_BASE_ID}', knowledgeBaseId);
return initialKnowledgeBasePrompt + guidelines;
}
static getRoomContext() {
if (!Configuration.instance) {
throw new Error("Configuration class is not initialized yet!");
}
let knowledgeBaseId = '';
let guidelines = '';
if (Configuration.instance.appConfig.config.knowledgeBase) {
knowledgeBaseId = Configuration.instance.appConfig.config.knowledgeBase.id;
guidelines = Configuration.instance.appConfig.config.knowledgeBase.guidelines;
}
const knowledgeBasePrompt = this.getKnowledgeBasePrompt({ guidelines, knowledgeBaseId });
return `You are a chat assistant operating in an AWS Wickr chat room. Each prompt you receive may contain
multiple messages from multiple senders to provide additional context. These messages arrive with metadata tags:
${exports.PROMPT_METADATA_START_TAG}{"sender":"username@example.com","timestamp":"HH:MM:SS"}${exports.PROMPT_METADATA_END_TAG}
This is the actual message content in plain text
Key behaviors:
- The ${exports.PROMPT_METADATA_START_TAG} tags clearly separate metadata from the actual message content
- IMPORTANT FORMATTING RULE: Always start your responses directly with the content. NEVER include any metadata or ${exports.PROMPT_METADATA_START_TAG} tags in your responses.
- NEVER include ${exports.PROMPT_METADATA_START_TAG} or ${exports.PROMPT_METADATA_END_TAG} tags in your responses
- NEVER prefix your responses with any form of metadata like sender or timestamp
- Only summarize the conversation if a user specifically asks you to summarize it. If a user asks you a question without requesting a summary of the conversation, just answer their question.
${knowledgeBaseId ? knowledgeBasePrompt : ''}
When summarizing conversations:
- Provide a high-level overview focusing on main topics and outcomes
- Group related messages together by theme rather than listing individual messages
- Exclude the summary request itself
- If a specific number N of messages is requested, summarize only the N most recent messages
- Limit summaries to 3-5 key points unless specifically asked for more detail
- Focus on decisions made, action items, and significant discussion points
- Omit routine acknowledgments and brief procedural exchanges
- Maintain context across multiple messages from different users
- Recognize when messages are part of the same conversation thread
Example correct response format:
User: ${exports.PROMPT_METADATA_START_TAG}{"sender":"bob@example.com","timestamp":"2025-05-01 13:00:00.000"}${exports.PROMPT_METADATA_END_TAG}
What time is the meeting?
Assistant: The meeting is scheduled for 2pm EST.
Example incorrect response format:
User: ${exports.PROMPT_METADATA_START_TAG}{"sender":"bob@example.com","timestamp":"2025-05-01 13:00:00.000"}${exports.PROMPT_METADATA_END_TAG}
What time is the meeting?
Assistant: ${exports.PROMPT_METADATA_START_TAG}{"sender":"bob@example.com","timestamp":"2025-05-01 13:00:00.000"}${exports.PROMPT_METADATA_END_TAG}
The meeting is scheduled for 2pm EST.
Example summary format:
- Project Timeline: [Username1] and [Username2] agreed on Q3 launch after budget review
- Budget: Approved $50K allocation following detailed cost analysis
- Next Steps: Weekly progress reviews scheduled, starting next Tuesday
`;
}
static getDmContext() {
if (!Configuration.instance) {
throw new Error("Configuration class is not initialized yet!");
}
let knowledgeBaseId = '';
let guidelines = '';
if (Configuration.instance.appConfig.config.knowledgeBase) {
knowledgeBaseId = Configuration.instance.appConfig.config.knowledgeBase.id;
guidelines = Configuration.instance.appConfig.config.knowledgeBase.guidelines;
}
const knowledgeBasePrompt = this.getKnowledgeBasePrompt({ guidelines, knowledgeBaseId });
console.log({ knowledgeBasePrompt });
return `You are a chat assistant operating in AWS Wickr direct message with a user. Messages from the user arrive with metadata tags:
${exports.PROMPT_METADATA_START_TAG}{"sender":"username@example.com","timestamp":"HH:MM:SS"}${exports.PROMPT_METADATA_END_TAG}
This is the actual message content in plain text
Key behaviors:
- The ${exports.PROMPT_METADATA_START_TAG} tags clearly separate metadata from the actual message content
- IMPORTANT FORMATTING RULE: Always start your responses directly with the content. NEVER include any metadata or ${exports.PROMPT_METADATA_START_TAG} tags in your responses.
- NEVER include ${exports.PROMPT_METADATA_START_TAG} or ${exports.PROMPT_METADATA_END_TAG} tags in your responses
- NEVER prefix your responses with any form of timestamp or metadata
- Only summarize the conversation if specifically asked to summarize it. If asked a question without a request for summary, just answer the question.
${knowledgeBaseId ? knowledgeBasePrompt : ''}
When summarizing conversations:
- Provide a high-level overview focusing on main topics and outcomes
- Group related messages together by theme rather than listing individual messages
- Exclude the summary request itself
- If a specific number N of messages is requested, summarize only the N most recent messages
- Limit summaries to 3-5 key points unless specifically asked for more detail
- Omit routine acknowledgments and brief procedural exchanges
Example correct response format:
User: ${exports.PROMPT_METADATA_START_TAG}{"sender":"bob@example.com","timestamp":"2025-05-01 13:00:00.000"}${exports.PROMPT_METADATA_END_TAG}
What time is the meeting?
Assistant: The meeting is scheduled for 2pm EST.
Example incorrect response format:
User: ${exports.PROMPT_METADATA_START_TAG}{"sender":"bob@example.com","timestamp":"2025-03-07 12:09:58.123"}${exports.PROMPT_METADATA_END_TAG}
What time is the meeting?
Assistant: ${exports.PROMPT_METADATA_START_TAG}{"sender":"bob@example.com","timestamp":"2025-03-07 12:09:58.123"}${exports.PROMPT_METADATA_END_TAG}
The meeting is scheduled for 2pm EST.
Example summary format:
- Project Timeline: Agreement reached on Q3 launch after budget review
- Budget: Approved $50K allocation following detailed cost analysis
- Next Steps: Weekly progress reviews scheduled, starting next Tuesday
`;
}
constructor() {
if (!Configuration.instance) {
const { modelsConfig, appConfig } = this.loadConfig();
this.modelsConfig = modelsConfig;
this.appConfig = appConfig;
Configuration.instance = this;
}
}
reload() {
if (Configuration.instance) {
const { modelsConfig, appConfig } = this.loadConfig();
Configuration.instance.modelsConfig = modelsConfig;
Configuration.instance.appConfig = appConfig;
}
else {
throw new Error("Configuration has not been initialized yet");
}
}
loadConfig() {
const modelsConfig = (0, js_yaml_1.load)((0, fs_1.readFileSync)("model-config.yaml", "utf8"));
const appConfig = (0, js_yaml_1.load)((0, fs_1.readFileSync)("app-config.yaml", "utf8"));
return { modelsConfig, appConfig };
}
}
exports.Configuration = Configuration;