handle <think> tag
This commit is contained in:
parent
3b440b9d00
commit
b0ff08a3cf
@ -9,6 +9,7 @@ import {
|
|||||||
|
|
||||||
import MarkdownActionBlock from './MarkdownActionBlock'
|
import MarkdownActionBlock from './MarkdownActionBlock'
|
||||||
import MarkdownReferenceBlock from './MarkdownReferenceBlock'
|
import MarkdownReferenceBlock from './MarkdownReferenceBlock'
|
||||||
|
import MarkdownReasoningBlock from './MarkdownReasoningBlock'
|
||||||
|
|
||||||
function ReactMarkdown({
|
function ReactMarkdown({
|
||||||
onApply,
|
onApply,
|
||||||
@ -36,6 +37,11 @@ function ReactMarkdown({
|
|||||||
<Markdown key={index} className="infio-markdown">
|
<Markdown key={index} className="infio-markdown">
|
||||||
{block.content}
|
{block.content}
|
||||||
</Markdown>
|
</Markdown>
|
||||||
|
) : block.type === 'think' ? (
|
||||||
|
<MarkdownReasoningBlock
|
||||||
|
key={index}
|
||||||
|
reasoningContent={block.content}
|
||||||
|
/>
|
||||||
) : block.startLine && block.endLine && block.filename && block.action === InfioBlockAction.Reference ? (
|
) : block.startLine && block.endLine && block.filename && block.action === InfioBlockAction.Reference ? (
|
||||||
<MarkdownReferenceBlock
|
<MarkdownReferenceBlock
|
||||||
key={index}
|
key={index}
|
||||||
|
|||||||
@ -199,4 +199,104 @@ Some text after without closing tag`,
|
|||||||
const result = parseinfioBlocks(input)
|
const result = parseinfioBlocks(input)
|
||||||
expect(result).toEqual(expected)
|
expect(result).toEqual(expected)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('should parse a string with think elements', () => {
|
||||||
|
const input = `Some text before
|
||||||
|
<think>
|
||||||
|
This is a thought that should be parsed separately.
|
||||||
|
It might contain multiple lines of text.
|
||||||
|
</think>
|
||||||
|
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 = `
|
||||||
|
<think></think>
|
||||||
|
`
|
||||||
|
|
||||||
|
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
|
||||||
|
<infio_block language="python" filename="script.py">
|
||||||
|
def greet(name):
|
||||||
|
print(f"Hello, {name}!")
|
||||||
|
</infio_block>
|
||||||
|
Middle
|
||||||
|
<think>
|
||||||
|
Let me think about this problem...
|
||||||
|
I need to consider several approaches.
|
||||||
|
</think>
|
||||||
|
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
|
||||||
|
<think>
|
||||||
|
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)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@ -17,6 +17,7 @@ export type ParsedInfioBlock =
|
|||||||
endLine?: number
|
endLine?: number
|
||||||
action?: InfioBlockAction
|
action?: InfioBlockAction
|
||||||
}
|
}
|
||||||
|
| { type: 'think'; content: string }
|
||||||
|
|
||||||
function isInfioBlockAction(value: string): value is InfioBlockAction {
|
function isInfioBlockAction(value: string): value is InfioBlockAction {
|
||||||
return Object.values<string>(InfioBlockAction).includes(value)
|
return Object.values<string>(InfioBlockAction).includes(value)
|
||||||
@ -82,6 +83,39 @@ export function parseinfioBlocks(input: string): ParsedInfioBlock[] {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
lastEndOffset = endOffset
|
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) {
|
if (lastEndOffset < input.length) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user