diff --git a/src/components/chat-view/ReactMarkdown.tsx b/src/components/chat-view/ReactMarkdown.tsx
index 8396660..21a8c1b 100644
--- a/src/components/chat-view/ReactMarkdown.tsx
+++ b/src/components/chat-view/ReactMarkdown.tsx
@@ -9,6 +9,7 @@ import {
import MarkdownActionBlock from './MarkdownActionBlock'
import MarkdownReferenceBlock from './MarkdownReferenceBlock'
+import MarkdownReasoningBlock from './MarkdownReasoningBlock'
function ReactMarkdown({
onApply,
@@ -36,6 +37,11 @@ function ReactMarkdown({
{block.content}
+ ) : block.type === 'think' ? (
+
) : block.startLine && block.endLine && block.filename && block.action === InfioBlockAction.Reference ? (
{
+ const input = `Some text before
+
+This is a thought that should be parsed separately.
+It might contain multiple lines of text.
+
+Some text after`
+
+ const expected: ParsedInfioBlock[] = [
+ { type: 'string', content: 'Some text before\n' },
+ {
+ type: 'think',
+ content: `
+This is a thought that should be parsed separately.
+It might contain multiple lines of text.
+`
+ },
+ { type: 'string', content: '\nSome text after' },
+ ]
+
+ const result = parseinfioBlocks(input)
+ expect(result).toEqual(expected)
+ })
+
+ it('should handle empty think elements', () => {
+ const input = `
+
+ `
+
+ const expected: ParsedInfioBlock[] = [
+ { type: 'string', content: '\n ' },
+ {
+ type: 'think',
+ content: '',
+ },
+ { type: 'string', content: '\n ' },
+ ]
+
+ const result = parseinfioBlocks(input)
+ expect(result).toEqual(expected)
+ })
+
+ it('should handle mixed infio_block and think elements', () => {
+ const input = `Start
+
+def greet(name):
+ print(f"Hello, {name}!")
+
+Middle
+
+Let me think about this problem...
+I need to consider several approaches.
+
+End`
+
+ const expected: ParsedInfioBlock[] = [
+ { type: 'string', content: 'Start\n' },
+ {
+ type: 'infio_block',
+ content: `
+def greet(name):
+ print(f"Hello, {name}!")
+`,
+ language: 'python',
+ filename: 'script.py',
+ },
+ { type: 'string', content: '\nMiddle\n' },
+ {
+ type: 'think',
+ content: `
+Let me think about this problem...
+I need to consider several approaches.
+`
+ },
+ { type: 'string', content: '\nEnd' },
+ ]
+
+ const result = parseinfioBlocks(input)
+ expect(result).toEqual(expected)
+ })
+
+ it('should handle unfinished think with only opening tag', () => {
+ const input = `Start
+
+Some unfinished thought
+without closing tag`
+ const expected: ParsedInfioBlock[] = [
+ { type: 'string', content: 'Start\n' },
+ {
+ type: 'think',
+ content: `
+Some unfinished thought
+without closing tag`,
+ },
+ ]
+
+ const result = parseinfioBlocks(input)
+ expect(result).toEqual(expected)
+ })
})
diff --git a/src/utils/parse-infio-block.ts b/src/utils/parse-infio-block.ts
index 202621c..09e3ba6 100644
--- a/src/utils/parse-infio-block.ts
+++ b/src/utils/parse-infio-block.ts
@@ -17,6 +17,7 @@ export type ParsedInfioBlock =
endLine?: number
action?: InfioBlockAction
}
+ | { type: 'think'; content: string }
function isInfioBlockAction(value: string): value is InfioBlockAction {
return Object.values(InfioBlockAction).includes(value)
@@ -82,6 +83,39 @@ export function parseinfioBlocks(input: string): ParsedInfioBlock[] {
})
}
lastEndOffset = endOffset
+ } else if (node.nodeName === 'think') {
+ if (!node.sourceCodeLocation) {
+ throw new Error('sourceCodeLocation is undefined')
+ }
+ const startOffset = node.sourceCodeLocation.startOffset
+ const endOffset = node.sourceCodeLocation.endOffset
+ if (startOffset > lastEndOffset) {
+ parsedResult.push({
+ type: 'string',
+ content: input.slice(lastEndOffset, startOffset),
+ })
+ }
+
+ const children = node.childNodes
+ if (children.length === 0) {
+ parsedResult.push({
+ type: 'think',
+ content: '',
+ })
+ } else {
+ const innerContentStartOffset =
+ children[0].sourceCodeLocation?.startOffset
+ const innerContentEndOffset =
+ children[children.length - 1].sourceCodeLocation?.endOffset
+ if (!innerContentStartOffset || !innerContentEndOffset) {
+ throw new Error('sourceCodeLocation is undefined')
+ }
+ parsedResult.push({
+ type: 'think',
+ content: input.slice(innerContentStartOffset, innerContentEndOffset),
+ })
+ }
+ lastEndOffset = endOffset
}
}
if (lastEndOffset < input.length) {