Skip to content

Commit 8f2541f

Browse files
committed
switch cli to use reasoning stream
1 parent f054796 commit 8f2541f

File tree

4 files changed

+78
-41
lines changed

4 files changed

+78
-41
lines changed

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

Lines changed: 48 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -557,8 +557,12 @@ export const useSendMessage = ({
557557
)
558558
}
559559

560-
const appendRootTextChunk = (delta: string) => {
561-
if (!delta) {
560+
const appendRootChunk = (
561+
delta:
562+
| { type: 'text'; text: string }
563+
| { type: 'reasoning'; text: string },
564+
) => {
565+
if (!delta.text) {
562566
return
563567
}
564568

@@ -571,10 +575,14 @@ export const useSendMessage = ({
571575
const blocks: ContentBlock[] = msg.blocks ? [...msg.blocks] : []
572576
const lastBlock = blocks[blocks.length - 1]
573577

574-
if (lastBlock && lastBlock.type === 'text') {
578+
if (
579+
lastBlock &&
580+
lastBlock.type === 'text' &&
581+
delta.type === lastBlock.textType
582+
) {
575583
const updatedBlock: ContentBlock = {
576584
...lastBlock,
577-
content: lastBlock.content + delta,
585+
content: lastBlock.content + delta.text,
578586
}
579587
return {
580588
...msg,
@@ -584,7 +592,15 @@ export const useSendMessage = ({
584592

585593
return {
586594
...msg,
587-
blocks: [...blocks, { type: 'text', content: delta }],
595+
blocks: [
596+
...blocks,
597+
{
598+
type: 'text',
599+
content: delta.text,
600+
textType: delta.type,
601+
...(delta.type === 'reasoning' && { color: 'grey' }),
602+
},
603+
],
588604
}
589605
}),
590606
)
@@ -627,7 +643,30 @@ export const useSendMessage = ({
627643
maxAgentSteps: 40,
628644

629645
handleStreamChunk: (event) => {
630-
if (typeof event !== 'string') {
646+
logger.info({ event }, 'asdf event')
647+
if (typeof event === 'string' || event.type === 'reasoning_chunk') {
648+
const eventObj:
649+
| { type: 'text'; text: string }
650+
| { type: 'reasoning'; text: string } =
651+
typeof event === 'string'
652+
? { type: 'text', text: event }
653+
: { type: 'reasoning', text: event.chunk }
654+
if (!hasReceivedContent) {
655+
hasReceivedContent = true
656+
setIsWaitingForResponse(false)
657+
}
658+
659+
if (!eventObj.text) {
660+
return
661+
}
662+
663+
if (eventObj.type === 'text') {
664+
rootStreamBufferRef.current =
665+
(rootStreamBufferRef.current ?? '') + eventObj.text
666+
}
667+
rootStreamSeenRef.current = true
668+
appendRootChunk(eventObj)
669+
} else if (event.type === 'subagent_chunk') {
631670
const { agentId, chunk } = event
632671

633672
const previous =
@@ -642,21 +681,9 @@ export const useSendMessage = ({
642681
content: chunk,
643682
})
644683
return
684+
} else {
685+
event satisfies never
645686
}
646-
647-
if (!hasReceivedContent) {
648-
hasReceivedContent = true
649-
setIsWaitingForResponse(false)
650-
}
651-
652-
const previous = rootStreamBufferRef.current ?? ''
653-
if (!event) {
654-
return
655-
}
656-
657-
rootStreamBufferRef.current = previous + event
658-
rootStreamSeenRef.current = true
659-
appendRootTextChunk(event)
660687
},
661688

662689
handleEvent: (event: any) => {
@@ -727,7 +754,7 @@ export const useSendMessage = ({
727754
)
728755
rootStreamBufferRef.current = previous + text
729756

730-
appendRootTextChunk(text)
757+
appendRootChunk({ type: 'text', text })
731758
}
732759
return
733760
}

cli/src/types/chat.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export type ContentBlock =
1212
marginTop?: number
1313
marginBottom?: number
1414
status?: 'running' | 'complete'
15+
textType?: 'reasoning' | 'text'
1516
}
1617
| {
1718
type: 'html'

packages/agent-runtime/src/tools/stream-parser.ts

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,4 @@
1-
import {
2-
endToolTag,
3-
startToolTag,
4-
toolNameParam,
5-
toolNames,
6-
} from '@codebuff/common/tools/constants'
1+
import { toolNames } from '@codebuff/common/tools/constants'
72
import { buildArray } from '@codebuff/common/util/array'
83
import { generateCompactId } from '@codebuff/common/util/string'
94
import { cloneDeep } from 'lodash'
@@ -181,7 +176,6 @@ export async function processStreamWithTools(
181176
},
182177
})
183178

184-
let reasoning = false
185179
let messageId: string | null = null
186180
while (true) {
187181
const { value: chunk, done } = await streamWithTags.next()
@@ -191,18 +185,8 @@ export async function processStreamWithTools(
191185
}
192186

193187
if (chunk.type === 'reasoning') {
194-
if (!reasoning) {
195-
reasoning = true
196-
onResponseChunk(`\n\n${startToolTag}{
197-
${JSON.stringify(toolNameParam)}: "think_deeply",
198-
"thought": "`)
199-
}
200-
onResponseChunk(JSON.stringify(chunk.text).slice(1, -1))
188+
onResponseChunk(chunk)
201189
} else if (chunk.type === 'text') {
202-
if (reasoning) {
203-
reasoning = false
204-
onResponseChunk(`"\n}${endToolTag}\n\n`)
205-
}
206190
onResponseChunk(chunk.text)
207191
fullResponseChunks.push(chunk.text)
208192
} else if (chunk.type === 'error') {

sdk/src/run.ts

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,10 @@ export type CodebuffClientOptions = {
6464
agentId: string
6565
agentType: string
6666
chunk: string
67+
}
68+
| {
69+
type: 'reasoning_chunk'
70+
chunk: string
6771
},
6872
) => void | Promise<void>
6973

@@ -151,13 +155,31 @@ export async function run({
151155

152156
const buffers: Record<string | 0, string> = { 0: '' }
153157

158+
let reasoning = ''
159+
async function flushReasoning() {
160+
if (reasoning) {
161+
await handleEvent?.({
162+
type: 'reasoning',
163+
text: reasoning,
164+
})
165+
}
166+
reasoning = ''
167+
}
154168
const onResponseChunk = async (
155169
action: ServerAction<'response-chunk'>,
156170
): Promise<void> => {
157171
checkAborted(signal)
158172
const { chunk } = action
159173
if (typeof chunk !== 'string') {
160-
await handleEvent?.(chunk)
174+
if (chunk.type === 'reasoning') {
175+
handleStreamChunk?.({
176+
type: 'reasoning_chunk',
177+
chunk: chunk.text,
178+
})
179+
} else {
180+
await flushReasoning()
181+
await handleEvent?.(chunk)
182+
}
161183
return
162184
}
163185

@@ -173,7 +195,10 @@ export async function run({
173195
break
174196
}
175197

176-
await handleStreamChunk(value.chunk)
198+
if (value.chunk) {
199+
await flushReasoning()
200+
await handleStreamChunk(value.chunk)
201+
}
177202
}
178203
}
179204
}

0 commit comments

Comments
 (0)