diff --git a/sgr-agent-frontend/src/shared/lib/constants/agents.ts b/sgr-agent-frontend/src/shared/lib/constants/agents.ts new file mode 100644 index 00000000..f8204d1b --- /dev/null +++ b/sgr-agent-frontend/src/shared/lib/constants/agents.ts @@ -0,0 +1,4 @@ +export const MODEL_TYPES = [ + { name: 'sgr_agent', value: 'sgr_agent', id: 1 }, + { name: 'sgr_auto_tool_calling_agent', value: 'sgr_auto_tool_calling_agent', id: 2 }, +] diff --git a/sgr-agent-frontend/src/shared/lib/index.ts b/sgr-agent-frontend/src/shared/lib/index.ts new file mode 100644 index 00000000..86bff296 --- /dev/null +++ b/sgr-agent-frontend/src/shared/lib/index.ts @@ -0,0 +1,4 @@ +// Shared lib exports +export * from './constants/agents' +export * from './utils/id' +export * from './utils/formatMessage' diff --git a/sgr-agent-frontend/src/shared/lib/utils/formatMessage.ts b/sgr-agent-frontend/src/shared/lib/utils/formatMessage.ts new file mode 100644 index 00000000..dd843553 --- /dev/null +++ b/sgr-agent-frontend/src/shared/lib/utils/formatMessage.ts @@ -0,0 +1,111 @@ +import type { ChatMessageExtended } from '@/shared/types/store' + +/** + * Formats message to markdown format for copying + */ +export function formatMessageToMarkdown(message: ChatMessageExtended): string { + const lines: string[] = [] + + // Message header + if (message.role === 'user') { + lines.push('## 👤 User\n') + } else if (message.role === 'assistant') { + lines.push('## 🤖 Assistant\n') + } else { + lines.push('## System\n') + } + + // Main content + if (message.content && message.content.length > 0) { + message.content.forEach((content) => { + // content can be string or ReasoningStep object + if (typeof content === 'string') { + lines.push(content) + } else if (content && typeof content === 'object') { + // If it's an object (ReasoningStep), convert to string + lines.push(JSON.stringify(content, null, 2)) + } + }) + } + + // Agent Reasoning (if exists) + if (message.agentReasoning) { + lines.push('\n### 🧠 Reasoning\n') + + if (message.agentReasoning.reasoning) { + lines.push('**Reasoning:**') + lines.push(String(message.agentReasoning.reasoning)) + lines.push('') + } + + if (message.agentReasoning.steps && Array.isArray(message.agentReasoning.steps)) { + lines.push('**Steps:**\n') + message.agentReasoning.steps.forEach((step: any, index: number) => { + lines.push(`${index + 1}. **${step.action || step.title || 'Action'}**`) + if (step.reasoning) { + lines.push(` - Reasoning: ${step.reasoning}`) + } + if (step.result || step.content) { + lines.push(` - Result: ${step.result || step.content}`) + } + lines.push('') + }) + } + } + + // Tool History (if exists) + if (message.toolHistory && message.toolHistory.length > 0) { + lines.push('\n### 🔧 Tool History\n') + message.toolHistory.forEach((tool, index) => { + lines.push(`#### Tool ${index + 1}: ${tool.tool_name || 'Unknown'}`) + if (tool.tool_call_id) { + lines.push(`- Call ID: \`${tool.tool_call_id}\``) + } + lines.push('- Content:') + lines.push('```') + lines.push(tool.content || '') + lines.push('```') + lines.push('') + }) + } + + // Timestamp + if (message.timestamp) { + const date = new Date(message.timestamp) + lines.push(`\n---`) + lines.push(`*${date.toLocaleString()}*`) + } + + return lines.join('\n') +} + +/** + * Copies text to clipboard + */ +export async function copyToClipboard(text: string): Promise { + try { + // Modern API + if (navigator.clipboard && navigator.clipboard.writeText) { + await navigator.clipboard.writeText(text) + return true + } + + // Fallback for old browsers + const textArea = document.createElement('textarea') + textArea.value = text + textArea.style.position = 'fixed' + textArea.style.left = '-999999px' + textArea.style.top = '-999999px' + document.body.appendChild(textArea) + textArea.focus() + textArea.select() + + const successful = document.execCommand('copy') + document.body.removeChild(textArea) + + return successful + } catch (error) { + console.error('Failed to copy to clipboard:', error) + return false + } +} diff --git a/sgr-agent-frontend/src/shared/lib/utils/id.ts b/sgr-agent-frontend/src/shared/lib/utils/id.ts new file mode 100644 index 00000000..227d0b6d --- /dev/null +++ b/sgr-agent-frontend/src/shared/lib/utils/id.ts @@ -0,0 +1,26 @@ +/** + * Generates a unique ID using timestamp and random string + * @param prefix - Optional prefix for the ID + * @returns Unique ID string + */ +export function generateUniqueId(prefix: string = ''): string { + const timestamp = Date.now() + const randomString = Math.random().toString(36).substr(2, 9) + return prefix ? `${prefix}_${timestamp}_${randomString}` : `${timestamp}_${randomString}` +} + +/** + * Generates a unique chat session ID + * @returns Unique chat session ID + */ +export function generateChatSessionId(): string { + return generateUniqueId('chat') +} + +/** + * Generates a unique message ID + * @returns Unique message ID + */ +export function generateMessageId(): string { + return generateUniqueId('msg') +}