Skip to content

Commit d9e948c

Browse files
committed
add getUserMessage and getSystemMessage functions
1 parent 0e7e1fb commit d9e948c

File tree

6 files changed

+66
-81
lines changed

6 files changed

+66
-81
lines changed

cli/src/commands/init.ts

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import {
77
} from '@codebuff/common/json-config/constants'
88

99
import { getProjectRoot } from '../project-files'
10+
import { getSystemMessage } from '../utils/message-history'
1011

1112
import type { PostUserMessageFn } from '../types/contracts/send-message'
1213

@@ -19,13 +20,7 @@ export function handleInitializationFlowLocally(): {
1920
if (existsSync(configPath)) {
2021
const postUserMessage: PostUserMessageFn = (prev) => [
2122
...prev,
22-
23-
{
24-
id: `sys-${Date.now()}`,
25-
variant: 'ai' as const,
26-
content: `📋 ${codebuffConfigFile} already exists.`,
27-
timestamp: new Date().toISOString(),
28-
},
23+
getSystemMessage(`📋 ${codebuffConfigFile} already exists.`),
2924
]
3025
return {
3126
postUserMessage,
@@ -37,12 +32,7 @@ export function handleInitializationFlowLocally(): {
3732

3833
const postUserMessage: PostUserMessageFn = (prev) => [
3934
...prev,
40-
{
41-
id: `sys-${Date.now()}`,
42-
variant: 'ai' as const,
43-
content: `✅ Created \`${codebuffConfigFile}\``,
44-
timestamp: new Date().toISOString(),
45-
},
35+
getSystemMessage(`✅ Created \`${codebuffConfigFile}\``),
4636
]
4737
return { postUserMessage }
4838
}

cli/src/commands/router.ts

Lines changed: 10 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { runTerminalCommand } from '@codebuff/sdk'
22

33
import { handleInitializationFlowLocally } from './init'
44
import { handleUsageCommand } from './usage'
5+
import { getSystemMessage, getUserMessage } from '../utils/message-history'
56

67
import type { MultilineInputHandle } from '../components/multiline-input'
78
import type { InputValue } from '../state/chat-store'
@@ -82,19 +83,8 @@ export async function routeUserPrompt(params: {
8283

8384
setMessages((prev) => [
8485
...prev,
85-
{
86-
id: `user-${Date.now()}`,
87-
variant: 'user',
88-
content: trimmed,
89-
timestamp: new Date().toISOString(),
90-
},
91-
{
92-
id: `sys-${Date.now()}`,
93-
variant: 'ai',
94-
content: '',
95-
blocks: [resultBlock],
96-
timestamp: new Date().toISOString(),
97-
},
86+
getUserMessage(trimmed),
87+
getSystemMessage([resultBlock]),
9888
])
9989

10090
runTerminalCommand({
@@ -134,13 +124,12 @@ export async function routeUserPrompt(params: {
134124
const normalized = trimmed.startsWith('/') ? trimmed.slice(1) : trimmed
135125
const cmd = normalized.split(/\s+/)[0].toLowerCase()
136126
if (cmd === 'login' || cmd === 'signin') {
137-
const msg = {
138-
id: `sys-${Date.now()}`,
139-
variant: 'ai' as const,
140-
content: "You're already in the app. Use /logout to switch accounts.",
141-
timestamp: new Date().toISOString(),
142-
}
143-
setMessages((prev) => [...prev, msg])
127+
setMessages((prev) => [
128+
...prev,
129+
getSystemMessage(
130+
"You're already in the app. Use /logout to switch accounts.",
131+
),
132+
])
144133
setInputValue({ text: '', cursorPosition: 0, lastEditDueToNav: false })
145134
return
146135
}
@@ -151,13 +140,7 @@ export async function routeUserPrompt(params: {
151140

152141
logoutMutation.mutate(undefined, {
153142
onSettled: () => {
154-
const msg = {
155-
id: `sys-${Date.now()}`,
156-
variant: 'ai' as const,
157-
content: 'Logged out.',
158-
timestamp: new Date().toISOString(),
159-
}
160-
setMessages((prev) => [...prev, msg])
143+
setMessages((prev) => [...prev, getSystemMessage('Logged out.')])
161144
setInputValue({ text: '', cursorPosition: 0, lastEditDueToNav: false })
162145
setTimeout(() => {
163146
setUser(null)

cli/src/commands/usage.ts

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ import { BACKEND_URL } from '@codebuff/sdk'
33
import { useChatStore } from '../state/chat-store'
44
import { getAuthToken } from '../utils/auth'
55
import { logger } from '../utils/logger'
6+
import { getSystemMessage } from '../utils/message-history'
7+
68
import type { PostUserMessageFn } from '../types/contracts/send-message'
79

810
interface UsageResponse {
@@ -22,12 +24,7 @@ export async function handleUsageCommand(): Promise<{
2224
if (!authToken) {
2325
const postUserMessage: PostUserMessageFn = (prev) => [
2426
...prev,
25-
{
26-
id: `sys-${Date.now()}`,
27-
variant: 'ai' as const,
28-
content: 'Please log in first to view your usage.',
29-
timestamp: new Date().toISOString(),
30-
},
27+
getSystemMessage('Please log in first to view your usage.'),
3128
]
3229
return { postUserMessage }
3330
}
@@ -53,12 +50,7 @@ export async function handleUsageCommand(): Promise<{
5350

5451
const postUserMessage: PostUserMessageFn = (prev) => [
5552
...prev,
56-
{
57-
id: `sys-${Date.now()}`,
58-
variant: 'ai' as const,
59-
content: `Failed to fetch usage data: ${errorText}`,
60-
timestamp: new Date().toISOString(),
61-
},
53+
getSystemMessage(`Failed to fetch usage data: ${errorText}`),
6254
]
6355
return { postUserMessage }
6456
}
@@ -96,12 +88,7 @@ export async function handleUsageCommand(): Promise<{
9688

9789
const postUserMessage: PostUserMessageFn = (prev) => [
9890
...prev,
99-
{
100-
id: `sys-${Date.now()}`,
101-
variant: 'ai' as const,
102-
content: usageMessage,
103-
timestamp: new Date().toISOString(),
104-
},
91+
getSystemMessage(usageMessage),
10592
]
10693
return { postUserMessage }
10794
} catch (error) {
@@ -115,12 +102,7 @@ export async function handleUsageCommand(): Promise<{
115102

116103
const postUserMessage: PostUserMessageFn = (prev) => [
117104
...prev,
118-
{
119-
id: `sys-${Date.now()}`,
120-
variant: 'ai' as const,
121-
content: 'Error checking usage. Please try again later.',
122-
timestamp: new Date().toISOString(),
123-
},
105+
getSystemMessage('Error checking usage. Please try again later.'),
124106
]
125107
return { postUserMessage }
126108
}

cli/src/hooks/use-send-message.ts

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { formatTimestamp } from '../utils/helpers'
1313
import { loadAgentDefinitions } from '../utils/load-agent-definitions'
1414
import { getLoadedAgentsData } from '../utils/local-agent-registry'
1515
import { logger } from '../utils/logger'
16+
import { getUserMessage } from '../utils/message-history'
1617

1718
import type { ElapsedTimeTracker } from './use-elapsed-time'
1819
import type { StreamStatus } from './use-message-queue'
@@ -404,7 +405,6 @@ export const useSendMessage = ({
404405
const sendMessage = useCallback<SendMessageFn>(
405406
async (params: ParamsOf<SendMessageFn>) => {
406407
const { content, agentMode, postUserMessage } = params
407-
const timestamp = formatTimestamp()
408408

409409
if (agentMode !== 'PLAN') {
410410
setHasReceivedPlanResponse(false)
@@ -425,14 +425,6 @@ export const useSendMessage = ({
425425
const shouldInsertDivider =
426426
lastMessageMode === null || lastMessageMode !== agentMode
427427

428-
// Add user message to UI first
429-
const userMessage: ChatMessage = {
430-
id: `user-${Date.now()}`,
431-
variant: 'user',
432-
content,
433-
timestamp,
434-
}
435-
436428
applyMessageUpdate((prev) => {
437429
let newMessages = [...prev]
438430

@@ -453,7 +445,8 @@ export const useSendMessage = ({
453445
newMessages.push(dividerMessage)
454446
}
455447

456-
newMessages.push(userMessage)
448+
// Add user message to UI first
449+
newMessages.push(getUserMessage(content))
457450

458451
if (postUserMessage) {
459452
newMessages = postUserMessage(newMessages)

cli/src/utils/message-history.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,44 @@ import path from 'path'
44
import { getConfigDir } from './auth'
55
import { logger } from './logger'
66

7+
import type { ChatMessage, ContentBlock } from '../types/chat'
8+
79
const MAX_HISTORY_SIZE = 1000
810

11+
export function getUserMessage(message: string | ContentBlock[]): ChatMessage {
12+
return {
13+
id: `user-${Date.now()}`,
14+
variant: 'user',
15+
...(typeof message === 'string'
16+
? {
17+
content: message,
18+
}
19+
: {
20+
content: '',
21+
blocks: message,
22+
}),
23+
timestamp: new Date().toISOString(),
24+
}
25+
}
26+
27+
export function getSystemMessage(
28+
content: string | ContentBlock[],
29+
): ChatMessage {
30+
return {
31+
id: `sys-${Date.now()}`,
32+
variant: 'ai' as const,
33+
...(typeof content === 'string'
34+
? {
35+
content,
36+
}
37+
: {
38+
content: '',
39+
blocks: content,
40+
}),
41+
timestamp: new Date().toISOString(),
42+
}
43+
}
44+
945
/**
1046
* Get the message history file path
1147
*/

cli/src/utils/slash-commands.ts

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { getSystemMessage } from './message-history'
2+
13
import type { User } from './auth'
24
import type { AgentMode } from './constants'
35
import type { MultilineInputHandle } from '../components/multiline-input'
@@ -60,13 +62,12 @@ export function handleSlashCommands(params: {
6062
const normalized = trimmed.startsWith('/') ? trimmed.slice(1) : trimmed
6163
const cmd = normalized.split(/\s+/)[0].toLowerCase()
6264
if (cmd === 'login' || cmd === 'signin') {
63-
const msg = {
64-
id: `sys-${Date.now()}`,
65-
variant: 'ai' as const,
66-
content: "You're already in the app. Use /logout to switch accounts.",
67-
timestamp: new Date().toISOString(),
68-
}
69-
setMessages((prev) => [...prev, msg])
65+
setMessages((prev) => [
66+
...prev,
67+
getSystemMessage(
68+
"You're already in the app. Use /logout to switch accounts.",
69+
),
70+
])
7071
setInputValue('')
7172
return
7273
}

0 commit comments

Comments
 (0)