| | const ARTIFACT_START = ':::artifact'; |
| | const ARTIFACT_END = ':::'; |
| |
|
| | |
| | |
| | |
| | |
| | |
| | const findAllArtifacts = (message) => { |
| | const artifacts = []; |
| |
|
| | |
| | if (message.content?.length) { |
| | message.content.forEach((part, partIndex) => { |
| | if (part.type === 'text' && typeof part.text === 'string') { |
| | let currentIndex = 0; |
| | let start = part.text.indexOf(ARTIFACT_START, currentIndex); |
| |
|
| | while (start !== -1) { |
| | const end = part.text.indexOf(ARTIFACT_END, start + ARTIFACT_START.length); |
| | artifacts.push({ |
| | start, |
| | end: end !== -1 ? end + ARTIFACT_END.length : part.text.length, |
| | source: 'content', |
| | partIndex, |
| | text: part.text, |
| | }); |
| |
|
| | currentIndex = end !== -1 ? end + ARTIFACT_END.length : part.text.length; |
| | start = part.text.indexOf(ARTIFACT_START, currentIndex); |
| | } |
| | } |
| | }); |
| | } |
| |
|
| | |
| | if (!artifacts.length && message.text) { |
| | let currentIndex = 0; |
| | let start = message.text.indexOf(ARTIFACT_START, currentIndex); |
| |
|
| | while (start !== -1) { |
| | const end = message.text.indexOf(ARTIFACT_END, start + ARTIFACT_START.length); |
| | artifacts.push({ |
| | start, |
| | end: end !== -1 ? end + ARTIFACT_END.length : message.text.length, |
| | source: 'text', |
| | text: message.text, |
| | }); |
| |
|
| | currentIndex = end !== -1 ? end + ARTIFACT_END.length : message.text.length; |
| | start = message.text.indexOf(ARTIFACT_START, currentIndex); |
| | } |
| | } |
| |
|
| | return artifacts; |
| | }; |
| |
|
| | const replaceArtifactContent = (originalText, artifact, original, updated) => { |
| | const artifactContent = artifact.text.substring(artifact.start, artifact.end); |
| |
|
| | |
| | const contentStart = artifactContent.indexOf('\n', artifactContent.indexOf(ARTIFACT_START)) + 1; |
| | let contentEnd = artifactContent.lastIndexOf(ARTIFACT_END); |
| |
|
| | |
| | |
| | |
| | if (contentEnd === 0 && artifactContent.indexOf(ARTIFACT_START) === 0) { |
| | contentEnd = artifactContent.length; |
| | } |
| |
|
| | if (contentStart === -1 || contentEnd === -1) { |
| | return null; |
| | } |
| |
|
| | |
| | const codeBlockStart = artifactContent.indexOf('```\n', contentStart); |
| | const codeBlockEnd = artifactContent.lastIndexOf('\n```', contentEnd); |
| |
|
| | |
| | let searchStart, searchEnd; |
| | if (codeBlockStart !== -1) { |
| | |
| | searchStart = codeBlockStart + 4; |
| |
|
| | if (codeBlockEnd !== -1 && codeBlockEnd > codeBlockStart) { |
| | |
| | searchEnd = codeBlockEnd; |
| | } else { |
| | |
| | |
| | searchEnd = contentEnd; |
| | } |
| | } else { |
| | |
| | searchStart = contentStart; |
| | searchEnd = contentEnd; |
| | } |
| |
|
| | const innerContent = artifactContent.substring(searchStart, searchEnd); |
| | |
| | const originalTrimmed = original.replace(/\n$/, ''); |
| | const relativeIndex = innerContent.indexOf(originalTrimmed); |
| |
|
| | if (relativeIndex === -1) { |
| | return null; |
| | } |
| |
|
| | const absoluteIndex = artifact.start + searchStart + relativeIndex; |
| | const endText = originalText.substring(absoluteIndex + originalTrimmed.length); |
| | const hasTrailingNewline = endText.startsWith('\n'); |
| |
|
| | const updatedText = |
| | originalText.substring(0, absoluteIndex) + updated + (hasTrailingNewline ? '' : '\n') + endText; |
| |
|
| | return updatedText.replace(/\n+(?=```\n:::)/g, '\n'); |
| | }; |
| |
|
| | module.exports = { |
| | ARTIFACT_START, |
| | ARTIFACT_END, |
| | findAllArtifacts, |
| | replaceArtifactContent, |
| | }; |
| |
|