mirror of
https://github.com/AutoMaker-Org/automaker.git
synced 2026-01-30 14:22:02 +00:00
Created 5 new utility modules in apps/server/src/lib/ to eliminate ~320 lines of duplicated code: - image-handler.ts: Centralized image processing (MIME types, base64, content blocks) - prompt-builder.ts: Standardized prompt building with image attachments - model-resolver.ts: Model alias resolution and provider routing - conversation-utils.ts: Conversation history processing for providers - error-handler.ts: Error classification and user-friendly messages Updated services and providers to use shared utilities: - agent-service.ts: -51 lines (removed duplicate image handling, model logic) - auto-mode-service.ts: -75 lines (removed MODEL_MAP, duplicate utilities) - claude-provider.ts: -10 lines (uses conversation-utils) - codex-provider.ts: -5 lines (uses conversation-utils) Added comprehensive documentation: - docs/server/utilities.md: Complete reference for all 9 lib utilities - docs/server/providers.md: Provider architecture guide with examples Benefits: - Single source of truth for critical business logic - Improved maintainability and testability - Consistent behavior across services and providers - Better documentation for future development 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
98 lines
2.6 KiB
TypeScript
98 lines
2.6 KiB
TypeScript
/**
|
|
* Conversation history utilities for processing message history
|
|
*
|
|
* Provides standardized conversation history handling:
|
|
* - Extract text from content (string or array format)
|
|
* - Normalize content blocks to array format
|
|
* - Format history as plain text for CLI-based providers
|
|
* - Convert history to Claude SDK message format
|
|
*/
|
|
|
|
import type { ConversationMessage } from "../providers/types.js";
|
|
|
|
/**
|
|
* Extract plain text from message content (handles both string and array formats)
|
|
*
|
|
* @param content - Message content (string or array of content blocks)
|
|
* @returns Extracted text content
|
|
*/
|
|
export function extractTextFromContent(
|
|
content: string | Array<{ type: string; text?: string; source?: object }>
|
|
): string {
|
|
if (typeof content === "string") {
|
|
return content;
|
|
}
|
|
|
|
// Extract text blocks only
|
|
return content
|
|
.filter((block) => block.type === "text")
|
|
.map((block) => block.text || "")
|
|
.join("\n");
|
|
}
|
|
|
|
/**
|
|
* Normalize message content to array format
|
|
*
|
|
* @param content - Message content (string or array)
|
|
* @returns Content as array of blocks
|
|
*/
|
|
export function normalizeContentBlocks(
|
|
content: string | Array<{ type: string; text?: string; source?: object }>
|
|
): Array<{ type: string; text?: string; source?: object }> {
|
|
if (Array.isArray(content)) {
|
|
return content;
|
|
}
|
|
return [{ type: "text", text: content }];
|
|
}
|
|
|
|
/**
|
|
* Format conversation history as plain text for CLI-based providers
|
|
*
|
|
* @param history - Array of conversation messages
|
|
* @returns Formatted text with role labels
|
|
*/
|
|
export function formatHistoryAsText(history: ConversationMessage[]): string {
|
|
if (history.length === 0) {
|
|
return "";
|
|
}
|
|
|
|
let historyText = "Previous conversation:\n\n";
|
|
|
|
for (const msg of history) {
|
|
const contentText = extractTextFromContent(msg.content);
|
|
const role = msg.role === "user" ? "User" : "Assistant";
|
|
historyText += `${role}: ${contentText}\n\n`;
|
|
}
|
|
|
|
historyText += "---\n\n";
|
|
return historyText;
|
|
}
|
|
|
|
/**
|
|
* Convert conversation history to Claude SDK message format
|
|
*
|
|
* @param history - Array of conversation messages
|
|
* @returns Array of Claude SDK formatted messages
|
|
*/
|
|
export function convertHistoryToMessages(
|
|
history: ConversationMessage[]
|
|
): Array<{
|
|
type: "user" | "assistant";
|
|
session_id: string;
|
|
message: {
|
|
role: "user" | "assistant";
|
|
content: Array<{ type: string; text?: string; source?: object }>;
|
|
};
|
|
parent_tool_use_id: null;
|
|
}> {
|
|
return history.map((historyMsg) => ({
|
|
type: historyMsg.role,
|
|
session_id: "",
|
|
message: {
|
|
role: historyMsg.role,
|
|
content: normalizeContentBlocks(historyMsg.content),
|
|
},
|
|
parent_tool_use_id: null,
|
|
}));
|
|
}
|