unique_web_search 2026.30.0.dev0__tar.gz → 2026.30.0.dev2__tar.gz

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 (132) hide show
  1. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/PKG-INFO +4 -4
  2. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/pyproject.toml +4 -4
  3. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/service.py +46 -136
  4. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/executors/base_executor.py +14 -0
  5. unique_web_search-2026.30.0.dev2/src/unique_web_search/services/executors/modes.py +164 -0
  6. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/executors/v1/__init__.py +3 -5
  7. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/executors/v1/config.py +0 -35
  8. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/executors/v1/executor.py +17 -17
  9. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/executors/v1/prompts/__init__.py +0 -3
  10. unique_web_search-2026.30.0.dev2/src/unique_web_search/services/executors/v1/schema.py +38 -0
  11. unique_web_search-2026.30.0.dev2/src/unique_web_search/services/executors/v1/strategy.py +67 -0
  12. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/executors/v2/config.py +28 -0
  13. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/executors/v2/executor.py +3 -0
  14. unique_web_search-2026.30.0.dev2/src/unique_web_search/services/executors/v2/strategy.py +79 -0
  15. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/executors/v3/executor.py +13 -2
  16. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/executors/v3/schema.py +67 -17
  17. unique_web_search-2026.30.0.dev2/src/unique_web_search/services/executors/v3/strategy.py +100 -0
  18. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/search_engine/__init__.py +2 -0
  19. unique_web_search-2026.30.0.dev2/src/unique_web_search/services/search_engine/base.py +194 -0
  20. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/search_engine/bing.py +7 -25
  21. unique_web_search-2026.30.0.dev2/src/unique_web_search/services/search_engine/brave.py +42 -0
  22. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/search_engine/custom_api.py +11 -9
  23. unique_web_search-2026.30.0.dev2/src/unique_web_search/services/search_engine/google.py +157 -0
  24. unique_web_search-2026.30.0.dev2/src/unique_web_search/services/search_engine/perplexity.py +43 -0
  25. unique_web_search-2026.30.0.dev2/src/unique_web_search/services/search_engine/registry.py +110 -0
  26. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/search_engine/vertexai.py +16 -32
  27. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/utils.py +0 -31
  28. unique_web_search-2026.30.0.dev0/src/unique_web_search/services/executors/v1/prompts/restrict_date_description.j2 +0 -3
  29. unique_web_search-2026.30.0.dev0/src/unique_web_search/services/executors/v1/schema.py +0 -26
  30. unique_web_search-2026.30.0.dev0/src/unique_web_search/services/search_engine/base.py +0 -62
  31. unique_web_search-2026.30.0.dev0/src/unique_web_search/services/search_engine/brave.py +0 -64
  32. unique_web_search-2026.30.0.dev0/src/unique_web_search/services/search_engine/google.py +0 -209
  33. unique_web_search-2026.30.0.dev0/src/unique_web_search/services/search_engine/perplexity.py +0 -62
  34. unique_web_search-2026.30.0.dev0/src/unique_web_search/services/search_engine/registry.py +0 -62
  35. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/README.md +0 -0
  36. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/__init__.py +0 -0
  37. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/client_settings.py +0 -0
  38. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/config.py +0 -0
  39. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/metrics.py +0 -0
  40. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/prompts.py +0 -0
  41. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/schema.py +0 -0
  42. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/_registry.py +0 -0
  43. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/argument_screening/__init__.py +0 -0
  44. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/argument_screening/config.py +0 -0
  45. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/argument_screening/exceptions.py +0 -0
  46. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/argument_screening/prompts/__init__.py +0 -0
  47. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/argument_screening/prompts/guidelines.j2 +0 -0
  48. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/argument_screening/prompts/guidelines_with_keywords.j2 +0 -0
  49. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/argument_screening/prompts/rejection_response.j2 +0 -0
  50. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/argument_screening/prompts/system_prompt.j2 +0 -0
  51. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/argument_screening/prompts/user_prompt.j2 +0 -0
  52. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/argument_screening/service.py +0 -0
  53. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/client/proxy_config.py +0 -0
  54. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/content_processing/__init__.py +0 -0
  55. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/content_processing/cleaning/__init__.py +0 -0
  56. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/content_processing/cleaning/character_sanitize.py +0 -0
  57. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/content_processing/cleaning/clean.py +0 -0
  58. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/content_processing/cleaning/config.py +0 -0
  59. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/content_processing/config.py +0 -0
  60. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/content_processing/processing_strategies/base.py +0 -0
  61. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/content_processing/processing_strategies/config.py +0 -0
  62. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/content_processing/processing_strategies/llm_guard_judge.py +0 -0
  63. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/content_processing/processing_strategies/llm_keyword_redact.py +0 -0
  64. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/content_processing/processing_strategies/llm_process.py +0 -0
  65. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/content_processing/processing_strategies/prompts/__init__.py +0 -0
  66. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/content_processing/processing_strategies/prompts/judge_and_sanitize_prompt.j2 +0 -0
  67. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/content_processing/processing_strategies/prompts/judge_prompt.j2 +0 -0
  68. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/content_processing/processing_strategies/prompts/keyword_extract_prompt.j2 +0 -0
  69. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/content_processing/processing_strategies/prompts/page_context.j2 +0 -0
  70. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/content_processing/processing_strategies/prompts/sanitize_rules.j2 +0 -0
  71. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/content_processing/processing_strategies/prompts/system_prompt.j2 +0 -0
  72. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/content_processing/processing_strategies/prompts/user_prompt.j2 +0 -0
  73. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/content_processing/processing_strategies/schema.py +0 -0
  74. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/content_processing/processing_strategies/settings.py +0 -0
  75. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/content_processing/processing_strategies/truncate.py +0 -0
  76. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/content_processing/service.py +0 -0
  77. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/crawlers/README.md +0 -0
  78. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/crawlers/__init__.py +0 -0
  79. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/crawlers/base.py +0 -0
  80. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/crawlers/basic.py +0 -0
  81. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/crawlers/crawl4ai.py +0 -0
  82. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/crawlers/firecrawl.py +0 -0
  83. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/crawlers/jina.py +0 -0
  84. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/crawlers/tavily.py +0 -0
  85. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/crawlers/url_safety/__init__.py +0 -0
  86. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/crawlers/utils.py +0 -0
  87. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/executors/README.md +0 -0
  88. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/executors/__init__.py +0 -0
  89. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/executors/base_config.py +0 -0
  90. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/executors/context.py +0 -0
  91. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/executors/v1/prompts/refine_query_system_prompt.j2 +0 -0
  92. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/executors/v1/prompts/tool_description.j2 +0 -0
  93. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/executors/v1/prompts/tool_description_for_system_prompt.j2 +0 -0
  94. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/executors/v2/__init__.py +0 -0
  95. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/executors/v2/prompts/__init__.py +0 -0
  96. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/executors/v2/prompts/step_query_description.j2 +0 -0
  97. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/executors/v2/prompts/tool_description.j2 +0 -0
  98. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/executors/v2/prompts/tool_description_for_system_prompt.j2 +0 -0
  99. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/executors/v2/schema.py +0 -0
  100. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/executors/v3/__init__.py +0 -0
  101. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/executors/v3/config.py +0 -0
  102. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/executors/v3/prompts/__init__.py +0 -0
  103. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/executors/v3/prompts/tool_description.j2 +0 -0
  104. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/executors/v3/prompts/tool_description_for_system_prompt.j2 +0 -0
  105. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/helpers.py +0 -0
  106. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/message_log.py +0 -0
  107. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/proxy/__init__.py +0 -0
  108. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/proxy/bridge.py +0 -0
  109. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/proxy/mappers.py +0 -0
  110. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/query_elicitation.py +0 -0
  111. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/search_engine/README.md +0 -0
  112. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/search_engine/schema.py +0 -0
  113. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/search_engine/utils/google/schema.py +0 -0
  114. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/search_engine/utils/grounding/__init__.py +0 -0
  115. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/search_engine/utils/grounding/bing/__init__.py +0 -0
  116. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/search_engine/utils/grounding/bing/client.py +0 -0
  117. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/search_engine/utils/grounding/bing/models.py +0 -0
  118. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/search_engine/utils/grounding/bing/runner.py +0 -0
  119. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/search_engine/utils/grounding/models.py +0 -0
  120. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/search_engine/utils/grounding/response_parsing.py +0 -0
  121. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/search_engine/utils/grounding/vertexai/__init__.py +0 -0
  122. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/search_engine/utils/grounding/vertexai/client.py +0 -0
  123. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/search_engine/utils/grounding/vertexai/exceptions.py +0 -0
  124. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/search_engine/utils/grounding/vertexai/gemini.py +0 -0
  125. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/search_engine/utils/grounding/vertexai/response_handler.py +0 -0
  126. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/snippet_judge/__init__.py +0 -0
  127. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/snippet_judge/prompts.py +0 -0
  128. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/snippet_judge/schema.py +0 -0
  129. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/snippet_judge/service.py +0 -0
  130. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/services/structured_llm.py +0 -0
  131. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/settings.py +0 -0
  132. {unique_web_search-2026.30.0.dev0 → unique_web_search-2026.30.0.dev2}/src/unique_web_search/skills/web-search-v3.md +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: unique-web-search
