| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| |
|
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | 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
|
| | }; |