@vedangiitb/qwintly-core 1.4.12 → 1.4.13

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.
Files changed (142) hide show
  1. package/dist/ai/generate/gemini.client.js +1 -1
  2. package/dist/ai/generate/gemini.client.js.map +1 -1
  3. package/dist/ai/generate/generateClient.d.ts.map +1 -1
  4. package/dist/ai/generate/generateClient.js +7 -3
  5. package/dist/ai/generate/generateClient.js.map +1 -1
  6. package/dist/ai/toolLoop/helpers/aiCall.helper.d.ts +16 -0
  7. package/dist/ai/toolLoop/helpers/aiCall.helper.d.ts.map +1 -0
  8. package/dist/ai/toolLoop/helpers/aiCall.helper.js +23 -0
  9. package/dist/ai/toolLoop/helpers/aiCall.helper.js.map +1 -0
  10. package/dist/ai/toolLoop/helpers/applyPatch.helper.d.ts +6 -0
  11. package/dist/ai/toolLoop/helpers/applyPatch.helper.d.ts.map +1 -0
  12. package/dist/ai/toolLoop/helpers/applyPatch.helper.js +10 -0
  13. package/dist/ai/toolLoop/helpers/applyPatch.helper.js.map +1 -0
  14. package/dist/ai/toolLoop/helpers/errors.helper.d.ts +15 -0
  15. package/dist/ai/toolLoop/helpers/errors.helper.d.ts.map +1 -0
  16. package/dist/ai/toolLoop/helpers/errors.helper.js +50 -0
  17. package/dist/ai/toolLoop/helpers/errors.helper.js.map +1 -0
  18. package/dist/ai/toolLoop/helpers/fsHelpers.d.ts +5 -0
  19. package/dist/ai/toolLoop/helpers/fsHelpers.d.ts.map +1 -0
  20. package/dist/ai/toolLoop/helpers/fsHelpers.js +28 -0
  21. package/dist/ai/toolLoop/helpers/fsHelpers.js.map +1 -0
  22. package/dist/ai/toolLoop/helpers/patchRetry.helper.d.ts +11 -0
  23. package/dist/ai/toolLoop/helpers/patchRetry.helper.d.ts.map +1 -0
  24. package/dist/ai/toolLoop/helpers/patchRetry.helper.js +30 -0
  25. package/dist/ai/toolLoop/helpers/patchRetry.helper.js.map +1 -0
  26. package/dist/ai/toolLoop/helpers/persistTokens.helpers.d.ts +7 -0
  27. package/dist/ai/toolLoop/helpers/persistTokens.helpers.d.ts.map +1 -0
  28. package/dist/ai/toolLoop/helpers/persistTokens.helpers.js +25 -0
  29. package/dist/ai/toolLoop/helpers/persistTokens.helpers.js.map +1 -0
  30. package/dist/ai/toolLoop/{plannerTaskParser.d.ts → helpers/plannerTaskParser.d.ts} +1 -1
  31. package/dist/ai/toolLoop/helpers/plannerTaskParser.d.ts.map +1 -0
  32. package/dist/ai/toolLoop/helpers/plannerTaskParser.js.map +1 -0
  33. package/dist/ai/toolLoop/helpers/readFile.helpers.d.ts +10 -0
  34. package/dist/ai/toolLoop/helpers/readFile.helpers.d.ts.map +1 -0
  35. package/dist/ai/toolLoop/helpers/readFile.helpers.js +26 -0
  36. package/dist/ai/toolLoop/helpers/readFile.helpers.js.map +1 -0
  37. package/dist/ai/toolLoop/helpers/signatures.helper.d.ts +2 -0
  38. package/dist/ai/toolLoop/helpers/signatures.helper.d.ts.map +1 -0
  39. package/dist/ai/toolLoop/helpers/signatures.helper.js +23 -0
  40. package/dist/ai/toolLoop/helpers/signatures.helper.js.map +1 -0
  41. package/dist/ai/toolLoop/helpers/toolArgs.helper.d.ts +12 -0
  42. package/dist/ai/toolLoop/helpers/toolArgs.helper.d.ts.map +1 -0
  43. package/dist/ai/toolLoop/helpers/toolArgs.helper.js +40 -0
  44. package/dist/ai/toolLoop/helpers/toolArgs.helper.js.map +1 -0
  45. package/dist/ai/toolLoop/helpers/toolExecution.helper.d.ts +22 -0
  46. package/dist/ai/toolLoop/helpers/toolExecution.helper.d.ts.map +1 -0
  47. package/dist/ai/toolLoop/helpers/toolExecution.helper.js +75 -0
  48. package/dist/ai/toolLoop/helpers/toolExecution.helper.js.map +1 -0
  49. package/dist/ai/toolLoop/helpers/toolHandlers.helper.d.ts +6 -0
  50. package/dist/ai/toolLoop/helpers/toolHandlers.helper.d.ts.map +1 -0
  51. package/dist/ai/toolLoop/helpers/toolHandlers.helper.js +86 -0
  52. package/dist/ai/toolLoop/helpers/toolHandlers.helper.js.map +1 -0
  53. package/dist/ai/toolLoop/toolEventSummary.d.ts +28 -0
  54. package/dist/ai/toolLoop/toolEventSummary.d.ts.map +1 -0
  55. package/dist/ai/toolLoop/toolEventSummary.js +253 -0
  56. package/dist/ai/toolLoop/toolEventSummary.js.map +1 -0
  57. package/dist/ai/toolLoop/toolLoopContext.d.ts +0 -14
  58. package/dist/ai/toolLoop/toolLoopContext.d.ts.map +1 -1
  59. package/dist/ai/toolLoop/toolLoopContext.js +7 -50
  60. package/dist/ai/toolLoop/toolLoopContext.js.map +1 -1
  61. package/dist/ai/toolLoop/toolLoopRunner.d.ts +6 -5
  62. package/dist/ai/toolLoop/toolLoopRunner.d.ts.map +1 -1
  63. package/dist/ai/toolLoop/toolLoopRunner.js +48 -281
  64. package/dist/ai/toolLoop/toolLoopRunner.js.map +1 -1
  65. package/dist/ai/toolLoop/toolStatusMessage.d.ts +6 -0
  66. package/dist/ai/toolLoop/toolStatusMessage.d.ts.map +1 -0
  67. package/dist/ai/toolLoop/toolStatusMessage.js +140 -0
  68. package/dist/ai/toolLoop/toolStatusMessage.js.map +1 -0
  69. package/dist/ai/tools/helpers/applyPatch.helpers.d.ts.map +1 -1
  70. package/dist/ai/tools/helpers/applyPatch.helpers.js +9 -4
  71. package/dist/ai/tools/helpers/applyPatch.helpers.js.map +1 -1
  72. package/dist/ai/tools/helpers/fileSystem.helpers.d.ts.map +1 -1
  73. package/dist/ai/tools/helpers/fileSystem.helpers.js +7 -1
  74. package/dist/ai/tools/helpers/fileSystem.helpers.js.map +1 -1
  75. package/dist/ai/tools/helpers/pageConfigJson.helpers.d.ts +13 -0
  76. package/dist/ai/tools/helpers/pageConfigJson.helpers.d.ts.map +1 -1
  77. package/dist/ai/tools/helpers/pageConfigJson.helpers.js +51 -21
  78. package/dist/ai/tools/helpers/pageConfigJson.helpers.js.map +1 -1
  79. package/dist/ai/tools/implementations/applyPatch.impl.js +2 -2
  80. package/dist/ai/tools/implementations/applyPatch.impl.js.map +1 -1
  81. package/dist/ai/tools/implementations/createNewRoute.impl.js +1 -1
  82. package/dist/ai/tools/implementations/createNewRoute.impl.js.map +1 -1
  83. package/dist/ai/tools/implementations/deleteElement.impl.d.ts.map +1 -1
  84. package/dist/ai/tools/implementations/deleteElement.impl.js +5 -37
  85. package/dist/ai/tools/implementations/deleteElement.impl.js.map +1 -1
  86. package/dist/ai/tools/implementations/insertElement.impl.d.ts.map +1 -1
  87. package/dist/ai/tools/implementations/insertElement.impl.js +9 -46
  88. package/dist/ai/tools/implementations/insertElement.impl.js.map +1 -1
  89. package/dist/ai/tools/implementations/updateClassName.impl.d.ts.map +1 -1
  90. package/dist/ai/tools/implementations/updateClassName.impl.js +5 -37
  91. package/dist/ai/tools/implementations/updateClassName.impl.js.map +1 -1
  92. package/dist/ai/tools/implementations/updateGlobalStyles.impl.d.ts.map +1 -1
  93. package/dist/ai/tools/implementations/updateGlobalStyles.impl.js +4 -3
  94. package/dist/ai/tools/implementations/updateGlobalStyles.impl.js.map +1 -1
  95. package/dist/ai/tools/implementations/updateProps.impl.d.ts.map +1 -1
  96. package/dist/ai/tools/implementations/updateProps.impl.js +5 -37
  97. package/dist/ai/tools/implementations/updateProps.impl.js.map +1 -1
  98. package/dist/ai/tools/schemas/createNewRoute.schema.d.ts.map +1 -1
  99. package/dist/ai/tools/schemas/createNewRoute.schema.js +1 -1
  100. package/dist/ai/tools/schemas/createNewRoute.schema.js.map +1 -1
  101. package/dist/ai/tools/schemas/deleteElement.schema.d.ts.map +1 -1
  102. package/dist/ai/tools/schemas/deleteElement.schema.js +1 -2
  103. package/dist/ai/tools/schemas/deleteElement.schema.js.map +1 -1
  104. package/dist/ai/tools/schemas/elementProps.schema.d.ts +101 -0
  105. package/dist/ai/tools/schemas/elementProps.schema.d.ts.map +1 -0
  106. package/dist/ai/tools/schemas/elementProps.schema.js +74 -0
  107. package/dist/ai/tools/schemas/elementProps.schema.js.map +1 -0
  108. package/dist/ai/tools/schemas/insertElement.schema.d.ts.map +1 -1
  109. package/dist/ai/tools/schemas/insertElement.schema.js +2 -74
  110. package/dist/ai/tools/schemas/insertElement.schema.js.map +1 -1
  111. package/dist/ai/tools/schemas/updateClassName.schema.d.ts.map +1 -1
  112. package/dist/ai/tools/schemas/updateClassName.schema.js +1 -2
  113. package/dist/ai/tools/schemas/updateClassName.schema.js.map +1 -1
  114. package/dist/ai/tools/schemas/updateProps.schema.d.ts +9 -9
  115. package/dist/ai/tools/schemas/updateProps.schema.d.ts.map +1 -1
  116. package/dist/ai/tools/schemas/updateProps.schema.js +3 -69
  117. package/dist/ai/tools/schemas/updateProps.schema.js.map +1 -1
  118. package/dist/image/unsplash.service.d.ts.map +1 -1
  119. package/dist/image/unsplash.service.js +6 -2
  120. package/dist/image/unsplash.service.js.map +1 -1
  121. package/dist/indexer/projectInfoIndex.d.ts.map +1 -1
  122. package/dist/indexer/projectInfoIndex.js +33 -25
  123. package/dist/indexer/projectInfoIndex.js.map +1 -1
  124. package/dist/types/styleConfig.d.ts.map +1 -1
  125. package/dist/types/styleConfig.js +2 -3
  126. package/dist/types/styleConfig.js.map +1 -1
  127. package/dist/utils/utils.d.ts +3 -0
  128. package/dist/utils/utils.d.ts.map +1 -1
  129. package/dist/utils/utils.js +8 -0
  130. package/dist/utils/utils.js.map +1 -1
  131. package/dist/utils/workspace.d.ts +1 -1
  132. package/dist/utils/workspace.d.ts.map +1 -1
  133. package/dist/utils/workspace.js +6 -11
  134. package/dist/utils/workspace.js.map +1 -1
  135. package/package.json +1 -1
  136. package/dist/ai/toolLoop/plannerTaskParser.d.ts.map +0 -1
  137. package/dist/ai/toolLoop/plannerTaskParser.js.map +0 -1
  138. package/dist/ai/toolLoop/toolLoopRunnerUtils.d.ts +0 -51
  139. package/dist/ai/toolLoop/toolLoopRunnerUtils.d.ts.map +0 -1
  140. package/dist/ai/toolLoop/toolLoopRunnerUtils.js +0 -367
  141. package/dist/ai/toolLoop/toolLoopRunnerUtils.js.map +0 -1
  142. /package/dist/ai/toolLoop/{plannerTaskParser.js → helpers/plannerTaskParser.js} +0 -0
