fix(coding-agent): restricted key extraction to top-level json depth
- Introduced JSON depth tracking to ensure string keys are only extracted at the top level. - Prevented nested keys matching designated streaming keys from being prematurely or incorrectly captured. - Added comprehensive unit tests validating nested key exclusion and correct top-level extraction order.
This commit is contained in:
@@ -64,6 +64,10 @@ class StreamingJsonStringExtractor {
|
||||
readonly #keys: Set<string>;
|
||||
#source = "";
|
||||
#offset = 0;
|
||||
/** `{`/`[` nesting outside strings. Candidate keys match only at depth 1 —
|
||||
* the top level of the args object — so a nested object's key (e.g.
|
||||
* `{"meta":{"content":…}}`) is never captured as a streamed top-level arg. */
|
||||
#depth = 0;
|
||||
#state: StreamingJsonStringExtractorState = "scan";
|
||||
#candidate = "";
|
||||
#candidateEscaped = false;
|
||||
@@ -82,6 +86,7 @@ class StreamingJsonStringExtractor {
|
||||
reset(): void {
|
||||
this.#source = "";
|
||||
this.#offset = 0;
|
||||
this.#depth = 0;
|
||||
this.#state = "scan";
|
||||
this.#candidate = "";
|
||||
this.#candidateEscaped = false;
|
||||
@@ -129,6 +134,10 @@ class StreamingJsonStringExtractor {
|
||||
this.#candidateEscaped = false;
|
||||
this.#candidateUnicode = "";
|
||||
this.#state = "candidate";
|
||||
} else if (ch === "{" || ch === "[") {
|
||||
this.#depth++;
|
||||
} else if (ch === "}" || ch === "]") {
|
||||
this.#depth--;
|
||||
}
|
||||
this.#offset++;
|
||||
}
|
||||
@@ -154,7 +163,7 @@ class StreamingJsonStringExtractor {
|
||||
return;
|
||||
}
|
||||
if (ch === '"') {
|
||||
this.#matchedKey = this.#keys.has(this.#candidate) ? this.#candidate : undefined;
|
||||
this.#matchedKey = this.#depth === 1 && this.#keys.has(this.#candidate) ? this.#candidate : undefined;
|
||||
this.#state = "afterCandidate";
|
||||
this.#offset++;
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user