@vedangiitb/qwintly-core 1.3.7 → 1.3.9
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/prompts/codegen.prompt.d.ts.map +1 -1
- package/dist/ai/prompts/codegen.prompt.js +37 -39
- package/dist/ai/prompts/codegen.prompt.js.map +1 -1
- package/dist/ai/prompts/examples/codegen.examples.js +1 -1
- package/dist/ai/prompts/examples/codegen.examples.js.map +1 -1
- package/dist/ai/prompts/examples/planner.examples.d.ts.map +1 -1
- package/dist/ai/prompts/examples/planner.examples.js +6 -1
- package/dist/ai/prompts/examples/planner.examples.js.map +1 -1
- package/dist/ai/prompts/helpers/promptParts.helper.d.ts +1 -3
- package/dist/ai/prompts/helpers/promptParts.helper.d.ts.map +1 -1
- package/dist/ai/prompts/helpers/promptParts.helper.js +9 -18
- package/dist/ai/prompts/helpers/promptParts.helper.js.map +1 -1
- package/dist/ai/prompts/planner.prompt.d.ts.map +1 -1
- package/dist/ai/prompts/planner.prompt.js +32 -36
- package/dist/ai/prompts/planner.prompt.js.map +1 -1
- package/dist/ai/prompts/validator.prompt.d.ts.map +1 -1
- package/dist/ai/prompts/validator.prompt.js +38 -39
- package/dist/ai/prompts/validator.prompt.js.map +1 -1
- package/dist/ai/toolLoop/toolLoopContext.js +1 -1
- package/dist/ai/toolLoop/toolLoopContext.js.map +1 -1
- package/dist/ai/toolLoop/toolLoopRunner.d.ts.map +1 -1
- package/dist/ai/toolLoop/toolLoopRunner.js +22 -15
- package/dist/ai/toolLoop/toolLoopRunner.js.map +1 -1
- package/dist/ai/toolLoop/toolLoopRunnerUtils.d.ts.map +1 -1
- package/dist/ai/toolLoop/toolLoopRunnerUtils.js +13 -0
- package/dist/ai/toolLoop/toolLoopRunnerUtils.js.map +1 -1
- package/dist/ai/tools/implementations/createNewRoute.impl.d.ts +13 -1
- package/dist/ai/tools/implementations/createNewRoute.impl.d.ts.map +1 -1
- package/dist/ai/tools/implementations/createNewRoute.impl.js +98 -29
- package/dist/ai/tools/implementations/createNewRoute.impl.js.map +1 -1
- package/dist/ai/tools/implementations/factories.d.ts +17 -2
- package/dist/ai/tools/implementations/factories.d.ts.map +1 -1
- package/dist/ai/tools/implementations/insertElement.impl.d.ts.map +1 -1
- package/dist/ai/tools/implementations/insertElement.impl.js +1 -1
- package/dist/ai/tools/implementations/insertElement.impl.js.map +1 -1
- package/dist/ai/tools/implementations/readFile.impl.d.ts +4 -1
- package/dist/ai/tools/implementations/readFile.impl.d.ts.map +1 -1
- package/dist/ai/tools/implementations/readFile.impl.js +10 -0
- package/dist/ai/tools/implementations/readFile.impl.js.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/insertElement.schema.d.ts.map +1 -1
- package/dist/ai/tools/schemas/insertElement.schema.js +7 -7
- package/dist/ai/tools/schemas/insertElement.schema.js.map +1 -1
- package/dist/ai/tools/schemas/updateProps.schema.js +1 -1
- 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 +1 -0
- package/dist/image/unsplash.service.js.map +1 -1
- package/dist/indexer/data/configs.constants.d.ts +21 -28
- package/dist/indexer/data/configs.constants.d.ts.map +1 -1
- package/dist/indexer/data/configs.constants.js +34 -45
- package/dist/indexer/data/configs.constants.js.map +1 -1
- package/dist/tests/createNewRoute.impl.test.js +11 -3
- package/dist/tests/createNewRoute.impl.test.js.map +1 -1
- package/dist/types/public.d.ts +0 -1
- package/dist/types/public.d.ts.map +1 -1
- package/dist/types/public.js.map +1 -1
- package/package.json +1 -1
- package/dist/types/index/conventions.types.d.ts +0 -40
- package/dist/types/index/conventions.types.d.ts.map +0 -1
- package/dist/types/index/conventions.types.js +0 -2
- package/dist/types/index/conventions.types.js.map +0 -1
|
@@ -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;AAChE,OAAO,EAAe,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAML,qBAAqB,EACtB,MAAM,sBAAsB,CAAC;AAS9B,MAAM,MAAM,WAAW,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAE9E,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,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAE9E,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,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACtC,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;CAC/B,CAAC;AAEF,wBAAsB,WAAW,CAC/B,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,cAAc,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,EAAe,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EAML,qBAAqB,EACtB,MAAM,sBAAsB,CAAC;AAS9B,MAAM,MAAM,WAAW,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAE9E,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,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,SAAS,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;AAE9E,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,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,CAAC;IACtC,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;CAC/B,CAAC;AAEF,wBAAsB,WAAW,CAC/B,OAAO,EAAE,kBAAkB,GAC1B,OAAO,CAAC,cAAc,CAAC,CA4SzB"}
|
|
@@ -142,21 +142,28 @@ export async function runToolLoop(options) {
|
|
|
142
142
|
let toolResult = toolResultRaw;
|
|
143
143
|
if (name === "read_file" && readFileMeta) {
|
|
144
144
|
const path = String(effectiveArgs.path ?? "");
|
|
145
|
-
const
|
|
146
|
-
|
|
147
|
-
:
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
:
|
|
159
|
-
|
|
145
|
+
const jsonPayload = toolResultRaw?.kind === "json" ? toolResultRaw?.json : undefined;
|
|
146
|
+
if (jsonPayload !== undefined) {
|
|
147
|
+
// Token-efficient: return JSON as structured data (no double-stringifying).
|
|
148
|
+
toolResult = { path, json: jsonPayload };
|
|
149
|
+
}
|
|
150
|
+
else {
|
|
151
|
+
const rawContent = typeof toolResultRaw?.content === "string"
|
|
152
|
+
? String(toolResultRaw.content)
|
|
153
|
+
: typeof toolResultRaw === "string"
|
|
154
|
+
? toolResultRaw
|
|
155
|
+
: JSON.stringify(toolResultRaw ?? null);
|
|
156
|
+
toolResult = {
|
|
157
|
+
path,
|
|
158
|
+
start_line: readFileMeta.start,
|
|
159
|
+
end_line: readFileMeta.end,
|
|
160
|
+
truncated: readFileMeta.wasCapped,
|
|
161
|
+
content: rawContent,
|
|
162
|
+
note: readFileMeta.wasCapped
|
|
163
|
+
? `Capped to ${policy.readFileDefaultMaxLines} lines. Request more with start_line/end_line.`
|
|
164
|
+
: undefined,
|
|
165
|
+
};
|
|
166
|
+
}
|
|
160
167
|
}
|
|
161
168
|
try {
|
|
162
169
|
await persistToolCall(name, modelArgs, toolResult);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"toolLoopRunner.js","sourceRoot":"","sources":["../../../src/ai/toolLoop/toolLoopRunner.ts"],"names":[],"mappings":"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","sourcesContent":["import { FunctionCallingConfigMode, Tool } from \"@google/genai\";\nimport { EVENT_TYPES, EventType } from \"../../types/events.js\";\nimport {\n compactForModel,\n DEFAULT_CONTEXT_POLICY,\n normalizeReadFileArgs,\n redactFunctionCallArgs,\n ToolEvent,\n ToolLoopContextPolicy,\n} from \"./toolLoopContext.js\";\nimport {\n aiCallWithRetry,\n buildToolStatusMessage,\n recordToolEvent,\n serializeError,\n} from \"./toolLoopRunnerUtils.js\";\nimport { persistToolCall } from \"../../services/toolcallPersist.service.js\";\n\nexport type ToolHandler = (args: Record<string, unknown>) => Promise<unknown>;\n\nexport type ToolLoopResult = {\n contents: any[];\n modelContents: any[];\n finalText: string;\n steps: number;\n terminalCall?: {\n name: string;\n args: Record<string, unknown>;\n response: unknown;\n };\n};\n\nexport type Logger = (message: string, eventType: EventType) => Promise<void>;\n\nexport type AiCallResponse = {\n functionCalls?: any[];\n text?: string;\n};\n\nexport type AiCallFn = (\n request: unknown,\n options: {\n tools?: Tool[];\n model?: string;\n toolCallingMode?: FunctionCallingConfigMode;\n },\n) => Promise<AiCallResponse>;\n\nexport type RunToolLoopOptions = {\n initialContents: any[];\n tools: Tool[];\n handlers: Record<string, ToolHandler>;\n maxSteps?: number;\n toolCallingMode?: FunctionCallingConfigMode;\n terminalToolNames?: string[];\n keepFullTrace?: boolean;\n contextPolicy?: ToolLoopContextPolicy;\n aiCall: AiCallFn;\n logger: Logger;\n applyPatchAutoRetryMax?: number;\n aiCallAutoRetryMax?: number;\n aiCallAutoRetryBaseMs?: number;\n aiCallAutoRetryMaxMs?: number;\n};\n\nexport async function runToolLoop(\n options: RunToolLoopOptions,\n): Promise<ToolLoopResult> {\n const {\n initialContents,\n tools,\n handlers,\n maxSteps = 30,\n toolCallingMode = FunctionCallingConfigMode.ANY,\n terminalToolNames = [],\n keepFullTrace = true,\n contextPolicy,\n aiCall,\n logger,\n applyPatchAutoRetryMax = 2,\n aiCallAutoRetryMax = 3, // must have it to try 3 times as gemini errors a lot due to high demand sometimes\n aiCallAutoRetryBaseMs = 400,\n aiCallAutoRetryMaxMs = 10_000,\n } = options;\n\n if (typeof aiCall !== \"function\") {\n throw new Error(\"Tool loop: aiCall is required.\");\n }\n\n const policy: Required<ToolLoopContextPolicy> = {\n ...DEFAULT_CONTEXT_POLICY,\n ...(contextPolicy ?? {}),\n };\n\n const toolEvents: ToolEvent[] = [];\n let applyPatchRetryCount = 0;\n\n const fullTraceContents: any[] = keepFullTrace ? [...initialContents] : [];\n let modelContents: any[] = [...initialContents];\n const pushBoth = (fullItem: any, modelItem: any) => {\n if (keepFullTrace) fullTraceContents.push(fullItem);\n modelContents.push(modelItem);\n };\n const pushModelOnly = (modelItem: any) => {\n modelContents.push(modelItem);\n };\n\n for (let step = 0; step < maxSteps; step++) {\n modelContents = compactForModel({\n initialCount: initialContents.length,\n modelContents,\n toolEvents,\n policy,\n });\n\n if (policy.logApproxModelChars) {\n const approxChars = JSON.stringify(modelContents).length;\n console.log(\"Tool loop: approx model chars\", {\n approxChars,\n step: step + 1,\n });\n }\n\n let response: Awaited<ReturnType<AiCallFn>>;\n response = await aiCallWithRetry({\n aiCall,\n request: modelContents,\n options: { tools, toolCallingMode },\n retryMax: aiCallAutoRetryMax,\n retryBaseMs: aiCallAutoRetryBaseMs,\n retryMaxMs: aiCallAutoRetryMaxMs,\n step: step + 1,\n logger,\n });\n\n const functionCalls = response.functionCalls ?? [];\n if (functionCalls.length === 0) {\n return {\n contents: keepFullTrace ? fullTraceContents : modelContents,\n modelContents,\n finalText: (response.text ?? \"\").trim(),\n steps: step + 1,\n };\n }\n\n for (const call of functionCalls) {\n const name = call.name?.toString() ?? \"\";\n const args = (call.args ?? {}) as Record<string, unknown>;\n\n if (!name) {\n throw new Error(\"Tool loop: function call missing name.\");\n }\n\n const handler = handlers[name];\n const handlerMissingResult = !handler\n ? {\n success: false,\n error: `No handler registered for \"${name}\".`,\n error_detail: {\n name: \"MissingToolHandlerError\",\n message: `No handler registered for \"${name}\".`,\n },\n }\n : null;\n\n let effectiveArgs: Record<string, unknown> = args;\n let readFileMeta: {\n start: number;\n end: number;\n wasCapped: boolean;\n } | null = null;\n if (name === \"read_file\") {\n const normalized = normalizeReadFileArgs(\n effectiveArgs,\n policy.readFileDefaultMaxLines,\n );\n effectiveArgs = normalized.effectiveArgs;\n readFileMeta = {\n start: normalized.start,\n end: normalized.end,\n wasCapped: normalized.wasCapped,\n };\n }\n\n logger(\n buildToolStatusMessage(name, effectiveArgs, readFileMeta),\n EVENT_TYPES.STEP_STARTED,\n );\n\n const modelArgs = redactFunctionCallArgs(name, effectiveArgs);\n\n const assistantFull = {\n role: \"model\",\n parts: [\n {\n functionCall: {\n name,\n args: effectiveArgs,\n },\n },\n ],\n };\n\n const assistantModel = {\n role: \"model\",\n parts: [\n {\n functionCall: {\n name,\n args: modelArgs,\n },\n },\n ],\n };\n\n if (keepFullTrace) {\n pushBoth(assistantFull, assistantModel);\n } else {\n pushModelOnly(assistantModel);\n }\n\n let toolResultRaw: unknown;\n if (handlerMissingResult) {\n toolResultRaw = handlerMissingResult;\n } else {\n try {\n toolResultRaw = await handler(effectiveArgs);\n } catch (err) {\n logger(`AI tool: ${name} failed`, EVENT_TYPES.STEP_ERROR);\n console.error(\"Tool loop: handler threw\", err, {\n tool: name,\n step: step + 1,\n });\n toolResultRaw = {\n success: false,\n error: err instanceof Error ? err.message : String(err),\n error_detail: serializeError(err),\n note: \"Tool handler threw. Inspect error_detail and retry with corrected args or a different approach.\",\n };\n }\n }\n let toolResult: unknown = toolResultRaw;\n\n if (name === \"read_file\" && readFileMeta) {\n const path = String(effectiveArgs.path ?? \"\");\n const rawContent =\n typeof (toolResultRaw as any)?.content === \"string\"\n ? String((toolResultRaw as any).content)\n : typeof toolResultRaw === \"string\"\n ? toolResultRaw\n : JSON.stringify(toolResultRaw ?? null);\n\n toolResult = {\n path,\n start_line: readFileMeta.start,\n end_line: readFileMeta.end,\n truncated: readFileMeta.wasCapped,\n content: rawContent,\n note: readFileMeta.wasCapped\n ? `Capped to ${policy.readFileDefaultMaxLines} lines. Request more with start_line/end_line.`\n : undefined,\n };\n }\n\n try {\n await persistToolCall(name, modelArgs, toolResult);\n } catch (err) {\n console.error(\"Tool loop: failed to persist tool call\", err, {\n tool: name,\n step: step + 1,\n });\n }\n\n const responseFull = {\n role: \"user\",\n parts: [\n {\n functionResponse: {\n name,\n response: toolResult,\n },\n },\n ],\n };\n\n if (keepFullTrace) {\n fullTraceContents.push(responseFull);\n }\n modelContents.push(responseFull);\n\n if (\n name === \"apply_patch\" &&\n (toolResult as any)?.success === false &&\n applyPatchAutoRetryMax > 0 &&\n applyPatchRetryCount < applyPatchAutoRetryMax\n ) {\n applyPatchRetryCount += 1;\n\n const error = String((toolResult as any)?.error ?? \"unknown error\");\n const debugFiles = Array.isArray((toolResult as any)?.debug?.files)\n ? ((toolResult as any).debug.files as Array<{\n path?: string;\n head?: string;\n }>)\n : [];\n\n const debugText =\n debugFiles.length > 0\n ? `\\n\\nFILE SNAPSHOTS (for regenerating the patch):\\n${debugFiles\n .slice(0, 3)\n .map(\n (f) =>\n `--- ${String(f.path ?? \"\")} ---\\n${String(\n f.head ?? \"\",\n )}\\n--- end ---`,\n )\n .join(\"\\n\\n\")}`\n : \"\";\n\n const retryInstruction = {\n role: \"user\",\n parts: [\n {\n text:\n `apply_patch failed (attempt ${applyPatchRetryCount}/${applyPatchAutoRetryMax}): ${error}\\n` +\n `Regenerate a patch that matches the current file contents. ` +\n `For large rewrites, prefer write_file(path, content) or Delete+Add instead of Update.` +\n debugText,\n },\n ],\n };\n\n if (keepFullTrace) fullTraceContents.push(retryInstruction);\n modelContents.push(retryInstruction);\n }\n\n recordToolEvent({\n toolEvents,\n name,\n effectiveArgs,\n modelArgs,\n readFileMeta,\n toolResult,\n toolResultRaw,\n });\n\n if (terminalToolNames.includes(name)) {\n return {\n contents: keepFullTrace ? fullTraceContents : modelContents,\n modelContents,\n finalText: \"\",\n steps: step + 1,\n terminalCall: { name, args: effectiveArgs, response: toolResultRaw },\n };\n }\n }\n }\n\n throw new Error(`Tool loop: max steps reached (${maxSteps}).`);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"toolLoopRunner.js","sourceRoot":"","sources":["../../../src/ai/toolLoop/toolLoopRunner.ts"],"names":[],"mappings":"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","sourcesContent":["import { FunctionCallingConfigMode, Tool } from \"@google/genai\";\nimport { EVENT_TYPES, EventType } from \"../../types/events.js\";\nimport {\n compactForModel,\n DEFAULT_CONTEXT_POLICY,\n normalizeReadFileArgs,\n redactFunctionCallArgs,\n ToolEvent,\n ToolLoopContextPolicy,\n} from \"./toolLoopContext.js\";\nimport {\n aiCallWithRetry,\n buildToolStatusMessage,\n recordToolEvent,\n serializeError,\n} from \"./toolLoopRunnerUtils.js\";\nimport { persistToolCall } from \"../../services/toolcallPersist.service.js\";\n\nexport type ToolHandler = (args: Record<string, unknown>) => Promise<unknown>;\n\nexport type ToolLoopResult = {\n contents: any[];\n modelContents: any[];\n finalText: string;\n steps: number;\n terminalCall?: {\n name: string;\n args: Record<string, unknown>;\n response: unknown;\n };\n};\n\nexport type Logger = (message: string, eventType: EventType) => Promise<void>;\n\nexport type AiCallResponse = {\n functionCalls?: any[];\n text?: string;\n};\n\nexport type AiCallFn = (\n request: unknown,\n options: {\n tools?: Tool[];\n model?: string;\n toolCallingMode?: FunctionCallingConfigMode;\n },\n) => Promise<AiCallResponse>;\n\nexport type RunToolLoopOptions = {\n initialContents: any[];\n tools: Tool[];\n handlers: Record<string, ToolHandler>;\n maxSteps?: number;\n toolCallingMode?: FunctionCallingConfigMode;\n terminalToolNames?: string[];\n keepFullTrace?: boolean;\n contextPolicy?: ToolLoopContextPolicy;\n aiCall: AiCallFn;\n logger: Logger;\n applyPatchAutoRetryMax?: number;\n aiCallAutoRetryMax?: number;\n aiCallAutoRetryBaseMs?: number;\n aiCallAutoRetryMaxMs?: number;\n};\n\nexport async function runToolLoop(\n options: RunToolLoopOptions,\n): Promise<ToolLoopResult> {\n const {\n initialContents,\n tools,\n handlers,\n maxSteps = 30,\n toolCallingMode = FunctionCallingConfigMode.ANY,\n terminalToolNames = [],\n keepFullTrace = true,\n contextPolicy,\n aiCall,\n logger,\n applyPatchAutoRetryMax = 2,\n aiCallAutoRetryMax = 3, // must have it to try 3 times as gemini errors a lot due to high demand sometimes\n aiCallAutoRetryBaseMs = 400,\n aiCallAutoRetryMaxMs = 10_000,\n } = options;\n\n if (typeof aiCall !== \"function\") {\n throw new Error(\"Tool loop: aiCall is required.\");\n }\n\n const policy: Required<ToolLoopContextPolicy> = {\n ...DEFAULT_CONTEXT_POLICY,\n ...(contextPolicy ?? {}),\n };\n\n const toolEvents: ToolEvent[] = [];\n let applyPatchRetryCount = 0;\n\n const fullTraceContents: any[] = keepFullTrace ? [...initialContents] : [];\n let modelContents: any[] = [...initialContents];\n const pushBoth = (fullItem: any, modelItem: any) => {\n if (keepFullTrace) fullTraceContents.push(fullItem);\n modelContents.push(modelItem);\n };\n const pushModelOnly = (modelItem: any) => {\n modelContents.push(modelItem);\n };\n\n for (let step = 0; step < maxSteps; step++) {\n modelContents = compactForModel({\n initialCount: initialContents.length,\n modelContents,\n toolEvents,\n policy,\n });\n\n if (policy.logApproxModelChars) {\n const approxChars = JSON.stringify(modelContents).length;\n console.log(\"Tool loop: approx model chars\", {\n approxChars,\n step: step + 1,\n });\n }\n\n let response: Awaited<ReturnType<AiCallFn>>;\n response = await aiCallWithRetry({\n aiCall,\n request: modelContents,\n options: { tools, toolCallingMode },\n retryMax: aiCallAutoRetryMax,\n retryBaseMs: aiCallAutoRetryBaseMs,\n retryMaxMs: aiCallAutoRetryMaxMs,\n step: step + 1,\n logger,\n });\n\n const functionCalls = response.functionCalls ?? [];\n if (functionCalls.length === 0) {\n return {\n contents: keepFullTrace ? fullTraceContents : modelContents,\n modelContents,\n finalText: (response.text ?? \"\").trim(),\n steps: step + 1,\n };\n }\n\n for (const call of functionCalls) {\n const name = call.name?.toString() ?? \"\";\n const args = (call.args ?? {}) as Record<string, unknown>;\n\n if (!name) {\n throw new Error(\"Tool loop: function call missing name.\");\n }\n\n const handler = handlers[name];\n const handlerMissingResult = !handler\n ? {\n success: false,\n error: `No handler registered for \"${name}\".`,\n error_detail: {\n name: \"MissingToolHandlerError\",\n message: `No handler registered for \"${name}\".`,\n },\n }\n : null;\n\n let effectiveArgs: Record<string, unknown> = args;\n let readFileMeta: {\n start: number;\n end: number;\n wasCapped: boolean;\n } | null = null;\n if (name === \"read_file\") {\n const normalized = normalizeReadFileArgs(\n effectiveArgs,\n policy.readFileDefaultMaxLines,\n );\n effectiveArgs = normalized.effectiveArgs;\n readFileMeta = {\n start: normalized.start,\n end: normalized.end,\n wasCapped: normalized.wasCapped,\n };\n }\n\n logger(\n buildToolStatusMessage(name, effectiveArgs, readFileMeta),\n EVENT_TYPES.STEP_STARTED,\n );\n\n const modelArgs = redactFunctionCallArgs(name, effectiveArgs);\n\n const assistantFull = {\n role: \"model\",\n parts: [\n {\n functionCall: {\n name,\n args: effectiveArgs,\n },\n },\n ],\n };\n\n const assistantModel = {\n role: \"model\",\n parts: [\n {\n functionCall: {\n name,\n args: modelArgs,\n },\n },\n ],\n };\n\n if (keepFullTrace) {\n pushBoth(assistantFull, assistantModel);\n } else {\n pushModelOnly(assistantModel);\n }\n\n let toolResultRaw: unknown;\n if (handlerMissingResult) {\n toolResultRaw = handlerMissingResult;\n } else {\n try {\n toolResultRaw = await handler(effectiveArgs);\n } catch (err) {\n logger(`AI tool: ${name} failed`, EVENT_TYPES.STEP_ERROR);\n console.error(\"Tool loop: handler threw\", err, {\n tool: name,\n step: step + 1,\n });\n toolResultRaw = {\n success: false,\n error: err instanceof Error ? err.message : String(err),\n error_detail: serializeError(err),\n note: \"Tool handler threw. Inspect error_detail and retry with corrected args or a different approach.\",\n };\n }\n }\n let toolResult: unknown = toolResultRaw;\n\n if (name === \"read_file\" && readFileMeta) {\n const path = String(effectiveArgs.path ?? \"\");\n\n const jsonPayload =\n (toolResultRaw as any)?.kind === \"json\" ? (toolResultRaw as any)?.json : undefined;\n if (jsonPayload !== undefined) {\n // Token-efficient: return JSON as structured data (no double-stringifying).\n toolResult = { path, json: jsonPayload };\n } else {\n const rawContent =\n typeof (toolResultRaw as any)?.content === \"string\"\n ? String((toolResultRaw as any).content)\n : typeof toolResultRaw === \"string\"\n ? toolResultRaw\n : JSON.stringify(toolResultRaw ?? null);\n\n toolResult = {\n path,\n start_line: readFileMeta.start,\n end_line: readFileMeta.end,\n truncated: readFileMeta.wasCapped,\n content: rawContent,\n note: readFileMeta.wasCapped\n ? `Capped to ${policy.readFileDefaultMaxLines} lines. Request more with start_line/end_line.`\n : undefined,\n };\n }\n }\n\n try {\n await persistToolCall(name, modelArgs, toolResult);\n } catch (err) {\n console.error(\"Tool loop: failed to persist tool call\", err, {\n tool: name,\n step: step + 1,\n });\n }\n\n const responseFull = {\n role: \"user\",\n parts: [\n {\n functionResponse: {\n name,\n response: toolResult,\n },\n },\n ],\n };\n\n if (keepFullTrace) {\n fullTraceContents.push(responseFull);\n }\n modelContents.push(responseFull);\n\n if (\n name === \"apply_patch\" &&\n (toolResult as any)?.success === false &&\n applyPatchAutoRetryMax > 0 &&\n applyPatchRetryCount < applyPatchAutoRetryMax\n ) {\n applyPatchRetryCount += 1;\n\n const error = String((toolResult as any)?.error ?? \"unknown error\");\n const debugFiles = Array.isArray((toolResult as any)?.debug?.files)\n ? ((toolResult as any).debug.files as Array<{\n path?: string;\n head?: string;\n }>)\n : [];\n\n const debugText =\n debugFiles.length > 0\n ? `\\n\\nFILE SNAPSHOTS (for regenerating the patch):\\n${debugFiles\n .slice(0, 3)\n .map(\n (f) =>\n `--- ${String(f.path ?? \"\")} ---\\n${String(\n f.head ?? \"\",\n )}\\n--- end ---`,\n )\n .join(\"\\n\\n\")}`\n : \"\";\n\n const retryInstruction = {\n role: \"user\",\n parts: [\n {\n text:\n `apply_patch failed (attempt ${applyPatchRetryCount}/${applyPatchAutoRetryMax}): ${error}\\n` +\n `Regenerate a patch that matches the current file contents. ` +\n `For large rewrites, prefer write_file(path, content) or Delete+Add instead of Update.` +\n debugText,\n },\n ],\n };\n\n if (keepFullTrace) fullTraceContents.push(retryInstruction);\n modelContents.push(retryInstruction);\n }\n\n recordToolEvent({\n toolEvents,\n name,\n effectiveArgs,\n modelArgs,\n readFileMeta,\n toolResult,\n toolResultRaw,\n });\n\n if (terminalToolNames.includes(name)) {\n return {\n contents: keepFullTrace ? fullTraceContents : modelContents,\n modelContents,\n finalText: \"\",\n steps: step + 1,\n terminalCall: { name, args: effectiveArgs, response: toolResultRaw },\n };\n }\n }\n }\n\n throw new Error(`Tool loop: max steps reached (${maxSteps}).`);\n}\n"]}
|
|
@@ -1 +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,
|
|
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,SA6FA,CAAC"}
|
|
@@ -155,6 +155,19 @@ export const recordToolEvent = (params) => {
|
|
|
155
155
|
toolEvents.push({ name, summary: `delete_file ${p}` });
|
|
156
156
|
return;
|
|
157
157
|
}
|
|
158
|
+
const successVal = toolResult?.success;
|
|
159
|
+
if (typeof successVal === "boolean") {
|
|
160
|
+
const changedVal = toolResult?.changed;
|
|
161
|
+
const changedText = typeof changedVal === "boolean" ? ` changed=${changedVal}` : "";
|
|
162
|
+
const errText = successVal === false
|
|
163
|
+
? ` error=${JSON.stringify(toolResult?.error ?? "unknown")}`
|
|
164
|
+
: "";
|
|
165
|
+
toolEvents.push({
|
|
166
|
+
name,
|
|
167
|
+
summary: `${name} ${successVal ? "success" : "failure"}${changedText}${errText}`,
|
|
168
|
+
});
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
158
171
|
toolEvents.push({ name, summary: `${name} called` });
|
|
159
172
|
}
|
|
160
173
|
catch {
|
|
@@ -1 +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"]}
|
|
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 const successVal = (toolResult as any)?.success;\n if (typeof successVal === \"boolean\") {\n const changedVal = (toolResult as any)?.changed;\n const changedText = typeof changedVal === \"boolean\" ? ` changed=${changedVal}` : \"\";\n const errText =\n successVal === false\n ? ` error=${JSON.stringify((toolResult as any)?.error ?? \"unknown\")}`\n : \"\";\n toolEvents.push({\n name,\n summary: `${name} ${successVal ? \"success\" : \"failure\"}${changedText}${errText}`,\n });\n return;\n }\n\n toolEvents.push({ name, summary: `${name} called` });\n } catch {\n toolEvents.push({ name, summary: `${name} called` });\n }\n};\n"]}
|
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
import { type WorkspaceDeps } from "./workspaceDeps.js";
|
|
2
|
-
export declare const createCreateNewRouteImpl: (deps: WorkspaceDeps) => (parentRoute: string, routeName: string) => Promise<
|
|
2
|
+
export declare const createCreateNewRouteImpl: (deps: WorkspaceDeps) => (parentRoute: string, routeName: string) => Promise<{
|
|
3
|
+
success: false;
|
|
4
|
+
error: string;
|
|
5
|
+
route?: undefined;
|
|
6
|
+
created_files?: undefined;
|
|
7
|
+
page_config_json?: undefined;
|
|
8
|
+
} | {
|
|
9
|
+
success: true;
|
|
10
|
+
route: string;
|
|
11
|
+
created_files: string[];
|
|
12
|
+
page_config_json: unknown;
|
|
13
|
+
error?: undefined;
|
|
14
|
+
}>;
|
|
3
15
|
export declare const DEFAULT_PAGE_CONFIG_JSON: string;
|
|
4
16
|
export declare const PAGE_TSX_TEMPLATE_STRING: string;
|
|
5
17
|
//# sourceMappingURL=createNewRoute.impl.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createNewRoute.impl.d.ts","sourceRoot":"","sources":["../../../../src/ai/tools/implementations/createNewRoute.impl.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"createNewRoute.impl.d.ts","sourceRoot":"","sources":["../../../../src/ai/tools/implementations/createNewRoute.impl.ts"],"names":[],"mappings":"AAQA,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AA0CxD,eAAO,MAAM,wBAAwB,GAAI,MAAM,aAAa,MAG5C,aAAa,MAAM,EAAE,WAAW,MAAM;;;;;;;;;;;;EAgJrD,CAAC;AAEF,eAAO,MAAM,wBAAwB,QAAsB,CAAC;AAC5D,eAAO,MAAM,wBAAwB,QAAoB,CAAC"}
|
|
@@ -20,14 +20,7 @@ const DEFAULT_PAGE_CONFIG = (() => {
|
|
|
20
20
|
id: "root",
|
|
21
21
|
type: "div",
|
|
22
22
|
className: "min-h-screen p-6",
|
|
23
|
-
|
|
24
|
-
{
|
|
25
|
-
id: "title",
|
|
26
|
-
type: "text",
|
|
27
|
-
className: "text-sm font-semibold tracking-wide text-slate-200",
|
|
28
|
-
props: { text: "Qwintly Starter" },
|
|
29
|
-
},
|
|
30
|
-
],
|
|
23
|
+
props: {},
|
|
31
24
|
},
|
|
32
25
|
];
|
|
33
26
|
// Validate uniqueness (and keep deterministic IDs).
|
|
@@ -43,10 +36,16 @@ export const createCreateNewRouteImpl = (deps) => {
|
|
|
43
36
|
const parentSegments = normalizeRouteSegments(parentRoute);
|
|
44
37
|
const routeSegment = String(routeName ?? "").trim();
|
|
45
38
|
if (!isSafeSegment(routeSegment)) {
|
|
46
|
-
return
|
|
39
|
+
return {
|
|
40
|
+
success: false,
|
|
41
|
+
error: "Invalid route name",
|
|
42
|
+
};
|
|
47
43
|
}
|
|
48
44
|
if (parentSegments.some((s) => !isSafeSegment(s))) {
|
|
49
|
-
return
|
|
45
|
+
return {
|
|
46
|
+
success: false,
|
|
47
|
+
error: "Invalid parent route",
|
|
48
|
+
};
|
|
50
49
|
}
|
|
51
50
|
const appDir = toWorkspacePath(workspaceRoot, "app");
|
|
52
51
|
const parentDir = path.join(appDir, ...parentSegments);
|
|
@@ -54,46 +53,116 @@ export const createCreateNewRouteImpl = (deps) => {
|
|
|
54
53
|
// Parent must exist (don't implicitly create arbitrary routes).
|
|
55
54
|
try {
|
|
56
55
|
const st = await coreFs.stat(parentDir);
|
|
57
|
-
if (!st.isDirectory())
|
|
58
|
-
return
|
|
56
|
+
if (!st.isDirectory()) {
|
|
57
|
+
return {
|
|
58
|
+
success: false,
|
|
59
|
+
error: "Parent not a folder",
|
|
60
|
+
};
|
|
61
|
+
}
|
|
59
62
|
}
|
|
60
63
|
catch (err) {
|
|
61
64
|
const code = err?.code;
|
|
62
|
-
if (code === "ENOENT")
|
|
63
|
-
return
|
|
64
|
-
|
|
65
|
+
if (code === "ENOENT") {
|
|
66
|
+
return {
|
|
67
|
+
success: false,
|
|
68
|
+
error: "Parent route missing",
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
return {
|
|
72
|
+
success: false,
|
|
73
|
+
error: "Parent check failed",
|
|
74
|
+
};
|
|
65
75
|
}
|
|
66
76
|
// Route must not already exist.
|
|
67
77
|
try {
|
|
68
78
|
await coreFs.stat(finalDir);
|
|
69
|
-
return
|
|
79
|
+
return {
|
|
80
|
+
success: false,
|
|
81
|
+
error: "Route already exists",
|
|
82
|
+
};
|
|
70
83
|
}
|
|
71
84
|
catch (err) {
|
|
72
85
|
const code = err?.code;
|
|
73
|
-
if (code && code !== "ENOENT")
|
|
74
|
-
return
|
|
86
|
+
if (code && code !== "ENOENT") {
|
|
87
|
+
return {
|
|
88
|
+
success: false,
|
|
89
|
+
error: "Route check failed",
|
|
90
|
+
};
|
|
91
|
+
}
|
|
75
92
|
}
|
|
76
93
|
const tmpDir = path.join(parentDir, `.qwintly_route_tmp_${routeSegment}_${Date.now()}_${Math.random().toString(16).slice(2)}`);
|
|
94
|
+
const rollback = async () => {
|
|
95
|
+
// Rollback any partially-created temp output.
|
|
96
|
+
try {
|
|
97
|
+
await fs.rm(tmpDir, { recursive: true, force: true });
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
// best-effort cleanup only
|
|
101
|
+
}
|
|
102
|
+
};
|
|
77
103
|
try {
|
|
78
104
|
await coreFs.mkdirp(tmpDir);
|
|
105
|
+
}
|
|
106
|
+
catch (err) {
|
|
107
|
+
await rollback();
|
|
108
|
+
return {
|
|
109
|
+
success: false,
|
|
110
|
+
error: "Temp folder create failed",
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
try {
|
|
79
114
|
await coreFs.writeFile(path.join(tmpDir, "page.tsx"), PAGE_TSX_TEMPLATE);
|
|
115
|
+
}
|
|
116
|
+
catch (err) {
|
|
117
|
+
await rollback();
|
|
118
|
+
return {
|
|
119
|
+
success: false,
|
|
120
|
+
error: "Write page.tsx failed",
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
try {
|
|
80
124
|
await coreFs.writeFile(path.join(tmpDir, "pageConfig.json"), DEFAULT_PAGE_CONFIG);
|
|
125
|
+
}
|
|
126
|
+
catch (err) {
|
|
127
|
+
await rollback();
|
|
128
|
+
return {
|
|
129
|
+
success: false,
|
|
130
|
+
error: "Write pageConfig failed",
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
try {
|
|
81
134
|
// Commit: move temp dir into place (best-effort atomic within same parent).
|
|
82
135
|
await fs.rename(tmpDir, finalDir);
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
136
|
+
}
|
|
137
|
+
catch (err) {
|
|
138
|
+
await rollback();
|
|
139
|
+
return {
|
|
140
|
+
success: false,
|
|
141
|
+
error: "Finalize route failed",
|
|
142
|
+
};
|
|
143
|
+
}
|
|
144
|
+
const routePath = "/" + [...parentSegments, routeSegment].filter(Boolean).join("/");
|
|
145
|
+
let pageConfigJson = null;
|
|
146
|
+
try {
|
|
147
|
+
pageConfigJson = JSON.parse(DEFAULT_PAGE_CONFIG);
|
|
86
148
|
}
|
|
87
149
|
catch {
|
|
88
|
-
//
|
|
89
|
-
|
|
90
|
-
await fs.rm(tmpDir, { recursive: true, force: true });
|
|
91
|
-
}
|
|
92
|
-
catch {
|
|
93
|
-
// best-effort cleanup only
|
|
94
|
-
}
|
|
95
|
-
return "failed to create";
|
|
150
|
+
// shouldn't happen, but keep the tool robust
|
|
151
|
+
pageConfigJson = { elements: [] };
|
|
96
152
|
}
|
|
153
|
+
return {
|
|
154
|
+
success: true,
|
|
155
|
+
route: routePath,
|
|
156
|
+
created_files: [
|
|
157
|
+
path
|
|
158
|
+
.join("app", ...parentSegments, routeSegment, "page.tsx")
|
|
159
|
+
.replace(/\\/g, "/"),
|
|
160
|
+
path
|
|
161
|
+
.join("app", ...parentSegments, routeSegment, "pageConfig.json")
|
|
162
|
+
.replace(/\\/g, "/"),
|
|
163
|
+
],
|
|
164
|
+
page_config_json: pageConfigJson,
|
|
165
|
+
};
|
|
97
166
|
};
|
|
98
167
|
};
|
|
99
168
|
export const DEFAULT_PAGE_CONFIG_JSON = DEFAULT_PAGE_CONFIG;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createNewRoute.impl.js","sourceRoot":"","sources":["../../../../src/ai/tools/implementations/createNewRoute.impl.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { extractAllIds } from \"../helpers/elementid.helpers.js\";\nimport { toWorkspacePath } from \"../helpers/fileSystem.helpers.js\";\nimport {\n isSafeSegment,\n normalizeRouteSegments,\n} from \"../helpers/pageConfigJson.helpers.js\";\nimport { type WorkspaceDeps } from \"./workspaceDeps.js\";\n\nconst PAGE_TSX_TEMPLATE = [\n 'import { RenderElement } from \"@/lib/renderer/RenderElement\";',\n 'import pageConfig from \"./pageConfig.json\";',\n 'import type { BuilderElement } from \"@/types/elements\";',\n \"\",\n \"export default function Page() {\",\n \" const config = pageConfig as { elements: BuilderElement[] };\",\n \" return config.elements.map((el) => <RenderElement key={el.id} el={el} />);\",\n \"}\",\n \"\",\n].join(\"\\n\");\n\nconst DEFAULT_PAGE_CONFIG = (() => {\n const elements: any[] = [\n {\n id: \"root\",\n type: \"div\",\n className: \"min-h-screen p-6\",\n children: [\n {\n id: \"title\",\n type: \"text\",\n className: \"text-sm font-semibold tracking-wide text-slate-200\",\n props: { text: \"Qwintly Starter\" },\n },\n ],\n },\n ];\n\n // Validate uniqueness (and keep deterministic IDs).\n const ids = extractAllIds(elements as any);\n if (ids.size !== 2 || !ids.has(\"root\") || !ids.has(\"title\")) {\n throw new Error(\"DEFAULT_PAGE_CONFIG ids must be stable and unique\");\n }\n\n return JSON.stringify({ elements }, null, 2) + \"\\n\";\n})();\n\nexport const createCreateNewRouteImpl = (deps: WorkspaceDeps) => {\n const { workspaceRoot, fs: coreFs } = deps;\n\n return async (parentRoute: string, routeName: string) => {\n const parentSegments = normalizeRouteSegments(parentRoute);\n const routeSegment = String(routeName ?? \"\").trim();\n\n if (!isSafeSegment(routeSegment)) {\n return \"failed to create\";\n }\n if (parentSegments.some((s) => !isSafeSegment(s))) {\n return \"failed to create\";\n }\n\n const appDir = toWorkspacePath(workspaceRoot, \"app\");\n const parentDir = path.join(appDir, ...parentSegments);\n const finalDir = path.join(parentDir, routeSegment);\n\n // Parent must exist (don't implicitly create arbitrary routes).\n try {\n const st = await coreFs.stat(parentDir);\n if (!st.isDirectory()) return \"failed to create\";\n } catch (err) {\n const code = (err as NodeJS.ErrnoException | null)?.code;\n if (code === \"ENOENT\") return \"failed to create\";\n return \"failed to create\";\n }\n\n // Route must not already exist.\n try {\n await coreFs.stat(finalDir);\n return \"failed to create\";\n } catch (err) {\n const code = (err as NodeJS.ErrnoException | null)?.code;\n if (code && code !== \"ENOENT\") return \"failed to create\";\n }\n\n const tmpDir = path.join(\n parentDir,\n `.qwintly_route_tmp_${routeSegment}_${Date.now()}_${Math.random().toString(16).slice(2)}`,\n );\n\n try {\n await coreFs.mkdirp(tmpDir);\n await coreFs.writeFile(path.join(tmpDir, \"page.tsx\"), PAGE_TSX_TEMPLATE);\n await coreFs.writeFile(\n path.join(tmpDir, \"pageConfig.json\"),\n DEFAULT_PAGE_CONFIG,\n );\n\n // Commit: move temp dir into place (best-effort atomic within same parent).\n await fs.rename(tmpDir, finalDir);\n\n const routePath =\n \"/\" + [...parentSegments, routeSegment].filter(Boolean).join(\"/\");\n\n return (\n `created page.tsx successfully and content of pageConfig.json at route \"${routePath}\":\\n` +\n DEFAULT_PAGE_CONFIG\n );\n } catch {\n // Rollback any partially-created temp output.\n try {\n await fs.rm(tmpDir, { recursive: true, force: true });\n } catch {\n // best-effort cleanup only\n }\n return \"failed to create\";\n }\n };\n};\n\nexport const DEFAULT_PAGE_CONFIG_JSON = DEFAULT_PAGE_CONFIG;\nexport const PAGE_TSX_TEMPLATE_STRING = PAGE_TSX_TEMPLATE;\n"]}
|
|
1
|
+
{"version":3,"file":"createNewRoute.impl.js","sourceRoot":"","sources":["../../../../src/ai/tools/implementations/createNewRoute.impl.ts"],"names":[],"mappings":"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","sourcesContent":["import fs from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { extractAllIds } from \"../helpers/elementid.helpers.js\";\nimport { toWorkspacePath } from \"../helpers/fileSystem.helpers.js\";\nimport {\n isSafeSegment,\n normalizeRouteSegments,\n} from \"../helpers/pageConfigJson.helpers.js\";\nimport { type WorkspaceDeps } from \"./workspaceDeps.js\";\n\ntype CreateNewRouteResult =\n | {\n success: true;\n route: string;\n created_files: string[];\n page_config_json: unknown;\n }\n | { success: false; error: string };\n\nconst PAGE_TSX_TEMPLATE = [\n 'import { RenderElement } from \"@/lib/renderer/RenderElement\";',\n 'import pageConfig from \"./pageConfig.json\";',\n 'import type { BuilderElement } from \"@/types/elements\";',\n \"\",\n \"export default function Page() {\",\n \" const config = pageConfig as { elements: BuilderElement[] };\",\n \" return config.elements.map((el) => <RenderElement key={el.id} el={el} />);\",\n \"}\",\n \"\",\n].join(\"\\n\");\n\nconst DEFAULT_PAGE_CONFIG = (() => {\n const elements: any[] = [\n {\n id: \"root\",\n type: \"div\",\n className: \"min-h-screen p-6\",\n props: {},\n },\n ];\n\n // Validate uniqueness (and keep deterministic IDs).\n const ids = extractAllIds(elements as any);\n if (ids.size !== 2 || !ids.has(\"root\") || !ids.has(\"title\")) {\n throw new Error(\"DEFAULT_PAGE_CONFIG ids must be stable and unique\");\n }\n\n return JSON.stringify({ elements }, null, 2) + \"\\n\";\n})();\n\nexport const createCreateNewRouteImpl = (deps: WorkspaceDeps) => {\n const { workspaceRoot, fs: coreFs } = deps;\n\n return async (parentRoute: string, routeName: string) => {\n const parentSegments = normalizeRouteSegments(parentRoute);\n const routeSegment = String(routeName ?? \"\").trim();\n\n if (!isSafeSegment(routeSegment)) {\n return {\n success: false,\n error: \"Invalid route name\",\n } satisfies CreateNewRouteResult;\n }\n if (parentSegments.some((s) => !isSafeSegment(s))) {\n return {\n success: false,\n error: \"Invalid parent route\",\n } satisfies CreateNewRouteResult;\n }\n\n const appDir = toWorkspacePath(workspaceRoot, \"app\");\n const parentDir = path.join(appDir, ...parentSegments);\n const finalDir = path.join(parentDir, routeSegment);\n\n // Parent must exist (don't implicitly create arbitrary routes).\n try {\n const st = await coreFs.stat(parentDir);\n if (!st.isDirectory()) {\n return {\n success: false,\n error: \"Parent not a folder\",\n } satisfies CreateNewRouteResult;\n }\n } catch (err) {\n const code = (err as NodeJS.ErrnoException | null)?.code;\n if (code === \"ENOENT\") {\n return {\n success: false,\n error: \"Parent route missing\",\n } satisfies CreateNewRouteResult;\n }\n return {\n success: false,\n error: \"Parent check failed\",\n } satisfies CreateNewRouteResult;\n }\n\n // Route must not already exist.\n try {\n await coreFs.stat(finalDir);\n return {\n success: false,\n error: \"Route already exists\",\n } satisfies CreateNewRouteResult;\n } catch (err) {\n const code = (err as NodeJS.ErrnoException | null)?.code;\n if (code && code !== \"ENOENT\") {\n return {\n success: false,\n error: \"Route check failed\",\n } satisfies CreateNewRouteResult;\n }\n }\n\n const tmpDir = path.join(\n parentDir,\n `.qwintly_route_tmp_${routeSegment}_${Date.now()}_${Math.random().toString(16).slice(2)}`,\n );\n\n const rollback = async () => {\n // Rollback any partially-created temp output.\n try {\n await fs.rm(tmpDir, { recursive: true, force: true });\n } catch {\n // best-effort cleanup only\n }\n };\n\n try {\n await coreFs.mkdirp(tmpDir);\n } catch (err) {\n await rollback();\n return {\n success: false,\n error: \"Temp folder create failed\",\n } satisfies CreateNewRouteResult;\n }\n\n try {\n await coreFs.writeFile(path.join(tmpDir, \"page.tsx\"), PAGE_TSX_TEMPLATE);\n } catch (err) {\n await rollback();\n return {\n success: false,\n error: \"Write page.tsx failed\",\n } satisfies CreateNewRouteResult;\n }\n\n try {\n await coreFs.writeFile(\n path.join(tmpDir, \"pageConfig.json\"),\n DEFAULT_PAGE_CONFIG,\n );\n } catch (err) {\n await rollback();\n return {\n success: false,\n error: \"Write pageConfig failed\",\n } satisfies CreateNewRouteResult;\n }\n\n try {\n // Commit: move temp dir into place (best-effort atomic within same parent).\n await fs.rename(tmpDir, finalDir);\n } catch (err) {\n await rollback();\n return {\n success: false,\n error: \"Finalize route failed\",\n } satisfies CreateNewRouteResult;\n }\n\n const routePath =\n \"/\" + [...parentSegments, routeSegment].filter(Boolean).join(\"/\");\n\n let pageConfigJson: unknown = null;\n try {\n pageConfigJson = JSON.parse(DEFAULT_PAGE_CONFIG);\n } catch {\n // shouldn't happen, but keep the tool robust\n pageConfigJson = { elements: [] };\n }\n\n return {\n success: true,\n route: routePath,\n created_files: [\n path\n .join(\"app\", ...parentSegments, routeSegment, \"page.tsx\")\n .replace(/\\\\/g, \"/\"),\n path\n .join(\"app\", ...parentSegments, routeSegment, \"pageConfig.json\")\n .replace(/\\\\/g, \"/\"),\n ],\n page_config_json: pageConfigJson,\n } satisfies CreateNewRouteResult;\n };\n};\n\nexport const DEFAULT_PAGE_CONFIG_JSON = DEFAULT_PAGE_CONFIG;\nexport const PAGE_TSX_TEMPLATE_STRING = PAGE_TSX_TEMPLATE;\n"]}
|
|
@@ -12,7 +12,10 @@ export { createUpdateClassNameImpl } from "./updateClassName.impl.js";
|
|
|
12
12
|
export { createUpdatePropsImpl } from "./updateProps.impl.js";
|
|
13
13
|
export { createWriteFileImpl } from "./writeFile.impl.js";
|
|
14
14
|
export declare const createWorkspaceToolImpls: (deps: SearchDeps) => {
|
|
15
|
-
readFileImpl: (filePath: string, startLine?: number, endLine?: number) => Promise<string
|
|
15
|
+
readFileImpl: (filePath: string, startLine?: number, endLine?: number) => Promise<string | {
|
|
16
|
+
kind: string;
|
|
17
|
+
json: unknown;
|
|
18
|
+
}>;
|
|
16
19
|
writeFileImpl: (filePath: string, content: string) => Promise<{
|
|
17
20
|
success: boolean;
|
|
18
21
|
rejected: boolean;
|
|
@@ -91,7 +94,19 @@ export declare const createWorkspaceToolImpls: (deps: SearchDeps) => {
|
|
|
91
94
|
changed?: undefined;
|
|
92
95
|
warnings?: undefined;
|
|
93
96
|
}>;
|
|
94
|
-
createNewRouteImpl: (parentRoute: string, routeName: string) => Promise<
|
|
97
|
+
createNewRouteImpl: (parentRoute: string, routeName: string) => Promise<{
|
|
98
|
+
success: false;
|
|
99
|
+
error: string;
|
|
100
|
+
route?: undefined;
|
|
101
|
+
created_files?: undefined;
|
|
102
|
+
page_config_json?: undefined;
|
|
103
|
+
} | {
|
|
104
|
+
success: true;
|
|
105
|
+
route: string;
|
|
106
|
+
created_files: string[];
|
|
107
|
+
page_config_json: unknown;
|
|
108
|
+
error?: undefined;
|
|
109
|
+
}>;
|
|
95
110
|
deleteElementImpl: (route: string, elementId: string) => Promise<{
|
|
96
111
|
success: boolean;
|
|
97
112
|
error: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factories.d.ts","sourceRoot":"","sources":["../../../../src/ai/tools/implementations/factories.ts"],"names":[],"mappings":"AAMA,OAAO,EAAoB,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAKrE,OAAO,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAChE,YAAY,EACV,UAAU,EACV,MAAM,EACN,aAAa,GACd,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EACL,gBAAgB,EAChB,KAAK,UAAU,EACf,KAAK,YAAY,GAClB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE1D,eAAO,MAAM,wBAAwB,GAAI,MAAM,UAAU
|
|
1
|
+
{"version":3,"file":"factories.d.ts","sourceRoot":"","sources":["../../../../src/ai/tools/implementations/factories.ts"],"names":[],"mappings":"AAMA,OAAO,EAAoB,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAKrE,OAAO,EAAE,0BAA0B,EAAE,MAAM,oBAAoB,CAAC;AAChE,YAAY,EACV,UAAU,EACV,MAAM,EACN,aAAa,GACd,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,wBAAwB,EAAE,MAAM,0BAA0B,CAAC;AACpE,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAClE,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EACL,gBAAgB,EAChB,KAAK,UAAU,EACf,KAAK,YAAY,GAClB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,yBAAyB,EAAE,MAAM,2BAA2B,CAAC;AACtE,OAAO,EAAE,qBAAqB,EAAE,MAAM,uBAAuB,CAAC;AAC9D,OAAO,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAC;AAE1D,eAAO,MAAM,wBAAwB,GAAI,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwBxD,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"insertElement.impl.d.ts","sourceRoot":"","sources":["../../../../src/ai/tools/implementations/insertElement.impl.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAWjE,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,eAAO,MAAM,uBAAuB,GAAI,MAAM,aAAa,MAG3C,OAAO,MAAM,EAAE,UAAU,MAAM,EAAE,SAAS,cAAc;;;;;;;;;;;;;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"insertElement.impl.d.ts","sourceRoot":"","sources":["../../../../src/ai/tools/implementations/insertElement.impl.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAWjE,OAAO,EAAE,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAExD,eAAO,MAAM,uBAAuB,GAAI,MAAM,aAAa,MAG3C,OAAO,MAAM,EAAE,UAAU,MAAM,EAAE,SAAS,cAAc;;;;;;;;;;;;;;;;;;;;;;EAmFvE,CAAC"}
|
|
@@ -63,7 +63,7 @@ export const createInsertElementImpl = (deps) => {
|
|
|
63
63
|
if (!parent)
|
|
64
64
|
return { success: false, error: "parent not found" };
|
|
65
65
|
const anyParent = parent;
|
|
66
|
-
if (!Array.isArray(anyParent.children))
|
|
66
|
+
if (!anyParent.children || !Array.isArray(anyParent.children))
|
|
67
67
|
anyParent.children = [];
|
|
68
68
|
anyParent.children.push(toInsert);
|
|
69
69
|
const after = stringifyPageConfigJson({ elements });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"insertElement.impl.js","sourceRoot":"","sources":["../../../../src/ai/tools/implementations/insertElement.impl.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"insertElement.impl.js","sourceRoot":"","sources":["../../../../src/ai/tools/implementations/insertElement.impl.ts"],"names":[],"mappings":"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","sourcesContent":["import { resolveUnsplashImagesDeep } from \"../../../image/unsplash.service.js\";\nimport type { BuilderElement } from \"../../../types/elements.js\";\nimport { InsertElementArgsZod } from \"../validators/builderElement.zod.js\";\nimport {\n ensureElementIds,\n extractAllIdsDeep,\n findElementById,\n getPageConfigJsonPath,\n parsePageConfigJson,\n stringifyPageConfigJson,\n writeFileAtomic,\n} from \"../helpers/pageConfigJson.helpers.js\";\nimport { type WorkspaceDeps } from \"./workspaceDeps.js\";\n\nexport const createInsertElementImpl = (deps: WorkspaceDeps) => {\n const { workspaceRoot, fs } = deps;\n\n return async (route: string, parentId: string, element: BuilderElement) => {\n const parsedArgs = InsertElementArgsZod.safeParse({\n route,\n parent_id: parentId,\n element,\n });\n if (!parsedArgs.success) {\n return {\n success: false,\n error: \"invalid args\",\n error_detail: parsedArgs.error.flatten(),\n };\n }\n\n const parent_id = String(parentId ?? \"\").trim();\n if (!parent_id) return { success: false, error: \"invalid parent_id\" };\n\n let configPath: string;\n try {\n configPath = getPageConfigJsonPath(workspaceRoot, route);\n } catch (err) {\n return {\n success: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n\n let before = \"\";\n try {\n before = await fs.readFile(configPath);\n } catch (err) {\n const code = (err as NodeJS.ErrnoException | null)?.code;\n if (code === \"ENOENT\") return { success: false, error: \"not found\" };\n return {\n success: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n\n let parsed: ReturnType<typeof parsePageConfigJson>;\n try {\n parsed = parsePageConfigJson(before);\n } catch (err) {\n return {\n success: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n\n const elements = parsed.elements ?? [];\n const existingIds = extractAllIdsDeep(elements);\n ensureElementIds(elements, existingIds);\n\n // Clone + inject ids for the inserted element subtree.\n const toInsert = JSON.parse(\n JSON.stringify(element ?? null),\n ) as BuilderElement;\n await resolveUnsplashImagesDeep(toInsert);\n ensureElementIds([toInsert], existingIds);\n\n const parent = findElementById(elements, parent_id);\n if (!parent) return { success: false, error: \"parent not found\" };\n\n const anyParent = parent as any;\n if (!anyParent.children || !Array.isArray(anyParent.children))\n anyParent.children = [];\n (anyParent.children as BuilderElement[]).push(toInsert);\n\n const after = stringifyPageConfigJson({ elements });\n try {\n await writeFileAtomic(configPath, after);\n return {\n success: true,\n changed: true,\n inserted_id: (toInsert as any).id,\n };\n } catch (err) {\n return {\n success: false,\n error: err instanceof Error ? err.message : String(err),\n };\n }\n };\n};\n"]}
|
|
@@ -1,3 +1,6 @@
|
|
|
1
1
|
import { type WorkspaceDeps } from "./workspaceDeps.js";
|
|
2
|
-
export declare const createReadFileImpl: (deps: WorkspaceDeps) => (filePath: string, startLine?: number, endLine?: number) => Promise<string
|
|
2
|
+
export declare const createReadFileImpl: (deps: WorkspaceDeps) => (filePath: string, startLine?: number, endLine?: number) => Promise<string | {
|
|
3
|
+
kind: string;
|
|
4
|
+
json: unknown;
|
|
5
|
+
}>;
|
|
3
6
|
//# sourceMappingURL=readFile.impl.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"readFile.impl.d.ts","sourceRoot":"","sources":["../../../../src/ai/tools/implementations/readFile.impl.ts"],"names":[],"mappings":"AAEA,OAAO,EAA8B,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEpF,eAAO,MAAM,kBAAkB,GAAI,MAAM,aAAa,MAGtC,UAAU,MAAM,EAAE,YAAY,MAAM,EAAE,UAAU,MAAM,
|
|
1
|
+
{"version":3,"file":"readFile.impl.d.ts","sourceRoot":"","sources":["../../../../src/ai/tools/implementations/readFile.impl.ts"],"names":[],"mappings":"AAEA,OAAO,EAA8B,KAAK,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEpF,eAAO,MAAM,kBAAkB,GAAI,MAAM,aAAa,MAGtC,UAAU,MAAM,EAAE,YAAY,MAAM,EAAE,UAAU,MAAM;;UAmBV,OAAO;EAQlE,CAAC"}
|
|
@@ -17,6 +17,16 @@ export const createReadFileImpl = (deps) => {
|
|
|
17
17
|
throw err;
|
|
18
18
|
}
|
|
19
19
|
const content = await fs.readFile(fullPath);
|
|
20
|
+
const isJson = filePath.trim().toLowerCase().endsWith(".json");
|
|
21
|
+
const isRanged = startLine !== undefined || endLine !== undefined;
|
|
22
|
+
if (isJson && !isRanged) {
|
|
23
|
+
try {
|
|
24
|
+
return { kind: "json", json: JSON.parse(content) };
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
// If JSON parsing fails (or file isn't actually JSON), fall back to text slicing.
|
|
28
|
+
}
|
|
29
|
+
}
|
|
20
30
|
return sliceByLines(content, startLine, endLine);
|
|
21
31
|
};
|
|
22
32
|
};
|