@code-yeongyu/senpi 2026.7.31-2 → 2026.8.1

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 (163) hide show
  1. package/CHANGELOG.md +153 -0
  2. package/dist/core/agent-session.d.ts +1 -1
  3. package/dist/core/agent-session.d.ts.map +1 -1
  4. package/dist/core/agent-session.js +10 -19
  5. package/dist/core/agent-session.js.map +1 -1
  6. package/dist/core/extensions/builtin/goal/persistence.d.ts +15 -0
  7. package/dist/core/extensions/builtin/goal/persistence.d.ts.map +1 -1
  8. package/dist/core/extensions/builtin/goal/persistence.js +150 -18
  9. package/dist/core/extensions/builtin/goal/persistence.js.map +1 -1
  10. package/dist/core/extensions/builtin/gpt-apply-patch/extension.d.ts.map +1 -1
  11. package/dist/core/extensions/builtin/gpt-apply-patch/extension.js +15 -0
  12. package/dist/core/extensions/builtin/gpt-apply-patch/extension.js.map +1 -1
  13. package/dist/core/extensions/builtin/gpt-apply-patch/tool.d.ts.map +1 -1
  14. package/dist/core/extensions/builtin/gpt-apply-patch/tool.js +30 -3
  15. package/dist/core/extensions/builtin/gpt-apply-patch/tool.js.map +1 -1
  16. package/dist/core/extensions/builtin/prompt-preset/deepseek-v4-flash-0731.d.ts +3 -0
  17. package/dist/core/extensions/builtin/prompt-preset/deepseek-v4-flash-0731.d.ts.map +1 -0
  18. package/dist/core/extensions/builtin/prompt-preset/deepseek-v4-flash-0731.js +10 -0
  19. package/dist/core/extensions/builtin/prompt-preset/deepseek-v4-flash-0731.js.map +1 -0
  20. package/dist/core/extensions/builtin/prompt-preset/deepseek-v4-flash.d.ts +3 -0
  21. package/dist/core/extensions/builtin/prompt-preset/deepseek-v4-flash.d.ts.map +1 -0
  22. package/dist/core/extensions/builtin/prompt-preset/deepseek-v4-flash.js +10 -0
  23. package/dist/core/extensions/builtin/prompt-preset/deepseek-v4-flash.js.map +1 -0
  24. package/dist/core/extensions/builtin/prompt-preset/deepseek-v4-pro.d.ts +3 -0
  25. package/dist/core/extensions/builtin/prompt-preset/deepseek-v4-pro.d.ts.map +1 -0
  26. package/dist/core/extensions/builtin/prompt-preset/deepseek-v4-pro.js +11 -0
  27. package/dist/core/extensions/builtin/prompt-preset/deepseek-v4-pro.js.map +1 -0
  28. package/dist/core/extensions/builtin/prompt-preset/deepseek-v4.d.ts +13 -0
  29. package/dist/core/extensions/builtin/prompt-preset/deepseek-v4.d.ts.map +1 -0
  30. package/dist/core/extensions/builtin/prompt-preset/deepseek-v4.js +60 -0
  31. package/dist/core/extensions/builtin/prompt-preset/deepseek-v4.js.map +1 -0
  32. package/dist/core/extensions/builtin/prompt-preset/presets.d.ts.map +1 -1
  33. package/dist/core/extensions/builtin/prompt-preset/presets.js +42 -0
  34. package/dist/core/extensions/builtin/prompt-preset/presets.js.map +1 -1
  35. package/dist/core/extensions/builtin/prompt-preset/settings.d.ts +1 -1
  36. package/dist/core/extensions/builtin/prompt-preset/settings.d.ts.map +1 -1
  37. package/dist/core/extensions/builtin/prompt-preset/settings.js +3 -0
  38. package/dist/core/extensions/builtin/prompt-preset/settings.js.map +1 -1
  39. package/dist/core/extensions/builtin/recommended-models/index.d.ts.map +1 -1
  40. package/dist/core/extensions/builtin/recommended-models/index.js +2 -1
  41. package/dist/core/extensions/builtin/recommended-models/index.js.map +1 -1
  42. package/dist/core/extensions/builtin/terminal/monitor-notify.d.ts.map +1 -1
  43. package/dist/core/extensions/builtin/terminal/monitor-notify.js +42 -5
  44. package/dist/core/extensions/builtin/terminal/monitor-notify.js.map +1 -1
  45. package/dist/core/extensions/builtin/terminal/tools/monitor.js +1 -1
  46. package/dist/core/extensions/builtin/terminal/tools/monitor.js.map +1 -1
  47. package/dist/core/extensions/builtin/todotools/commands.d.ts +2 -2
  48. package/dist/core/extensions/builtin/todotools/commands.d.ts.map +1 -1
  49. package/dist/core/extensions/builtin/todotools/commands.js.map +1 -1
  50. package/dist/core/extensions/builtin/todotools/index.d.ts.map +1 -1
  51. package/dist/core/extensions/builtin/todotools/index.js +6 -3
  52. package/dist/core/extensions/builtin/todotools/index.js.map +1 -1
  53. package/dist/core/extensions/builtin/todotools/state.d.ts +1 -1
  54. package/dist/core/extensions/builtin/todotools/state.d.ts.map +1 -1
  55. package/dist/core/extensions/builtin/todotools/state.js +1 -1
  56. package/dist/core/extensions/builtin/todotools/state.js.map +1 -1
  57. package/dist/core/extensions/builtin/todotools/todo-widget-component.d.ts +19 -0
  58. package/dist/core/extensions/builtin/todotools/todo-widget-component.d.ts.map +1 -0
  59. package/dist/core/extensions/builtin/todotools/todo-widget-component.js +78 -0
  60. package/dist/core/extensions/builtin/todotools/todo-widget-component.js.map +1 -0
  61. package/dist/core/extensions/builtin/todotools/todo-widget.d.ts +13 -1
  62. package/dist/core/extensions/builtin/todotools/todo-widget.d.ts.map +1 -1
  63. package/dist/core/extensions/builtin/todotools/todo-widget.js +32 -14
  64. package/dist/core/extensions/builtin/todotools/todo-widget.js.map +1 -1
  65. package/dist/core/extensions/builtin/todotools/tools/todo.d.ts +2 -2
  66. package/dist/core/extensions/builtin/todotools/tools/todo.d.ts.map +1 -1
  67. package/dist/core/extensions/builtin/todotools/tools/todo.js +1 -1
  68. package/dist/core/extensions/builtin/todotools/tools/todo.js.map +1 -1
  69. package/dist/core/extensions/builtin/tps.d.ts.map +1 -1
  70. package/dist/core/extensions/builtin/tps.js +5 -2
  71. package/dist/core/extensions/builtin/tps.js.map +1 -1
  72. package/dist/core/extensions/builtin/websearch/websearch/config.d.ts.map +1 -1
  73. package/dist/core/extensions/builtin/websearch/websearch/config.js +1 -0
  74. package/dist/core/extensions/builtin/websearch/websearch/config.js.map +1 -1
  75. package/dist/core/extensions/builtin/websearch/websearch/native.d.ts.map +1 -1
  76. package/dist/core/extensions/builtin/websearch/websearch/native.js +16 -5
  77. package/dist/core/extensions/builtin/websearch/websearch/native.js.map +1 -1
  78. package/dist/core/extensions/builtin/websearch/websearch/provider-endpoints.d.ts.map +1 -1
  79. package/dist/core/extensions/builtin/websearch/websearch/provider-endpoints.js +1 -0
  80. package/dist/core/extensions/builtin/websearch/websearch/provider-endpoints.js.map +1 -1
  81. package/dist/core/extensions/builtin/websearch/websearch/providers/anthropic.d.ts +4 -1
  82. package/dist/core/extensions/builtin/websearch/websearch/providers/anthropic.d.ts.map +1 -1
  83. package/dist/core/extensions/builtin/websearch/websearch/providers/anthropic.js +44 -37
  84. package/dist/core/extensions/builtin/websearch/websearch/providers/anthropic.js.map +1 -1
  85. package/dist/core/extensions/builtin/websearch/websearch/providers/deepseek.d.ts +3 -0
  86. package/dist/core/extensions/builtin/websearch/websearch/providers/deepseek.d.ts.map +1 -0
  87. package/dist/core/extensions/builtin/websearch/websearch/providers/deepseek.js +12 -0
  88. package/dist/core/extensions/builtin/websearch/websearch/providers/deepseek.js.map +1 -0
  89. package/dist/core/extensions/builtin/websearch/websearch/providers.d.ts.map +1 -1
  90. package/dist/core/extensions/builtin/websearch/websearch/providers.js +2 -0
  91. package/dist/core/extensions/builtin/websearch/websearch/providers.js.map +1 -1
  92. package/dist/core/extensions/builtin/websearch/websearch/renderers.d.ts.map +1 -1
  93. package/dist/core/extensions/builtin/websearch/websearch/renderers.js +2 -2
  94. package/dist/core/extensions/builtin/websearch/websearch/renderers.js.map +1 -1
  95. package/dist/core/extensions/builtin/websearch/websearch/tool.js +2 -2
  96. package/dist/core/extensions/builtin/websearch/websearch/tool.js.map +1 -1
  97. package/dist/core/extensions/builtin/websearch/websearch/types.d.ts +1 -1
  98. package/dist/core/extensions/builtin/websearch/websearch/types.d.ts.map +1 -1
  99. package/dist/core/extensions/builtin/websearch/websearch/types.js.map +1 -1
  100. package/dist/core/model-resolver.js +2 -2
  101. package/dist/core/model-resolver.js.map +1 -1
  102. package/dist/core/thinking-levels.d.ts +5 -0
  103. package/dist/core/thinking-levels.d.ts.map +1 -1
  104. package/dist/core/thinking-levels.js +9 -59
  105. package/dist/core/thinking-levels.js.map +1 -1
  106. package/dist/modes/interactive/interactive-mode.js +1 -1
  107. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  108. package/dist/modes/interactive/risky-main-model-warning.d.ts +1 -1
  109. package/dist/modes/interactive/risky-main-model-warning.d.ts.map +1 -1
  110. package/dist/modes/interactive/risky-main-model-warning.js +1 -1
  111. package/dist/modes/interactive/risky-main-model-warning.js.map +1 -1
  112. package/docs/settings.md +1 -1
  113. package/examples/extensions/overlay-test.ts +1 -1
  114. package/node_modules/@code-yeongyu/senpi-codemode/CHANGELOG.md +18 -0
  115. package/node_modules/@code-yeongyu/senpi-codemode/README.md +6 -3
  116. package/node_modules/@code-yeongyu/senpi-codemode/package.json +3 -3
  117. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/cell-execution.ts +146 -0
  118. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/cell-handler.ts +21 -119
  119. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/cell-runtime.ts +157 -0
  120. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/detached-cell-manager.ts +55 -210
  121. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/detached-cell-notification.ts +98 -0
  122. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/detached-cell-snapshot.ts +81 -0
  123. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/detached-cell-state.ts +24 -0
  124. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/detached-eval-result.ts +140 -0
  125. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/detached-notification-queue.ts +53 -0
  126. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-request.ts +45 -0
  127. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-tool-options.ts +45 -0
  128. package/node_modules/@code-yeongyu/senpi-codemode/src/tool/eval-tool.ts +20 -342
  129. package/node_modules/@earendil-works/pi-agent-core/package.json +2 -2
  130. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses/fallback-state.d.ts +24 -0
  131. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses/fallback-state.d.ts.map +1 -0
  132. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses/fallback-state.js +70 -0
  133. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses/fallback-state.js.map +1 -0
  134. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.d.ts +2 -16
  135. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.d.ts.map +1 -1
  136. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js +8 -56
  137. package/node_modules/@earendil-works/pi-ai/dist/api/openai-codex-responses.js.map +1 -1
  138. package/node_modules/@earendil-works/pi-ai/dist/api/openai-prompt-cache.d.ts +1 -0
  139. package/node_modules/@earendil-works/pi-ai/dist/api/openai-prompt-cache.d.ts.map +1 -1
  140. package/node_modules/@earendil-works/pi-ai/dist/api/openai-prompt-cache.js +7 -0
  141. package/node_modules/@earendil-works/pi-ai/dist/api/openai-prompt-cache.js.map +1 -1
  142. package/node_modules/@earendil-works/pi-ai/dist/model.d.ts +2 -1
  143. package/node_modules/@earendil-works/pi-ai/dist/model.d.ts.map +1 -1
  144. package/node_modules/@earendil-works/pi-ai/dist/model.js.map +1 -1
  145. package/node_modules/@earendil-works/pi-ai/dist/models.d.ts +13 -0
  146. package/node_modules/@earendil-works/pi-ai/dist/models.d.ts.map +1 -1
  147. package/node_modules/@earendil-works/pi-ai/dist/models.js +71 -45
  148. package/node_modules/@earendil-works/pi-ai/dist/models.js.map +1 -1
  149. package/node_modules/@earendil-works/pi-ai/dist/providers/data/.manifest.json +1 -1
  150. package/node_modules/@earendil-works/pi-ai/dist/providers/data/openrouter.json +1 -1
  151. package/node_modules/@earendil-works/pi-ai/dist/providers/data/vercel-ai-gateway.json +1 -1
  152. package/node_modules/@earendil-works/pi-ai/dist/providers/data/zai-coding-cn.json +1 -1
  153. package/node_modules/@earendil-works/pi-ai/dist/providers/data/zai.json +1 -1
  154. package/node_modules/@earendil-works/pi-ai/package.json +1 -1
  155. package/node_modules/@earendil-works/pi-pty/package.json +1 -1
  156. package/node_modules/@earendil-works/pi-tui/dist/mux.js +1 -1
  157. package/node_modules/@earendil-works/pi-tui/dist/mux.js.map +1 -1
  158. package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts +1 -0
  159. package/node_modules/@earendil-works/pi-tui/dist/tui.d.ts.map +1 -1
  160. package/node_modules/@earendil-works/pi-tui/dist/tui.js +17 -3
  161. package/node_modules/@earendil-works/pi-tui/dist/tui.js.map +1 -1
  162. package/node_modules/@earendil-works/pi-tui/package.json +1 -1
  163. package/package.json +6 -6
@@ -1,6 +1,6 @@
1
1
  import { Type } from "typebox";
2
2
  import type { ExtensionAPI, ExtensionContext } from "../../../types.ts";
3
- import { type TodoPhase } from "../state.ts";
3
+ import { type TodoCompletionTransition, type TodoPhase } from "../state.ts";
4
4
  export declare const TODO_PARAMS_SCHEMA: Type.TObject<{
5
5
  op: Type.TOptional<Type.TUnion<[Type.TLiteral<"init">, Type.TLiteral<"start">, Type.TLiteral<"done">, Type.TLiteral<"rm">, Type.TLiteral<"drop">, Type.TLiteral<"append">, Type.TLiteral<"view">]>>;
6
6
  list: Type.TOptional<Type.TArray<Type.TObject<{
@@ -14,7 +14,7 @@ export declare const TODO_PARAMS_SCHEMA: Type.TObject<{
14
14
  type TodoAccessors = {
15
15
  getCurrentPhases: () => TodoPhase[];
16
16
  setCurrentPhases: (phases: TodoPhase[]) => void;
17
- syncWidget: (ctx: ExtensionContext) => void;
17
+ syncWidget: (ctx: ExtensionContext, completedTasks?: readonly TodoCompletionTransition[]) => void;
18
18
  };
19
19
  export declare function phaseRomanNumeral(oneBasedIndex: number): string;
20
20
  export declare function registerTodoTool(pi: ExtensionAPI, accessors: TodoAccessors): void;
@@ -1 +1 @@
1
- {"version":3,"file":"todo.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/todotools/tools/todo.ts"],"names":[],"mappings":"AAMA,OAAO,EAAe,IAAI,EAAE,MAAM,SAAS,CAAC;AAG5C,OAAO,KAAK,EAEX,YAAY,EACZ,gBAAgB,EAIhB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAYN,KAAK,SAAS,EAGd,MAAM,aAAa,CAAC;AAuBrB,eAAO,MAAM,kBAAkB;;;;;;;;;EAU7B,CAAC;AAIH,KAAK,aAAa,GAAG;IACpB,gBAAgB,EAAE,MAAM,SAAS,EAAE,CAAC;IACpC,gBAAgB,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,IAAI,CAAC;IAChD,UAAU,EAAE,CAAC,GAAG,EAAE,gBAAgB,KAAK,IAAI,CAAC;CAC5C,CAAC;AA4CF,wBAAgB,iBAAiB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CA0B/D;AAyID,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,YAAY,EAAE,SAAS,EAAE,aAAa,GAAG,IAAI,CAyEjF"}
1
+ {"version":3,"file":"todo.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/todotools/tools/todo.ts"],"names":[],"mappings":"AAMA,OAAO,EAAe,IAAI,EAAE,MAAM,SAAS,CAAC;AAG5C,OAAO,KAAK,EAEX,YAAY,EACZ,gBAAgB,EAIhB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAUN,KAAK,wBAAwB,EAE7B,KAAK,SAAS,EAGd,MAAM,aAAa,CAAC;AAuBrB,eAAO,MAAM,kBAAkB;;;;;;;;;EAU7B,CAAC;AAIH,KAAK,aAAa,GAAG;IACpB,gBAAgB,EAAE,MAAM,SAAS,EAAE,CAAC;IACpC,gBAAgB,EAAE,CAAC,MAAM,EAAE,SAAS,EAAE,KAAK,IAAI,CAAC;IAChD,UAAU,EAAE,CAAC,GAAG,EAAE,gBAAgB,EAAE,cAAc,CAAC,EAAE,SAAS,wBAAwB,EAAE,KAAK,IAAI,CAAC;CAClG,CAAC;AA4CF,wBAAgB,iBAAiB,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CA0B/D;AAyID,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,YAAY,EAAE,SAAS,EAAE,aAAa,GAAG,IAAI,CAyEjF"}
@@ -239,7 +239,7 @@ export function registerTodoTool(pi, accessors) {
239
239
  phases: clonePhases(applied.phases),
240
240
  });
