Files
openmaic/OpenMAIC/lib/orchestration/summarizers/conversation-summary.ts
2026-08-16 14:58:47 +08:00

70 lines
2.3 KiB
TypeScript

// ==================== Conversation Summary ====================
/**
* OpenAI message format (used by director)
*/
export interface OpenAIMessage {
role: 'system' | 'user' | 'assistant';
content: string;
}
/**
* Regex used only for content stripping — removes the [senderName]: display prefix
* that message-converter.ts adds to role:'user' messages.
* Used cosmetically in summarizeConversation() output; NOT used for discrimination.
*/
const SENDER_PREFIX_RE = /^\[[^\]]+\]:\s*/;
/**
* Summarize conversation history for the director agent.
*
* In the director path, convertMessagesToOpenAI() is called without currentAgentId,
* so peer agent messages remain as role:'assistant'. The role field is therefore a
* reliable discriminator:
* - role:'user' → genuine human student message
* - role:'assistant' → agent turn
*
* message-converter.ts adds a [senderName]: display prefix to role:'user' content
* (e.g. "[You]: Can a 3D object be axisymmetric?"). This prefix is stripped from
* the summary output for readability — it is NOT used for discrimination.
*
* @param messages - OpenAI-format messages from the director path
* @param maxMessages - Maximum number of recent messages to include (default 10)
* @param maxContentLength - Maximum content length per message (default 200)
*/
export function summarizeConversation(
messages: OpenAIMessage[],
maxMessages = 10,
maxContentLength = 200,
): string {
if (messages.length === 0) {
return 'No conversation history yet.';
}
const recent = messages.slice(-maxMessages);
const lines = recent.map((msg) => {
let roleLabel: string;
let content: string;
if (msg.role === 'user') {
// In the director path, all role:'user' messages are genuine human turns.
// Strip the [senderName]: display prefix added by message-converter for readability.
roleLabel = 'Student (Human)';
content = msg.content.replace(SENDER_PREFIX_RE, '');
} else if (msg.role === 'assistant') {
roleLabel = 'Agent';
content = msg.content;
} else {
roleLabel = 'System';
content = msg.content;
}
const truncated =
content.length > maxContentLength ? content.slice(0, maxContentLength) + '...' : content;
return `[${roleLabel}] ${truncated}`;
});
return lines.join('\n');
}