| |
| |
| |
| |
| |
| |
|
|
|
|
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| export class BaseMessage {
|
| constructor(content, additionalKwargs = {}) {
|
| this.content = content;
|
| this.additionalKwargs = additionalKwargs;
|
| this.timestamp = Date.now();
|
| this.id = this.generateId();
|
| }
|
|
|
| |
| |
|
|
| generateId() {
|
| return `msg_${this.timestamp}_${Math.random().toString(36).substr(2, 9)}`;
|
| }
|
|
|
| |
| |
|
|
| get type() {
|
| throw new Error('Subclass must implement type getter');
|
| }
|
|
|
| |
| |
|
|
| toJSON() {
|
| return {
|
| id: this.id,
|
| type: this.type,
|
| content: this.content,
|
| timestamp: this.timestamp,
|
| ...this.additionalKwargs
|
| };
|
| }
|
|
|
| |
| |
|
|
| static fromJSON(json) {
|
| const MessageClass = MESSAGE_TYPES[json.type];
|
| if (!MessageClass) {
|
| throw new Error(`Unknown message type: ${json.type}`);
|
| }
|
|
|
| const message = new MessageClass(json.content, json.additionalKwargs);
|
| message.id = json.id;
|
| message.timestamp = json.timestamp;
|
| return message;
|
| }
|
|
|
| |
| |
|
|
| toString() {
|
| const date = new Date(this.timestamp).toLocaleTimeString();
|
| return `[${date}] ${this.type}: ${this.content}`;
|
| }
|
| }
|
|
|
| |
| |
| |
| |
| |
|
|
| export class SystemMessage extends BaseMessage {
|
| constructor(content, additionalKwargs = {}) {
|
| super(content, additionalKwargs);
|
| }
|
|
|
| get type() {
|
| return 'system';
|
| }
|
|
|
| |
| |
|
|
| toPromptFormat() {
|
| return {
|
| role: 'system',
|
| content: this.content
|
| };
|
| }
|
| }
|
|
|
| |
| |
| |
| |
| |
|
|
| export class HumanMessage extends BaseMessage {
|
| constructor(content, additionalKwargs = {}) {
|
| super(content, additionalKwargs);
|
| }
|
|
|
| get type() {
|
| return 'human';
|
| }
|
|
|
| toPromptFormat() {
|
| return {
|
| role: 'user',
|
| content: this.content
|
| };
|
| }
|
| }
|
|
|
| |
| |
| |
| |
| |
|
|
| export class AIMessage extends BaseMessage {
|
| constructor(content, additionalKwargs = {}) {
|
| super(content, additionalKwargs);
|
|
|
|
|
| this.toolCalls = additionalKwargs.toolCalls || [];
|
| }
|
|
|
| get type() {
|
| return 'ai';
|
| }
|
|
|
| |
| |
|
|
| hasToolCalls() {
|
| return this.toolCalls.length > 0;
|
| }
|
|
|
| |
| |
|
|
| getToolCall(index = 0) {
|
| return this.toolCalls[index];
|
| }
|
|
|
| toPromptFormat() {
|
| const formatted = {
|
| role: 'assistant',
|
| content: this.content
|
| };
|
|
|
| if (this.hasToolCalls()) {
|
| formatted.tool_calls = this.toolCalls;
|
| }
|
|
|
| return formatted;
|
| }
|
| }
|
|
|
| |
| |
| |
| |
| |
|
|
| export class ToolMessage extends BaseMessage {
|
| constructor(content, toolCallId, additionalKwargs = {}) {
|
| super(content, additionalKwargs);
|
| this.toolCallId = toolCallId;
|
| }
|
|
|
| get type() {
|
| return 'tool';
|
| }
|
|
|
| toPromptFormat() {
|
| return {
|
| role: 'tool',
|
| content: this.content,
|
| tool_call_id: this.toolCallId
|
| };
|
| }
|
| }
|
|
|
| |
| |
|
|
| export const MESSAGE_TYPES = {
|
| 'system': SystemMessage,
|
| 'human': HumanMessage,
|
| 'ai': AIMessage,
|
| 'tool': ToolMessage
|
| };
|
|
|
| |
| |
| |
| |
| |
|
|
| export function messagesToPromptFormat(messages) {
|
| return messages.map(msg => msg.toPromptFormat());
|
| }
|
|
|
| |
| |
| |
| |
| |
| |
|
|
| export function filterMessagesByType(messages, type) {
|
| return messages.filter(msg => msg._type === type);
|
| }
|
|
|
| |
| |
| |
| |
| |
| |
|
|
| export function getLastMessages(messages, n) {
|
| return messages.slice(-n);
|
| }
|
|
|
| |
| |
| |
| |
| |
| |
|
|
| export function mergeConsecutiveMessages(messages) {
|
| if (messages.length === 0) return [];
|
|
|
| const merged = [messages[0]];
|
|
|
| for (let i = 1; i < messages.length; i++) {
|
| const current = messages[i];
|
| const last = merged[merged.length - 1];
|
|
|
|
|
| if (
|
| current._type === last._type &&
|
| typeof current.content === 'string' &&
|
| typeof last.content === 'string' &&
|
| current._type !== 'tool'
|
| ) {
|
|
|
| const MessageClass = MESSAGE_CLASSES[current._type];
|
| const mergedContent = last.content + '\n' + current.content;
|
| merged[merged.length - 1] = new MessageClass(mergedContent, {
|
| name: last.name,
|
| additionalKwargs: { ...last.additionalKwargs, merged: true }
|
| });
|
| } else {
|
| merged.push(current);
|
| }
|
| }
|
|
|
| return merged;
|
| }
|
|
|
| export default {
|
| BaseMessage,
|
| SystemMessage,
|
| HumanMessage,
|
| AIMessage,
|
| ToolMessage,
|
| MESSAGE_TYPES
|
| }; |