-
Notifications
You must be signed in to change notification settings - Fork 172
Expand file tree
/
Copy pathformatMessage.ts
More file actions
111 lines (98 loc) · 3.12 KB
/
formatMessage.ts
File metadata and controls
111 lines (98 loc) · 3.12 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
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<boolean> {
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
}
}