-
Notifications
You must be signed in to change notification settings - Fork 0
chore: sync core lib and CLAUDE.md from agent-core #21
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 |
|---|---|---|
|
|
@@ -114,8 +114,11 @@ const CRITICAL_PATTERNS = [ | |
| const SUBAGENT_PATTERN = /subagent_type\s*[=:]\s*["']([^"']+)["']/g; | ||
|
|
||
| /** Pre-compiled patterns for cleaning content */ | ||
| const BAD_EXAMPLE_TAG_PATTERN = /<bad[_\- ]?example>[\s\S]*?<\/bad[_\- ]?example>/gi; | ||
| const BAD_EXAMPLE_CODE_PATTERN = /```[^\n]*bad[^\n]*\n[\s\S]*?```/gi; | ||
| // ReDoS fix: bound the lazy [\s\S]*? bodies so an unterminated <bad-example> or | ||
| // ``` fence cannot drive polynomial backtracking; 50k chars covers any realistic | ||
| // example block, so the stripped regions are unchanged for real content. | ||
| const BAD_EXAMPLE_TAG_PATTERN = /<bad[_\- ]?example>[\s\S]{0,50000}?<\/bad[_\- ]?example>/gi; | ||
| const BAD_EXAMPLE_CODE_PATTERN = /```[^\n]{0,500}bad[^\n]{0,500}\n[\s\S]{0,50000}?```/gi; | ||
|
|
||
| // ============================================ | ||
| // TOOL PATTERN CACHE | ||
|
|
@@ -649,10 +652,14 @@ function analyzePromptConsistency(agents) { | |
|
|
||
| // Extract action keywords | ||
| let action; | ||
| // ReDoS fix: bound the greedy prefix to non-newline chars. `line` is a single | ||
| // trimmed line (no newlines), so [^\n]{0,N} is equivalent to the prior `.*`: | ||
| // greedy match strips everything up to and including the LAST keyword plus its | ||
| // trailing whitespace, preserving the word-boundary semantics exactly. | ||
| if (isAlways) { | ||
| action = line.replace(/.*\bALWAYS\b\s*/i, '').substring(0, ACTION_COMPARISON_LENGTH); | ||
| action = line.replace(/[^\n]{0,2000}\bALWAYS\b\s{0,200}/i, '').substring(0, ACTION_COMPARISON_LENGTH); | ||
| } else { | ||
| action = line.replace(/.*\b(?:NEVER|DO NOT)\b\s*/i, '').substring(0, ACTION_COMPARISON_LENGTH); | ||
| action = line.replace(/[^\n]{0,2000}\b(?:NEVER|DO NOT)\b\s{0,200}/i, '').substring(0, ACTION_COMPARISON_LENGTH); | ||
|
Comment on lines
+660
to
+662
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. Using Instead of using a regex with arbitrary bounds to simulate a greedy match up to the last keyword, we can split the string by the keyword regex and take the last element. This is completely safe from ReDoS, has no arbitrary length limits, and is much cleaner. const parts = line.split(/\bALWAYS\b\s*/i);
action = parts[parts.length - 1].substring(0, ACTION_COMPARISON_LENGTH);
} else {
const parts = line.split(/\b(?:NEVER|DO NOT)\b\s*/i);
action = parts[parts.length - 1].substring(0, ACTION_COMPARISON_LENGTH); |
||
| } | ||
|
|
||
| // Extract significant keywords from action | ||
|
|
||
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.
Using a regex with an arbitrary limit like
[\s\S]{0,50000}can fail to detect orchestrators in large files if thesubagent_typekeyword is located more than 50,000 characters after theTaskcall.Instead of a single complex regex with arbitrary bounds, we can split this into two simple checks: checking if the content contains
subagent_typeand testing for theTaskcall pattern. This is completely safe from ReDoS, has no arbitrary limits, and is much more performant.