@vedangiitb/qwintly-core 1.0.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.
Files changed (226) hide show
  1. package/README.md +8 -0
  2. package/dist/ai/ai.d.ts +2 -0
  3. package/dist/ai/ai.d.ts.map +1 -0
  4. package/dist/ai/ai.js +2 -0
  5. package/dist/ai/ai.js.map +1 -0
  6. package/dist/ai/generate/gemini.client.d.ts +15 -0
  7. package/dist/ai/generate/gemini.client.d.ts.map +1 -0
  8. package/dist/ai/generate/gemini.client.js +39 -0
  9. package/dist/ai/generate/gemini.client.js.map +1 -0
  10. package/dist/ai/generate/generateClient.d.ts +3 -0
  11. package/dist/ai/generate/generateClient.d.ts.map +1 -0
  12. package/dist/ai/generate/generateClient.js +8 -0
  13. package/dist/ai/generate/generateClient.js.map +1 -0
  14. package/dist/ai/toolLoop/toolLoopContext.d.ts +33 -0
  15. package/dist/ai/toolLoop/toolLoopContext.d.ts.map +1 -0
  16. package/dist/ai/toolLoop/toolLoopContext.js +112 -0
  17. package/dist/ai/toolLoop/toolLoopContext.js.map +1 -0
  18. package/dist/ai/toolLoop/toolLoopRunner.d.ts +43 -0
  19. package/dist/ai/toolLoop/toolLoopRunner.d.ts.map +1 -0
  20. package/dist/ai/toolLoop/toolLoopRunner.js +227 -0
  21. package/dist/ai/toolLoop/toolLoopRunner.js.map +1 -0
  22. package/dist/ai/toolLoop/toolLoopRunnerUtils.d.ts +51 -0
  23. package/dist/ai/toolLoop/toolLoopRunnerUtils.d.ts.map +1 -0
  24. package/dist/ai/toolLoop/toolLoopRunnerUtils.js +164 -0
  25. package/dist/ai/toolLoop/toolLoopRunnerUtils.js.map +1 -0
  26. package/dist/ai/tools/helpers/applyPatch.helpers.d.ts +36 -0
  27. package/dist/ai/tools/helpers/applyPatch.helpers.d.ts.map +1 -0
  28. package/dist/ai/tools/helpers/applyPatch.helpers.js +307 -0
  29. package/dist/ai/tools/helpers/applyPatch.helpers.js.map +1 -0
  30. package/dist/ai/tools/helpers/applyPatch.helpers.test.d.ts +2 -0
  31. package/dist/ai/tools/helpers/applyPatch.helpers.test.d.ts.map +1 -0
  32. package/dist/ai/tools/helpers/applyPatch.helpers.test.js +50 -0
  33. package/dist/ai/tools/helpers/applyPatch.helpers.test.js.map +1 -0
  34. package/dist/ai/tools/helpers/fileSystem.helpers.d.ts +2 -0
  35. package/dist/ai/tools/helpers/fileSystem.helpers.d.ts.map +1 -0
  36. package/dist/ai/tools/helpers/fileSystem.helpers.js +45 -0
  37. package/dist/ai/tools/helpers/fileSystem.helpers.js.map +1 -0
  38. package/dist/ai/tools/helpers/fileSystem.helpers.test.d.ts +2 -0
  39. package/dist/ai/tools/helpers/fileSystem.helpers.test.d.ts.map +1 -0
  40. package/dist/ai/tools/helpers/fileSystem.helpers.test.js +15 -0
  41. package/dist/ai/tools/helpers/fileSystem.helpers.test.js.map +1 -0
  42. package/dist/ai/tools/helpers/format.helpers.d.ts +2 -0
  43. package/dist/ai/tools/helpers/format.helpers.d.ts.map +1 -0
  44. package/dist/ai/tools/helpers/format.helpers.js +14 -0
  45. package/dist/ai/tools/helpers/format.helpers.js.map +1 -0
  46. package/dist/ai/tools/helpers/nextRouteFilePolicy.d.ts +8 -0
  47. package/dist/ai/tools/helpers/nextRouteFilePolicy.d.ts.map +1 -0
  48. package/dist/ai/tools/helpers/nextRouteFilePolicy.js +26 -0
  49. package/dist/ai/tools/helpers/nextRouteFilePolicy.js.map +1 -0
  50. package/dist/ai/tools/implementations/applyPatch.impl.d.ts +53 -0
  51. package/dist/ai/tools/implementations/applyPatch.impl.d.ts.map +1 -0
  52. package/dist/ai/tools/implementations/applyPatch.impl.js +242 -0
  53. package/dist/ai/tools/implementations/applyPatch.impl.js.map +1 -0
  54. package/dist/ai/tools/implementations/applyPatch.impl.test.d.ts +2 -0
  55. package/dist/ai/tools/implementations/applyPatch.impl.test.d.ts.map +1 -0
  56. package/dist/ai/tools/implementations/applyPatch.impl.test.js +72 -0
  57. package/dist/ai/tools/implementations/applyPatch.impl.test.js.map +1 -0
  58. package/dist/ai/tools/implementations/factories.d.ts +90 -0
  59. package/dist/ai/tools/implementations/factories.d.ts.map +1 -0
  60. package/dist/ai/tools/implementations/factories.js +26 -0
  61. package/dist/ai/tools/implementations/factories.js.map +1 -0
  62. package/dist/ai/tools/implementations/listDir.impl.d.ts +3 -0
  63. package/dist/ai/tools/implementations/listDir.impl.d.ts.map +1 -0
  64. package/dist/ai/tools/implementations/listDir.impl.js +47 -0
  65. package/dist/ai/tools/implementations/listDir.impl.js.map +1 -0
  66. package/dist/ai/tools/implementations/readFile.impl.d.ts +3 -0
  67. package/dist/ai/tools/implementations/readFile.impl.d.ts.map +1 -0
  68. package/dist/ai/tools/implementations/readFile.impl.js +23 -0
  69. package/dist/ai/tools/implementations/readFile.impl.js.map +1 -0
  70. package/dist/ai/tools/implementations/search.impl.d.ts +18 -0
  71. package/dist/ai/tools/implementations/search.impl.d.ts.map +1 -0
  72. package/dist/ai/tools/implementations/search.impl.js +74 -0
  73. package/dist/ai/tools/implementations/search.impl.js.map +1 -0
  74. package/dist/ai/tools/implementations/workspaceDeps.d.ts +22 -0
  75. package/dist/ai/tools/implementations/workspaceDeps.d.ts.map +1 -0
  76. package/dist/ai/tools/implementations/workspaceDeps.js +2 -0
  77. package/dist/ai/tools/implementations/workspaceDeps.js.map +1 -0
  78. package/dist/ai/tools/implementations/writeFile.impl.d.ts +27 -0
  79. package/dist/ai/tools/implementations/writeFile.impl.d.ts.map +1 -0
  80. package/dist/ai/tools/implementations/writeFile.impl.js +62 -0
  81. package/dist/ai/tools/implementations/writeFile.impl.js.map +1 -0
  82. package/dist/ai/tools/schemas/applyPatch.schema.d.ts +16 -0
  83. package/dist/ai/tools/schemas/applyPatch.schema.d.ts.map +1 -0
  84. package/dist/ai/tools/schemas/applyPatch.schema.js +17 -0
  85. package/dist/ai/tools/schemas/applyPatch.schema.js.map +1 -0
  86. package/dist/ai/tools/schemas/listDir.schema.d.ts +22 -0
  87. package/dist/ai/tools/schemas/listDir.schema.d.ts.map +1 -0
  88. package/dist/ai/tools/schemas/listDir.schema.js +22 -0
  89. package/dist/ai/tools/schemas/listDir.schema.js.map +1 -0
  90. package/dist/ai/tools/schemas/readFile.schema.d.ts +26 -0
  91. package/dist/ai/tools/schemas/readFile.schema.d.ts.map +1 -0
  92. package/dist/ai/tools/schemas/readFile.schema.js +26 -0
  93. package/dist/ai/tools/schemas/readFile.schema.js.map +1 -0
  94. package/dist/ai/tools/schemas/search.schema.d.ts +16 -0
  95. package/dist/ai/tools/schemas/search.schema.d.ts.map +1 -0
  96. package/dist/ai/tools/schemas/search.schema.js +16 -0
  97. package/dist/ai/tools/schemas/search.schema.js.map +1 -0
  98. package/dist/ai/tools/schemas/submitCodegenDone.schema.d.ts +16 -0
  99. package/dist/ai/tools/schemas/submitCodegenDone.schema.d.ts.map +1 -0
  100. package/dist/ai/tools/schemas/submitCodegenDone.schema.js +16 -0
  101. package/dist/ai/tools/schemas/submitCodegenDone.schema.js.map +1 -0
  102. package/dist/ai/tools/schemas/submitPlannerTasks.schema.d.ts +33 -0
  103. package/dist/ai/tools/schemas/submitPlannerTasks.schema.d.ts.map +1 -0
  104. package/dist/ai/tools/schemas/submitPlannerTasks.schema.js +31 -0
  105. package/dist/ai/tools/schemas/submitPlannerTasks.schema.js.map +1 -0
  106. package/dist/ai/tools/schemas/writeFile.schema.d.ts +20 -0
  107. package/dist/ai/tools/schemas/writeFile.schema.d.ts.map +1 -0
  108. package/dist/ai/tools/schemas/writeFile.schema.js +23 -0
  109. package/dist/ai/tools/schemas/writeFile.schema.js.map +1 -0
  110. package/dist/ai/tools/toolsets/codegenTools.d.ts +3 -0
  111. package/dist/ai/tools/toolsets/codegenTools.d.ts.map +1 -0
  112. package/dist/ai/tools/toolsets/codegenTools.js +17 -0
  113. package/dist/ai/tools/toolsets/codegenTools.js.map +1 -0
  114. package/dist/ai/tools/toolsets/plannerTools.d.ts +3 -0
  115. package/dist/ai/tools/toolsets/plannerTools.d.ts.map +1 -0
  116. package/dist/ai/tools/toolsets/plannerTools.js +17 -0
  117. package/dist/ai/tools/toolsets/plannerTools.js.map +1 -0
  118. package/dist/core.d.ts +44 -0
  119. package/dist/core.d.ts.map +1 -0
  120. package/dist/core.js +80 -0
  121. package/dist/core.js.map +1 -0
  122. package/dist/index.d.ts +2 -0
  123. package/dist/index.d.ts.map +1 -0
  124. package/dist/index.js +3 -0
  125. package/dist/index.js.map +1 -0
  126. package/dist/indexer/codegenIndex.d.ts +3 -0
  127. package/dist/indexer/codegenIndex.d.ts.map +1 -0
  128. package/dist/indexer/codegenIndex.js +17 -0
  129. package/dist/indexer/codegenIndex.js.map +1 -0
  130. package/dist/indexer/data/configs.constants.d.ts +85 -0
  131. package/dist/indexer/data/configs.constants.d.ts.map +1 -0
  132. package/dist/indexer/data/configs.constants.js +136 -0
  133. package/dist/indexer/data/configs.constants.js.map +1 -0
  134. package/dist/indexer/helpers/buildFolderTree.d.ts +2 -0
  135. package/dist/indexer/helpers/buildFolderTree.d.ts.map +1 -0
  136. package/dist/indexer/helpers/buildFolderTree.js +40 -0
  137. package/dist/indexer/helpers/buildFolderTree.js.map +1 -0
  138. package/dist/indexer/plannerIndex.d.ts +3 -0
  139. package/dist/indexer/plannerIndex.d.ts.map +1 -0
  140. package/dist/indexer/plannerIndex.js +20 -0
  141. package/dist/indexer/plannerIndex.js.map +1 -0
  142. package/dist/indexer/projectInfoIndex.d.ts +3 -0
  143. package/dist/indexer/projectInfoIndex.d.ts.map +1 -0
  144. package/dist/indexer/projectInfoIndex.js +257 -0
  145. package/dist/indexer/projectInfoIndex.js.map +1 -0
  146. package/dist/indexer/validatorIndex.d.ts +3 -0
  147. package/dist/indexer/validatorIndex.d.ts.map +1 -0
  148. package/dist/indexer/validatorIndex.js +14 -0
  149. package/dist/indexer/validatorIndex.js.map +1 -0
  150. package/dist/lib/redis.d.ts +3 -0
  151. package/dist/lib/redis.d.ts.map +1 -0
  152. package/dist/lib/redis.js +7 -0
  153. package/dist/lib/redis.js.map +1 -0
  154. package/dist/lib/supabase.d.ts +2 -0
  155. package/dist/lib/supabase.d.ts.map +1 -0
  156. package/dist/lib/supabase.js +4 -0
  157. package/dist/lib/supabase.js.map +1 -0
  158. package/dist/logging/genStatus.service.d.ts +14 -0
  159. package/dist/logging/genStatus.service.d.ts.map +1 -0
  160. package/dist/logging/genStatus.service.js +36 -0
  161. package/dist/logging/genStatus.service.js.map +1 -0
  162. package/dist/logging/logging.utils.d.ts +12 -0
  163. package/dist/logging/logging.utils.d.ts.map +1 -0
  164. package/dist/logging/logging.utils.js +15 -0
  165. package/dist/logging/logging.utils.js.map +1 -0
  166. package/dist/logging/redis.service.d.ts +11 -0
  167. package/dist/logging/redis.service.d.ts.map +1 -0
  168. package/dist/logging/redis.service.js +26 -0
  169. package/dist/logging/redis.service.js.map +1 -0
  170. package/dist/repository/context.repository.d.ts +8 -0
  171. package/dist/repository/context.repository.d.ts.map +1 -0
  172. package/dist/repository/context.repository.js +59 -0
  173. package/dist/repository/context.repository.js.map +1 -0
  174. package/dist/repository/genStatus.repository.d.ts +13 -0
  175. package/dist/repository/genStatus.repository.d.ts.map +1 -0
  176. package/dist/repository/genStatus.repository.js +18 -0
  177. package/dist/repository/genStatus.repository.js.map +1 -0
  178. package/dist/repository/planTasks.repository.d.ts +9 -0
  179. package/dist/repository/planTasks.repository.d.ts.map +1 -0
  180. package/dist/repository/planTasks.repository.js +24 -0
  181. package/dist/repository/planTasks.repository.js.map +1 -0
  182. package/dist/repository/repository.d.ts +5 -0
  183. package/dist/repository/repository.d.ts.map +1 -0
  184. package/dist/repository/repository.js +7 -0
  185. package/dist/repository/repository.js.map +1 -0
  186. package/dist/types/context.types.d.ts +64 -0
  187. package/dist/types/context.types.d.ts.map +1 -0
  188. package/dist/types/context.types.js +55 -0
  189. package/dist/types/context.types.js.map +1 -0
  190. package/dist/types/events.d.ts +16 -0
  191. package/dist/types/events.d.ts.map +1 -0
  192. package/dist/types/events.js +14 -0
  193. package/dist/types/events.js.map +1 -0
  194. package/dist/types/index/configs.types.d.ts +28 -0
  195. package/dist/types/index/configs.types.d.ts.map +1 -0
  196. package/dist/types/index/configs.types.js +2 -0
  197. package/dist/types/index/configs.types.js.map +1 -0
  198. package/dist/types/index/conventions.types.d.ts +40 -0
  199. package/dist/types/index/conventions.types.d.ts.map +1 -0
  200. package/dist/types/index/conventions.types.js +2 -0
  201. package/dist/types/index/conventions.types.js.map +1 -0
  202. package/dist/types/index/index.types.d.ts +16 -0
  203. package/dist/types/index/index.types.d.ts.map +1 -0
  204. package/dist/types/index/index.types.js +2 -0
  205. package/dist/types/index/index.types.js.map +1 -0
  206. package/dist/types/index/indexing.types.d.ts +9 -0
  207. package/dist/types/index/indexing.types.d.ts.map +1 -0
  208. package/dist/types/index/indexing.types.js +2 -0
  209. package/dist/types/index/indexing.types.js.map +1 -0
  210. package/dist/types/projectInfo.types.d.ts +16 -0
  211. package/dist/types/projectInfo.types.d.ts.map +1 -0
  212. package/dist/types/projectInfo.types.js +2 -0
  213. package/dist/types/projectInfo.types.js.map +1 -0
  214. package/dist/types/updatePlan.types.d.ts +34 -0
  215. package/dist/types/updatePlan.types.d.ts.map +1 -0
  216. package/dist/types/updatePlan.types.js +18 -0
  217. package/dist/types/updatePlan.types.js.map +1 -0
  218. package/dist/utils/utils.d.ts +2 -0
  219. package/dist/utils/utils.d.ts.map +1 -0
  220. package/dist/utils/utils.js +6 -0
  221. package/dist/utils/utils.js.map +1 -0
  222. package/dist/utils/workspace.d.ts +13 -0
  223. package/dist/utils/workspace.d.ts.map +1 -0
  224. package/dist/utils/workspace.js +92 -0
  225. package/dist/utils/workspace.js.map +1 -0
  226. package/package.json +58 -0
