fix(ENG-12518): fix field filter and batch sentence classification#35
fix(ENG-12518): fix field filter and batch sentence classification#35
Conversation
There was a problem hiding this comment.
Pull request overview
Updates the ONNX classifier’s session/promise caching so it is shared across CommonJS and ESM evaluations within the same Node.js process, preventing duplicate model loads when the package is consumed in dual-module-format setups.
Changes:
- Moved ONNX session cache and in-flight load promise tracking from module-level
Maps toglobalThis-backed singletons. - Added a dedicated
SessionCacheEntrytype and expanded inline documentation describing the CJS/ESM sharing rationale.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
There was a problem hiding this comment.
1 issue found across 2 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/config.ts">
<violation number="1" location="src/config.ts:176">
P3: The comment claims the Tier 2 field list adds "data" and "value", but the array only includes "snippet". Either add the missing fields or update the comment to avoid misleading configuration guidance.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
f274fe8 to
a36f52a
Compare
The traverse function in extractStrings() had a fallthrough case that collected every leaf string reached during recursion, even under non-matching field keys. This made the tier2Fields filter (and the riskyFieldNames fallback from Tier 1) completely ineffective — Tier 2 always scanned every string in the payload. For Gmail emails this meant classifying ~58 sentences (MIME headers, DKIM signatures, base64 blobs) instead of ~4 (just the snippet field identified by Tier 1). At ~35ms per ONNX inference on server CPU, this caused ~2s latency per request instead of ~140ms. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
classifyBySentence() was calling classify() per sentence in a loop, submitting N separate session.run() calls to the libuv thread pool. Under concurrency, these compete for threads and stack up. Switch to classifyBatch() which pads all sentences into a single batched tensor and runs one session.run() call. This reduces ONNX calls from N-per-request to 1-per-request, eliminating stacking under concurrent load. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
a36f52a to
53622f7
Compare
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 2 out of 2 changed files in this pull request and generated 5 comments.
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…entence - extractStrings: verify strings under non-matching keys are skipped, bare string input is collected, and riskyFieldNames fallback works - classifyBySentence: verify maxSentence selection, sentenceScores alignment, skip reasons, and score parity with individual classify Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
0 issues found across 2 files (changes from recent commits).
Requires human review: Modifies core filtering and classification logic in a security-sensitive component (Prompt Defense). Such changes to input traversal and execution batching require human verification.
…cores - extractStrings: handle bare array input consistently with bare string when tier2Fields is set (both collect directly via collectAll) - classifyBySentence: guard against NaN/Infinity scores from batch classification with Number.isFinite check Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
1 issue found across 3 files (changes from recent commits).
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="src/core/prompt-defense.ts">
<violation number="1" location="src/core/prompt-defense.ts:71">
P2: Arrays at the root now bypass field filtering and collect every string. If tool results are arrays of objects, tier2Fields is ignored and non-matching fields get classified again. Keep arrays in the filtered traversal path.</violation>
</file>
Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.
Arrays of objects at the root need field filtering — collectAll would bypass tier2Fields and classify every string. Only bare strings need the early return; arrays are already handled by traverse(). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
0 issues found across 2 files (changes from recent commits).
Requires human review: This PR modifies core security/filtering logic in the prompt defense system and introduces batch processing for ONNX classification, which requires human validation to ensure no bypasses.
Context
Two issues causing high Tier 2 latency:
extractStrings()field filter was broken — thetraversefunction had a fallthrough case that collected every leaf string under non-matching keys, makingtier2Fieldsand theriskyFieldNamesfallback from Tier 1 completely ineffective. For Gmail emails, this meant classifying ~58 sentences (MIME headers, DKIM signatures, base64 blobs) instead of ~4 (just thesnippetfield identified by Tier 1). At ~35ms per ONNX inference on server CPU, this caused ~2s latency per request instead of ~140ms.classifyBySentence()calledclassify()per sentence in a loop — submitting N separatesession.run()calls to the libuv thread pool. Under concurrency, these compete for threads and stack up. Switched toclassifyBatch()which pads all sentences into a single batched tensor and runs onesession.run()call.Changes
src/core/prompt-defense.ts: FixextractStrings()to skip strings under non-matching keys when field filtering is active. Handle bare string input as edge case.src/classifiers/tier2-classifier.ts: RefactorclassifyBySentence()to collect all sentences first, then callclassifyBatch()once instead ofclassify()N times.Checklist
Post-merge
@stackone/defenderinunified-cloud-apiandconnect-handler🤖 Generated with Claude Code