3
- Version: 2026.30.0.dev0
3
+ Version: 2026.30.0.dev2
4
4
  Summary:
5
5
  Author: Andreas Hauri, Gustav Hartz, Rami Azouz
6
6
  Author-email: Andreas Hauri <andreas@unique.ch>, Gustav Hartz <gustav.hartz.ext@unique.ch>, Rami Azouz <rami.ext@unique.ch>
@@ -17,7 +17,7 @@ Requires-Dist: tavily-python>=0.7.11,<1
17
17
  Requires-Dist: unidecode>=1.4.0,<2
18
18
  Requires-Dist: azure-ai-projects>=1.0.0,<2
19
19
  Requires-Dist: azure-identity>=1.25.0,<2
20
- Requires-Dist: unique-toolkit[monitoring]>=2026.30.0.dev0,<2026.30.0rc0
20
+ Requires-Dist: unique-toolkit[monitoring]>=2026.30.0.dev12,<2026.30.0rc0
21
21
  Requires-Dist: azure-core>=1.36.0,<2
22
22
  Requires-Dist: google-cloud-aiplatform>=1.128.0,<2
23
23
  Requires-Dist: google-auth>=2.43.0,<3
@@ -27,8 +27,8 @@ Requires-Dist: httpx>=0.28.1
27
27
  Requires-Dist: certifi>=2025.11.12