@@ -0,0 +1,51 @@
1
+ import { FunctionCallingConfigMode, Tool } from "@google/genai";
2
+ import { ToolEvent } from "./toolLoopContext.js";
3
+ import { AiCallFn, Logger } from "./toolLoopRunner.js";
4
+ export declare const sleep: (ms: number) => Promise<void>;
5
+ export declare const serializeError: (err: unknown) => {
6
+ name: string;
7
+ message: string;
8
+ stack: string | undefined;
9
+ cause: unknown;
10
+ value?: undefined;
11
+ } | {
12
+ name: "string" | "number" | "bigint" | "boolean" | "symbol" | "undefined" | "object" | "function";
13
+ message: string;
14
+ value: unknown;
15
+ stack?: undefined;
16
+ cause?: undefined;
17
+ };
18
+ export declare const isTransientAiCallError: (err: unknown) => boolean;
19
+ export declare const computeBackoffMs: (attempt: number, baseMs: number, maxMs: number) => number;
20
+ export declare const aiCallWithRetry: (params: {
21
+ aiCall: AiCallFn;
22
+ request: unknown;
23
+ options: {
24
+ tools?: Tool[];
25
+ toolCallingMode?: FunctionCallingConfigMode;
26
+ };
27
+ retryMax: number;
28
+ retryBaseMs: number;
29
+ retryMaxMs: number;
30
+ step: number;
31
+ logger: Logger;
32
+ }) => Promise<import("./toolLoopRunner.js").AiCallResponse>;
33
+ export declare const buildToolStatusMessage: (name: string, effectiveArgs: Record<string, unknown>, readFileMeta: {
34
+ start: number;
35
+ end: number;
36
+ wasCapped: boolean;
37
+ } | null) => string;
38
+ export declare const recordToolEvent: (params: {
39
+ toolEvents: ToolEvent[];
40
+ name: string;
41
+ effectiveArgs: Record<string, unknown>;
42
+ modelArgs: Record<string, unknown>;
43
+ readFileMeta: {
44
+ start: number;
45
+ end: number;
46
+ wasCapped: boolean;
47
+ } | null;
48
+ toolResult: unknown;
49
+ toolResultRaw: unknown;
50
+ }) => void;
51
+ //# sourceMappingURL=toolLoopRunnerUtils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toolLoopRunnerUtils.d.ts","sourceRoot":"","sources":["../../../src/ai/toolLoop/toolLoopRunnerUtils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,yBAAyB,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAEhE,OAAO,EAA0B,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACzE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAEvD,eAAO,MAAM,KAAK,GAAI,IAAI,MAAM,kBACsC,CAAC;AAEvE,eAAO,MAAM,cAAc,GAAI,KAAK,OAAO;;;;;;;;;;;;CAuB1C,CAAC;AAEF,eAAO,MAAM,sBAAsB,GAAI,KAAK,OAAO,YA+BlD,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAC3B,SAAS,MAAM,EACf,QAAQ,MAAM,EACd,OAAO,MAAM,WAMd,CAAC;AAEF,eAAO,MAAM,eAAe,GAAU,QAAQ;IAC5C,MAAM,EAAE,QAAQ,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE;QAAE,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;QAAC,eAAe,CAAC,EAAE,yBAAyB,CAAA;KAAE,CAAC;IACzE,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;CAChB,0DA2BA,CAAC;AAEF,eAAO,MAAM,sBAAsB,GACjC,MAAM,MAAM,EACZ,eAAe,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACtC,cAAc;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAA;CAAE,GAAG,IAAI,WAqBxE,CAAC;AAEF,eAAO,MAAM,eAAe,GAAI,QAAQ;IACtC,UAAU,EAAE,SAAS,EAAE,CAAC;IACxB,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACnC,YAAY,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IACxE,UAAU,EAAE,OAAO,CAAC;IACpB,aAAa,EAAE,OAAO,CAAC;CACxB,SA8EA,CAAC"}
@@ -0,0 +1,164 @@
1
+ import { EVENT_TYPES } from "../../types/events.js";
2
+ import { getApplyPatchEventMeta } from "./toolLoopContext.js";
3
+ export const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, Math.max(0, ms)));
4
+ export const serializeError = (err) => {
5
+ if (err instanceof Error) {
6
+ const cause = err.cause;
7
+ return {
8
+ name: err.name,
9
+ message: err.message,
10
+ stack: err.stack,
11
+ cause: cause instanceof Error
12
+ ? {
13
+ name: cause.name,
14
+ message: cause.message,
15
+ stack: cause.stack,
16
+ }
17
+ : cause,
18
+ };
19
+ }
20
+ return {
21
+ name: typeof err,
22
+ message: typeof err === "string" ? err : "Non-Error thrown",
23
+ value: err,
24
+ };
25
+ };
26
+ export const isTransientAiCallError = (err) => {
27
+ const anyErr = err;
28
+ const code = anyErr?.error?.code ??
29
+ anyErr?.code ??
30
+ anyErr?.statusCode ??
31
+ anyErr?.response?.status;
32
+ const status = anyErr?.error?.status ??
33
+ anyErr?.status ??
34
+ anyErr?.response?.data?.error?.status;
35
+ const message = anyErr?.error?.message ??
36
+ anyErr?.message ??
37
+ anyErr?.response?.data?.error?.message;
38
+ const msg = typeof message === "string" ? message.toLowerCase() : "";
39
+ const stat = typeof status === "string" ? status.toUpperCase() : "";
40
+ if (code === 503)
41
+ return true;
42
+ if (code === 429)
43
+ return true;
44
+ if (stat === "UNAVAILABLE")
45
+ return true;
46
+ if (stat === "RESOURCE_EXHAUSTED")
47
+ return true;
48
+ if (msg.includes("high demand"))
49
+ return true;
50
+ if (msg.includes("try again later"))
51
+ return true;
52
+ if (msg.includes("temporar"))
53
+ return true;
54
+ return false;
55
+ };
56
+ export const computeBackoffMs = (attempt, baseMs, maxMs) => {
57
+ const exp = baseMs * Math.pow(2, Math.max(0, attempt - 1));
58
+ const capped = Math.min(maxMs, exp);
59
+ const jitter = capped * (0.2 * Math.random());
60
+ return Math.round(capped + jitter);
61
+ };
62
+ export const aiCallWithRetry = async (params) => {
63
+ const { aiCall, request, options, retryMax, retryBaseMs, retryMaxMs, logger, } = params;
64
+ let retryCount = 0;
65
+ while (true) {
66
+ try {
67
+ return await aiCall(request, options);
68
+ }
69
+ catch (err) {
70
+ const transient = isTransientAiCallError(err);
71
+ if (!transient || retryMax <= 0 || retryCount >= retryMax) {
72
+ throw err;
73
+ }
74
+ retryCount += 1;
75
+ const delayMs = computeBackoffMs(retryCount, retryBaseMs, retryMaxMs);
76
+ logger("Tool loop: aiCall failed; retrying", EVENT_TYPES.STEP_RETRY);
77
+ await sleep(delayMs);
78
+ }
79
+ }
80
+ };
81
+ export const buildToolStatusMessage = (name, effectiveArgs, readFileMeta) => {
82
+ if (name === "read_file" && readFileMeta) {
83
+ return `AI tool: read_file (${readFileMeta.start}-${readFileMeta.end}${readFileMeta.wasCapped ? ", capped" : ""})`;
84
+ }
85
+ if (name === "apply_patch") {
86
+ const meta = getApplyPatchEventMeta(effectiveArgs);
87
+ const files = Array.isArray(meta.files) ? meta.files.length : 0;
88
+ return `AI tool: apply_patch (${files} file${files === 1 ? "" : "s"})`;
89
+ }
90
+ if (name === "search")
91
+ return "AI tool: search";
92
+ if (name === "list_dir")
93
+ return "AI tool: list_dir";
94
+ if (name === "write_file")
95
+ return "AI tool: write_file";
96
+ if (name === "submit_planner_tasks")
97
+ return "AI tool: submit_planner_tasks";
98
+ if (name === "submit_codegen_done")
99
+ return "AI tool: submit_codegen_done";
100
+ return `AI tool: ${name}`;
101
+ };
102
+ export const recordToolEvent = (params) => {
103
+ const { toolEvents, name, effectiveArgs, modelArgs, readFileMeta, toolResult, toolResultRaw, } = params;
104
+ try {
105
+ if (name === "read_file") {
106
+ const path = String(effectiveArgs.path ?? "");
107
+ const start = readFileMeta?.start ?? Number(effectiveArgs.start_line ?? 1);
108
+ const end = readFileMeta?.end ?? Number(effectiveArgs.end_line ?? start);
109
+ toolEvents.push({
110
+ name,
111
+ summary: `read_file ${path}:${start}-${end}${readFileMeta?.wasCapped ? " (capped)" : ""}`,
112
+ });
113
+ return;
114
+ }
115
+ if (name === "apply_patch") {
116
+ const meta = typeof modelArgs.patch_string === "object"
117
+ ? modelArgs.patch_string
118
+ : null;
119
+ const fallback = getApplyPatchEventMeta(effectiveArgs);
120
+ const ok = toolResult?.success === true
121
+ ? "success"
122
+ : toolResult?.success === false
123
+ ? "failure"
124
+ : "done";
125
+ toolEvents.push({
126
+ name,
127
+ summary: `apply_patch files=${JSON.stringify(meta?.files ?? fallback.files)} sha256=${String(meta?.sha256 ?? fallback.sha256).slice(0, 12)} chars=${meta?.chars ?? fallback.chars} result=${ok}`,
128
+ });
129
+ return;
130
+ }
131
+ if (name === "search") {
132
+ const q = String(effectiveArgs.search_query ?? "").trim();
133
+ const results = Array.isArray(toolResultRaw?.results)
134
+ ? toolResultRaw.results
135
+ : [];
136
+ toolEvents.push({
137
+ name,
138
+ summary: `search "${q}" -> ${results.length} results`,
139
+ });
140
+ return;
141
+ }
142
+ if (name === "list_dir") {
143
+ const p = String(effectiveArgs.path ?? "");
144
+ const d = Number(effectiveArgs.depth ?? 1);
145
+ toolEvents.push({ name, summary: `list_dir ${p} depth=${d}` });
146
+ return;
147
+ }
148
+ if (name === "create_file") {
149
+ const p = String(effectiveArgs.path ?? "");
150
+ toolEvents.push({ name, summary: `create_file ${p}` });
151
+ return;
152
+ }
153
+ if (name === "delete_file") {
154
+ const p = String(effectiveArgs.path ?? "");
155
+ toolEvents.push({ name, summary: `delete_file ${p}` });
156
+ return;
157
+ }
158
+ toolEvents.push({ name, summary: `${name} called` });
159
+ }
160
+ catch {
161
+ toolEvents.push({ name, summary: `${name} called` });
162
+ }
163
+ };
164
+ //# sourceMappingURL=toolLoopRunnerUtils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toolLoopRunnerUtils.js","sourceRoot":"","sources":["../../../src/ai/toolLoop/toolLoopRunnerUtils.ts"],"names":[],"mappings":"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","sourcesContent":["import { FunctionCallingConfigMode, Tool } from \"@google/genai\";\nimport { EVENT_TYPES } from \"../../types/events.js\";\nimport { getApplyPatchEventMeta, ToolEvent } from \"./toolLoopContext.js\";\nimport { AiCallFn, Logger } from \"./toolLoopRunner.js\";\n\nexport const sleep = (ms: number) =>\n new Promise<void>((resolve) => setTimeout(resolve, Math.max(0, ms)));\n\nexport const serializeError = (err: unknown) => {\n if (err instanceof Error) {\n const cause = (err as any).cause as unknown;\n return {\n name: err.name,\n message: err.message,\n stack: err.stack,\n cause:\n cause instanceof Error\n ? {\n name: cause.name,\n message: cause.message,\n stack: cause.stack,\n }\n : cause,\n };\n }\n\n return {\n name: typeof err,\n message: typeof err === \"string\" ? err : \"Non-Error thrown\",\n value: err,\n };\n};\n\nexport const isTransientAiCallError = (err: unknown) => {\n const anyErr = err as any;\n\n const code =\n anyErr?.error?.code ??\n anyErr?.code ??\n anyErr?.statusCode ??\n anyErr?.response?.status;\n\n const status =\n anyErr?.error?.status ??\n anyErr?.status ??\n anyErr?.response?.data?.error?.status;\n\n const message =\n anyErr?.error?.message ??\n anyErr?.message ??\n anyErr?.response?.data?.error?.message;\n\n const msg = typeof message === \"string\" ? message.toLowerCase() : \"\";\n const stat = typeof status === \"string\" ? status.toUpperCase() : \"\";\n\n if (code === 503) return true;\n if (code === 429) return true;\n if (stat === \"UNAVAILABLE\") return true;\n if (stat === \"RESOURCE_EXHAUSTED\") return true;\n if (msg.includes(\"high demand\")) return true;\n if (msg.includes(\"try again later\")) return true;\n if (msg.includes(\"temporar\")) return true;\n\n return false;\n};\n\nexport const computeBackoffMs = (\n attempt: number,\n baseMs: number,\n maxMs: number,\n) => {\n const exp = baseMs * Math.pow(2, Math.max(0, attempt - 1));\n const capped = Math.min(maxMs, exp);\n const jitter = capped * (0.2 * Math.random());\n return Math.round(capped + jitter);\n};\n\nexport const aiCallWithRetry = async (params: {\n aiCall: AiCallFn;\n request: unknown;\n options: { tools?: Tool[]; toolCallingMode?: FunctionCallingConfigMode };\n retryMax: number;\n retryBaseMs: number;\n retryMaxMs: number;\n step: number;\n logger: Logger;\n}) => {\n const {\n aiCall,\n request,\n options,\n retryMax,\n retryBaseMs,\n retryMaxMs,\n logger,\n } = params;\n\n let retryCount = 0;\n while (true) {\n try {\n return await aiCall(request, options);\n } catch (err) {\n const transient = isTransientAiCallError(err);\n if (!transient || retryMax <= 0 || retryCount >= retryMax) {\n throw err;\n }\n\n retryCount += 1;\n const delayMs = computeBackoffMs(retryCount, retryBaseMs, retryMaxMs);\n logger(\"Tool loop: aiCall failed; retrying\", EVENT_TYPES.STEP_RETRY);\n await sleep(delayMs);\n }\n }\n};\n\nexport const buildToolStatusMessage = (\n name: string,\n effectiveArgs: Record<string, unknown>,\n readFileMeta: { start: number; end: number; wasCapped: boolean } | null,\n) => {\n if (name === \"read_file\" && readFileMeta) {\n return `AI tool: read_file (${readFileMeta.start}-${readFileMeta.end}${\n readFileMeta.wasCapped ? \", capped\" : \"\"\n })`;\n }\n\n if (name === \"apply_patch\") {\n const meta = getApplyPatchEventMeta(effectiveArgs);\n const files = Array.isArray(meta.files) ? meta.files.length : 0;\n return `AI tool: apply_patch (${files} file${files === 1 ? \"\" : \"s\"})`;\n }\n\n if (name === \"search\") return \"AI tool: search\";\n if (name === \"list_dir\") return \"AI tool: list_dir\";\n if (name === \"write_file\") return \"AI tool: write_file\";\n if (name === \"submit_planner_tasks\") return \"AI tool: submit_planner_tasks\";\n if (name === \"submit_codegen_done\") return \"AI tool: submit_codegen_done\";\n\n return `AI tool: ${name}`;\n};\n\nexport const recordToolEvent = (params: {\n toolEvents: ToolEvent[];\n name: string;\n effectiveArgs: Record<string, unknown>;\n modelArgs: Record<string, unknown>;\n readFileMeta: { start: number; end: number; wasCapped: boolean } | null;\n toolResult: unknown;\n toolResultRaw: unknown;\n}) => {\n const {\n toolEvents,\n name,\n effectiveArgs,\n modelArgs,\n readFileMeta,\n toolResult,\n toolResultRaw,\n } = params;\n\n try {\n if (name === \"read_file\") {\n const path = String(effectiveArgs.path ?? \"\");\n const start =\n readFileMeta?.start ?? Number(effectiveArgs.start_line ?? 1);\n const end = readFileMeta?.end ?? Number(effectiveArgs.end_line ?? start);\n toolEvents.push({\n name,\n summary: `read_file ${path}:${start}-${end}${readFileMeta?.wasCapped ? \" (capped)\" : \"\"}`,\n });\n return;\n }\n\n if (name === \"apply_patch\") {\n const meta =\n typeof (modelArgs as any).patch_string === \"object\"\n ? ((modelArgs as any).patch_string as any)\n : null;\n const fallback = getApplyPatchEventMeta(effectiveArgs);\n const ok =\n (toolResult as any)?.success === true\n ? \"success\"\n : (toolResult as any)?.success === false\n ? \"failure\"\n : \"done\";\n toolEvents.push({\n name,\n summary: `apply_patch files=${JSON.stringify(meta?.files ?? fallback.files)} sha256=${String(meta?.sha256 ?? fallback.sha256).slice(0, 12)} chars=${meta?.chars ?? fallback.chars} result=${ok}`,\n });\n return;\n }\n\n if (name === \"search\") {\n const q = String(effectiveArgs.search_query ?? \"\").trim();\n const results = Array.isArray((toolResultRaw as any)?.results)\n ? (toolResultRaw as any).results\n : [];\n toolEvents.push({\n name,\n summary: `search \"${q}\" -> ${results.length} results`,\n });\n return;\n }\n\n if (name === \"list_dir\") {\n const p = String(effectiveArgs.path ?? \"\");\n const d = Number(effectiveArgs.depth ?? 1);\n toolEvents.push({ name, summary: `list_dir ${p} depth=${d}` });\n return;\n }\n\n if (name === \"create_file\") {\n const p = String(effectiveArgs.path ?? \"\");\n toolEvents.push({ name, summary: `create_file ${p}` });\n return;\n }\n\n if (name === \"delete_file\") {\n const p = String(effectiveArgs.path ?? \"\");\n toolEvents.push({ name, summary: `delete_file ${p}` });\n return;\n }\n\n toolEvents.push({ name, summary: `${name} called` });\n } catch {\n toolEvents.push({ name, summary: `${name} called` });\n }\n};\n"]}
@@ -0,0 +1,36 @@
1
+ export type ApplyPatchOperation = {
2
+ kind: "update";
3
+ filePath: string;
4
+ moveTo?: string;
5
+ hunks: PatchHunk[];
6
+ } | {
7
+ kind: "add";
8
+ filePath: string;
9
+ hunks: PatchHunk[];
10
+ } | {
11
+ kind: "delete";
12
+ filePath: string;
13
+ };
14
+ type PatchLine = {
15
+ kind: "context";
16
+ text: string;
17
+ } | {
18
+ kind: "add";
19
+ text: string;
20
+ } | {
21
+ kind: "delete";
22
+ text: string;
23
+ };
24
+ export type PatchHunk = {
25
+ label?: string;
26
+ anchorEOF?: boolean;
27
+ lines: PatchLine[];
28
+ };
29
+ export declare function parseApplyPatch(patchString: string): ApplyPatchOperation[];
30
+ export declare function applyHunksToContent(content: string, hunks: PatchHunk[]): {
31
+ content: string;
32
+ changed: boolean;
33
+ };
34
+ export declare function isTextFilePath(filePath: string): boolean;
35
+ export {};
36
+ //# sourceMappingURL=applyPatch.helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"applyPatch.helpers.d.ts","sourceRoot":"","sources":["../../../../src/ai/tools/helpers/applyPatch.helpers.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,mBAAmB,GAC3B;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,SAAS,EAAE,CAAC;CACpB,GACD;IACE,IAAI,EAAE,KAAK,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,SAAS,EAAE,CAAC;CACpB,GACD;IACE,IAAI,EAAE,QAAQ,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAEN,KAAK,SAAS,GACV;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAC7B;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC;AAErC,MAAM,MAAM,SAAS,GAAG;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,KAAK,EAAE,SAAS,EAAE,CAAC;CACpB,CAAC;AA6DF,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,mBAAmB,EAAE,CAqJ1E;AA4ED,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,SAAS,EAAE,GACjB;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAyEvC;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,WAG9C"}
@@ -0,0 +1,307 @@
1
+ import path from "node:path";
2
+ const normalizeNewlines = (value) => value.replace(/\r\n/g, "\n");
3
+ const normalizeLineForLooseMatch = (value) => value
4
+ .replace(/[ \t]+$/g, "")
5
+ .replace(/;$/g, "")
6
+ .replace(/['"]/g, '"');
7
+ const normalizeLineForWhitespaceAgnosticMatch = (value) => normalizeLineForLooseMatch(value).trim().replace(/\s+/g, " ");
8
+ const stripOuterMarkdownCodeFence = (value) => {
9
+ const lines = value.split("\n");
10
+ let start = 0;
11
+ while (start < lines.length && !lines[start].trim())
12
+ start += 1;
13
+ let end = lines.length - 1;
14
+ while (end >= 0 && !lines[end].trim())
15
+ end -= 1;
16
+ if (start >= end)
17
+ return value;
18
+ const first = lines[start].trim();
19
+ const last = lines[end].trim();
20
+ const isFenceStart = /^```[a-zA-Z0-9_-]*\s*$/.test(first);
21
+ const isFenceEnd = last === "```";
22
+ if (!isFenceStart || !isFenceEnd)
23
+ return value;
24
+ return lines.slice(start + 1, end).join("\n");
25
+ };
26
+ const dedentBlock = (value) => {
27
+ const lines = value.split("\n");
28
+ let minIndent = null;
29
+ for (const line of lines) {
30
+ if (!line.trim())
31
+ continue;
32
+ const match = /^[ \t]+/.exec(line);
33
+ const indent = match ? match[0].length : 0;
34
+ minIndent = minIndent === null ? indent : Math.min(minIndent, indent);
35
+ if (minIndent === 0)
36
+ break;
37
+ }
38
+ if (!minIndent)
39
+ return value;
40
+ return lines
41
+ .map((line) => {
42
+ if (!line.trim())
43
+ return line;
44
+ return line.slice(minIndent);
45
+ })
46
+ .join("\n");
47
+ };
48
+ const preprocessPatchString = (patchString) => {
49
+ const normalized = normalizeNewlines(patchString ?? "");
50
+ return dedentBlock(stripOuterMarkdownCodeFence(normalized));
51
+ };
52
+ export function parseApplyPatch(patchString) {
53
+ const preprocessed = preprocessPatchString(patchString);
54
+ const rawLines = preprocessed.split("\n");
55
+ let startIndex = 0;
56
+ while (startIndex < rawLines.length && !rawLines[startIndex].trim()) {
57
+ startIndex += 1;
58
+ }
59
+ if (startIndex >= rawLines.length ||
60
+ rawLines[startIndex].replace(/^\uFEFF/, "").trim() !== "*** Begin Patch") {
61
+ throw new Error('Invalid patch: missing "*** Begin Patch" header.');
62
+ }
63
+ let endIndex = -1;
64
+ for (let idx = rawLines.length - 1; idx >= startIndex; idx -= 1) {
65
+ if (rawLines[idx].trim() === "*** End Patch") {
66
+ endIndex = idx;
67
+ break;
68
+ }
69
+ }
70
+ if (endIndex === -1)
71
+ endIndex = rawLines.length;
72
+ const hasFooter = endIndex !== rawLines.length;
73
+ const hasNonEmptyAfterFooter = hasFooter
74
+ ? rawLines.slice(endIndex + 1).some((line) => Boolean(line.trim()))
75
+ : false;
76
+ const lines = hasFooter && !hasNonEmptyAfterFooter
77
+ ? rawLines.slice(startIndex + 1, endIndex)
78
+ : rawLines.slice(startIndex + 1);
79
+ const operations = [];
80
+ const isOpHeader = (line) => line.startsWith("*** Add File:") ||
81
+ line.startsWith("*** Update File:") ||
82
+ line.startsWith("*** Delete File:");
83
+ let i = 0;
84
+ while (i < lines.length) {
85
+ const line = lines[i];
86
+ if (line.trim() === "*** End Patch") {
87
+ i += 1;
88
+ continue;
89
+ }
90
+ if (!line.trim()) {
91
+ i += 1;
92
+ continue;
93
+ }
94
+ if (!isOpHeader(line)) {
95
+ throw new Error(`Invalid patch: expected file header at line ${i + 2}.`);
96
+ }
97
+ if (line.startsWith("*** Add File:") || line.startsWith("*** Update File:")) {
98
+ const kind = line.startsWith("*** Add File:") ? "add" : "update";
99
+ const headerLength = line.startsWith("*** Add File:")
100
+ ? "*** Add File:".length
101
+ : "*** Update File:".length;
102
+ const filePath = line.slice(headerLength).trim();
103
+ if (!filePath) {
104
+ throw new Error(`Invalid patch: empty ${kind === "add" ? "Add" : "Update"} File path.`);
105
+ }
106
+ i += 1;
107
+ let moveTo;
108
+ if (i < lines.length && lines[i].startsWith("*** Move to:")) {
109
+ if (kind !== "update") {
110
+ throw new Error(`Invalid patch: Move operations are only allowed for Update File.`);
111
+ }
112
+ moveTo = lines[i].slice("*** Move to:".length).trim();
113
+ if (!moveTo)
114
+ throw new Error(`Invalid patch: empty Move to path.`);
115
+ i += 1;
116
+ }
117
+ const hunks = [];
118
+ let currentHunk = null;
119
+ const pushHunk = () => {
120
+ if (!currentHunk)
121
+ return;
122
+ if (currentHunk.lines.length === 0 && !currentHunk.anchorEOF)
123
+ return;
124
+ hunks.push(currentHunk);
125
+ };
126
+ while (i < lines.length && !isOpHeader(lines[i])) {
127
+ const current = lines[i];
128
+ if (!currentHunk)
129
+ currentHunk = { lines: [] };
130
+ if (current.trim() === "*** End Patch") {
131
+ i += 1;
132
+ continue;
133
+ }
134
+ if (current === "*** End of File") {
135
+ currentHunk.anchorEOF = true;
136
+ i += 1;
137
+ continue;
138
+ }
139
+ if (current.startsWith("@@")) {
140
+ pushHunk();
141
+ currentHunk = { label: current.slice(2).trim() || undefined, lines: [] };
142
+ i += 1;
143
+ continue;
144
+ }
145
+ const prefix = current.slice(0, 1);
146
+ // Tolerate a common patch style:
147
+ // - For "*** Add File:", unprefixed lines are treated as additions (full line content preserved).
148
+ // - For "*** Update File:", unprefixed lines are treated as context (full line content preserved).
149
+ if (kind === "add") {
150
+ if (prefix === "+") {
151
+ currentHunk.lines.push({ kind: "add", text: current.slice(1) });
152
+ }
153
+ else if (prefix === "-") {
154
+ currentHunk.lines.push({ kind: "delete", text: current.slice(1) });
155
+ }
156
+ else {
157
+ currentHunk.lines.push({ kind: "add", text: current });
158
+ }
159
+ i += 1;
160
+ continue;
161
+ }
162
+ // update
163
+ if (prefix === " ")
164
+ currentHunk.lines.push({ kind: "context", text: current.slice(1) });
165
+ else if (prefix === "+")
166
+ currentHunk.lines.push({ kind: "add", text: current.slice(1) });
167
+ else if (prefix === "-")
168
+ currentHunk.lines.push({ kind: "delete", text: current.slice(1) });
169
+ else
170
+ currentHunk.lines.push({ kind: "context", text: current });
171
+ i += 1;
172
+ }
173
+ pushHunk();
174
+ operations.push({ kind, filePath, moveTo, hunks });
175
+ continue;
176
+ }
177
+ if (line.startsWith("*** Delete File:")) {
178
+ const filePath = line.slice("*** Delete File:".length).trim();
179
+ if (!filePath)
180
+ throw new Error("Invalid patch: empty Delete File path.");
181
+ operations.push({ kind: "delete", filePath });
182
+ i += 1;
183
+ continue;
184
+ }
185
+ }
186
+ return operations;
187
+ }
188
+ const findSubsequence = (haystack, needle, startIndex, anchorEOF) => {
189
+ if (needle.length === 0)
190
+ return anchorEOF ? haystack.length : startIndex;
191
+ const lastStart = haystack.length - needle.length;
192
+ const from = Math.max(0, Math.min(startIndex, haystack.length));
193
+ const candidates = anchorEOF ? [lastStart] : Array.from({ length: lastStart - from + 1 }, (_, i) => from + i);
194
+ for (const pos of candidates) {
195
+ if (pos < 0 || pos > lastStart)
196
+ continue;
197
+ let ok = true;
198
+ for (let i = 0; i < needle.length; i++) {
199
+ if ((haystack[pos + i] ?? "") !== needle[i]) {
200
+ ok = false;
201
+ break;
202
+ }
203
+ }
204
+ if (ok)
205
+ return pos;
206
+ }
207
+ return -1;
208
+ };
209
+ const findHunkPosition = (fileLines, expected, cursor, requireEnd) => {
210
+ const strictFromCursor = requireEnd
211
+ ? findSubsequence(fileLines, expected, 0, true)
212
+ : findSubsequence(fileLines, expected, cursor, false);
213
+ if (strictFromCursor !== -1)
214
+ return { pos: strictFromCursor, mode: "strict" };
215
+ if (!requireEnd) {
216
+ const strictFromStart = findSubsequence(fileLines, expected, 0, false);
217
+ if (strictFromStart !== -1)
218
+ return { pos: strictFromStart, mode: "strict" };
219
+ }
220
+ const looseFileLines = fileLines.map(normalizeLineForLooseMatch);
221
+ const looseExpected = expected.map(normalizeLineForLooseMatch);
222
+ const looseFromCursor = requireEnd
223
+ ? findSubsequence(looseFileLines, looseExpected, 0, true)
224
+ : findSubsequence(looseFileLines, looseExpected, cursor, false);
225
+ if (looseFromCursor !== -1)
226
+ return { pos: looseFromCursor, mode: "loose" };
227
+ if (!requireEnd) {
228
+ const looseFromStart = findSubsequence(looseFileLines, looseExpected, 0, false);
229
+ if (looseFromStart !== -1)
230
+ return { pos: looseFromStart, mode: "loose" };
231
+ }
232
+ const wsFileLines = fileLines.map(normalizeLineForWhitespaceAgnosticMatch);
233
+ const wsExpected = expected.map(normalizeLineForWhitespaceAgnosticMatch);
234
+ const wsFromCursor = requireEnd
235
+ ? findSubsequence(wsFileLines, wsExpected, 0, true)
236
+ : findSubsequence(wsFileLines, wsExpected, cursor, false);
237
+ if (wsFromCursor !== -1)
238
+ return { pos: wsFromCursor, mode: "ws" };
239
+ if (!requireEnd) {
240
+ const wsFromStart = findSubsequence(wsFileLines, wsExpected, 0, false);
241
+ if (wsFromStart !== -1)
242
+ return { pos: wsFromStart, mode: "ws" };
243
+ }
244
+ return { pos: -1, mode: "strict" };
245
+ };
246
+ export function applyHunksToContent(content, hunks) {
247
+ const normalized = normalizeNewlines(content);
248
+ const newline = content.includes("\r\n") ? "\r\n" : "\n";
249
+ const endsWithNewline = normalized.endsWith("\n");
250
+ const fileLines = normalized.split("\n");
251
+ let cursor = 0;
252
+ let changed = false;
253
+ for (const hunk of hunks) {
254
+ const expected = hunk.lines
255
+ .filter((l) => l.kind === "context" || l.kind === "delete")
256
+ .map((l) => l.text);
257
+ const requireEnd = Boolean(hunk.anchorEOF);
258
+ const { pos, mode } = findHunkPosition(fileLines, expected, cursor, requireEnd);
259
+ if (pos === -1) {
260
+ const preview = expected.slice(0, 3).join("\\n");
261
+ throw new Error(`Patch hunk failed to apply${hunk.label ? ` (${hunk.label})` : ""}: context not found. Expected (first lines): ${preview}`);
262
+ }
263
+ const linesEqual = (a, b) => {
264
+ if (mode === "strict")
265
+ return a === b;
266
+ if (mode === "loose") {
267
+ return normalizeLineForLooseMatch(a) === normalizeLineForLooseMatch(b);
268
+ }
269
+ return (normalizeLineForWhitespaceAgnosticMatch(a) ===
270
+ normalizeLineForWhitespaceAgnosticMatch(b));
271
+ };
272
+ let idx = pos;
273
+ for (const line of hunk.lines) {
274
+ if (line.kind === "context") {
275
+ if (!linesEqual(fileLines[idx] ?? "", line.text)) {
276
+ throw new Error(`Patch context mismatch at line ${idx + 1}: expected "${line.text}"`);
277
+ }
278
+ idx += 1;
279
+ continue;
280
+ }
281
+ if (line.kind === "delete") {
282
+ if (!linesEqual(fileLines[idx] ?? "", line.text)) {
283
+ throw new Error(`Patch delete mismatch at line ${idx + 1}: expected "${line.text}"`);
284
+ }
285
+ fileLines.splice(idx, 1);
286
+ changed = true;
287
+ continue;
288
+ }
289
+ if (line.kind === "add") {
290
+ fileLines.splice(idx, 0, line.text);
291
+ idx += 1;
292
+ changed = true;
293
+ }
294
+ }
295
+ cursor = idx;
296
+ }
297
+ let next = fileLines.join("\n");
298
+ if (endsWithNewline && !next.endsWith("\n"))
299
+ next += "\n";
300
+ next = next.replace(/\n/g, newline);
301
+ return { content: next, changed };
302
+ }
303
+ export function isTextFilePath(filePath) {
304
+ const ext = path.extname(filePath).toLowerCase();
305
+ return ext !== ".png" && ext !== ".jpg" && ext !== ".jpeg" && ext !== ".gif";
306
+ }
307
+ //# sourceMappingURL=applyPatch.helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"applyPatch.helpers.js","sourceRoot":"","sources":["../../../../src/ai/tools/helpers/applyPatch.helpers.ts"],"names":[],"mappings":"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","sourcesContent":["import path from \"node:path\";\n\nexport type ApplyPatchOperation =\n | {\n kind: \"update\";\n filePath: string;\n moveTo?: string;\n hunks: PatchHunk[];\n }\n | {\n kind: \"add\";\n filePath: string;\n hunks: PatchHunk[];\n }\n | {\n kind: \"delete\";\n filePath: string;\n };\n\ntype PatchLine =\n | { kind: \"context\"; text: string }\n | { kind: \"add\"; text: string }\n | { kind: \"delete\"; text: string };\n\nexport type PatchHunk = {\n label?: string;\n anchorEOF?: boolean;\n lines: PatchLine[];\n};\n\nconst normalizeNewlines = (value: string) => value.replace(/\\r\\n/g, \"\\n\");\n\nconst normalizeLineForLooseMatch = (value: string) =>\n value\n .replace(/[ \\t]+$/g, \"\")\n .replace(/;$/g, \"\")\n .replace(/['\"]/g, '\"');\n\nconst normalizeLineForWhitespaceAgnosticMatch = (value: string) =>\n normalizeLineForLooseMatch(value).trim().replace(/\\s+/g, \" \");\n\nconst stripOuterMarkdownCodeFence = (value: string) => {\n const lines = value.split(\"\\n\");\n\n let start = 0;\n while (start < lines.length && !lines[start].trim()) start += 1;\n\n let end = lines.length - 1;\n while (end >= 0 && !lines[end].trim()) end -= 1;\n\n if (start >= end) return value;\n\n const first = lines[start].trim();\n const last = lines[end].trim();\n\n const isFenceStart = /^```[a-zA-Z0-9_-]*\\s*$/.test(first);\n const isFenceEnd = last === \"```\";\n\n if (!isFenceStart || !isFenceEnd) return value;\n\n return lines.slice(start + 1, end).join(\"\\n\");\n};\n\nconst dedentBlock = (value: string) => {\n const lines = value.split(\"\\n\");\n let minIndent: number | null = null;\n\n for (const line of lines) {\n if (!line.trim()) continue;\n const match = /^[ \\t]+/.exec(line);\n const indent = match ? match[0].length : 0;\n minIndent = minIndent === null ? indent : Math.min(minIndent, indent);\n if (minIndent === 0) break;\n }\n\n if (!minIndent) return value;\n return lines\n .map((line) => {\n if (!line.trim()) return line;\n return line.slice(minIndent);\n })\n .join(\"\\n\");\n};\n\nconst preprocessPatchString = (patchString: string) => {\n const normalized = normalizeNewlines(patchString ?? \"\");\n return dedentBlock(stripOuterMarkdownCodeFence(normalized));\n};\n\nexport function parseApplyPatch(patchString: string): ApplyPatchOperation[] {\n const preprocessed = preprocessPatchString(patchString);\n const rawLines = preprocessed.split(\"\\n\");\n\n let startIndex = 0;\n while (startIndex < rawLines.length && !rawLines[startIndex].trim()) {\n startIndex += 1;\n }\n if (\n startIndex >= rawLines.length ||\n rawLines[startIndex].replace(/^\\uFEFF/, \"\").trim() !== \"*** Begin Patch\"\n ) {\n throw new Error('Invalid patch: missing \"*** Begin Patch\" header.');\n }\n\n let endIndex = -1;\n for (let idx = rawLines.length - 1; idx >= startIndex; idx -= 1) {\n if (rawLines[idx].trim() === \"*** End Patch\") {\n endIndex = idx;\n break;\n }\n }\n if (endIndex === -1) endIndex = rawLines.length;\n\n const hasFooter = endIndex !== rawLines.length;\n const hasNonEmptyAfterFooter = hasFooter\n ? rawLines.slice(endIndex + 1).some((line) => Boolean(line.trim()))\n : false;\n const lines =\n hasFooter && !hasNonEmptyAfterFooter\n ? rawLines.slice(startIndex + 1, endIndex)\n : rawLines.slice(startIndex + 1);\n const operations: ApplyPatchOperation[] = [];\n\n const isOpHeader = (line: string) =>\n line.startsWith(\"*** Add File:\") ||\n line.startsWith(\"*** Update File:\") ||\n line.startsWith(\"*** Delete File:\");\n\n let i = 0;\n while (i < lines.length) {\n const line = lines[i];\n if (line.trim() === \"*** End Patch\") {\n i += 1;\n continue;\n }\n if (!line.trim()) {\n i += 1;\n continue;\n }\n\n if (!isOpHeader(line)) {\n throw new Error(`Invalid patch: expected file header at line ${i + 2}.`);\n }\n\n if (line.startsWith(\"*** Add File:\") || line.startsWith(\"*** Update File:\")) {\n const kind = line.startsWith(\"*** Add File:\") ? \"add\" : \"update\";\n const headerLength = line.startsWith(\"*** Add File:\")\n ? \"*** Add File:\".length\n : \"*** Update File:\".length;\n const filePath = line.slice(headerLength).trim();\n if (!filePath) {\n throw new Error(\n `Invalid patch: empty ${kind === \"add\" ? \"Add\" : \"Update\"} File path.`,\n );\n }\n i += 1;\n\n let moveTo: string | undefined;\n if (i < lines.length && lines[i].startsWith(\"*** Move to:\")) {\n if (kind !== \"update\") {\n throw new Error(`Invalid patch: Move operations are only allowed for Update File.`);\n }\n moveTo = lines[i].slice(\"*** Move to:\".length).trim();\n if (!moveTo) throw new Error(`Invalid patch: empty Move to path.`);\n i += 1;\n }\n\n const hunks: PatchHunk[] = [];\n let currentHunk: PatchHunk | null = null;\n\n const pushHunk = () => {\n if (!currentHunk) return;\n if (currentHunk.lines.length === 0 && !currentHunk.anchorEOF) return;\n hunks.push(currentHunk);\n };\n\n while (i < lines.length && !isOpHeader(lines[i])) {\n const current = lines[i];\n if (!currentHunk) currentHunk = { lines: [] };\n\n if (current.trim() === \"*** End Patch\") {\n i += 1;\n continue;\n }\n\n if (current === \"*** End of File\") {\n currentHunk.anchorEOF = true;\n i += 1;\n continue;\n }\n\n if (current.startsWith(\"@@\")) {\n pushHunk();\n currentHunk = { label: current.slice(2).trim() || undefined, lines: [] };\n i += 1;\n continue;\n }\n\n const prefix = current.slice(0, 1);\n\n // Tolerate a common patch style:\n // - For \"*** Add File:\", unprefixed lines are treated as additions (full line content preserved).\n // - For \"*** Update File:\", unprefixed lines are treated as context (full line content preserved).\n if (kind === \"add\") {\n if (prefix === \"+\") {\n currentHunk.lines.push({ kind: \"add\", text: current.slice(1) });\n } else if (prefix === \"-\") {\n currentHunk.lines.push({ kind: \"delete\", text: current.slice(1) });\n } else {\n currentHunk.lines.push({ kind: \"add\", text: current });\n }\n i += 1;\n continue;\n }\n\n // update\n if (prefix === \" \") currentHunk.lines.push({ kind: \"context\", text: current.slice(1) });\n else if (prefix === \"+\") currentHunk.lines.push({ kind: \"add\", text: current.slice(1) });\n else if (prefix === \"-\") currentHunk.lines.push({ kind: \"delete\", text: current.slice(1) });\n else currentHunk.lines.push({ kind: \"context\", text: current });\n i += 1;\n }\n\n pushHunk();\n operations.push({ kind, filePath, moveTo, hunks } as any);\n continue;\n }\n\n if (line.startsWith(\"*** Delete File:\")) {\n const filePath = line.slice(\"*** Delete File:\".length).trim();\n if (!filePath) throw new Error(\"Invalid patch: empty Delete File path.\");\n operations.push({ kind: \"delete\", filePath });\n i += 1;\n continue;\n }\n }\n\n return operations;\n}\n\nconst findSubsequence = (\n haystack: string[],\n needle: string[],\n startIndex: number,\n anchorEOF: boolean,\n) => {\n if (needle.length === 0) return anchorEOF ? haystack.length : startIndex;\n\n const lastStart = haystack.length - needle.length;\n const from = Math.max(0, Math.min(startIndex, haystack.length));\n const candidates = anchorEOF ? [lastStart] : Array.from({ length: lastStart - from + 1 }, (_, i) => from + i);\n\n for (const pos of candidates) {\n if (pos < 0 || pos > lastStart) continue;\n let ok = true;\n for (let i = 0; i < needle.length; i++) {\n if ((haystack[pos + i] ?? \"\") !== needle[i]) {\n ok = false;\n break;\n }\n }\n if (ok) return pos;\n }\n\n return -1;\n};\n\ntype HunkSearchResult = { pos: number; mode: \"strict\" | \"loose\" | \"ws\" };\n\nconst findHunkPosition = (\n fileLines: string[],\n expected: string[],\n cursor: number,\n requireEnd: boolean,\n): HunkSearchResult => {\n const strictFromCursor = requireEnd\n ? findSubsequence(fileLines, expected, 0, true)\n : findSubsequence(fileLines, expected, cursor, false);\n if (strictFromCursor !== -1) return { pos: strictFromCursor, mode: \"strict\" };\n\n if (!requireEnd) {\n const strictFromStart = findSubsequence(fileLines, expected, 0, false);\n if (strictFromStart !== -1) return { pos: strictFromStart, mode: \"strict\" };\n }\n\n const looseFileLines = fileLines.map(normalizeLineForLooseMatch);\n const looseExpected = expected.map(normalizeLineForLooseMatch);\n\n const looseFromCursor = requireEnd\n ? findSubsequence(looseFileLines, looseExpected, 0, true)\n : findSubsequence(looseFileLines, looseExpected, cursor, false);\n if (looseFromCursor !== -1) return { pos: looseFromCursor, mode: \"loose\" };\n\n if (!requireEnd) {\n const looseFromStart = findSubsequence(looseFileLines, looseExpected, 0, false);\n if (looseFromStart !== -1) return { pos: looseFromStart, mode: \"loose\" };\n }\n\n const wsFileLines = fileLines.map(normalizeLineForWhitespaceAgnosticMatch);\n const wsExpected = expected.map(normalizeLineForWhitespaceAgnosticMatch);\n\n const wsFromCursor = requireEnd\n ? findSubsequence(wsFileLines, wsExpected, 0, true)\n : findSubsequence(wsFileLines, wsExpected, cursor, false);\n if (wsFromCursor !== -1) return { pos: wsFromCursor, mode: \"ws\" };\n\n if (!requireEnd) {\n const wsFromStart = findSubsequence(wsFileLines, wsExpected, 0, false);\n if (wsFromStart !== -1) return { pos: wsFromStart, mode: \"ws\" };\n }\n\n return { pos: -1, mode: \"strict\" };\n};\n\nexport function applyHunksToContent(\n content: string,\n hunks: PatchHunk[],\n): { content: string; changed: boolean } {\n const normalized = normalizeNewlines(content);\n const newline = content.includes(\"\\r\\n\") ? \"\\r\\n\" : \"\\n\";\n const endsWithNewline = normalized.endsWith(\"\\n\");\n const fileLines = normalized.split(\"\\n\");\n\n let cursor = 0;\n let changed = false;\n\n for (const hunk of hunks) {\n const expected = hunk.lines\n .filter((l) => l.kind === \"context\" || l.kind === \"delete\")\n .map((l) => l.text);\n\n const requireEnd = Boolean(hunk.anchorEOF);\n const { pos, mode } = findHunkPosition(fileLines, expected, cursor, requireEnd);\n\n if (pos === -1) {\n const preview = expected.slice(0, 3).join(\"\\\\n\");\n throw new Error(\n `Patch hunk failed to apply${hunk.label ? ` (${hunk.label})` : \"\"}: context not found. Expected (first lines): ${preview}`,\n );\n }\n\n const linesEqual = (a: string, b: string) => {\n if (mode === \"strict\") return a === b;\n if (mode === \"loose\") {\n return normalizeLineForLooseMatch(a) === normalizeLineForLooseMatch(b);\n }\n return (\n normalizeLineForWhitespaceAgnosticMatch(a) ===\n normalizeLineForWhitespaceAgnosticMatch(b)\n );\n };\n\n let idx = pos;\n for (const line of hunk.lines) {\n if (line.kind === \"context\") {\n if (!linesEqual(fileLines[idx] ?? \"\", line.text)) {\n throw new Error(\n `Patch context mismatch at line ${idx + 1}: expected \"${line.text}\"`,\n );\n }\n idx += 1;\n continue;\n }\n\n if (line.kind === \"delete\") {\n if (!linesEqual(fileLines[idx] ?? \"\", line.text)) {\n throw new Error(\n `Patch delete mismatch at line ${idx + 1}: expected \"${line.text}\"`,\n );\n }\n fileLines.splice(idx, 1);\n changed = true;\n continue;\n }\n\n if (line.kind === \"add\") {\n fileLines.splice(idx, 0, line.text);\n idx += 1;\n changed = true;\n }\n }\n\n cursor = idx;\n }\n\n let next = fileLines.join(\"\\n\");\n if (endsWithNewline && !next.endsWith(\"\\n\")) next += \"\\n\";\n next = next.replace(/\\n/g, newline);\n\n return { content: next, changed };\n}\n\nexport function isTextFilePath(filePath: string) {\n const ext = path.extname(filePath).toLowerCase();\n return ext !== \".png\" && ext !== \".jpg\" && ext !== \".jpeg\" && ext !== \".gif\";\n}\n"]}