@code-yeongyu/senpi 2026.7.16 → 2026.7.17-3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (176) hide show
  1. package/CHANGELOG.md +81 -0
  2. package/dist/core/dynamic-prompt/build.d.ts +7 -0
  3. package/dist/core/dynamic-prompt/build.d.ts.map +1 -1
  4. package/dist/core/dynamic-prompt/build.js +5 -0
  5. package/dist/core/dynamic-prompt/build.js.map +1 -1
  6. package/dist/core/dynamic-prompt/workstation.d.ts +35 -0
  7. package/dist/core/dynamic-prompt/workstation.d.ts.map +1 -0
  8. package/dist/core/dynamic-prompt/workstation.js +81 -0
  9. package/dist/core/dynamic-prompt/workstation.js.map +1 -0
  10. package/dist/core/extensions/builtin/anthropic-web-search/index.d.ts +6 -2
  11. package/dist/core/extensions/builtin/anthropic-web-search/index.d.ts.map +1 -1
  12. package/dist/core/extensions/builtin/anthropic-web-search/index.js +73 -5
  13. package/dist/core/extensions/builtin/anthropic-web-search/index.js.map +1 -1
  14. package/dist/core/extensions/builtin/goal/command-registration.d.ts +1 -0
  15. package/dist/core/extensions/builtin/goal/command-registration.d.ts.map +1 -1
  16. package/dist/core/extensions/builtin/goal/command-registration.js +4 -5
  17. package/dist/core/extensions/builtin/goal/command-registration.js.map +1 -1
  18. package/dist/core/extensions/builtin/goal/elapsed-ticker.d.ts +43 -0
  19. package/dist/core/extensions/builtin/goal/elapsed-ticker.d.ts.map +1 -0
  20. package/dist/core/extensions/builtin/goal/elapsed-ticker.js +58 -0
  21. package/dist/core/extensions/builtin/goal/elapsed-ticker.js.map +1 -0
  22. package/dist/core/extensions/builtin/goal/index.d.ts.map +1 -1
  23. package/dist/core/extensions/builtin/goal/index.js +39 -14
  24. package/dist/core/extensions/builtin/goal/index.js.map +1 -1
  25. package/dist/core/extensions/builtin/goal/tool-registration.d.ts +1 -0
  26. package/dist/core/extensions/builtin/goal/tool-registration.d.ts.map +1 -1
  27. package/dist/core/extensions/builtin/goal/tool-registration.js +3 -4
  28. package/dist/core/extensions/builtin/goal/tool-registration.js.map +1 -1
  29. package/dist/core/extensions/builtin/goal/ui.d.ts +2 -2
  30. package/dist/core/extensions/builtin/goal/ui.d.ts.map +1 -1
  31. package/dist/core/extensions/builtin/goal/ui.js +8 -4
  32. package/dist/core/extensions/builtin/goal/ui.js.map +1 -1
  33. package/dist/core/extensions/builtin/mcp/expose/native-search.d.ts +1 -1
  34. package/dist/core/extensions/builtin/mcp/expose/native-search.d.ts.map +1 -1
  35. package/dist/core/extensions/builtin/mcp/expose/native-search.js +1 -1
  36. package/dist/core/extensions/builtin/mcp/expose/native-search.js.map +1 -1
  37. package/dist/core/extensions/builtin/mcp/expose/policy.js +1 -1
  38. package/dist/core/extensions/builtin/mcp/expose/policy.js.map +1 -1
  39. package/dist/core/extensions/builtin/mcp/expose/status.js +1 -1
  40. package/dist/core/extensions/builtin/mcp/expose/status.js.map +1 -1
  41. package/dist/core/extensions/builtin/mcp/expose/tier-b.d.ts +3 -3
  42. package/dist/core/extensions/builtin/mcp/expose/tier-b.d.ts.map +1 -1
  43. package/dist/core/extensions/builtin/mcp/expose/tier-b.js +10 -10
  44. package/dist/core/extensions/builtin/mcp/expose/tier-b.js.map +1 -1
  45. package/dist/core/extensions/builtin/mcp/expose/tool-search.d.ts +3 -3
  46. package/dist/core/extensions/builtin/mcp/expose/tool-search.d.ts.map +1 -1
  47. package/dist/core/extensions/builtin/mcp/expose/tool-search.js +14 -14
  48. package/dist/core/extensions/builtin/mcp/expose/tool-search.js.map +1 -1
  49. package/dist/core/extensions/builtin/mcp/index.js +5 -5
  50. package/dist/core/extensions/builtin/mcp/index.js.map +1 -1
  51. package/dist/core/extensions/builtin/mcp/service.d.ts +2 -2
  52. package/dist/core/extensions/builtin/mcp/service.d.ts.map +1 -1
  53. package/dist/core/extensions/builtin/mcp/service.js +2 -2
  54. package/dist/core/extensions/builtin/mcp/service.js.map +1 -1
  55. package/dist/core/extensions/builtin/prompt-preset/claude-fable-5.d.ts.map +1 -1
  56. package/dist/core/extensions/builtin/prompt-preset/claude-fable-5.js +5 -1
  57. package/dist/core/extensions/builtin/prompt-preset/claude-fable-5.js.map +1 -1
  58. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-5.d.ts.map +1 -1
  59. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-5.js +5 -1
  60. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-5.js.map +1 -1
  61. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-6.d.ts.map +1 -1
  62. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-6.js +5 -1
  63. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-6.js.map +1 -1
  64. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-7.d.ts.map +1 -1
  65. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-7.js +5 -1
  66. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-7.js.map +1 -1
  67. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-8.d.ts.map +1 -1
  68. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-8.js +5 -1
  69. package/dist/core/extensions/builtin/prompt-preset/claude-opus-4-8.js.map +1 -1
  70. package/dist/core/extensions/builtin/prompt-preset/glm-5-2.js +1 -1
  71. package/dist/core/extensions/builtin/prompt-preset/glm-5-2.js.map +1 -1
  72. package/dist/core/extensions/builtin/prompt-preset/gpt-5.2.js +1 -1
  73. package/dist/core/extensions/builtin/prompt-preset/gpt-5.2.js.map +1 -1
  74. package/dist/core/extensions/builtin/prompt-preset/gpt-5.3-codex.js +1 -1
  75. package/dist/core/extensions/builtin/prompt-preset/gpt-5.3-codex.js.map +1 -1
  76. package/dist/core/extensions/builtin/prompt-preset/gpt-5.4.js +1 -1
  77. package/dist/core/extensions/builtin/prompt-preset/gpt-5.4.js.map +1 -1
  78. package/dist/core/extensions/builtin/prompt-preset/gpt-5.5.js +1 -1
  79. package/dist/core/extensions/builtin/prompt-preset/gpt-5.5.js.map +1 -1
  80. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.js +1 -1
  81. package/dist/core/extensions/builtin/prompt-preset/gpt-5.6.js.map +1 -1
  82. package/dist/core/extensions/builtin/prompt-preset/gpt-5.js +1 -1
  83. package/dist/core/extensions/builtin/prompt-preset/gpt-5.js.map +1 -1
  84. package/dist/core/extensions/builtin/prompt-preset/kimi-k2-6.js +1 -1
  85. package/dist/core/extensions/builtin/prompt-preset/kimi-k2-6.js.map +1 -1
  86. package/dist/core/extensions/builtin/prompt-preset/kimi-k2-7.js +1 -1
  87. package/dist/core/extensions/builtin/prompt-preset/kimi-k2-7.js.map +1 -1
  88. package/dist/core/extensions/builtin/prompt-preset/kimi-k3.d.ts +3 -0
  89. package/dist/core/extensions/builtin/prompt-preset/kimi-k3.d.ts.map +1 -0
  90. package/dist/core/extensions/builtin/prompt-preset/kimi-k3.js +14 -0
  91. package/dist/core/extensions/builtin/prompt-preset/kimi-k3.js.map +1 -0
  92. package/dist/core/extensions/builtin/prompt-preset/presets.d.ts.map +1 -1
  93. package/dist/core/extensions/builtin/prompt-preset/presets.js +13 -0
  94. package/dist/core/extensions/builtin/prompt-preset/presets.js.map +1 -1
  95. package/dist/core/extensions/builtin/prompt-preset/settings.d.ts +1 -1
  96. package/dist/core/extensions/builtin/prompt-preset/settings.d.ts.map +1 -1
  97. package/dist/core/extensions/builtin/prompt-preset/settings.js +1 -0
  98. package/dist/core/extensions/builtin/prompt-preset/settings.js.map +1 -1
  99. package/dist/core/extensions/builtin/webfetch/webfetch/renderers.d.ts.map +1 -1
  100. package/dist/core/extensions/builtin/webfetch/webfetch/renderers.js +2 -1
  101. package/dist/core/extensions/builtin/webfetch/webfetch/renderers.js.map +1 -1
  102. package/dist/core/extensions/builtin/webfetch/webfetch/tool.d.ts +27 -0
  103. package/dist/core/extensions/builtin/webfetch/webfetch/tool.d.ts.map +1 -1
  104. package/dist/core/extensions/builtin/webfetch/webfetch/tool.js +60 -1
  105. package/dist/core/extensions/builtin/webfetch/webfetch/tool.js.map +1 -1
  106. package/dist/core/extensions/types.d.ts +5 -0
  107. package/dist/core/extensions/types.d.ts.map +1 -1
  108. package/dist/core/extensions/types.js.map +1 -1
  109. package/dist/core/model-config.d.ts +5 -0
  110. package/dist/core/model-config.d.ts.map +1 -1
  111. package/dist/core/model-config.js +1 -0
  112. package/dist/core/model-config.js.map +1 -1
  113. package/dist/modes/interactive/components/tool-execution-renderer.d.ts.map +1 -1
  114. package/dist/modes/interactive/components/tool-execution-renderer.js +1 -0
  115. package/dist/modes/interactive/components/tool-execution-renderer.js.map +1 -1
  116. package/docs/AGENTS.md +70 -0
  117. package/docs/mcp.md +5 -5
  118. package/docs/settings.md +1 -1
  119. package/examples/AGENTS.md +3 -0
  120. package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
  121. package/examples/extensions/custom-provider-anthropic/package.json +1 -1
  122. package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
  123. package/examples/extensions/gondolin/package-lock.json +2 -2
  124. package/examples/extensions/gondolin/package.json +1 -1
  125. package/examples/extensions/sandbox/package-lock.json +2 -2
  126. package/examples/extensions/sandbox/package.json +1 -1
  127. package/examples/extensions/with-deps/package-lock.json +2 -2
  128. package/examples/extensions/with-deps/package.json +1 -1
  129. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +49 -0
  130. package/node_modules/@code-yeongyu/senpi-codemode/package.json +3 -3
  131. package/node_modules/@code-yeongyu/senpi-codemode/src/index.ts +59 -19
  132. package/node_modules/@code-yeongyu/senpi-codemode/src/prompt/eval-prompt.ts +68 -2
  133. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-tool.ts +6 -0
  134. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/render.ts +6 -0
  135. package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
  136. package/node_modules/@earendil-works/pi-ai/README.md +1 -1
  137. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.d.ts.map +1 -1
  138. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js +58 -7
  139. package/node_modules/@earendil-works/pi-ai/dist/api/anthropic-messages.js.map +1 -1
  140. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.d.ts +2 -1
  141. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.d.ts.map +1 -1
  142. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js +25 -1
  143. package/node_modules/@earendil-works/pi-ai/dist/api/openai-completions.js.map +1 -1
  144. package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts +70 -131
  145. package/node_modules/@earendil-works/pi-ai/dist/models.generated.d.ts.map +1 -1
  146. package/node_modules/@earendil-works/pi-ai/dist/providers/kimi-coding.models.d.ts +26 -0
  147. package/node_modules/@earendil-works/pi-ai/dist/providers/kimi-coding.models.d.ts.map +1 -1
  148. package/node_modules/@earendil-works/pi-ai/dist/providers/kimi-coding.models.js +6 -0
  149. package/node_modules/@earendil-works/pi-ai/dist/providers/kimi-coding.models.js.map +1 -1
  150. package/node_modules/@earendil-works/pi-ai/dist/providers/moonshotai-cn.models.js +3 -3
  151. package/node_modules/@earendil-works/pi-ai/dist/providers/moonshotai-cn.models.js.map +1 -1
  152. package/node_modules/@earendil-works/pi-ai/dist/providers/moonshotai.models.js +3 -3
  153. package/node_modules/@earendil-works/pi-ai/dist/providers/moonshotai.models.js.map +1 -1
  154. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode-go.models.d.ts +44 -0
  155. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode-go.models.d.ts.map +1 -1
  156. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode-go.models.js +36 -0
  157. package/node_modules/@earendil-works/pi-ai/dist/providers/opencode-go.models.js.map +1 -1
  158. package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.d.ts +0 -21
  159. package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.d.ts.map +1 -1
  160. package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.js +20 -38
  161. package/node_modules/@earendil-works/pi-ai/dist/providers/openrouter.models.js.map +1 -1
  162. package/node_modules/@earendil-works/pi-ai/dist/providers/xai.models.d.ts +0 -110
  163. package/node_modules/@earendil-works/pi-ai/dist/providers/xai.models.d.ts.map +1 -1
  164. package/node_modules/@earendil-works/pi-ai/dist/providers/xai.models.js +0 -90
  165. package/node_modules/@earendil-works/pi-ai/dist/providers/xai.models.js.map +1 -1
  166. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts +14 -0
  167. package/node_modules/@earendil-works/pi-ai/dist/types.d.ts.map +1 -1
  168. package/node_modules/@earendil-works/pi-ai/dist/types.js.map +1 -1
  169. package/node_modules/@earendil-works/pi-ai/dist/utils/tool-schema-compat.d.ts +19 -0
  170. package/node_modules/@earendil-works/pi-ai/dist/utils/tool-schema-compat.d.ts.map +1 -0
  171. package/node_modules/@earendil-works/pi-ai/dist/utils/tool-schema-compat.js +171 -0
  172. package/node_modules/@earendil-works/pi-ai/dist/utils/tool-schema-compat.js.map +1 -0
  173. package/node_modules/@earendil-works/pi-ai/package.json +1 -1
  174. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  175. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  176. package/package.json +6 -6
