Tesseract / studio /src /utils /parseMessage.js
rkbosamia's picture
fine tuning + base model change
bb15695
Raw
History Blame Contribute Delete
2.29 kB
// Parse an assistant message into ordered segments: prose chunks and code
// chunks. Handles the streaming case where the trailing fence is still open.
//
// Each code segment carries: { type:'code', lang, filename, code, streaming }
// Each prose segment carries: { type:'prose', content }
//
// "streaming: true" marks a code block whose closing ``` hasn't arrived yet —
// the UI uses this to show a live indicator and auto-scroll.
const FENCE_OPEN_RE = /```([a-zA-Z0-9_-]*)?\n/
const FENCE_CLOSE_RE = /\n```/
const FILE_COMMENT_RE = /^\s*\/\/\s*[Ff]ile:\s*([^\n]+)\n/
function defaultFilename(lang) {
const l = (lang || '').toLowerCase()
if (l === 'css') return 'styles.css'
if (l === 'html') return 'index.html'
if (l === 'json') return 'data.json'
return 'App.jsx'
}
export function parseMessageSegments(text) {
const segments = []
if (!text) return segments
let cursor = 0
while (cursor < text.length) {
const rest = text.slice(cursor)
const openMatch = rest.match(FENCE_OPEN_RE)
if (!openMatch) {
// Remaining is all prose
const tail = rest
if (tail.trim()) segments.push({ type: 'prose', content: tail })
break
}
const openIdx = openMatch.index
// Prose before this code block
if (openIdx > 0) {
const prose = rest.slice(0, openIdx)
if (prose.trim()) segments.push({ type: 'prose', content: prose })
}
const lang = openMatch[1] || ''
const afterOpen = rest.slice(openIdx + openMatch[0].length)
const closeMatch = afterOpen.match(FENCE_CLOSE_RE)
let body, streaming, advance
if (closeMatch) {
body = afterOpen.slice(0, closeMatch.index)
streaming = false
advance = openIdx + openMatch[0].length + closeMatch.index + closeMatch[0].length
} else {
// No closing fence yet — this block is still streaming.
body = afterOpen
streaming = true
advance = rest.length
}
const fileComment = body.match(FILE_COMMENT_RE)
const filename = fileComment
? fileComment[1].trim().replace(/^\//, '')
: defaultFilename(lang)
const code = fileComment ? body.slice(fileComment[0].length) : body
segments.push({ type: 'code', lang, filename, code, streaming })
cursor += advance
}
return segments
}