241
241
  accessors.setCurrentPhases(clonePhases(applied.phases));
242
- accessors.syncWidget(ctx);
242
+ accessors.syncWidget(ctx, completedTasks);
243
243
  }
244
244
  const details = {
245
245
  op: entry.op,
@@ -1 +1 @@
1
- {"version":3,"file":"todo.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/todotools/tools/todo.ts"],"names":[],"mappings":"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","sourcesContent":["// Ported and adapted from oh-my-pi's todo tool (MIT License).\n// Copyright (c) 2025 Mario Zechner\n// Copyright (c) 2025-2026 Can Bölük\n// https://github.com/can1357/oh-my-pi\n\nimport { Text } from \"@earendil-works/pi-tui\";\nimport { type Static, Type } from \"typebox\";\nimport { partialStrikethrough, strikeRevealCount } from \"../../../../../modes/interactive/components/todo-strike.ts\";\nimport type { Theme } from \"../../../../../modes/interactive/theme/theme.ts\";\nimport type {\n\tAgentToolResult,\n\tExtensionAPI,\n\tExtensionContext,\n\tToolDefinition,\n\tToolRenderContext,\n\tToolRenderResultOptions,\n} from \"../../../types.ts\";\nimport { normalizeTodoParams } from \"../normalize.ts\";\nimport { TODO_TOOL_DESCRIPTION } from \"../prompt.ts\";\nimport {\n\tapplyParams,\n\tclonePhases,\n\tfindTaskByContent,\n\tformatSummary,\n\tgetCompletionTransitions,\n\tgetTodoMarker,\n\tnextActionableTask,\n\tsanitizeTodoText,\n\tTODO_STATE_ENTRY_TYPE,\n\ttype TodoCompletionTransition,\n\ttype TodoOperation,\n\ttype TodoPhase,\n\ttype TodoStateEntry,\n\ttype TodoToolDetails,\n} from \"../state.ts\";\n\nconst TodoOperationSchema = Type.Union(\n\t[\n\t\tType.Literal(\"init\"),\n\t\tType.Literal(\"start\"),\n\t\tType.Literal(\"done\"),\n\t\tType.Literal(\"rm\"),\n\t\tType.Literal(\"drop\"),\n\t\tType.Literal(\"append\"),\n\t\tType.Literal(\"view\"),\n\t],\n\t{ description: \"Operation to perform. Required — always pass it explicitly.\" },\n);\n\nconst TodoPhaseInputSchema = Type.Object({\n\tphase: Type.String({ description: \"Phase name\" }),\n\titems: Type.Array(Type.String({ description: \"Task content\" }), {\n\t\tdescription: \"Tasks for this phase\",\n\t\tminItems: 1,\n\t}),\n});\n\nexport const TODO_PARAMS_SCHEMA = Type.Object({\n\top: Type.Optional(TodoOperationSchema),\n\tlist: Type.Optional(Type.Array(TodoPhaseInputSchema, { description: \"Phased task list for init\" })),\n\ttask: Type.Optional(Type.String({ description: \"Exact task text copied from the previous todo result\" })),\n\tphase: Type.Optional(Type.String({ description: \"Exact phase name copied from the previous todo result\" })),\n\t// Keep this unconstrained at the schema boundary. init and append return\n\t// operation-specific errors, while unrelated operations may ignore it.\n\titems: Type.Optional(\n\t\tType.Array(Type.String({ description: \"Task content\" }), { description: \"Task texts to append\" }),\n\t),\n});\n\ntype TodoParams = Static<typeof TODO_PARAMS_SCHEMA>;\n\ntype TodoAccessors = {\n\tgetCurrentPhases: () => TodoPhase[];\n\tsetCurrentPhases: (phases: TodoPhase[]) => void;\n\tsyncWidget: (ctx: ExtensionContext) => void;\n};\n\nfunction countInitItems(params: TodoParams): { phases: number; tasks: number } {\n\tif (params.list) {\n\t\treturn {\n\t\t\tphases: params.list.length,\n\t\t\ttasks: params.list.reduce((total, phase) => total + phase.items.length, 0),\n\t\t};\n\t}\n\tif (params.items) return { phases: params.items.length > 0 ? 1 : 0, tasks: params.items.length };\n\treturn { phases: 0, tasks: 0 };\n}\n\nfunction countLabel(count: number, singular: string): string {\n\treturn `${count} ${singular}${count === 1 ? \"\" : \"s\"}`;\n}\n\nfunction renderCallLabel(params: TodoParams): string {\n\tswitch (params.op) {\n\t\tcase \"init\": {\n\t\t\tconst counts = countInitItems(params);\n\t\t\treturn `todo init (${countLabel(counts.phases, \"phase\")}, ${countLabel(counts.tasks, \"task\")})`;\n\t\t}\n\t\tcase \"append\":\n\t\t\treturn `todo append: ${sanitizeTodoText(params.phase ?? \"\") || \"(missing phase)\"} (${countLabel(\n\t\t\t\tparams.items?.length ?? 0,\n\t\t\t\t\"item\",\n\t\t\t)})`;\n\t\tcase \"start\":\n\t\tcase \"done\":\n\t\tcase \"drop\":\n\t\t\treturn `todo ${params.op}: ${sanitizeTodoText(params.task ?? params.phase ?? \"\") || \"(missing target)\"}`;\n\t\tcase \"rm\":\n\t\t\treturn `todo rm: ${sanitizeTodoText(params.task ?? params.phase ?? \"all\") || \"all\"}`;\n\t\tcase \"view\":\n\t\t\treturn \"todo view\";\n\t\t// Normalization can rescue a call that omitted `op`; label it generically until\n\t\t// execute resolves the effective operation. Listing `undefined` explicitly (instead\n\t\t// of `default`) keeps this switch exhaustive, so a new TodoOperation fails typecheck.\n\t\tcase undefined:\n\t\t\treturn \"todo\";\n\t}\n}\n\nexport function phaseRomanNumeral(oneBasedIndex: number): string {\n\tif (oneBasedIndex <= 0) return \"\";\n\tconst pairs: ReadonlyArray<readonly [number, string]> = [\n\t\t[1000, \"M\"],\n\t\t[900, \"CM\"],\n\t\t[500, \"D\"],\n\t\t[400, \"CD\"],\n\t\t[100, \"C\"],\n\t\t[90, \"XC\"],\n\t\t[50, \"L\"],\n\t\t[40, \"XL\"],\n\t\t[10, \"X\"],\n\t\t[9, \"IX\"],\n\t\t[5, \"V\"],\n\t\t[4, \"IV\"],\n\t\t[1, \"I\"],\n\t];\n\tlet remaining = oneBasedIndex;\n\tlet output = \"\";\n\tfor (const [value, symbol] of pairs) {\n\t\twhile (remaining >= value) {\n\t\t\toutput += symbol;\n\t\t\tremaining -= value;\n\t\t}\n\t}\n\treturn output;\n}\n\nfunction formatPhaseHeader(name: string, index: number, theme: Theme): string {\n\treturn theme.fg(\"accent\", theme.bold(`${phaseRomanNumeral(index)}. ${sanitizeTodoText(name)}`));\n}\n\nfunction formatPhaseSummary(phase: TodoPhase, index: number, theme: Theme): string {\n\tconst closed = phase.tasks.filter((task) => task.status === \"completed\" || task.status === \"abandoned\").length;\n\treturn theme.fg(\n\t\t\"dim\",\n\t\t`${phaseRomanNumeral(index)}. ${sanitizeTodoText(phase.name)} — ${closed}/${phase.tasks.length} done`,\n\t);\n}\n\nfunction formatTaskLine(\n\ttask: TodoPhase[\"tasks\"][number],\n\ttheme: Theme,\n\tcompletionKeys: ReadonlySet<string>,\n\tframe: number | undefined,\n): string {\n\tconst content = sanitizeTodoText(task.content);\n\tconst line = `${getTodoMarker(task.status)} ${content}`;\n\tswitch (task.status) {\n\t\tcase \"completed\": {\n\t\t\tconst reveal = completionKeys.has(task.content) ? strikeRevealCount(line, frame) : undefined;\n\t\t\treturn reveal === undefined\n\t\t\t\t? theme.fg(\"dim\", theme.strikethrough(line))\n\t\t\t\t: theme.fg(\n\t\t\t\t\t\t\"dim\",\n\t\t\t\t\t\tpartialStrikethrough(line, reveal, (text) => theme.strikethrough(text)),\n\t\t\t\t\t);\n\t\t}\n\t\tcase \"in_progress\":\n\t\t\treturn theme.fg(\"accent\", theme.bold(line));\n\t\tcase \"abandoned\":\n\t\t\treturn theme.fg(\"dim\", line);\n\t\tcase \"pending\":\n\t\t\treturn line;\n\t}\n}\n\nfunction computeTouchedPhases(\n\targs: TodoParams,\n\toperation: TodoOperation | undefined,\n\tphases: readonly TodoPhase[],\n\tcompletedTasks: readonly TodoCompletionTransition[],\n): Set<string> | null {\n\tconst touched = new Set<string>();\n\tconst activeTask = nextActionableTask(phases);\n\tif (activeTask) {\n\t\tconst activePhase = phases.find((phase) => phase.tasks.includes(activeTask));\n\t\tif (activePhase) touched.add(activePhase.name);\n\t}\n\tfor (const transition of completedTasks) touched.add(transition.phase);\n\t// Exhaustive over TodoOperation | undefined so adding an operation is a typecheck\n\t// failure here rather than a silent fall-through into target-scoped highlighting.\n\tswitch (operation) {\n\t\tcase \"init\":\n\t\t\tfor (const phase of phases) touched.add(phase.name);\n\t\t\tbreak;\n\t\tcase \"start\":\n\t\tcase \"done\":\n\t\tcase \"drop\":\n\t\tcase \"rm\":\n\t\tcase \"append\":\n\t\tcase \"view\":\n\t\tcase undefined: {\n\t\t\tif (args.phase) {\n\t\t\t\tconst phase = phases.find((candidate) => candidate.name === args.phase);\n\t\t\t\tif (phase) touched.add(phase.name);\n\t\t\t}\n\t\t\tif (args.task) {\n\t\t\t\tconst hit = findTaskByContent([...phases], args.task);\n\t\t\t\tif (hit) touched.add(hit.phase.name);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tdefault: {\n\t\t\tconst _exhaustive: never = operation;\n\t\t\treturn touched.size > 0 ? touched : null;\n\t\t}\n\t}\n\treturn touched.size > 0 ? touched : null;\n}\n\nconst EMPTY_SET: ReadonlySet<string> = new Set();\n\nfunction renderTodoPhases(\n\tphases: readonly TodoPhase[],\n\tcompletedTasks: readonly TodoCompletionTransition[],\n\toptions: ToolRenderResultOptions,\n\targs: TodoParams,\n\toperation: TodoOperation | undefined,\n\ttheme: Theme,\n\tframe: number | undefined,\n): string {\n\tconst visiblePhases = phases.filter((phase) => phase.tasks.length > 0);\n\tif (visiblePhases.length === 0) return \"\";\n\n\tconst touched =\n\t\toptions.expanded || visiblePhases.length === 1\n\t\t\t? null\n\t\t\t: computeTouchedPhases(args, operation, visiblePhases, completedTasks);\n\tconst completionKeysByPhase = new Map<string, Set<string>>();\n\tfor (const transition of completedTasks) {\n\t\tlet completionKeys = completionKeysByPhase.get(transition.phase);\n\t\tif (!completionKeys) {\n\t\t\tcompletionKeys = new Set();\n\t\t\tcompletionKeysByPhase.set(transition.phase, completionKeys);\n\t\t}\n\t\tcompletionKeys.add(transition.content);\n\t}\n\tconst lines: string[] = [];\n\tfor (let index = 0; index < visiblePhases.length; index += 1) {\n\t\tconst phase = visiblePhases[index];\n\t\tconst oneBasedIndex = index + 1;\n\t\tif (touched && !touched.has(phase.name)) {\n\t\t\tlines.push(formatPhaseSummary(phase, oneBasedIndex, theme));\n\t\t\tcontinue;\n\t\t}\n\t\tlines.push(formatPhaseHeader(phase.name, oneBasedIndex, theme));\n\t\tconst completionKeys = completionKeysByPhase.get(phase.name) ?? EMPTY_SET;\n\t\tfor (const task of phase.tasks) lines.push(` ${formatTaskLine(task, theme, completionKeys, frame)}`);\n\t}\n\treturn lines.join(\"\\n\");\n}\n\nfunction getTextContent(result: AgentToolResult<TodoToolDetails>): string {\n\treturn result.content\n\t\t.filter(\n\t\t\t(content): content is { type: \"text\"; text: string } =>\n\t\t\t\tcontent.type === \"text\" && typeof content.text === \"string\",\n\t\t)\n\t\t.map((content) => content.text)\n\t\t.join(\"\\n\");\n}\n\nexport function registerTodoTool(pi: ExtensionAPI, accessors: TodoAccessors): void {\n\tconst tool: ToolDefinition<typeof TODO_PARAMS_SCHEMA, TodoToolDetails, unknown> = {\n\t\tname: \"todo\",\n\t\tlabel: \"Todo\",\n\t\tdescription: TODO_TOOL_DESCRIPTION,\n\t\tpromptSnippet: \"Track phased tasks with one op-based todo tool; reference tasks by their exact content.\",\n\t\tpromptGuidelines: [\n\t\t\t\"Use one todo operation at a time; batch it with the real work rather than making a solo todo turn.\",\n\t\t\t\"Reference tasks and phases by their exact content/name; use view when the text is uncertain.\",\n\t\t\t\"Mark work done immediately and use drop for tasks that are no longer needed.\",\n\t\t],\n\t\tparameters: TODO_PARAMS_SCHEMA,\n\t\texecutionMode: \"sequential\",\n\t\tasync execute(_toolCallId, params, _signal, _onUpdate, ctx): Promise<AgentToolResult<TodoToolDetails>> {\n\t\t\tconst previousPhases = clonePhases(accessors.getCurrentPhases());\n\t\t\tconst normalized = normalizeTodoParams(params as Record<string, unknown>, previousPhases);\n\t\t\tif (normalized.error || !normalized.entry) {\n\t\t\t\tconst error =\n\t\t\t\t\tnormalized.error ?? 'Missing \"op\". Example: {\"op\":\"init\",\"list\":[{\"phase\":\"Setup\",\"items\":[\"...\"]}]}';\n\t\t\t\tthrow new Error(`${error}\\n\\n${formatSummary(previousPhases, [], true)}`);\n\t\t\t}\n\t\t\tconst entry = normalized.entry;\n\t\t\tconst corrections = normalized.corrections;\n\t\t\tconst readOnly = entry.op === \"view\";\n\t\t\tconst applied = readOnly\n\t\t\t\t? { phases: previousPhases, errors: [] as string[] }\n\t\t\t\t: applyParams(clonePhases(previousPhases), entry, corrections);\n\t\t\tif (applied.errors.length > 0) throw new Error(formatSummary(previousPhases, applied.errors, readOnly));\n\t\t\tconst completedTasks = readOnly ? [] : getCompletionTransitions(previousPhases, applied.phases);\n\t\t\tif (!readOnly) {\n\t\t\t\tpi.appendEntry(TODO_STATE_ENTRY_TYPE, {\n\t\t\t\t\tschema: \"v2\",\n\t\t\t\t\tphases: clonePhases(applied.phases),\n\t\t\t\t} satisfies TodoStateEntry);\n\t\t\t\taccessors.setCurrentPhases(clonePhases(applied.phases));\n\t\t\t\taccessors.syncWidget(ctx);\n\t\t\t}\n\n\t\t\tconst details: TodoToolDetails = {\n\t\t\t\top: entry.op,\n\t\t\t\tphases: clonePhases(applied.phases),\n\t\t\t\tstorage: ctx.sessionManager.getSessionFile() ? \"session\" : \"memory\",\n\t\t\t};\n\t\t\tif (corrections.length > 0) details.corrections = corrections;\n\t\t\tif (completedTasks.length > 0) details.completedTasks = completedTasks;\n\t\t\tconst summary = formatSummary(applied.phases, [], readOnly);\n\t\t\tconst text = corrections.length > 0 ? `${corrections.join(\"\\n\")}\\n\\n${summary}` : summary;\n\n\t\t\treturn { content: [{ type: \"text\", text }], details };\n\t\t},\n\t\trenderCall(args, theme) {\n\t\t\treturn new Text(theme.fg(\"toolTitle\", theme.bold(renderCallLabel(args))), 0, 0);\n\t\t},\n\t\trenderResult(result, options, theme, context: ToolRenderContext<unknown, TodoParams>) {\n\t\t\tif (context.isError) {\n\t\t\t\treturn new Text(theme.fg(\"toolOutput\", getTextContent(result)), 0, 0);\n\t\t\t}\n\t\t\tconst phases = result.details?.phases ?? [];\n\t\t\tconst rendered = renderTodoPhases(\n\t\t\t\tphases,\n\t\t\t\tresult.details?.completedTasks ?? [],\n\t\t\t\toptions,\n\t\t\t\tcontext.args,\n\t\t\t\tresult.details?.op,\n\t\t\t\ttheme,\n\t\t\t\tcontext.spinnerFrame,\n\t\t\t);\n\t\t\tconst text = rendered || getTextContent(result) || \"Todo list is empty.\";\n\t\t\treturn new Text(text, 0, 0);\n\t\t},\n\t};\n\n\tpi.registerTool(tool);\n}\n"]}
1
+ {"version":3,"file":"todo.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/todotools/tools/todo.ts"],"names":[],"mappings":"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","sourcesContent":["// Ported and adapted from oh-my-pi's todo tool (MIT License).\n// Copyright (c) 2025 Mario Zechner\n// Copyright (c) 2025-2026 Can Bölük\n// https://github.com/can1357/oh-my-pi\n\nimport { Text } from \"@earendil-works/pi-tui\";\nimport { type Static, Type } from \"typebox\";\nimport { partialStrikethrough, strikeRevealCount } from \"../../../../../modes/interactive/components/todo-strike.ts\";\nimport type { Theme } from \"../../../../../modes/interactive/theme/theme.ts\";\nimport type {\n\tAgentToolResult,\n\tExtensionAPI,\n\tExtensionContext,\n\tToolDefinition,\n\tToolRenderContext,\n\tToolRenderResultOptions,\n} from \"../../../types.ts\";\nimport { normalizeTodoParams } from \"../normalize.ts\";\nimport { TODO_TOOL_DESCRIPTION } from \"../prompt.ts\";\nimport {\n\tapplyParams,\n\tclonePhases,\n\tfindTaskByContent,\n\tformatSummary,\n\tgetCompletionTransitions,\n\tgetTodoMarker,\n\tnextActionableTask,\n\tsanitizeTodoText,\n\tTODO_STATE_ENTRY_TYPE,\n\ttype TodoCompletionTransition,\n\ttype TodoOperation,\n\ttype TodoPhase,\n\ttype TodoStateEntry,\n\ttype TodoToolDetails,\n} from \"../state.ts\";\n\nconst TodoOperationSchema = Type.Union(\n\t[\n\t\tType.Literal(\"init\"),\n\t\tType.Literal(\"start\"),\n\t\tType.Literal(\"done\"),\n\t\tType.Literal(\"rm\"),\n\t\tType.Literal(\"drop\"),\n\t\tType.Literal(\"append\"),\n\t\tType.Literal(\"view\"),\n\t],\n\t{ description: \"Operation to perform. Required — always pass it explicitly.\" },\n);\n\nconst TodoPhaseInputSchema = Type.Object({\n\tphase: Type.String({ description: \"Phase name\" }),\n\titems: Type.Array(Type.String({ description: \"Task content\" }), {\n\t\tdescription: \"Tasks for this phase\",\n\t\tminItems: 1,\n\t}),\n});\n\nexport const TODO_PARAMS_SCHEMA = Type.Object({\n\top: Type.Optional(TodoOperationSchema),\n\tlist: Type.Optional(Type.Array(TodoPhaseInputSchema, { description: \"Phased task list for init\" })),\n\ttask: Type.Optional(Type.String({ description: \"Exact task text copied from the previous todo result\" })),\n\tphase: Type.Optional(Type.String({ description: \"Exact phase name copied from the previous todo result\" })),\n\t// Keep this unconstrained at the schema boundary. init and append return\n\t// operation-specific errors, while unrelated operations may ignore it.\n\titems: Type.Optional(\n\t\tType.Array(Type.String({ description: \"Task content\" }), { description: \"Task texts to append\" }),\n\t),\n});\n\ntype TodoParams = Static<typeof TODO_PARAMS_SCHEMA>;\n\ntype TodoAccessors = {\n\tgetCurrentPhases: () => TodoPhase[];\n\tsetCurrentPhases: (phases: TodoPhase[]) => void;\n\tsyncWidget: (ctx: ExtensionContext, completedTasks?: readonly TodoCompletionTransition[]) => void;\n};\n\nfunction countInitItems(params: TodoParams): { phases: number; tasks: number } {\n\tif (params.list) {\n\t\treturn {\n\t\t\tphases: params.list.length,\n\t\t\ttasks: params.list.reduce((total, phase) => total + phase.items.length, 0),\n\t\t};\n\t}\n\tif (params.items) return { phases: params.items.length > 0 ? 1 : 0, tasks: params.items.length };\n\treturn { phases: 0, tasks: 0 };\n}\n\nfunction countLabel(count: number, singular: string): string {\n\treturn `${count} ${singular}${count === 1 ? \"\" : \"s\"}`;\n}\n\nfunction renderCallLabel(params: TodoParams): string {\n\tswitch (params.op) {\n\t\tcase \"init\": {\n\t\t\tconst counts = countInitItems(params);\n\t\t\treturn `todo init (${countLabel(counts.phases, \"phase\")}, ${countLabel(counts.tasks, \"task\")})`;\n\t\t}\n\t\tcase \"append\":\n\t\t\treturn `todo append: ${sanitizeTodoText(params.phase ?? \"\") || \"(missing phase)\"} (${countLabel(\n\t\t\t\tparams.items?.length ?? 0,\n\t\t\t\t\"item\",\n\t\t\t)})`;\n\t\tcase \"start\":\n\t\tcase \"done\":\n\t\tcase \"drop\":\n\t\t\treturn `todo ${params.op}: ${sanitizeTodoText(params.task ?? params.phase ?? \"\") || \"(missing target)\"}`;\n\t\tcase \"rm\":\n\t\t\treturn `todo rm: ${sanitizeTodoText(params.task ?? params.phase ?? \"all\") || \"all\"}`;\n\t\tcase \"view\":\n\t\t\treturn \"todo view\";\n\t\t// Normalization can rescue a call that omitted `op`; label it generically until\n\t\t// execute resolves the effective operation. Listing `undefined` explicitly (instead\n\t\t// of `default`) keeps this switch exhaustive, so a new TodoOperation fails typecheck.\n\t\tcase undefined:\n\t\t\treturn \"todo\";\n\t}\n}\n\nexport function phaseRomanNumeral(oneBasedIndex: number): string {\n\tif (oneBasedIndex <= 0) return \"\";\n\tconst pairs: ReadonlyArray<readonly [number, string]> = [\n\t\t[1000, \"M\"],\n\t\t[900, \"CM\"],\n\t\t[500, \"D\"],\n\t\t[400, \"CD\"],\n\t\t[100, \"C\"],\n\t\t[90, \"XC\"],\n\t\t[50, \"L\"],\n\t\t[40, \"XL\"],\n\t\t[10, \"X\"],\n\t\t[9, \"IX\"],\n\t\t[5, \"V\"],\n\t\t[4, \"IV\"],\n\t\t[1, \"I\"],\n\t];\n\tlet remaining = oneBasedIndex;\n\tlet output = \"\";\n\tfor (const [value, symbol] of pairs) {\n\t\twhile (remaining >= value) {\n\t\t\toutput += symbol;\n\t\t\tremaining -= value;\n\t\t}\n\t}\n\treturn output;\n}\n\nfunction formatPhaseHeader(name: string, index: number, theme: Theme): string {\n\treturn theme.fg(\"accent\", theme.bold(`${phaseRomanNumeral(index)}. ${sanitizeTodoText(name)}`));\n}\n\nfunction formatPhaseSummary(phase: TodoPhase, index: number, theme: Theme): string {\n\tconst closed = phase.tasks.filter((task) => task.status === \"completed\" || task.status === \"abandoned\").length;\n\treturn theme.fg(\n\t\t\"dim\",\n\t\t`${phaseRomanNumeral(index)}. ${sanitizeTodoText(phase.name)} — ${closed}/${phase.tasks.length} done`,\n\t);\n}\n\nfunction formatTaskLine(\n\ttask: TodoPhase[\"tasks\"][number],\n\ttheme: Theme,\n\tcompletionKeys: ReadonlySet<string>,\n\tframe: number | undefined,\n): string {\n\tconst content = sanitizeTodoText(task.content);\n\tconst line = `${getTodoMarker(task.status)} ${content}`;\n\tswitch (task.status) {\n\t\tcase \"completed\": {\n\t\t\tconst reveal = completionKeys.has(task.content) ? strikeRevealCount(line, frame) : undefined;\n\t\t\treturn reveal === undefined\n\t\t\t\t? theme.fg(\"dim\", theme.strikethrough(line))\n\t\t\t\t: theme.fg(\n\t\t\t\t\t\t\"dim\",\n\t\t\t\t\t\tpartialStrikethrough(line, reveal, (text) => theme.strikethrough(text)),\n\t\t\t\t\t);\n\t\t}\n\t\tcase \"in_progress\":\n\t\t\treturn theme.fg(\"accent\", theme.bold(line));\n\t\tcase \"abandoned\":\n\t\t\treturn theme.fg(\"dim\", line);\n\t\tcase \"pending\":\n\t\t\treturn line;\n\t}\n}\n\nfunction computeTouchedPhases(\n\targs: TodoParams,\n\toperation: TodoOperation | undefined,\n\tphases: readonly TodoPhase[],\n\tcompletedTasks: readonly TodoCompletionTransition[],\n): Set<string> | null {\n\tconst touched = new Set<string>();\n\tconst activeTask = nextActionableTask(phases);\n\tif (activeTask) {\n\t\tconst activePhase = phases.find((phase) => phase.tasks.includes(activeTask));\n\t\tif (activePhase) touched.add(activePhase.name);\n\t}\n\tfor (const transition of completedTasks) touched.add(transition.phase);\n\t// Exhaustive over TodoOperation | undefined so adding an operation is a typecheck\n\t// failure here rather than a silent fall-through into target-scoped highlighting.\n\tswitch (operation) {\n\t\tcase \"init\":\n\t\t\tfor (const phase of phases) touched.add(phase.name);\n\t\t\tbreak;\n\t\tcase \"start\":\n\t\tcase \"done\":\n\t\tcase \"drop\":\n\t\tcase \"rm\":\n\t\tcase \"append\":\n\t\tcase \"view\":\n\t\tcase undefined: {\n\t\t\tif (args.phase) {\n\t\t\t\tconst phase = phases.find((candidate) => candidate.name === args.phase);\n\t\t\t\tif (phase) touched.add(phase.name);\n\t\t\t}\n\t\t\tif (args.task) {\n\t\t\t\tconst hit = findTaskByContent([...phases], args.task);\n\t\t\t\tif (hit) touched.add(hit.phase.name);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\t\tdefault: {\n\t\t\tconst _exhaustive: never = operation;\n\t\t\treturn touched.size > 0 ? touched : null;\n\t\t}\n\t}\n\treturn touched.size > 0 ? touched : null;\n}\n\nconst EMPTY_SET: ReadonlySet<string> = new Set();\n\nfunction renderTodoPhases(\n\tphases: readonly TodoPhase[],\n\tcompletedTasks: readonly TodoCompletionTransition[],\n\toptions: ToolRenderResultOptions,\n\targs: TodoParams,\n\toperation: TodoOperation | undefined,\n\ttheme: Theme,\n\tframe: number | undefined,\n): string {\n\tconst visiblePhases = phases.filter((phase) => phase.tasks.length > 0);\n\tif (visiblePhases.length === 0) return \"\";\n\n\tconst touched =\n\t\toptions.expanded || visiblePhases.length === 1\n\t\t\t? null\n\t\t\t: computeTouchedPhases(args, operation, visiblePhases, completedTasks);\n\tconst completionKeysByPhase = new Map<string, Set<string>>();\n\tfor (const transition of completedTasks) {\n\t\tlet completionKeys = completionKeysByPhase.get(transition.phase);\n\t\tif (!completionKeys) {\n\t\t\tcompletionKeys = new Set();\n\t\t\tcompletionKeysByPhase.set(transition.phase, completionKeys);\n\t\t}\n\t\tcompletionKeys.add(transition.content);\n\t}\n\tconst lines: string[] = [];\n\tfor (let index = 0; index < visiblePhases.length; index += 1) {\n\t\tconst phase = visiblePhases[index];\n\t\tconst oneBasedIndex = index + 1;\n\t\tif (touched && !touched.has(phase.name)) {\n\t\t\tlines.push(formatPhaseSummary(phase, oneBasedIndex, theme));\n\t\t\tcontinue;\n\t\t}\n\t\tlines.push(formatPhaseHeader(phase.name, oneBasedIndex, theme));\n\t\tconst completionKeys = completionKeysByPhase.get(phase.name) ?? EMPTY_SET;\n\t\tfor (const task of phase.tasks) lines.push(` ${formatTaskLine(task, theme, completionKeys, frame)}`);\n\t}\n\treturn lines.join(\"\\n\");\n}\n\nfunction getTextContent(result: AgentToolResult<TodoToolDetails>): string {\n\treturn result.content\n\t\t.filter(\n\t\t\t(content): content is { type: \"text\"; text: string } =>\n\t\t\t\tcontent.type === \"text\" && typeof content.text === \"string\",\n\t\t)\n\t\t.map((content) => content.text)\n\t\t.join(\"\\n\");\n}\n\nexport function registerTodoTool(pi: ExtensionAPI, accessors: TodoAccessors): void {\n\tconst tool: ToolDefinition<typeof TODO_PARAMS_SCHEMA, TodoToolDetails, unknown> = {\n\t\tname: \"todo\",\n\t\tlabel: \"Todo\",\n\t\tdescription: TODO_TOOL_DESCRIPTION,\n\t\tpromptSnippet: \"Track phased tasks with one op-based todo tool; reference tasks by their exact content.\",\n\t\tpromptGuidelines: [\n\t\t\t\"Use one todo operation at a time; batch it with the real work rather than making a solo todo turn.\",\n\t\t\t\"Reference tasks and phases by their exact content/name; use view when the text is uncertain.\",\n\t\t\t\"Mark work done immediately and use drop for tasks that are no longer needed.\",\n\t\t],\n\t\tparameters: TODO_PARAMS_SCHEMA,\n\t\texecutionMode: \"sequential\",\n\t\tasync execute(_toolCallId, params, _signal, _onUpdate, ctx): Promise<AgentToolResult<TodoToolDetails>> {\n\t\t\tconst previousPhases = clonePhases(accessors.getCurrentPhases());\n\t\t\tconst normalized = normalizeTodoParams(params as Record<string, unknown>, previousPhases);\n\t\t\tif (normalized.error || !normalized.entry) {\n\t\t\t\tconst error =\n\t\t\t\t\tnormalized.error ?? 'Missing \"op\". Example: {\"op\":\"init\",\"list\":[{\"phase\":\"Setup\",\"items\":[\"...\"]}]}';\n\t\t\t\tthrow new Error(`${error}\\n\\n${formatSummary(previousPhases, [], true)}`);\n\t\t\t}\n\t\t\tconst entry = normalized.entry;\n\t\t\tconst corrections = normalized.corrections;\n\t\t\tconst readOnly = entry.op === \"view\";\n\t\t\tconst applied = readOnly\n\t\t\t\t? { phases: previousPhases, errors: [] as string[] }\n\t\t\t\t: applyParams(clonePhases(previousPhases), entry, corrections);\n\t\t\tif (applied.errors.length > 0) throw new Error(formatSummary(previousPhases, applied.errors, readOnly));\n\t\t\tconst completedTasks = readOnly ? [] : getCompletionTransitions(previousPhases, applied.phases);\n\t\t\tif (!readOnly) {\n\t\t\t\tpi.appendEntry(TODO_STATE_ENTRY_TYPE, {\n\t\t\t\t\tschema: \"v2\",\n\t\t\t\t\tphases: clonePhases(applied.phases),\n\t\t\t\t} satisfies TodoStateEntry);\n\t\t\t\taccessors.setCurrentPhases(clonePhases(applied.phases));\n\t\t\t\taccessors.syncWidget(ctx, completedTasks);\n\t\t\t}\n\n\t\t\tconst details: TodoToolDetails = {\n\t\t\t\top: entry.op,\n\t\t\t\tphases: clonePhases(applied.phases),\n\t\t\t\tstorage: ctx.sessionManager.getSessionFile() ? \"session\" : \"memory\",\n\t\t\t};\n\t\t\tif (corrections.length > 0) details.corrections = corrections;\n\t\t\tif (completedTasks.length > 0) details.completedTasks = completedTasks;\n\t\t\tconst summary = formatSummary(applied.phases, [], readOnly);\n\t\t\tconst text = corrections.length > 0 ? `${corrections.join(\"\\n\")}\\n\\n${summary}` : summary;\n\n\t\t\treturn { content: [{ type: \"text\", text }], details };\n\t\t},\n\t\trenderCall(args, theme) {\n\t\t\treturn new Text(theme.fg(\"toolTitle\", theme.bold(renderCallLabel(args))), 0, 0);\n\t\t},\n\t\trenderResult(result, options, theme, context: ToolRenderContext<unknown, TodoParams>) {\n\t\t\tif (context.isError) {\n\t\t\t\treturn new Text(theme.fg(\"toolOutput\", getTextContent(result)), 0, 0);\n\t\t\t}\n\t\t\tconst phases = result.details?.phases ?? [];\n\t\t\tconst rendered = renderTodoPhases(\n\t\t\t\tphases,\n\t\t\t\tresult.details?.completedTasks ?? [],\n\t\t\t\toptions,\n\t\t\t\tcontext.args,\n\t\t\t\tresult.details?.op,\n\t\t\t\ttheme,\n\t\t\t\tcontext.spinnerFrame,\n\t\t\t);\n\t\t\tconst text = rendered || getTextContent(result) || \"Todo list is empty.\";\n\t\t\treturn new Text(text, 0, 0);\n\t\t},\n\t};\n\n\tpi.registerTool(tool);\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"tps.d.ts","sourceRoot":"","sources":["../../../../src/core/extensions/builtin/tps.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAmBhD,MAAM,CAAC,OAAO,WAAW,EAAE,EAAE,YAAY,QAgExC"}
1
+ {"version":3,"file":"tps.d.ts","sourceRoot":"","sources":["../../../../src/core/extensions/builtin/tps.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAmBhD,MAAM,CAAC,OAAO,WAAW,EAAE,EAAE,YAAY,QAmExC"}
@@ -10,7 +10,10 @@ export default function (pi) {
10
10
  const finishActiveAssistantTiming = () => {
11
11
  if (activeAssistantStartMs === null)
12
12
  return;
13
- const elapsedMs = Date.now() - activeAssistantStartMs;
13
+ // Use the monotonic clock so a wall-clock jump backward (NTP skew or
14
+ // manual time change) between message_start and message_end cannot
15
+ // produce a non-positive interval that suppresses a valid TPS notice.
16
+ const elapsedMs = performance.now() - activeAssistantStartMs;
14
17
  if (elapsedMs > 0) {
15
18
  assistantElapsedMs += elapsedMs;
16
19
  }
@@ -24,7 +27,7 @@ export default function (pi) {
24
27
  if (!isAssistantMessage(event.message))
25
28
  return;
26
29
  finishActiveAssistantTiming();
27
- activeAssistantStartMs = Date.now();
30
+ activeAssistantStartMs = performance.now();
28
31
  });
29
32
  pi.on("message_end", (event) => {
30
33
  if (!isAssistantMessage(event.message))
@@ -1 +1 @@
1
- {"version":3,"file":"tps.js","sourceRoot":"","sources":["../../../../src/core/extensions/builtin/tps.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ExtensionAPI } from \"../types.ts\";\n\ntype AssistantMessageLike = {\n\trole: \"assistant\";\n\tusage?: {\n\t\tinput?: number;\n\t\toutput?: number;\n\t\tcacheRead?: number;\n\t\tcacheWrite?: number;\n\t\ttotalTokens?: number;\n\t};\n};\n\nfunction isAssistantMessage(message: unknown): message is AssistantMessageLike {\n\tif (!message || typeof message !== \"object\") return false;\n\tconst role = (message as { role?: unknown }).role;\n\treturn role === \"assistant\";\n}\n\nexport default function (pi: ExtensionAPI) {\n\tlet activeAssistantStartMs: number | null = null;\n\tlet assistantElapsedMs = 0;\n\n\tconst finishActiveAssistantTiming = () => {\n\t\tif (activeAssistantStartMs === null) return;\n\n\t\tconst elapsedMs = Date.now() - activeAssistantStartMs;\n\t\tif (elapsedMs > 0) {\n\t\t\tassistantElapsedMs += elapsedMs;\n\t\t}\n\t\tactiveAssistantStartMs = null;\n\t};\n\n\tpi.on(\"agent_start\", () => {\n\t\tactiveAssistantStartMs = null;\n\t\tassistantElapsedMs = 0;\n\t});\n\n\tpi.on(\"message_start\", (event) => {\n\t\tif (!isAssistantMessage(event.message)) return;\n\n\t\tfinishActiveAssistantTiming();\n\t\tactiveAssistantStartMs = Date.now();\n\t});\n\n\tpi.on(\"message_end\", (event) => {\n\t\tif (!isAssistantMessage(event.message)) return;\n\n\t\tfinishActiveAssistantTiming();\n\t});\n\n\tpi.on(\"agent_end\", (event, ctx) => {\n\t\tfinishActiveAssistantTiming();\n\n\t\tconst elapsedMs = assistantElapsedMs;\n\t\tactiveAssistantStartMs = null;\n\t\tassistantElapsedMs = 0;\n\n\t\tif (!ctx.hasUI) return;\n\t\tif (elapsedMs <= 0) return;\n\n\t\tlet input = 0;\n\t\tlet output = 0;\n\t\tlet cacheRead = 0;\n\t\tlet cacheWrite = 0;\n\t\tlet totalTokens = 0;\n\n\t\tfor (const message of event.messages) {\n\t\t\tif (!isAssistantMessage(message)) continue;\n\t\t\tinput += message.usage?.input ?? 0;\n\t\t\toutput += message.usage?.output ?? 0;\n\t\t\tcacheRead += message.usage?.cacheRead ?? 0;\n\t\t\tcacheWrite += message.usage?.cacheWrite ?? 0;\n\t\t\ttotalTokens += message.usage?.totalTokens ?? 0;\n\t\t}\n\n\t\tif (output <= 0) return;\n\n\t\tconst elapsedSeconds = elapsedMs / 1000;\n\t\tconst tokensPerSecond = output / elapsedSeconds;\n\t\tconst message = `TPS ${tokensPerSecond.toFixed(1)} tok/s. out ${output.toLocaleString()}, in ${input.toLocaleString()}, cache r/w ${cacheRead.toLocaleString()}/${cacheWrite.toLocaleString()}, total ${totalTokens.toLocaleString()}, ${elapsedSeconds.toFixed(1)}s`;\n\t\tctx.ui.notify(message, \"info\");\n\t});\n}\n"]}
1
+ {"version":3,"file":"tps.js","sourceRoot":"","sources":["../../../../src/core/extensions/builtin/tps.ts"],"names":[],"mappings":"AAaA,SAAS,kBAAkB,CAAC,OAAgB;IAC3C,IAAI,CAAC,OAAO,IAAI,OAAO,OAAO,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC1D,MAAM,IAAI,GAAI,OAA8B,CAAC,IAAI,CAAC;IAClD,OAAO,IAAI,KAAK,WAAW,CAAC;AAC7B,CAAC;AAED,MAAM,CAAC,OAAO,WAAW,EAAgB;IACxC,IAAI,sBAAsB,GAAkB,IAAI,CAAC;IACjD,IAAI,kBAAkB,GAAG,CAAC,CAAC;IAE3B,MAAM,2BAA2B,GAAG,GAAG,EAAE;QACxC,IAAI,sBAAsB,KAAK,IAAI;YAAE,OAAO;QAE5C,qEAAqE;QACrE,mEAAmE;QACnE,sEAAsE;QACtE,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,EAAE,GAAG,sBAAsB,CAAC;QAC7D,IAAI,SAAS,GAAG,CAAC,EAAE,CAAC;YACnB,kBAAkB,IAAI,SAAS,CAAC;QACjC,CAAC;QACD,sBAAsB,GAAG,IAAI,CAAC;IAC/B,CAAC,CAAC;IAEF,EAAE,CAAC,EAAE,CAAC,aAAa,EAAE,GAAG,EAAE;QACzB,sBAAsB,GAAG,IAAI,CAAC;QAC9B,kBAAkB,GAAG,CAAC,CAAC;IACxB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,EAAE,CAAC,eAAe,EAAE,CAAC,KAAK,EAAE,EAAE;QAChC,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,OAAO,CAAC;YAAE,OAAO;QAE/C,2BAA2B,EAAE,CAAC;QAC9B,sBAAsB,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,EAAE,CAAC,aAAa,EAAE,CAAC,KAAK,EAAE,EAAE;QAC9B,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,OAAO,CAAC;YAAE,OAAO;QAE/C,2BAA2B,EAAE,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,EAAE,GAAG,EAAE,EAAE;QACjC,2BAA2B,EAAE,CAAC;QAE9B,MAAM,SAAS,GAAG,kBAAkB,CAAC;QACrC,sBAAsB,GAAG,IAAI,CAAC;QAC9B,kBAAkB,GAAG,CAAC,CAAC;QAEvB,IAAI,CAAC,GAAG,CAAC,KAAK;YAAE,OAAO;QACvB,IAAI,SAAS,IAAI,CAAC;YAAE,OAAO;QAE3B,IAAI,KAAK,GAAG,CAAC,CAAC;QACd,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,IAAI,SAAS,GAAG,CAAC,CAAC;QAClB,IAAI,UAAU,GAAG,CAAC,CAAC;QACnB,IAAI,WAAW,GAAG,CAAC,CAAC;QAEpB,KAAK,MAAM,OAAO,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;YACtC,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC;gBAAE,SAAS;YAC3C,KAAK,IAAI,OAAO,CAAC,KAAK,EAAE,KAAK,IAAI,CAAC,CAAC;YACnC,MAAM,IAAI,OAAO,CAAC,KAAK,EAAE,MAAM,IAAI,CAAC,CAAC;YACrC,SAAS,IAAI,OAAO,CAAC,KAAK,EAAE,SAAS,IAAI,CAAC,CAAC;YAC3C,UAAU,IAAI,OAAO,CAAC,KAAK,EAAE,UAAU,IAAI,CAAC,CAAC;YAC7C,WAAW,IAAI,OAAO,CAAC,KAAK,EAAE,WAAW,IAAI,CAAC,CAAC;QAChD,CAAC;QAED,IAAI,MAAM,IAAI,CAAC;YAAE,OAAO;QAExB,MAAM,cAAc,GAAG,SAAS,GAAG,IAAI,CAAC;QACxC,MAAM,eAAe,GAAG,MAAM,GAAG,cAAc,CAAC;QAChD,MAAM,OAAO,GAAG,OAAO,eAAe,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,MAAM,CAAC,cAAc,EAAE,QAAQ,KAAK,CAAC,cAAc,EAAE,eAAe,SAAS,CAAC,cAAc,EAAE,IAAI,UAAU,CAAC,cAAc,EAAE,WAAW,WAAW,CAAC,cAAc,EAAE,KAAK,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC;QACtQ,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAChC,CAAC,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import type { ExtensionAPI } from \"../types.ts\";\n\ntype AssistantMessageLike = {\n\trole: \"assistant\";\n\tusage?: {\n\t\tinput?: number;\n\t\toutput?: number;\n\t\tcacheRead?: number;\n\t\tcacheWrite?: number;\n\t\ttotalTokens?: number;\n\t};\n};\n\nfunction isAssistantMessage(message: unknown): message is AssistantMessageLike {\n\tif (!message || typeof message !== \"object\") return false;\n\tconst role = (message as { role?: unknown }).role;\n\treturn role === \"assistant\";\n}\n\nexport default function (pi: ExtensionAPI) {\n\tlet activeAssistantStartMs: number | null = null;\n\tlet assistantElapsedMs = 0;\n\n\tconst finishActiveAssistantTiming = () => {\n\t\tif (activeAssistantStartMs === null) return;\n\n\t\t// Use the monotonic clock so a wall-clock jump backward (NTP skew or\n\t\t// manual time change) between message_start and message_end cannot\n\t\t// produce a non-positive interval that suppresses a valid TPS notice.\n\t\tconst elapsedMs = performance.now() - activeAssistantStartMs;\n\t\tif (elapsedMs > 0) {\n\t\t\tassistantElapsedMs += elapsedMs;\n\t\t}\n\t\tactiveAssistantStartMs = null;\n\t};\n\n\tpi.on(\"agent_start\", () => {\n\t\tactiveAssistantStartMs = null;\n\t\tassistantElapsedMs = 0;\n\t});\n\n\tpi.on(\"message_start\", (event) => {\n\t\tif (!isAssistantMessage(event.message)) return;\n\n\t\tfinishActiveAssistantTiming();\n\t\tactiveAssistantStartMs = performance.now();\n\t});\n\n\tpi.on(\"message_end\", (event) => {\n\t\tif (!isAssistantMessage(event.message)) return;\n\n\t\tfinishActiveAssistantTiming();\n\t});\n\n\tpi.on(\"agent_end\", (event, ctx) => {\n\t\tfinishActiveAssistantTiming();\n\n\t\tconst elapsedMs = assistantElapsedMs;\n\t\tactiveAssistantStartMs = null;\n\t\tassistantElapsedMs = 0;\n\n\t\tif (!ctx.hasUI) return;\n\t\tif (elapsedMs <= 0) return;\n\n\t\tlet input = 0;\n\t\tlet output = 0;\n\t\tlet cacheRead = 0;\n\t\tlet cacheWrite = 0;\n\t\tlet totalTokens = 0;\n\n\t\tfor (const message of event.messages) {\n\t\t\tif (!isAssistantMessage(message)) continue;\n\t\t\tinput += message.usage?.input ?? 0;\n\t\t\toutput += message.usage?.output ?? 0;\n\t\t\tcacheRead += message.usage?.cacheRead ?? 0;\n\t\t\tcacheWrite += message.usage?.cacheWrite ?? 0;\n\t\t\ttotalTokens += message.usage?.totalTokens ?? 0;\n\t\t}\n\n\t\tif (output <= 0) return;\n\n\t\tconst elapsedSeconds = elapsedMs / 1000;\n\t\tconst tokensPerSecond = output / elapsedSeconds;\n\t\tconst message = `TPS ${tokensPerSecond.toFixed(1)} tok/s. out ${output.toLocaleString()}, in ${input.toLocaleString()}, cache r/w ${cacheRead.toLocaleString()}/${cacheWrite.toLocaleString()}, total ${totalTokens.toLocaleString()}, ${elapsedSeconds.toFixed(1)}s`;\n\t\tctx.ui.notify(message, \"info\");\n\t});\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/websearch/websearch/config.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAEX,gBAAgB,EAGhB,wBAAwB,EAKxB,mBAAmB,EAEnB,eAAe,EACf,MAAM,YAAY,CAAC;AA2BpB,MAAM,WAAW,iBAAiB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAgID,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,mBAAmB,GAAG,wBAAwB,CAmD5F;AAED,wBAAgB,uBAAuB,CACtC,MAAM,EAAE,eAAe,GACrB,wBAAwB,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,eAAe,CAAA;CAAE,CAiBlE;AAWD,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA0B/F"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/websearch/websearch/config.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAEX,gBAAgB,EAGhB,wBAAwB,EAKxB,mBAAmB,EAEnB,eAAe,EACf,MAAM,YAAY,CAAC;AA4BpB,MAAM,WAAW,iBAAiB;IACjC,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC;CACjB;AAgID,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,mBAAmB,GAAG,wBAAwB,CAmD5F;AAED,wBAAgB,uBAAuB,CACtC,MAAM,EAAE,eAAe,GACrB,wBAAwB,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,EAAE,eAAe,CAAA;CAAE,CAiBlE;AAWD,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CA0B/F"}
@@ -8,6 +8,7 @@ const PROVIDERS = [
8
8
  "tavily",
9
9
  "brave",
10
10
  "duckduckgo-html",
11
+ "deepseek",
11
12
  "serper",
12
13
  "google-cse",
13
14
  "z-ai",
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/websearch/websearch/config.ts"],"names":[],"mappings":"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","sourcesContent":["import { access, readFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nimport { CONFIG_DIR_NAME } from \"../../../../../config.ts\";\nimport { isAllowedProviderBaseUrl } from \"./provider-endpoints.ts\";\nimport type {\n\tCodexSearchMode,\n\tConfigLoadResult,\n\tJsonObject,\n\tJsonValue,\n\tProviderValidationResult,\n\tRoutingStrategy,\n\tSearchContextSize,\n\tSearchProvider,\n\tSearchProviderConfig,\n\tSearchProviderEntry,\n\tSearchUserLocation,\n\tWebsearchConfig,\n} from \"./types.ts\";\n\nconst PROVIDERS: readonly SearchProvider[] = [\n\t\"exa\",\n\t\"tavily\",\n\t\"brave\",\n\t\"duckduckgo-html\",\n\t\"serper\",\n\t\"google-cse\",\n\t\"z-ai\",\n\t\"openai\",\n\t\"codex\",\n\t\"anthropic\",\n\t\"perplexity\",\n\t\"xai\",\n\t\"kimi\",\n];\nconst CONTEXT_SIZES: readonly SearchContextSize[] = [\"low\", \"medium\", \"high\"];\nconst CODEX_MODES: readonly CodexSearchMode[] = [\"cached\", \"live\"];\nconst STRATEGIES: readonly RoutingStrategy[] = [\"priority\", \"round-robin\", \"fill-first\"];\nconst DEFAULT_FREE_CONFIG: WebsearchConfig = {\n\tstrategy: \"priority\",\n\tfallback: true,\n\tauto: true,\n\tproviders: [{ id: \"default\", provider: \"duckduckgo-html\", maxResults: 10 }],\n};\n\nexport interface ConfigLoadOptions {\n\tcwd: string;\n\thomeDir?: string;\n}\n\nfunction isJsonObject(value: unknown): value is JsonObject {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction oneOf<TValue extends string>(values: readonly TValue[], value: unknown): value is TValue {\n\treturn typeof value === \"string\" && (values as readonly string[]).includes(value);\n}\n\nfunction isStringArray(value: JsonValue | undefined): value is string[] {\n\treturn Array.isArray(value) && value.every((item) => typeof item === \"string\");\n}\n\nfunction optionalString(value: JsonValue | undefined): string | undefined {\n\treturn typeof value === \"string\" && value.length > 0 ? value : undefined;\n}\n\nfunction optionalNumber(value: JsonValue | undefined): number | undefined {\n\treturn typeof value === \"number\" && Number.isFinite(value) ? value : undefined;\n}\n\nfunction optionalBoolean(value: JsonValue | undefined): boolean | undefined {\n\treturn typeof value === \"boolean\" ? value : undefined;\n}\n\nfunction optionalProvider(value: JsonValue | undefined): SearchProvider | undefined {\n\treturn oneOf(PROVIDERS, value) ? value : undefined;\n}\n\nfunction optionalContextSize(value: JsonValue | undefined): SearchContextSize | undefined {\n\treturn oneOf(CONTEXT_SIZES, value) ? value : undefined;\n}\n\nfunction optionalCodexMode(value: JsonValue | undefined): CodexSearchMode | undefined {\n\treturn oneOf(CODEX_MODES, value) ? value : undefined;\n}\n\nfunction optionalStrategy(value: JsonValue | undefined): RoutingStrategy | undefined {\n\treturn oneOf(STRATEGIES, value) ? value : undefined;\n}\n\nfunction optionalLocation(value: JsonValue | undefined): SearchUserLocation | undefined {\n\tif (!isJsonObject(value)) return undefined;\n\tconst location: SearchUserLocation = {};\n\tconst country = optionalString(value.country);\n\tconst region = optionalString(value.region);\n\tconst city = optionalString(value.city);\n\tconst timezone = optionalString(value.timezone);\n\tif (country) location.country = country;\n\tif (region) location.region = region;\n\tif (city) location.city = city;\n\tif (timezone) location.timezone = timezone;\n\treturn Object.keys(location).length > 0 ? location : undefined;\n}\n\nfunction parseJsonObject(content: string): JsonObject | null {\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(content);\n\t} catch {\n\t\treturn null;\n\t}\n\treturn isJsonObject(parsed) ? parsed : null;\n}\n\nfunction providerEntryFromObject(raw: JsonObject): SearchProviderEntry | null {\n\tconst provider = optionalProvider(raw.provider) ?? optionalProvider(raw.backend);\n\tif (!provider) return null;\n\n\tconst config: SearchProviderEntry = { provider };\n\tconst id = optionalString(raw.id);\n\tconst apiKey = optionalString(raw.apiKey);\n\tconst baseUrl = optionalString(raw.baseUrl);\n\tconst searchEngineId = optionalString(raw.searchEngineId);\n\tconst maxResults = optionalNumber(raw.maxResults);\n\tconst model = optionalString(raw.model);\n\tconst codexMode = optionalCodexMode(raw.codexMode);\n\tconst searchContextSize = optionalContextSize(raw.searchContextSize);\n\tconst rawAllowedDomains = raw.allowedDomains;\n\tconst rawBlockedDomains = raw.blockedDomains;\n\tconst allowedDomains = isStringArray(rawAllowedDomains) ? rawAllowedDomains : undefined;\n\tconst blockedDomains = isStringArray(rawBlockedDomains) ? rawBlockedDomains : undefined;\n\tconst userLocation = optionalLocation(raw.userLocation);\n\tconst timeoutMs = optionalNumber(raw.timeoutMs);\n\tconst priority = optionalNumber(raw.priority);\n\tconst weight = optionalNumber(raw.weight);\n\n\tif (id) config.id = id;\n\tif (apiKey) config.apiKey = apiKey;\n\tif (baseUrl) config.baseUrl = baseUrl;\n\tif (searchEngineId) config.searchEngineId = searchEngineId;\n\tif (maxResults) config.maxResults = maxResults;\n\tif (model) config.model = model;\n\tif (codexMode) config.codexMode = codexMode;\n\tif (searchContextSize) config.searchContextSize = searchContextSize;\n\tif (allowedDomains) config.allowedDomains = allowedDomains;\n\tif (blockedDomains) config.blockedDomains = blockedDomains;\n\tif (userLocation) config.userLocation = userLocation;\n\tif (timeoutMs !== undefined) config.timeoutMs = timeoutMs;\n\tif (priority !== undefined) config.priority = priority;\n\tif (weight !== undefined) config.weight = weight;\n\n\treturn config;\n}\n\nfunction configFromObject(raw: JsonObject): WebsearchConfig | null {\n\tconst auto = optionalBoolean(raw.auto) ?? true;\n\tconst providersValue = raw.providers;\n\tconst rawProviders = Array.isArray(providersValue) ? providersValue : undefined;\n\tif (rawProviders) {\n\t\tif (optionalProvider(raw.provider)) return null;\n\t\tconst providers = rawProviders\n\t\t\t.map((value) => (isJsonObject(value) ? providerEntryFromObject(value) : null))\n\t\t\t.filter((entry): entry is SearchProviderEntry => entry !== null);\n\t\tconst strategy = optionalStrategy(raw.strategy) ?? \"priority\";\n\t\tconst fallback = optionalBoolean(raw.fallback) ?? true;\n\t\treturn { strategy, fallback, auto, providers };\n\t}\n\n\tconst provider = providerEntryFromObject(raw);\n\treturn provider ? { strategy: \"priority\", fallback: true, auto, providers: [provider] } : null;\n}\n\nfunction hasApiKey(config: SearchProviderConfig): boolean {\n\treturn typeof config.apiKey === \"string\" && config.apiKey.length > 0;\n}\n\nexport function validateProviderConfig(config: SearchProviderEntry): ProviderValidationResult {\n\tif (!PROVIDERS.includes(config.provider)) {\n\t\treturn { ok: false, reason: \"invalid_config\", message: `Unsupported provider: ${config.provider}` };\n\t}\n\n\tif (config.allowedDomains && config.blockedDomains) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\treason: \"invalid_config\",\n\t\t\tmessage: \"Provider config cannot specify both allowedDomains and blockedDomains.\",\n\t\t};\n\t}\n\n\tif (config.weight !== undefined && config.weight <= 0) {\n\t\treturn { ok: false, reason: \"invalid_config\", message: \"Provider weight must be greater than 0.\" };\n\t}\n\n\tif (config.timeoutMs !== undefined && config.timeoutMs <= 0) {\n\t\treturn { ok: false, reason: \"invalid_config\", message: \"Provider timeoutMs must be greater than 0.\" };\n\t}\n\n\tif (config.baseUrl && !isAllowedProviderBaseUrl(config.baseUrl)) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\treason: \"invalid_config\",\n\t\t\tmessage: `Provider ${config.provider} baseUrl must be a public HTTPS URL without credentials.`,\n\t\t};\n\t}\n\n\tif (config.provider === \"google-cse\" && !config.searchEngineId) {\n\t\treturn { ok: false, reason: \"missing_api_key\", message: \"Provider google-cse requires searchEngineId.\" };\n\t}\n\n\tif ((config.provider === \"codex\" || config.provider === \"openai\") && !hasApiKey(config)) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\treason: \"missing_api_key\",\n\t\t\tmessage: `Provider ${config.provider} requires apiKey for hosted Responses API search.`,\n\t\t};\n\t}\n\n\tif (\n\t\tconfig.provider !== \"codex\" &&\n\t\tconfig.provider !== \"openai\" &&\n\t\tconfig.provider !== \"duckduckgo-html\" &&\n\t\t!hasApiKey(config)\n\t) {\n\t\treturn { ok: false, reason: \"missing_api_key\", message: `Provider ${config.provider} requires apiKey.` };\n\t}\n\n\treturn { ok: true, config };\n}\n\nexport function validateWebsearchConfig(\n\tconfig: WebsearchConfig,\n): ProviderValidationResult | { ok: true; config: WebsearchConfig } {\n\tif (!STRATEGIES.includes(config.strategy)) {\n\t\treturn { ok: false, reason: \"invalid_config\", message: `Unsupported routing strategy: ${config.strategy}` };\n\t}\n\tif (typeof config.auto !== \"boolean\") {\n\t\treturn { ok: false, reason: \"invalid_config\", message: \"Websearch config auto must be a boolean.\" };\n\t}\n\tif (config.providers.length === 0) {\n\t\treturn { ok: false, reason: \"invalid_config\", message: \"Websearch config requires at least one provider.\" };\n\t}\n\n\tfor (const provider of config.providers) {\n\t\tconst validation = validateProviderConfig(provider);\n\t\tif (!validation.ok) return validation;\n\t}\n\n\treturn { ok: true, config };\n}\n\nasync function fileExists(path: string): Promise<boolean> {\n\ttry {\n\t\tawait access(path);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nexport async function loadWebsearchConfig(options: ConfigLoadOptions): Promise<ConfigLoadResult> {\n\tconst home = options.homeDir ?? homedir();\n\tconst paths = [\n\t\tjoin(options.cwd, CONFIG_DIR_NAME, \"websearch.json\"),\n\t\tjoin(options.cwd, \".pi\", \"websearch.json\"),\n\t\tjoin(home, \"websearch.json\"),\n\t\tjoin(home, CONFIG_DIR_NAME, \"websearch.json\"),\n\t\tjoin(home, \".pi\", \"websearch.json\"),\n\t].filter((path, index, all) => all.indexOf(path) === index);\n\n\tfor (const path of paths) {\n\t\tif (!(await fileExists(path))) continue;\n\t\tconst raw = parseJsonObject(await readFile(path, \"utf8\"));\n\t\tif (!raw) {\n\t\t\treturn { ok: false, reason: \"invalid_config\", message: `Invalid JSON object in ${path}`, source: path };\n\t\t}\n\t\tconst config = configFromObject(raw);\n\t\tif (!config) {\n\t\t\treturn { ok: false, reason: \"invalid_config\", message: `Invalid provider config in ${path}`, source: path };\n\t\t}\n\t\tconst validation = validateWebsearchConfig(config);\n\t\tif (!validation.ok) return { ...validation, source: path };\n\t\treturn { ok: true, config, source: path };\n\t}\n\n\treturn { ok: true, config: DEFAULT_FREE_CONFIG, source: \"default:duckduckgo-html\" };\n}\n"]}
1
+ {"version":3,"file":"config.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/websearch/websearch/config.ts"],"names":[],"mappings":"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","sourcesContent":["import { access, readFile } from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\nimport { CONFIG_DIR_NAME } from \"../../../../../config.ts\";\nimport { isAllowedProviderBaseUrl } from \"./provider-endpoints.ts\";\nimport type {\n\tCodexSearchMode,\n\tConfigLoadResult,\n\tJsonObject,\n\tJsonValue,\n\tProviderValidationResult,\n\tRoutingStrategy,\n\tSearchContextSize,\n\tSearchProvider,\n\tSearchProviderConfig,\n\tSearchProviderEntry,\n\tSearchUserLocation,\n\tWebsearchConfig,\n} from \"./types.ts\";\n\nconst PROVIDERS: readonly SearchProvider[] = [\n\t\"exa\",\n\t\"tavily\",\n\t\"brave\",\n\t\"duckduckgo-html\",\n\t\"deepseek\",\n\t\"serper\",\n\t\"google-cse\",\n\t\"z-ai\",\n\t\"openai\",\n\t\"codex\",\n\t\"anthropic\",\n\t\"perplexity\",\n\t\"xai\",\n\t\"kimi\",\n];\nconst CONTEXT_SIZES: readonly SearchContextSize[] = [\"low\", \"medium\", \"high\"];\nconst CODEX_MODES: readonly CodexSearchMode[] = [\"cached\", \"live\"];\nconst STRATEGIES: readonly RoutingStrategy[] = [\"priority\", \"round-robin\", \"fill-first\"];\nconst DEFAULT_FREE_CONFIG: WebsearchConfig = {\n\tstrategy: \"priority\",\n\tfallback: true,\n\tauto: true,\n\tproviders: [{ id: \"default\", provider: \"duckduckgo-html\", maxResults: 10 }],\n};\n\nexport interface ConfigLoadOptions {\n\tcwd: string;\n\thomeDir?: string;\n}\n\nfunction isJsonObject(value: unknown): value is JsonObject {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value);\n}\n\nfunction oneOf<TValue extends string>(values: readonly TValue[], value: unknown): value is TValue {\n\treturn typeof value === \"string\" && (values as readonly string[]).includes(value);\n}\n\nfunction isStringArray(value: JsonValue | undefined): value is string[] {\n\treturn Array.isArray(value) && value.every((item) => typeof item === \"string\");\n}\n\nfunction optionalString(value: JsonValue | undefined): string | undefined {\n\treturn typeof value === \"string\" && value.length > 0 ? value : undefined;\n}\n\nfunction optionalNumber(value: JsonValue | undefined): number | undefined {\n\treturn typeof value === \"number\" && Number.isFinite(value) ? value : undefined;\n}\n\nfunction optionalBoolean(value: JsonValue | undefined): boolean | undefined {\n\treturn typeof value === \"boolean\" ? value : undefined;\n}\n\nfunction optionalProvider(value: JsonValue | undefined): SearchProvider | undefined {\n\treturn oneOf(PROVIDERS, value) ? value : undefined;\n}\n\nfunction optionalContextSize(value: JsonValue | undefined): SearchContextSize | undefined {\n\treturn oneOf(CONTEXT_SIZES, value) ? value : undefined;\n}\n\nfunction optionalCodexMode(value: JsonValue | undefined): CodexSearchMode | undefined {\n\treturn oneOf(CODEX_MODES, value) ? value : undefined;\n}\n\nfunction optionalStrategy(value: JsonValue | undefined): RoutingStrategy | undefined {\n\treturn oneOf(STRATEGIES, value) ? value : undefined;\n}\n\nfunction optionalLocation(value: JsonValue | undefined): SearchUserLocation | undefined {\n\tif (!isJsonObject(value)) return undefined;\n\tconst location: SearchUserLocation = {};\n\tconst country = optionalString(value.country);\n\tconst region = optionalString(value.region);\n\tconst city = optionalString(value.city);\n\tconst timezone = optionalString(value.timezone);\n\tif (country) location.country = country;\n\tif (region) location.region = region;\n\tif (city) location.city = city;\n\tif (timezone) location.timezone = timezone;\n\treturn Object.keys(location).length > 0 ? location : undefined;\n}\n\nfunction parseJsonObject(content: string): JsonObject | null {\n\tlet parsed: unknown;\n\ttry {\n\t\tparsed = JSON.parse(content);\n\t} catch {\n\t\treturn null;\n\t}\n\treturn isJsonObject(parsed) ? parsed : null;\n}\n\nfunction providerEntryFromObject(raw: JsonObject): SearchProviderEntry | null {\n\tconst provider = optionalProvider(raw.provider) ?? optionalProvider(raw.backend);\n\tif (!provider) return null;\n\n\tconst config: SearchProviderEntry = { provider };\n\tconst id = optionalString(raw.id);\n\tconst apiKey = optionalString(raw.apiKey);\n\tconst baseUrl = optionalString(raw.baseUrl);\n\tconst searchEngineId = optionalString(raw.searchEngineId);\n\tconst maxResults = optionalNumber(raw.maxResults);\n\tconst model = optionalString(raw.model);\n\tconst codexMode = optionalCodexMode(raw.codexMode);\n\tconst searchContextSize = optionalContextSize(raw.searchContextSize);\n\tconst rawAllowedDomains = raw.allowedDomains;\n\tconst rawBlockedDomains = raw.blockedDomains;\n\tconst allowedDomains = isStringArray(rawAllowedDomains) ? rawAllowedDomains : undefined;\n\tconst blockedDomains = isStringArray(rawBlockedDomains) ? rawBlockedDomains : undefined;\n\tconst userLocation = optionalLocation(raw.userLocation);\n\tconst timeoutMs = optionalNumber(raw.timeoutMs);\n\tconst priority = optionalNumber(raw.priority);\n\tconst weight = optionalNumber(raw.weight);\n\n\tif (id) config.id = id;\n\tif (apiKey) config.apiKey = apiKey;\n\tif (baseUrl) config.baseUrl = baseUrl;\n\tif (searchEngineId) config.searchEngineId = searchEngineId;\n\tif (maxResults) config.maxResults = maxResults;\n\tif (model) config.model = model;\n\tif (codexMode) config.codexMode = codexMode;\n\tif (searchContextSize) config.searchContextSize = searchContextSize;\n\tif (allowedDomains) config.allowedDomains = allowedDomains;\n\tif (blockedDomains) config.blockedDomains = blockedDomains;\n\tif (userLocation) config.userLocation = userLocation;\n\tif (timeoutMs !== undefined) config.timeoutMs = timeoutMs;\n\tif (priority !== undefined) config.priority = priority;\n\tif (weight !== undefined) config.weight = weight;\n\n\treturn config;\n}\n\nfunction configFromObject(raw: JsonObject): WebsearchConfig | null {\n\tconst auto = optionalBoolean(raw.auto) ?? true;\n\tconst providersValue = raw.providers;\n\tconst rawProviders = Array.isArray(providersValue) ? providersValue : undefined;\n\tif (rawProviders) {\n\t\tif (optionalProvider(raw.provider)) return null;\n\t\tconst providers = rawProviders\n\t\t\t.map((value) => (isJsonObject(value) ? providerEntryFromObject(value) : null))\n\t\t\t.filter((entry): entry is SearchProviderEntry => entry !== null);\n\t\tconst strategy = optionalStrategy(raw.strategy) ?? \"priority\";\n\t\tconst fallback = optionalBoolean(raw.fallback) ?? true;\n\t\treturn { strategy, fallback, auto, providers };\n\t}\n\n\tconst provider = providerEntryFromObject(raw);\n\treturn provider ? { strategy: \"priority\", fallback: true, auto, providers: [provider] } : null;\n}\n\nfunction hasApiKey(config: SearchProviderConfig): boolean {\n\treturn typeof config.apiKey === \"string\" && config.apiKey.length > 0;\n}\n\nexport function validateProviderConfig(config: SearchProviderEntry): ProviderValidationResult {\n\tif (!PROVIDERS.includes(config.provider)) {\n\t\treturn { ok: false, reason: \"invalid_config\", message: `Unsupported provider: ${config.provider}` };\n\t}\n\n\tif (config.allowedDomains && config.blockedDomains) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\treason: \"invalid_config\",\n\t\t\tmessage: \"Provider config cannot specify both allowedDomains and blockedDomains.\",\n\t\t};\n\t}\n\n\tif (config.weight !== undefined && config.weight <= 0) {\n\t\treturn { ok: false, reason: \"invalid_config\", message: \"Provider weight must be greater than 0.\" };\n\t}\n\n\tif (config.timeoutMs !== undefined && config.timeoutMs <= 0) {\n\t\treturn { ok: false, reason: \"invalid_config\", message: \"Provider timeoutMs must be greater than 0.\" };\n\t}\n\n\tif (config.baseUrl && !isAllowedProviderBaseUrl(config.baseUrl)) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\treason: \"invalid_config\",\n\t\t\tmessage: `Provider ${config.provider} baseUrl must be a public HTTPS URL without credentials.`,\n\t\t};\n\t}\n\n\tif (config.provider === \"google-cse\" && !config.searchEngineId) {\n\t\treturn { ok: false, reason: \"missing_api_key\", message: \"Provider google-cse requires searchEngineId.\" };\n\t}\n\n\tif ((config.provider === \"codex\" || config.provider === \"openai\") && !hasApiKey(config)) {\n\t\treturn {\n\t\t\tok: false,\n\t\t\treason: \"missing_api_key\",\n\t\t\tmessage: `Provider ${config.provider} requires apiKey for hosted Responses API search.`,\n\t\t};\n\t}\n\n\tif (\n\t\tconfig.provider !== \"codex\" &&\n\t\tconfig.provider !== \"openai\" &&\n\t\tconfig.provider !== \"duckduckgo-html\" &&\n\t\t!hasApiKey(config)\n\t) {\n\t\treturn { ok: false, reason: \"missing_api_key\", message: `Provider ${config.provider} requires apiKey.` };\n\t}\n\n\treturn { ok: true, config };\n}\n\nexport function validateWebsearchConfig(\n\tconfig: WebsearchConfig,\n): ProviderValidationResult | { ok: true; config: WebsearchConfig } {\n\tif (!STRATEGIES.includes(config.strategy)) {\n\t\treturn { ok: false, reason: \"invalid_config\", message: `Unsupported routing strategy: ${config.strategy}` };\n\t}\n\tif (typeof config.auto !== \"boolean\") {\n\t\treturn { ok: false, reason: \"invalid_config\", message: \"Websearch config auto must be a boolean.\" };\n\t}\n\tif (config.providers.length === 0) {\n\t\treturn { ok: false, reason: \"invalid_config\", message: \"Websearch config requires at least one provider.\" };\n\t}\n\n\tfor (const provider of config.providers) {\n\t\tconst validation = validateProviderConfig(provider);\n\t\tif (!validation.ok) return validation;\n\t}\n\n\treturn { ok: true, config };\n}\n\nasync function fileExists(path: string): Promise<boolean> {\n\ttry {\n\t\tawait access(path);\n\t\treturn true;\n\t} catch {\n\t\treturn false;\n\t}\n}\n\nexport async function loadWebsearchConfig(options: ConfigLoadOptions): Promise<ConfigLoadResult> {\n\tconst home = options.homeDir ?? homedir();\n\tconst paths = [\n\t\tjoin(options.cwd, CONFIG_DIR_NAME, \"websearch.json\"),\n\t\tjoin(options.cwd, \".pi\", \"websearch.json\"),\n\t\tjoin(home, \"websearch.json\"),\n\t\tjoin(home, CONFIG_DIR_NAME, \"websearch.json\"),\n\t\tjoin(home, \".pi\", \"websearch.json\"),\n\t].filter((path, index, all) => all.indexOf(path) === index);\n\n\tfor (const path of paths) {\n\t\tif (!(await fileExists(path))) continue;\n\t\tconst raw = parseJsonObject(await readFile(path, \"utf8\"));\n\t\tif (!raw) {\n\t\t\treturn { ok: false, reason: \"invalid_config\", message: `Invalid JSON object in ${path}`, source: path };\n\t\t}\n\t\tconst config = configFromObject(raw);\n\t\tif (!config) {\n\t\t\treturn { ok: false, reason: \"invalid_config\", message: `Invalid provider config in ${path}`, source: path };\n\t\t}\n\t\tconst validation = validateWebsearchConfig(config);\n\t\tif (!validation.ok) return { ...validation, source: path };\n\t\treturn { ok: true, config, source: path };\n\t}\n\n\treturn { ok: true, config: DEFAULT_FREE_CONFIG, source: \"default:duckduckgo-html\" };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"native.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/websearch/websearch/native.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAkB,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtE,MAAM,WAAW,eAAe;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;CACb;AAED,MAAM,MAAM,gBAAgB,GACzB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAC/D;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhC,MAAM,WAAW,mBAAmB;IACnC,mBAAmB,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACvE,YAAY,CAAC,IAAI,eAAe,EAAE,CAAC;CACnC;AAoJD,wBAAsB,kBAAkB,CACvC,KAAK,EAAE,eAAe,GAAG,SAAS,EAClC,aAAa,EAAE,mBAAmB,GAAG,SAAS,EAC9C,MAAM,CAAC,EAAE,WAAW,GAClB,OAAO,CAAC,mBAAmB,EAAE,CAAC,CA8BhC;AAED,wBAAsB,gBAAgB,CACrC,KAAK,EAAE,eAAe,GAAG,SAAS,EAClC,aAAa,EAAE,mBAAmB,GAAG,SAAS,EAC9C,EAAE,SAAW,GACX,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAErC"}
1
+ {"version":3,"file":"native.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/websearch/websearch/native.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAkB,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEtE,MAAM,WAAW,eAAe;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;CACb;AAED,MAAM,MAAM,gBAAgB,GACzB;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAC/D;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEhC,MAAM,WAAW,mBAAmB;IACnC,mBAAmB,CAAC,KAAK,EAAE,eAAe,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACvE,YAAY,CAAC,IAAI,eAAe,EAAE,CAAC;CACnC;AAkKD,wBAAsB,kBAAkB,CACvC,KAAK,EAAE,eAAe,GAAG,SAAS,EAClC,aAAa,EAAE,mBAAmB,GAAG,SAAS,EAC9C,MAAM,CAAC,EAAE,WAAW,GAClB,OAAO,CAAC,mBAAmB,EAAE,CAAC,CA8BhC;AAED,wBAAsB,gBAAgB,CACrC,KAAK,EAAE,eAAe,GAAG,SAAS,EAClC,aAAa,EAAE,mBAAmB,GAAG,SAAS,EAC9C,EAAE,SAAW,GACX,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,CAErC"}
@@ -16,6 +16,14 @@ function nativeMapping(model) {
16
16
  if (model.provider !== "anthropic" && model.api === "anthropic-messages" && /^claude-/.test(model.id)) {
17
17
  return { provider: "anthropic", resource: "messages", routeLabel: model.provider };
18
18
  }
19
+ if (model.provider === "deepseek" && /^deepseek-v4-/.test(model.id)) {
20
+ return {
21
+ provider: "deepseek",
22
+ resource: "messages",
23
+ routeLabel: "deepseek",
24
+ endpointPath: "/anthropic/v1/messages",
25
+ };
26
+ }
19
27
  if (model.provider === "xai" && /^grok-/.test(model.id)) {
20
28
  return { provider: "xai", resource: "responses" };
21
29
  }
@@ -46,11 +54,9 @@ function shouldDiscoverNativeRoute(activeModel, availableModel) {
46
54
  return false;
47
55
  if (!activeModel)
48
56
  return true;
49
- if (mapping.provider !== "openai" && mapping.provider !== "anthropic")
50
- return true;
51
57
  return activeModel.provider === availableModel.provider;
52
58
  }
53
- function buildEndpointUrl(baseUrl, resource) {
59
+ function buildEndpointUrl(baseUrl, resource, endpointPath) {
54
60
  let configured;
55
61
  try {
56
62
  configured = new URL(baseUrl);
@@ -58,6 +64,11 @@ function buildEndpointUrl(baseUrl, resource) {
58
64
  catch {
59
65
  return baseUrl;
60
66
  }
67
+ if (endpointPath) {
68
+ configured.pathname = endpointPath;
69
+ configured.hash = "";
70
+ return configured.href;
71
+ }
61
72
  const trimmedPath = configured.pathname.replace(/\/+$/, "");
62
73
  const resourceSlash = `/${resource}`;
63
74
  if (trimmedPath.endsWith(resourceSlash)) {
@@ -76,7 +87,7 @@ function nativeRouteKey(model) {
76
87
  const mapping = nativeMapping(model);
77
88
  if (!mapping)
78
89
  return null;
79
- const baseUrl = buildEndpointUrl(model.baseUrl, mapping.resource);
90
+ const baseUrl = buildEndpointUrl(model.baseUrl, mapping.resource, mapping.endpointPath);
80
91
  if (!isAllowedProviderBaseUrl(baseUrl))
81
92
  return null;
82
93
  const routeUrl = new URL(baseUrl);
@@ -95,7 +106,7 @@ async function buildNativeEntryForModel(model, modelRegistry, options = {}) {
95
106
  if (!mapping)
96
107
  return null;
97
108
  const entryId = id ?? (mapping.routeLabel ? `${mapping.routeLabel}/native` : "native");
98
- const baseUrl = buildEndpointUrl(model.baseUrl, mapping.resource);
109
+ const baseUrl = buildEndpointUrl(model.baseUrl, mapping.resource, mapping.endpointPath);
99
110
  if (!isAllowedProviderBaseUrl(baseUrl))
100
111
  return null;
101
112
  signal?.throwIfAborted();
@@ -1 +1 @@
1
- {"version":3,"file":"native.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/websearch/websearch/native.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash } from \"node:crypto\";\n\nimport { isAllowedProviderBaseUrl } from \"./provider-endpoints.ts\";\nimport type { SearchProvider, SearchProviderEntry } from \"./types.ts\";\n\nexport interface NativeModelInfo {\n\tprovider: string;\n\tid: string;\n\tbaseUrl: string;\n\tapi?: string;\n}\n\nexport type NativeAuthResult =\n\t| { ok: true; apiKey?: string; headers?: Record<string, string> }\n\t| { ok: false; error: string };\n\nexport interface NativeModelRegistry {\n\tgetApiKeyAndHeaders(model: NativeModelInfo): Promise<NativeAuthResult>;\n\tgetAvailable?(): NativeModelInfo[];\n}\n\ninterface NativeProviderMapping {\n\tprovider: SearchProvider;\n\tresource: string;\n\trouteLabel?: string;\n}\n\ninterface NativeEntryOptions {\n\tid?: string;\n\tsignal?: AbortSignal;\n}\n\nfunction nativeMapping(model: NativeModelInfo): NativeProviderMapping | null {\n\tconst isOpenAiModel = /^gpt-(4o|4\\.1|5)/.test(model.id) && !model.id.includes(\"codex\");\n\tif (model.provider === \"openai\" && isOpenAiModel) {\n\t\treturn { provider: \"openai\", resource: \"responses\" };\n\t}\n\tif (\n\t\tmodel.provider !== \"openai\" &&\n\t\t(model.api === \"openai-responses\" || model.api === \"azure-openai-responses\") &&\n\t\tisOpenAiModel\n\t) {\n\t\treturn { provider: \"openai\", resource: \"responses\", routeLabel: model.provider };\n\t}\n\n\tif (model.provider === \"anthropic\" && /^claude-/.test(model.id)) {\n\t\treturn { provider: \"anthropic\", resource: \"messages\" };\n\t}\n\tif (model.provider !== \"anthropic\" && model.api === \"anthropic-messages\" && /^claude-/.test(model.id)) {\n\t\treturn { provider: \"anthropic\", resource: \"messages\", routeLabel: model.provider };\n\t}\n\n\tif (model.provider === \"xai\" && /^grok-/.test(model.id)) {\n\t\treturn { provider: \"xai\", resource: \"responses\" };\n\t}\n\n\tif (model.provider === \"perplexity\" && /^sonar/.test(model.id)) {\n\t\treturn { provider: \"perplexity\", resource: \"chat/completions\" };\n\t}\n\n\tif ((model.provider === \"z-ai\" || model.provider === \"zai\") && /^glm-/.test(model.id)) {\n\t\treturn { provider: \"z-ai\", resource: \"chat/completions\" };\n\t}\n\n\tif (model.provider === \"kimi-coding\") {\n\t\treturn { provider: \"kimi\", resource: \"search\" };\n\t}\n\n\tif (model.provider === \"openrouter\") {\n\t\tconst slashIndex = model.id.indexOf(\"/\");\n\t\tif (slashIndex <= 0) return null;\n\t\tconst effectiveProvider = model.id.slice(0, slashIndex);\n\t\tconst effectiveId = model.id.slice(slashIndex + 1);\n\t\tif (effectiveProvider === \"openrouter\") return null;\n\t\treturn nativeMapping({ ...model, provider: effectiveProvider, id: effectiveId });\n\t}\n\n\treturn null;\n}\n\nfunction shouldDiscoverNativeRoute(activeModel: NativeModelInfo | undefined, availableModel: NativeModelInfo): boolean {\n\tconst mapping = nativeMapping(availableModel);\n\tif (!mapping) return false;\n\tif (!activeModel) return true;\n\tif (mapping.provider !== \"openai\" && mapping.provider !== \"anthropic\") return true;\n\treturn activeModel.provider === availableModel.provider;\n}\n\nfunction buildEndpointUrl(baseUrl: string, resource: string): string {\n\tlet configured: URL;\n\ttry {\n\t\tconfigured = new URL(baseUrl);\n\t} catch {\n\t\treturn baseUrl;\n\t}\n\tconst trimmedPath = configured.pathname.replace(/\\/+$/, \"\");\n\tconst resourceSlash = `/${resource}`;\n\tif (trimmedPath.endsWith(resourceSlash)) {\n\t\tconfigured.pathname = trimmedPath;\n\t} else if (/\\/v\\d+$/.test(trimmedPath)) {\n\t\tconfigured.pathname = `${trimmedPath}${resourceSlash}`;\n\t} else {\n\t\tconfigured.pathname = `${trimmedPath}/v1${resourceSlash}`;\n\t}\n\tconfigured.hash = \"\";\n\treturn configured.href;\n}\n\nfunction nativeRouteKey(model: NativeModelInfo): string | null {\n\tconst mapping = nativeMapping(model);\n\tif (!mapping) return null;\n\tconst baseUrl = buildEndpointUrl(model.baseUrl, mapping.resource);\n\tif (!isAllowedProviderBaseUrl(baseUrl)) return null;\n\tconst routeUrl = new URL(baseUrl);\n\trouteUrl.hostname = routeUrl.hostname.replace(/\\.$/, \"\");\n\treturn `${mapping.provider}|${routeUrl.href}`;\n}\n\nfunction discoveredNativeEntryId(provider: SearchProvider, routeKey: string): string {\n\tconst routeFingerprint = createHash(\"sha256\").update(routeKey).digest(\"hex\").slice(0, 16);\n\treturn `native-${provider}-${routeFingerprint}`;\n}\n\nasync function buildNativeEntryForModel(\n\tmodel: NativeModelInfo | undefined,\n\tmodelRegistry: NativeModelRegistry | undefined,\n\toptions: NativeEntryOptions = {},\n): Promise<SearchProviderEntry | null> {\n\tif (!model || !modelRegistry) return null;\n\tconst { id, signal } = options;\n\n\tconst mapping = nativeMapping(model);\n\tif (!mapping) return null;\n\tconst entryId = id ?? (mapping.routeLabel ? `${mapping.routeLabel}/native` : \"native\");\n\tconst baseUrl = buildEndpointUrl(model.baseUrl, mapping.resource);\n\tif (!isAllowedProviderBaseUrl(baseUrl)) return null;\n\n\tsignal?.throwIfAborted();\n\tconst authPromise = modelRegistry.getApiKeyAndHeaders(model);\n\tlet auth: NativeAuthResult;\n\tif (!signal) {\n\t\tauth = await authPromise;\n\t} else {\n\t\tsignal.throwIfAborted();\n\t\tlet removeAbortListener = (): void => {};\n\t\tconst abortPromise = new Promise<never>((_resolve, reject) => {\n\t\t\tconst onAbort = (): void => reject(signal.reason);\n\t\t\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\tremoveAbortListener = () => signal.removeEventListener(\"abort\", onAbort);\n\t\t});\n\t\ttry {\n\t\t\tauth = await Promise.race([authPromise, abortPromise]);\n\t\t} finally {\n\t\t\tremoveAbortListener();\n\t\t}\n\t}\n\tif (!auth.ok || !auth.apiKey) return null;\n\n\treturn {\n\t\tid: entryId,\n\t\tprovider: mapping.provider,\n\t\tapiKey: auth.apiKey,\n\t\tbaseUrl,\n\t\tmodel: model.id,\n\t\tpriority: -1,\n\t};\n}\nexport async function buildNativeEntries(\n\tmodel: NativeModelInfo | undefined,\n\tmodelRegistry: NativeModelRegistry | undefined,\n\tsignal?: AbortSignal,\n): Promise<SearchProviderEntry[]> {\n\tsignal?.throwIfAborted();\n\tif (!modelRegistry) return [];\n\n\tconst entries: SearchProviderEntry[] = [];\n\tconst seenRoutes = new Set<string>();\n\n\tconst activeRouteKey = model ? nativeRouteKey(model) : null;\n\tif (activeRouteKey) {\n\t\tseenRoutes.add(activeRouteKey);\n\t\tconst activeEntry = await buildNativeEntryForModel(model, modelRegistry, { signal });\n\t\tif (activeEntry) entries.push(activeEntry);\n\t}\n\n\tif (!modelRegistry.getAvailable) return entries;\n\n\tfor (const availableModel of modelRegistry.getAvailable()) {\n\t\tif (!shouldDiscoverNativeRoute(model, availableModel)) continue;\n\t\tconst routeKey = nativeRouteKey(availableModel);\n\t\tif (!routeKey || seenRoutes.has(routeKey)) continue;\n\t\tseenRoutes.add(routeKey);\n\t\tconst entry = await buildNativeEntryForModel(availableModel, modelRegistry, {\n\t\t\tid: \"native-discovered\",\n\t\t\tsignal,\n\t\t});\n\t\tif (!entry) continue;\n\t\tentries.push({ ...entry, id: discoveredNativeEntryId(entry.provider, routeKey) });\n\t}\n\n\treturn entries;\n}\n\nexport async function buildNativeEntry(\n\tmodel: NativeModelInfo | undefined,\n\tmodelRegistry: NativeModelRegistry | undefined,\n\tid = \"native\",\n): Promise<SearchProviderEntry | null> {\n\treturn buildNativeEntryForModel(model, modelRegistry, { id });\n}\n"]}
1
+ {"version":3,"file":"native.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/websearch/websearch/native.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzC,OAAO,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AA+BnE,SAAS,aAAa,CAAC,KAAsB;IAC5C,MAAM,aAAa,GAAG,kBAAkB,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC;IACvF,IAAI,KAAK,CAAC,QAAQ,KAAK,QAAQ,IAAI,aAAa,EAAE,CAAC;QAClD,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;IACtD,CAAC;IACD,IACC,KAAK,CAAC,QAAQ,KAAK,QAAQ;QAC3B,CAAC,KAAK,CAAC,GAAG,KAAK,kBAAkB,IAAI,KAAK,CAAC,GAAG,KAAK,wBAAwB,CAAC;QAC5E,aAAa,EACZ,CAAC;QACF,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC;IAClF,CAAC;IAED,IAAI,KAAK,CAAC,QAAQ,KAAK,WAAW,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;QACjE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC;IACxD,CAAC;IACD,IAAI,KAAK,CAAC,QAAQ,KAAK,WAAW,IAAI,KAAK,CAAC,GAAG,KAAK,oBAAoB,IAAI,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;QACvG,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,QAAQ,EAAE,UAAU,EAAE,UAAU,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC;IACpF,CAAC;IAED,IAAI,KAAK,CAAC,QAAQ,KAAK,UAAU,IAAI,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;QACrE,OAAO;YACN,QAAQ,EAAE,UAAU;YACpB,QAAQ,EAAE,UAAU;YACpB,UAAU,EAAE,UAAU;YACtB,YAAY,EAAE,wBAAwB;SACtC,CAAC;IACH,CAAC;IAED,IAAI,KAAK,CAAC,QAAQ,KAAK,KAAK,IAAI,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;QACzD,OAAO,EAAE,QAAQ,EAAE,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,CAAC;IACnD,CAAC;IAED,IAAI,KAAK,CAAC,QAAQ,KAAK,YAAY,IAAI,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;QAChE,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,kBAAkB,EAAE,CAAC;IACjE,CAAC;IAED,IAAI,CAAC,KAAK,CAAC,QAAQ,KAAK,MAAM,IAAI,KAAK,CAAC,QAAQ,KAAK,KAAK,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,EAAE,CAAC;QACvF,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,kBAAkB,EAAE,CAAC;IAC3D,CAAC;IAED,IAAI,KAAK,CAAC,QAAQ,KAAK,aAAa,EAAE,CAAC;QACtC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;IACjD,CAAC;IAED,IAAI,KAAK,CAAC,QAAQ,KAAK,YAAY,EAAE,CAAC;QACrC,MAAM,UAAU,GAAG,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QACzC,IAAI,UAAU,IAAI,CAAC;YAAE,OAAO,IAAI,CAAC;QACjC,MAAM,iBAAiB,GAAG,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,EAAE,UAAU,CAAC,CAAC;QACxD,MAAM,WAAW,GAAG,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC;QACnD,IAAI,iBAAiB,KAAK,YAAY;YAAE,OAAO,IAAI,CAAC;QACpD,OAAO,aAAa,CAAC,EAAE,GAAG,KAAK,EAAE,QAAQ,EAAE,iBAAiB,EAAE,EAAE,EAAE,WAAW,EAAE,CAAC,CAAC;IAClF,CAAC;IAED,OAAO,IAAI,CAAC;AACb,CAAC;AAED,SAAS,yBAAyB,CAAC,WAAwC,EAAE,cAA+B;IAC3G,MAAM,OAAO,GAAG,aAAa,CAAC,cAAc,CAAC,CAAC;IAC9C,IAAI,CAAC,OAAO;QAAE,OAAO,KAAK,CAAC;IAC3B,IAAI,CAAC,WAAW;QAAE,OAAO,IAAI,CAAC;IAC9B,OAAO,WAAW,CAAC,QAAQ,KAAK,cAAc,CAAC,QAAQ,CAAC;AACzD,CAAC;AAED,SAAS,gBAAgB,CAAC,OAAe,EAAE,QAAgB,EAAE,YAAqB;IACjF,IAAI,UAAe,CAAC;IACpB,IAAI,CAAC;QACJ,UAAU,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;IAC/B,CAAC;IAAC,MAAM,CAAC;QACR,OAAO,OAAO,CAAC;IAChB,CAAC;IACD,IAAI,YAAY,EAAE,CAAC;QAClB,UAAU,CAAC,QAAQ,GAAG,YAAY,CAAC;QACnC,UAAU,CAAC,IAAI,GAAG,EAAE,CAAC;QACrB,OAAO,UAAU,CAAC,IAAI,CAAC;IACxB,CAAC;IACD,MAAM,WAAW,GAAG,UAAU,CAAC,QAAQ,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC5D,MAAM,aAAa,GAAG,IAAI,QAAQ,EAAE,CAAC;IACrC,IAAI,WAAW,CAAC,QAAQ,CAAC,aAAa,CAAC,EAAE,CAAC;QACzC,UAAU,CAAC,QAAQ,GAAG,WAAW,CAAC;IACnC,CAAC;SAAM,IAAI,SAAS,CAAC,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;QACxC,UAAU,CAAC,QAAQ,GAAG,GAAG,WAAW,GAAG,aAAa,EAAE,CAAC;IACxD,CAAC;SAAM,CAAC;QACP,UAAU,CAAC,QAAQ,GAAG,GAAG,WAAW,MAAM,aAAa,EAAE,CAAC;IAC3D,CAAC;IACD,UAAU,CAAC,IAAI,GAAG,EAAE,CAAC;IACrB,OAAO,UAAU,CAAC,IAAI,CAAC;AACxB,CAAC;AAED,SAAS,cAAc,CAAC,KAAsB;IAC7C,MAAM,OAAO,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IACrC,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,MAAM,OAAO,GAAG,gBAAgB,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IACxF,IAAI,CAAC,wBAAwB,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IACpD,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,CAAC;IAClC,QAAQ,CAAC,QAAQ,GAAG,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;IACzD,OAAO,GAAG,OAAO,CAAC,QAAQ,IAAI,QAAQ,CAAC,IAAI,EAAE,CAAC;AAC/C,CAAC;AAED,SAAS,uBAAuB,CAAC,QAAwB,EAAE,QAAgB;IAC1E,MAAM,gBAAgB,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IAC1F,OAAO,UAAU,QAAQ,IAAI,gBAAgB,EAAE,CAAC;AACjD,CAAC;AAED,KAAK,UAAU,wBAAwB,CACtC,KAAkC,EAClC,aAA8C,EAC9C,OAAO,GAAuB,EAAE;IAEhC,IAAI,CAAC,KAAK,IAAI,CAAC,aAAa;QAAE,OAAO,IAAI,CAAC;IAC1C,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC;IAE/B,MAAM,OAAO,GAAG,aAAa,CAAC,KAAK,CAAC,CAAC;IACrC,IAAI,CAAC,OAAO;QAAE,OAAO,IAAI,CAAC;IAC1B,MAAM,OAAO,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,UAAU,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IACvF,MAAM,OAAO,GAAG,gBAAgB,CAAC,KAAK,CAAC,OAAO,EAAE,OAAO,CAAC,QAAQ,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IACxF,IAAI,CAAC,wBAAwB,CAAC,OAAO,CAAC;QAAE,OAAO,IAAI,CAAC;IAEpD,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,MAAM,WAAW,GAAG,aAAa,CAAC,mBAAmB,CAAC,KAAK,CAAC,CAAC;IAC7D,IAAI,IAAsB,CAAC;IAC3B,IAAI,CAAC,MAAM,EAAE,CAAC;QACb,IAAI,GAAG,MAAM,WAAW,CAAC;IAC1B,CAAC;SAAM,CAAC;QACP,MAAM,CAAC,cAAc,EAAE,CAAC;QACxB,IAAI,mBAAmB,GAAG,GAAS,EAAE,GAAE,CAAC,CAAC;QACzC,MAAM,YAAY,GAAG,IAAI,OAAO,CAAQ,CAAC,QAAQ,EAAE,MAAM,EAAE,EAAE;YAC5D,MAAM,OAAO,GAAG,GAAS,EAAE,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAClD,MAAM,CAAC,gBAAgB,CAAC,OAAO,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;YAC1D,mBAAmB,GAAG,GAAG,EAAE,CAAC,MAAM,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;QAC1E,CAAC,CAAC,CAAC;QACH,IAAI,CAAC;YACJ,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC,CAAC;QACxD,CAAC;gBAAS,CAAC;YACV,mBAAmB,EAAE,CAAC;QACvB,CAAC;IACF,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IAE1C,OAAO;QACN,EAAE,EAAE,OAAO;QACX,QAAQ,EAAE,OAAO,CAAC,QAAQ;QAC1B,MAAM,EAAE,IAAI,CAAC,MAAM;QACnB,OAAO;QACP,KAAK,EAAE,KAAK,CAAC,EAAE;QACf,QAAQ,EAAE,CAAC,CAAC;KACZ,CAAC;AACH,CAAC;AACD,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACvC,KAAkC,EAClC,aAA8C,EAC9C,MAAoB;IAEpB,MAAM,EAAE,cAAc,EAAE,CAAC;IACzB,IAAI,CAAC,aAAa;QAAE,OAAO,EAAE,CAAC;IAE9B,MAAM,OAAO,GAA0B,EAAE,CAAC;IAC1C,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;IAErC,MAAM,cAAc,GAAG,KAAK,CAAC,CAAC,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;IAC5D,IAAI,cAAc,EAAE,CAAC;QACpB,UAAU,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QAC/B,MAAM,WAAW,GAAG,MAAM,wBAAwB,CAAC,KAAK,EAAE,aAAa,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;QACrF,IAAI,WAAW;YAAE,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;IAC5C,CAAC;IAED,IAAI,CAAC,aAAa,CAAC,YAAY;QAAE,OAAO,OAAO,CAAC;IAEhD,KAAK,MAAM,cAAc,IAAI,aAAa,CAAC,YAAY,EAAE,EAAE,CAAC;QAC3D,IAAI,CAAC,yBAAyB,CAAC,KAAK,EAAE,cAAc,CAAC;YAAE,SAAS;QAChE,MAAM,QAAQ,GAAG,cAAc,CAAC,cAAc,CAAC,CAAC;QAChD,IAAI,CAAC,QAAQ,IAAI,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC;YAAE,SAAS;QACpD,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACzB,MAAM,KAAK,GAAG,MAAM,wBAAwB,CAAC,cAAc,EAAE,aAAa,EAAE;YAC3E,EAAE,EAAE,mBAAmB;YACvB,MAAM;SACN,CAAC,CAAC;QACH,IAAI,CAAC,KAAK;YAAE,SAAS;QACrB,OAAO,CAAC,IAAI,CAAC,EAAE,GAAG,KAAK,EAAE,EAAE,EAAE,uBAAuB,CAAC,KAAK,CAAC,QAAQ,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC;IACnF,CAAC;IAED,OAAO,OAAO,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACrC,KAAkC,EAClC,aAA8C,EAC9C,EAAE,GAAG,QAAQ;IAEb,OAAO,wBAAwB,CAAC,KAAK,EAAE,aAAa,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;AAC/D,CAAC","sourcesContent":["import { createHash } from \"node:crypto\";\n\nimport { isAllowedProviderBaseUrl } from \"./provider-endpoints.ts\";\nimport type { SearchProvider, SearchProviderEntry } from \"./types.ts\";\n\nexport interface NativeModelInfo {\n\tprovider: string;\n\tid: string;\n\tbaseUrl: string;\n\tapi?: string;\n}\n\nexport type NativeAuthResult =\n\t| { ok: true; apiKey?: string; headers?: Record<string, string> }\n\t| { ok: false; error: string };\n\nexport interface NativeModelRegistry {\n\tgetApiKeyAndHeaders(model: NativeModelInfo): Promise<NativeAuthResult>;\n\tgetAvailable?(): NativeModelInfo[];\n}\n\ninterface NativeProviderMapping {\n\tprovider: SearchProvider;\n\tresource: string;\n\trouteLabel?: string;\n\tendpointPath?: string;\n}\n\ninterface NativeEntryOptions {\n\tid?: string;\n\tsignal?: AbortSignal;\n}\n\nfunction nativeMapping(model: NativeModelInfo): NativeProviderMapping | null {\n\tconst isOpenAiModel = /^gpt-(4o|4\\.1|5)/.test(model.id) && !model.id.includes(\"codex\");\n\tif (model.provider === \"openai\" && isOpenAiModel) {\n\t\treturn { provider: \"openai\", resource: \"responses\" };\n\t}\n\tif (\n\t\tmodel.provider !== \"openai\" &&\n\t\t(model.api === \"openai-responses\" || model.api === \"azure-openai-responses\") &&\n\t\tisOpenAiModel\n\t) {\n\t\treturn { provider: \"openai\", resource: \"responses\", routeLabel: model.provider };\n\t}\n\n\tif (model.provider === \"anthropic\" && /^claude-/.test(model.id)) {\n\t\treturn { provider: \"anthropic\", resource: \"messages\" };\n\t}\n\tif (model.provider !== \"anthropic\" && model.api === \"anthropic-messages\" && /^claude-/.test(model.id)) {\n\t\treturn { provider: \"anthropic\", resource: \"messages\", routeLabel: model.provider };\n\t}\n\n\tif (model.provider === \"deepseek\" && /^deepseek-v4-/.test(model.id)) {\n\t\treturn {\n\t\t\tprovider: \"deepseek\",\n\t\t\tresource: \"messages\",\n\t\t\trouteLabel: \"deepseek\",\n\t\t\tendpointPath: \"/anthropic/v1/messages\",\n\t\t};\n\t}\n\n\tif (model.provider === \"xai\" && /^grok-/.test(model.id)) {\n\t\treturn { provider: \"xai\", resource: \"responses\" };\n\t}\n\n\tif (model.provider === \"perplexity\" && /^sonar/.test(model.id)) {\n\t\treturn { provider: \"perplexity\", resource: \"chat/completions\" };\n\t}\n\n\tif ((model.provider === \"z-ai\" || model.provider === \"zai\") && /^glm-/.test(model.id)) {\n\t\treturn { provider: \"z-ai\", resource: \"chat/completions\" };\n\t}\n\n\tif (model.provider === \"kimi-coding\") {\n\t\treturn { provider: \"kimi\", resource: \"search\" };\n\t}\n\n\tif (model.provider === \"openrouter\") {\n\t\tconst slashIndex = model.id.indexOf(\"/\");\n\t\tif (slashIndex <= 0) return null;\n\t\tconst effectiveProvider = model.id.slice(0, slashIndex);\n\t\tconst effectiveId = model.id.slice(slashIndex + 1);\n\t\tif (effectiveProvider === \"openrouter\") return null;\n\t\treturn nativeMapping({ ...model, provider: effectiveProvider, id: effectiveId });\n\t}\n\n\treturn null;\n}\n\nfunction shouldDiscoverNativeRoute(activeModel: NativeModelInfo | undefined, availableModel: NativeModelInfo): boolean {\n\tconst mapping = nativeMapping(availableModel);\n\tif (!mapping) return false;\n\tif (!activeModel) return true;\n\treturn activeModel.provider === availableModel.provider;\n}\n\nfunction buildEndpointUrl(baseUrl: string, resource: string, endpointPath?: string): string {\n\tlet configured: URL;\n\ttry {\n\t\tconfigured = new URL(baseUrl);\n\t} catch {\n\t\treturn baseUrl;\n\t}\n\tif (endpointPath) {\n\t\tconfigured.pathname = endpointPath;\n\t\tconfigured.hash = \"\";\n\t\treturn configured.href;\n\t}\n\tconst trimmedPath = configured.pathname.replace(/\\/+$/, \"\");\n\tconst resourceSlash = `/${resource}`;\n\tif (trimmedPath.endsWith(resourceSlash)) {\n\t\tconfigured.pathname = trimmedPath;\n\t} else if (/\\/v\\d+$/.test(trimmedPath)) {\n\t\tconfigured.pathname = `${trimmedPath}${resourceSlash}`;\n\t} else {\n\t\tconfigured.pathname = `${trimmedPath}/v1${resourceSlash}`;\n\t}\n\tconfigured.hash = \"\";\n\treturn configured.href;\n}\n\nfunction nativeRouteKey(model: NativeModelInfo): string | null {\n\tconst mapping = nativeMapping(model);\n\tif (!mapping) return null;\n\tconst baseUrl = buildEndpointUrl(model.baseUrl, mapping.resource, mapping.endpointPath);\n\tif (!isAllowedProviderBaseUrl(baseUrl)) return null;\n\tconst routeUrl = new URL(baseUrl);\n\trouteUrl.hostname = routeUrl.hostname.replace(/\\.$/, \"\");\n\treturn `${mapping.provider}|${routeUrl.href}`;\n}\n\nfunction discoveredNativeEntryId(provider: SearchProvider, routeKey: string): string {\n\tconst routeFingerprint = createHash(\"sha256\").update(routeKey).digest(\"hex\").slice(0, 16);\n\treturn `native-${provider}-${routeFingerprint}`;\n}\n\nasync function buildNativeEntryForModel(\n\tmodel: NativeModelInfo | undefined,\n\tmodelRegistry: NativeModelRegistry | undefined,\n\toptions: NativeEntryOptions = {},\n): Promise<SearchProviderEntry | null> {\n\tif (!model || !modelRegistry) return null;\n\tconst { id, signal } = options;\n\n\tconst mapping = nativeMapping(model);\n\tif (!mapping) return null;\n\tconst entryId = id ?? (mapping.routeLabel ? `${mapping.routeLabel}/native` : \"native\");\n\tconst baseUrl = buildEndpointUrl(model.baseUrl, mapping.resource, mapping.endpointPath);\n\tif (!isAllowedProviderBaseUrl(baseUrl)) return null;\n\n\tsignal?.throwIfAborted();\n\tconst authPromise = modelRegistry.getApiKeyAndHeaders(model);\n\tlet auth: NativeAuthResult;\n\tif (!signal) {\n\t\tauth = await authPromise;\n\t} else {\n\t\tsignal.throwIfAborted();\n\t\tlet removeAbortListener = (): void => {};\n\t\tconst abortPromise = new Promise<never>((_resolve, reject) => {\n\t\t\tconst onAbort = (): void => reject(signal.reason);\n\t\t\tsignal.addEventListener(\"abort\", onAbort, { once: true });\n\t\t\tremoveAbortListener = () => signal.removeEventListener(\"abort\", onAbort);\n\t\t});\n\t\ttry {\n\t\t\tauth = await Promise.race([authPromise, abortPromise]);\n\t\t} finally {\n\t\t\tremoveAbortListener();\n\t\t}\n\t}\n\tif (!auth.ok || !auth.apiKey) return null;\n\n\treturn {\n\t\tid: entryId,\n\t\tprovider: mapping.provider,\n\t\tapiKey: auth.apiKey,\n\t\tbaseUrl,\n\t\tmodel: model.id,\n\t\tpriority: -1,\n\t};\n}\nexport async function buildNativeEntries(\n\tmodel: NativeModelInfo | undefined,\n\tmodelRegistry: NativeModelRegistry | undefined,\n\tsignal?: AbortSignal,\n): Promise<SearchProviderEntry[]> {\n\tsignal?.throwIfAborted();\n\tif (!modelRegistry) return [];\n\n\tconst entries: SearchProviderEntry[] = [];\n\tconst seenRoutes = new Set<string>();\n\n\tconst activeRouteKey = model ? nativeRouteKey(model) : null;\n\tif (activeRouteKey) {\n\t\tseenRoutes.add(activeRouteKey);\n\t\tconst activeEntry = await buildNativeEntryForModel(model, modelRegistry, { signal });\n\t\tif (activeEntry) entries.push(activeEntry);\n\t}\n\n\tif (!modelRegistry.getAvailable) return entries;\n\n\tfor (const availableModel of modelRegistry.getAvailable()) {\n\t\tif (!shouldDiscoverNativeRoute(model, availableModel)) continue;\n\t\tconst routeKey = nativeRouteKey(availableModel);\n\t\tif (!routeKey || seenRoutes.has(routeKey)) continue;\n\t\tseenRoutes.add(routeKey);\n\t\tconst entry = await buildNativeEntryForModel(availableModel, modelRegistry, {\n\t\t\tid: \"native-discovered\",\n\t\t\tsignal,\n\t\t});\n\t\tif (!entry) continue;\n\t\tentries.push({ ...entry, id: discoveredNativeEntryId(entry.provider, routeKey) });\n\t}\n\n\treturn entries;\n}\n\nexport async function buildNativeEntry(\n\tmodel: NativeModelInfo | undefined,\n\tmodelRegistry: NativeModelRegistry | undefined,\n\tid = \"native\",\n): Promise<SearchProviderEntry | null> {\n\treturn buildNativeEntryForModel(model, modelRegistry, { id });\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"provider-endpoints.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/websearch/websearch/provider-endpoints.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAkBvE,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,CAEnE;AA0BD,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAcjE;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,oBAAoB,GAAG,MAAM,CAEhE"}
1
+ {"version":3,"file":"provider-endpoints.d.ts","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/websearch/websearch/provider-endpoints.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAmBvE,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,CAEnE;AA0BD,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAcjE;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,oBAAoB,GAAG,MAAM,CAEhE"}
@@ -3,6 +3,7 @@ const DEFAULT_PROVIDER_URLS = {
3
3
  tavily: "https://api.tavily.com/search",
4
4
  brave: "https://api.search.brave.com/res/v1/web/search",
5
5
  "duckduckgo-html": "https://html.duckduckgo.com/html/",
6
+ deepseek: "https://api.deepseek.com/anthropic/v1/messages",
6
7
  serper: "https://google.serper.dev/search",
7
8
  "google-cse": "https://customsearch.googleapis.com/customsearch/v1",
8
9
  "z-ai": "https://api.z.ai/api/paas/v4/web_search",
@@ -1 +1 @@
1
- {"version":3,"file":"provider-endpoints.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/websearch/websearch/provider-endpoints.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SearchProvider, SearchProviderConfig } from \"./types.ts\";\n\nconst DEFAULT_PROVIDER_URLS: Record<SearchProvider, string> = {\n\texa: \"https://api.exa.ai/search\",\n\ttavily: \"https://api.tavily.com/search\",\n\tbrave: \"https://api.search.brave.com/res/v1/web/search\",\n\t\"duckduckgo-html\": \"https://html.duckduckgo.com/html/\",\n\tserper: \"https://google.serper.dev/search\",\n\t\"google-cse\": \"https://customsearch.googleapis.com/customsearch/v1\",\n\t\"z-ai\": \"https://api.z.ai/api/paas/v4/web_search\",\n\topenai: \"https://api.openai.com/v1/responses\",\n\tcodex: \"https://api.openai.com/v1/responses\",\n\tanthropic: \"https://api.anthropic.com/v1/messages\",\n\tperplexity: \"https://api.perplexity.ai/search\",\n\txai: \"https://api.x.ai/v1/responses\",\n\tkimi: \"https://api.kimi.com/coding/v1/search\",\n};\n\nexport function defaultProviderUrl(provider: SearchProvider): string {\n\treturn DEFAULT_PROVIDER_URLS[provider];\n}\n\nfunction isPrivateIpv4(hostname: string): boolean {\n\tconst parts = hostname.split(\".\").map((part) => Number.parseInt(part, 10));\n\tif (parts.length !== 4 || parts.some((part) => !Number.isInteger(part) || part < 0 || part > 255)) return false;\n\tconst first = parts[0] ?? -1;\n\tconst second = parts[1] ?? -1;\n\tif (first === 10 || first === 127 || first === 0 || (first === 169 && second === 254)) return true;\n\tif (first === 172 && second >= 16 && second <= 31) return true;\n\treturn first === 192 && second === 168;\n}\n\nfunction isPrivateHostname(hostname: string): boolean {\n\tconst normalized = hostname.toLowerCase().replace(/^\\[/, \"\").replace(/\\]$/, \"\").replace(/\\.$/, \"\");\n\treturn (\n\t\tnormalized === \"localhost\" ||\n\t\tnormalized.endsWith(\".localhost\") ||\n\t\tnormalized.includes(\":\") ||\n\t\tnormalized === \"::1\" ||\n\t\tnormalized.startsWith(\"fc\") ||\n\t\tnormalized.startsWith(\"fd\") ||\n\t\t/^fe[89ab][0-9a-f]:/.test(normalized) ||\n\t\tisPrivateIpv4(normalized)\n\t);\n}\n\nexport function isAllowedProviderBaseUrl(baseUrl: string): boolean {\n\tlet configured: URL;\n\ttry {\n\t\tconfigured = new URL(baseUrl);\n\t} catch {\n\t\treturn false;\n\t}\n\treturn (\n\t\tconfigured.protocol === \"https:\" &&\n\t\tconfigured.username === \"\" &&\n\t\tconfigured.password === \"\" &&\n\t\t!configured.hostname.endsWith(\"..\") &&\n\t\t!isPrivateHostname(configured.hostname)\n\t);\n}\n\nexport function providerUrl(config: SearchProviderConfig): string {\n\treturn config.baseUrl ?? defaultProviderUrl(config.provider);\n}\n"]}
1
+ {"version":3,"file":"provider-endpoints.js","sourceRoot":"","sources":["../../../../../../src/core/extensions/builtin/websearch/websearch/provider-endpoints.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SearchProvider, SearchProviderConfig } from \"./types.ts\";\n\nconst DEFAULT_PROVIDER_URLS: Record<SearchProvider, string> = {\n\texa: \"https://api.exa.ai/search\",\n\ttavily: \"https://api.tavily.com/search\",\n\tbrave: \"https://api.search.brave.com/res/v1/web/search\",\n\t\"duckduckgo-html\": \"https://html.duckduckgo.com/html/\",\n\tdeepseek: \"https://api.deepseek.com/anthropic/v1/messages\",\n\tserper: \"https://google.serper.dev/search\",\n\t\"google-cse\": \"https://customsearch.googleapis.com/customsearch/v1\",\n\t\"z-ai\": \"https://api.z.ai/api/paas/v4/web_search\",\n\topenai: \"https://api.openai.com/v1/responses\",\n\tcodex: \"https://api.openai.com/v1/responses\",\n\tanthropic: \"https://api.anthropic.com/v1/messages\",\n\tperplexity: \"https://api.perplexity.ai/search\",\n\txai: \"https://api.x.ai/v1/responses\",\n\tkimi: \"https://api.kimi.com/coding/v1/search\",\n};\n\nexport function defaultProviderUrl(provider: SearchProvider): string {\n\treturn DEFAULT_PROVIDER_URLS[provider];\n}\n\nfunction isPrivateIpv4(hostname: string): boolean {\n\tconst parts = hostname.split(\".\").map((part) => Number.parseInt(part, 10));\n\tif (parts.length !== 4 || parts.some((part) => !Number.isInteger(part) || part < 0 || part > 255)) return false;\n\tconst first = parts[0] ?? -1;\n\tconst second = parts[1] ?? -1;\n\tif (first === 10 || first === 127 || first === 0 || (first === 169 && second === 254)) return true;\n\tif (first === 172 && second >= 16 && second <= 31) return true;\n\treturn first === 192 && second === 168;\n}\n\nfunction isPrivateHostname(hostname: string): boolean {\n\tconst normalized = hostname.toLowerCase().replace(/^\\[/, \"\").replace(/\\]$/, \"\").replace(/\\.$/, \"\");\n\treturn (\n\t\tnormalized === \"localhost\" ||\n\t\tnormalized.endsWith(\".localhost\") ||\n\t\tnormalized.includes(\":\") ||\n\t\tnormalized === \"::1\" ||\n\t\tnormalized.startsWith(\"fc\") ||\n\t\tnormalized.startsWith(\"fd\") ||\n\t\t/^fe[89ab][0-9a-f]:/.test(normalized) ||\n\t\tisPrivateIpv4(normalized)\n\t);\n}\n\nexport function isAllowedProviderBaseUrl(baseUrl: string): boolean {\n\tlet configured: URL;\n\ttry {\n\t\tconfigured = new URL(baseUrl);\n\t} catch {\n\t\treturn false;\n\t}\n\treturn (\n\t\tconfigured.protocol === \"https:\" &&\n\t\tconfigured.username === \"\" &&\n\t\tconfigured.password === \"\" &&\n\t\t!configured.hostname.endsWith(\"..\") &&\n\t\t!isPrivateHostname(configured.hostname)\n\t);\n}\n\nexport function providerUrl(config: SearchProviderConfig): string {\n\treturn config.baseUrl ?? defaultProviderUrl(config.provider);\n}\n"]}
@@ -1,3 +1,6 @@
1
- import type { ProviderModule } from "./shared.ts";
1
+ import type { BuiltSearchRequest, JsonObject, SearchResultItem } from "../types.ts";
2
+ import type { BuildContext, ProviderModule } from "./shared.ts";
3
+ export declare function buildAnthropicMessagesSearchRequest(ctx: BuildContext, defaultModel: string): BuiltSearchRequest;
4
+ export declare function normalizeAnthropicMessagesSearchPayload(data: JsonObject): SearchResultItem[];
2
5
  export declare const anthropicProvider: ProviderModule;
3
6
  //# sourceMappingURL=anthropic.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../../../../../../src/core/extensions/builtin/websearch/websearch/providers/anthropic.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAgB,cAAc,EAAE,MAAM,aAAa,CAAC;AAGhE,eAAO,MAAM,iBAAiB,EAAE,cA4C/B,CAAC"}
1
+ {"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../../../../../../src/core/extensions/builtin/websearch/websearch/providers/anthropic.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,kBAAkB,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AACpF,OAAO,KAAK,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAGhE,wBAAgB,mCAAmC,CAAC,GAAG,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,GAAG,kBAAkB,CAqB/G;AAED,wBAAgB,uCAAuC,CAAC,IAAI,EAAE,UAAU,GAAG,gBAAgB,EAAE,CAqB5F;AAED,eAAO,MAAM,iBAAiB,EAAE,cAO/B,CAAC"}