@r3b1s/pi-repair-layer 0.2.1 → 0.4.0
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/README.md +173 -293
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/{index.ts → dist/index.js} +2 -1
- package/dist/index.js.map +1 -0
- package/dist/src/core.d.ts +8 -0
- package/dist/src/core.d.ts.map +1 -0
- package/dist/src/core.js +7 -0
- package/dist/src/core.js.map +1 -0
- package/dist/src/envelope.d.ts +21 -0
- package/dist/src/envelope.d.ts.map +1 -0
- package/dist/src/envelope.js +158 -0
- package/dist/src/envelope.js.map +1 -0
- package/dist/src/grammar-recovery.d.ts +105 -0
- package/dist/src/grammar-recovery.d.ts.map +1 -0
- package/dist/src/grammar-recovery.js +1052 -0
- package/dist/src/grammar-recovery.js.map +1 -0
- package/dist/src/grammar.d.ts +2 -0
- package/dist/src/grammar.d.ts.map +1 -0
- package/dist/src/grammar.js +2 -0
- package/dist/src/grammar.js.map +1 -0
- package/dist/src/index.d.ts +36 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +558 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/lifecycle.d.ts +34 -0
- package/dist/src/lifecycle.d.ts.map +1 -0
- package/dist/src/lifecycle.js +133 -0
- package/dist/src/lifecycle.js.map +1 -0
- package/dist/src/pi.d.ts +19 -0
- package/dist/src/pi.d.ts.map +1 -0
- package/dist/src/pi.js +38 -0
- package/dist/src/pi.js.map +1 -0
- package/dist/src/pipeline.d.ts +10 -0
- package/dist/src/pipeline.d.ts.map +1 -0
- package/dist/src/pipeline.js +166 -0
- package/dist/src/pipeline.js.map +1 -0
- package/dist/src/policy.d.ts +16 -0
- package/dist/src/policy.d.ts.map +1 -0
- package/dist/src/policy.js +31 -0
- package/dist/src/policy.js.map +1 -0
- package/dist/src/preprocess.d.ts +37 -0
- package/dist/src/preprocess.d.ts.map +1 -0
- package/dist/src/preprocess.js +216 -0
- package/dist/src/preprocess.js.map +1 -0
- package/dist/src/repair-engine.d.ts +91 -0
- package/dist/src/repair-engine.d.ts.map +1 -0
- package/dist/src/repair-engine.js +457 -0
- package/dist/src/repair-engine.js.map +1 -0
- package/dist/src/settings.d.ts +38 -0
- package/dist/src/settings.d.ts.map +1 -0
- package/dist/src/settings.js +87 -0
- package/dist/src/settings.js.map +1 -0
- package/dist/src/tables.d.ts +16 -0
- package/dist/src/tables.d.ts.map +1 -0
- package/dist/src/tables.js +302 -0
- package/dist/src/tables.js.map +1 -0
- package/dist/src/types.d.ts +52 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +2 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/value-strips.d.ts +52 -0
- package/dist/src/value-strips.d.ts.map +1 -0
- package/dist/src/value-strips.js +191 -0
- package/dist/src/value-strips.js.map +1 -0
- package/docs/how-it-works.md +227 -0
- package/docs/operations.md +141 -0
- package/docs/research.md +390 -0
- package/docs/tool-owner-integration.md +557 -0
- package/package.json +31 -6
- package/src/grammar-recovery.ts +0 -1269
- package/src/index.ts +0 -621
- package/src/repair-engine.ts +0 -518
- package/src/settings.ts +0 -95
- package/src/tables.ts +0 -184
- package/src/value-strips.ts +0 -218
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Repair configuration for pi's seven built-in tools.
|
|
3
|
+
*
|
|
4
|
+
* The alias lists encode the field names open models actually emit — mostly
|
|
5
|
+
* leakage from the tool contracts they were RL-trained on (Claude Code's
|
|
6
|
+
* `file_path`/`old_string`/`new_string`, aider's `search`/`replace`, generic
|
|
7
|
+
* `cmd`/`query`). Aliases only ever apply when the canonical field is missing
|
|
8
|
+
* or undefined at a path the validator flagged, so valid calls never pay for
|
|
9
|
+
* this table.
|
|
10
|
+
*/
|
|
11
|
+
const PATH_ALIASES = [
|
|
12
|
+
"file_path",
|
|
13
|
+
"filePath",
|
|
14
|
+
"filepath",
|
|
15
|
+
"absolute_path",
|
|
16
|
+
"absolutePath",
|
|
17
|
+
"pathname",
|
|
18
|
+
"file",
|
|
19
|
+
"filename",
|
|
20
|
+
"fileName",
|
|
21
|
+
"target_file",
|
|
22
|
+
"targetFile",
|
|
23
|
+
];
|
|
24
|
+
const OLD_TEXT_ALIASES = [
|
|
25
|
+
"old_string",
|
|
26
|
+
"oldString",
|
|
27
|
+
"old_str",
|
|
28
|
+
"oldStr",
|
|
29
|
+
"old_text",
|
|
30
|
+
"oldValue",
|
|
31
|
+
"old_value",
|
|
32
|
+
"oldContent",
|
|
33
|
+
"old_content",
|
|
34
|
+
"old",
|
|
35
|
+
"from",
|
|
36
|
+
"search",
|
|
37
|
+
];
|
|
38
|
+
const NEW_TEXT_ALIASES = [
|
|
39
|
+
"new_string",
|
|
40
|
+
"newString",
|
|
41
|
+
"new_str",
|
|
42
|
+
"newStr",
|
|
43
|
+
"new_text",
|
|
44
|
+
"newValue",
|
|
45
|
+
"new_value",
|
|
46
|
+
"newContent",
|
|
47
|
+
"new_content",
|
|
48
|
+
"new",
|
|
49
|
+
"to",
|
|
50
|
+
"replace",
|
|
51
|
+
];
|
|
52
|
+
/**
|
|
53
|
+
* pi's `edit` takes `edits: [{ oldText, newText }]`, but models trained on
|
|
54
|
+
* single-edit contracts send the pair flat at the top level (usually as
|
|
55
|
+
* `old_string`/`new_string`). Field renames alone can't fix that — the pair
|
|
56
|
+
* has to move into an array element — so this runs as a structural repair.
|
|
57
|
+
* pi's own built-in shim already folds a flat `oldText`/`newText` pair; this
|
|
58
|
+
* extends the same fold to the aliased spellings.
|
|
59
|
+
*/
|
|
60
|
+
const foldFlatEditFields = {
|
|
61
|
+
name: "foldFlatEditFields",
|
|
62
|
+
apply(args, toolName) {
|
|
63
|
+
if (Array.isArray(args.edits) && args.edits.length > 0)
|
|
64
|
+
return false;
|
|
65
|
+
const oldKey = ["oldText", ...OLD_TEXT_ALIASES].find((key) => typeof args[key] === "string");
|
|
66
|
+
const newKey = ["newText", ...NEW_TEXT_ALIASES].find((key) => typeof args[key] === "string");
|
|
67
|
+
if (oldKey === undefined || newKey === undefined)
|
|
68
|
+
return false;
|
|
69
|
+
const edit = { oldText: args[oldKey], newText: args[newKey] };
|
|
70
|
+
for (const key of [
|
|
71
|
+
"oldText",
|
|
72
|
+
"newText",
|
|
73
|
+
...OLD_TEXT_ALIASES,
|
|
74
|
+
...NEW_TEXT_ALIASES,
|
|
75
|
+
]) {
|
|
76
|
+
delete args[key];
|
|
77
|
+
}
|
|
78
|
+
args.edits = [edit];
|
|
79
|
+
return `Folded flat \`${oldKey}\`/\`${newKey}\` fields into \`edits: [{oldText, newText}]\` for tool "${toolName}". This tool takes an array of edit objects — send \`edits\` next time.`;
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
export const REPAIR_CONFIGS = {
|
|
83
|
+
read: {
|
|
84
|
+
fieldAliases: { path: PATH_ALIASES },
|
|
85
|
+
rootString: { field: "path" },
|
|
86
|
+
pathFields: ["path"],
|
|
87
|
+
},
|
|
88
|
+
bash: {
|
|
89
|
+
fieldAliases: {
|
|
90
|
+
command: [
|
|
91
|
+
"cmd",
|
|
92
|
+
"script",
|
|
93
|
+
"shell",
|
|
94
|
+
"bash_command",
|
|
95
|
+
"bashCommand",
|
|
96
|
+
"command_line",
|
|
97
|
+
"commandLine",
|
|
98
|
+
],
|
|
99
|
+
},
|
|
100
|
+
rootString: { field: "command" },
|
|
101
|
+
},
|
|
102
|
+
edit: {
|
|
103
|
+
fieldAliases: {
|
|
104
|
+
path: PATH_ALIASES,
|
|
105
|
+
edits: ["changes", "replacements", "modifications", "operations"],
|
|
106
|
+
oldText: OLD_TEXT_ALIASES,
|
|
107
|
+
newText: NEW_TEXT_ALIASES,
|
|
108
|
+
},
|
|
109
|
+
pathFields: ["path"],
|
|
110
|
+
structural: [foldFlatEditFields],
|
|
111
|
+
},
|
|
112
|
+
write: {
|
|
113
|
+
fieldAliases: {
|
|
114
|
+
path: PATH_ALIASES,
|
|
115
|
+
content: [
|
|
116
|
+
"text",
|
|
117
|
+
"body",
|
|
118
|
+
"data",
|
|
119
|
+
"contents",
|
|
120
|
+
"file_content",
|
|
121
|
+
"fileContent",
|
|
122
|
+
"file_text",
|
|
123
|
+
"fileText",
|
|
124
|
+
"new_content",
|
|
125
|
+
"newContent",
|
|
126
|
+
],
|
|
127
|
+
},
|
|
128
|
+
pathFields: ["path"],
|
|
129
|
+
},
|
|
130
|
+
grep: {
|
|
131
|
+
fieldAliases: {
|
|
132
|
+
pattern: [
|
|
133
|
+
"query",
|
|
134
|
+
"regex",
|
|
135
|
+
"search",
|
|
136
|
+
"q",
|
|
137
|
+
"expression",
|
|
138
|
+
"search_pattern",
|
|
139
|
+
"searchPattern",
|
|
140
|
+
],
|
|
141
|
+
},
|
|
142
|
+
rootString: { field: "pattern" },
|
|
143
|
+
pathFields: ["path"],
|
|
144
|
+
},
|
|
145
|
+
find: {
|
|
146
|
+
fieldAliases: {
|
|
147
|
+
pattern: [
|
|
148
|
+
"glob",
|
|
149
|
+
"query",
|
|
150
|
+
"name_pattern",
|
|
151
|
+
"namePattern",
|
|
152
|
+
"file_pattern",
|
|
153
|
+
"filePattern",
|
|
154
|
+
"search",
|
|
155
|
+
"name",
|
|
156
|
+
],
|
|
157
|
+
},
|
|
158
|
+
rootString: { field: "pattern" },
|
|
159
|
+
pathFields: ["path"],
|
|
160
|
+
},
|
|
161
|
+
ls: {
|
|
162
|
+
fieldAliases: {
|
|
163
|
+
path: [
|
|
164
|
+
"directory",
|
|
165
|
+
"dir",
|
|
166
|
+
"folder",
|
|
167
|
+
"directory_path",
|
|
168
|
+
"directoryPath",
|
|
169
|
+
...PATH_ALIASES,
|
|
170
|
+
],
|
|
171
|
+
},
|
|
172
|
+
rootString: { field: "path" },
|
|
173
|
+
pathFields: ["path"],
|
|
174
|
+
},
|
|
175
|
+
};
|
|
176
|
+
const aliases = (selector, values, emptyEquivalentToMissing = false, accepts = "string") => ({
|
|
177
|
+
kind: "alias",
|
|
178
|
+
selector,
|
|
179
|
+
aliases: values,
|
|
180
|
+
accepts,
|
|
181
|
+
emptyEquivalentToMissing,
|
|
182
|
+
});
|
|
183
|
+
const path = (selector) => ({
|
|
184
|
+
kind: "filesystem-path",
|
|
185
|
+
selector,
|
|
186
|
+
});
|
|
187
|
+
const anchor = (selector) => ({
|
|
188
|
+
kind: "anchor-bleed",
|
|
189
|
+
selector,
|
|
190
|
+
modelFamilies: [/kimi-k2/i, /minimax/i, /glm/i],
|
|
191
|
+
});
|
|
192
|
+
const grammar = (selector) => ({
|
|
193
|
+
kind: "grammar-tokens",
|
|
194
|
+
selector,
|
|
195
|
+
modelFamilies: [/glm/i],
|
|
196
|
+
});
|
|
197
|
+
const foldFlatEditPreprocessor = {
|
|
198
|
+
kind: "structural",
|
|
199
|
+
selector: "",
|
|
200
|
+
ruleId: foldFlatEditFields.name,
|
|
201
|
+
apply(value) {
|
|
202
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
203
|
+
return undefined;
|
|
204
|
+
}
|
|
205
|
+
const note = foldFlatEditFields.apply(value, "edit");
|
|
206
|
+
return note === false ? undefined : { value, note };
|
|
207
|
+
},
|
|
208
|
+
};
|
|
209
|
+
/** Selector-based configuration used by the public pipeline and extension. */
|
|
210
|
+
export const PIPELINE_PREPROCESSORS = {
|
|
211
|
+
read: [
|
|
212
|
+
aliases("/path", PATH_ALIASES, true),
|
|
213
|
+
path("/path"),
|
|
214
|
+
anchor("/path"),
|
|
215
|
+
grammar(""),
|
|
216
|
+
],
|
|
217
|
+
bash: [
|
|
218
|
+
aliases("/command", [
|
|
219
|
+
"cmd",
|
|
220
|
+
"script",
|
|
221
|
+
"shell",
|
|
222
|
+
"bash_command",
|
|
223
|
+
"bashCommand",
|
|
224
|
+
"command_line",
|
|
225
|
+
"commandLine",
|
|
226
|
+
]),
|
|
227
|
+
grammar(""),
|
|
228
|
+
],
|
|
229
|
+
edit: [
|
|
230
|
+
aliases("/path", PATH_ALIASES, true),
|
|
231
|
+
aliases("/edits", ["changes", "replacements", "modifications", "operations"], false, "array"),
|
|
232
|
+
aliases("/edits/*/oldText", OLD_TEXT_ALIASES),
|
|
233
|
+
aliases("/edits/*/newText", NEW_TEXT_ALIASES),
|
|
234
|
+
path("/path"),
|
|
235
|
+
anchor("/path"),
|
|
236
|
+
grammar(""),
|
|
237
|
+
grammar("/edits/*"),
|
|
238
|
+
foldFlatEditPreprocessor,
|
|
239
|
+
],
|
|
240
|
+
write: [
|
|
241
|
+
aliases("/path", PATH_ALIASES, true),
|
|
242
|
+
aliases("/content", [
|
|
243
|
+
"text",
|
|
244
|
+
"body",
|
|
245
|
+
"data",
|
|
246
|
+
"contents",
|
|
247
|
+
"file_content",
|
|
248
|
+
"fileContent",
|
|
249
|
+
"file_text",
|
|
250
|
+
"fileText",
|
|
251
|
+
"new_content",
|
|
252
|
+
"newContent",
|
|
253
|
+
]),
|
|
254
|
+
path("/path"),
|
|
255
|
+
anchor("/path"),
|
|
256
|
+
grammar(""),
|
|
257
|
+
],
|
|
258
|
+
grep: [
|
|
259
|
+
aliases("/pattern", [
|
|
260
|
+
"query",
|
|
261
|
+
"regex",
|
|
262
|
+
"search",
|
|
263
|
+
"q",
|
|
264
|
+
"expression",
|
|
265
|
+
"search_pattern",
|
|
266
|
+
"searchPattern",
|
|
267
|
+
]),
|
|
268
|
+
path("/path"),
|
|
269
|
+
anchor("/path"),
|
|
270
|
+
grammar(""),
|
|
271
|
+
],
|
|
272
|
+
find: [
|
|
273
|
+
aliases("/pattern", [
|
|
274
|
+
"glob",
|
|
275
|
+
"query",
|
|
276
|
+
"name_pattern",
|
|
277
|
+
"namePattern",
|
|
278
|
+
"file_pattern",
|
|
279
|
+
"filePattern",
|
|
280
|
+
"search",
|
|
281
|
+
"name",
|
|
282
|
+
]),
|
|
283
|
+
path("/path"),
|
|
284
|
+
anchor("/path"),
|
|
285
|
+
anchor("/pattern"),
|
|
286
|
+
grammar(""),
|
|
287
|
+
],
|
|
288
|
+
ls: [
|
|
289
|
+
aliases("/path", [
|
|
290
|
+
"directory",
|
|
291
|
+
"dir",
|
|
292
|
+
"folder",
|
|
293
|
+
"directory_path",
|
|
294
|
+
"directoryPath",
|
|
295
|
+
...PATH_ALIASES,
|
|
296
|
+
], true),
|
|
297
|
+
path("/path"),
|
|
298
|
+
anchor("/path"),
|
|
299
|
+
grammar(""),
|
|
300
|
+
],
|
|
301
|
+
};
|
|
302
|
+
//# sourceMappingURL=tables.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tables.js","sourceRoot":"","sources":["../../src/tables.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { TSchema } from "typebox";
|
|
2
|
+
import type { RepairPolicyOverrides, RepairPolicyProfile } from "./policy.ts";
|
|
3
|
+
import type { Preprocessor } from "./preprocess.ts";
|
|
4
|
+
import type { ToolRepairConfig } from "./repair-engine.ts";
|
|
5
|
+
export type RepairStage = "envelope" | "owner-shim" | "preprocess" | "valid-value" | "strict-validation" | "schema-repair" | "final-validation";
|
|
6
|
+
export interface RepairChange {
|
|
7
|
+
ruleId: string;
|
|
8
|
+
stage: RepairStage;
|
|
9
|
+
note: string;
|
|
10
|
+
}
|
|
11
|
+
/** Value-free metadata suitable for local telemetry callbacks. */
|
|
12
|
+
export interface RepairObservation {
|
|
13
|
+
channel: "tool" | "message";
|
|
14
|
+
stage: RepairStage | "grammar";
|
|
15
|
+
ruleId: string;
|
|
16
|
+
toolName?: string;
|
|
17
|
+
grammar?: string;
|
|
18
|
+
outcome?: "detected" | "valid" | "repaired" | "unrepairable";
|
|
19
|
+
}
|
|
20
|
+
export interface RepairPipelineLimits {
|
|
21
|
+
maxInputBytes?: number;
|
|
22
|
+
maxNestingDepth?: number;
|
|
23
|
+
maxDecodeAttempts?: number;
|
|
24
|
+
maxCandidates?: number;
|
|
25
|
+
maxWorkMs?: number;
|
|
26
|
+
}
|
|
27
|
+
export interface RepairPipelineConfig {
|
|
28
|
+
toolName: string;
|
|
29
|
+
schema: TSchema;
|
|
30
|
+
policy?: RepairPolicyProfile;
|
|
31
|
+
policyOverrides?: RepairPolicyOverrides;
|
|
32
|
+
preprocessors?: readonly Preprocessor[];
|
|
33
|
+
/** Compatibility input accepted throughout the current major version. */
|
|
34
|
+
legacyConfig?: ToolRepairConfig;
|
|
35
|
+
modelId?: string;
|
|
36
|
+
ownerPrepareArguments?: (input: unknown) => unknown;
|
|
37
|
+
limits?: RepairPipelineLimits;
|
|
38
|
+
onObservation?: (observation: RepairObservation) => void;
|
|
39
|
+
/** Optional consumer-owned reporting hook; the core itself stores nothing. */
|
|
40
|
+
onOutcome?: (outcome: RepairPipelineResult) => void;
|
|
41
|
+
}
|
|
42
|
+
export interface RepairPipelineResult {
|
|
43
|
+
outcome: "valid" | "repaired" | "unrepairable";
|
|
44
|
+
args: unknown;
|
|
45
|
+
policy: RepairPolicyProfile;
|
|
46
|
+
changes: RepairChange[];
|
|
47
|
+
observations: RepairObservation[];
|
|
48
|
+
issueSummary?: string;
|
|
49
|
+
fingerprint?: string;
|
|
50
|
+
retryMessage?: string;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,KAAK,EAAE,qBAAqB,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAC9E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AACpD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE3D,MAAM,MAAM,WAAW,GACnB,UAAU,GACV,YAAY,GACZ,YAAY,GACZ,aAAa,GACb,mBAAmB,GACnB,eAAe,GACf,kBAAkB,CAAC;AAEvB,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,WAAW,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,kEAAkE;AAClE,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,KAAK,EAAE,WAAW,GAAG,SAAS,CAAC;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,UAAU,GAAG,OAAO,GAAG,UAAU,GAAG,cAAc,CAAC;CAC9D;AAED,MAAM,WAAW,oBAAoB;IACnC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,mBAAmB,CAAC;IAC7B,eAAe,CAAC,EAAE,qBAAqB,CAAC;IACxC,aAAa,CAAC,EAAE,SAAS,YAAY,EAAE,CAAC;IACxC,yEAAyE;IACzE,YAAY,CAAC,EAAE,gBAAgB,CAAC;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,qBAAqB,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC;IACpD,MAAM,CAAC,EAAE,oBAAoB,CAAC;IAC9B,aAAa,CAAC,EAAE,CAAC,WAAW,EAAE,iBAAiB,KAAK,IAAI,CAAC;IACzD,8EAA8E;IAC9E,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,IAAI,CAAC;CACrD;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,GAAG,UAAU,GAAG,cAAc,CAAC;IAC/C,IAAI,EAAE,OAAO,CAAC;IACd,MAAM,EAAE,mBAAmB,CAAC;IAC5B,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,YAAY,EAAE,iBAAiB,EAAE,CAAC;IAClC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model-gated value strips — a pre-pass that runs at the top of the
|
|
3
|
+
* `prepareArguments` override, before the validate-then-repair engine.
|
|
4
|
+
*
|
|
5
|
+
* Adapted from monotykamary/pi-tool-repair (MIT): its `stripAnchorBleedInPlace`
|
|
6
|
+
* and `stripGrammarTokenLeaksInPlace`. Two differences from upstream:
|
|
7
|
+
* - Anchor stripping skips regex-typed fields (the `grep.pattern` field), where
|
|
8
|
+
* a leading `^` / trailing `$` may be intended regex syntax and is
|
|
9
|
+
* indistinguishable from a bled anchor — so we never guess there.
|
|
10
|
+
* - Strips are surfaced through this extension's repair-note / telemetry
|
|
11
|
+
* machinery (a distinct rule id per strip) rather than debug stderr.
|
|
12
|
+
*
|
|
13
|
+
* Why a pre-pass and not an engine rule: the engine's rules fire on
|
|
14
|
+
* schema-invalid input, but an anchor-bled string still validates as a string.
|
|
15
|
+
* Strips transform input that is valid both before and after, so they run
|
|
16
|
+
* ahead of the engine on their own trigger (a model gate), not on a validation
|
|
17
|
+
* failure. See design decision D1.
|
|
18
|
+
*/
|
|
19
|
+
/** Model families that bleed regex anchors into generated values. */
|
|
20
|
+
export declare const ANCHOR_BLEED_MODELS: readonly RegExp[];
|
|
21
|
+
/** Model families that leak GLM-style grammar tokens into keys/values. */
|
|
22
|
+
export declare const GRAMMAR_LEAK_MODELS: readonly RegExp[];
|
|
23
|
+
/**
|
|
24
|
+
* Regex-typed fields exempt from anchor stripping, keyed by tool. `grep.pattern`
|
|
25
|
+
* is the only true regex field among the built-ins (`find.pattern` is a glob,
|
|
26
|
+
* where anchors are never syntax, so it is *not* exempt). See D2 and
|
|
27
|
+
* docs/research.md Claim 8.
|
|
28
|
+
*/
|
|
29
|
+
export declare const ANCHOR_STRIP_SKIP: Record<string, ReadonlySet<string>>;
|
|
30
|
+
export declare const STRIP_ANCHOR_RULE = "stripAnchorBleed";
|
|
31
|
+
export declare const STRIP_GRAMMAR_RULE = "stripGrammarTokenLeak";
|
|
32
|
+
export interface ValueStripResult {
|
|
33
|
+
changed: boolean;
|
|
34
|
+
/** Distinct rule identifier per strip that fired. */
|
|
35
|
+
rules: string[];
|
|
36
|
+
/** Model-facing notes for the repair-note channel. */
|
|
37
|
+
notes: string[];
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Run the model-gated strips over a clone of `input`. Returns the (possibly
|
|
41
|
+
* modified) clone plus a result describing what fired. When nothing fires,
|
|
42
|
+
* `result.changed` is false and the original `input` reference is returned.
|
|
43
|
+
*/
|
|
44
|
+
export declare function stripValues(options: {
|
|
45
|
+
toolName: string;
|
|
46
|
+
input: unknown;
|
|
47
|
+
modelId: string | undefined;
|
|
48
|
+
}): {
|
|
49
|
+
input: unknown;
|
|
50
|
+
result: ValueStripResult;
|
|
51
|
+
};
|
|
52
|
+
//# sourceMappingURL=value-strips.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"value-strips.d.ts","sourceRoot":"","sources":["../../src/value-strips.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,qEAAqE;AACrE,eAAO,MAAM,mBAAmB,EAAE,SAAS,MAAM,EAIhD,CAAC;AAEF,0EAA0E;AAC1E,eAAO,MAAM,mBAAmB,EAAE,SAAS,MAAM,EAAa,CAAC;AAE/D;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,CAAC,CAEjE,CAAC;AAEF,eAAO,MAAM,iBAAiB,qBAAqB,CAAC;AACpD,eAAO,MAAM,kBAAkB,0BAA0B,CAAC;AAY1D,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,OAAO,CAAC;IACjB,qDAAqD;IACrD,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,sDAAsD;IACtD,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAoHD;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;CAC7B,GAAG;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAA;CAAE,CAkC/C"}
|
|
@@ -0,0 +1,191 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model-gated value strips — a pre-pass that runs at the top of the
|
|
3
|
+
* `prepareArguments` override, before the validate-then-repair engine.
|
|
4
|
+
*
|
|
5
|
+
* Adapted from monotykamary/pi-tool-repair (MIT): its `stripAnchorBleedInPlace`
|
|
6
|
+
* and `stripGrammarTokenLeaksInPlace`. Two differences from upstream:
|
|
7
|
+
* - Anchor stripping skips regex-typed fields (the `grep.pattern` field), where
|
|
8
|
+
* a leading `^` / trailing `$` may be intended regex syntax and is
|
|
9
|
+
* indistinguishable from a bled anchor — so we never guess there.
|
|
10
|
+
* - Strips are surfaced through this extension's repair-note / telemetry
|
|
11
|
+
* machinery (a distinct rule id per strip) rather than debug stderr.
|
|
12
|
+
*
|
|
13
|
+
* Why a pre-pass and not an engine rule: the engine's rules fire on
|
|
14
|
+
* schema-invalid input, but an anchor-bled string still validates as a string.
|
|
15
|
+
* Strips transform input that is valid both before and after, so they run
|
|
16
|
+
* ahead of the engine on their own trigger (a model gate), not on a validation
|
|
17
|
+
* failure. See design decision D1.
|
|
18
|
+
*/
|
|
19
|
+
/** Model families that bleed regex anchors into generated values. */
|
|
20
|
+
export const ANCHOR_BLEED_MODELS = [
|
|
21
|
+
/kimi-k2/i,
|
|
22
|
+
/minimax/i,
|
|
23
|
+
/glm/i,
|
|
24
|
+
];
|
|
25
|
+
/** Model families that leak GLM-style grammar tokens into keys/values. */
|
|
26
|
+
export const GRAMMAR_LEAK_MODELS = [/glm/i];
|
|
27
|
+
/**
|
|
28
|
+
* Regex-typed fields exempt from anchor stripping, keyed by tool. `grep.pattern`
|
|
29
|
+
* is the only true regex field among the built-ins (`find.pattern` is a glob,
|
|
30
|
+
* where anchors are never syntax, so it is *not* exempt). See D2 and
|
|
31
|
+
* docs/research.md Claim 8.
|
|
32
|
+
*/
|
|
33
|
+
export const ANCHOR_STRIP_SKIP = {
|
|
34
|
+
grep: new Set(["pattern"]),
|
|
35
|
+
};
|
|
36
|
+
export const STRIP_ANCHOR_RULE = "stripAnchorBleed";
|
|
37
|
+
export const STRIP_GRAMMAR_RULE = "stripGrammarTokenLeak";
|
|
38
|
+
// Leaked grammar markers from GLM/ChatGLM-style tool-call grammars: they can
|
|
39
|
+
// land as literal prefixes/suffixes on parsed object keys or string values
|
|
40
|
+
// instead of being interpreted as XML tags.
|
|
41
|
+
const GRAMMAR_TOKEN_LEAKS = [
|
|
42
|
+
{ tag: "<arg_key>", at: "start" },
|
|
43
|
+
{ tag: "</arg_key>", at: "end" },
|
|
44
|
+
{ tag: "<arg_value>", at: "start" },
|
|
45
|
+
{ tag: "</arg_value>", at: "end" },
|
|
46
|
+
];
|
|
47
|
+
function isContainer(value) {
|
|
48
|
+
return value !== null && typeof value === "object";
|
|
49
|
+
}
|
|
50
|
+
function modelMatches(modelId, families) {
|
|
51
|
+
if (!modelId)
|
|
52
|
+
return false;
|
|
53
|
+
return families.some((re) => re.test(modelId));
|
|
54
|
+
}
|
|
55
|
+
function stripAnchorsFromString(value) {
|
|
56
|
+
let s = value;
|
|
57
|
+
while (s.startsWith("^"))
|
|
58
|
+
s = s.slice(1);
|
|
59
|
+
while (s.endsWith("$"))
|
|
60
|
+
s = s.slice(0, -1);
|
|
61
|
+
return s;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Recursively strip leading `^` / trailing `$` from string values. `skipKeys`
|
|
65
|
+
* exempts regex-typed fields, and only applies at the top level (nested
|
|
66
|
+
* built-in fields are never regex).
|
|
67
|
+
*/
|
|
68
|
+
function stripAnchorBleed(node, skipKeys) {
|
|
69
|
+
let changed = false;
|
|
70
|
+
if (Array.isArray(node)) {
|
|
71
|
+
for (let i = 0; i < node.length; i++) {
|
|
72
|
+
const item = node[i];
|
|
73
|
+
if (typeof item === "string") {
|
|
74
|
+
const stripped = stripAnchorsFromString(item);
|
|
75
|
+
if (stripped !== item) {
|
|
76
|
+
node[i] = stripped;
|
|
77
|
+
changed = true;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
else if (isContainer(item)) {
|
|
81
|
+
if (stripAnchorBleed(item, undefined))
|
|
82
|
+
changed = true;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return changed;
|
|
86
|
+
}
|
|
87
|
+
for (const key of Object.keys(node)) {
|
|
88
|
+
if (skipKeys?.has(key))
|
|
89
|
+
continue;
|
|
90
|
+
const value = node[key];
|
|
91
|
+
if (typeof value === "string") {
|
|
92
|
+
const stripped = stripAnchorsFromString(value);
|
|
93
|
+
if (stripped !== value) {
|
|
94
|
+
node[key] = stripped;
|
|
95
|
+
changed = true;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
else if (isContainer(value)) {
|
|
99
|
+
if (stripAnchorBleed(value, undefined))
|
|
100
|
+
changed = true;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
return changed;
|
|
104
|
+
}
|
|
105
|
+
function stripGrammarTokensFromString(value) {
|
|
106
|
+
let s = value;
|
|
107
|
+
for (const { tag, at } of GRAMMAR_TOKEN_LEAKS) {
|
|
108
|
+
if (at === "start" && s.startsWith(tag))
|
|
109
|
+
s = s.slice(tag.length);
|
|
110
|
+
else if (at === "end" && s.endsWith(tag))
|
|
111
|
+
s = s.slice(0, -tag.length);
|
|
112
|
+
}
|
|
113
|
+
return s.trim();
|
|
114
|
+
}
|
|
115
|
+
/** Recursively strip grammar-token leaks from object keys and string values. */
|
|
116
|
+
function stripGrammarTokenLeaks(node) {
|
|
117
|
+
let changed = false;
|
|
118
|
+
if (Array.isArray(node)) {
|
|
119
|
+
for (let i = 0; i < node.length; i++) {
|
|
120
|
+
const item = node[i];
|
|
121
|
+
if (typeof item === "string") {
|
|
122
|
+
const stripped = stripGrammarTokensFromString(item);
|
|
123
|
+
if (stripped !== item) {
|
|
124
|
+
node[i] = stripped;
|
|
125
|
+
changed = true;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
else if (isContainer(item)) {
|
|
129
|
+
if (stripGrammarTokenLeaks(item))
|
|
130
|
+
changed = true;
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
return changed;
|
|
134
|
+
}
|
|
135
|
+
for (const key of Object.keys(node)) {
|
|
136
|
+
const value = node[key];
|
|
137
|
+
const newKey = stripGrammarTokensFromString(key);
|
|
138
|
+
if (newKey !== key) {
|
|
139
|
+
delete node[key];
|
|
140
|
+
node[newKey] = value;
|
|
141
|
+
changed = true;
|
|
142
|
+
}
|
|
143
|
+
const target = newKey;
|
|
144
|
+
const current = node[target];
|
|
145
|
+
if (typeof current === "string") {
|
|
146
|
+
const stripped = stripGrammarTokensFromString(current);
|
|
147
|
+
if (stripped !== current) {
|
|
148
|
+
node[target] = stripped;
|
|
149
|
+
changed = true;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
else if (isContainer(current)) {
|
|
153
|
+
if (stripGrammarTokenLeaks(current))
|
|
154
|
+
changed = true;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
return changed;
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* Run the model-gated strips over a clone of `input`. Returns the (possibly
|
|
161
|
+
* modified) clone plus a result describing what fired. When nothing fires,
|
|
162
|
+
* `result.changed` is false and the original `input` reference is returned.
|
|
163
|
+
*/
|
|
164
|
+
export function stripValues(options) {
|
|
165
|
+
const { toolName, input, modelId } = options;
|
|
166
|
+
const result = { changed: false, rules: [], notes: [] };
|
|
167
|
+
if (!isContainer(input))
|
|
168
|
+
return { input, result };
|
|
169
|
+
const doAnchor = modelMatches(modelId, ANCHOR_BLEED_MODELS);
|
|
170
|
+
const doGrammar = modelMatches(modelId, GRAMMAR_LEAK_MODELS);
|
|
171
|
+
if (!doAnchor && !doGrammar)
|
|
172
|
+
return { input, result };
|
|
173
|
+
const clone = structuredClone(input);
|
|
174
|
+
// Grammar tokens first: they wrap the real value, and removing them can expose
|
|
175
|
+
// a bled anchor underneath for the anchor pass to clean.
|
|
176
|
+
if (doGrammar && stripGrammarTokenLeaks(clone)) {
|
|
177
|
+
result.changed = true;
|
|
178
|
+
result.rules.push(STRIP_GRAMMAR_RULE);
|
|
179
|
+
result.notes.push(`Removed leaked grammar tokens (\`<arg_key>\`/\`<arg_value>\`) from keys/values for tool "${toolName}". These are grammar markers, not part of your field names or values — send plain keys and values next time.`);
|
|
180
|
+
}
|
|
181
|
+
if (doAnchor) {
|
|
182
|
+
const skip = Array.isArray(clone) ? undefined : ANCHOR_STRIP_SKIP[toolName];
|
|
183
|
+
if (stripAnchorBleed(clone, skip)) {
|
|
184
|
+
result.changed = true;
|
|
185
|
+
result.rules.push(STRIP_ANCHOR_RULE);
|
|
186
|
+
result.notes.push(`Stripped leaked regex anchors (\`^\` / \`$\`) from string value(s) for tool "${toolName}". These anchors bled in from the tool-call grammar and were not part of your intended value.`);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
return { input: result.changed ? clone : input, result };
|
|
190
|
+
}
|
|
191
|
+
//# sourceMappingURL=value-strips.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"value-strips.js","sourceRoot":"","sources":["../../src/value-strips.ts"],"names":[],"mappings":"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"}
|