@@ -1 +1 @@
1
- {"version":3,"file":"kimi-k2-7.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/prompt-preset/kimi-k2-7.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwC,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAElH,SAAS,kBAAkB;IAC1B,OAAO;;yRAEiR,CAAC;AAC1R,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,OAAwC;IAC1E,OAAO,wBAAwB,CAAC,EAAE,GAAG,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,EAAE,CAAC,CAAC;AACtF,CAAC","sourcesContent":["import { type BuildDynamicSystemPromptOptions, buildDynamicSystemPrompt } from \"../../../dynamic-prompt/build.ts\";\n\nfunction buildKimiK27Tuning(): string {\n\treturn `You are running on Kimi K2.7 - restrained and outcome-first. Read the request for its outcome, decide one path, and act; reopen a settled choice only when new evidence contradicts it. Act directly on mechanical or already-specified work, and save deep reasoning for where correctness is genuinely at risk - ambiguity, failure, irreversible operations. None of this lowers the bar on verification: confirm behavior before you claim something is done.\n\nThe intent gate routing line is required every turn. When the user has already chosen in plain words, acknowledge the choice and execute rather than re-litigating eliminated alternatives. Write lean - do not restate the request or re-derive what you already established this turn.`;\n}\n\nexport function buildKimiK27Prompt(options: BuildDynamicSystemPromptOptions): string {\n\treturn buildDynamicSystemPrompt({ ...options, tuningSection: buildKimiK27Tuning() });\n}\n"]}
1
+ {"version":3,"file":"kimi-k2-7.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/prompt-preset/kimi-k2-7.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwC,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAElH,SAAS,kBAAkB;IAC1B,OAAO;;yRAEiR,CAAC;AAC1R,CAAC;AAED,MAAM,UAAU,kBAAkB,CAAC,OAAwC;IAC1E,OAAO,wBAAwB,CAAC,EAAE,GAAG,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,EAAE,kBAAkB,EAAE,MAAM,EAAE,CAAC,CAAC;AAClH,CAAC","sourcesContent":["import { type BuildDynamicSystemPromptOptions, buildDynamicSystemPrompt } from \"../../../dynamic-prompt/build.ts\";\n\nfunction buildKimiK27Tuning(): string {\n\treturn `You are running on Kimi K2.7 - restrained and outcome-first. Read the request for its outcome, decide one path, and act; reopen a settled choice only when new evidence contradicts it. Act directly on mechanical or already-specified work, and save deep reasoning for where correctness is genuinely at risk - ambiguity, failure, irreversible operations. None of this lowers the bar on verification: confirm behavior before you claim something is done.\n\nThe intent gate routing line is required every turn. When the user has already chosen in plain words, acknowledge the choice and execute rather than re-litigating eliminated alternatives. Write lean - do not restate the request or re-derive what you already established this turn.`;\n}\n\nexport function buildKimiK27Prompt(options: BuildDynamicSystemPromptOptions): string {\n\treturn buildDynamicSystemPrompt({ ...options, tuningSection: buildKimiK27Tuning(), workstationDialect: \"kimi\" });\n}\n"]}
@@ -0,0 +1,3 @@
1
+ import { type BuildDynamicSystemPromptOptions } from "../../../dynamic-prompt/build.ts";
2
+ export declare function buildKimiK3Prompt(options: BuildDynamicSystemPromptOptions): string;
3
+ //# sourceMappingURL=kimi-k3.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kimi-k3.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/prompt-preset/kimi-k3.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,+BAA+B,EAA4B,MAAM,kCAAkC,CAAC;AAYlH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,+BAA+B,GAAG,MAAM,CAElF"}
@@ -0,0 +1,14 @@
1
+ import { buildDynamicSystemPrompt } from "../../../dynamic-prompt/build.js";
2
+ function buildKimiK3Tuning() {
3
+ return `You are running on Kimi K3 - decisive and evidence-first. Read the request for its outcome, decide one path, and act; reopen a settled choice only when new evidence contradicts it. Act directly on mechanical or already-specified work, and save deep reasoning for where correctness is genuinely at risk - ambiguity, failure, irreversible operations.
4
+
5
+ Do not restate the user's request, do not re-derive facts you already established this turn, and skip filler verification language ("let me confirm again", "to be sure", "just to double-check"). When weighing a choice for the user, give a recommendation, not a survey.
6
+
7
+ The intent gate routing line is required every turn. On confirmation turns where the user already chose an option in plain words, acknowledge that choice and execute, not re-litigate alternatives the user already eliminated.
8
+
9
+ Do not stop for context limits; the harness auto-compacts. Keep working until the task is complete.`;
10
+ }
11
+ export function buildKimiK3Prompt(options) {
12
+ return buildDynamicSystemPrompt({ ...options, tuningSection: buildKimiK3Tuning(), workstationDialect: "kimi" });
13
+ }
14
+ //# sourceMappingURL=kimi-k3.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kimi-k3.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/prompt-preset/kimi-k3.ts"],"names":[],"mappings":"AAAA,OAAO,EAAwC,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAElH,SAAS,iBAAiB;IACzB,OAAO;;;;;;oGAM4F,CAAC;AACrG,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,OAAwC;IACzE,OAAO,wBAAwB,CAAC,EAAE,GAAG,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,EAAE,kBAAkB,EAAE,MAAM,EAAE,CAAC,CAAC;AACjH,CAAC","sourcesContent":["import { type BuildDynamicSystemPromptOptions, buildDynamicSystemPrompt } from \"../../../dynamic-prompt/build.ts\";\n\nfunction buildKimiK3Tuning(): string {\n\treturn `You are running on Kimi K3 - decisive and evidence-first. Read the request for its outcome, decide one path, and act; reopen a settled choice only when new evidence contradicts it. Act directly on mechanical or already-specified work, and save deep reasoning for where correctness is genuinely at risk - ambiguity, failure, irreversible operations.\n\nDo not restate the user's request, do not re-derive facts you already established this turn, and skip filler verification language (\"let me confirm again\", \"to be sure\", \"just to double-check\"). When weighing a choice for the user, give a recommendation, not a survey.\n\nThe intent gate routing line is required every turn. On confirmation turns where the user already chose an option in plain words, acknowledge that choice and execute, not re-litigate alternatives the user already eliminated.\n\nDo not stop for context limits; the harness auto-compacts. Keep working until the task is complete.`;\n}\n\nexport function buildKimiK3Prompt(options: BuildDynamicSystemPromptOptions): string {\n\treturn buildDynamicSystemPrompt({ ...options, tuningSection: buildKimiK3Tuning(), workstationDialect: \"kimi\" });\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"presets.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/prompt-preset/presets.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,kCAAkC,CAAC;AAexF,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,oBAAoB,EAAqB,MAAM,eAAe,CAAC;AAEpG,YAAY,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAE1D,KAAK,kBAAkB,GAAG,OAAO,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;AAC5D,KAAK,6BAA6B,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,GAAG,UAAU,CAAC,GAAG;IAC1E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,WAAW,oBAAoB;IACpC,IAAI,EAAE,kBAAkB,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;CACf;AA2ED,wBAAgB,iBAAiB,CAChC,KAAK,EAAE,6BAA6B,EACpC,QAAQ,EAAE,oBAAoB,GAC5B,kBAAkB,GAAG,SAAS,CA+BhC;AA8CD,wBAAgB,aAAa,CAC5B,KAAK,EAAE,6BAA6B,EACpC,QAAQ,EAAE,oBAAoB,EAC9B,OAAO,CAAC,EAAE,OAAO,CAAC,+BAA+B,CAAC,GAChD,oBAAoB,GAAG,SAAS,CAMlC"}
1
+ {"version":3,"file":"presets.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/prompt-preset/presets.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,KAAK,EAAE,+BAA+B,EAAE,MAAM,kCAAkC,CAAC;AAgBxF,OAAO,EAAE,KAAK,gBAAgB,EAAE,KAAK,oBAAoB,EAAqB,MAAM,eAAe,CAAC;AAEpG,YAAY,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAE1D,KAAK,kBAAkB,GAAG,OAAO,CAAC,gBAAgB,EAAE,MAAM,CAAC,CAAC;AAC5D,KAAK,6BAA6B,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,IAAI,GAAG,UAAU,CAAC,GAAG;IAC1E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,MAAM,WAAW,oBAAoB;IACpC,IAAI,EAAE,kBAAkB,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;CACf;AAoFD,wBAAgB,iBAAiB,CAChC,KAAK,EAAE,6BAA6B,EACpC,QAAQ,EAAE,oBAAoB,GAC5B,kBAAkB,GAAG,SAAS,CAkChC;AAgDD,wBAAgB,aAAa,CAC5B,KAAK,EAAE,6BAA6B,EACpC,QAAQ,EAAE,oBAAoB,EAC9B,OAAO,CAAC,EAAE,OAAO,CAAC,+BAA+B,CAAC,GAChD,oBAAoB,GAAG,SAAS,CAMlC"}
@@ -12,6 +12,7 @@ import { buildGpt56Prompt } from "./gpt-5.6.js";
12
12
  import { buildGpt5Prompt } from "./gpt-5.js";
13
13
  import { buildKimiK26Prompt } from "./kimi-k2-6.js";
14
14
  import { buildKimiK27Prompt } from "./kimi-k2-7.js";
15
+ import { buildKimiK3Prompt } from "./kimi-k3.js";
15
16
  import { parsePromptPreset } from "./settings.js";
