@caupulican/pi-ai 0.86.17 → 0.90.2

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.
@@ -18,78 +18,78 @@ export const TOOL_REPAIR_MODE_NAMES = [
18
18
  export const TOOL_REPAIR_REGISTRY = [
19
19
  {
20
20
  name: "nullOptionalDrop",
21
- noteTemplate: "sent null for optional `{path}` -> omit the field instead",
22
- standingRule: "Omit optional fields instead of sending null.",
21
+ noteTemplate: "optional `{path}` was null; omit field",
22
+ standingRule: "Optional field: omit, never null.",
23
23
  },
24
24
  {
25
25
  name: "nullRequiredBounce",
26
- noteTemplate: "`{path}` is required and cannot be null -> send a real value",
27
- standingRule: "Send real values for required fields; never send null for a required field.",
26
+ noteTemplate: "required `{path}` was null; send real value",
27
+ standingRule: "Required field: real value, never null.",
28
28
  },
29
29
  {
30
30
  name: "jsonStringParse",
31
- noteTemplate: "sent `{path}` as a quoted JSON string -> send a raw JSON array/object",
32
- standingRule: "Send raw JSON arrays/objects where the tool schema expects arrays/objects; do not quote them as JSON strings.",
31
+ noteTemplate: "`{path}` was quoted JSON; send raw array/object",
32
+ standingRule: "Schema array/object: raw JSON, never quoted JSON string.",
33
33
  },
34
34
  {
35
35
  name: "jsonObjectPropertySalvage",
36
- noteTemplate: "sent `{path}` as malformed JSON with recoverable declared properties -> keep the schema-declared properties",
37
- standingRule: "When sending JSON objects, use strict JSON syntax with commas between properties and no extra text inside the object.",
36
+ noteTemplate: "`{path}` was malformed JSON; retained declared properties",
37
+ standingRule: "JSON object: strict syntax, commas between properties, no extra inner text.",
38
38
  },
39
39
  {
40
40
  name: "singleObjectWrap",
41
- noteTemplate: "sent one object where `{path}` takes a list -> wrap it in [ ]",
42
- standingRule: "Wrap a single object in [ ] when the tool schema expects a list.",
41
+ noteTemplate: "`{path}` needs list; wrap object in [ ]",
42
+ standingRule: "List schema: wrap one object in [ ].",
43
43
  },
44
44
  {
45
45
  name: "bareScalarWrap",
46
- noteTemplate: "sent a single value where `{path}` takes a list -> wrap it in [ ]",
47
- standingRule: "Wrap a single scalar in [ ] when the tool schema expects a list.",
46
+ noteTemplate: "`{path}` needs list; wrap scalar in [ ]",
47
+ standingRule: "List schema: wrap one scalar in [ ].",
48
48
  },
49
49
  {
50
50
  name: "emptyObjectPlaceholder",
51
- noteTemplate: "sent `{}` as a placeholder -> omit `{path}`; its default applies",
52
- standingRule: "Omit defaulted object fields instead of sending `{}` placeholders.",
51
+ noteTemplate: "`{path}` was `{}` placeholder; omit for default",
52
+ standingRule: "Defaulted object field: omit, never `{}` placeholder.",
53
53
  },
54
54
  {
55
55
  name: "numberFromString",
56
- noteTemplate: "sent `{path}` as a quoted number -> send a bare number",
57
- standingRule: "Send bare numbers where the tool schema expects numbers; do not quote them.",
56
+ noteTemplate: "`{path}` was quoted number; send bare number",
57
+ standingRule: "Number schema: bare number, never quoted.",
58
58
  },
59
59
  {
60
60
  name: "boolFromString",
61
- noteTemplate: "sent `{path}` as a quoted boolean -> send bare true/false",
62
- standingRule: "Send bare true/false where the tool schema expects booleans; do not quote them.",
61
+ noteTemplate: "`{path}` was quoted boolean; send bare true/false",
62
+ standingRule: "Boolean schema: bare true/false, never quoted.",
63
63
  },
64
64
  {
65
65
  name: "enumCaseNormalize",
66
- noteTemplate: "`{path}` matched a declared enum value after case/space normalization",
67
- standingRule: "Use enum values exactly as declared, preserving case and spacing.",
66
+ noteTemplate: "`{path}` normalized to declared enum case/spacing",
67
+ standingRule: "Enum value: exact declared case/spacing.",
68
68
  },
69
69
  {
70
70
  name: "propertyCaseNormalize",
71
- noteTemplate: "sent `{path}` with different property-key casing -> use the schema key casing",
72
- standingRule: "Use tool argument property names exactly as declared in the schema, preserving case.",
71
+ noteTemplate: "`{path}` used wrong key case; use schema case",
72
+ standingRule: "Argument property: exact schema name/case.",
73
73
  },
74
74
  {
75
75
  name: "singleElementUnwrap",
76
- noteTemplate: "sent `{path}` as a 1-item list where a single value was expected -> send the value",
77
- standingRule: "Send a single value directly when the tool schema expects a single value; do not wrap it in a one-item list.",
76
+ noteTemplate: "`{path}` needs scalar; unwrap 1-item list",
77
+ standingRule: "Scalar schema: direct value, never 1-item list.",
78
78
  },
79
79
  {
80
80
  name: "stringifiedNumberInArray",
81
- noteTemplate: "list `{path}` holds quoted numbers -> send bare numbers",
82
- standingRule: "Use bare numbers inside number arrays; do not quote them.",
81
+ noteTemplate: "number list `{path}` held quoted values; send bare numbers",
82
+ standingRule: "Number array: bare numbers, never quoted.",
83
83
  },
84
84
  {
85
85
  name: "bashCommandArgvJoin",
86
- noteTemplate: "bash takes one command string, not an argv list -> joined the argv values",
87
- standingRule: "For bash, send one command string rather than an argv array.",
86
+ noteTemplate: "bash needs one command string; joined argv values",
87
+ standingRule: "bash command: one string, never argv array.",
88
88
  },
89
89
  {
90
90
  name: "bashCommandUnwrap",
91
- noteTemplate: "bash `command` is a string -> unwrapped the command object",
92
- standingRule: "For bash, send `command` as a string rather than an object wrapper.",
91
+ noteTemplate: "bash `command` needs string; unwrapped object",
92
+ standingRule: "bash `command`: string, never object wrapper.",
93
93
  },
94
94
  ];
95
95
  const registryByName = new Map(TOOL_REPAIR_REGISTRY.map((entry) => [entry.name, entry]));
@@ -108,7 +108,7 @@ export function formatToolRepairStandingRule(name) {
108
108
  export const REPEATED_SUCCESSFUL_TOOL_CALL_FAILURE = {
109
109
  failureCode: "repeated_successful_call",
110
110
  diagnostic: "The identical phone tool call already succeeded and was not executed again.",
111
- guidance: "Use the previous successful result and continue; it is quoted in the diagnostic. Answer the user if the task is complete, or call a different required tool. Do not retry the same call unchanged.",
111
+ guidance: "Use prior successful result; continue. Task complete: answer user. Otherwise call different required tool. Never retry unchanged.",
112
112
  };
113
113
  export const TOOL_EXECUTION_ERROR_CATALOGUE = [
114
114
  {
@@ -116,7 +116,7 @@ export const TOOL_EXECUTION_ERROR_CATALOGUE = [
116
116
  phase: "provisioning",
117
117
  failureCode: "provisioning_failed",
118
118
  retainDiagnostic: true,
119
- guidance: "Provisioning failed; use the exact diagnostic, repair that cause, and retry only after the environment changes.",
119
+ guidance: "Provisioning failed. Use exact diagnostic, fix cause; retry only after environment changes.",
120
120
  matches(message) {
121
121
  return /\bPI_TOOL_PROVISIONING_FAILED\b/i.test(message);
122
122
  },
@@ -124,7 +124,7 @@ export const TOOL_EXECUTION_ERROR_CATALOGUE = [
124
124
  {
125
125
  name: "commandNotFound",
126
126
  phase: "provisioning",
127
- guidance: "Command was not found; check the command name or available tools before retrying.",
127
+ guidance: "Command not found. Check exact name/available tools before retry.",
128
128
  matches(message) {
129
129
  return /^spawn \S+ ENOENT\b/i.test(message) || /(?:^|\n|:)\s*command not found\b/i.test(message);
130
130
  },
@@ -132,7 +132,7 @@ export const TOOL_EXECUTION_ERROR_CATALOGUE = [
132
132
  {
133
133
  name: "bashNoOutput",
134
134
  phase: "execution",
135
- guidance: "The command exited with an error but returned no output; verify the command syntax and check its specific documentation before retrying.",
135
+ guidance: "Command failed without output. Verify syntax, exact command documentation before retry.",
136
136
  matches(message) {
137
137
  return message === "(no output)";
138
138
  },
@@ -140,7 +140,7 @@ export const TOOL_EXECUTION_ERROR_CATALOGUE = [
140
140
  {
141
141
  name: "bashPosixNotSupported",
142
142
  phase: "execution",
143
- guidance: "POSIX shell scripts (.sh) are not supported on this Windows host; use a PowerShell equivalent or invoke the executable directly.",
143
+ guidance: "Windows host rejects POSIX .sh scripts. Use PowerShell equivalent or invoke executable directly.",
144
144
  matches(message) {
145
145
  return /POSIX shell scripts are not supported by the Windows shell contract router/i.test(message);
146
146
  },
@@ -148,7 +148,7 @@ export const TOOL_EXECUTION_ERROR_CATALOGUE = [
148
148
  {
149
149
  name: "bashNestedShell",
150
150
  phase: "execution",
151
- guidance: "Do not wrap commands in powershell.exe or pwsh. Invoke the .ps1 script or command directly.",
151
+ guidance: "Never wrap command in powershell.exe/pwsh. Invoke .ps1 or command directly.",
152
152
  matches(message) {
153
153
  return /Nested shell execution is not supported by the Windows shell contract router/i.test(message);
154
154
  },
@@ -156,7 +156,7 @@ export const TOOL_EXECUTION_ERROR_CATALOGUE = [
156
156
  {
157
157
  name: "bashMissingCommandWord",
158
158
  phase: "execution",
159
- guidance: "The shell command was malformed (missing command word). Check for empty pipeline elements or incorrect string quoting before retrying.",
159
+ guidance: "Missing shell command word. Fix empty pipeline element or string quoting before retry.",
160
160
  matches(message) {
161
161
  return /Missing command: a pipeline\/list element has no command word/i.test(message);
162
162
  },
@@ -164,7 +164,7 @@ export const TOOL_EXECUTION_ERROR_CATALOGUE = [
164
164
  {
165
165
  name: "bashEmptyRedirectTarget",
166
166
  phase: "execution",
167
- guidance: "The shell redirect target was empty; provide a valid file path for the redirect before retrying.",
167
+ guidance: "Empty redirect target. Supply valid file path before retry.",
168
168
  matches(message) {
169
169
  return /redirect target expanded to nothing/i.test(message);
170
170
  },
@@ -174,7 +174,7 @@ export const TOOL_EXECUTION_ERROR_CATALOGUE = [
174
174
  phase: "execution",
175
175
  failureCode: "encoding_corruption",
176
176
  attemptMemory: "discard",
177
- guidance: "Change approach: exact UTF-8 text replacement is unsafe for this file. Use an encoding-aware or byte-safe tool/workflow instead; do not replay the text edit.",
177
+ guidance: "Change approach: exact UTF-8 replacement unsafe. Use encoding-aware/byte-safe tool; never replay text edit.",
178
178
  matches(message) {
179
179
  return /\bPI_FILE_ENCODING_CORRUPTION\b/i.test(message);
180
180
  },
@@ -196,7 +196,7 @@ export const TOOL_EXECUTION_ERROR_CATALOGUE = [
196
196
  failureCode: "mutation_retarget_required",
197
197
  attemptMemory: "discard",
198
198
  retainDiagnostic: true,
199
- guidance: "The mutation payload is already retained by the harness. Choose only the corrected target path and reuse the exact payloadRef from the diagnostic; do not regenerate content or edits.",
199
+ guidance: "Harness retained mutation. Choose corrected target path, reuse exact diagnostic payloadRef; never regenerate content/edits.",
200
200
  matches(message) {
201
201
  return /\bPI_FILE_MUTATION_RETARGET\b/i.test(message);
202
202
  },
@@ -205,7 +205,7 @@ export const TOOL_EXECUTION_ERROR_CATALOGUE = [
205
205
  name: "fileNotFound",
206
206
  phase: "execution",
207
207
  failureCode: "file_not_found",
208
- guidance: "Path was not found; list the parent directory or re-read the path before retrying.",
208
+ guidance: "Path not found. List parent directory or re-read path before retry.",
209
209
  matches(message) {
210
210
  return (/\bENOENT\b/i.test(message) ||
211
211
  /no such file or directory/i.test(message) ||
@@ -216,7 +216,7 @@ export const TOOL_EXECUTION_ERROR_CATALOGUE = [
216
216
  name: "editOldTextNotFound",
217
217
  phase: "execution",
218
218
  failureCode: "edit_old_text_not_found",
219
- guidance: "Re-read the target file and use the exact current text before retrying.",
219
+ guidance: "Re-read target; use exact current text before retry.",
220
220
  matches(message) {
221
221
  return /(?:oldText|old text|exact text).*(?:not found|no match|failed to match|must match)/is.test(message);
222
222
  },
@@ -224,7 +224,7 @@ export const TOOL_EXECUTION_ERROR_CATALOGUE = [
224
224
  {
225
225
  name: "pathOutsideCwd",
226
226
  phase: "policy",
227
- guidance: "Choose a path inside the current working directory, or ask before changing scope.",
227
+ guidance: "Choose path inside current working directory; ask before scope change.",
228
228
  matches(message) {
229
229
  return /outside (?:the )?(?:current working directory|cwd|workspace|root)/i.test(message);
230
230
  },
@@ -234,7 +234,7 @@ export const TOOL_EXECUTION_ERROR_CATALOGUE = [
234
234
  phase: "policy",
235
235
  failureCode: "permission_denied",
236
236
  retainDiagnostic: true,
237
- guidance: "Access was denied; verify the target path and current authority, then request or change permissions before retrying.",
237
+ guidance: "Access denied. Verify target/current authority; obtain permissions before retry.",
238
238
  matches(message) {
239
239
  return /\b(?:EACCES|EPERM)\b/i.test(message) || /(?:permission|access) (?:is )?denied/i.test(message);
240
240
  },
@@ -244,7 +244,7 @@ export const TOOL_EXECUTION_ERROR_CATALOGUE = [
244
244
  phase: "execution",
245
245
  failureCode: "invalid_option",
246
246
  retainDiagnostic: true,
247
- guidance: "Option rejected; re-read command help and remove or replace it before retrying.",
247
+ guidance: "Option rejected. Read command help; remove/replace option before retry.",
248
248
  matches(message) {
249
249
  return /\b(?:invalid|unknown|unrecognized) (?:command-line )?(?:option|argument)\b/i.test(message);
250
250
  },
@@ -254,7 +254,7 @@ export const TOOL_EXECUTION_ERROR_CATALOGUE = [
254
254
  phase: "execution",
255
255
  failureCode: "invalid_pattern",
256
256
  retainDiagnostic: true,
257
- guidance: "The search pattern was invalid; simplify it or correct its regex/glob escaping before retrying.",
257
+ guidance: "Invalid search pattern. Simplify or fix regex/glob escaping before retry.",
258
258
  matches(message) {
259
259
  return (/(?:regex|regular expression|glob) (?:parse )?error\b/i.test(message) ||
260
260
  /\bunclosed (?:group|class)\b/i.test(message));
@@ -264,7 +264,7 @@ export const TOOL_EXECUTION_ERROR_CATALOGUE = [
264
264
  name: "outputLimit",
265
265
  phase: "execution",
266
266
  failureCode: "output_limit",
267
- guidance: "Output exceeded its bound; narrow the scope, page the request, or use the retained artifact before retrying.",
267
+ guidance: "Output exceeded bound. Narrow scope, page request, or use retained artifact before retry.",
268
268
  matches(message) {
269
269
  return /\b(?:output|result|response).*(?:limit|truncat|too large)\b/i.test(message);
270
270
  },
@@ -274,7 +274,7 @@ export const TOOL_EXECUTION_ERROR_CATALOGUE = [
274
274
  phase: "timeout",
275
275
  failureCode: "timeout",
276
276
  unchangedRetryLimit: 1,
277
- guidance: "The operation timed out; narrow or split the work, then retry once only when repeating it is safe and still required.",
277
+ guidance: "Operation timed out. Narrow/split work; one unchanged retry only when safe, still required.",
278
278
  matches(message) {
279
279
  return (/\b(?:command|operation|process|request|tool)\s+(?:timed out|timeout(?: after)?)\b/i.test(message) ||
280
280
  /\bETIMEDOUT\b/i.test(message));
@@ -284,7 +284,7 @@ export const TOOL_EXECUTION_ERROR_CATALOGUE = [
284
284
  name: "cancelled",
285
285
  phase: "cancelled",
286
286
  failureCode: "cancelled",
287
- guidance: "The operation was cancelled; retry only if it is still required and the cancellation condition has cleared.",
287
+ guidance: "Operation cancelled. Retry only when still required, cancellation condition cleared.",
288
288
  matches(message) {
289
289
  return (/^(?:operation|request|tool) (?:was )?(?:aborted|cancelled|canceled)\b/i.test(message) ||
290
290
  /\bAbortError\b/i.test(message));
@@ -1 +1 @@
1
- {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/utils/tool-repair/registry.ts"],"names":[],"mappings":"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","sourcesContent":["export const TOOL_REPAIR_MODE_NAMES = [\n\t\"nullOptionalDrop\",\n\t\"nullRequiredBounce\",\n\t\"jsonStringParse\",\n\t\"jsonObjectPropertySalvage\",\n\t\"singleObjectWrap\",\n\t\"bareScalarWrap\",\n\t\"emptyObjectPlaceholder\",\n\t\"numberFromString\",\n\t\"boolFromString\",\n\t\"enumCaseNormalize\",\n\t\"propertyCaseNormalize\",\n\t\"singleElementUnwrap\",\n\t\"stringifiedNumberInArray\",\n\t\"bashCommandArgvJoin\",\n\t\"bashCommandUnwrap\",\n] as const;\n\nexport type ToolRepairModeName = (typeof TOOL_REPAIR_MODE_NAMES)[number];\nexport type ToolRepairFailureModeName = ToolRepairModeName | \"other\";\n\nexport interface ToolRepairRegistryEntry {\n\tname: ToolRepairModeName;\n\tnoteTemplate: string;\n\tstandingRule: string;\n}\n\nexport const TOOL_REPAIR_REGISTRY: readonly ToolRepairRegistryEntry[] = [\n\t{\n\t\tname: \"nullOptionalDrop\",\n\t\tnoteTemplate: \"sent null for optional `{path}` -> omit the field instead\",\n\t\tstandingRule: \"Omit optional fields instead of sending null.\",\n\t},\n\t{\n\t\tname: \"nullRequiredBounce\",\n\t\tnoteTemplate: \"`{path}` is required and cannot be null -> send a real value\",\n\t\tstandingRule: \"Send real values for required fields; never send null for a required field.\",\n\t},\n\t{\n\t\tname: \"jsonStringParse\",\n\t\tnoteTemplate: \"sent `{path}` as a quoted JSON string -> send a raw JSON array/object\",\n\t\tstandingRule:\n\t\t\t\"Send raw JSON arrays/objects where the tool schema expects arrays/objects; do not quote them as JSON strings.\",\n\t},\n\t{\n\t\tname: \"jsonObjectPropertySalvage\",\n\t\tnoteTemplate:\n\t\t\t\"sent `{path}` as malformed JSON with recoverable declared properties -> keep the schema-declared properties\",\n\t\tstandingRule:\n\t\t\t\"When sending JSON objects, use strict JSON syntax with commas between properties and no extra text inside the object.\",\n\t},\n\t{\n\t\tname: \"singleObjectWrap\",\n\t\tnoteTemplate: \"sent one object where `{path}` takes a list -> wrap it in [ ]\",\n\t\tstandingRule: \"Wrap a single object in [ ] when the tool schema expects a list.\",\n\t},\n\t{\n\t\tname: \"bareScalarWrap\",\n\t\tnoteTemplate: \"sent a single value where `{path}` takes a list -> wrap it in [ ]\",\n\t\tstandingRule: \"Wrap a single scalar in [ ] when the tool schema expects a list.\",\n\t},\n\t{\n\t\tname: \"emptyObjectPlaceholder\",\n\t\tnoteTemplate: \"sent `{}` as a placeholder -> omit `{path}`; its default applies\",\n\t\tstandingRule: \"Omit defaulted object fields instead of sending `{}` placeholders.\",\n\t},\n\t{\n\t\tname: \"numberFromString\",\n\t\tnoteTemplate: \"sent `{path}` as a quoted number -> send a bare number\",\n\t\tstandingRule: \"Send bare numbers where the tool schema expects numbers; do not quote them.\",\n\t},\n\t{\n\t\tname: \"boolFromString\",\n\t\tnoteTemplate: \"sent `{path}` as a quoted boolean -> send bare true/false\",\n\t\tstandingRule: \"Send bare true/false where the tool schema expects booleans; do not quote them.\",\n\t},\n\t{\n\t\tname: \"enumCaseNormalize\",\n\t\tnoteTemplate: \"`{path}` matched a declared enum value after case/space normalization\",\n\t\tstandingRule: \"Use enum values exactly as declared, preserving case and spacing.\",\n\t},\n\t{\n\t\tname: \"propertyCaseNormalize\",\n\t\tnoteTemplate: \"sent `{path}` with different property-key casing -> use the schema key casing\",\n\t\tstandingRule: \"Use tool argument property names exactly as declared in the schema, preserving case.\",\n\t},\n\t{\n\t\tname: \"singleElementUnwrap\",\n\t\tnoteTemplate: \"sent `{path}` as a 1-item list where a single value was expected -> send the value\",\n\t\tstandingRule:\n\t\t\t\"Send a single value directly when the tool schema expects a single value; do not wrap it in a one-item list.\",\n\t},\n\t{\n\t\tname: \"stringifiedNumberInArray\",\n\t\tnoteTemplate: \"list `{path}` holds quoted numbers -> send bare numbers\",\n\t\tstandingRule: \"Use bare numbers inside number arrays; do not quote them.\",\n\t},\n\t{\n\t\tname: \"bashCommandArgvJoin\",\n\t\tnoteTemplate: \"bash takes one command string, not an argv list -> joined the argv values\",\n\t\tstandingRule: \"For bash, send one command string rather than an argv array.\",\n\t},\n\t{\n\t\tname: \"bashCommandUnwrap\",\n\t\tnoteTemplate: \"bash `command` is a string -> unwrapped the command object\",\n\t\tstandingRule: \"For bash, send `command` as a string rather than an object wrapper.\",\n\t},\n] as const;\n\nconst registryByName = new Map(TOOL_REPAIR_REGISTRY.map((entry) => [entry.name, entry]));\n\nexport function getToolRepairRegistryEntry(name: ToolRepairModeName): ToolRepairRegistryEntry {\n\tconst entry = registryByName.get(name);\n\tif (!entry) throw new Error(`Unknown tool repair mode: ${name}`);\n\treturn entry;\n}\n\nexport function formatToolRepairNote(name: ToolRepairModeName, path: string): string {\n\treturn getToolRepairRegistryEntry(name).noteTemplate.replaceAll(\"{path}\", path);\n}\n\nexport function formatToolRepairStandingRule(name: ToolRepairModeName): string {\n\treturn getToolRepairRegistryEntry(name).standingRule;\n}\n\nexport type ToolExecutionAttemptMemory = \"retain\" | \"discard\";\nexport type ToolFailurePhase =\n\t| \"validation\"\n\t| \"policy\"\n\t| \"preflight\"\n\t| \"execution\"\n\t| \"timeout\"\n\t| \"cancelled\"\n\t| \"provisioning\";\n\nexport const REPEATED_SUCCESSFUL_TOOL_CALL_FAILURE = {\n\tfailureCode: \"repeated_successful_call\",\n\tdiagnostic: \"The identical phone tool call already succeeded and was not executed again.\",\n\tguidance:\n\t\t\"Use the previous successful result and continue; it is quoted in the diagnostic. Answer the user if the task is complete, or call a different required tool. Do not retry the same call unchanged.\",\n} as const;\n\ninterface ToolExecutionErrorCatalogueEntry {\n\tname: string;\n\tphase: ToolFailurePhase;\n\tguidance: string;\n\tfailureCode?: string;\n\tattemptMemory?: ToolExecutionAttemptMemory;\n\tretainDiagnostic?: boolean;\n\t/** Number of unchanged executions permitted after the first failure in one recovery window. */\n\tunchangedRetryLimit?: number;\n\tmatches(message: string): boolean;\n}\n\nexport const TOOL_EXECUTION_ERROR_CATALOGUE = [\n\t{\n\t\tname: \"provisioningFailed\",\n\t\tphase: \"provisioning\",\n\t\tfailureCode: \"provisioning_failed\",\n\t\tretainDiagnostic: true,\n\t\tguidance:\n\t\t\t\"Provisioning failed; use the exact diagnostic, repair that cause, and retry only after the environment changes.\",\n\t\tmatches(message: string): boolean {\n\t\t\treturn /\\bPI_TOOL_PROVISIONING_FAILED\\b/i.test(message);\n\t\t},\n\t},\n\t{\n\t\tname: \"commandNotFound\",\n\t\tphase: \"provisioning\",\n\t\tguidance: \"Command was not found; check the command name or available tools before retrying.\",\n\t\tmatches(message: string): boolean {\n\t\t\treturn /^spawn \\S+ ENOENT\\b/i.test(message) || /(?:^|\\n|:)\\s*command not found\\b/i.test(message);\n\t\t},\n\t},\n\t{\n\t\tname: \"bashNoOutput\",\n\t\tphase: \"execution\",\n\t\tguidance:\n\t\t\t\"The command exited with an error but returned no output; verify the command syntax and check its specific documentation before retrying.\",\n\t\tmatches(message: string): boolean {\n\t\t\treturn message === \"(no output)\";\n\t\t},\n\t},\n\t{\n\t\tname: \"bashPosixNotSupported\",\n\t\tphase: \"execution\",\n\t\tguidance:\n\t\t\t\"POSIX shell scripts (.sh) are not supported on this Windows host; use a PowerShell equivalent or invoke the executable directly.\",\n\t\tmatches(message: string): boolean {\n\t\t\treturn /POSIX shell scripts are not supported by the Windows shell contract router/i.test(message);\n\t\t},\n\t},\n\t{\n\t\tname: \"bashNestedShell\",\n\t\tphase: \"execution\",\n\t\tguidance: \"Do not wrap commands in powershell.exe or pwsh. Invoke the .ps1 script or command directly.\",\n\t\tmatches(message: string): boolean {\n\t\t\treturn /Nested shell execution is not supported by the Windows shell contract router/i.test(message);\n\t\t},\n\t},\n\t{\n\t\tname: \"bashMissingCommandWord\",\n\t\tphase: \"execution\",\n\t\tguidance:\n\t\t\t\"The shell command was malformed (missing command word). Check for empty pipeline elements or incorrect string quoting before retrying.\",\n\t\tmatches(message: string): boolean {\n\t\t\treturn /Missing command: a pipeline\\/list element has no command word/i.test(message);\n\t\t},\n\t},\n\t{\n\t\tname: \"bashEmptyRedirectTarget\",\n\t\tphase: \"execution\",\n\t\tguidance: \"The shell redirect target was empty; provide a valid file path for the redirect before retrying.\",\n\t\tmatches(message: string): boolean {\n\t\t\treturn /redirect target expanded to nothing/i.test(message);\n\t\t},\n\t},\n\t{\n\t\tname: \"encodingCorruption\",\n\t\tphase: \"execution\",\n\t\tfailureCode: \"encoding_corruption\",\n\t\tattemptMemory: \"discard\",\n\t\tguidance:\n\t\t\t\"Change approach: exact UTF-8 text replacement is unsafe for this file. Use an encoding-aware or byte-safe tool/workflow instead; do not replay the text edit.\",\n\t\tmatches(message: string): boolean {\n\t\t\treturn /\\bPI_FILE_ENCODING_CORRUPTION\\b/i.test(message);\n\t\t},\n\t},\n\t{\n\t\tname: \"repeatedSuccessfulCall\",\n\t\tphase: \"execution\",\n\t\tfailureCode: REPEATED_SUCCESSFUL_TOOL_CALL_FAILURE.failureCode,\n\t\tattemptMemory: \"discard\",\n\t\tretainDiagnostic: true,\n\t\tguidance: REPEATED_SUCCESSFUL_TOOL_CALL_FAILURE.guidance,\n\t\tmatches(message: string): boolean {\n\t\t\treturn message === REPEATED_SUCCESSFUL_TOOL_CALL_FAILURE.diagnostic;\n\t\t},\n\t},\n\t{\n\t\tname: \"fileMutationRetarget\",\n\t\tphase: \"execution\",\n\t\tfailureCode: \"mutation_retarget_required\",\n\t\tattemptMemory: \"discard\",\n\t\tretainDiagnostic: true,\n\t\tguidance:\n\t\t\t\"The mutation payload is already retained by the harness. Choose only the corrected target path and reuse the exact payloadRef from the diagnostic; do not regenerate content or edits.\",\n\t\tmatches(message: string): boolean {\n\t\t\treturn /\\bPI_FILE_MUTATION_RETARGET\\b/i.test(message);\n\t\t},\n\t},\n\t{\n\t\tname: \"fileNotFound\",\n\t\tphase: \"execution\",\n\t\tfailureCode: \"file_not_found\",\n\t\tguidance: \"Path was not found; list the parent directory or re-read the path before retrying.\",\n\t\tmatches(message: string): boolean {\n\t\t\treturn (\n\t\t\t\t/\\bENOENT\\b/i.test(message) ||\n\t\t\t\t/no such file or directory/i.test(message) ||\n\t\t\t\t/\\b(?:file|path) not found\\b/i.test(message)\n\t\t\t);\n\t\t},\n\t},\n\t{\n\t\tname: \"editOldTextNotFound\",\n\t\tphase: \"execution\",\n\t\tfailureCode: \"edit_old_text_not_found\",\n\t\tguidance: \"Re-read the target file and use the exact current text before retrying.\",\n\t\tmatches(message: string): boolean {\n\t\t\treturn /(?:oldText|old text|exact text).*(?:not found|no match|failed to match|must match)/is.test(message);\n\t\t},\n\t},\n\t{\n\t\tname: \"pathOutsideCwd\",\n\t\tphase: \"policy\",\n\t\tguidance: \"Choose a path inside the current working directory, or ask before changing scope.\",\n\t\tmatches(message: string): boolean {\n\t\t\treturn /outside (?:the )?(?:current working directory|cwd|workspace|root)/i.test(message);\n\t\t},\n\t},\n\t{\n\t\tname: \"permissionDenied\",\n\t\tphase: \"policy\",\n\t\tfailureCode: \"permission_denied\",\n\t\tretainDiagnostic: true,\n\t\tguidance:\n\t\t\t\"Access was denied; verify the target path and current authority, then request or change permissions before retrying.\",\n\t\tmatches(message: string): boolean {\n\t\t\treturn /\\b(?:EACCES|EPERM)\\b/i.test(message) || /(?:permission|access) (?:is )?denied/i.test(message);\n\t\t},\n\t},\n\t{\n\t\tname: \"invalidOption\",\n\t\tphase: \"execution\",\n\t\tfailureCode: \"invalid_option\",\n\t\tretainDiagnostic: true,\n\t\tguidance: \"Option rejected; re-read command help and remove or replace it before retrying.\",\n\t\tmatches(message: string): boolean {\n\t\t\treturn /\\b(?:invalid|unknown|unrecognized) (?:command-line )?(?:option|argument)\\b/i.test(message);\n\t\t},\n\t},\n\t{\n\t\tname: \"invalidPattern\",\n\t\tphase: \"execution\",\n\t\tfailureCode: \"invalid_pattern\",\n\t\tretainDiagnostic: true,\n\t\tguidance: \"The search pattern was invalid; simplify it or correct its regex/glob escaping before retrying.\",\n\t\tmatches(message: string): boolean {\n\t\t\treturn (\n\t\t\t\t/(?:regex|regular expression|glob) (?:parse )?error\\b/i.test(message) ||\n\t\t\t\t/\\bunclosed (?:group|class)\\b/i.test(message)\n\t\t\t);\n\t\t},\n\t},\n\t{\n\t\tname: \"outputLimit\",\n\t\tphase: \"execution\",\n\t\tfailureCode: \"output_limit\",\n\t\tguidance:\n\t\t\t\"Output exceeded its bound; narrow the scope, page the request, or use the retained artifact before retrying.\",\n\t\tmatches(message: string): boolean {\n\t\t\treturn /\\b(?:output|result|response).*(?:limit|truncat|too large)\\b/i.test(message);\n\t\t},\n\t},\n\t{\n\t\tname: \"timedOut\",\n\t\tphase: \"timeout\",\n\t\tfailureCode: \"timeout\",\n\t\tunchangedRetryLimit: 1,\n\t\tguidance:\n\t\t\t\"The operation timed out; narrow or split the work, then retry once only when repeating it is safe and still required.\",\n\t\tmatches(message: string): boolean {\n\t\t\treturn (\n\t\t\t\t/\\b(?:command|operation|process|request|tool)\\s+(?:timed out|timeout(?: after)?)\\b/i.test(message) ||\n\t\t\t\t/\\bETIMEDOUT\\b/i.test(message)\n\t\t\t);\n\t\t},\n\t},\n\t{\n\t\tname: \"cancelled\",\n\t\tphase: \"cancelled\",\n\t\tfailureCode: \"cancelled\",\n\t\tguidance:\n\t\t\t\"The operation was cancelled; retry only if it is still required and the cancellation condition has cleared.\",\n\t\tmatches(message: string): boolean {\n\t\t\treturn (\n\t\t\t\t/^(?:operation|request|tool) (?:was )?(?:aborted|cancelled|canceled)\\b/i.test(message) ||\n\t\t\t\t/\\bAbortError\\b/i.test(message)\n\t\t\t);\n\t\t},\n\t},\n] as const satisfies readonly ToolExecutionErrorCatalogueEntry[];\n\nexport type ToolExecutionErrorClass = (typeof TOOL_EXECUTION_ERROR_CATALOGUE)[number][\"name\"];\nconst executionErrorCatalogue: readonly ToolExecutionErrorCatalogueEntry[] = TOOL_EXECUTION_ERROR_CATALOGUE;\n\nexport interface ToolExecutionErrorPolicy {\n\tname: ToolExecutionErrorClass;\n\tphase: ToolFailurePhase;\n\tguidance: string;\n\tfailureCode?: string;\n\tattemptMemory: ToolExecutionAttemptMemory;\n\tretainDiagnostic: boolean;\n\tunchangedRetryLimit: number;\n}\n\nexport function getToolExecutionErrorPolicy(errorMessage: string): ToolExecutionErrorPolicy | undefined {\n\tconst entry = executionErrorCatalogue.find((candidate) => candidate.matches(errorMessage));\n\tif (!entry) return undefined;\n\treturn {\n\t\tname: entry.name as ToolExecutionErrorClass,\n\t\tphase: entry.phase,\n\t\tguidance: entry.guidance,\n\t\t...(entry.failureCode ? { failureCode: entry.failureCode } : {}),\n\t\tattemptMemory: entry.attemptMemory ?? \"retain\",\n\t\tretainDiagnostic: entry.retainDiagnostic ?? false,\n\t\tunchangedRetryLimit: entry.unchangedRetryLimit ?? 0,\n\t};\n}\n\nexport function getToolExecutionAttemptMemory(failureCode: string): ToolExecutionAttemptMemory {\n\tconst entry = executionErrorCatalogue.find((candidate) => candidate.failureCode === failureCode);\n\treturn entry?.attemptMemory ?? \"retain\";\n}\n\nexport function getToolExecutionUnchangedRetryLimit(failureCode: string): number {\n\tconst entry = executionErrorCatalogue.find((candidate) => candidate.failureCode === failureCode);\n\treturn entry?.unchangedRetryLimit ?? 0;\n}\n\nexport function getToolExecutionErrorGuidance(errorMessage: string): string | undefined {\n\treturn getToolExecutionErrorPolicy(errorMessage)?.guidance;\n}\n"]}
1
+ {"version":3,"file":"registry.js","sourceRoot":"","sources":["../../../src/utils/tool-repair/registry.ts"],"names":[],"mappings":"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","sourcesContent":["export const TOOL_REPAIR_MODE_NAMES = [\n\t\"nullOptionalDrop\",\n\t\"nullRequiredBounce\",\n\t\"jsonStringParse\",\n\t\"jsonObjectPropertySalvage\",\n\t\"singleObjectWrap\",\n\t\"bareScalarWrap\",\n\t\"emptyObjectPlaceholder\",\n\t\"numberFromString\",\n\t\"boolFromString\",\n\t\"enumCaseNormalize\",\n\t\"propertyCaseNormalize\",\n\t\"singleElementUnwrap\",\n\t\"stringifiedNumberInArray\",\n\t\"bashCommandArgvJoin\",\n\t\"bashCommandUnwrap\",\n] as const;\n\nexport type ToolRepairModeName = (typeof TOOL_REPAIR_MODE_NAMES)[number];\nexport type ToolRepairFailureModeName = ToolRepairModeName | \"other\";\n\nexport interface ToolRepairRegistryEntry {\n\tname: ToolRepairModeName;\n\tnoteTemplate: string;\n\tstandingRule: string;\n}\n\nexport const TOOL_REPAIR_REGISTRY: readonly ToolRepairRegistryEntry[] = [\n\t{\n\t\tname: \"nullOptionalDrop\",\n\t\tnoteTemplate: \"optional `{path}` was null; omit field\",\n\t\tstandingRule: \"Optional field: omit, never null.\",\n\t},\n\t{\n\t\tname: \"nullRequiredBounce\",\n\t\tnoteTemplate: \"required `{path}` was null; send real value\",\n\t\tstandingRule: \"Required field: real value, never null.\",\n\t},\n\t{\n\t\tname: \"jsonStringParse\",\n\t\tnoteTemplate: \"`{path}` was quoted JSON; send raw array/object\",\n\t\tstandingRule: \"Schema array/object: raw JSON, never quoted JSON string.\",\n\t},\n\t{\n\t\tname: \"jsonObjectPropertySalvage\",\n\t\tnoteTemplate: \"`{path}` was malformed JSON; retained declared properties\",\n\t\tstandingRule: \"JSON object: strict syntax, commas between properties, no extra inner text.\",\n\t},\n\t{\n\t\tname: \"singleObjectWrap\",\n\t\tnoteTemplate: \"`{path}` needs list; wrap object in [ ]\",\n\t\tstandingRule: \"List schema: wrap one object in [ ].\",\n\t},\n\t{\n\t\tname: \"bareScalarWrap\",\n\t\tnoteTemplate: \"`{path}` needs list; wrap scalar in [ ]\",\n\t\tstandingRule: \"List schema: wrap one scalar in [ ].\",\n\t},\n\t{\n\t\tname: \"emptyObjectPlaceholder\",\n\t\tnoteTemplate: \"`{path}` was `{}` placeholder; omit for default\",\n\t\tstandingRule: \"Defaulted object field: omit, never `{}` placeholder.\",\n\t},\n\t{\n\t\tname: \"numberFromString\",\n\t\tnoteTemplate: \"`{path}` was quoted number; send bare number\",\n\t\tstandingRule: \"Number schema: bare number, never quoted.\",\n\t},\n\t{\n\t\tname: \"boolFromString\",\n\t\tnoteTemplate: \"`{path}` was quoted boolean; send bare true/false\",\n\t\tstandingRule: \"Boolean schema: bare true/false, never quoted.\",\n\t},\n\t{\n\t\tname: \"enumCaseNormalize\",\n\t\tnoteTemplate: \"`{path}` normalized to declared enum case/spacing\",\n\t\tstandingRule: \"Enum value: exact declared case/spacing.\",\n\t},\n\t{\n\t\tname: \"propertyCaseNormalize\",\n\t\tnoteTemplate: \"`{path}` used wrong key case; use schema case\",\n\t\tstandingRule: \"Argument property: exact schema name/case.\",\n\t},\n\t{\n\t\tname: \"singleElementUnwrap\",\n\t\tnoteTemplate: \"`{path}` needs scalar; unwrap 1-item list\",\n\t\tstandingRule: \"Scalar schema: direct value, never 1-item list.\",\n\t},\n\t{\n\t\tname: \"stringifiedNumberInArray\",\n\t\tnoteTemplate: \"number list `{path}` held quoted values; send bare numbers\",\n\t\tstandingRule: \"Number array: bare numbers, never quoted.\",\n\t},\n\t{\n\t\tname: \"bashCommandArgvJoin\",\n\t\tnoteTemplate: \"bash needs one command string; joined argv values\",\n\t\tstandingRule: \"bash command: one string, never argv array.\",\n\t},\n\t{\n\t\tname: \"bashCommandUnwrap\",\n\t\tnoteTemplate: \"bash `command` needs string; unwrapped object\",\n\t\tstandingRule: \"bash `command`: string, never object wrapper.\",\n\t},\n] as const;\n\nconst registryByName = new Map(TOOL_REPAIR_REGISTRY.map((entry) => [entry.name, entry]));\n\nexport function getToolRepairRegistryEntry(name: ToolRepairModeName): ToolRepairRegistryEntry {\n\tconst entry = registryByName.get(name);\n\tif (!entry) throw new Error(`Unknown tool repair mode: ${name}`);\n\treturn entry;\n}\n\nexport function formatToolRepairNote(name: ToolRepairModeName, path: string): string {\n\treturn getToolRepairRegistryEntry(name).noteTemplate.replaceAll(\"{path}\", path);\n}\n\nexport function formatToolRepairStandingRule(name: ToolRepairModeName): string {\n\treturn getToolRepairRegistryEntry(name).standingRule;\n}\n\nexport type ToolExecutionAttemptMemory = \"retain\" | \"discard\";\nexport type ToolFailurePhase =\n\t| \"validation\"\n\t| \"policy\"\n\t| \"preflight\"\n\t| \"execution\"\n\t| \"timeout\"\n\t| \"cancelled\"\n\t| \"provisioning\";\n\nexport const REPEATED_SUCCESSFUL_TOOL_CALL_FAILURE = {\n\tfailureCode: \"repeated_successful_call\",\n\tdiagnostic: \"The identical phone tool call already succeeded and was not executed again.\",\n\tguidance:\n\t\t\"Use prior successful result; continue. Task complete: answer user. Otherwise call different required tool. Never retry unchanged.\",\n} as const;\n\ninterface ToolExecutionErrorCatalogueEntry {\n\tname: string;\n\tphase: ToolFailurePhase;\n\tguidance: string;\n\tfailureCode?: string;\n\tattemptMemory?: ToolExecutionAttemptMemory;\n\tretainDiagnostic?: boolean;\n\t/** Number of unchanged executions permitted after the first failure in one recovery window. */\n\tunchangedRetryLimit?: number;\n\tmatches(message: string): boolean;\n}\n\nexport const TOOL_EXECUTION_ERROR_CATALOGUE = [\n\t{\n\t\tname: \"provisioningFailed\",\n\t\tphase: \"provisioning\",\n\t\tfailureCode: \"provisioning_failed\",\n\t\tretainDiagnostic: true,\n\t\tguidance: \"Provisioning failed. Use exact diagnostic, fix cause; retry only after environment changes.\",\n\t\tmatches(message: string): boolean {\n\t\t\treturn /\\bPI_TOOL_PROVISIONING_FAILED\\b/i.test(message);\n\t\t},\n\t},\n\t{\n\t\tname: \"commandNotFound\",\n\t\tphase: \"provisioning\",\n\t\tguidance: \"Command not found. Check exact name/available tools before retry.\",\n\t\tmatches(message: string): boolean {\n\t\t\treturn /^spawn \\S+ ENOENT\\b/i.test(message) || /(?:^|\\n|:)\\s*command not found\\b/i.test(message);\n\t\t},\n\t},\n\t{\n\t\tname: \"bashNoOutput\",\n\t\tphase: \"execution\",\n\t\tguidance: \"Command failed without output. Verify syntax, exact command documentation before retry.\",\n\t\tmatches(message: string): boolean {\n\t\t\treturn message === \"(no output)\";\n\t\t},\n\t},\n\t{\n\t\tname: \"bashPosixNotSupported\",\n\t\tphase: \"execution\",\n\t\tguidance: \"Windows host rejects POSIX .sh scripts. Use PowerShell equivalent or invoke executable directly.\",\n\t\tmatches(message: string): boolean {\n\t\t\treturn /POSIX shell scripts are not supported by the Windows shell contract router/i.test(message);\n\t\t},\n\t},\n\t{\n\t\tname: \"bashNestedShell\",\n\t\tphase: \"execution\",\n\t\tguidance: \"Never wrap command in powershell.exe/pwsh. Invoke .ps1 or command directly.\",\n\t\tmatches(message: string): boolean {\n\t\t\treturn /Nested shell execution is not supported by the Windows shell contract router/i.test(message);\n\t\t},\n\t},\n\t{\n\t\tname: \"bashMissingCommandWord\",\n\t\tphase: \"execution\",\n\t\tguidance: \"Missing shell command word. Fix empty pipeline element or string quoting before retry.\",\n\t\tmatches(message: string): boolean {\n\t\t\treturn /Missing command: a pipeline\\/list element has no command word/i.test(message);\n\t\t},\n\t},\n\t{\n\t\tname: \"bashEmptyRedirectTarget\",\n\t\tphase: \"execution\",\n\t\tguidance: \"Empty redirect target. Supply valid file path before retry.\",\n\t\tmatches(message: string): boolean {\n\t\t\treturn /redirect target expanded to nothing/i.test(message);\n\t\t},\n\t},\n\t{\n\t\tname: \"encodingCorruption\",\n\t\tphase: \"execution\",\n\t\tfailureCode: \"encoding_corruption\",\n\t\tattemptMemory: \"discard\",\n\t\tguidance:\n\t\t\t\"Change approach: exact UTF-8 replacement unsafe. Use encoding-aware/byte-safe tool; never replay text edit.\",\n\t\tmatches(message: string): boolean {\n\t\t\treturn /\\bPI_FILE_ENCODING_CORRUPTION\\b/i.test(message);\n\t\t},\n\t},\n\t{\n\t\tname: \"repeatedSuccessfulCall\",\n\t\tphase: \"execution\",\n\t\tfailureCode: REPEATED_SUCCESSFUL_TOOL_CALL_FAILURE.failureCode,\n\t\tattemptMemory: \"discard\",\n\t\tretainDiagnostic: true,\n\t\tguidance: REPEATED_SUCCESSFUL_TOOL_CALL_FAILURE.guidance,\n\t\tmatches(message: string): boolean {\n\t\t\treturn message === REPEATED_SUCCESSFUL_TOOL_CALL_FAILURE.diagnostic;\n\t\t},\n\t},\n\t{\n\t\tname: \"fileMutationRetarget\",\n\t\tphase: \"execution\",\n\t\tfailureCode: \"mutation_retarget_required\",\n\t\tattemptMemory: \"discard\",\n\t\tretainDiagnostic: true,\n\t\tguidance:\n\t\t\t\"Harness retained mutation. Choose corrected target path, reuse exact diagnostic payloadRef; never regenerate content/edits.\",\n\t\tmatches(message: string): boolean {\n\t\t\treturn /\\bPI_FILE_MUTATION_RETARGET\\b/i.test(message);\n\t\t},\n\t},\n\t{\n\t\tname: \"fileNotFound\",\n\t\tphase: \"execution\",\n\t\tfailureCode: \"file_not_found\",\n\t\tguidance: \"Path not found. List parent directory or re-read path before retry.\",\n\t\tmatches(message: string): boolean {\n\t\t\treturn (\n\t\t\t\t/\\bENOENT\\b/i.test(message) ||\n\t\t\t\t/no such file or directory/i.test(message) ||\n\t\t\t\t/\\b(?:file|path) not found\\b/i.test(message)\n\t\t\t);\n\t\t},\n\t},\n\t{\n\t\tname: \"editOldTextNotFound\",\n\t\tphase: \"execution\",\n\t\tfailureCode: \"edit_old_text_not_found\",\n\t\tguidance: \"Re-read target; use exact current text before retry.\",\n\t\tmatches(message: string): boolean {\n\t\t\treturn /(?:oldText|old text|exact text).*(?:not found|no match|failed to match|must match)/is.test(message);\n\t\t},\n\t},\n\t{\n\t\tname: \"pathOutsideCwd\",\n\t\tphase: \"policy\",\n\t\tguidance: \"Choose path inside current working directory; ask before scope change.\",\n\t\tmatches(message: string): boolean {\n\t\t\treturn /outside (?:the )?(?:current working directory|cwd|workspace|root)/i.test(message);\n\t\t},\n\t},\n\t{\n\t\tname: \"permissionDenied\",\n\t\tphase: \"policy\",\n\t\tfailureCode: \"permission_denied\",\n\t\tretainDiagnostic: true,\n\t\tguidance: \"Access denied. Verify target/current authority; obtain permissions before retry.\",\n\t\tmatches(message: string): boolean {\n\t\t\treturn /\\b(?:EACCES|EPERM)\\b/i.test(message) || /(?:permission|access) (?:is )?denied/i.test(message);\n\t\t},\n\t},\n\t{\n\t\tname: \"invalidOption\",\n\t\tphase: \"execution\",\n\t\tfailureCode: \"invalid_option\",\n\t\tretainDiagnostic: true,\n\t\tguidance: \"Option rejected. Read command help; remove/replace option before retry.\",\n\t\tmatches(message: string): boolean {\n\t\t\treturn /\\b(?:invalid|unknown|unrecognized) (?:command-line )?(?:option|argument)\\b/i.test(message);\n\t\t},\n\t},\n\t{\n\t\tname: \"invalidPattern\",\n\t\tphase: \"execution\",\n\t\tfailureCode: \"invalid_pattern\",\n\t\tretainDiagnostic: true,\n\t\tguidance: \"Invalid search pattern. Simplify or fix regex/glob escaping before retry.\",\n\t\tmatches(message: string): boolean {\n\t\t\treturn (\n\t\t\t\t/(?:regex|regular expression|glob) (?:parse )?error\\b/i.test(message) ||\n\t\t\t\t/\\bunclosed (?:group|class)\\b/i.test(message)\n\t\t\t);\n\t\t},\n\t},\n\t{\n\t\tname: \"outputLimit\",\n\t\tphase: \"execution\",\n\t\tfailureCode: \"output_limit\",\n\t\tguidance: \"Output exceeded bound. Narrow scope, page request, or use retained artifact before retry.\",\n\t\tmatches(message: string): boolean {\n\t\t\treturn /\\b(?:output|result|response).*(?:limit|truncat|too large)\\b/i.test(message);\n\t\t},\n\t},\n\t{\n\t\tname: \"timedOut\",\n\t\tphase: \"timeout\",\n\t\tfailureCode: \"timeout\",\n\t\tunchangedRetryLimit: 1,\n\t\tguidance: \"Operation timed out. Narrow/split work; one unchanged retry only when safe, still required.\",\n\t\tmatches(message: string): boolean {\n\t\t\treturn (\n\t\t\t\t/\\b(?:command|operation|process|request|tool)\\s+(?:timed out|timeout(?: after)?)\\b/i.test(message) ||\n\t\t\t\t/\\bETIMEDOUT\\b/i.test(message)\n\t\t\t);\n\t\t},\n\t},\n\t{\n\t\tname: \"cancelled\",\n\t\tphase: \"cancelled\",\n\t\tfailureCode: \"cancelled\",\n\t\tguidance: \"Operation cancelled. Retry only when still required, cancellation condition cleared.\",\n\t\tmatches(message: string): boolean {\n\t\t\treturn (\n\t\t\t\t/^(?:operation|request|tool) (?:was )?(?:aborted|cancelled|canceled)\\b/i.test(message) ||\n\t\t\t\t/\\bAbortError\\b/i.test(message)\n\t\t\t);\n\t\t},\n\t},\n] as const satisfies readonly ToolExecutionErrorCatalogueEntry[];\n\nexport type ToolExecutionErrorClass = (typeof TOOL_EXECUTION_ERROR_CATALOGUE)[number][\"name\"];\nconst executionErrorCatalogue: readonly ToolExecutionErrorCatalogueEntry[] = TOOL_EXECUTION_ERROR_CATALOGUE;\n\nexport interface ToolExecutionErrorPolicy {\n\tname: ToolExecutionErrorClass;\n\tphase: ToolFailurePhase;\n\tguidance: string;\n\tfailureCode?: string;\n\tattemptMemory: ToolExecutionAttemptMemory;\n\tretainDiagnostic: boolean;\n\tunchangedRetryLimit: number;\n}\n\nexport function getToolExecutionErrorPolicy(errorMessage: string): ToolExecutionErrorPolicy | undefined {\n\tconst entry = executionErrorCatalogue.find((candidate) => candidate.matches(errorMessage));\n\tif (!entry) return undefined;\n\treturn {\n\t\tname: entry.name as ToolExecutionErrorClass,\n\t\tphase: entry.phase,\n\t\tguidance: entry.guidance,\n\t\t...(entry.failureCode ? { failureCode: entry.failureCode } : {}),\n\t\tattemptMemory: entry.attemptMemory ?? \"retain\",\n\t\tretainDiagnostic: entry.retainDiagnostic ?? false,\n\t\tunchangedRetryLimit: entry.unchangedRetryLimit ?? 0,\n\t};\n}\n\nexport function getToolExecutionAttemptMemory(failureCode: string): ToolExecutionAttemptMemory {\n\tconst entry = executionErrorCatalogue.find((candidate) => candidate.failureCode === failureCode);\n\treturn entry?.attemptMemory ?? \"retain\";\n}\n\nexport function getToolExecutionUnchangedRetryLimit(failureCode: string): number {\n\tconst entry = executionErrorCatalogue.find((candidate) => candidate.failureCode === failureCode);\n\treturn entry?.unchangedRetryLimit ?? 0;\n}\n\nexport function getToolExecutionErrorGuidance(errorMessage: string): string | undefined {\n\treturn getToolExecutionErrorPolicy(errorMessage)?.guidance;\n}\n"]}
@@ -19,7 +19,7 @@ export function renderTextProtocolToolResult(toolResult) {
19
19
  const text = joinTextContent(toolResult.content);
20
20
  const result = text.length > 0 ? text : "(see attached image)";
21
21
  return toolResult.isError
22
- ? `Tool result (${toolResult.toolName}; failed):\n${result}\nFollow the repair or next_action before retrying; do not resend the unchanged call.`
23
- : `Tool result (${toolResult.toolName}; succeeded):\n${result}\nUse this result and continue. Do not repeat this unchanged successful call.`;
22
+ ? `TOOL ${toolResult.toolName} FAILED\n${result}\nDo repair/next_action before retry; never resend unchanged.`
23
+ : `TOOL ${toolResult.toolName} OK\n${result}\nUse result; continue. Never repeat unchanged call.`;
24
24
  }
25
25
  //# sourceMappingURL=text-protocol-history.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"text-protocol-history.js","sourceRoot":"","sources":["../../../src/utils/tool-repair/text-protocol-history.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AAExE,OAAO,EAAE,qBAAqB,EAAgC,MAAM,oBAAoB,CAAC;AAEzF;;;;;;GAMG;AACH,MAAM,UAAU,+BAA+B,CAAC,QAAkB,EAAE,OAAgC;IACnG,OAAO,qBAAqB,CAAC,OAAO,EAAE,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,CAAC;AAChG,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,4BAA4B,CAAC,UAA6B;IACzE,MAAM,IAAI,GAAG,eAAe,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IACjD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,sBAAsB,CAAC;IAC/D,OAAO,UAAU,CAAC,OAAO;QACxB,CAAC,CAAC,gBAAgB,UAAU,CAAC,QAAQ,eAAe,MAAM,uFAAuF;QACjJ,CAAC,CAAC,gBAAgB,UAAU,CAAC,QAAQ,kBAAkB,MAAM,+EAA+E,CAAC;AAC/I,CAAC","sourcesContent":["import { joinTextContent } from \"../../providers/transform-messages.ts\";\nimport type { ToolCall, ToolResultMessage } from \"../../types.ts\";\nimport { formatVariantEnvelope, type TextToolProtocolVariant } from \"./text-protocol.ts\";\n\n/**\n * Renders a prior text-protocol tool call as the assistant-visible history text, in the exact\n * dialect `variant` teaches (reusing {@link formatVariantEnvelope} so a phone model sees its own\n * call echoed back exactly as the primer taught it to speak - the round-trip invariant this\n * module is gated on: `parseTextToolCalls(renderTextProtocolAssistantCall(call, variant), tools)`\n * must recover the SAME name+arguments).\n */\nexport function renderTextProtocolAssistantCall(toolCall: ToolCall, variant: TextToolProtocolVariant): string {\n\treturn formatVariantEnvelope(variant, toolCall.name, JSON.stringify(toolCall.arguments ?? {}));\n}\n\n/**\n * Renders a tool result as plain text a text-protocol (phone) model reads as a user turn. The\n * protocol has no `tool_call_id`; the caller places this immediately after the echoed call it\n * answers (§2.3: conversation ORDER + tool name is the only linkage a phone model has).\n */\nexport function renderTextProtocolToolResult(toolResult: ToolResultMessage): string {\n\tconst text = joinTextContent(toolResult.content);\n\tconst result = text.length > 0 ? text : \"(see attached image)\";\n\treturn toolResult.isError\n\t\t? `Tool result (${toolResult.toolName}; failed):\\n${result}\\nFollow the repair or next_action before retrying; do not resend the unchanged call.`\n\t\t: `Tool result (${toolResult.toolName}; succeeded):\\n${result}\\nUse this result and continue. Do not repeat this unchanged successful call.`;\n}\n"]}
1
+ {"version":3,"file":"text-protocol-history.js","sourceRoot":"","sources":["../../../src/utils/tool-repair/text-protocol-history.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,uCAAuC,CAAC;AAExE,OAAO,EAAE,qBAAqB,EAAgC,MAAM,oBAAoB,CAAC;AAEzF;;;;;;GAMG;AACH,MAAM,UAAU,+BAA+B,CAAC,QAAkB,EAAE,OAAgC;IACnG,OAAO,qBAAqB,CAAC,OAAO,EAAE,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,CAAC;AAChG,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,4BAA4B,CAAC,UAA6B;IACzE,MAAM,IAAI,GAAG,eAAe,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;IACjD,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,sBAAsB,CAAC;IAC/D,OAAO,UAAU,CAAC,OAAO;QACxB,CAAC,CAAC,QAAQ,UAAU,CAAC,QAAQ,YAAY,MAAM,+DAA+D;QAC9G,CAAC,CAAC,QAAQ,UAAU,CAAC,QAAQ,QAAQ,MAAM,sDAAsD,CAAC;AACpG,CAAC","sourcesContent":["import { joinTextContent } from \"../../providers/transform-messages.ts\";\nimport type { ToolCall, ToolResultMessage } from \"../../types.ts\";\nimport { formatVariantEnvelope, type TextToolProtocolVariant } from \"./text-protocol.ts\";\n\n/**\n * Renders a prior text-protocol tool call as the assistant-visible history text, in the exact\n * dialect `variant` teaches (reusing {@link formatVariantEnvelope} so a phone model sees its own\n * call echoed back exactly as the primer taught it to speak - the round-trip invariant this\n * module is gated on: `parseTextToolCalls(renderTextProtocolAssistantCall(call, variant), tools)`\n * must recover the SAME name+arguments).\n */\nexport function renderTextProtocolAssistantCall(toolCall: ToolCall, variant: TextToolProtocolVariant): string {\n\treturn formatVariantEnvelope(variant, toolCall.name, JSON.stringify(toolCall.arguments ?? {}));\n}\n\n/**\n * Renders a tool result as plain text a text-protocol (phone) model reads as a user turn. The\n * protocol has no `tool_call_id`; the caller places this immediately after the echoed call it\n * answers (§2.3: conversation ORDER + tool name is the only linkage a phone model has).\n */\nexport function renderTextProtocolToolResult(toolResult: ToolResultMessage): string {\n\tconst text = joinTextContent(toolResult.content);\n\tconst result = text.length > 0 ? text : \"(see attached image)\";\n\treturn toolResult.isError\n\t\t? `TOOL ${toolResult.toolName} FAILED\\n${result}\\nDo repair/next_action before retry; never resend unchanged.`\n\t\t: `TOOL ${toolResult.toolName} OK\\n${result}\\nUse result; continue. Never repeat unchanged call.`;\n}\n"]}
@@ -546,13 +546,13 @@ function exampleTools(tools) {
546
546
  }
547
547
  function protocolHeader(variant) {
548
548
  return [
549
- "Text tool-call protocol is enabled. To call a tool, emit an envelope in exactly this shape:",
549
+ "Text tool-call protocol is enabled. Call tools only with this exact envelope:",
550
550
  formatVariantEnvelope(variant, "TOOL", '{"arg":"value"}'),
551
- "Arguments are one JSON object: double-quoted keys/strings, arrays as [ ] (never a quoted string), optional args omitted rather than null.",
552
- "Reasoning may appear as prose before an envelope, never inside one.",
553
- "Emit several envelopes in one reply to call multiple tools in parallel; each is executed and answered on its own.",
554
- "After a successful tool result, use it and continue; do not repeat the same unchanged call.",
555
- "Files, directories, searches, edits, writes, and shell commands always go through a tool envelope - never type out shell commands, file paths, or invented results yourself.",
551
+ "Arguments: one JSON object; quote keys/strings; arrays [ ] never quoted; omit optional args, never null.",
552
+ "Reasoning before envelope only.",
553
+ "Parallel: multiple envelopes/reply; each runs, returns independently.",
554
+ "Success: use result; do not repeat unchanged successful calls.",
555
+ "File-read request: first reply one read call only, never guess. All file/directory/search/edit/write/shell work uses envelopes; never substitute prose commands/paths/invented results.",
556
556
  ];
557
557
  }
558
558
  export function generateTextToolProtocolPrimer(tools, options) {