@@ -1,25 +1,10 @@
1
- import crypto from "node:crypto";
1
+ import { extractPatchFiles, sha256Hex } from "./helpers/fsHelpers.js";
2
2
  export const DEFAULT_CONTEXT_POLICY = {
3
3
  readFileDefaultMaxLines: 200,
4
4
  tailMessages: 8,
5
5
  maxModelChars: 120000,
6
6
  logApproxModelChars: false,
7
7
  };
8
- const sha256Hex = (value) => crypto.createHash("sha256").update(value, "utf8").digest("hex");
9
- const extractPatchFiles = (patchString) => {
10
- const lines = patchString.replace(/\r\n/g, "\n").split("\n");
11
- const files = new Set();
12
- for (const line of lines) {
13
- const match = /^\*\*\* (Update File|Add File|Delete File):\s+(.+)$/.exec(line) ??
14
- /^\*\*\* Move to:\s+(.+)$/.exec(line);
15
- if (!match)
16
- continue;
17
- const filePath = (match[2] ?? match[1] ?? "").trim();
18
- if (filePath)
19
- files.add(filePath);
20
- }
21
- return [...files];
22
- };
23
8
  export const redactFunctionCallArgs = (name, args) => {
24
9
  if (name !== "apply_patch")
25
10
  return args;
@@ -27,7 +12,12 @@ export const redactFunctionCallArgs = (name, args) => {
27
12
  if (!patch) {
28
13
  return {
29
14
  ...args,
30
- patch_string: { omitted: true, chars: 0, sha256: sha256Hex(""), files: [] },
15
+ patch_string: {
16
+ omitted: true,
17
+ chars: 0,
18
+ sha256: sha256Hex(""),
19
+ files: [],
20
+ },
31
21
  };
32
22
  }
33
23
  return {
@@ -76,37 +66,4 @@ export const compactForModel = (input) => {
76
66
  }
77
67
  return compacted;
78
68
  };
79
- export const normalizeReadFileArgs = (args, maxLines) => {
80
- const requestedStart = args.start_line === undefined || args.start_line === null
81
- ? 1
82
- : Number(args.start_line);
83
- const requestedEnd = args.end_line === undefined || args.end_line === null
84
- ? undefined
85
- : Number(args.end_line);
86
- const start = Number.isFinite(requestedStart) && requestedStart > 0 ? requestedStart : 1;
87
- const cap = Math.max(1, Math.floor(maxLines));
88
- const desiredEnd = requestedEnd === undefined ||
89
- !Number.isFinite(requestedEnd) ||
90
- requestedEnd < start
91
- ? start + cap - 1
92
- : requestedEnd;
93
- const cappedEnd = Math.min(desiredEnd, start + cap - 1);
94
- const wasCapped = requestedEnd === undefined ||
95
- desiredEnd !== requestedEnd ||
96
- cappedEnd !== desiredEnd;
97
- return {
98
- effectiveArgs: { ...args, start_line: start, end_line: cappedEnd },
99
- start,
100
- end: cappedEnd,
101
- wasCapped,
102
- };
103
- };
104
- export const getApplyPatchEventMeta = (args) => {
105
- const patch = typeof args.patch_string === "string" ? args.patch_string : "";
106
- return {
107
- chars: patch.length,
108
- sha256: sha256Hex(patch),
109
- files: extractPatchFiles(patch),
110
- };
111
- };
112
69
  //# sourceMappingURL=toolLoopContext.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"toolLoopContext.js","sourceRoot":"","sources":["../../../src/ai/toolLoop/toolLoopContext.ts"],"names":[],"mappings":"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","sourcesContent":["import crypto from \"node:crypto\";\n\nexport type ToolEvent = {\n name: string;\n summary: string;\n};\n\nexport type ToolLoopContextPolicy = {\n readFileDefaultMaxLines?: number;\n tailMessages?: number;\n maxModelChars?: number;\n logApproxModelChars?: boolean;\n};\n\nexport const DEFAULT_CONTEXT_POLICY: Required<ToolLoopContextPolicy> = {\n readFileDefaultMaxLines: 200,\n tailMessages: 8,\n maxModelChars: 120_000,\n logApproxModelChars: false,\n};\n\nconst sha256Hex = (value: string) =>\n crypto.createHash(\"sha256\").update(value, \"utf8\").digest(\"hex\");\n\nconst extractPatchFiles = (patchString: string): string[] => {\n const lines = patchString.replace(/\\r\\n/g, \"\\n\").split(\"\\n\");\n const files = new Set<string>();\n\n for (const line of lines) {\n const match =\n /^\\*\\*\\* (Update File|Add File|Delete File):\\s+(.+)$/.exec(line) ??\n /^\\*\\*\\* Move to:\\s+(.+)$/.exec(line);\n\n if (!match) continue;\n\n const filePath = (match[2] ?? match[1] ?? \"\").trim();\n if (filePath) files.add(filePath);\n }\n\n return [...files];\n};\n\nexport const redactFunctionCallArgs = (\n name: string,\n args: Record<string, unknown>,\n) => {\n if (name !== \"apply_patch\") return args;\n\n const patch = typeof args.patch_string === \"string\" ? args.patch_string : \"\";\n if (!patch) {\n return {\n ...args,\n patch_string: { omitted: true, chars: 0, sha256: sha256Hex(\"\"), files: [] },\n };\n }\n\n return {\n ...args,\n patch_string: {\n omitted: true,\n chars: patch.length,\n sha256: sha256Hex(patch),\n files: extractPatchFiles(patch),\n },\n };\n};\n\nconst isMemoryMessage = (item: any) => {\n const text = item?.parts?.[0]?.text;\n return (\n item?.role === \"model\" &&\n typeof text === \"string\" &&\n text.startsWith(\"MEMORY (tool trace summary):\")\n );\n};\n\nconst buildMemoryText = (events: ToolEvent[]) => {\n if (events.length === 0) return \"\";\n const lines = events.map((e) => `- ${e.summary}`);\n return `MEMORY (tool trace summary):\\n${lines.join(\"\\n\")}`;\n};\n\nexport const compactForModel = (input: {\n initialCount: number;\n modelContents: any[];\n toolEvents: ToolEvent[];\n policy: Required<ToolLoopContextPolicy>;\n}) => {\n const { initialCount, modelContents, toolEvents, policy } = input;\n\n const withoutOldMemory = modelContents.filter((c) => !isMemoryMessage(c));\n const tailStart = Math.max(\n initialCount,\n withoutOldMemory.length - policy.tailMessages,\n );\n\n const initial = withoutOldMemory.slice(0, initialCount);\n const tail = withoutOldMemory.slice(tailStart);\n const memoryText = buildMemoryText(toolEvents);\n const memory = memoryText\n ? [{ role: \"model\", parts: [{ text: memoryText }] }]\n : [];\n\n let compacted = [...initial, ...memory, ...tail];\n\n const maxChars = Math.max(10_000, policy.maxModelChars);\n while (JSON.stringify(compacted).length > maxChars) {\n const minLen = initial.length + memory.length + 1;\n if (compacted.length <= minLen) break;\n compacted = [\n ...initial,\n ...memory,\n ...compacted.slice(initial.length + memory.length + 1),\n ];\n }\n\n return compacted;\n};\n\nexport const normalizeReadFileArgs = (\n args: Record<string, unknown>,\n maxLines: number,\n) => {\n const requestedStart =\n args.start_line === undefined || args.start_line === null\n ? 1\n : Number(args.start_line);\n\n const requestedEnd =\n args.end_line === undefined || args.end_line === null\n ? undefined\n : Number(args.end_line);\n\n const start =\n Number.isFinite(requestedStart) && requestedStart > 0 ? requestedStart : 1;\n const cap = Math.max(1, Math.floor(maxLines));\n\n const desiredEnd =\n requestedEnd === undefined ||\n !Number.isFinite(requestedEnd) ||\n requestedEnd < start\n ? start + cap - 1\n : requestedEnd;\n\n const cappedEnd = Math.min(desiredEnd, start + cap - 1);\n const wasCapped =\n requestedEnd === undefined ||\n desiredEnd !== requestedEnd ||\n cappedEnd !== desiredEnd;\n\n return {\n effectiveArgs: { ...args, start_line: start, end_line: cappedEnd },\n start,\n end: cappedEnd,\n wasCapped,\n };\n};\n\nexport const getApplyPatchEventMeta = (args: Record<string, unknown>) => {\n const patch = typeof args.patch_string === \"string\" ? args.patch_string : \"\";\n return {\n chars: patch.length,\n sha256: sha256Hex(patch),\n files: extractPatchFiles(patch),\n };\n};\n\n"]}
1
+ {"version":3,"file":"toolLoopContext.js","sourceRoot":"","sources":["../../../src/ai/toolLoop/toolLoopContext.ts"],"names":[],"mappings":"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","sourcesContent":["import { extractPatchFiles, sha256Hex } from \"./helpers/fsHelpers.js\";\n\nexport type ToolEvent = {\n name: string;\n summary: string;\n};\n\nexport type ToolLoopContextPolicy = {\n readFileDefaultMaxLines?: number;\n tailMessages?: number;\n maxModelChars?: number;\n logApproxModelChars?: boolean;\n};\n\nexport const DEFAULT_CONTEXT_POLICY: Required<ToolLoopContextPolicy> = {\n readFileDefaultMaxLines: 200,\n tailMessages: 8,\n maxModelChars: 120_000,\n logApproxModelChars: false,\n};\n\nexport const redactFunctionCallArgs = (\n name: string,\n args: Record<string, unknown>,\n) => {\n if (name !== \"apply_patch\") return args;\n\n const patch = typeof args.patch_string === \"string\" ? args.patch_string : \"\";\n if (!patch) {\n return {\n ...args,\n patch_string: {\n omitted: true,\n chars: 0,\n sha256: sha256Hex(\"\"),\n files: [],\n },\n };\n }\n\n return {\n ...args,\n patch_string: {\n omitted: true,\n chars: patch.length,\n sha256: sha256Hex(patch),\n files: extractPatchFiles(patch),\n },\n };\n};\n\nconst isMemoryMessage = (item: any) => {\n const text = item?.parts?.[0]?.text;\n return (\n item?.role === \"model\" &&\n typeof text === \"string\" &&\n text.startsWith(\"MEMORY (tool trace summary):\")\n );\n};\n\nconst buildMemoryText = (events: ToolEvent[]) => {\n if (events.length === 0) return \"\";\n const lines = events.map((e) => `- ${e.summary}`);\n return `MEMORY (tool trace summary):\\n${lines.join(\"\\n\")}`;\n};\n\nexport const compactForModel = (input: {\n initialCount: number;\n modelContents: any[];\n toolEvents: ToolEvent[];\n policy: Required<ToolLoopContextPolicy>;\n}) => {\n const { initialCount, modelContents, toolEvents, policy } = input;\n\n const withoutOldMemory = modelContents.filter((c) => !isMemoryMessage(c));\n const tailStart = Math.max(\n initialCount,\n withoutOldMemory.length - policy.tailMessages,\n );\n\n const initial = withoutOldMemory.slice(0, initialCount);\n const tail = withoutOldMemory.slice(tailStart);\n const memoryText = buildMemoryText(toolEvents);\n const memory = memoryText\n ? [{ role: \"model\", parts: [{ text: memoryText }] }]\n : [];\n\n let compacted = [...initial, ...memory, ...tail];\n\n const maxChars = Math.max(10_000, policy.maxModelChars);\n while (JSON.stringify(compacted).length > maxChars) {\n const minLen = initial.length + memory.length + 1;\n if (compacted.length <= minLen) break;\n compacted = [\n ...initial,\n ...memory,\n ...compacted.slice(initial.length + memory.length + 1),\n ];\n }\n\n return compacted;\n};\n"]}
@@ -23,6 +23,11 @@ export type AiCallFn = (request: unknown, options: {
23
23
  model?: string;
24
24
  toolCallingMode?: FunctionCallingConfigMode;
25
25
  }) => Promise<AiCallResponse>;
26
+ export type TokenPersistence = {
27
+ repository: Pick<GenTokensRepository, "persistGenTokens">;
28
+ sessionId: string;
29
+ model: string;
30
+ };
26
31
  export type RunToolLoopOptions = {
27
32
  initialContents: any[];
28
33
  tools: Tool[];
@@ -39,11 +44,7 @@ export type RunToolLoopOptions = {
39
44
  aiCallAutoRetryBaseMs?: number;
40
45
  aiCallAutoRetryMaxMs?: number;
41
46
  persistResponse?: (modelInput: any, modelOutput: any) => Promise<void>;
42
- tokenPersistence?: {
43
- repository: Pick<GenTokensRepository, "persistGenTokens">;
44
- sessionId: string;
45
- model: string;
46
- };
47
+ tokenPersistence?: TokenPersistence;
47
48
  };
48
49
  export declare function runToolLoop(options: RunToolLoopOptions): Promise<ToolLoopResult>;
49
50
  //# sourceMappingURL=toolLoopRunner.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"toolLoopRunner.d.ts","sourceRoot":"","sources":["../../../src/ai/toolLoop/toolLoopRunner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAEhE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0CAA0C,CAAC;AAEpF,OAAO,EAAe,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAM/D,OAAO,EAML,qBAAqB,EACtB,MAAM,sBAAsB,CAAC;AAQ9B,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,EAAE,GAAG,EAAE,CAAC;IAChB,aAAa,EAAE,GAAG,EAAE,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE;QACb,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC9B,QAAQ,EAAE,OAAO,CAAC;KACnB,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG,CACnB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,SAAS,EACpB,gBAAgB,CAAC,EAAE,OAAO,KACvB,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB,MAAM,MAAM,cAAc,GAAG;IAC3B,aAAa,CAAC,EAAE,GAAG,EAAE,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG,CACrB,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE;IACP,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,yBAAyB,CAAC;CAC7C,KACE,OAAO,CAAC,cAAc,CAAC,CAAC;AAE7B,MAAM,MAAM,kBAAkB,GAAG;IAC/B,eAAe,EAAE,GAAG,EAAE,CAAC;IACvB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,yBAAyB,CAAC;IAC5C,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,qBAAqB,CAAC;IACtC,MAAM,EAAE,QAAQ,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,eAAe,CAAC,EAAE,CAAC,UAAU,EAAE,GAAG,EAAE,WAAW,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACvE,gBAAgB,CAAC,EAAE;QACjB,UAAU,EAAE,IAAI,CAAC,mBAAmB,EAAE,kBAAkB,CAAC,CAAC;QAC1D,SAAS,EAAE,MAAM,CAAC;QAClB,KAAK,EAAE,MAAM,CAAC;KACf,CAAC;CACH,CAAC;AAEF,wBAAsB,WAAW,CAC/B,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,cAAc,CAAC,CA8nBzB"}
1
+ {"version":3,"file":"toolLoopRunner.d.ts","sourceRoot":"","sources":["../../../src/ai/toolLoop/toolLoopRunner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAChE,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,0CAA0C,CAAC;AAEpF,OAAO,EAAe,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAmB/D,OAAO,EAKL,qBAAqB,EACtB,MAAM,sBAAsB,CAAC;AAG9B,MAAM,MAAM,cAAc,GAAG;IAC3B,QAAQ,EAAE,GAAG,EAAE,CAAC;IAChB,aAAa,EAAE,GAAG,EAAE,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE;QACb,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC9B,QAAQ,EAAE,OAAO,CAAC;KACnB,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,MAAM,GAAG,CACnB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,SAAS,EACpB,gBAAgB,CAAC,EAAE,OAAO,KACvB,OAAO,CAAC,IAAI,CAAC,CAAC;AAEnB,MAAM,MAAM,cAAc,GAAG;IAC3B,aAAa,CAAC,EAAE,GAAG,EAAE,CAAC;IACtB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG,CACrB,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE;IACP,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,yBAAyB,CAAC;CAC7C,KACE,OAAO,CAAC,cAAc,CAAC,CAAC;AAE7B,MAAM,MAAM,gBAAgB,GAAG;IAC7B,UAAU,EAAE,IAAI,CAAC,mBAAmB,EAAE,kBAAkB,CAAC,CAAC;IAC1D,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,eAAe,EAAE,GAAG,EAAE,CAAC;IACvB,KAAK,EAAE,IAAI,EAAE,CAAC;IACd,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,eAAe,CAAC,EAAE,yBAAyB,CAAC;IAC5C,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,aAAa,CAAC,EAAE,qBAAqB,CAAC;IACtC,MAAM,EAAE,QAAQ,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,eAAe,CAAC,EAAE,CAAC,UAAU,EAAE,GAAG,EAAE,WAAW,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACvE,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;CACrC,CAAC;AAEF,wBAAsB,WAAW,CAC/B,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,cAAc,CAAC,CAsXzB"}
@@ -1,139 +1,35 @@
1
1
  import { FunctionCallingConfigMode } from "@google/genai";
2
- import fs from "node:fs/promises";
3
2
  import { persistToolCall } from "../../services/toolcallPersist.service.js";
4
3
  import { EVENT_TYPES } from "../../types/events.js";
5
4
  import { STYLE_TOKEN_KEYS } from "../../types/styleConfig.js";
6
- import { getAvailableRoutes } from "../tools/helpers/pageConfigJson.helpers.js";
7
5
  import { createWorkspaceToolImpls } from "../tools/implementations/factories.js";
8
- import { parsePlannerTasksUnknown } from "./plannerTaskParser.js";
9
- import { compactForModel, DEFAULT_CONTEXT_POLICY, normalizeReadFileArgs, redactFunctionCallArgs, } from "./toolLoopContext.js";
10
- import { aiCallWithRetry, buildToolStatusMessage, recordToolEvent, serializeError, } from "./toolLoopRunnerUtils.js";
6
+ import { aiCallWithRetry } from "./helpers/aiCall.helper.js";
7
+ import { serializeError } from "./helpers/errors.helper.js";
8
+ import { nodeFs } from "./helpers/fsHelpers.js";
9
+ import { handleApplyPatchFailure } from "./helpers/patchRetry.helper.js";
10
+ import { extractUsageTokenCounts, persistTokensOnce, } from "./helpers/persistTokens.helpers.js";
11
+ import { extractThoughtSignatures } from "./helpers/signatures.helper.js";
12
+ import { normalizeToolArgs } from "./helpers/toolArgs.helper.js";
13
+ import { executeToolHandler, postProcessToolResult, } from "./helpers/toolExecution.helper.js";
14
+ import { createToolHandlers } from "./helpers/toolHandlers.helper.js";
15
+ import { recordToolEvent } from "./toolEventSummary.js";
16
+ import { compactForModel, DEFAULT_CONTEXT_POLICY, redactFunctionCallArgs, } from "./toolLoopContext.js";
17
+ import { buildToolStatusMessage } from "./toolStatusMessage.js";
11
18
  export async function runToolLoop(options) {
12
- const isPlainObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
13
19
  const styleTokenKeySet = new Set(STYLE_TOKEN_KEYS);
14
20
  const { initialContents, tools, workspaceRoot, maxSteps = 30, toolCallingMode = FunctionCallingConfigMode.ANY, terminalToolNames = [], keepFullTrace = true, contextPolicy, aiCall, logger, applyPatchAutoRetryMax = 2, aiCallAutoRetryMax = 3, // must have it to try 3 times as gemini errors a lot due to high demand sometimes
15
21
  aiCallAutoRetryBaseMs = 400, aiCallAutoRetryMaxMs = 10000, persistResponse, tokenPersistence, } = options;
16
- const extractUsageTokenCounts = (rawResponse) => {
17
- const usage = rawResponse?.usageMetadata;
18
- const promptTokenCount = usage?.promptTokenCount;
19
- const candidatesTokenCount = usage?.candidatesTokenCount;
20
- const inputTokens = Number(promptTokenCount);
21
- const outputTokens = Number(candidatesTokenCount);
22
- if (!Number.isFinite(inputTokens) || inputTokens < 0)
23
- return null;
24
- if (!Number.isFinite(outputTokens) || outputTokens < 0)
25
- return null;
26
- return { inputTokens, outputTokens };
27
- };
28
22
  let totalInputTokens = 0;
29
23
  let totalOutputTokens = 0;
30
24
  let sawAnyTokenUsage = false;
31
- const persistTokensOnce = async () => {
32
- if (!tokenPersistence)
33
- return;
34
- if (!sawAnyTokenUsage)
35
- return;
36
- try {
37
- await tokenPersistence.repository.persistGenTokens(tokenPersistence.sessionId, totalInputTokens, totalOutputTokens, tokenPersistence.model);
38
- }
39
- catch (err) {
40
- console.error("Tool loop: failed to persist gen tokens", err);
41
- }
42
- };
43
- const nodeFs = {
44
- readFile: async (absolutePath) => fs.readFile(absolutePath, "utf-8"),
45
- writeFile: async (absolutePath, content) => fs.writeFile(absolutePath, content ?? "", "utf-8"),
46
- mkdirp: async (absoluteDir) => {
47
- await fs.mkdir(absoluteDir, { recursive: true });
48
- },
49
- rmFile: async (absolutePath) => fs.rm(absolutePath, { force: true }),
50
- stat: async (absolutePath) => fs.stat(absolutePath),
51
- safeReadDir: async (absoluteDir) => fs.readdir(absoluteDir, { withFileTypes: true }),
52
- };
53
25
  const impls = createWorkspaceToolImpls({
54
26
  workspaceRoot,
55
27
  fs: nodeFs,
56
28
  });
57
- const toolHandlers = {
58
- read_file: async (args) => {
59
- const path = String(args.path ?? "");
60
- const startLine = args.start_line === undefined ? undefined : Number(args.start_line);
61
- const endLine = args.end_line === undefined ? undefined : Number(args.end_line);
62
- const content = await impls.readFileImpl(path, startLine, endLine);
63
- return { path, content };
64
- },
65
- write_file: (args) => impls.writeFileImpl(String(args.path ?? ""), String(args.content ?? "")),
66
- list_dir: async (args) => {
67
- const content = await impls.listDirImpl(String(args.path ?? ""), Number(args.depth ?? 1));
68
- return { content };
69
- },
70
- search: async (args) => {
71
- const results = await impls.searchImpl(String(args.search_query ?? ""));
72
- return { results };
73
- },
74
- apply_patch: (args) => impls.applyPatchImpl(String(args.patch_string ?? "")),
75
- update_global_styles: async (args) => {
76
- const result = await impls.updateGlobalStylesImpl(args);
77
- return result;
78
- },
79
- create_new_route: async (args) => {
80
- const parentRoute = String(args.parent_route ?? "");
81
- const routeName = String(args.route_name ?? "");
82
- const result = await impls.createNewRouteImpl(parentRoute, routeName);
83
- return result;
84
- },
85
- delete_element: async (args) => {
86
- const route = String(args.route ?? "");
87
- const element_id = String(args.element_id ?? "");
88
- const result = await impls.deleteElementImpl(route, element_id);
89
- return result;
90
- },
91
- insert_element: async (args) => {
92
- const result = await impls.insertElementImpl(args);
93
- if (!result.success) {
94
- const available = await getAvailableRoutes({
95
- workspaceRoot,
96
- fs: nodeFs,
97
- });
98
- return {
99
- success: false,
100
- error: `insert_element failed: ${result.error}. Available routes are: ${JSON.stringify(available)}. If you intend to create a new route, create it using the 'create_new_route' tool.`,
101
- available_routes: available,
102
- };
103
- }
104
- return result;
105
- },
106
- update_props: async (args) => {
107
- const route = String(args.route ?? "");
108
- const element_id = String(args.element_id ?? "");
109
- const props = args.props;
110
- const result = await impls.updatePropsImpl({
111
- route,
112
- element_id,
113
- ...props,
114
- });
115
- return result;
116
- },
117
- update_classname: async (args) => {
118
- const route = String(args.route ?? "");
119
- const element_id = String(args.element_id ?? "");
120
- const class_name = String(args.class_name ?? "");
121
- const result = await impls.updateClassNameImpl(route, element_id, class_name);
122
- return result;
123
- },
124
- get_available_routes: async (args) => {
125
- const routes = await getAvailableRoutes({ workspaceRoot, fs: nodeFs });
126
- return { success: true, routes };
127
- },
128
- submit_codegen_done: async (args) => ({
129
- success: true,
130
- summary: String(args.summary ?? "").trim(),
131
- }),
132
- submit_planner_tasks: async (args) => {
133
- const tasks = parsePlannerTasksUnknown(args.planner_tasks);
134
- return { success: true, count: tasks.length };
135
- },
136
- };
29
+ const toolHandlers = createToolHandlers({
30
+ impls,
31
+ workspaceRoot,
32
+ });
137
33
  if (typeof aiCall !== "function") {
138
34
  throw new Error("Tool loop: aiCall is required.");
139
35
  }
@@ -236,7 +132,7 @@ export async function runToolLoop(options) {
236
132
  }
237
133
  const functionCalls = response.functionCalls ?? [];
238
134
  if (functionCalls.length === 0) {
239
- await persistTokensOnce();
135
+ await persistTokensOnce(tokenPersistence, sawAnyTokenUsage, totalInputTokens, totalOutputTokens);
240
136
  return {
241
137
  contents: keepFullTrace ? fullTraceContents : modelContents,
242
138
  modelContents,
@@ -244,28 +140,7 @@ export async function runToolLoop(options) {
244
140
  steps: step + 1,
245
141
  };
246
142
  }
247
- const signatureById = (() => {
248
- try {
249
- const candidates = Array.isArray(response?.candidates)
250
- ? response.candidates
251
- : [];
252
- const parts = candidates?.[0]?.content?.parts;
253
- const arr = Array.isArray(parts) ? parts : [];
254
- const map = new Map();
255
- for (const p of arr) {
256
- const fc = p?.functionCall;
257
- const id = fc?.id;
258
- const sig = p?.thoughtSignature ?? p?.thought_signature;
259
- if (typeof id === "string" && typeof sig === "string" && sig) {
260
- map.set(id, sig);
261
- }
262
- }
263
- return map;
264
- }
265
- catch {
266
- return new Map();
267
- }
268
- })();
143
+ const signatureById = extractThoughtSignatures(response);
269
144
  for (let callIndex = 0; callIndex < functionCalls.length; callIndex++) {
270
145
  const call = functionCalls[callIndex];
271
146
  const name = call.name?.toString() ?? "";
@@ -298,48 +173,10 @@ export async function runToolLoop(options) {
298
173
  continue;
299
174
  }
300
175
  const handler = toolHandlers[name];
301
- const handlerMissingResult = !handler
302
- ? {
303
- success: false,
304
- error: `No handler registered for "${name}".`,
305
- error_detail: {
306
- name: "MissingToolHandlerError",
307
- message: `No handler registered for "${name}".`,
308
- },
309
- }
310
- : null;
311
- let effectiveArgs = args;
312
- let readFileMeta = null;
313
- if (name === "read_file") {
314
- const normalized = normalizeReadFileArgs(effectiveArgs, policy.readFileDefaultMaxLines);
315
- effectiveArgs = normalized.effectiveArgs;
316
- readFileMeta = {
317
- start: normalized.start,
318
- end: normalized.end,
319
- wasCapped: normalized.wasCapped,
320
- };
321
- }
322
- if (name === "update_global_styles") {
323
- const tokensMaybe = effectiveArgs?.tokens;
324
- const normalized = {};
325
- if (isPlainObject(tokensMaybe)) {
326
- for (const [k, v] of Object.entries(tokensMaybe)) {
327
- if (!styleTokenKeySet.has(k))
328
- continue;
329
- if (typeof v !== "string")
330
- continue;
331
- normalized[k] = v;
332
- }
333
- }
334
- for (const [k, v] of Object.entries(effectiveArgs ?? {})) {
335
- if (!styleTokenKeySet.has(k))
336
- continue;
337
- if (typeof v !== "string")
338
- continue;
339
- normalized[k] = v;
340
- }
341
- effectiveArgs = normalized;
342
- }
176
+ const { effectiveArgs, readFileMeta } = normalizeToolArgs(name, args, {
177
+ readFileDefaultMaxLines: policy.readFileDefaultMaxLines,
178
+ styleTokenKeySet,
179
+ });
343
180
  logger(buildToolStatusMessage(name, effectiveArgs, readFileMeta), EVENT_TYPES.STEP_STARTED, true);
344
181
  const modelArgs = redactFunctionCallArgs(name, effectiveArgs);
345
182
  const functionCallPart = {
@@ -388,75 +225,21 @@ export async function runToolLoop(options) {
388
225
  else {
389
226
  pushModelOnly(assistantModel);
390
227
  }
391
- let toolResultRaw;
392
- if (handlerMissingResult) {
393
- toolResultRaw = handlerMissingResult;
394
- }
395
- else {
396
- try {
397
- if (name === "update_global_styles") {
398
- const flatKeys = Object.keys(effectiveArgs ?? {}).filter((k) => styleTokenKeySet.has(k));
399
- if (flatKeys.length === 0) {
400
- toolResultRaw = {
401
- success: false,
402
- error: "must include at least one token key/value",
403
- error_detail: {
404
- name: "InvalidToolArgumentsError",
405
- message: 'update_global_styles requires at least one token key/value (e.g. { radius: "0.75rem" }).',
406
- },
407
- note: "Resend update_global_styles with at least one token key/value, or skip this tool call.",
408
- };
409
- }
410
- else {
411
- toolResultRaw = await handler(effectiveArgs);
412
- }
413
- }
414
- else {
415
- toolResultRaw = await handler(effectiveArgs);
416
- }
417
- }
418
- catch (err) {
419
- logger(`AI tool: ${name} failed`, EVENT_TYPES.STEP_ERROR, true);
420
- console.error("Tool loop: handler threw", err, {
421
- tool: name,
422
- step: step + 1,
423
- });
424
- toolResultRaw = {
425
- success: false,
426
- error: err instanceof Error ? err.message : String(err),
427
- error_detail: serializeError(err),
428
- note: "Tool handler threw. Inspect error_detail and retry with corrected args or a different approach.",
429
- };
430
- }
431
- }
432
- let toolResult = toolResultRaw;
433
- if (name === "read_file" && readFileMeta) {
434
- const path = String(effectiveArgs.path ?? "");
435
- const jsonPayload = toolResultRaw?.kind === "json"
436
- ? toolResultRaw?.json
437
- : undefined;
438
- if (jsonPayload !== undefined) {
439
- // Token-efficient: return JSON as structured data (no double-stringifying).
440
- toolResult = { path, json: jsonPayload };
441
- }
442
- else {
443
- const rawContent = typeof toolResultRaw?.content === "string"
444
- ? String(toolResultRaw.content)
445
- : typeof toolResultRaw === "string"
446
- ? toolResultRaw
447
- : JSON.stringify(toolResultRaw ?? null);
448
- toolResult = {
449
- path,
450
- start_line: readFileMeta.start,
451
- end_line: readFileMeta.end,
452
- truncated: readFileMeta.wasCapped,
453
- content: rawContent,
454
- note: readFileMeta.wasCapped
455
- ? `Capped to ${policy.readFileDefaultMaxLines} lines. Request more with start_line/end_line.`
456
- : undefined,
457
- };
458
- }
459
- }
228
+ const toolResultRaw = await executeToolHandler({
229
+ name,
230
+ handler,
231
+ effectiveArgs,
232
+ styleTokenKeySet,
233
+ step: step + 1,
234
+ logger,
235
+ });
236
+ const toolResult = postProcessToolResult({
237
+ name,
238
+ toolResultRaw,
239
+ effectiveArgs,
240
+ readFileMeta,
241
+ readFileDefaultMaxLines: policy.readFileDefaultMaxLines,
242
+ });
460
243
  try {
461
244
  await persistToolCall(name, modelArgs, toolResult);
462
245
  }
@@ -485,31 +268,15 @@ export async function runToolLoop(options) {
485
268
  toolResult?.success === false &&
486
269
  applyPatchAutoRetryMax > 0 &&
487
270
  applyPatchRetryCount < applyPatchAutoRetryMax) {
488
- applyPatchRetryCount += 1;
489
- const error = String(toolResult?.error ?? "unknown error");
490
- const debugFiles = Array.isArray(toolResult?.debug?.files)
491
- ? toolResult.debug.files
492
- : [];
493
- const debugText = debugFiles.length > 0
494
- ? `\n\nFILE SNAPSHOTS (for regenerating the patch):\n${debugFiles
495
- .slice(0, 3)
496
- .map((f) => `--- ${String(f.path ?? "")} ---\n${String(f.head ?? "")}\n--- end ---`)
497
- .join("\n\n")}`
498
- : "";
499
- const retryInstruction = {
500
- role: "user",
501
- parts: [
502
- {
503
- text: `apply_patch failed (attempt ${applyPatchRetryCount}/${applyPatchAutoRetryMax}): ${error}\n` +
504
- `Regenerate a patch that matches the current file contents. ` +
505
- `For large rewrites, prefer write_file(path, content) or Delete+Add instead of Update.` +
506
- debugText,
507
- },
508
- ],
509
- };
510
- if (keepFullTrace)
511
- fullTraceContents.push(retryInstruction);
512
- modelContents.push(retryInstruction);
271
+ const failureResult = handleApplyPatchFailure({
272
+ toolResult,
273
+ applyPatchAutoRetryMax,
274
+ applyPatchRetryCount,
275
+ keepFullTrace,
276
+ fullTraceContents,
277
+ modelContents,
278
+ });
279
+ applyPatchRetryCount = failureResult.applyPatchRetryCount;
513
280
  }
514
281
  recordToolEvent({
515
282
  toolEvents,
@@ -521,7 +288,7 @@ export async function runToolLoop(options) {
521
288
  toolResultRaw,
522
289
  });
523
290
  if (terminalToolNames.includes(name)) {
524
- await persistTokensOnce();
291
+ await persistTokensOnce(tokenPersistence, sawAnyTokenUsage, totalInputTokens, totalOutputTokens);
525
292
  return {
526
293
  contents: keepFullTrace ? fullTraceContents : modelContents,
527
294
  modelContents,
@@ -532,7 +299,7 @@ export async function runToolLoop(options) {
532
299
  }
533
300
  }
534
301
  }
535
- await persistTokensOnce();
302
+ await persistTokensOnce(tokenPersistence, sawAnyTokenUsage, totalInputTokens, totalOutputTokens);
536
303
  return {
537
304
  contents: keepFullTrace ? fullTraceContents : modelContents,
538
305
  modelContents,