@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.
- package/dist/ai/generate/gemini.client.js +1 -1
- package/dist/ai/generate/gemini.client.js.map +1 -1
- package/dist/ai/generate/generateClient.d.ts.map +1 -1
- package/dist/ai/generate/generateClient.js +7 -3
- package/dist/ai/generate/generateClient.js.map +1 -1
- package/dist/ai/toolLoop/helpers/aiCall.helper.d.ts +16 -0
- package/dist/ai/toolLoop/helpers/aiCall.helper.d.ts.map +1 -0
- package/dist/ai/toolLoop/helpers/aiCall.helper.js +23 -0
- package/dist/ai/toolLoop/helpers/aiCall.helper.js.map +1 -0
- package/dist/ai/toolLoop/helpers/applyPatch.helper.d.ts +6 -0
- package/dist/ai/toolLoop/helpers/applyPatch.helper.d.ts.map +1 -0
- package/dist/ai/toolLoop/helpers/applyPatch.helper.js +10 -0
- package/dist/ai/toolLoop/helpers/applyPatch.helper.js.map +1 -0
- package/dist/ai/toolLoop/helpers/errors.helper.d.ts +15 -0
- package/dist/ai/toolLoop/helpers/errors.helper.d.ts.map +1 -0
- package/dist/ai/toolLoop/helpers/errors.helper.js +50 -0
- package/dist/ai/toolLoop/helpers/errors.helper.js.map +1 -0
- package/dist/ai/toolLoop/helpers/fsHelpers.d.ts +5 -0
- package/dist/ai/toolLoop/helpers/fsHelpers.d.ts.map +1 -0
- package/dist/ai/toolLoop/helpers/fsHelpers.js +28 -0
- package/dist/ai/toolLoop/helpers/fsHelpers.js.map +1 -0
- package/dist/ai/toolLoop/helpers/patchRetry.helper.d.ts +11 -0
- package/dist/ai/toolLoop/helpers/patchRetry.helper.d.ts.map +1 -0
- package/dist/ai/toolLoop/helpers/patchRetry.helper.js +30 -0
- package/dist/ai/toolLoop/helpers/patchRetry.helper.js.map +1 -0
- package/dist/ai/toolLoop/helpers/persistTokens.helpers.d.ts +7 -0
- package/dist/ai/toolLoop/helpers/persistTokens.helpers.d.ts.map +1 -0
- package/dist/ai/toolLoop/helpers/persistTokens.helpers.js +25 -0
- package/dist/ai/toolLoop/helpers/persistTokens.helpers.js.map +1 -0
- package/dist/ai/toolLoop/{plannerTaskParser.d.ts → helpers/plannerTaskParser.d.ts} +1 -1
- package/dist/ai/toolLoop/helpers/plannerTaskParser.d.ts.map +1 -0
- package/dist/ai/toolLoop/helpers/plannerTaskParser.js.map +1 -0
- package/dist/ai/toolLoop/helpers/readFile.helpers.d.ts +10 -0
- package/dist/ai/toolLoop/helpers/readFile.helpers.d.ts.map +1 -0
- package/dist/ai/toolLoop/helpers/readFile.helpers.js +26 -0
- package/dist/ai/toolLoop/helpers/readFile.helpers.js.map +1 -0
- package/dist/ai/toolLoop/helpers/signatures.helper.d.ts +2 -0
- package/dist/ai/toolLoop/helpers/signatures.helper.d.ts.map +1 -0
- package/dist/ai/toolLoop/helpers/signatures.helper.js +23 -0
- package/dist/ai/toolLoop/helpers/signatures.helper.js.map +1 -0
- package/dist/ai/toolLoop/helpers/toolArgs.helper.d.ts +12 -0
- package/dist/ai/toolLoop/helpers/toolArgs.helper.d.ts.map +1 -0
- package/dist/ai/toolLoop/helpers/toolArgs.helper.js +40 -0
- package/dist/ai/toolLoop/helpers/toolArgs.helper.js.map +1 -0
- package/dist/ai/toolLoop/helpers/toolExecution.helper.d.ts +22 -0
- package/dist/ai/toolLoop/helpers/toolExecution.helper.d.ts.map +1 -0
- package/dist/ai/toolLoop/helpers/toolExecution.helper.js +75 -0
- package/dist/ai/toolLoop/helpers/toolExecution.helper.js.map +1 -0
- package/dist/ai/toolLoop/helpers/toolHandlers.helper.d.ts +6 -0
- package/dist/ai/toolLoop/helpers/toolHandlers.helper.d.ts.map +1 -0
- package/dist/ai/toolLoop/helpers/toolHandlers.helper.js +86 -0
- package/dist/ai/toolLoop/helpers/toolHandlers.helper.js.map +1 -0
- package/dist/ai/toolLoop/toolEventSummary.d.ts +28 -0
- package/dist/ai/toolLoop/toolEventSummary.d.ts.map +1 -0
- package/dist/ai/toolLoop/toolEventSummary.js +253 -0
- package/dist/ai/toolLoop/toolEventSummary.js.map +1 -0
- package/dist/ai/toolLoop/toolLoopContext.d.ts +0 -14
- package/dist/ai/toolLoop/toolLoopContext.d.ts.map +1 -1
- package/dist/ai/toolLoop/toolLoopContext.js +7 -50
- package/dist/ai/toolLoop/toolLoopContext.js.map +1 -1
- package/dist/ai/toolLoop/toolLoopRunner.d.ts +6 -5
- package/dist/ai/toolLoop/toolLoopRunner.d.ts.map +1 -1
- package/dist/ai/toolLoop/toolLoopRunner.js +48 -281
- package/dist/ai/toolLoop/toolLoopRunner.js.map +1 -1
- package/dist/ai/toolLoop/toolStatusMessage.d.ts +6 -0
- package/dist/ai/toolLoop/toolStatusMessage.d.ts.map +1 -0
- package/dist/ai/toolLoop/toolStatusMessage.js +140 -0
- package/dist/ai/toolLoop/toolStatusMessage.js.map +1 -0
- package/dist/ai/tools/helpers/applyPatch.helpers.d.ts.map +1 -1
- package/dist/ai/tools/helpers/applyPatch.helpers.js +9 -4
- package/dist/ai/tools/helpers/applyPatch.helpers.js.map +1 -1
- package/dist/ai/tools/helpers/fileSystem.helpers.d.ts.map +1 -1
- package/dist/ai/tools/helpers/fileSystem.helpers.js +7 -1
- package/dist/ai/tools/helpers/fileSystem.helpers.js.map +1 -1
- package/dist/ai/tools/helpers/pageConfigJson.helpers.d.ts +13 -0
- package/dist/ai/tools/helpers/pageConfigJson.helpers.d.ts.map +1 -1
- package/dist/ai/tools/helpers/pageConfigJson.helpers.js +51 -21
- package/dist/ai/tools/helpers/pageConfigJson.helpers.js.map +1 -1
- package/dist/ai/tools/implementations/applyPatch.impl.js +2 -2
- package/dist/ai/tools/implementations/applyPatch.impl.js.map +1 -1
- package/dist/ai/tools/implementations/createNewRoute.impl.js +1 -1
- package/dist/ai/tools/implementations/createNewRoute.impl.js.map +1 -1
- package/dist/ai/tools/implementations/deleteElement.impl.d.ts.map +1 -1
- package/dist/ai/tools/implementations/deleteElement.impl.js +5 -37
- package/dist/ai/tools/implementations/deleteElement.impl.js.map +1 -1
- package/dist/ai/tools/implementations/insertElement.impl.d.ts.map +1 -1
- package/dist/ai/tools/implementations/insertElement.impl.js +9 -46
- package/dist/ai/tools/implementations/insertElement.impl.js.map +1 -1
- package/dist/ai/tools/implementations/updateClassName.impl.d.ts.map +1 -1
- package/dist/ai/tools/implementations/updateClassName.impl.js +5 -37
- package/dist/ai/tools/implementations/updateClassName.impl.js.map +1 -1
- package/dist/ai/tools/implementations/updateGlobalStyles.impl.d.ts.map +1 -1
- package/dist/ai/tools/implementations/updateGlobalStyles.impl.js +4 -3
- package/dist/ai/tools/implementations/updateGlobalStyles.impl.js.map +1 -1
- package/dist/ai/tools/implementations/updateProps.impl.d.ts.map +1 -1
- package/dist/ai/tools/implementations/updateProps.impl.js +5 -37
- package/dist/ai/tools/implementations/updateProps.impl.js.map +1 -1
- package/dist/ai/tools/schemas/createNewRoute.schema.d.ts.map +1 -1
- package/dist/ai/tools/schemas/createNewRoute.schema.js +1 -1
- package/dist/ai/tools/schemas/createNewRoute.schema.js.map +1 -1
- package/dist/ai/tools/schemas/deleteElement.schema.d.ts.map +1 -1
- package/dist/ai/tools/schemas/deleteElement.schema.js +1 -2
- package/dist/ai/tools/schemas/deleteElement.schema.js.map +1 -1
- package/dist/ai/tools/schemas/elementProps.schema.d.ts +101 -0
- package/dist/ai/tools/schemas/elementProps.schema.d.ts.map +1 -0
- package/dist/ai/tools/schemas/elementProps.schema.js +74 -0
- package/dist/ai/tools/schemas/elementProps.schema.js.map +1 -0
- package/dist/ai/tools/schemas/insertElement.schema.d.ts.map +1 -1
- package/dist/ai/tools/schemas/insertElement.schema.js +2 -74
- package/dist/ai/tools/schemas/insertElement.schema.js.map +1 -1
- package/dist/ai/tools/schemas/updateClassName.schema.d.ts.map +1 -1
- package/dist/ai/tools/schemas/updateClassName.schema.js +1 -2
- package/dist/ai/tools/schemas/updateClassName.schema.js.map +1 -1
- package/dist/ai/tools/schemas/updateProps.schema.d.ts +9 -9
- package/dist/ai/tools/schemas/updateProps.schema.d.ts.map +1 -1
- package/dist/ai/tools/schemas/updateProps.schema.js +3 -69
- package/dist/ai/tools/schemas/updateProps.schema.js.map +1 -1
- package/dist/image/unsplash.service.d.ts.map +1 -1
- package/dist/image/unsplash.service.js +6 -2
- package/dist/image/unsplash.service.js.map +1 -1
- package/dist/indexer/projectInfoIndex.d.ts.map +1 -1
- package/dist/indexer/projectInfoIndex.js +33 -25
- package/dist/indexer/projectInfoIndex.js.map +1 -1
- package/dist/types/styleConfig.d.ts.map +1 -1
- package/dist/types/styleConfig.js +2 -3
- package/dist/types/styleConfig.js.map +1 -1
- package/dist/utils/utils.d.ts +3 -0
- package/dist/utils/utils.d.ts.map +1 -1
- package/dist/utils/utils.js +8 -0
- package/dist/utils/utils.js.map +1 -1
- package/dist/utils/workspace.d.ts +1 -1
- package/dist/utils/workspace.d.ts.map +1 -1
- package/dist/utils/workspace.js +6 -11
- package/dist/utils/workspace.js.map +1 -1
- package/package.json +1 -1
- package/dist/ai/toolLoop/plannerTaskParser.d.ts.map +0 -1
- package/dist/ai/toolLoop/plannerTaskParser.js.map +0 -1
- package/dist/ai/toolLoop/toolLoopRunnerUtils.d.ts +0 -51
- package/dist/ai/toolLoop/toolLoopRunnerUtils.d.ts.map +0 -1
- package/dist/ai/toolLoop/toolLoopRunnerUtils.js +0 -367
- package/dist/ai/toolLoop/toolLoopRunnerUtils.js.map +0 -1
- /package/dist/ai/toolLoop/{plannerTaskParser.js → helpers/plannerTaskParser.js} +0 -0
|
@@ -1,25 +1,10 @@
|
|
|
1
|
-
import
|
|
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: {
|
|
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":"AAAA,OAAO,
|
|
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;
|
|
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 {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
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
|
-
|
|
59
|
-
|
|
60
|
-
|
|
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
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
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
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
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
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
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,
|