From f1fb8e991cfb982002bd4c4696242eeb5375b39e Mon Sep 17 00:00:00 2001 From: Danny Avila Date: Fri, 23 Aug 2024 21:40:56 -0400 Subject: [PATCH] wip: remove thinking text and artifact formatting if empty --- client/src/utils/artifacts.spec.ts | 94 ++++++++++++++++++++++++++++++ client/src/utils/artifacts.ts | 20 +++++++ 2 files changed, 114 insertions(+) create mode 100644 client/src/utils/artifacts.spec.ts diff --git a/client/src/utils/artifacts.spec.ts b/client/src/utils/artifacts.spec.ts new file mode 100644 index 0000000000..b71dcd852f --- /dev/null +++ b/client/src/utils/artifacts.spec.ts @@ -0,0 +1,94 @@ +import { preprocessCodeArtifacts } from './artifacts'; + +describe('preprocessCodeArtifacts', () => { + test('should return non-string inputs unchanged', () => { + expect(preprocessCodeArtifacts(123 as unknown as string)).toBe(''); + expect(preprocessCodeArtifacts(null as unknown as string)).toBe(''); + expect(preprocessCodeArtifacts(undefined)).toBe(''); + expect(preprocessCodeArtifacts({} as unknown as string)).toEqual(''); + }); + + test('should remove tags and their content', () => { + const input = 'This should be removedSome content'; + const expected = 'Some content'; + expect(preprocessCodeArtifacts(input)).toBe(expected); + }); + + test('should remove unclosed tags and their content', () => { + const input = 'This should be removed\nSome content'; + const expected = ''; + expect(preprocessCodeArtifacts(input)).toBe(expected); + }); + + test('should remove artifact headers up to and including empty code block', () => { + const input = ':::artifact{identifier="test"}\n```\n```\nSome content'; + const expected = ':::artifact{identifier="test"}\n```\n```\nSome content'; + expect(preprocessCodeArtifacts(input)).toBe(expected); + }); + + test('should keep artifact headers when followed by empty code block and content', () => { + const input = ':::artifact{identifier="test"}\n```\n```\nSome content'; + const expected = ':::artifact{identifier="test"}\n```\n```\nSome content'; + expect(preprocessCodeArtifacts(input)).toBe(expected); + }); + + test('should handle multiple artifact headers correctly', () => { + const input = ':::artifact{id="1"}\n```\n```\n:::artifact{id="2"}\n```\ncode\n```\nContent'; + const expected = ':::artifact{id="1"}\n```\n```\n:::artifact{id="2"}\n```\ncode\n```\nContent'; + expect(preprocessCodeArtifacts(input)).toBe(expected); + }); + + test('should handle complex input with multiple patterns', () => { + const input = ` + Remove this + Some text + :::artifact{id="1"} + \`\`\` + \`\`\` + And this + :::artifact{id="2"} + \`\`\` + keep this code + \`\`\` + More text + `; + const expected = ` + + Some text + :::artifact{id="1"} + \`\`\` + \`\`\` + + :::artifact{id="2"} + \`\`\` + keep this code + \`\`\` + More text + `; + expect(preprocessCodeArtifacts(input)).toBe(expected); + }); + + test('should remove artifact headers without code blocks', () => { + const input = ':::artifact{identifier="test"}\nSome content without code block'; + const expected = ''; + expect(preprocessCodeArtifacts(input)).toBe(expected); + }); + + test('should remove artifact headers up to incomplete code block', () => { + const input = ':::artifact{identifier="react-cal'; + const expected = ''; + expect(preprocessCodeArtifacts(input)).toBe(expected); + }); + + test('should keep artifact headers when any character follows code block', () => { + const input = ':::artifact{identifier="react-calculator"}\n```t'; + const expected = ':::artifact{identifier="react-calculator"}\n```t'; + expect(preprocessCodeArtifacts(input)).toBe(expected); + }); + + test('should keep artifact headers when whitespace follows code block', () => { + const input = ':::artifact{identifier="react-calculator"}\n``` '; + const expected = ':::artifact{identifier="react-calculator"}\n``` '; + expect(preprocessCodeArtifacts(input)).toBe(expected); + }); +}); diff --git a/client/src/utils/artifacts.ts b/client/src/utils/artifacts.ts index d48362eed4..197919ff60 100644 --- a/client/src/utils/artifacts.ts +++ b/client/src/utils/artifacts.ts @@ -136,3 +136,23 @@ export const sharedFiles = { `, }; + +export function preprocessCodeArtifacts(text?: string): string { + if (typeof text !== 'string') { + return ''; + } + + // Remove tags and their content + text = text.replace(/[\s\S]*?<\/thinking>|[\s\S]*/g, ''); + + // Process artifact headers + const regex = /(^|\n)(:::artifact[\s\S]*?(?:```[\s\S]*?```|$))/g; + return text.replace(regex, (match, newline, artifactBlock) => { + if (artifactBlock.includes('```') === true) { + // Keep artifact headers with code blocks (empty or not) + return newline + artifactBlock; + } + // Remove artifact headers without code blocks, but keep the newline + return newline; + }); +}