@vedangiitb/qwintly-core 1.3.4 → 1.3.5

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.
@@ -33,10 +33,10 @@ ${projectStateNote(isNewProject, "codegen")}
33
33
  submit_codegen_done: Use when you are done with the task and want to submit the codegen to the backend for validation.
34
34
 
35
35
  Important things to note:
36
- 1. If a route doesn't exists, please create it using the create_new_route tool.
37
- 2. When you are adding an image, just give the alt, which should be clear description of the image. The src of the image will be taken care by us.
38
- 3. For icons use only lucide-react icons.
39
-
36
+ 1. If you want to insert an element to a route, use only 1 insert_element call with all its children. DO NOT use multiple insert_element calls for inserting children for an element.
37
+ 2. If a route doesn't exists, please create it using the create_new_route tool.
38
+ 3. When you are adding an image, just give the alt, which should be clear description of the image. The src of the image will be taken care by us.
39
+ 4. For icons use only lucide-react icons.
40
40
  `);
41
41
  const taskInfo = mdSection("Task (Authoritative)", jsonBlock("TASK (You need to implement)", task ?? null));
42
42
  const examples = codegenExamples;
@@ -1 +1 @@
1
- {"version":3,"file":"codegen.prompt.js","sourceRoot":"","sources":["../../../src/ai/prompts/codegen.prompt.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EACL,SAAS,EACT,SAAS,EACT,gBAAgB,GACjB,MAAM,iCAAiC,CAAC;AASzC,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,MAA+B,EAAE,EAAE;IAC/D,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,gBAAgB,EAAE,YAAY,EAAE,GAAG,MAAM,CAAC;IAEtE,MAAM,YAAY,GAAG;EACrB,gBAAgB,CAAC,YAAY,EAAE,SAAS,CAAC;KACtC,CAAC;IAEJ,MAAM,OAAO,GAAG,SAAS,CACvB,yBAAyB,EACzB;QACE,SAAS,CACP,yCAAyC,EACzC,gBAAgB,IAAI,EAAE,CACvB;KACF,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;IAEF,MAAM,oBAAoB,GAAG,SAAS,CACpC,uBAAuB,EACvB;QACE,SAAS,CACP,kBAAkB,EAClB,YAAY,CAAC,cAAc,CAAC,eAAe,CAC5C;QACD,SAAS,CAAC,gBAAgB,EAAE,YAAY,CAAC,cAAc,CAAC,aAAa,CAAC;QACtE,SAAS,CACP,yBAAyB,EACzB,YAAY,CAAC,cAAc,CAAC,eAAe,CAC5C;KACF,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;IAEF,MAAM,SAAS,GAAG,SAAS,CACzB,YAAY,EAEZ;;;;;;;;;;;;;;;;;;;;;;;;GAwBD,CACA,CAAC;IAEF,MAAM,QAAQ,GAAG,SAAS,CACxB,sBAAsB,EACtB,SAAS,CAAC,8BAA8B,EAAE,IAAI,IAAI,IAAI,CAAC,CACxD,CAAC;IAEF,MAAM,QAAQ,GAAG,eAAe,CAAC;IAEjC,MAAM,QAAQ,GAAG;QACf,YAAY;QACZ,OAAO;QACP,oBAAoB;QACpB,SAAS;QACT,QAAQ;QACR,QAAQ;KACT,CAAC;IACF,OAAO,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;AACtC,CAAC,CAAC","sourcesContent":["import { CodegenIndex, CollectedContext, PlanTask } from \"../../types/public.js\";\r\nimport { codegenExamples } from \"./examples/codegen.examples.js\";\r\nimport {\r\n jsonBlock,\r\n mdSection,\r\n projectStateNote,\r\n} from \"./helpers/promptParts.helper.js\";\r\n\r\nexport type CodegenNodePromptParams = {\r\n task: any;\r\n codegenIndex: CodegenIndex;\r\n collectedContext: CollectedContext;\r\n isNewProject: boolean;\r\n};\r\n\r\nexport const codegenPrompt = (params: CodegenNodePromptParams) => {\r\n const { task, codegenIndex, collectedContext, isNewProject } = params;\r\n\r\n const intialPrompt = `You are a senior software engineer responsible for implementing ONE coding task precisely and safely within an existing codebase.\r\n${projectStateNote(isNewProject, \"codegen\")}\r\n `;\r\n\r\n const context = mdSection(\r\n \"Context (Authoritative)\",\r\n [\r\n jsonBlock(\r\n \"Project Context (User preferences etc.)\",\r\n collectedContext ?? {},\r\n ),\r\n ].join(\"\\n\"),\r\n );\r\n\r\n const projectConfiguration = mdSection(\r\n \"Project Configuration\",\r\n [\r\n jsonBlock(\r\n \"FRAMEWORK CONFIG\",\r\n codegenIndex.projectConfigs.frameworkConfig,\r\n ),\r\n jsonBlock(\"RUNTIME CONFIG\", codegenIndex.projectConfigs.runtimeConfig),\r\n jsonBlock(\r\n \"RENDERING CONFIGURATION\",\r\n codegenIndex.projectConfigs.renderingConfig,\r\n ),\r\n ].join(\"\\n\"),\r\n );\r\n\r\n const toolsInfo = mdSection(\r\n \"Tool Usage\",\r\n\r\n `\r\n You are provided access to the following tools and use them to implement coding tasks.\r\n\r\n read_file: Use when you want to read a file from the codebase.\r\n\r\n list_dir: Use when you want to list the directory structure of a given path.\r\n\r\n create_new_route: Use when you want to create a new route. It will create a new route with a page.tsx and pageConfig.json (initial contents) file.\r\n \r\n insert_element: Use when you want to insert a new element in the config\r\n \r\n delete_element: Use when you want to delete an element from the config.\r\n\r\n update_classname: Use when you want to update the className of an element.\r\n \r\n update_props: Use when you want to update the props of an element.\r\n\r\n submit_codegen_done: Use when you are done with the task and want to submit the codegen to the backend for validation.\r\n\r\n Important things to note:\r\n 1. If a route doesn't exists, please create it using the create_new_route tool.\r\n 2. When you are adding an image, just give the alt, which should be clear description of the image. The src of the image will be taken care by us.\r\n 3. For icons use only lucide-react icons.\r\n\r\n `,\r\n );\r\n\r\n const taskInfo = mdSection(\r\n \"Task (Authoritative)\",\r\n jsonBlock(\"TASK (You need to implement)\", task ?? null),\r\n );\r\n\r\n const examples = codegenExamples;\r\n\r\n const sections = [\r\n intialPrompt,\r\n context,\r\n projectConfiguration,\r\n toolsInfo,\r\n examples,\r\n taskInfo,\r\n ];\r\n return sections.join(\"\\n\\n---\\n\\n\");\r\n};\r\n"]}
1
+ {"version":3,"file":"codegen.prompt.js","sourceRoot":"","sources":["../../../src/ai/prompts/codegen.prompt.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC;AACjE,OAAO,EACL,SAAS,EACT,SAAS,EACT,gBAAgB,GACjB,MAAM,iCAAiC,CAAC;AASzC,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,MAA+B,EAAE,EAAE;IAC/D,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,gBAAgB,EAAE,YAAY,EAAE,GAAG,MAAM,CAAC;IAEtE,MAAM,YAAY,GAAG;EACrB,gBAAgB,CAAC,YAAY,EAAE,SAAS,CAAC;KACtC,CAAC;IAEJ,MAAM,OAAO,GAAG,SAAS,CACvB,yBAAyB,EACzB;QACE,SAAS,CACP,yCAAyC,EACzC,gBAAgB,IAAI,EAAE,CACvB;KACF,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;IAEF,MAAM,oBAAoB,GAAG,SAAS,CACpC,uBAAuB,EACvB;QACE,SAAS,CACP,kBAAkB,EAClB,YAAY,CAAC,cAAc,CAAC,eAAe,CAC5C;QACD,SAAS,CAAC,gBAAgB,EAAE,YAAY,CAAC,cAAc,CAAC,aAAa,CAAC;QACtE,SAAS,CACP,yBAAyB,EACzB,YAAY,CAAC,cAAc,CAAC,eAAe,CAC5C;KACF,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;IAEF,MAAM,SAAS,GAAG,SAAS,CACzB,YAAY,EAEZ;;;;;;;;;;;;;;;;;;;;;;;;GAwBD,CACA,CAAC;IAEF,MAAM,QAAQ,GAAG,SAAS,CACxB,sBAAsB,EACtB,SAAS,CAAC,8BAA8B,EAAE,IAAI,IAAI,IAAI,CAAC,CACxD,CAAC;IAEF,MAAM,QAAQ,GAAG,eAAe,CAAC;IAEjC,MAAM,QAAQ,GAAG;QACf,YAAY;QACZ,OAAO;QACP,oBAAoB;QACpB,SAAS;QACT,QAAQ;QACR,QAAQ;KACT,CAAC;IACF,OAAO,QAAQ,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;AACtC,CAAC,CAAC","sourcesContent":["import { CodegenIndex, CollectedContext, PlanTask } from \"../../types/public.js\";\r\nimport { codegenExamples } from \"./examples/codegen.examples.js\";\r\nimport {\r\n jsonBlock,\r\n mdSection,\r\n projectStateNote,\r\n} from \"./helpers/promptParts.helper.js\";\r\n\r\nexport type CodegenNodePromptParams = {\r\n task: any;\r\n codegenIndex: CodegenIndex;\r\n collectedContext: CollectedContext;\r\n isNewProject: boolean;\r\n};\r\n\r\nexport const codegenPrompt = (params: CodegenNodePromptParams) => {\r\n const { task, codegenIndex, collectedContext, isNewProject } = params;\r\n\r\n const intialPrompt = `You are a senior software engineer responsible for implementing ONE coding task precisely and safely within an existing codebase.\r\n${projectStateNote(isNewProject, \"codegen\")}\r\n `;\r\n\r\n const context = mdSection(\r\n \"Context (Authoritative)\",\r\n [\r\n jsonBlock(\r\n \"Project Context (User preferences etc.)\",\r\n collectedContext ?? {},\r\n ),\r\n ].join(\"\\n\"),\r\n );\r\n\r\n const projectConfiguration = mdSection(\r\n \"Project Configuration\",\r\n [\r\n jsonBlock(\r\n \"FRAMEWORK CONFIG\",\r\n codegenIndex.projectConfigs.frameworkConfig,\r\n ),\r\n jsonBlock(\"RUNTIME CONFIG\", codegenIndex.projectConfigs.runtimeConfig),\r\n jsonBlock(\r\n \"RENDERING CONFIGURATION\",\r\n codegenIndex.projectConfigs.renderingConfig,\r\n ),\r\n ].join(\"\\n\"),\r\n );\r\n\r\n const toolsInfo = mdSection(\r\n \"Tool Usage\",\r\n\r\n `\r\n You are provided access to the following tools and use them to implement coding tasks.\r\n\r\n read_file: Use when you want to read a file from the codebase.\r\n\r\n list_dir: Use when you want to list the directory structure of a given path.\r\n\r\n create_new_route: Use when you want to create a new route. It will create a new route with a page.tsx and pageConfig.json (initial contents) file.\r\n \r\n insert_element: Use when you want to insert a new element in the config\r\n \r\n delete_element: Use when you want to delete an element from the config.\r\n\r\n update_classname: Use when you want to update the className of an element.\r\n \r\n update_props: Use when you want to update the props of an element.\r\n\r\n submit_codegen_done: Use when you are done with the task and want to submit the codegen to the backend for validation.\r\n\r\n Important things to note:\r\n 1. If you want to insert an element to a route, use only 1 insert_element call with all its children. DO NOT use multiple insert_element calls for inserting children for an element.\r\n 2. If a route doesn't exists, please create it using the create_new_route tool.\r\n 3. When you are adding an image, just give the alt, which should be clear description of the image. The src of the image will be taken care by us.\r\n 4. For icons use only lucide-react icons.\r\n `,\r\n );\r\n\r\n const taskInfo = mdSection(\r\n \"Task (Authoritative)\",\r\n jsonBlock(\"TASK (You need to implement)\", task ?? null),\r\n );\r\n\r\n const examples = codegenExamples;\r\n\r\n const sections = [\r\n intialPrompt,\r\n context,\r\n projectConfiguration,\r\n toolsInfo,\r\n examples,\r\n taskInfo,\r\n ];\r\n return sections.join(\"\\n\\n---\\n\\n\");\r\n};\r\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"codegen.examples.d.ts","sourceRoot":"","sources":["../../../../src/ai/prompts/examples/codegen.examples.ts"],"names":[],"mappings":"AAkFA,eAAO,MAAM,eAAe,QAAsB,CAAC"}
1
+ {"version":3,"file":"codegen.examples.d.ts","sourceRoot":"","sources":["../../../../src/ai/prompts/examples/codegen.examples.ts"],"names":[],"mappings":"AAmFA,eAAO,MAAM,eAAe,QAAsB,CAAC"}
@@ -36,6 +36,7 @@ Tool call:
36
36
 
37
37
  Notes:
38
38
  - Always pass a complete \`className\` string (Tailwind only).
39
+ - Use \`children\` to nest elements; children can themselves have \`children\` (deep nesting is supported).
39
40
  - Use the returned \`inserted_id\` for follow-up updates.`,
40
41
  `### Example: \`update_classname\` (replace className fully)
41
42
  Goal: Update styling on an existing element.
@@ -1 +1 @@
1
- {"version":3,"file":"codegen.examples.js","sourceRoot":"","sources":["../../../../src/ai/prompts/examples/codegen.examples.ts"],"names":[],"mappings":"AAAA,MAAM,QAAQ,GAAG;IACf;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0DAqCwD;IAExD;;;;;;;;;;;;;+DAa6D;IAE7D;;;;;;;;;;;;;;;;;;;;;;;;8FAwB4F;CAC7F,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC","sourcesContent":["const examples = [\n `## Examples of tool calls\n\n### Example: \\`insert_element\\` (add a CTA section)\nGoal: Insert a new section under the page root on route \\`/\\`.\n\nTool call:\n\\`\\`\\`json\n{\n \"route\": \"/\",\n \"parent_id\": \"root\",\n \"element\": {\n \"type\": \"div\",\n \"className\": \"mt-10 flex items-center justify-between gap-6 rounded-2xl border border-slate-200 bg-white p-6\",\n \"children\": [\n {\n \"type\": \"div\",\n \"className\": \"flex flex-col gap-1\",\n \"children\": [\n { \"type\": \"text\", \"className\": \"text-lg font-semibold text-slate-900\", \"props\": { \"text\": \"Ready to get started?\" } },\n { \"type\": \"text\", \"className\": \"text-sm text-slate-600\", \"props\": { \"text\": \"Create your first project in under a minute.\" } }\n ]\n },\n {\n \"type\": \"button\",\n \"className\": \"inline-flex items-center justify-center rounded-xl bg-slate-900 px-4 py-2 text-sm font-medium text-white hover:bg-slate-800\",\n \"props\": {\n \"text\": \"Get Started\",\n \"onClick\": { \"kind\": \"route\", \"href\": \"/signup\" }\n }\n }\n ]\n }\n}\n\\`\\`\\`\n\nNotes:\n- Always pass a complete \\`className\\` string (Tailwind only).\n- Use the returned \\`inserted_id\\` for follow-up updates.`,\n\n `### Example: \\`update_classname\\` (replace className fully)\nGoal: Update styling on an existing element.\n\nTool call:\n\\`\\`\\`json\n{\n \"route\": \"/\",\n \"element_id\": \"el_123abc\",\n \"className\": \"mt-8 grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3\"\n}\n\\`\\`\\`\n\nNotes:\n- Provide the full \\`className\\`; do not send partial patches.`,\n\n `### Example: \\`update_props\\` (update element props)\nGoal: Update the text and click action for a button.\n\nTool call (function name in tool schema is \\`update_element\\`):\n\\`\\`\\`json\n{\n \"route\": \"/\",\n \"element_id\": \"el_123abc\",\n \"text\": \"Start free trial\",\n \"onClick\": { \"kind\": \"route\", \"href\": \"/pricing\", \"replace\": false }\n}\n\\`\\`\\`\n\nOther common prop updates:\n\\`\\`\\`json\n{\n \"route\": \"/\",\n \"element_id\": \"el_img_001\",\n \"alt\": \"A person collaborating on a laptop in a bright office\"\n}\n\\`\\`\\`\n\nNotes:\n- Only include props you want to change; omitted fields remain unchanged.\n- For images, \\`alt\\` is also used to fetch a suitable Unsplash image (src is auto-resolved).`,\n];\n\nexport const codegenExamples = examples.join(\"\\n\");\n"]}
1
+ {"version":3,"file":"codegen.examples.js","sourceRoot":"","sources":["../../../../src/ai/prompts/examples/codegen.examples.ts"],"names":[],"mappings":"AAAA,MAAM,QAAQ,GAAG;IACf;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0DAsCwD;IAExD;;;;;;;;;;;;;+DAa6D;IAE7D;;;;;;;;;;;;;;;;;;;;;;;;8FAwB4F;CAC7F,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC","sourcesContent":["const examples = [\n `## Examples of tool calls\n\n### Example: \\`insert_element\\` (add a CTA section)\nGoal: Insert a new section under the page root on route \\`/\\`.\n\nTool call:\n\\`\\`\\`json\n{\n \"route\": \"/\",\n \"parent_id\": \"root\",\n \"element\": {\n \"type\": \"div\",\n \"className\": \"mt-10 flex items-center justify-between gap-6 rounded-2xl border border-slate-200 bg-white p-6\",\n \"children\": [\n {\n \"type\": \"div\",\n \"className\": \"flex flex-col gap-1\",\n \"children\": [\n { \"type\": \"text\", \"className\": \"text-lg font-semibold text-slate-900\", \"props\": { \"text\": \"Ready to get started?\" } },\n { \"type\": \"text\", \"className\": \"text-sm text-slate-600\", \"props\": { \"text\": \"Create your first project in under a minute.\" } }\n ]\n },\n {\n \"type\": \"button\",\n \"className\": \"inline-flex items-center justify-center rounded-xl bg-slate-900 px-4 py-2 text-sm font-medium text-white hover:bg-slate-800\",\n \"props\": {\n \"text\": \"Get Started\",\n \"onClick\": { \"kind\": \"route\", \"href\": \"/signup\" }\n }\n }\n ]\n }\n}\n\\`\\`\\`\n\nNotes:\n- Always pass a complete \\`className\\` string (Tailwind only).\n- Use \\`children\\` to nest elements; children can themselves have \\`children\\` (deep nesting is supported).\n- Use the returned \\`inserted_id\\` for follow-up updates.`,\n\n `### Example: \\`update_classname\\` (replace className fully)\nGoal: Update styling on an existing element.\n\nTool call:\n\\`\\`\\`json\n{\n \"route\": \"/\",\n \"element_id\": \"el_123abc\",\n \"className\": \"mt-8 grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3\"\n}\n\\`\\`\\`\n\nNotes:\n- Provide the full \\`className\\`; do not send partial patches.`,\n\n `### Example: \\`update_props\\` (update element props)\nGoal: Update the text and click action for a button.\n\nTool call (function name in tool schema is \\`update_element\\`):\n\\`\\`\\`json\n{\n \"route\": \"/\",\n \"element_id\": \"el_123abc\",\n \"text\": \"Start free trial\",\n \"onClick\": { \"kind\": \"route\", \"href\": \"/pricing\", \"replace\": false }\n}\n\\`\\`\\`\n\nOther common prop updates:\n\\`\\`\\`json\n{\n \"route\": \"/\",\n \"element_id\": \"el_img_001\",\n \"alt\": \"A person collaborating on a laptop in a bright office\"\n}\n\\`\\`\\`\n\nNotes:\n- Only include props you want to change; omitted fields remain unchanged.\n- For images, \\`alt\\` is also used to fetch a suitable Unsplash image (src is auto-resolved).`,\n];\n\nexport const codegenExamples = examples.join(\"\\n\");\n"]}
@@ -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;AAQ9B,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,CA2RzB"}
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,CAoSzB"}
@@ -2,6 +2,7 @@ import { FunctionCallingConfigMode } from "@google/genai";
2
2
  import { EVENT_TYPES } from "../../types/events.js";
3
3
  import { compactForModel, DEFAULT_CONTEXT_POLICY, normalizeReadFileArgs, redactFunctionCallArgs, } from "./toolLoopContext.js";
4
4
  import { aiCallWithRetry, buildToolStatusMessage, recordToolEvent, serializeError, } from "./toolLoopRunnerUtils.js";
5
+ import { persistToolCall } from "../../services/toolcallPersist.service.js";
5
6
  export async function runToolLoop(options) {
6
7
  const { initialContents, tools, handlers, 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
7
8
  aiCallAutoRetryBaseMs = 400, aiCallAutoRetryMaxMs = 10000, } = options;
@@ -157,6 +158,15 @@ export async function runToolLoop(options) {
157
158
  : undefined,
158
159
  };
159
160
  }
161
+ try {
162
+ await persistToolCall(name, modelArgs, toolResult);
163
+ }
164
+ catch (err) {
165
+ console.error("Tool loop: failed to persist tool call", err, {
166
+ tool: name,
167
+ step: step + 1,
168
+ });
169
+ }
160
170
  const responseFull = {
161
171
  role: "user",
162
172
  parts: [
@@ -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\";\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 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 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 +1 @@
1
- {"version":3,"file":"insertElement.schema.d.ts","sourceRoot":"","sources":["../../../../src/ai/tools/schemas/insertElement.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAErC,eAAO,MAAM,aAAa,8FAUhB,CAAC;AA6BX,eAAO,MAAM,oBAAoB,EAAE,GAoFlC,CAAC;AAEF,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;CAuB/B,CAAC"}
1
+ {"version":3,"file":"insertElement.schema.d.ts","sourceRoot":"","sources":["../../../../src/ai/tools/schemas/insertElement.schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,eAAe,CAAC;AAErC,eAAO,MAAM,aAAa,8FAUhB,CAAC;AAqFX,eAAO,MAAM,oBAAoB,EAAE,GA8BlC,CAAC;AAEF,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;CAuB/B,CAAC"}
@@ -33,7 +33,57 @@ const OnClickActionSchema = {
33
33
  },
34
34
  required: ["kind"],
35
35
  };
36
- // Self-referential schema (children.items -> BuilderElementSchema)
36
+ const BuilderElementPropsSchema = {
37
+ type: Type.OBJECT,
38
+ properties: {
39
+ onClick: OnClickActionSchema,
40
+ text: {
41
+ type: Type.STRING,
42
+ description: "Text content used by 'text' (<p>), 'button' (label), and as a fallback for 'link' when it has no children.",
43
+ },
44
+ href: {
45
+ type: Type.STRING,
46
+ description: "For 'link': the href attribute (defaults to '#').",
47
+ },
48
+ placeholder: {
49
+ type: Type.STRING,
50
+ description: "For 'input' and 'textarea': placeholder shown when empty.",
51
+ },
52
+ alt: {
53
+ type: Type.STRING,
54
+ description: "For 'image': alt text for accessibility AND the query used to fetch a suitable Unsplash image (src is auto-resolved from alt).",
55
+ },
56
+ target: {
57
+ type: Type.STRING,
58
+ description: "For 'link': target attribute (e.g. '_blank').",
59
+ },
60
+ rel: {
61
+ type: Type.STRING,
62
+ description: "For 'link': rel attribute (e.g. 'noreferrer').",
63
+ },
64
+ value: {
65
+ type: Type.STRING,
66
+ description: "For 'input' and 'textarea': default value (maps to defaultValue).",
67
+ },
68
+ type: {
69
+ type: Type.STRING,
70
+ description: "For 'input': input type (e.g. 'text', 'email', 'password'). Defaults to 'text'.",
71
+ },
72
+ // icon
73
+ name: {
74
+ type: Type.STRING,
75
+ description: "For 'icon': Lucide icon name (e.g. 'ArrowRight', 'Menu').",
76
+ },
77
+ size: { type: Type.NUMBER, description: "For 'icon': size in px." },
78
+ color: { type: Type.STRING, description: "For 'icon': stroke color." },
79
+ strokeWidth: {
80
+ type: Type.NUMBER,
81
+ description: "For 'icon': stroke width.",
82
+ },
83
+ },
84
+ };
85
+ // Recursive via JSON Schema $ref (no cyclic JS object needed).
86
+ // This lets the model emit arbitrarily deep nested `children` safely.
37
87
  export const BuilderElementSchema = {
38
88
  type: Type.OBJECT,
39
89
  properties: {
@@ -50,60 +100,13 @@ export const BuilderElementSchema = {
50
100
  type: Type.BOOLEAN,
51
101
  description: "Whether the element should be shown.",
52
102
  },
53
- props: {
54
- type: Type.OBJECT,
55
- properties: {
56
- onClick: OnClickActionSchema,
57
- text: {
58
- type: Type.STRING,
59
- description: "Text content used by 'text' (<p>), 'button' (label), and as a fallback for 'link' when it has no children.",
60
- },
61
- href: {
62
- type: Type.STRING,
63
- description: "For 'link': the href attribute (defaults to '#').",
64
- },
65
- placeholder: {
66
- type: Type.STRING,
67
- description: "For 'input' and 'textarea': placeholder shown when empty.",
68
- },
69
- alt: {
70
- type: Type.STRING,
71
- description: "For 'image': alt text for accessibility AND the query used to fetch a suitable Unsplash image (src is auto-resolved from alt).",
72
- },
73
- target: {
74
- type: Type.STRING,
75
- description: "For 'link': target attribute (e.g. '_blank').",
76
- },
77
- rel: {
78
- type: Type.STRING,
79
- description: "For 'link': rel attribute (e.g. 'noreferrer').",
80
- },
81
- value: {
82
- type: Type.STRING,
83
- description: "For 'input' and 'textarea': default value (maps to defaultValue).",
84
- },
85
- type: {
86
- type: Type.STRING,
87
- description: "For 'input': input type (e.g. 'text', 'email', 'password'). Defaults to 'text'.",
88
- },
89
- // icon
90
- name: {
91
- type: Type.STRING,
92
- description: "For 'icon': Lucide icon name (e.g. 'ArrowRight', 'Menu').",
93
- },
94
- size: { type: Type.NUMBER, description: "For 'icon': size in px." },
95
- color: { type: Type.STRING, description: "For 'icon': stroke color." },
96
- strokeWidth: {
97
- type: Type.NUMBER,
98
- description: "For 'icon': stroke width.",
99
- },
100
- },
101
- },
103
+ props: BuilderElementPropsSchema,
102
104
  children: {
103
105
  type: Type.ARRAY,
104
- description: "Nested children. Used by 'fragment' and 'div' directly, and by 'button'/'link' when present (otherwise they use props.text).",
106
+ description: "Nested children (each child is another element). Use children[].children[] for deeper nesting.",
105
107
  items: {
106
- type: Type.OBJECT,
108
+ // JSON Schema self-reference: the item is another BuilderElement
109
+ $ref: "#",
107
110
  },
108
111
  },
109
112
  },
@@ -111,7 +114,7 @@ export const BuilderElementSchema = {
111
114
  };
112
115
  export const InsertElementSchema = {
113
116
  name: "insert_element",
114
- description: "Inserts element code. The element should be valid following the BuilderElement schema.",
117
+ description: "Inserts element code. Use element.children to create nested UI. Each child is another BuilderElement and can itself have children.",
115
118
  parameters: {
116
119
  type: Type.OBJECT,
117
120
  properties: {
@@ -1 +1 @@
1
- {"version":3,"file":"insertElement.schema.js","sourceRoot":"","sources":["../../../../src/ai/tools/schemas/insertElement.schema.ts"],"names":[],"mappings":"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","sourcesContent":["import { Type } from \"@google/genai\";\n\nexport const ELEMENT_TYPES = [\n \"fragment\",\n \"div\",\n \"text\",\n \"image\",\n \"button\",\n \"input\",\n \"textarea\",\n \"link\",\n \"icon\",\n] as const;\n\nconst OnClickActionSchema = {\n type: Type.OBJECT,\n properties: {\n kind: {\n type: Type.STRING,\n enum: [\"route\", \"back\", \"reload\", \"external\"],\n description:\n \"What happens when the element is clicked. 'route' navigates within the app, 'external' opens a URL, 'back' goes back, 'reload' refreshes.\",\n },\n href: {\n type: Type.STRING,\n description:\n \"URL to navigate to (used for kind='route' and kind='external').\",\n },\n replace: {\n type: Type.BOOLEAN,\n description: \"For kind='route': replace history instead of pushing.\",\n },\n newTab: {\n type: Type.BOOLEAN,\n description: \"For kind='external': open link in a new tab.\",\n },\n },\n required: [\"kind\"],\n};\n\n// Self-referential schema (children.items -> BuilderElementSchema)\nexport const BuilderElementSchema: any = {\n type: Type.OBJECT,\n properties: {\n type: {\n type: Type.STRING,\n enum: ELEMENT_TYPES,\n description:\n \"Element type to render. 'text' renders a <p>, 'image' renders an <img>, 'link' renders an <a>, 'icon' renders a Lucide icon, 'fragment' renders children only.\",\n },\n className: {\n type: Type.STRING,\n description:\n \"Tailwind CSS className applied to the rendered element (Tailwind only).\",\n },\n visible: {\n type: Type.BOOLEAN,\n description: \"Whether the element should be shown.\",\n },\n props: {\n type: Type.OBJECT,\n properties: {\n onClick: OnClickActionSchema,\n text: {\n type: Type.STRING,\n description:\n \"Text content used by 'text' (<p>), 'button' (label), and as a fallback for 'link' when it has no children.\",\n },\n href: {\n type: Type.STRING,\n description: \"For 'link': the href attribute (defaults to '#').\",\n },\n placeholder: {\n type: Type.STRING,\n description:\n \"For 'input' and 'textarea': placeholder shown when empty.\",\n },\n alt: {\n type: Type.STRING,\n description:\n \"For 'image': alt text for accessibility AND the query used to fetch a suitable Unsplash image (src is auto-resolved from alt).\",\n },\n target: {\n type: Type.STRING,\n description: \"For 'link': target attribute (e.g. '_blank').\",\n },\n rel: {\n type: Type.STRING,\n description: \"For 'link': rel attribute (e.g. 'noreferrer').\",\n },\n value: {\n type: Type.STRING,\n description:\n \"For 'input' and 'textarea': default value (maps to defaultValue).\",\n },\n type: {\n type: Type.STRING,\n description:\n \"For 'input': input type (e.g. 'text', 'email', 'password'). Defaults to 'text'.\",\n },\n\n // icon\n name: {\n type: Type.STRING,\n description:\n \"For 'icon': Lucide icon name (e.g. 'ArrowRight', 'Menu').\",\n },\n size: { type: Type.NUMBER, description: \"For 'icon': size in px.\" },\n color: { type: Type.STRING, description: \"For 'icon': stroke color.\" },\n strokeWidth: {\n type: Type.NUMBER,\n description: \"For 'icon': stroke width.\",\n },\n },\n },\n children: {\n type: Type.ARRAY,\n description:\n \"Nested children. Used by 'fragment' and 'div' directly, and by 'button'/'link' when present (otherwise they use props.text).\",\n items: {\n type: Type.OBJECT,\n },\n },\n },\n required: [\"type\"],\n};\n\nexport const InsertElementSchema = {\n name: \"insert_element\",\n description:\n \"Inserts element code. The element should be valid following the BuilderElement schema.\",\n parameters: {\n type: Type.OBJECT,\n properties: {\n route: {\n type: Type.STRING,\n description:\n \"The route to insert the element at. Example. '/' or '/about' etc.\",\n },\n parent_id: {\n type: Type.STRING,\n description: \"The parent id to insert the element at.\",\n },\n element: {\n ...BuilderElementSchema,\n description: \"The element to insert.\",\n },\n },\n required: [\"route\", \"parent_id\", \"element\"],\n },\n};\n"]}
1
+ {"version":3,"file":"insertElement.schema.js","sourceRoot":"","sources":["../../../../src/ai/tools/schemas/insertElement.schema.ts"],"names":[],"mappings":"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","sourcesContent":["import { Type } from \"@google/genai\";\n\nexport const ELEMENT_TYPES = [\n \"fragment\",\n \"div\",\n \"text\",\n \"image\",\n \"button\",\n \"input\",\n \"textarea\",\n \"link\",\n \"icon\",\n] as const;\n\nconst OnClickActionSchema = {\n type: Type.OBJECT,\n properties: {\n kind: {\n type: Type.STRING,\n enum: [\"route\", \"back\", \"reload\", \"external\"],\n description:\n \"What happens when the element is clicked. 'route' navigates within the app, 'external' opens a URL, 'back' goes back, 'reload' refreshes.\",\n },\n href: {\n type: Type.STRING,\n description:\n \"URL to navigate to (used for kind='route' and kind='external').\",\n },\n replace: {\n type: Type.BOOLEAN,\n description: \"For kind='route': replace history instead of pushing.\",\n },\n newTab: {\n type: Type.BOOLEAN,\n description: \"For kind='external': open link in a new tab.\",\n },\n },\n required: [\"kind\"],\n};\n\nconst BuilderElementPropsSchema = {\n type: Type.OBJECT,\n properties: {\n onClick: OnClickActionSchema,\n text: {\n type: Type.STRING,\n description:\n \"Text content used by 'text' (<p>), 'button' (label), and as a fallback for 'link' when it has no children.\",\n },\n href: {\n type: Type.STRING,\n description: \"For 'link': the href attribute (defaults to '#').\",\n },\n placeholder: {\n type: Type.STRING,\n description: \"For 'input' and 'textarea': placeholder shown when empty.\",\n },\n alt: {\n type: Type.STRING,\n description:\n \"For 'image': alt text for accessibility AND the query used to fetch a suitable Unsplash image (src is auto-resolved from alt).\",\n },\n target: {\n type: Type.STRING,\n description: \"For 'link': target attribute (e.g. '_blank').\",\n },\n rel: {\n type: Type.STRING,\n description: \"For 'link': rel attribute (e.g. 'noreferrer').\",\n },\n value: {\n type: Type.STRING,\n description:\n \"For 'input' and 'textarea': default value (maps to defaultValue).\",\n },\n type: {\n type: Type.STRING,\n description:\n \"For 'input': input type (e.g. 'text', 'email', 'password'). Defaults to 'text'.\",\n },\n\n // icon\n name: {\n type: Type.STRING,\n description: \"For 'icon': Lucide icon name (e.g. 'ArrowRight', 'Menu').\",\n },\n size: { type: Type.NUMBER, description: \"For 'icon': size in px.\" },\n color: { type: Type.STRING, description: \"For 'icon': stroke color.\" },\n strokeWidth: {\n type: Type.NUMBER,\n description: \"For 'icon': stroke width.\",\n },\n },\n};\n\n// Recursive via JSON Schema $ref (no cyclic JS object needed).\n// This lets the model emit arbitrarily deep nested `children` safely.\nexport const BuilderElementSchema: any = {\n type: Type.OBJECT,\n properties: {\n type: {\n type: Type.STRING,\n enum: ELEMENT_TYPES,\n description:\n \"Element type to render. 'text' renders a <p>, 'image' renders an <img>, 'link' renders an <a>, 'icon' renders a Lucide icon, 'fragment' renders children only.\",\n },\n className: {\n type: Type.STRING,\n description:\n \"Tailwind CSS className applied to the rendered element (Tailwind only).\",\n },\n visible: {\n type: Type.BOOLEAN,\n description: \"Whether the element should be shown.\",\n },\n props: BuilderElementPropsSchema,\n children: {\n type: Type.ARRAY,\n description:\n \"Nested children (each child is another element). Use children[].children[] for deeper nesting.\",\n items: {\n // JSON Schema self-reference: the item is another BuilderElement\n $ref: \"#\",\n },\n },\n },\n required: [\"type\"],\n};\n\nexport const InsertElementSchema = {\n name: \"insert_element\",\n description:\n \"Inserts element code. Use element.children to create nested UI. Each child is another BuilderElement and can itself have children.\",\n parameters: {\n type: Type.OBJECT,\n properties: {\n route: {\n type: Type.STRING,\n description:\n \"The route to insert the element at. Example. '/' or '/about' etc.\",\n },\n parent_id: {\n type: Type.STRING,\n description: \"The parent id to insert the element at.\",\n },\n element: {\n ...BuilderElementSchema,\n description: \"The element to insert.\",\n },\n },\n required: [\"route\", \"parent_id\", \"element\"],\n },\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AAAA,OAAO,EAA6B,IAAI,EAAE,MAAM,eAAe,CAAC;AAEhE,OAAO,EAGL,WAAW,EACX,cAAc,EACf,MAAM,iCAAiC,CAAC;AAUzC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,cAAc,EACf,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAGhE,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/C,OAAO,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACxC,QAAQ,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,MAAM,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC7C,CAAC;AAiBF,qBAAa,WAAW;IACtB,SAAgB,MAAM,EAAE,MAAM,CAAC;IAC/B,SAAgB,SAAS,EAAE,MAAM,CAAC;IAClC,SAAgB,aAAa,EAAE,MAAM,CAAC;IACtC,SAAgB,MAAM,EAAE,MAAM,CAAC;IAC/B,SAAgB,IAAI,EAAE,OAAO,CAAC;IAE9B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAW;IACrC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAsB;IACjD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoB;IAC5C,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAoB;gBAE7C,OAAO,EAAE,kBAAkB;IAkD1B,SAAS,CACpB,eAAe,EAAE,GAAG,EAAE,EACtB,KAAK,EAAE,IAAI,EAAE,EACb,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EACrC,QAAQ,EAAE,MAAM,EAChB,iBAAiB,EAAE,MAAM,EAAE,GAC1B,OAAO,CAAC,cAAc,CAAC;IAwBb,SAAS,CACpB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,SAAS,EACpB,gBAAgB,GAAE,OAAe,GAChC,OAAO,CAAC,IAAI,CAAC;IA2BH,mBAAmB,IAAI,OAAO,CAAC,WAAW,CAAC;YAQ1C,UAAU;IAMX,eAAe,IAAI,OAAO,CAAC,YAAY,CAAC;IAIxC,eAAe,IAAI,OAAO,CAAC,YAAY,CAAC;IAIxC,iBAAiB,IAAI,OAAO,CAAC,cAAc,CAAC;CAG1D"}
1
+ {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"AAAA,OAAO,EAA6B,IAAI,EAAE,MAAM,eAAe,CAAC;AAEhE,OAAO,EAGL,WAAW,EACX,cAAc,EACf,MAAM,iCAAiC,CAAC;AAUzC,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,cAAc,EACf,MAAM,8BAA8B,CAAC;AACtC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,8BAA8B,CAAC;AAIhE,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;IACd,QAAQ,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/C,OAAO,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC;IACxC,QAAQ,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAC7C,MAAM,CAAC,EAAE;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAC7C,CAAC;AAiBF,qBAAa,WAAW;IACtB,SAAgB,MAAM,EAAE,MAAM,CAAC;IAC/B,SAAgB,SAAS,EAAE,MAAM,CAAC;IAClC,SAAgB,aAAa,EAAE,MAAM,CAAC;IACtC,SAAgB,MAAM,EAAE,MAAM,CAAC;IAC/B,SAAgB,IAAI,EAAE,OAAO,CAAC;IAE9B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAW;IACrC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAsB;IACjD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAoB;IAC5C,OAAO,CAAC,QAAQ,CAAC,oBAAoB,CAAoB;gBAE7C,OAAO,EAAE,kBAAkB;IAuD1B,SAAS,CACpB,eAAe,EAAE,GAAG,EAAE,EACtB,KAAK,EAAE,IAAI,EAAE,EACb,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,WAAW,CAAC,EACrC,QAAQ,EAAE,MAAM,EAChB,iBAAiB,EAAE,MAAM,EAAE,GAC1B,OAAO,CAAC,cAAc,CAAC;IAwBb,SAAS,CACpB,OAAO,EAAE,MAAM,EACf,SAAS,EAAE,SAAS,EACpB,gBAAgB,GAAE,OAAe,GAChC,OAAO,CAAC,IAAI,CAAC;IA2BH,mBAAmB,IAAI,OAAO,CAAC,WAAW,CAAC;YAQ1C,UAAU;IAMX,eAAe,IAAI,OAAO,CAAC,YAAY,CAAC;IAIxC,eAAe,IAAI,OAAO,CAAC,YAAY,CAAC;IAIxC,iBAAiB,IAAI,OAAO,CAAC,cAAc,CAAC;CAG1D"}
package/dist/core.js CHANGED
@@ -10,6 +10,7 @@ import { SendStatusToRedis } from "./logging/redis.service.js";
10
10
  import { ContextRepository } from "./repository/context.repository.js";
11
11
  import { GenStatusRepository } from "./repository/genStatus.repository.js";
12
12
  import { assertNonEmptyString } from "./utils/utils.js";
13
+ import { initializeToolCallsRepository } from "./services/toolcallPersist.service.js";
13
14
  export class QwintlyCore {
14
15
  constructor(options) {
15
16
  assertNonEmptyString(options.chatId, "chatId");
@@ -38,6 +39,7 @@ export class QwintlyCore {
38
39
  this.statusRepo = new GenStatusRepository(options.supabase.endpoint, options.supabase.secret);
39
40
  this.ctxRepo = new ContextRepository(options.supabase.endpoint, options.supabase.secret);
40
41
  this.redisStatusPublisher = new SendStatusToRedis(options.upstash.url, options.upstash.token);
42
+ initializeToolCallsRepository(options.supabase.endpoint, options.supabase.secret, options.sessionId);
41
43
  console.log(`QwintlyCore initialized (chatId=${this.chatId}, sessionId=${this.sessionId})`);
42
44
  }
43
45
  async runAiFlow(initialContents, tools, handlers, maxSteps, terminalToolNames) {
package/dist/core.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"core.js","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"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","sourcesContent":["import { FunctionCallingConfigMode, Tool } from \"@google/genai\";\nimport { getClient } from \"./ai/generate/generateClient.js\";\nimport {\n runToolLoop,\n RunToolLoopOptions,\n ToolHandler,\n ToolLoopResult,\n} from \"./ai/toolLoop/toolLoopRunner.js\";\nimport { initUnsplash } from \"./image/unsplash.service.js\";\nimport { buildCodegenIndex } from \"./indexer/codegenIndex.js\";\nimport { buildPlannerIndex } from \"./indexer/plannerIndex.js\";\nimport { computeProjectInfo } from \"./indexer/projectInfoIndex.js\";\nimport { buildValidatorIndex } from \"./indexer/validatorIndex.js\";\nimport { statusService } from \"./logging/genStatus.service.js\";\nimport { SendStatusToRedis } from \"./logging/redis.service.js\";\nimport { ContextRepository } from \"./repository/context.repository.js\";\nimport { GenStatusRepository } from \"./repository/genStatus.repository.js\";\nimport { EventType, GenStep } from \"./types/events.js\";\nimport {\n CodegenIndex,\n PlannerIndex,\n ValidatorIndex,\n} from \"./types/index/index.types.js\";\nimport type { ProjectInfo } from \"./types/projectInfo.types.js\";\nimport { assertNonEmptyString } from \"./utils/utils.js\";\n\nexport type QwintlyCoreOptions = {\n chatId: string;\n sessionId: string;\n workspacePath: string;\n source: string;\n step: GenStep;\n supabase: { endpoint: string; secret: string };\n upstash: { url: string; token: string };\n unsplash: { url: string; accessKey: string };\n gemini?: { apiKey: string; model?: string };\n};\n\ntype AiResponseOptions = {\n tools?: Tool[];\n toolCallingMode?: FunctionCallingConfigMode;\n};\n\ntype AiClient = {\n aiResponse: (\n request: unknown,\n options?: AiResponseOptions,\n ) => Promise<{\n functionCalls?: any[];\n text?: string;\n }>;\n};\n\nexport class QwintlyCore {\n public readonly chatId: string;\n public readonly sessionId: string;\n public readonly workspacePath: string;\n public readonly source: string;\n public readonly step: GenStep;\n\n private readonly aiClient?: AiClient;\n private readonly statusRepo: GenStatusRepository;\n private readonly ctxRepo: ContextRepository;\n private readonly redisStatusPublisher: SendStatusToRedis;\n\n constructor(options: QwintlyCoreOptions) {\n assertNonEmptyString(options.chatId, \"chatId\");\n assertNonEmptyString(options.sessionId, \"sessionId\");\n assertNonEmptyString(options.workspacePath, \"workspacePath\");\n assertNonEmptyString(options.source, \"source\");\n assertNonEmptyString(options.step, \"step\");\n assertNonEmptyString(options.supabase?.endpoint, \"supabase.endpoint\");\n assertNonEmptyString(options.supabase?.secret, \"supabase.secret\");\n assertNonEmptyString(options.upstash?.url, \"upstash.url\");\n assertNonEmptyString(options.upstash?.token, \"upstash.token\");\n\n this.chatId = options.chatId;\n this.sessionId = options.sessionId;\n this.workspacePath = options.workspacePath;\n this.source = options.source;\n this.step = options.step;\n\n if (options.unsplash?.url && options.unsplash?.accessKey) {\n initUnsplash({\n url: options.unsplash.url,\n accessKey: options.unsplash.accessKey,\n });\n }\n\n if (options.gemini?.apiKey) {\n this.aiClient = getClient(\n \"gemini\",\n options.gemini.apiKey,\n options.gemini.model,\n ) as AiClient;\n }\n\n this.statusRepo = new GenStatusRepository(\n options.supabase.endpoint,\n options.supabase.secret,\n );\n this.ctxRepo = new ContextRepository(\n options.supabase.endpoint,\n options.supabase.secret,\n );\n this.redisStatusPublisher = new SendStatusToRedis(\n options.upstash.url,\n options.upstash.token,\n );\n\n console.log(\n `QwintlyCore initialized (chatId=${this.chatId}, sessionId=${this.sessionId})`,\n );\n }\n\n public async runAiFlow(\n initialContents: any[],\n tools: Tool[],\n handlers: Record<string, ToolHandler>,\n maxSteps: number,\n terminalToolNames: string[],\n ): Promise<ToolLoopResult> {\n if (!this.aiClient) {\n throw new Error(\n \"AI client not initialized. Please provide 'gemini' config to use runAiFlow.\",\n );\n }\n const toolLoopOptions: RunToolLoopOptions = {\n initialContents: initialContents,\n tools: tools,\n handlers: handlers,\n maxSteps: maxSteps,\n terminalToolNames: terminalToolNames,\n aiCall: (request, options) =>\n this.aiClient!.aiResponse(request, {\n tools: options.tools,\n toolCallingMode: options.toolCallingMode,\n }),\n logger: this.streamLog.bind(this),\n };\n\n const result = await runToolLoop(toolLoopOptions);\n return result;\n }\n\n public async streamLog(\n message: string,\n eventType: EventType,\n displayedSummary: boolean = false,\n ): Promise<void> {\n try {\n assertNonEmptyString(message, \"message\");\n await statusService(\n this.chatId,\n this.sessionId,\n eventType,\n this.step,\n message,\n this.source,\n {\n repository: {\n persist: this.statusRepo.persistStatusMessage.bind(this.statusRepo),\n },\n publisher: {\n publish: this.redisStatusPublisher.sendStatusToRedis.bind(\n this.redisStatusPublisher,\n ),\n },\n },\n displayedSummary,\n );\n } catch (error) {\n console.error(error);\n }\n }\n\n public async buildProjectInfoIdx(): Promise<ProjectInfo> {\n const projectInfo = await computeProjectInfo(this.workspacePath);\n\n await this.ctxRepo.updateProjectInfo(this.chatId, projectInfo);\n\n return projectInfo;\n }\n\n private async buildIndex<T>(\n builder: (path: string) => Promise<T>,\n ): Promise<T> {\n return builder(this.workspacePath);\n }\n\n public async buildPlannerIdx(): Promise<PlannerIndex> {\n return this.buildIndex(buildPlannerIndex);\n }\n\n public async buildCodegenIdx(): Promise<CodegenIndex> {\n return this.buildIndex(buildCodegenIndex);\n }\n\n public async buildValidatorIdx(): Promise<ValidatorIndex> {\n return this.buildIndex(buildValidatorIndex);\n }\n}\n"]}
1
+ {"version":3,"file":"core.js","sourceRoot":"","sources":["../src/core.ts"],"names":[],"mappings":"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","sourcesContent":["import { FunctionCallingConfigMode, Tool } from \"@google/genai\";\nimport { getClient } from \"./ai/generate/generateClient.js\";\nimport {\n runToolLoop,\n RunToolLoopOptions,\n ToolHandler,\n ToolLoopResult,\n} from \"./ai/toolLoop/toolLoopRunner.js\";\nimport { initUnsplash } from \"./image/unsplash.service.js\";\nimport { buildCodegenIndex } from \"./indexer/codegenIndex.js\";\nimport { buildPlannerIndex } from \"./indexer/plannerIndex.js\";\nimport { computeProjectInfo } from \"./indexer/projectInfoIndex.js\";\nimport { buildValidatorIndex } from \"./indexer/validatorIndex.js\";\nimport { statusService } from \"./logging/genStatus.service.js\";\nimport { SendStatusToRedis } from \"./logging/redis.service.js\";\nimport { ContextRepository } from \"./repository/context.repository.js\";\nimport { GenStatusRepository } from \"./repository/genStatus.repository.js\";\nimport { EventType, GenStep } from \"./types/events.js\";\nimport {\n CodegenIndex,\n PlannerIndex,\n ValidatorIndex,\n} from \"./types/index/index.types.js\";\nimport type { ProjectInfo } from \"./types/projectInfo.types.js\";\nimport { assertNonEmptyString } from \"./utils/utils.js\";\nimport { initializeToolCallsRepository } from \"./services/toolcallPersist.service.js\";\n\nexport type QwintlyCoreOptions = {\n chatId: string;\n sessionId: string;\n workspacePath: string;\n source: string;\n step: GenStep;\n supabase: { endpoint: string; secret: string };\n upstash: { url: string; token: string };\n unsplash: { url: string; accessKey: string };\n gemini?: { apiKey: string; model?: string };\n};\n\ntype AiResponseOptions = {\n tools?: Tool[];\n toolCallingMode?: FunctionCallingConfigMode;\n};\n\ntype AiClient = {\n aiResponse: (\n request: unknown,\n options?: AiResponseOptions,\n ) => Promise<{\n functionCalls?: any[];\n text?: string;\n }>;\n};\n\nexport class QwintlyCore {\n public readonly chatId: string;\n public readonly sessionId: string;\n public readonly workspacePath: string;\n public readonly source: string;\n public readonly step: GenStep;\n\n private readonly aiClient?: AiClient;\n private readonly statusRepo: GenStatusRepository;\n private readonly ctxRepo: ContextRepository;\n private readonly redisStatusPublisher: SendStatusToRedis;\n\n constructor(options: QwintlyCoreOptions) {\n assertNonEmptyString(options.chatId, \"chatId\");\n assertNonEmptyString(options.sessionId, \"sessionId\");\n assertNonEmptyString(options.workspacePath, \"workspacePath\");\n assertNonEmptyString(options.source, \"source\");\n assertNonEmptyString(options.step, \"step\");\n assertNonEmptyString(options.supabase?.endpoint, \"supabase.endpoint\");\n assertNonEmptyString(options.supabase?.secret, \"supabase.secret\");\n assertNonEmptyString(options.upstash?.url, \"upstash.url\");\n assertNonEmptyString(options.upstash?.token, \"upstash.token\");\n\n this.chatId = options.chatId;\n this.sessionId = options.sessionId;\n this.workspacePath = options.workspacePath;\n this.source = options.source;\n this.step = options.step;\n\n if (options.unsplash?.url && options.unsplash?.accessKey) {\n initUnsplash({\n url: options.unsplash.url,\n accessKey: options.unsplash.accessKey,\n });\n }\n\n if (options.gemini?.apiKey) {\n this.aiClient = getClient(\n \"gemini\",\n options.gemini.apiKey,\n options.gemini.model,\n ) as AiClient;\n }\n\n this.statusRepo = new GenStatusRepository(\n options.supabase.endpoint,\n options.supabase.secret,\n );\n this.ctxRepo = new ContextRepository(\n options.supabase.endpoint,\n options.supabase.secret,\n );\n this.redisStatusPublisher = new SendStatusToRedis(\n options.upstash.url,\n options.upstash.token,\n );\n initializeToolCallsRepository(\n options.supabase.endpoint,\n options.supabase.secret,\n options.sessionId,\n );\n\n console.log(\n `QwintlyCore initialized (chatId=${this.chatId}, sessionId=${this.sessionId})`,\n );\n }\n\n public async runAiFlow(\n initialContents: any[],\n tools: Tool[],\n handlers: Record<string, ToolHandler>,\n maxSteps: number,\n terminalToolNames: string[],\n ): Promise<ToolLoopResult> {\n if (!this.aiClient) {\n throw new Error(\n \"AI client not initialized. Please provide 'gemini' config to use runAiFlow.\",\n );\n }\n const toolLoopOptions: RunToolLoopOptions = {\n initialContents: initialContents,\n tools: tools,\n handlers: handlers,\n maxSteps: maxSteps,\n terminalToolNames: terminalToolNames,\n aiCall: (request, options) =>\n this.aiClient!.aiResponse(request, {\n tools: options.tools,\n toolCallingMode: options.toolCallingMode,\n }),\n logger: this.streamLog.bind(this),\n };\n\n const result = await runToolLoop(toolLoopOptions);\n return result;\n }\n\n public async streamLog(\n message: string,\n eventType: EventType,\n displayedSummary: boolean = false,\n ): Promise<void> {\n try {\n assertNonEmptyString(message, \"message\");\n await statusService(\n this.chatId,\n this.sessionId,\n eventType,\n this.step,\n message,\n this.source,\n {\n repository: {\n persist: this.statusRepo.persistStatusMessage.bind(this.statusRepo),\n },\n publisher: {\n publish: this.redisStatusPublisher.sendStatusToRedis.bind(\n this.redisStatusPublisher,\n ),\n },\n },\n displayedSummary,\n );\n } catch (error) {\n console.error(error);\n }\n }\n\n public async buildProjectInfoIdx(): Promise<ProjectInfo> {\n const projectInfo = await computeProjectInfo(this.workspacePath);\n\n await this.ctxRepo.updateProjectInfo(this.chatId, projectInfo);\n\n return projectInfo;\n }\n\n private async buildIndex<T>(\n builder: (path: string) => Promise<T>,\n ): Promise<T> {\n return builder(this.workspacePath);\n }\n\n public async buildPlannerIdx(): Promise<PlannerIndex> {\n return this.buildIndex(buildPlannerIndex);\n }\n\n public async buildCodegenIdx(): Promise<CodegenIndex> {\n return this.buildIndex(buildCodegenIndex);\n }\n\n public async buildValidatorIdx(): Promise<ValidatorIndex> {\n return this.buildIndex(buildValidatorIndex);\n }\n}\n"]}
@@ -0,0 +1,5 @@
1
+ import { DBRepository } from "./repository.js";
2
+ export declare class GenToolCallsRepository extends DBRepository {
3
+ persistToolCall(sessionId: string, toolName: string, toolParams: any, toolOutput: any): Promise<void>;
4
+ }
5
+ //# sourceMappingURL=genToolCalls.repository.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"genToolCalls.repository.d.ts","sourceRoot":"","sources":["../../src/repository/genToolCalls.repository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,qBAAa,sBAAuB,SAAQ,YAAY;IAChD,eAAe,CACnB,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,EAChB,UAAU,EAAE,GAAG,EACf,UAAU,EAAE,GAAG,GACd,OAAO,CAAC,IAAI,CAAC;CAWjB"}
@@ -0,0 +1,15 @@
1
+ import { DBRepository } from "./repository.js";
2
+ export class GenToolCallsRepository extends DBRepository {
3
+ async persistToolCall(sessionId, toolName, toolParams, toolOutput) {
4
+ const { error } = await this.client.from("gen_tool_calls").insert({
5
+ gen_id: sessionId,
6
+ tool_call_name: toolName,
7
+ tool_params: toolParams,
8
+ tool_final_output: toolOutput,
9
+ });
10
+ if (error) {
11
+ throw new Error(`Failed calling persist_tool_call RPC: ${error.message}`);
12
+ }
13
+ }
14
+ }
15
+ //# sourceMappingURL=genToolCalls.repository.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"genToolCalls.repository.js","sourceRoot":"","sources":["../../src/repository/genToolCalls.repository.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,MAAM,OAAO,sBAAuB,SAAQ,YAAY;IACtD,KAAK,CAAC,eAAe,CACnB,SAAiB,EACjB,QAAgB,EAChB,UAAe,EACf,UAAe;QAEf,MAAM,EAAE,KAAK,EAAE,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,gBAAgB,CAAC,CAAC,MAAM,CAAC;YAChE,MAAM,EAAE,SAAS;YACjB,cAAc,EAAE,QAAQ;YACxB,WAAW,EAAE,UAAU;YACvB,iBAAiB,EAAE,UAAU;SAC9B,CAAC,CAAC;QACH,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,IAAI,KAAK,CAAC,yCAAyC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;QAC5E,CAAC;IACH,CAAC;CACF","sourcesContent":["import { DBRepository } from \"./repository.js\";\r\n\r\nexport class GenToolCallsRepository extends DBRepository {\r\n async persistToolCall(\r\n sessionId: string,\r\n toolName: string,\r\n toolParams: any,\r\n toolOutput: any,\r\n ): Promise<void> {\r\n const { error } = await this.client.from(\"gen_tool_calls\").insert({\r\n gen_id: sessionId,\r\n tool_call_name: toolName,\r\n tool_params: toolParams,\r\n tool_final_output: toolOutput,\r\n });\r\n if (error) {\r\n throw new Error(`Failed calling persist_tool_call RPC: ${error.message}`);\r\n }\r\n }\r\n}\r\n"]}
@@ -0,0 +1,3 @@
1
+ export declare const initializeToolCallsRepository: (endpoint: string, secret: string, session: string) => void;
2
+ export declare const persistToolCall: (toolName: string, toolParams: any, toolOutput: any) => Promise<void>;
3
+ //# sourceMappingURL=toolcallPersist.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toolcallPersist.service.d.ts","sourceRoot":"","sources":["../../src/services/toolcallPersist.service.ts"],"names":[],"mappings":"AAIA,eAAO,MAAM,6BAA6B,GACxC,UAAU,MAAM,EAChB,QAAQ,MAAM,EACd,SAAS,MAAM,SAIhB,CAAC;AAEF,eAAO,MAAM,eAAe,GAC1B,UAAU,MAAM,EAChB,YAAY,GAAG,EACf,YAAY,GAAG,kBAahB,CAAC"}
@@ -0,0 +1,15 @@
1
+ import { GenToolCallsRepository } from "../repository/genToolCalls.repository.js";
2
+ let toolCallsRepository = null;
3
+ let sessionId = "";
4
+ export const initializeToolCallsRepository = (endpoint, secret, session) => {
5
+ toolCallsRepository = new GenToolCallsRepository(endpoint, secret);
6
+ sessionId = session;
7
+ };
8
+ export const persistToolCall = async (toolName, toolParams, toolOutput) => {
9
+ if (!toolCallsRepository || !sessionId) {
10
+ console.error("ToolCall repo not initialized");
11
+ return;
12
+ }
13
+ await toolCallsRepository.persistToolCall(sessionId, toolName, toolParams, toolOutput);
14
+ };
15
+ //# sourceMappingURL=toolcallPersist.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"toolcallPersist.service.js","sourceRoot":"","sources":["../../src/services/toolcallPersist.service.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,sBAAsB,EAAE,MAAM,0CAA0C,CAAC;AAElF,IAAI,mBAAmB,GAAkC,IAAI,CAAC;AAC9D,IAAI,SAAS,GAAG,EAAE,CAAC;AACnB,MAAM,CAAC,MAAM,6BAA6B,GAAG,CAC3C,QAAgB,EAChB,MAAc,EACd,OAAe,EACf,EAAE;IACF,mBAAmB,GAAG,IAAI,sBAAsB,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACnE,SAAS,GAAG,OAAO,CAAC;AACtB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,KAAK,EAClC,QAAgB,EAChB,UAAe,EACf,UAAe,EACf,EAAE;IACF,IAAI,CAAC,mBAAmB,IAAI,CAAC,SAAS,EAAE,CAAC;QACvC,OAAO,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAC;QAC/C,OAAO;IACT,CAAC;IAED,MAAM,mBAAmB,CAAC,eAAe,CACvC,SAAS,EACT,QAAQ,EACR,UAAU,EACV,UAAU,CACX,CAAC;AACJ,CAAC,CAAC","sourcesContent":["import { GenToolCallsRepository } from \"../repository/genToolCalls.repository.js\";\r\n\r\nlet toolCallsRepository: GenToolCallsRepository | null = null;\r\nlet sessionId = \"\";\r\nexport const initializeToolCallsRepository = (\r\n endpoint: string,\r\n secret: string,\r\n session: string,\r\n) => {\r\n toolCallsRepository = new GenToolCallsRepository(endpoint, secret);\r\n sessionId = session;\r\n};\r\n\r\nexport const persistToolCall = async (\r\n toolName: string,\r\n toolParams: any,\r\n toolOutput: any,\r\n) => {\r\n if (!toolCallsRepository || !sessionId) {\r\n console.error(\"ToolCall repo not initialized\");\r\n return;\r\n }\r\n\r\n await toolCallsRepository.persistToolCall(\r\n sessionId,\r\n toolName,\r\n toolParams,\r\n toolOutput,\r\n );\r\n};\r\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vedangiitb/qwintly-core",
3
- "version": "1.3.4",
3
+ "version": "1.3.5",
4
4
  "description": "Qwintly Core",
5
5
  "homepage": "https://github.com/vedangiitb/qwintly-core#readme",
6
6
  "bugs": {