@adeu/core 1.18.0 → 1.18.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +23 -7
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +10 -0
- package/dist/index.d.ts +10 -0
- package/dist/index.js +23 -7
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/engine.feedback.test.ts +34 -2
- package/src/engine.ts +30 -7
package/package.json
CHANGED
|
@@ -31,7 +31,11 @@ describe("Feedback Layer & Dry Run Verification", () => {
|
|
|
31
31
|
expect(stats.version).toBeDefined();
|
|
32
32
|
});
|
|
33
33
|
|
|
34
|
-
it("punctuation anchor
|
|
34
|
+
it("punctuation anchor: no warning on clean apply", async () => {
|
|
35
|
+
// A punctuated anchor that matches and applies cleanly must NOT raise the
|
|
36
|
+
// tokenization-splitting warning. The redline preview already reports the
|
|
37
|
+
// change; a warning here is a false positive that pushes agents into
|
|
38
|
+
// needless "cleaner anchor" retries.
|
|
35
39
|
const doc = await createTestDocument();
|
|
36
40
|
addParagraph(doc, "Refer to sample_term_name in Section 4.");
|
|
37
41
|
const engine = new RedlineEngine(doc, "Reviewer TS");
|
|
@@ -41,9 +45,37 @@ describe("Feedback Layer & Dry Run Verification", () => {
|
|
|
41
45
|
]);
|
|
42
46
|
|
|
43
47
|
const report = stats.edits[0];
|
|
48
|
+
expect(report.status).toBe("applied");
|
|
49
|
+
expect(report.warning).toBeNull();
|
|
50
|
+
|
|
51
|
+
// Same expectation under dry_run.
|
|
52
|
+
const doc2 = await createTestDocument();
|
|
53
|
+
addParagraph(doc2, "Refer to sample_term_name in Section 4.");
|
|
54
|
+
const engine2 = new RedlineEngine(doc2, "Reviewer TS");
|
|
55
|
+
const dryStats = (engine2 as any).process_batch([
|
|
56
|
+
{ type: "modify", target_text: "sample_term_name", new_text: "validated_term_name" }
|
|
57
|
+
], true);
|
|
58
|
+
const dryReport = dryStats.edits[0];
|
|
59
|
+
expect(dryReport.status).toBe("applied");
|
|
60
|
+
expect(dryReport.warning).toBeNull();
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
it("punctuation anchor: warns only when match fails", async () => {
|
|
64
|
+
// When a punctuated anchor fails to match, the warning IS surfaced as
|
|
65
|
+
// recovery context (the punctuation may be why the match missed).
|
|
66
|
+
const doc = await createTestDocument();
|
|
67
|
+
addParagraph(doc, "Refer to sample_term_name in Section 4.");
|
|
68
|
+
const engine = new RedlineEngine(doc, "Reviewer TS");
|
|
69
|
+
|
|
70
|
+
const stats = (engine as any).process_batch([
|
|
71
|
+
{ type: "modify", target_text: "phantom_term-x", new_text: "anything" }
|
|
72
|
+
], true);
|
|
73
|
+
|
|
74
|
+
const report = stats.edits[0];
|
|
75
|
+
expect(report.status).toBe("failed");
|
|
44
76
|
expect(report.warning).not.toBeNull();
|
|
45
77
|
expect(report.warning.toLowerCase()).toContain("punctuation");
|
|
46
|
-
expect(report.warning).toContain("
|
|
78
|
+
expect(report.warning).toContain("phantom_term-x");
|
|
47
79
|
});
|
|
48
80
|
|
|
49
81
|
it("dry_run does not mutate and reports safely", async () => {
|
package/src/engine.ts
CHANGED
|
@@ -322,8 +322,19 @@ export class RedlineEngine {
|
|
|
322
322
|
this.comments_manager = new CommentsManager(this.doc);
|
|
323
323
|
}
|
|
324
324
|
|
|
325
|
+
/**
|
|
326
|
+
* Return a hint when a short, single-token anchor contains punctuation that
|
|
327
|
+
* can split awkwardly, else null.
|
|
328
|
+
*
|
|
329
|
+
* Surface this ONLY for edits that actually failed to match/apply. On a
|
|
330
|
+
* successful edit the batch report already carries the redline preview, so
|
|
331
|
+
* emitting this would be a false positive: the punctuation (dates,
|
|
332
|
+
* `[_name_]` placeholders, `____` blanks) is frequently the literal target
|
|
333
|
+
* and the edit succeeds despite it. Mirrors the Python engine.
|
|
334
|
+
*/
|
|
325
335
|
private _check_punctuation_warning(target_text: string): string | null {
|
|
326
336
|
if (!target_text) return null;
|
|
337
|
+
if (target_text.length > 20 || target_text.includes(" ")) return null;
|
|
327
338
|
if (target_text.includes("_") || target_text.includes("-")) {
|
|
328
339
|
return `Warning: target_text '${target_text}' contains tokenization-splitting punctuation ('_' or '-'). This can trigger mid-word splits in the diff engine. Consider using a longer plain-prose anchor.`;
|
|
329
340
|
}
|
|
@@ -1894,11 +1905,16 @@ export class RedlineEngine {
|
|
|
1894
1905
|
for (let i = 0; i < edits.length; i++) {
|
|
1895
1906
|
const edit = edits[i];
|
|
1896
1907
|
const single_errors = this.validate_edits([edit], i);
|
|
1897
|
-
const warning = this._check_punctuation_warning(
|
|
1898
|
-
(edit as any).target_text || "",
|
|
1899
|
-
);
|
|
1900
1908
|
if (single_errors.length > 0) {
|
|
1901
1909
|
skipped_edits++;
|
|
1910
|
+
// Only surface the punctuation-anchor warning when the edit actually
|
|
1911
|
+
// failed. A clean apply already returns the redline preview, so the
|
|
1912
|
+
// warning is pure noise on success — and it misleads agents into
|
|
1913
|
+
// hunting for a "cleaner" anchor that was never needed (e.g. on
|
|
1914
|
+
// placeholders/dates where the punctuation IS the literal target).
|
|
1915
|
+
const warning = this._check_punctuation_warning(
|
|
1916
|
+
(edit as any).target_text || "",
|
|
1917
|
+
);
|
|
1902
1918
|
edits_reports.push({
|
|
1903
1919
|
status: "failed",
|
|
1904
1920
|
target_text: (edit as any).target_text || "",
|
|
@@ -1918,7 +1934,7 @@ export class RedlineEngine {
|
|
|
1918
1934
|
status: "applied",
|
|
1919
1935
|
target_text: (edit as any).target_text || "",
|
|
1920
1936
|
new_text: (edit as any).new_text || "",
|
|
1921
|
-
warning:
|
|
1937
|
+
warning: null,
|
|
1922
1938
|
error: null,
|
|
1923
1939
|
critic_markup: previews[0],
|
|
1924
1940
|
clean_text: previews[1],
|
|
@@ -1935,6 +1951,9 @@ export class RedlineEngine {
|
|
|
1935
1951
|
this.skipped_details.length > 0
|
|
1936
1952
|
? this.skipped_details[this.skipped_details.length - 1]
|
|
1937
1953
|
: "Failed to apply edit";
|
|
1954
|
+
const warning = this._check_punctuation_warning(
|
|
1955
|
+
(edit as any).target_text || "",
|
|
1956
|
+
);
|
|
1938
1957
|
edits_reports.push({
|
|
1939
1958
|
status: "failed",
|
|
1940
1959
|
target_text: (edit as any).target_text || "",
|
|
@@ -1983,15 +2002,19 @@ export class RedlineEngine {
|
|
|
1983
2002
|
for (const edit of edits) {
|
|
1984
2003
|
const success = (edit as any)._applied_status || false;
|
|
1985
2004
|
const error_msg = (edit as any)._error_msg || null;
|
|
1986
|
-
const warning = this._check_punctuation_warning(
|
|
1987
|
-
(edit as any).target_text || "",
|
|
1988
|
-
);
|
|
1989
2005
|
let critic_markup = null;
|
|
1990
2006
|
let clean_text = null;
|
|
2007
|
+
// Punctuation-anchor warning is failure-context only: on success the
|
|
2008
|
+
// redline preview below already reports the change cleanly.
|
|
2009
|
+
let warning: string | null = null;
|
|
1991
2010
|
if (success) {
|
|
1992
2011
|
const previews = this._build_edit_context_previews(edit);
|
|
1993
2012
|
critic_markup = previews[0];
|
|
1994
2013
|
clean_text = previews[1];
|
|
2014
|
+
} else {
|
|
2015
|
+
warning = this._check_punctuation_warning(
|
|
2016
|
+
(edit as any).target_text || "",
|
|
2017
|
+
);
|
|
1995
2018
|
}
|
|
1996
2019
|
edits_reports.push({
|
|
1997
2020
|
status: success ? "applied" : "failed",
|