16
17
  function normalizeModelId(modelId) {
17
18
  return modelId.toLowerCase().replace(/\s+/g, "-");
@@ -47,6 +48,13 @@ function hasKimiK27Signal(value) {
47
48
  function isKimiK27Model(model) {
48
49
  return hasKimiK27Signal(model.id) || (model.name !== undefined && hasKimiK27Signal(model.name));
49
50
  }
51
+ function hasKimiK3Signal(value) {
52
+ const normalized = normalizeModelId(value);
53
+ return normalized === "k3" || /(?:^|[/@._-])kimi-k3(?:$|[/@._:-])/.test(normalized);
54
+ }
55
+ function isKimiK3Model(model) {
56
+ return hasKimiK3Signal(model.id) || (model.name !== undefined && hasKimiK3Signal(model.name));
57
+ }
50
58
  function hasGlm52Signal(value) {
51
59
  return /(?:^|[/@._-])glm(?:[._-]|p)5(?:[._-]|p)2(?:$|[/@._:-])/.test(normalizeModelId(value));
52
60
  }
@@ -84,6 +92,9 @@ export function resolvePresetName(model, settings) {
84
92
  if (gpt5Version) {
85
93
  return gpt5Version;
86
94
  }
95
+ if (isKimiK3Model(model)) {
96
+ return "kimi-k3";
97
+ }
87
98
  if (isKimiK27Model(model)) {
88
99
  return "kimi-k2-7";
89
100
  }
@@ -118,6 +129,8 @@ function buildPreset(name, options) {
118
129
  return { name, prompt: buildGpt5Prompt(options) };
119
130
  case "glm-5.2":
120
131
  return { name, prompt: buildGlm52Prompt(options) };
132
+ case "kimi-k3":
133
+ return { name, prompt: buildKimiK3Prompt(options) };
121
134
  case "kimi-k2-7":
122
135
  return { name, prompt: buildKimiK27Prompt(options) };
123
136
  case "kimi-k2-6":
@@ -1 +1 @@
1
- {"version":3,"file":"presets.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/prompt-preset/presets.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Api, Model } from \"@earendil-works/pi-ai\";\nimport type { BuildDynamicSystemPromptOptions } from \"../../../dynamic-prompt/build.ts\";\nimport { buildClaudeFable5Prompt } from \"./claude-fable-5.ts\";\nimport { buildClaudeOpus45Prompt } from \"./claude-opus-4-5.ts\";\nimport { buildClaudeOpus46Prompt } from \"./claude-opus-4-6.ts\";\nimport { buildClaudeOpus47Prompt } from \"./claude-opus-4-7.ts\";\nimport { buildClaudeOpus48Prompt } from \"./claude-opus-4-8.ts\";\nimport { buildGlm52Prompt } from \"./glm-5-2.ts\";\nimport { buildGpt52Prompt } from \"./gpt-5.2.ts\";\nimport { buildGpt53CodexPrompt } from \"./gpt-5.3-codex.ts\";\nimport { buildGpt54Prompt } from \"./gpt-5.4.ts\";\nimport { buildGpt55Prompt } from \"./gpt-5.5.ts\";\nimport { buildGpt56Prompt } from \"./gpt-5.6.ts\";\nimport { buildGpt5Prompt } from \"./gpt-5.ts\";\nimport { buildKimiK26Prompt } from \"./kimi-k2-6.ts\";\nimport { buildKimiK27Prompt } from \"./kimi-k2-7.ts\";\nimport { type PromptPresetName, type PromptPresetSettings, parsePromptPreset } from \"./settings.ts\";\n\nexport type { PromptPresetSettings } from \"./settings.ts\";\n\ntype ResolvedPresetName = Exclude<PromptPresetName, \"auto\">;\ntype ModelWithPromptPresetMetadata = Pick<Model<Api>, \"id\" | \"provider\"> & {\n\tname?: string;\n\tpromptPreset?: string;\n};\n\nexport interface ResolvedPromptPreset {\n\tname: ResolvedPresetName;\n\tprompt: string;\n}\n\nfunction normalizeModelId(modelId: string): string {\n\treturn modelId.toLowerCase().replace(/\\s+/g, \"-\");\n}\n\ntype Gpt5Version = \"gpt-5.2\" | \"gpt-5.3-codex\" | \"gpt-5.4\" | \"gpt-5.5\" | \"gpt-5.6\";\n\nfunction extractGpt5Version(modelId: string): Gpt5Version | undefined {\n\tconst normalized = normalizeModelId(modelId);\n\tif (normalized.includes(\"gpt-5.6\")) {\n\t\treturn \"gpt-5.6\";\n\t}\n\tif (normalized.includes(\"gpt-5.5\")) {\n\t\treturn \"gpt-5.5\";\n\t}\n\tif (normalized.includes(\"gpt-5.4\")) {\n\t\treturn \"gpt-5.4\";\n\t}\n\tif (normalized.includes(\"gpt-5.3\")) {\n\t\treturn \"gpt-5.3-codex\";\n\t}\n\tif (normalized.includes(\"gpt-5.2\")) {\n\t\treturn \"gpt-5.2\";\n\t}\n\treturn undefined;\n}\n\nfunction hasKimiK26Signal(value: string): boolean {\n\treturn /(?:^|[/@._-])kimi-k2(?:[._-]|p)6(?:$|[/@._:-])/.test(normalizeModelId(value));\n}\n\nfunction isKimiK26Model(model: ModelWithPromptPresetMetadata): boolean {\n\treturn hasKimiK26Signal(model.id) || (model.name !== undefined && hasKimiK26Signal(model.name));\n}\n\nfunction hasKimiK27Signal(value: string): boolean {\n\treturn /(?:^|[/@._-])kimi-k2(?:[._-]|p)7(?:$|[/@._:-])/.test(normalizeModelId(value));\n}\n\nfunction isKimiK27Model(model: ModelWithPromptPresetMetadata): boolean {\n\treturn hasKimiK27Signal(model.id) || (model.name !== undefined && hasKimiK27Signal(model.name));\n}\n\nfunction hasGlm52Signal(value: string): boolean {\n\treturn /(?:^|[/@._-])glm(?:[._-]|p)5(?:[._-]|p)2(?:$|[/@._:-])/.test(normalizeModelId(value));\n}\n\nfunction isGlm52Model(model: ModelWithPromptPresetMetadata): boolean {\n\treturn hasGlm52Signal(model.id) || (model.name !== undefined && hasGlm52Signal(model.name));\n}\n\nfunction isClaudeFable5Model(modelId: string): boolean {\n\treturn normalizeModelId(modelId).includes(\"fable-5\");\n}\n\ntype ClaudeOpusVersion = \"claude-opus-4-8\" | \"claude-opus-4-7\" | \"claude-opus-4-6\" | \"claude-opus-4-5\";\n\nfunction extractClaudeOpusVersion(modelId: string): ClaudeOpusVersion | undefined {\n\tconst normalized = normalizeModelId(modelId);\n\tif (normalized.includes(\"opus-4-8\")) {\n\t\treturn \"claude-opus-4-8\";\n\t}\n\tif (normalized.includes(\"opus-4-7\")) {\n\t\treturn \"claude-opus-4-7\";\n\t}\n\tif (normalized.includes(\"opus-4-6\")) {\n\t\treturn \"claude-opus-4-6\";\n\t}\n\tif (normalized.includes(\"opus-4-5\") || normalized.includes(\"opus-4.5\")) {\n\t\treturn \"claude-opus-4-5\";\n\t}\n\treturn undefined;\n}\n\nexport function resolvePresetName(\n\tmodel: ModelWithPromptPresetMetadata,\n\tsettings: PromptPresetSettings,\n): ResolvedPresetName | undefined {\n\tif (settings.promptPreset !== \"auto\") {\n\t\treturn settings.promptPreset;\n\t}\n\n\tconst modelPromptPreset = parsePromptPreset(model.promptPreset);\n\tif (modelPromptPreset && modelPromptPreset !== \"auto\") {\n\t\treturn modelPromptPreset;\n\t}\n\n\tconst gpt5Version = extractGpt5Version(model.id);\n\tif (gpt5Version) {\n\t\treturn gpt5Version;\n\t}\n\tif (isKimiK27Model(model)) {\n\t\treturn \"kimi-k2-7\";\n\t}\n\tif (isKimiK26Model(model)) {\n\t\treturn \"kimi-k2-6\";\n\t}\n\tif (isClaudeFable5Model(model.id)) {\n\t\treturn \"claude-fable-5\";\n\t}\n\tconst claudeVersion = extractClaudeOpusVersion(model.id);\n\tif (claudeVersion) {\n\t\treturn claudeVersion;\n\t}\n\tif (isGlm52Model(model)) {\n\t\treturn \"glm-5.2\";\n\t}\n\treturn undefined;\n}\n\nfunction buildPreset(name: ResolvedPresetName, options: BuildDynamicSystemPromptOptions): ResolvedPromptPreset {\n\tswitch (name) {\n\t\tcase \"gpt-5.6\":\n\t\t\treturn { name, prompt: buildGpt56Prompt(options) };\n\t\tcase \"gpt-5.5\":\n\t\t\treturn { name, prompt: buildGpt55Prompt(options) };\n\t\tcase \"gpt-5.4\":\n\t\t\treturn { name, prompt: buildGpt54Prompt(options) };\n\t\tcase \"gpt-5.3-codex\":\n\t\t\treturn { name, prompt: buildGpt53CodexPrompt(options) };\n\t\tcase \"gpt-5.2\":\n\t\t\treturn { name, prompt: buildGpt52Prompt(options) };\n\t\tcase \"gpt-5\":\n\t\t\treturn { name, prompt: buildGpt5Prompt(options) };\n\t\tcase \"glm-5.2\":\n\t\t\treturn { name, prompt: buildGlm52Prompt(options) };\n\t\tcase \"kimi-k2-7\":\n\t\t\treturn { name, prompt: buildKimiK27Prompt(options) };\n\t\tcase \"kimi-k2-6\":\n\t\t\treturn { name, prompt: buildKimiK26Prompt(options) };\n\t\tcase \"claude-fable-5\":\n\t\t\treturn { name, prompt: buildClaudeFable5Prompt(options) };\n\t\tcase \"claude-opus-4-8\":\n\t\t\treturn { name, prompt: buildClaudeOpus48Prompt(options) };\n\t\tcase \"claude-opus-4-7\":\n\t\t\treturn { name, prompt: buildClaudeOpus47Prompt(options) };\n\t\tcase \"claude-opus-4-6\":\n\t\t\treturn { name, prompt: buildClaudeOpus46Prompt(options) };\n\t\tcase \"claude-opus-4-5\":\n\t\t\treturn { name, prompt: buildClaudeOpus45Prompt(options) };\n\t}\n}\n\nfunction withDefaults(options: Partial<BuildDynamicSystemPromptOptions> = {}): BuildDynamicSystemPromptOptions {\n\treturn {\n\t\tcwd: options.cwd ?? \"\",\n\t\tselectedTools: options.selectedTools ?? [],\n\t\ttoolSnippets: options.toolSnippets ?? {},\n\t\tpromptGuidelines: options.promptGuidelines ?? [],\n\t\tcontextFiles: options.contextFiles ?? [],\n\t\tskills: options.skills ?? [],\n\t};\n}\n\nexport function resolvePreset(\n\tmodel: ModelWithPromptPresetMetadata,\n\tsettings: PromptPresetSettings,\n\toptions?: Partial<BuildDynamicSystemPromptOptions>,\n): ResolvedPromptPreset | undefined {\n\tconst name = resolvePresetName(model, settings);\n\tif (!name) {\n\t\treturn undefined;\n\t}\n\treturn buildPreset(name, withDefaults(options));\n}\n"]}
1
+ {"version":3,"file":"presets.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/prompt-preset/presets.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Api, Model } from \"@earendil-works/pi-ai\";\nimport type { BuildDynamicSystemPromptOptions } from \"../../../dynamic-prompt/build.ts\";\nimport { buildClaudeFable5Prompt } from \"./claude-fable-5.ts\";\nimport { buildClaudeOpus45Prompt } from \"./claude-opus-4-5.ts\";\nimport { buildClaudeOpus46Prompt } from \"./claude-opus-4-6.ts\";\nimport { buildClaudeOpus47Prompt } from \"./claude-opus-4-7.ts\";\nimport { buildClaudeOpus48Prompt } from \"./claude-opus-4-8.ts\";\nimport { buildGlm52Prompt } from \"./glm-5-2.ts\";\nimport { buildGpt52Prompt } from \"./gpt-5.2.ts\";\nimport { buildGpt53CodexPrompt } from \"./gpt-5.3-codex.ts\";\nimport { buildGpt54Prompt } from \"./gpt-5.4.ts\";\nimport { buildGpt55Prompt } from \"./gpt-5.5.ts\";\nimport { buildGpt56Prompt } from \"./gpt-5.6.ts\";\nimport { buildGpt5Prompt } from \"./gpt-5.ts\";\nimport { buildKimiK26Prompt } from \"./kimi-k2-6.ts\";\nimport { buildKimiK27Prompt } from \"./kimi-k2-7.ts\";\nimport { buildKimiK3Prompt } from \"./kimi-k3.ts\";\nimport { type PromptPresetName, type PromptPresetSettings, parsePromptPreset } from \"./settings.ts\";\n\nexport type { PromptPresetSettings } from \"./settings.ts\";\n\ntype ResolvedPresetName = Exclude<PromptPresetName, \"auto\">;\ntype ModelWithPromptPresetMetadata = Pick<Model<Api>, \"id\" | \"provider\"> & {\n\tname?: string;\n\tpromptPreset?: string;\n};\n\nexport interface ResolvedPromptPreset {\n\tname: ResolvedPresetName;\n\tprompt: string;\n}\n\nfunction normalizeModelId(modelId: string): string {\n\treturn modelId.toLowerCase().replace(/\\s+/g, \"-\");\n}\n\ntype Gpt5Version = \"gpt-5.2\" | \"gpt-5.3-codex\" | \"gpt-5.4\" | \"gpt-5.5\" | \"gpt-5.6\";\n\nfunction extractGpt5Version(modelId: string): Gpt5Version | undefined {\n\tconst normalized = normalizeModelId(modelId);\n\tif (normalized.includes(\"gpt-5.6\")) {\n\t\treturn \"gpt-5.6\";\n\t}\n\tif (normalized.includes(\"gpt-5.5\")) {\n\t\treturn \"gpt-5.5\";\n\t}\n\tif (normalized.includes(\"gpt-5.4\")) {\n\t\treturn \"gpt-5.4\";\n\t}\n\tif (normalized.includes(\"gpt-5.3\")) {\n\t\treturn \"gpt-5.3-codex\";\n\t}\n\tif (normalized.includes(\"gpt-5.2\")) {\n\t\treturn \"gpt-5.2\";\n\t}\n\treturn undefined;\n}\n\nfunction hasKimiK26Signal(value: string): boolean {\n\treturn /(?:^|[/@._-])kimi-k2(?:[._-]|p)6(?:$|[/@._:-])/.test(normalizeModelId(value));\n}\n\nfunction isKimiK26Model(model: ModelWithPromptPresetMetadata): boolean {\n\treturn hasKimiK26Signal(model.id) || (model.name !== undefined && hasKimiK26Signal(model.name));\n}\n\nfunction hasKimiK27Signal(value: string): boolean {\n\treturn /(?:^|[/@._-])kimi-k2(?:[._-]|p)7(?:$|[/@._:-])/.test(normalizeModelId(value));\n}\n\nfunction isKimiK27Model(model: ModelWithPromptPresetMetadata): boolean {\n\treturn hasKimiK27Signal(model.id) || (model.name !== undefined && hasKimiK27Signal(model.name));\n}\n\nfunction hasKimiK3Signal(value: string): boolean {\n\tconst normalized = normalizeModelId(value);\n\treturn normalized === \"k3\" || /(?:^|[/@._-])kimi-k3(?:$|[/@._:-])/.test(normalized);\n}\n\nfunction isKimiK3Model(model: ModelWithPromptPresetMetadata): boolean {\n\treturn hasKimiK3Signal(model.id) || (model.name !== undefined && hasKimiK3Signal(model.name));\n}\n\nfunction hasGlm52Signal(value: string): boolean {\n\treturn /(?:^|[/@._-])glm(?:[._-]|p)5(?:[._-]|p)2(?:$|[/@._:-])/.test(normalizeModelId(value));\n}\n\nfunction isGlm52Model(model: ModelWithPromptPresetMetadata): boolean {\n\treturn hasGlm52Signal(model.id) || (model.name !== undefined && hasGlm52Signal(model.name));\n}\n\nfunction isClaudeFable5Model(modelId: string): boolean {\n\treturn normalizeModelId(modelId).includes(\"fable-5\");\n}\n\ntype ClaudeOpusVersion = \"claude-opus-4-8\" | \"claude-opus-4-7\" | \"claude-opus-4-6\" | \"claude-opus-4-5\";\n\nfunction extractClaudeOpusVersion(modelId: string): ClaudeOpusVersion | undefined {\n\tconst normalized = normalizeModelId(modelId);\n\tif (normalized.includes(\"opus-4-8\")) {\n\t\treturn \"claude-opus-4-8\";\n\t}\n\tif (normalized.includes(\"opus-4-7\")) {\n\t\treturn \"claude-opus-4-7\";\n\t}\n\tif (normalized.includes(\"opus-4-6\")) {\n\t\treturn \"claude-opus-4-6\";\n\t}\n\tif (normalized.includes(\"opus-4-5\") || normalized.includes(\"opus-4.5\")) {\n\t\treturn \"claude-opus-4-5\";\n\t}\n\treturn undefined;\n}\n\nexport function resolvePresetName(\n\tmodel: ModelWithPromptPresetMetadata,\n\tsettings: PromptPresetSettings,\n): ResolvedPresetName | undefined {\n\tif (settings.promptPreset !== \"auto\") {\n\t\treturn settings.promptPreset;\n\t}\n\n\tconst modelPromptPreset = parsePromptPreset(model.promptPreset);\n\tif (modelPromptPreset && modelPromptPreset !== \"auto\") {\n\t\treturn modelPromptPreset;\n\t}\n\n\tconst gpt5Version = extractGpt5Version(model.id);\n\tif (gpt5Version) {\n\t\treturn gpt5Version;\n\t}\n\tif (isKimiK3Model(model)) {\n\t\treturn \"kimi-k3\";\n\t}\n\tif (isKimiK27Model(model)) {\n\t\treturn \"kimi-k2-7\";\n\t}\n\tif (isKimiK26Model(model)) {\n\t\treturn \"kimi-k2-6\";\n\t}\n\tif (isClaudeFable5Model(model.id)) {\n\t\treturn \"claude-fable-5\";\n\t}\n\tconst claudeVersion = extractClaudeOpusVersion(model.id);\n\tif (claudeVersion) {\n\t\treturn claudeVersion;\n\t}\n\tif (isGlm52Model(model)) {\n\t\treturn \"glm-5.2\";\n\t}\n\treturn undefined;\n}\n\nfunction buildPreset(name: ResolvedPresetName, options: BuildDynamicSystemPromptOptions): ResolvedPromptPreset {\n\tswitch (name) {\n\t\tcase \"gpt-5.6\":\n\t\t\treturn { name, prompt: buildGpt56Prompt(options) };\n\t\tcase \"gpt-5.5\":\n\t\t\treturn { name, prompt: buildGpt55Prompt(options) };\n\t\tcase \"gpt-5.4\":\n\t\t\treturn { name, prompt: buildGpt54Prompt(options) };\n\t\tcase \"gpt-5.3-codex\":\n\t\t\treturn { name, prompt: buildGpt53CodexPrompt(options) };\n\t\tcase \"gpt-5.2\":\n\t\t\treturn { name, prompt: buildGpt52Prompt(options) };\n\t\tcase \"gpt-5\":\n\t\t\treturn { name, prompt: buildGpt5Prompt(options) };\n\t\tcase \"glm-5.2\":\n\t\t\treturn { name, prompt: buildGlm52Prompt(options) };\n\t\tcase \"kimi-k3\":\n\t\t\treturn { name, prompt: buildKimiK3Prompt(options) };\n\t\tcase \"kimi-k2-7\":\n\t\t\treturn { name, prompt: buildKimiK27Prompt(options) };\n\t\tcase \"kimi-k2-6\":\n\t\t\treturn { name, prompt: buildKimiK26Prompt(options) };\n\t\tcase \"claude-fable-5\":\n\t\t\treturn { name, prompt: buildClaudeFable5Prompt(options) };\n\t\tcase \"claude-opus-4-8\":\n\t\t\treturn { name, prompt: buildClaudeOpus48Prompt(options) };\n\t\tcase \"claude-opus-4-7\":\n\t\t\treturn { name, prompt: buildClaudeOpus47Prompt(options) };\n\t\tcase \"claude-opus-4-6\":\n\t\t\treturn { name, prompt: buildClaudeOpus46Prompt(options) };\n\t\tcase \"claude-opus-4-5\":\n\t\t\treturn { name, prompt: buildClaudeOpus45Prompt(options) };\n\t}\n}\n\nfunction withDefaults(options: Partial<BuildDynamicSystemPromptOptions> = {}): BuildDynamicSystemPromptOptions {\n\treturn {\n\t\tcwd: options.cwd ?? \"\",\n\t\tselectedTools: options.selectedTools ?? [],\n\t\ttoolSnippets: options.toolSnippets ?? {},\n\t\tpromptGuidelines: options.promptGuidelines ?? [],\n\t\tcontextFiles: options.contextFiles ?? [],\n\t\tskills: options.skills ?? [],\n\t};\n}\n\nexport function resolvePreset(\n\tmodel: ModelWithPromptPresetMetadata,\n\tsettings: PromptPresetSettings,\n\toptions?: Partial<BuildDynamicSystemPromptOptions>,\n): ResolvedPromptPreset | undefined {\n\tconst name = resolvePresetName(model, settings);\n\tif (!name) {\n\t\treturn undefined;\n\t}\n\treturn buildPreset(name, withDefaults(options));\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import type { SettingsManager } from "../../../settings-manager.ts";
2
- export type PromptPresetName = "auto" | "claude-fable-5" | "claude-opus-4-8" | "claude-opus-4-7" | "claude-opus-4-6" | "claude-opus-4-5" | "glm-5.2" | "kimi-k2-7" | "kimi-k2-6" | "gpt-5" | "gpt-5.2" | "gpt-5.3-codex" | "gpt-5.4" | "gpt-5.5" | "gpt-5.6";
2
+ export type PromptPresetName = "auto" | "claude-fable-5" | "claude-opus-4-8" | "claude-opus-4-7" | "claude-opus-4-6" | "claude-opus-4-5" | "glm-5.2" | "kimi-k3" | "kimi-k2-7" | "kimi-k2-6" | "gpt-5" | "gpt-5.2" | "gpt-5.3-codex" | "gpt-5.4" | "gpt-5.5" | "gpt-5.6";
3
3
  export interface PromptPresetSettings {
4
4
  promptPreset: PromptPresetName;
5
5
  }
@@ -1 +1 @@
1
- {"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/prompt-preset/settings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAY,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAE9E,MAAM,MAAM,gBAAgB,GACzB,MAAM,GACN,gBAAgB,GAChB,iBAAiB,GACjB,iBAAiB,GACjB,iBAAiB,GACjB,iBAAiB,GACjB,SAAS,GACT,WAAW,GACX,WAAW,GACX,OAAO,GACP,SAAS,GACT,eAAe,GACf,SAAS,GACT,SAAS,GACT,SAAS,CAAC;AAEb,MAAM,WAAW,oBAAoB;IACpC,YAAY,EAAE,gBAAgB,CAAC;CAC/B;AAsBD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,gBAAgB,GAAG,SAAS,CAKzF;AAED,wBAAgB,wBAAwB,CAAC,eAAe,EAAE,eAAe,GAAG,oBAAoB,CAQ/F"}
1
+ {"version":3,"file":"settings.d.ts","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/prompt-preset/settings.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAY,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAE9E,MAAM,MAAM,gBAAgB,GACzB,MAAM,GACN,gBAAgB,GAChB,iBAAiB,GACjB,iBAAiB,GACjB,iBAAiB,GACjB,iBAAiB,GACjB,SAAS,GACT,SAAS,GACT,WAAW,GACX,WAAW,GACX,OAAO,GACP,SAAS,GACT,eAAe,GACf,SAAS,GACT,SAAS,GACT,SAAS,CAAC;AAEb,MAAM,WAAW,oBAAoB;IACpC,YAAY,EAAE,gBAAgB,CAAC;CAC/B;AAuBD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,gBAAgB,GAAG,SAAS,CAKzF;AAED,wBAAgB,wBAAwB,CAAC,eAAe,EAAE,eAAe,GAAG,oBAAoB,CAQ/F"}
@@ -6,6 +6,7 @@ const VALID_PRESETS = new Set([
6
6
  "claude-opus-4-6",
7
7
  "claude-opus-4-5",
8
8
  "glm-5.2",
9
+ "kimi-k3",
9
10
  "kimi-k2-7",
10
11
  "kimi-k2-6",
11
12
  "gpt-5",
@@ -1 +1 @@
1
- {"version":3,"file":"settings.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/prompt-preset/settings.ts"],"names":[],"mappings":"AAyBA,MAAM,aAAa,GAAwB,IAAI,GAAG,CAAmB;IACpE,MAAM;IACN,gBAAgB;IAChB,iBAAiB;IACjB,iBAAiB;IACjB,iBAAiB;IACjB,iBAAiB;IACjB,SAAS;IACT,WAAW;IACX,WAAW;IACX,OAAO;IACP,SAAS;IACT,eAAe;IACf,SAAS;IACT,SAAS;IACT,SAAS;CACT,CAAC,CAAC;AAEH,MAAM,UAAU,iBAAiB,CAAC,KAAyB;IAC1D,IAAI,KAAK,IAAI,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QACvC,OAAO,KAAyB,CAAC;IAClC,CAAC;IACD,OAAO,SAAS,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,eAAgC;IACxE,MAAM,cAAc,GAAG,eAAe,CAAC,iBAAiB,EAA8B,CAAC;IACvF,MAAM,eAAe,GAAG,eAAe,CAAC,kBAAkB,EAA8B,CAAC;IAEzF,OAAO;QACN,YAAY,EACX,iBAAiB,CAAC,eAAe,CAAC,YAAY,CAAC,IAAI,iBAAiB,CAAC,cAAc,CAAC,YAAY,CAAC,IAAI,MAAM;KAC5G,CAAC;AACH,CAAC","sourcesContent":["import type { Settings, SettingsManager } from \"../../../settings-manager.ts\";\n\nexport type PromptPresetName =\n\t| \"auto\"\n\t| \"claude-fable-5\"\n\t| \"claude-opus-4-8\"\n\t| \"claude-opus-4-7\"\n\t| \"claude-opus-4-6\"\n\t| \"claude-opus-4-5\"\n\t| \"glm-5.2\"\n\t| \"kimi-k2-7\"\n\t| \"kimi-k2-6\"\n\t| \"gpt-5\"\n\t| \"gpt-5.2\"\n\t| \"gpt-5.3-codex\"\n\t| \"gpt-5.4\"\n\t| \"gpt-5.5\"\n\t| \"gpt-5.6\";\n\nexport interface PromptPresetSettings {\n\tpromptPreset: PromptPresetName;\n}\n\ntype SettingsWithPromptPreset = Settings & { promptPreset?: string };\n\nconst VALID_PRESETS: ReadonlySet<string> = new Set<PromptPresetName>([\n\t\"auto\",\n\t\"claude-fable-5\",\n\t\"claude-opus-4-8\",\n\t\"claude-opus-4-7\",\n\t\"claude-opus-4-6\",\n\t\"claude-opus-4-5\",\n\t\"glm-5.2\",\n\t\"kimi-k2-7\",\n\t\"kimi-k2-6\",\n\t\"gpt-5\",\n\t\"gpt-5.2\",\n\t\"gpt-5.3-codex\",\n\t\"gpt-5.4\",\n\t\"gpt-5.5\",\n\t\"gpt-5.6\",\n]);\n\nexport function parsePromptPreset(value: string | undefined): PromptPresetName | undefined {\n\tif (value && VALID_PRESETS.has(value)) {\n\t\treturn value as PromptPresetName;\n\t}\n\treturn undefined;\n}\n\nexport function loadPromptPresetSettings(settingsManager: SettingsManager): PromptPresetSettings {\n\tconst globalSettings = settingsManager.getGlobalSettings() as SettingsWithPromptPreset;\n\tconst projectSettings = settingsManager.getProjectSettings() as SettingsWithPromptPreset;\n\n\treturn {\n\t\tpromptPreset:\n\t\t\tparsePromptPreset(projectSettings.promptPreset) ?? parsePromptPreset(globalSettings.promptPreset) ?? \"auto\",\n\t};\n}\n"]}
1
+ {"version":3,"file":"settings.js","sourceRoot":"","sources":["../../../../../src/core/extensions/builtin/prompt-preset/settings.ts"],"names":[],"mappings":"AA0BA,MAAM,aAAa,GAAwB,IAAI,GAAG,CAAmB;IACpE,MAAM;IACN,gBAAgB;IAChB,iBAAiB;IACjB,iBAAiB;IACjB,iBAAiB;IACjB,iBAAiB;IACjB,SAAS;IACT,SAAS;IACT,WAAW;IACX,WAAW;IACX,OAAO;IACP,SAAS;IACT,eAAe;IACf,SAAS;IACT,SAAS;IACT,SAAS;CACT,CAAC,CAAC;AAEH,MAAM,UAAU,iBAAiB,CAAC,KAAyB;IAC1D,IAAI,KAAK,IAAI,aAAa,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;QACvC,OAAO,KAAyB,CAAC;IAClC,CAAC;IACD,OAAO,SAAS,CAAC;AAClB,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,eAAgC;IACxE,MAAM,cAAc,GAAG,eAAe,CAAC,iBAAiB,EAA8B,CAAC;IACvF,MAAM,eAAe,GAAG,eAAe,CAAC,kBAAkB,EAA8B,CAAC;IAEzF,OAAO;QACN,YAAY,EACX,iBAAiB,CAAC,eAAe,CAAC,YAAY,CAAC,IAAI,iBAAiB,CAAC,cAAc,CAAC,YAAY,CAAC,IAAI,MAAM;KAC5G,CAAC;AACH,CAAC","sourcesContent":["import type { Settings, SettingsManager } from \"../../../settings-manager.ts\";\n\nexport type PromptPresetName =\n\t| \"auto\"\n\t| \"claude-fable-5\"\n\t| \"claude-opus-4-8\"\n\t| \"claude-opus-4-7\"\n\t| \"claude-opus-4-6\"\n\t| \"claude-opus-4-5\"\n\t| \"glm-5.2\"\n\t| \"kimi-k3\"\n\t| \"kimi-k2-7\"\n\t| \"kimi-k2-6\"\n\t| \"gpt-5\"\n\t| \"gpt-5.2\"\n\t| \"gpt-5.3-codex\"\n\t| \"gpt-5.4\"\n\t| \"gpt-5.5\"\n\t| \"gpt-5.6\";\n\nexport interface PromptPresetSettings {\n\tpromptPreset: PromptPresetName;\n}\n\ntype SettingsWithPromptPreset = Settings & { promptPreset?: string };\n\nconst VALID_PRESETS: ReadonlySet<string> = new Set<PromptPresetName>([\n\t\"auto\",\n\t\"claude-fable-5\",\n\t\"claude-opus-4-8\",\n\t\"claude-opus-4-7\",\n\t\"claude-opus-4-6\",\n\t\"claude-opus-4-5\",\n\t\"glm-5.2\",\n\t\"kimi-k3\",\n\t\"kimi-k2-7\",\n\t\"kimi-k2-6\",\n\t\"gpt-5\",\n\t\"gpt-5.2\",\n\t\"gpt-5.3-codex\",\n\t\"gpt-5.4\",\n\t\"gpt-5.5\",\n\t\"gpt-5.6\",\n]);\n\nexport function parsePromptPreset(value: string | undefined): PromptPresetName | undefined {\n\tif (value && VALID_PRESETS.has(value)) {\n\t\treturn value as PromptPresetName;\n\t}\n\treturn undefined;\n}\n\nexport function loadPromptPresetSettings(settingsManager: SettingsManager): PromptPresetSettings {\n\tconst globalSettings = settingsManager.getGlobalSettings() as SettingsWithPromptPreset;\n\tconst projectSettings = settingsManager.getProjectSettings() as SettingsWithPromptPreset;\n\n\treturn {\n\t\tpromptPreset:\n\t\t\tparsePromptPreset(projectSettings.promptPreset) ?? parsePromptPreset(globalSettings.promptPreset) ?? \"auto\",\n\t};\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"renderers.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/webfetch/webfetch/renderers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAmB,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iDAAiD,CAAC;AAC7E,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAEjE,OAAO,KAAK,EAA4C,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAYjG,UAAU,UAAU,CAAC,QAAQ;IAC5B,OAAO,EAAE,aAAa,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxD,OAAO,CAAC,EAAE,QAAQ,CAAC;CACnB;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,CAOpE;AAED,wBAAgB,oBAAoB,CACnC,MAAM,EAAE,UAAU,CAAC,qBAAqB,CAAC,EACzC,OAAO,EAAE,uBAAuB,EAChC,KAAK,EAAE,KAAK,GACV,IAAI,CA0CN"}
1
+ {"version":3,"file":"renderers.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/webfetch/webfetch/renderers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAmB,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,iDAAiD,CAAC;AAC7E,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAEjE,OAAO,KAAK,EAA4C,qBAAqB,EAAE,MAAM,WAAW,CAAC;AAYjG,UAAU,UAAU,CAAC,QAAQ;IAC5B,OAAO,EAAE,aAAa,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxD,OAAO,CAAC,EAAE,QAAQ,CAAC;CACnB;AAED,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,CAOpE;AAED,wBAAgB,oBAAoB,CACnC,MAAM,EAAE,UAAU,CAAC,qBAAqB,CAAC,EACzC,OAAO,EAAE,uBAAuB,EAChC,KAAK,EAAE,KAAK,GACV,IAAI,CA2CN"}
@@ -28,7 +28,8 @@ export function renderWebfetchResult(result, options, theme) {
28
28
  const format = theme.fg("accent", details.format);
29
29
  const size = theme.fg("muted", formatBytes(details.bytes));
30
30
  const converted = details.converted ? theme.fg("dim", " converted") : "";
31
- const header = `${status} ${theme.fg("muted", "")} ${format} ${theme.fg("muted", "•")} ${size}${converted}`;
31
+ const truncatedNote = details.outputTruncated ? theme.fg("warning", " truncated") : "";
32
+ const header = `${status} ${theme.fg("muted", "•")} ${format} ${theme.fg("muted", "•")} ${size}${converted}${truncatedNote}`;
32
33
  if (!options.expanded) {
33
34
  const preview = previewText(text, theme);
34
35
  return new Text([header, ...preview].join("\n"), 0, 0);
@@ -1 +1 @@
1
- {"version":3,"file":"renderers.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/webfetch/webfetch/renderers.ts"],"names":[],"mappings":"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","sourcesContent":["import { Text, truncateToWidth } from \"@earendil-works/pi-tui\";\nimport type { Theme } from \"../../../../../modes/interactive/theme/theme.ts\";\nimport type { ToolRenderResultOptions } from \"../../../types.ts\";\n\nimport type { WebfetchDetails, WebfetchProgressDetails, WebfetchRenderDetails } from \"./tool.ts\";\n\nconst URL_BUDGET = 92;\nconst PREVIEW_LINES = 4;\nconst PREVIEW_WIDTH = 120;\n\ninterface WebfetchArgs {\n\turl: string;\n\tformat?: string;\n\ttimeout?: number;\n}\n\ninterface ResultLike<TDetails> {\n\tcontent: ReadonlyArray<{ type: string; text?: string }>;\n\tdetails?: TDetails;\n}\n\nexport function renderWebfetchCall(args: unknown, theme: Theme): Text {\n\tconst webfetchArgs = parseWebfetchArgs(args);\n\tconst head = theme.fg(\"toolTitle\", theme.bold(\"webfetch \"));\n\tconst url = theme.fg(\"accent\", shorten(webfetchArgs.url, URL_BUDGET));\n\tconst format = theme.fg(\"muted\", ` [${webfetchArgs.format ?? \"markdown\"}]`);\n\tconst timeout = webfetchArgs.timeout === undefined ? \"\" : theme.fg(\"dim\", ` ${webfetchArgs.timeout}s`);\n\treturn new Text(head + url + format + timeout, 0, 0);\n}\n\nexport function renderWebfetchResult(\n\tresult: ResultLike<WebfetchRenderDetails>,\n\toptions: ToolRenderResultOptions,\n\ttheme: Theme,\n): Text {\n\tif (options.isPartial) {\n\t\tconst details = result.details;\n\t\tif (isWebfetchProgressDetails(details)) {\n\t\t\treturn new Text(\n\t\t\t\ttheme.fg(\n\t\t\t\t\t\"warning\",\n\t\t\t\t\t`Fetching ${shorten(details.url, URL_BUDGET)} as ${details.format} (${details.timeoutSeconds}s)`,\n\t\t\t\t),\n\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t);\n\t\t}\n\t\treturn new Text(theme.fg(\"warning\", \"Fetching...\"), 0, 0);\n\t}\n\n\tconst details = result.details;\n\tconst text = result.content.find((block) => block.type === \"text\")?.text ?? \"\";\n\tif (!isWebfetchDetails(details)) {\n\t\treturn new Text(theme.fg(\"muted\", truncateToWidth(text, PREVIEW_WIDTH)), 0, 0);\n\t}\n\n\tconst statusKey = details.status >= 200 && details.status < 300 ? \"success\" : \"warning\";\n\tconst status = theme.fg(statusKey, `${details.status} ${details.statusText || \"OK\"}`);\n\tconst format = theme.fg(\"accent\", details.format);\n\tconst size = theme.fg(\"muted\", formatBytes(details.bytes));\n\tconst converted = details.converted ? theme.fg(\"dim\", \" converted\") : \"\";\n\tconst header = `${status} ${theme.fg(\"muted\", \"•\")} ${format} ${theme.fg(\"muted\", \"•\")} ${size}${converted}`;\n\n\tif (!options.expanded) {\n\t\tconst preview = previewText(text, theme);\n\t\treturn new Text([header, ...preview].join(\"\\n\"), 0, 0);\n\t}\n\n\tconst lines = [\n\t\theader,\n\t\ttheme.fg(\"dim\", `URL: ${shorten(details.finalUrl, URL_BUDGET)}`),\n\t\ttheme.fg(\"dim\", `Content-Type: ${details.contentType || \"unknown\"}`),\n\t\t\"\",\n\t\t...collectLines(text, 24).map((line) => theme.fg(\"toolOutput\", truncateToWidth(line, PREVIEW_WIDTH))),\n\t];\n\treturn new Text(lines.join(\"\\n\"), 0, 0);\n}\n\nfunction collectLines(text: string, limit: number): string[] {\n\tconst lines: string[] = [];\n\tlet start = 0;\n\twhile (lines.length < limit && start <= text.length) {\n\t\tconst newlineIndex = text.indexOf(\"\\n\", start);\n\t\tif (newlineIndex === -1) {\n\t\t\tlines.push(text.slice(start));\n\t\t\tbreak;\n\t\t}\n\t\tlines.push(text.slice(start, newlineIndex));\n\t\tstart = newlineIndex + 1;\n\t}\n\treturn lines;\n}\n\nfunction collectNonEmptyTrimmedLines(text: string, limit: number): string[] {\n\tconst lines: string[] = [];\n\tlet start = 0;\n\twhile (lines.length < limit && start <= text.length) {\n\t\tconst newlineIndex = text.indexOf(\"\\n\", start);\n\t\tconst line = (newlineIndex === -1 ? text.slice(start) : text.slice(start, newlineIndex)).trim();\n\t\tif (line.length > 0) lines.push(line);\n\t\tif (newlineIndex === -1) break;\n\t\tstart = newlineIndex + 1;\n\t}\n\treturn lines;\n}\n\nfunction parseWebfetchArgs(args: unknown): WebfetchArgs {\n\tif (typeof args !== \"object\" || args === null) {\n\t\treturn { url: \"\" };\n\t}\n\tconst webfetchArgs: WebfetchArgs = {\n\t\turl: \"url\" in args && typeof args.url === \"string\" ? args.url : \"\",\n\t};\n\tif (\"format\" in args && typeof args.format === \"string\") webfetchArgs.format = args.format;\n\tif (\"timeout\" in args && typeof args.timeout === \"number\") webfetchArgs.timeout = args.timeout;\n\treturn webfetchArgs;\n}\n\nfunction isWebfetchProgressDetails(details: WebfetchRenderDetails | unknown): details is WebfetchProgressDetails {\n\treturn typeof details === \"object\" && details !== null && \"phase\" in details && details.phase === \"fetching\";\n}\n\nfunction isWebfetchDetails(details: WebfetchRenderDetails | unknown): details is WebfetchDetails {\n\treturn typeof details === \"object\" && details !== null && \"status\" in details && typeof details.status === \"number\";\n}\n\nfunction previewText(text: string, theme: Theme): string[] {\n\tconst lines = collectNonEmptyTrimmedLines(text, PREVIEW_LINES);\n\tif (lines.length === 0) return [theme.fg(\"dim\", \" empty response\")];\n\treturn lines.map((line) => theme.fg(\"toolOutput\", ` ${truncateToWidth(line, PREVIEW_WIDTH)}`));\n}\n\nfunction shorten(value: string, max: number): string {\n\tif (value.length <= max) return value;\n\treturn `${value.slice(0, max - 1)}…`;\n}\n\nfunction formatBytes(bytes: number): string {\n\tif (bytes < 1024) return `${bytes} B`;\n\tif (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n\treturn `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n"]}
1
+ {"version":3,"file":"renderers.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/webfetch/webfetch/renderers.ts"],"names":[],"mappings":"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","sourcesContent":["import { Text, truncateToWidth } from \"@earendil-works/pi-tui\";\nimport type { Theme } from \"../../../../../modes/interactive/theme/theme.ts\";\nimport type { ToolRenderResultOptions } from \"../../../types.ts\";\n\nimport type { WebfetchDetails, WebfetchProgressDetails, WebfetchRenderDetails } from \"./tool.ts\";\n\nconst URL_BUDGET = 92;\nconst PREVIEW_LINES = 4;\nconst PREVIEW_WIDTH = 120;\n\ninterface WebfetchArgs {\n\turl: string;\n\tformat?: string;\n\ttimeout?: number;\n}\n\ninterface ResultLike<TDetails> {\n\tcontent: ReadonlyArray<{ type: string; text?: string }>;\n\tdetails?: TDetails;\n}\n\nexport function renderWebfetchCall(args: unknown, theme: Theme): Text {\n\tconst webfetchArgs = parseWebfetchArgs(args);\n\tconst head = theme.fg(\"toolTitle\", theme.bold(\"webfetch \"));\n\tconst url = theme.fg(\"accent\", shorten(webfetchArgs.url, URL_BUDGET));\n\tconst format = theme.fg(\"muted\", ` [${webfetchArgs.format ?? \"markdown\"}]`);\n\tconst timeout = webfetchArgs.timeout === undefined ? \"\" : theme.fg(\"dim\", ` ${webfetchArgs.timeout}s`);\n\treturn new Text(head + url + format + timeout, 0, 0);\n}\n\nexport function renderWebfetchResult(\n\tresult: ResultLike<WebfetchRenderDetails>,\n\toptions: ToolRenderResultOptions,\n\ttheme: Theme,\n): Text {\n\tif (options.isPartial) {\n\t\tconst details = result.details;\n\t\tif (isWebfetchProgressDetails(details)) {\n\t\t\treturn new Text(\n\t\t\t\ttheme.fg(\n\t\t\t\t\t\"warning\",\n\t\t\t\t\t`Fetching ${shorten(details.url, URL_BUDGET)} as ${details.format} (${details.timeoutSeconds}s)`,\n\t\t\t\t),\n\t\t\t\t0,\n\t\t\t\t0,\n\t\t\t);\n\t\t}\n\t\treturn new Text(theme.fg(\"warning\", \"Fetching...\"), 0, 0);\n\t}\n\n\tconst details = result.details;\n\tconst text = result.content.find((block) => block.type === \"text\")?.text ?? \"\";\n\tif (!isWebfetchDetails(details)) {\n\t\treturn new Text(theme.fg(\"muted\", truncateToWidth(text, PREVIEW_WIDTH)), 0, 0);\n\t}\n\n\tconst statusKey = details.status >= 200 && details.status < 300 ? \"success\" : \"warning\";\n\tconst status = theme.fg(statusKey, `${details.status} ${details.statusText || \"OK\"}`);\n\tconst format = theme.fg(\"accent\", details.format);\n\tconst size = theme.fg(\"muted\", formatBytes(details.bytes));\n\tconst converted = details.converted ? theme.fg(\"dim\", \" converted\") : \"\";\n\tconst truncatedNote = details.outputTruncated ? theme.fg(\"warning\", \" truncated\") : \"\";\n\tconst header = `${status} ${theme.fg(\"muted\", \"•\")} ${format} ${theme.fg(\"muted\", \"•\")} ${size}${converted}${truncatedNote}`;\n\n\tif (!options.expanded) {\n\t\tconst preview = previewText(text, theme);\n\t\treturn new Text([header, ...preview].join(\"\\n\"), 0, 0);\n\t}\n\n\tconst lines = [\n\t\theader,\n\t\ttheme.fg(\"dim\", `URL: ${shorten(details.finalUrl, URL_BUDGET)}`),\n\t\ttheme.fg(\"dim\", `Content-Type: ${details.contentType || \"unknown\"}`),\n\t\t\"\",\n\t\t...collectLines(text, 24).map((line) => theme.fg(\"toolOutput\", truncateToWidth(line, PREVIEW_WIDTH))),\n\t];\n\treturn new Text(lines.join(\"\\n\"), 0, 0);\n}\n\nfunction collectLines(text: string, limit: number): string[] {\n\tconst lines: string[] = [];\n\tlet start = 0;\n\twhile (lines.length < limit && start <= text.length) {\n\t\tconst newlineIndex = text.indexOf(\"\\n\", start);\n\t\tif (newlineIndex === -1) {\n\t\t\tlines.push(text.slice(start));\n\t\t\tbreak;\n\t\t}\n\t\tlines.push(text.slice(start, newlineIndex));\n\t\tstart = newlineIndex + 1;\n\t}\n\treturn lines;\n}\n\nfunction collectNonEmptyTrimmedLines(text: string, limit: number): string[] {\n\tconst lines: string[] = [];\n\tlet start = 0;\n\twhile (lines.length < limit && start <= text.length) {\n\t\tconst newlineIndex = text.indexOf(\"\\n\", start);\n\t\tconst line = (newlineIndex === -1 ? text.slice(start) : text.slice(start, newlineIndex)).trim();\n\t\tif (line.length > 0) lines.push(line);\n\t\tif (newlineIndex === -1) break;\n\t\tstart = newlineIndex + 1;\n\t}\n\treturn lines;\n}\n\nfunction parseWebfetchArgs(args: unknown): WebfetchArgs {\n\tif (typeof args !== \"object\" || args === null) {\n\t\treturn { url: \"\" };\n\t}\n\tconst webfetchArgs: WebfetchArgs = {\n\t\turl: \"url\" in args && typeof args.url === \"string\" ? args.url : \"\",\n\t};\n\tif (\"format\" in args && typeof args.format === \"string\") webfetchArgs.format = args.format;\n\tif (\"timeout\" in args && typeof args.timeout === \"number\") webfetchArgs.timeout = args.timeout;\n\treturn webfetchArgs;\n}\n\nfunction isWebfetchProgressDetails(details: WebfetchRenderDetails | unknown): details is WebfetchProgressDetails {\n\treturn typeof details === \"object\" && details !== null && \"phase\" in details && details.phase === \"fetching\";\n}\n\nfunction isWebfetchDetails(details: WebfetchRenderDetails | unknown): details is WebfetchDetails {\n\treturn typeof details === \"object\" && details !== null && \"status\" in details && typeof details.status === \"number\";\n}\n\nfunction previewText(text: string, theme: Theme): string[] {\n\tconst lines = collectNonEmptyTrimmedLines(text, PREVIEW_LINES);\n\tif (lines.length === 0) return [theme.fg(\"dim\", \" empty response\")];\n\treturn lines.map((line) => theme.fg(\"toolOutput\", ` ${truncateToWidth(line, PREVIEW_WIDTH)}`));\n}\n\nfunction shorten(value: string, max: number): string {\n\tif (value.length <= max) return value;\n\treturn `${value.slice(0, max - 1)}…`;\n}\n\nfunction formatBytes(bytes: number): string {\n\tif (bytes < 1024) return `${bytes} B`;\n\tif (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;\n\treturn `${(bytes / (1024 * 1024)).toFixed(1)} MB`;\n}\n"]}
@@ -10,7 +10,14 @@ export interface WebfetchDetails {
10
10
  bytes: number;
11
11
  timeoutSeconds: number;
12
12
  converted: boolean;
13
+ /** Whether the network response body was truncated at the {@link MAX_RESPONSE_SIZE_BYTES} fetch limit. */
13
14
  truncated: boolean;
15
+ /** Whether the text handed to the model was capped below the raw content size. */
16
+ outputTruncated: boolean;
17
+ /** Byte length of the text handed to the model (excluding the truncation notice). */
18
+ outputBytes: number;
19
+ /** Byte length of the full converted text before the output cap. */
20
+ outputTotalBytes: number;
14
21
  }
15
22
  export interface WebfetchProgressDetails {
16
23
  phase: "fetching";
@@ -25,4 +32,24 @@ export declare const webfetch: import("../../../types.ts").ToolDefinition<Type.T
25
32
  timeout: Type.TOptional<Type.TNumber>;
26
33
  }>, WebfetchRenderDetails, any> & import("../../../types.ts").ToolDefinition<any, any, any>;
27
34
  export declare function parseWebfetchFormat(value: unknown): WebfetchFormat;
35
+ /** Byte ceiling for the text handed to the model, mirroring senpi's read-tool output cap. */
36
+ export declare const DEFAULT_OUTPUT_MAX_BYTES: number;
37
+ export interface WebfetchOutputCap {
38
+ /** Model-facing text after the output cap, with a notice appended when truncated. */
39
+ text: string;
40
+ /** Whether the text was capped below the full converted size. */
41
+ truncated: boolean;
42
+ /** Byte length of {@link WebfetchOutputCap.text} excluding the appended notice. */
43
+ outputBytes: number;
44
+ /** Byte length of the full converted text before capping. */
45
+ totalBytes: number;
46
+ }
47
+ /**
48
+ * Bound the text handed to the model so a single fetch cannot flood the context
49
+ * window and force an unwanted compaction. Keeps whole leading lines until the
50
+ * byte ceiling is hit; when the first line alone exceeds the ceiling (minified
51
+ * JSON, single-line payloads) it falls back to a UTF-8-safe byte prefix so the
52
+ * head is preserved instead of dropped.
53
+ */
54
+ export declare function capWebfetchOutput(text: string): WebfetchOutputCap;
28
55
  //# sourceMappingURL=tool.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/webfetch/webfetch/tool.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAI/B,OAAO,EAA0B,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAc3E,MAAM,WAAW,eAAe;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,WAAW,uBAAuB;IACvC,KAAK,EAAE,UAAU,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,cAAc,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,qBAAqB,GAAG,eAAe,GAAG,uBAAuB,CAAC;AAE9E,eAAO,MAAM,QAAQ;;;;2FA2DnB,CAAC;AAEH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,cAAc,CAMlE"}
1
+ {"version":3,"file":"tool.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/webfetch/webfetch/tool.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,MAAM,SAAS,CAAC;AAI/B,OAAO,EAA0B,KAAK,cAAc,EAAE,MAAM,cAAc,CAAC;AAc3E,MAAM,WAAW,eAAe;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,cAAc,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,SAAS,EAAE,OAAO,CAAC;IACnB,0GAA0G;IAC1G,SAAS,EAAE,OAAO,CAAC;IACnB,kFAAkF;IAClF,eAAe,EAAE,OAAO,CAAC;IACzB,qFAAqF;IACrF,WAAW,EAAE,MAAM,CAAC;IACpB,oEAAoE;IACpE,gBAAgB,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,uBAAuB;IACvC,KAAK,EAAE,UAAU,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,cAAc,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,MAAM,qBAAqB,GAAG,eAAe,GAAG,uBAAuB,CAAC;AAE9E,eAAO,MAAM,QAAQ;;;;2FAgEnB,CAAC;AAEH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,cAAc,CAMlE;AAED,6FAA6F;AAC7F,eAAO,MAAM,wBAAwB,QAAY,CAAC;AAElD,MAAM,WAAW,iBAAiB;IACjC,qFAAqF;IACrF,IAAI,EAAE,MAAM,CAAC;IACb,iEAAiE;IACjE,SAAS,EAAE,OAAO,CAAC;IACnB,mFAAmF;IACnF,WAAW,EAAE,MAAM,CAAC;IACpB,6DAA6D;IAC7D,UAAU,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,iBAAiB,CAYjE"}
@@ -49,6 +49,7 @@ export const webfetch = defineTool({
49
49
  text = htmlToText(raw, fetched.url);
50
50
  converted = true;
51
51
  }
52
+ const capped = capWebfetchOutput(text);
52
53
  const details = {
53
54
  url: params.url,
54
55
  finalUrl: fetched.url,
@@ -60,9 +61,12 @@ export const webfetch = defineTool({
60
61
  timeoutSeconds,
61
62
  converted,
62
63
  truncated: fetched.truncated,
64
+ outputTruncated: capped.truncated,
65
+ outputBytes: capped.outputBytes,
66
+ outputTotalBytes: capped.totalBytes,
63
67
  };
64
68
  return {
65
- content: [{ type: "text", text }],
69
+ content: [{ type: "text", text: capped.text }],
66
70
  details,
67
71
  };
68
72
  },
@@ -76,4 +80,59 @@ export function parseWebfetchFormat(value) {
76
80
  }
77
81
  return "markdown";
78
82
  }
83
+ /** Byte ceiling for the text handed to the model, mirroring senpi's read-tool output cap. */
84
+ export const DEFAULT_OUTPUT_MAX_BYTES = 50 * 1024;
85
+ /**
86
+ * Bound the text handed to the model so a single fetch cannot flood the context
87
+ * window and force an unwanted compaction. Keeps whole leading lines until the
88
+ * byte ceiling is hit; when the first line alone exceeds the ceiling (minified
89
+ * JSON, single-line payloads) it falls back to a UTF-8-safe byte prefix so the
90
+ * head is preserved instead of dropped.
91
+ */
92
+ export function capWebfetchOutput(text) {
93
+ const totalBytes = Buffer.byteLength(text, "utf-8");
94
+ if (totalBytes <= DEFAULT_OUTPUT_MAX_BYTES) {
95
+ return { text, truncated: false, outputBytes: totalBytes, totalBytes };
96
+ }
97
+ const head = takeHeadBytes(text, DEFAULT_OUTPUT_MAX_BYTES);
98
+ const outputBytes = Buffer.byteLength(head, "utf-8");
99
+ const notice = `\n\n[Output truncated: ${formatByteSize(outputBytes)} of ${formatByteSize(totalBytes)} shown (${formatByteSize(DEFAULT_OUTPUT_MAX_BYTES)} limit). Re-fetch a more specific URL or use web_search for targeted content.]`;
100
+ return { text: head + notice, truncated: true, outputBytes, totalBytes };
101
+ }
102
+ /** Keep whole leading lines within the byte ceiling; fall back to a UTF-8-safe byte prefix for one oversized line. */
103
+ function takeHeadBytes(text, maxBytes) {
104
+ const lines = [];
105
+ let usedBytes = 0;
106
+ let start = 0;
107
+ while (start <= text.length) {
108
+ const newlineIndex = text.indexOf("\n", start);
109
+ const line = newlineIndex === -1 ? text.slice(start) : text.slice(start, newlineIndex);
110
+ const lineBytes = Buffer.byteLength(line, "utf-8") + (lines.length > 0 ? 1 : 0);
111
+ if (usedBytes + lineBytes > maxBytes)
112
+ break;
113
+ lines.push(line);
114
+ usedBytes += lineBytes;
115
+ if (newlineIndex === -1)
116
+ break;
117
+ start = newlineIndex + 1;
118
+ }
119
+ return lines.length === 0 ? sliceUtf8Head(text, maxBytes) : lines.join("\n");
120
+ }
121
+ /** Slice the first {@link maxBytes} bytes of a UTF-8 string without leaving a split code point. */
122
+ function sliceUtf8Head(value, maxBytes) {
123
+ const buffer = Buffer.from(value, "utf-8");
124
+ if (buffer.length <= maxBytes)
125
+ return value;
126
+ const decoded = new TextDecoder("utf-8").decode(buffer.subarray(0, maxBytes));
127
+ // A trailing partial code point decodes to U+FFFD; drop it so no split byte remains.
128
+ return decoded.endsWith("\uFFFD") ? decoded.slice(0, -1) : decoded;
129
+ }
130
+ /** Human-readable byte size (B / KB / MB). */
131
+ function formatByteSize(bytes) {
132
+ if (bytes < 1024)
133
+ return `${bytes}B`;
134
+ if (bytes < 1024 * 1024)
135
+ return `${(bytes / 1024).toFixed(1)}KB`;
136
+ return `${(bytes / (1024 * 1024)).toFixed(1)}MB`;
137
+ }
79
138
  //# sourceMappingURL=tool.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"tool.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/webfetch/webfetch/tool.ts"],"names":[],"mappings":"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","sourcesContent":["import { StringEnum } from \"@earendil-works/pi-ai\";\nimport { Type } from \"typebox\";\nimport { defineTool } from \"../../../types.ts\";\n\nimport { htmlToMarkdown, htmlToText } from \"./content.ts\";\nimport { clampTimeout, fetchUrl, type WebfetchFormat } from \"./fetcher.ts\";\n\nconst WEBFETCH_FORMATS = [\"markdown\", \"text\", \"html\"] as const;\n\nconst Params = Type.Object({\n\turl: Type.String({ description: \"The URL to fetch content from\" }),\n\tformat: Type.Optional(\n\t\tStringEnum([\"markdown\", \"text\", \"html\"] as const, {\n\t\t\tdescription: \"The format to return the content in. Defaults to markdown.\",\n\t\t}),\n\t),\n\ttimeout: Type.Optional(Type.Number({ description: \"Optional timeout in seconds. Maximum 120.\" })),\n});\n\nexport interface WebfetchDetails {\n\turl: string;\n\tfinalUrl: string;\n\tformat: WebfetchFormat;\n\tstatus: number;\n\tstatusText: string;\n\tcontentType: string;\n\tbytes: number;\n\ttimeoutSeconds: number;\n\tconverted: boolean;\n\ttruncated: boolean;\n}\n\nexport interface WebfetchProgressDetails {\n\tphase: \"fetching\";\n\turl: string;\n\tformat: WebfetchFormat;\n\ttimeoutSeconds: number;\n}\n\nexport type WebfetchRenderDetails = WebfetchDetails | WebfetchProgressDetails;\n\nexport const webfetch = defineTool<typeof Params, WebfetchRenderDetails>({\n\tname: \"webfetch\",\n\tlabel: \"Web Fetch\",\n\tdescription:\n\t\t\"Fetches content from a URL and returns it as markdown, plain text, or HTML. \" +\n\t\t\"Network use is bounded by timeout and response size limits.\",\n\tpromptSnippet: \"webfetch: retrieve URL content as markdown, text, or html\",\n\tpromptGuidelines: [\n\t\t\"Use webfetch when a specific URL must be retrieved.\",\n\t\t\"Prefer markdown format unless raw HTML or plain text is explicitly needed.\",\n\t\t\"The tool is read-only and does not modify files.\",\n\t],\n\tparameters: Params,\n\tasync execute(_toolCallId, params, signal, onUpdate, _ctx) {\n\t\tconst format = parseWebfetchFormat(params.format);\n\t\tconst timeoutSeconds = clampTimeout(params.timeout);\n\t\tonUpdate?.({\n\t\t\tcontent: [{ type: \"text\", text: `Fetching ${params.url} as ${format} (timeout ${timeoutSeconds}s)` }],\n\t\t\tdetails: { phase: \"fetching\", url: params.url, format, timeoutSeconds },\n\t\t});\n\n\t\tconst fetched = await fetchUrl({\n\t\t\turl: params.url,\n\t\t\tformat,\n\t\t\ttimeoutSeconds,\n\t\t\t...(signal === undefined ? {} : { signal }),\n\t\t});\n\t\tconst raw = new TextDecoder().decode(fetched.body);\n\t\tconst contentType = fetched.contentType.toLowerCase();\n\t\tconst isHtml = contentType.includes(\"text/html\") || contentType.includes(\"application/xhtml+xml\");\n\t\tlet text = raw;\n\t\tlet converted = false;\n\n\t\tif (isHtml && format === \"markdown\") {\n\t\t\ttext = htmlToMarkdown(raw, fetched.url);\n\t\t\tconverted = true;\n\t\t} else if (isHtml && format === \"text\") {\n\t\t\ttext = htmlToText(raw, fetched.url);\n\t\t\tconverted = true;\n\t\t}\n\n\t\tconst details: WebfetchDetails = {\n\t\t\turl: params.url,\n\t\t\tfinalUrl: fetched.url,\n\t\t\tformat,\n\t\t\tstatus: fetched.status,\n\t\t\tstatusText: fetched.statusText,\n\t\t\tcontentType: fetched.contentType,\n\t\t\tbytes: fetched.bytes,\n\t\t\ttimeoutSeconds,\n\t\t\tconverted,\n\t\t\ttruncated: fetched.truncated,\n\t\t};\n\n\t\treturn {\n\t\t\tcontent: [{ type: \"text\", text }],\n\t\t\tdetails,\n\t\t};\n\t},\n});\n\nexport function parseWebfetchFormat(value: unknown): WebfetchFormat {\n\tif (value === undefined) return \"markdown\";\n\tfor (const format of WEBFETCH_FORMATS) {\n\t\tif (value === format) return format;\n\t}\n\treturn \"markdown\";\n}\n"]}
1
+ {"version":3,"file":"tool.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/webfetch/webfetch/tool.ts"],"names":[],"mappings":"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","sourcesContent":["import { StringEnum } from \"@earendil-works/pi-ai\";\nimport { Type } from \"typebox\";\nimport { defineTool } from \"../../../types.ts\";\n\nimport { htmlToMarkdown, htmlToText } from \"./content.ts\";\nimport { clampTimeout, fetchUrl, type WebfetchFormat } from \"./fetcher.ts\";\n\nconst WEBFETCH_FORMATS = [\"markdown\", \"text\", \"html\"] as const;\n\nconst Params = Type.Object({\n\turl: Type.String({ description: \"The URL to fetch content from\" }),\n\tformat: Type.Optional(\n\t\tStringEnum([\"markdown\", \"text\", \"html\"] as const, {\n\t\t\tdescription: \"The format to return the content in. Defaults to markdown.\",\n\t\t}),\n\t),\n\ttimeout: Type.Optional(Type.Number({ description: \"Optional timeout in seconds. Maximum 120.\" })),\n});\n\nexport interface WebfetchDetails {\n\turl: string;\n\tfinalUrl: string;\n\tformat: WebfetchFormat;\n\tstatus: number;\n\tstatusText: string;\n\tcontentType: string;\n\tbytes: number;\n\ttimeoutSeconds: number;\n\tconverted: boolean;\n\t/** Whether the network response body was truncated at the {@link MAX_RESPONSE_SIZE_BYTES} fetch limit. */\n\ttruncated: boolean;\n\t/** Whether the text handed to the model was capped below the raw content size. */\n\toutputTruncated: boolean;\n\t/** Byte length of the text handed to the model (excluding the truncation notice). */\n\toutputBytes: number;\n\t/** Byte length of the full converted text before the output cap. */\n\toutputTotalBytes: number;\n}\n\nexport interface WebfetchProgressDetails {\n\tphase: \"fetching\";\n\turl: string;\n\tformat: WebfetchFormat;\n\ttimeoutSeconds: number;\n}\n\nexport type WebfetchRenderDetails = WebfetchDetails | WebfetchProgressDetails;\n\nexport const webfetch = defineTool<typeof Params, WebfetchRenderDetails>({\n\tname: \"webfetch\",\n\tlabel: \"Web Fetch\",\n\tdescription:\n\t\t\"Fetches content from a URL and returns it as markdown, plain text, or HTML. \" +\n\t\t\"Network use is bounded by timeout and response size limits.\",\n\tpromptSnippet: \"webfetch: retrieve URL content as markdown, text, or html\",\n\tpromptGuidelines: [\n\t\t\"Use webfetch when a specific URL must be retrieved.\",\n\t\t\"Prefer markdown format unless raw HTML or plain text is explicitly needed.\",\n\t\t\"The tool is read-only and does not modify files.\",\n\t],\n\tparameters: Params,\n\tasync execute(_toolCallId, params, signal, onUpdate, _ctx) {\n\t\tconst format = parseWebfetchFormat(params.format);\n\t\tconst timeoutSeconds = clampTimeout(params.timeout);\n\t\tonUpdate?.({\n\t\t\tcontent: [{ type: \"text\", text: `Fetching ${params.url} as ${format} (timeout ${timeoutSeconds}s)` }],\n\t\t\tdetails: { phase: \"fetching\", url: params.url, format, timeoutSeconds },\n\t\t});\n\n\t\tconst fetched = await fetchUrl({\n\t\t\turl: params.url,\n\t\t\tformat,\n\t\t\ttimeoutSeconds,\n\t\t\t...(signal === undefined ? {} : { signal }),\n\t\t});\n\t\tconst raw = new TextDecoder().decode(fetched.body);\n\t\tconst contentType = fetched.contentType.toLowerCase();\n\t\tconst isHtml = contentType.includes(\"text/html\") || contentType.includes(\"application/xhtml+xml\");\n\t\tlet text = raw;\n\t\tlet converted = false;\n\n\t\tif (isHtml && format === \"markdown\") {\n\t\t\ttext = htmlToMarkdown(raw, fetched.url);\n\t\t\tconverted = true;\n\t\t} else if (isHtml && format === \"text\") {\n\t\t\ttext = htmlToText(raw, fetched.url);\n\t\t\tconverted = true;\n\t\t}\n\n\t\tconst capped = capWebfetchOutput(text);\n\n\t\tconst details: WebfetchDetails = {\n\t\t\turl: params.url,\n\t\t\tfinalUrl: fetched.url,\n\t\t\tformat,\n\t\t\tstatus: fetched.status,\n\t\t\tstatusText: fetched.statusText,\n\t\t\tcontentType: fetched.contentType,\n\t\t\tbytes: fetched.bytes,\n\t\t\ttimeoutSeconds,\n\t\t\tconverted,\n\t\t\ttruncated: fetched.truncated,\n\t\t\toutputTruncated: capped.truncated,\n\t\t\toutputBytes: capped.outputBytes,\n\t\t\toutputTotalBytes: capped.totalBytes,\n\t\t};\n\n\t\treturn {\n\t\t\tcontent: [{ type: \"text\", text: capped.text }],\n\t\t\tdetails,\n\t\t};\n\t},\n});\n\nexport function parseWebfetchFormat(value: unknown): WebfetchFormat {\n\tif (value === undefined) return \"markdown\";\n\tfor (const format of WEBFETCH_FORMATS) {\n\t\tif (value === format) return format;\n\t}\n\treturn \"markdown\";\n}\n\n/** Byte ceiling for the text handed to the model, mirroring senpi's read-tool output cap. */\nexport const DEFAULT_OUTPUT_MAX_BYTES = 50 * 1024;\n\nexport interface WebfetchOutputCap {\n\t/** Model-facing text after the output cap, with a notice appended when truncated. */\n\ttext: string;\n\t/** Whether the text was capped below the full converted size. */\n\ttruncated: boolean;\n\t/** Byte length of {@link WebfetchOutputCap.text} excluding the appended notice. */\n\toutputBytes: number;\n\t/** Byte length of the full converted text before capping. */\n\ttotalBytes: number;\n}\n\n/**\n * Bound the text handed to the model so a single fetch cannot flood the context\n * window and force an unwanted compaction. Keeps whole leading lines until the\n * byte ceiling is hit; when the first line alone exceeds the ceiling (minified\n * JSON, single-line payloads) it falls back to a UTF-8-safe byte prefix so the\n * head is preserved instead of dropped.\n */\nexport function capWebfetchOutput(text: string): WebfetchOutputCap {\n\tconst totalBytes = Buffer.byteLength(text, \"utf-8\");\n\tif (totalBytes <= DEFAULT_OUTPUT_MAX_BYTES) {\n\t\treturn { text, truncated: false, outputBytes: totalBytes, totalBytes };\n\t}\n\n\tconst head = takeHeadBytes(text, DEFAULT_OUTPUT_MAX_BYTES);\n\tconst outputBytes = Buffer.byteLength(head, \"utf-8\");\n\tconst notice = `\\n\\n[Output truncated: ${formatByteSize(outputBytes)} of ${formatByteSize(\n\t\ttotalBytes,\n\t)} shown (${formatByteSize(DEFAULT_OUTPUT_MAX_BYTES)} limit). Re-fetch a more specific URL or use web_search for targeted content.]`;\n\treturn { text: head + notice, truncated: true, outputBytes, totalBytes };\n}\n\n/** Keep whole leading lines within the byte ceiling; fall back to a UTF-8-safe byte prefix for one oversized line. */\nfunction takeHeadBytes(text: string, maxBytes: number): string {\n\tconst lines: string[] = [];\n\tlet usedBytes = 0;\n\tlet start = 0;\n\twhile (start <= text.length) {\n\t\tconst newlineIndex = text.indexOf(\"\\n\", start);\n\t\tconst line = newlineIndex === -1 ? text.slice(start) : text.slice(start, newlineIndex);\n\t\tconst lineBytes = Buffer.byteLength(line, \"utf-8\") + (lines.length > 0 ? 1 : 0);\n\t\tif (usedBytes + lineBytes > maxBytes) break;\n\t\tlines.push(line);\n\t\tusedBytes += lineBytes;\n\t\tif (newlineIndex === -1) break;\n\t\tstart = newlineIndex + 1;\n\t}\n\treturn lines.length === 0 ? sliceUtf8Head(text, maxBytes) : lines.join(\"\\n\");\n}\n\n/** Slice the first {@link maxBytes} bytes of a UTF-8 string without leaving a split code point. */\nfunction sliceUtf8Head(value: string, maxBytes: number): string {\n\tconst buffer = Buffer.from(value, \"utf-8\");\n\tif (buffer.length <= maxBytes) return value;\n\tconst decoded = new TextDecoder(\"utf-8\").decode(buffer.subarray(0, maxBytes));\n\t// A trailing partial code point decodes to U+FFFD; drop it so no split byte remains.\n\treturn decoded.endsWith(\"\\uFFFD\") ? decoded.slice(0, -1) : decoded;\n}\n\n/** Human-readable byte size (B / KB / MB). */\nfunction formatByteSize(bytes: number): string {\n\tif (bytes < 1024) return `${bytes}B`;\n\tif (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)}KB`;\n\treturn `${(bytes / (1024 * 1024)).toFixed(1)}MB`;\n}\n"]}
@@ -380,6 +380,11 @@ export interface ToolRenderContext<TState = any, TArgs = any> {
380
380
  imageProtocol?: ImageProtocol;
381
381
  /** Whether the current result is an error. */
382
382
  isError: boolean;
383
+ /**
384
+ * Whether a result (partial or final) already exists for this tool call. Lets a call renderer that draws
385
+ * self-contained framing yield to the result renderer instead of stacking a duplicate block.
386
+ */
387
+ hasResult?: boolean;
383
388
  spinnerFrame?: number;
384
389
  }
385
390
  /**