28
28
  Requires-Dist: jinja2>=3.1.6
29
29
  Requires-Dist: playwright>=1.58.0
30
- Requires-Dist: unique-search-proxy-core>=2026.30.0.dev0,<2026.30.0rc0
31
- Requires-Dist: unique-search-proxy-sdk>=2026.30.0.dev0,<2026.30.0rc0
30
+ Requires-Dist: unique-search-proxy-core>=2026.30.0.dev2,<2026.30.0rc0
31
+ Requires-Dist: unique-search-proxy-sdk>=2026.30.0.dev2,<2026.30.0rc0
32
32
  Requires-Python: >=3.12, <4.0
33
33
  Description-Content-Type: text/markdown
34
34
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "unique_web_search"
3
- version = "2026.30.0.dev0"
3
+ version = "2026.30.0.dev2"
4
4
  description = ""
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12,<4.0"
@@ -23,7 +23,7 @@ dependencies = [
23
23
  "unidecode>=1.4.0,<2",
24
24
  "azure-ai-projects>=1.0.0,<2",
25
25
  "azure-identity>=1.25.0,<2",
26
- "unique-toolkit[monitoring]>=2026.30.0.dev0,<2026.30.0rc0",
26
+ "unique-toolkit[monitoring]>=2026.30.0.dev12,<2026.30.0rc0",
27
27
  "azure-core>=1.36.0,<2",
28
28
  "google-cloud-aiplatform>=1.128.0,<2",
29
29
  "google-auth>=2.43.0,<3",
@@ -33,8 +33,8 @@ dependencies = [
33
33
  "certifi>=2025.11.12",
34
34
  "jinja2>=3.1.6",
35
35
  "playwright>=1.58.0",
36
- "unique-search-proxy-core>=2026.30.0.dev0,<2026.30.0rc0",
37
- "unique-search-proxy-sdk>=2026.30.0.dev0,<2026.30.0rc0",
36
+ "unique-search-proxy-core>=2026.30.0.dev2,<2026.30.0rc0",
37
+ "unique-search-proxy-sdk>=2026.30.0.dev2,<2026.30.0rc0",
38
38
  ]
39
39
 
40
40
  [build-system]
@@ -1,10 +1,10 @@
1
1
  import logging
2
- import re
3
2
  from datetime import datetime
4
3
  from time import time
5
4
 
6
- from jinja2 import Template
7
5
  from typing_extensions import override
6
+ from unique_search_proxy_core.param_policy.exposed_params import ExposedParams
7
+ from unique_search_proxy_core.search_engines.base import BaseSearchEngineConfig
8
8
  from unique_toolkit._common.chunk_relevancy_sorter.service import ChunkRelevancySorter
9
9
  from unique_toolkit.agentic.evaluation.schemas import EvaluationMetricName
10
10
  from unique_toolkit.agentic.feature_flags.feature_flags import (
@@ -31,29 +31,22 @@ from unique_web_search.services.argument_screening import (
31
31
  )
32
32
  from unique_web_search.services.content_processing import ContentProcessor
33
33
  from unique_web_search.services.crawlers import get_crawler_service
34
- from unique_web_search.services.executors import (
35
- WebSearchMode,
36
- WebSearchV1Executor,
37
- WebSearchV2Executor,
38
- WebSearchV3Config,
39
- WebSearchV3Executor,
40
- )
41
34
  from unique_web_search.services.executors.context import (
42
35
  ExecutorCallbacks,
43
36
  ExecutorConfiguration,
44
37
  ExecutorServiceContext,
45
38
  )
46
- from unique_web_search.services.executors.v1.schema import WebSearchToolParameters
47
- from unique_web_search.services.executors.v2.schema import WebSearchPlan
48
- from unique_web_search.services.executors.v3.schema import WebSearchV3ToolParameters
39
+ from unique_web_search.services.executors.modes import (
40
+ WebSearchExecutor,
41
+ WebSearchToolContext,
42
+ WebSearchToolParametersInstance,
43
+ get_mode_strategy,
44
+ )
49
45
  from unique_web_search.services.message_log import WebSearchMessageLogger
50
46
  from unique_web_search.services.query_elicitation import QueryElicitationService
51
47
  from unique_web_search.services.search_engine import (
52
- SearchEngineMode,
53
- get_search_engine_mode,
54
48
  get_search_engine_service,
55
49
  )
56
- from unique_web_search.services.search_engine.custom_api import CustomAPIConfig
57
50
  from unique_web_search.utils import (
58
51
  WebPageChunk,
59
52
  reduce_sources_to_token_limit,
@@ -97,6 +90,8 @@ class WebSearchTool(Tool[WebSearchConfig]):
97
90
  )
98
91
  self.debug = self.config.debug
99
92
  self._display_name = kwargs.get("display_name", "Web Search")
93
+ self.exposed_params_cls = self._resolve_exposed_params_cls()
94
+ self._mode_strategy = get_mode_strategy(self.config.web_search_mode_config)
100
95
 
101
96
  def content_reducer(web_page_chunks: list[WebPageChunk]) -> list[WebPageChunk]:
102
97
 
@@ -111,83 +106,37 @@ class WebSearchTool(Tool[WebSearchConfig]):
111
106
 
112
107
  self.content_reducer = content_reducer
113
108
 
114
- def _resolve_search_engine_mode(self) -> SearchEngineMode:
115
- """Derive the search-engine mode, respecting CustomAPI overrides."""
116
- cfg = self.search_engine_service.config
117
- override = cfg.search_engine_mode if isinstance(cfg, CustomAPIConfig) else None
118
- return get_search_engine_mode(cfg.engine, override=override)
109
+ def _resolve_exposed_params_cls(self) -> type[ExposedParams] | None:
110
+ """Resolve the exposed-params model from the search-engine config, if any."""
111
+ cfg = self.config.search_engine_config
112
+ if isinstance(cfg, BaseSearchEngineConfig):
113
+ return cfg.exposed_params_model()
114
+ return None
115
+
116
+ def _tool_context(self) -> WebSearchToolContext:
117
+ return WebSearchToolContext(
118
+ search_engine_config=self.search_engine_service.config,
119
+ date_string=datetime.now().strftime("%A %B %d, %Y"),
120
+ exposed_params_cls=self.exposed_params_cls,
121
+ )
119
122
 
120
123
  @override
121
124
  def tool_description(self) -> LanguageModelToolDescription:
122
- if self.config.web_search_mode_config.mode == WebSearchMode.V1:
123
- self.tool_parameter_calls = WebSearchToolParameters.from_tool_parameter_query_description(
124
- self.config.web_search_mode_config.tool_parameters_description.query_description,
125
- self.config.web_search_mode_config.tool_parameters_description.date_restrict_description,
126
- )
127
- else:
128
- if self.config.web_search_mode_config.mode == WebSearchMode.V3:
129
- self.tool_parameter_calls = WebSearchV3ToolParameters
130
- else:
131
- engine_mode = self._resolve_search_engine_mode()
132
- self.tool_parameter_calls = WebSearchPlan.with_search_engine_mode(
133
- engine_mode
134
- )
135
-
136
- tool_description = self.config.web_search_mode_config.tool_description
137
-
138
- if self.config.web_search_mode_config.mode == WebSearchMode.V3:
139
- tool_description = Template(tool_description).render(
140
- tool_parameters_schema=WebSearchV3ToolParameters.schema_hint(),
141
- )
142
-
125
+ ctx = self._tool_context()
126
+ self.tool_parameter_calls = self._mode_strategy.build_tool_parameters(ctx)
143
127
  return LanguageModelToolDescription(
144
128
  name=self.name,
145
- description=tool_description,
129
+ description=self._mode_strategy.tool_description(ctx),
146
130
  parameters=self.tool_parameter_calls,
147
131
  )
148
132
 
149
133
  def tool_description_for_system_prompt(self) -> str:
150
- mode_config = self.config.web_search_mode_config
151
- if mode_config.mode == WebSearchMode.V1:
152
- return mode_config.tool_description_for_system_prompt
153
-
154
- template_str = mode_config.tool_description_for_system_prompt
155
-
156
- if mode_config.mode == WebSearchMode.V3:
157
- return Template(template_str).render(
158
- date_string=datetime.now().strftime("%A %B %d, %Y"),
159
- )
160
-
161
- # Backwards compatibility: V2 prompts persisted before the Jinja
162
- # migration use the legacy ``$max_steps`` placeholder. Jinja would
163
- # otherwise pass it through verbatim, so rewrite it to the Jinja
164
- # equivalent before rendering.
165
- if "$max_steps" in template_str:
166
- _LOGGER.warning(
167
- "V2 web-search prompt contains legacy '$max_steps' placeholder; "
168
- "rewriting to '{{ max_steps }}'. Please update the stored "
169
- "configuration to use Jinja syntax."
170
- )
171
- template_str = template_str.replace("$max_steps", "{{ max_steps }}")
172
-
173
- engine_mode = self._resolve_search_engine_mode()
174
- return Template(template_str).render(
175
- max_steps=mode_config.max_steps,
176
- date_string=datetime.now().strftime("%A %B %d, %Y"),
177
- search_engine_mode=engine_mode.value,
178
- tool_parameters_schema=WebSearchPlan.schema_hint(engine_mode),
179
- example_simple=WebSearchPlan.build_example_simple(
180
- engine_mode
181
- ).model_dump_json(indent=2),
182
- example_complex=WebSearchPlan.build_example_complex(
183
- engine_mode
184
- ).model_dump_json(indent=2),
185
- )
134
+ return self._mode_strategy.system_prompt(self._tool_context())
186
135
 
187
136
  def tool_format_information_for_system_prompt(self) -> str:
188
- if self.config.web_search_active_mode == WebSearchMode.V3:
189
- return self.config.web_search_mode_config_v3.tool_format_information_for_system_prompt
190
- return self.config.tool_format_information_for_system_prompt
137
+ return self._mode_strategy.format_information_for_system_prompt(
138
+ default=self.config.tool_format_information_for_system_prompt,
139
+ )
191
140
 
192
141
  def evaluation_check_list(self) -> list[EvaluationMetricName]:
193
142
  return self.config.evaluation_check_list
@@ -202,7 +151,7 @@ class WebSearchTool(Tool[WebSearchConfig]):
202
151
 
203
152
  screening_service = await self._get_argument_screening_service_if_ff_enabled()
204
153
 
205
- parameters_dump = parameters.model_dump()
154
+ parameters_dump = parameters.model_dump(by_alias=True)
206
155
  debug_info = WebSearchDebugInfo(parameters=parameters_dump)
207
156
 
208
157
  web_search_message_logger = WebSearchMessageLogger(
@@ -289,18 +238,16 @@ class WebSearchTool(Tool[WebSearchConfig]):
289
238
  def _get_executor(
290
239
  self,
291
240
  tool_call: LanguageModelFunction,
292
- parameters: WebSearchPlan | WebSearchToolParameters | WebSearchV3ToolParameters,
241
+ parameters: WebSearchToolParametersInstance,
293
242
  debug_info: WebSearchDebugInfo,
294
243
  web_search_message_logger: WebSearchMessageLogger,
295
- ) -> WebSearchV1Executor | WebSearchV2Executor | WebSearchV3Executor:
296
- # Initialize query elicitation service and get callbacks
244
+ ) -> WebSearchExecutor:
297
245
  elicitation_service = QueryElicitationService(
298
246
  chat_service=self._chat_service,
299
247
  display_name=self.display_name(),
300
248
  config=self.config.query_elicitation_config,
301
249
  )
302
250
 
303
- # Build context objects
304
251
  services = ExecutorServiceContext(
305
252
  search_engine_service=self.search_engine_service,
306
253
  crawler_service=self.crawler_service,
@@ -322,43 +269,14 @@ class WebSearchTool(Tool[WebSearchConfig]):
322
269
  tool_progress_reporter=self._ff_tool_progress_reporter(),
323
270
  )
324
271
 
325
- search_config = self.config.web_search_mode_config
326
- if search_config.mode == WebSearchMode.V3:
327
- assert isinstance(search_config, WebSearchV3Config)
328
- assert isinstance(parameters, WebSearchV3ToolParameters)
329
-
330
- return WebSearchV3Executor(
331
- services=services,
332
- config=config,
333
- callbacks=callbacks,
334
- tool_call=tool_call,
335
- tool_parameters=parameters,
336
- )
337
- if isinstance(parameters, WebSearchPlan):
338
- assert search_config.mode == WebSearchMode.V2
339
- return WebSearchV2Executor(
340
- services=services,
341
- config=config,
342
- callbacks=callbacks,
343
- tool_call=tool_call,
344
- tool_parameters=parameters,
345
- max_steps=search_config.max_steps,
346
- )
347
- elif isinstance(parameters, WebSearchToolParameters):
348
- assert search_config.mode == WebSearchMode.V1
349
- return WebSearchV1Executor(
350
- services=services,
351
- config=config,
352
- callbacks=callbacks,
353
- tool_call=tool_call,
354
- tool_parameters=parameters,
355
- refine_query_system_prompt=search_config.refine_query_mode.system_prompt,
356
- refine_query_language_model=search_config.refine_query_mode.language_model,
357
- mode=search_config.refine_query_mode.mode,
358
- max_queries=search_config.max_queries,
359
- )
360
- else:
361
- raise ValueError(f"Invalid parameters: {parameters}")
272
+ return self._mode_strategy.build_executor(
273
+ services=services,
274
+ config=config,
275
+ callbacks=callbacks,
276
+ tool_call=tool_call,
277
+ parameters=parameters,
278
+ exposed_params_cls=self.exposed_params_cls,
279
+ )
362
280
 
363
281
  def get_evaluation_checks_based_on_tool_response(
364
282
  self,
@@ -414,20 +332,12 @@ class WebSearchTool(Tool[WebSearchConfig]):
414
332
 
415
333
  def _build_display_name(
416
334
  self,
417
- parameters: WebSearchPlan | WebSearchToolParameters | WebSearchV3ToolParameters,
335
+ parameters: WebSearchToolParametersInstance,
418
336
  ) -> str:
419
- if not isinstance(parameters, WebSearchV3ToolParameters):
420
- return self.display_name()
421
-
422
- display_name = self.display_name()
423
- # Remove "search" from the display name (case-insensitive, all occurrences).
424
- display_name = re.sub(
425
- r"\bsearch\b", "", display_name, flags=re.IGNORECASE
426
- ).strip()
427
-
428
- suffix = parameters.get_display_name_suffix()
429
-
430
- return display_name + suffix
337
+ return self._mode_strategy.build_display_name(
338
+ base_display_name=self.display_name(),
339
+ parameters=parameters,
340
+ )
431
341
 
432
342
 
433
343
  ToolFactory.register_tool(WebSearchTool, WebSearchConfig)
@@ -4,6 +4,7 @@ from time import time
4
4
  from typing import Generic, TypeVar
5
5
 
6
6
  from pydantic import BaseModel
7
+ from unique_search_proxy_core.param_policy.exposed_params import ExposedParams
7
8
  from unique_toolkit.agentic.tools.tool_progress_reporter import (
8
9
  ProgressState,
9
10
  )
@@ -39,6 +40,7 @@ class BaseWebSearchExecutor(ABC, Generic[T]):
39
40
  callbacks: ExecutorCallbacks,
40
41
  tool_call: LanguageModelFunction,
41
42
  tool_parameters: T,
43
+ exposed_params_cls: type[ExposedParams] | None = None,
42
44
  ):
43
45
  # Extract from service context
44
46
  self.search_service = services.search_engine_service
@@ -61,6 +63,7 @@ class BaseWebSearchExecutor(ABC, Generic[T]):
61
63
  # Store tool parameters
62
64
  self.tool_call = tool_call
63
65
  self.tool_parameters = tool_parameters
66
+ self.exposed_params_cls = exposed_params_cls
64
67
 
65
68
  # Initialize notification state
66
69
  self._notify_name = ""
@@ -78,6 +81,17 @@ class BaseWebSearchExecutor(ABC, Generic[T]):
78
81
 
79
82
  self.notify_callback = notify_callback
80
83
 
84
+ def _extract_search_params(self, source: BaseModel) -> ExposedParams | None:
85
+ """Validate ``source`` against the exposed-params class, dropping tool-only fields.
86
+
87
+ Returns ``None`` when no knobs are exposed for this deployment. Otherwise
88
+ re-validates the source dump through ``exposed_params_cls``
89
+ (``extra="ignore"``) so only admin-exposed engine knobs remain.
90
+ """
91
+ if self.exposed_params_cls is None:
92
+ return None
93
+ return self.exposed_params_cls.model_validate(source.model_dump(by_alias=True))
94
+
81
95
  @property
82
96
  def notify_name(self):
83
97
  return self._notify_name
@@ -0,0 +1,164 @@
1
+ """Per-mode strategy objects for the WebSearch tool.
2
+
3
+ Each WebSearch mode (V1/V2/V3) differs only in how it builds its LLM-facing
4
+ surface and which executor runs it. A :class:`WebSearchModeStrategy` owns all of
5
+ that per-mode behaviour in one place:
6
+
7
+ - the tool-call parameter model (``query`` plus any engine-exposed knobs),
8
+ - the tool description shown to the model,
9
+ - the system-prompt text and citation/format-information text,
10
+ - the executor construction, and
11
+ - the runtime display name.
12
+
13
+ ``WebSearchTool`` resolves the strategy for the active mode via
14
+ :func:`get_mode_strategy` and delegates to it, staying free of mode branching.
15
+ """
16
+
17
+ from __future__ import annotations
18
+
19
+ from abc import ABC, abstractmethod
20
+ from collections.abc import Callable
21
+ from dataclasses import dataclass
22
+ from typing import cast
23
+
24
+ from pydantic import BaseModel
25
+ from unique_search_proxy_core.param_policy.exposed_params import ExposedParams
26
+ from unique_toolkit.language_model import LanguageModelFunction
27
+
28
+ from unique_web_search.services.executors.base_config import WebSearchMode
29
+ from unique_web_search.services.executors.context import (
30
+ ExecutorCallbacks,
31
+ ExecutorConfiguration,
32
+ ExecutorServiceContext,
33
+ )
34
+ from unique_web_search.services.executors.v1.config import WebSearchV1Config
35
+ from unique_web_search.services.executors.v1.executor import WebSearchV1Executor
36
+ from unique_web_search.services.executors.v1.schema import WebSearchToolParameters
37
+ from unique_web_search.services.executors.v2.config import WebSearchV2Config
38
+ from unique_web_search.services.executors.v2.executor import WebSearchV2Executor
39
+ from unique_web_search.services.executors.v2.schema import WebSearchPlan
40
+ from unique_web_search.services.executors.v3.config import WebSearchV3Config
41
+ from unique_web_search.services.executors.v3.executor import WebSearchV3Executor
42
+ from unique_web_search.services.executors.v3.schema import WebSearchV3ToolParameters
43
+
44
+ __all__ = [
45
+ "WebSearchExecutor",
46
+ "WebSearchModeConfig",
47
+ "WebSearchModeStrategy",
48
+ "WebSearchToolContext",
49
+ "WebSearchToolParametersInstance",
50
+ "WebSearchToolParametersType",
51
+ "get_mode_strategy",
52
+ ]
53
+
54
+ WebSearchModeConfig = WebSearchV1Config | WebSearchV2Config | WebSearchV3Config
55
+
56
+ WebSearchToolParametersType = (
57
+ type[WebSearchToolParameters]
58
+ | type[WebSearchPlan]
59
+ | type[WebSearchV3ToolParameters]
60
+ )
61
+
62
+ WebSearchToolParametersInstance = (
63
+ WebSearchToolParameters | WebSearchPlan | WebSearchV3ToolParameters
64
+ )
65
+
66
+ WebSearchExecutor = WebSearchV1Executor | WebSearchV2Executor | WebSearchV3Executor
67
+
68
+ _STRATEGY_FACTORIES: (
69
+ dict[WebSearchMode, Callable[[WebSearchModeConfig], WebSearchModeStrategy]] | None
70
+ ) = None
71
+
72
+
73
+ @dataclass(frozen=True)
74
+ class WebSearchToolContext:
75
+ """Inputs the mode strategy needs to build the LLM-facing tool surface.
76
+
77
+ ``exposed_params_cls`` is resolved once by ``WebSearchTool`` at init so
78
+ strategies do not re-call ``exposed_params_model()``. The engine *mode*
79
+ (standard vs agent) is resolved lazily by the one strategy (V2) that needs
80
+ it, so V1/V3 never pay for a resolution they ignore.
81
+ """
82
+
83
+ search_engine_config: BaseModel
84
+ date_string: str
85
+ exposed_params_cls: type[ExposedParams] | None
86
+
87
+
88
+ class WebSearchModeStrategy(ABC):
89
+ """Mode-specific behaviour for building and running the WebSearch tool."""
90
+
91
+ @abstractmethod
92
+ def build_tool_parameters(
93
+ self, ctx: WebSearchToolContext
94
+ ) -> WebSearchToolParametersType:
95
+ """Build the tool-call parameter model (``query`` plus exposed knobs)."""
96
+
97
+ @abstractmethod
98
+ def tool_description(self, ctx: WebSearchToolContext) -> str:
99
+ """Return the description the model sees when choosing this tool."""
100
+
101
+ @abstractmethod
102
+ def system_prompt(self, ctx: WebSearchToolContext) -> str:
103
+ """Return the tool's system-prompt instructions."""
104
+
105
+ @abstractmethod
106
+ def build_executor(
107
+ self,
108
+ *,
109
+ services: ExecutorServiceContext,
110
+ config: ExecutorConfiguration,
111
+ callbacks: ExecutorCallbacks,
112
+ tool_call: LanguageModelFunction,
113
+ parameters: WebSearchToolParametersInstance,
114
+ exposed_params_cls: type[ExposedParams] | None,
115
+ ) -> WebSearchExecutor:
116
+ """Construct the executor that runs a validated tool call."""
117
+
118
+ def format_information_for_system_prompt(self, *, default: str) -> str:
119
+ """Return citation/format instructions; falls back to the tool default."""
120
+ return default
121
+
122
+ def build_display_name(
123
+ self,
124
+ *,
125
+ base_display_name: str,
126
+ parameters: WebSearchToolParametersInstance,
127
+ ) -> str:
128
+ """Return the runtime display name for a tool call."""
129
+ return base_display_name
130
+
131
+
132
+ def _strategy_factories() -> dict[
133
+ WebSearchMode, Callable[[WebSearchModeConfig], WebSearchModeStrategy]
134
+ ]:
135
+ global _STRATEGY_FACTORIES
136
+ if _STRATEGY_FACTORIES is None:
137
+ from unique_web_search.services.executors.v1.strategy import (
138
+ WebSearchV1Strategy,
139
+ )
140
+ from unique_web_search.services.executors.v2.strategy import (
141
+ WebSearchV2Strategy,
142
+ )
143
+ from unique_web_search.services.executors.v3.strategy import (
144
+ WebSearchV3Strategy,
145
+ )
146
+
147
+ _STRATEGY_FACTORIES = {
148
+ WebSearchMode.V1: lambda cfg: WebSearchV1Strategy(
149
+ cast(WebSearchV1Config, cfg),
150
+ ),
151
+ WebSearchMode.V2: lambda cfg: WebSearchV2Strategy(
152
+ cast(WebSearchV2Config, cfg),
153
+ ),
154
+ WebSearchMode.V3: lambda cfg: WebSearchV3Strategy(
155
+ cast(WebSearchV3Config, cfg),
156
+ ),
157
+ }
158
+ return _STRATEGY_FACTORIES
159
+
160
+
161
+ def get_mode_strategy(mode_config: WebSearchModeConfig) -> WebSearchModeStrategy:
162
+ """Resolve the strategy for the configured WebSearch mode."""
163
+ factory = _strategy_factories()[mode_config.mode]
164
+ return factory(mode_config)
@@ -1,17 +1,15 @@
1
1
  from unique_web_search.services.executors.v1.config import (
2
2
  QueryRefinementConfig,
3
3
  RefineQueryMode,
4
- WebSearchToolParametersDescriptionConfig,
5
4
  WebSearchV1Config,
6
5
  )
7
- from unique_web_search.services.executors.v1.executor import (
8
- WebSearchV1Executor,
9
- )
6
+ from unique_web_search.services.executors.v1.executor import WebSearchV1Executor
7
+ from unique_web_search.services.executors.v1.schema import WebSearchToolParameters
10
8
 
11
9
  __all__ = [
12
10
  "QueryRefinementConfig",
13
11
  "RefineQueryMode",
14
- "WebSearchToolParametersDescriptionConfig",
15
12
  "WebSearchV1Config",
16
13
  "WebSearchV1Executor",
14
+ "WebSearchToolParameters",
17
15
  ]
@@ -15,7 +15,6 @@ from unique_web_search.services.executors.v1.prompts import (
15
15
  DEFAULT_TOOL_DESCRIPTION,
16
16
  DEFAULT_TOOL_DESCRIPTION_FOR_SYSTEM_PROMPT,
17
17
  REFINE_QUERY_SYSTEM_PROMPT,
18
- RESTRICT_DATE_DESCRIPTION,
19
18
  )
20
19
  from unique_web_search.settings import env_settings
21
20
 
@@ -26,34 +25,6 @@ class RefineQueryMode(StrEnum):
26
25
  DEACTIVATED = "Deactivated"
27
26
 
28
27
 
29
- _DEFAULT_QUERY_DESCRIPTION = "The search query to issue to the web."
30
-
31
-
32
- class WebSearchToolParametersDescriptionConfig(BaseModel):
33
- model_config = get_configuration_dict()
34
-
35
- query_description: Annotated[
36
- str,
37
- RJSFMetaTag.StringWidget.textarea(
38
- rows=len(_DEFAULT_QUERY_DESCRIPTION.split("\n"))
39
- ),
40
- ] = Field(
41
- default=_DEFAULT_QUERY_DESCRIPTION,
42
- title="Query Parameter Description",
43
- description="Advanced: Description of the search query parameter shown to the AI model.",
44
- )
45
- date_restrict_description: Annotated[
46
- str,
47
- RJSFMetaTag.StringWidget.textarea(
48
- rows=len(RESTRICT_DATE_DESCRIPTION.split("\n"))
49
- ),
50
- ] = Field(
51
- default=RESTRICT_DATE_DESCRIPTION,
52
- title="Date Filter Description",
53
- description="Advanced: Description of the date restriction parameter shown to the AI model.",
54
- )
55
-
56
-
57
28
  class QueryRefinementConfig(BaseModel):
58
29
  model_config = get_configuration_dict()
59
30
 
@@ -101,12 +72,6 @@ class WebSearchV1Config(BaseWebSearchModeConfig[WebSearchMode.V1]):
101
72
  description="Maximum number of separate searches to run per user request. Only applies when Query Refinement is set to Advanced.",
102
73
  )
103
74
 
104
- tool_parameters_description: WebSearchToolParametersDescriptionConfig = Field(
105
- default_factory=WebSearchToolParametersDescriptionConfig,
106
- title="Search Parameter Descriptions",
107
- description="Advanced: Descriptions of each search parameter, shown to the AI model.",
108
- )
109
-
110
75
  tool_description: Annotated[
111
76
  str,
112
77
  RJSFMetaTag.StringWidget.textarea(