-
Notifications
You must be signed in to change notification settings - Fork 7
Fix editorial workflow adding code fences to files #676
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -46,6 +46,8 @@ const MAX_AI_TOKENS = 8192; | |
| const OWNER = "ArcadeAI"; | ||
| const REPO = "docs"; | ||
| const EDITORIAL_COMMENT_REGEX = /<!-- Editorial: (.+?) -->/; | ||
| const CODE_FENCE_OPEN_REGEX = /^```(?:mdx?|markdown)?\n/; | ||
| const CODE_FENCE_CLOSE_REGEX = /\n```$/; | ||
| const HTTP_UNPROCESSABLE_ENTITY = 422; | ||
| const MEGABYTE = KILOBYTE * KILOBYTE; | ||
| const MAX_BUFFER_MB = 10; | ||
|
|
@@ -84,6 +86,15 @@ type ValeIssue = { | |
|
|
||
| type ValeOutput = Record<string, ValeIssue[]>; | ||
|
|
||
| // Strip markdown code fences from the beginning and end of LLM responses | ||
| // LLMs often wrap their output in ```mdx or ```markdown blocks | ||
| function stripCodeFences(content: string): string { | ||
| let result = content.trim(); | ||
| result = result.replace(CODE_FENCE_OPEN_REGEX, ""); | ||
| result = result.replace(CODE_FENCE_CLOSE_REGEX, ""); | ||
| return result; | ||
| } | ||
|
|
||
| // Run Vale on content and return issues | ||
| function runValeOnContent(filename: string, content: string): ValeIssue[] { | ||
| // Create temp directory and file with correct extension | ||
|
|
@@ -155,15 +166,18 @@ async function fixValeIssues( | |
| messages: [{ role: "user", content: prompt }], | ||
| }); | ||
| const textBlock = response.content.find((b) => b.type === "text"); | ||
| return textBlock?.type === "text" ? textBlock.text : content; | ||
| return textBlock?.type === "text" | ||
| ? stripCodeFences(textBlock.text) | ||
| : content; | ||
| } | ||
|
|
||
| const response = await ai.client.chat.completions.create({ | ||
| model: "gpt-4-turbo", | ||
| max_tokens: MAX_AI_TOKENS, | ||
| messages: [{ role: "user", content: prompt }], | ||
| }); | ||
| return response.choices[0]?.message?.content ?? content; | ||
| const result = response.choices[0]?.message?.content; | ||
| return result ? stripCodeFences(result) : content; | ||
| } catch (error) { | ||
| console.error("Error fixing Vale issues:", error); | ||
| return content; | ||
|
|
@@ -266,7 +280,7 @@ async function getEditorialFromAnthropic( | |
| return null; | ||
| } | ||
|
|
||
| const revisedContent = textBlock.text.trim(); | ||
| const revisedContent = stripCodeFences(textBlock.text); | ||
|
|
||
| if (revisedContent === "NO_CHANGES_NEEDED") { | ||
| return null; | ||
|
|
@@ -298,8 +312,12 @@ async function getEditorialFromOpenAI( | |
| messages: [{ role: "user", content: prompt }], | ||
| }); | ||
|
|
||
| const revisedContent = response.choices[0]?.message?.content?.trim(); | ||
| if (!revisedContent || revisedContent === "NO_CHANGES_NEEDED") { | ||
| const rawContent = response.choices[0]?.message?.content; | ||
| if (!rawContent) { | ||
| return null; | ||
| } | ||
| const revisedContent = stripCodeFences(rawContent); | ||
| if (revisedContent === "NO_CHANGES_NEEDED") { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing empty content check after stripping code fencesMedium Severity The |
||
| return null; | ||
| } | ||
|
|
||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing final trim allows whitespace to break comparison
Low Severity
The
stripCodeFencesfunction trims whitespace before stripping code fences but not after. If an LLM wraps its response in code fences and includes leading/trailing whitespace inside (e.g.,"```mdx\n NO_CHANGES_NEEDED \n```"), the result will be" NO_CHANGES_NEEDED "with preserved internal whitespace. This causes the"NO_CHANGES_NEEDED"equality check to fail, potentially creating an editorial PR that overwrites documentation with the literal text" NO_CHANGES_NEEDED ".