unique_web_search 2026.38.0.dev0__tar.gz → 2026.38.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.
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/PKG-INFO +5 -5
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/README.md +1 -1
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/pyproject.toml +4 -4
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/search_engine/README.md +35 -3
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/search_engine/bing.py +20 -20
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/search_engine/utils/grounding/bing/runner.py +0 -1
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/__init__.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/client_settings.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/config.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/invocation_stats.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/metrics.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/prompts.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/schema.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/service.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/_registry.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/argument_screening/__init__.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/argument_screening/config.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/argument_screening/exceptions.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/argument_screening/prompts/__init__.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/argument_screening/prompts/guidelines.j2 +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/argument_screening/prompts/guidelines_with_keywords.j2 +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/argument_screening/prompts/rejection_response.j2 +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/argument_screening/prompts/system_prompt.j2 +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/argument_screening/prompts/user_prompt.j2 +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/argument_screening/service.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/client/proxy_config.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/content_processing/__init__.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/content_processing/cleaning/__init__.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/content_processing/cleaning/character_sanitize.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/content_processing/cleaning/clean.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/content_processing/cleaning/config.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/content_processing/config.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/content_processing/processing_strategies/base.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/content_processing/processing_strategies/config.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/content_processing/processing_strategies/llm_guard_judge.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/content_processing/processing_strategies/llm_keyword_redact.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/content_processing/processing_strategies/llm_process.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/content_processing/processing_strategies/prompts/__init__.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/content_processing/processing_strategies/prompts/judge_and_sanitize_prompt.j2 +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/content_processing/processing_strategies/prompts/judge_prompt.j2 +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/content_processing/processing_strategies/prompts/keyword_extract_prompt.j2 +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/content_processing/processing_strategies/prompts/page_context.j2 +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/content_processing/processing_strategies/prompts/sanitize_rules.j2 +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/content_processing/processing_strategies/prompts/system_prompt.j2 +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/content_processing/processing_strategies/prompts/user_prompt.j2 +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/content_processing/processing_strategies/schema.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/content_processing/processing_strategies/settings.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/content_processing/processing_strategies/truncate.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/content_processing/service.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/crawlers/README.md +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/crawlers/__init__.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/crawlers/base.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/crawlers/basic.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/crawlers/firecrawl.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/crawlers/jina.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/crawlers/registry.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/crawlers/tavily.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/crawlers/url_safety/__init__.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/crawlers/utils.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/executors/README.md +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/executors/__init__.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/executors/base_config.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/executors/base_executor.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/executors/context.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/executors/modes.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/executors/v1/__init__.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/executors/v1/config.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/executors/v1/executor.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/executors/v1/prompts/__init__.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/executors/v1/prompts/refine_query_system_prompt.j2 +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/executors/v1/prompts/tool_description.j2 +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/executors/v1/prompts/tool_description_for_system_prompt.j2 +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/executors/v1/schema.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/executors/v1/strategy.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/executors/v2/__init__.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/executors/v2/config.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/executors/v2/executor.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/executors/v2/prompts/__init__.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/executors/v2/prompts/step_query_description.j2 +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/executors/v2/prompts/tool_description.j2 +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/executors/v2/prompts/tool_description_for_system_prompt.j2 +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/executors/v2/schema.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/executors/v2/strategy.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/executors/v3/__init__.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/executors/v3/config.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/executors/v3/executor.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/executors/v3/prompts/__init__.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/executors/v3/prompts/tool_description.j2 +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/executors/v3/prompts/tool_description_for_system_prompt.j2 +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/executors/v3/schema.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/executors/v3/strategy.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/helpers.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/message_log.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/proxy/__init__.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/proxy/bridge.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/proxy/mappers.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/query_elicitation.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/search_engine/__init__.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/search_engine/base.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/search_engine/brave.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/search_engine/custom_api.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/search_engine/google.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/search_engine/perplexity.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/search_engine/registry.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/search_engine/schema.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/search_engine/utils/google/schema.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/search_engine/utils/grounding/__init__.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/search_engine/utils/grounding/bing/__init__.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/search_engine/utils/grounding/bing/client.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/search_engine/utils/grounding/bing/models.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/search_engine/utils/grounding/models.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/search_engine/utils/grounding/response_parsing.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/search_engine/utils/grounding/vertexai/__init__.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/search_engine/utils/grounding/vertexai/client.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/search_engine/utils/grounding/vertexai/exceptions.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/search_engine/utils/grounding/vertexai/gemini.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/search_engine/utils/grounding/vertexai/response_handler.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/search_engine/vertexai.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/snippet_judge/__init__.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/snippet_judge/prompts.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/snippet_judge/schema.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/snippet_judge/service.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/services/structured_llm.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/settings.py +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/skills/web-search-v3.md +0 -0
- {unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: unique-web-search
|
|
3
|
-
Version: 2026.38.0.
|
|
3
|
+
Version: 2026.38.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>
|
|
@@ -16,7 +16,7 @@ Requires-Dist: tavily-python>=0.7.11,<1
|
|
|
16
16
|
Requires-Dist: unidecode>=1.4.0,<2
|
|
17
17
|
Requires-Dist: azure-ai-projects>=2.3,<3
|
|
18
18
|
Requires-Dist: azure-identity>=1.25.0,<2
|
|
19
|
-
Requires-Dist: unique-toolkit[monitoring]>=2026.38.0.
|
|
19
|
+
Requires-Dist: unique-toolkit[monitoring]>=2026.38.0.dev11,<2026.38.0rc0
|
|
20
20
|
Requires-Dist: azure-core>=1.36.0,<2
|
|
21
21
|
Requires-Dist: google-cloud-aiplatform>=1.128.0,<2
|
|
22
22
|
Requires-Dist: google-auth>=2.43.0,<3
|
|
@@ -25,8 +25,8 @@ Requires-Dist: rapidfuzz>=3.0.0,<4
|
|
|
25
25
|
Requires-Dist: httpx>=0.28.1
|
|
26
26
|
Requires-Dist: certifi>=2025.11.12
|
|
27
27
|
Requires-Dist: jinja2>=3.1.6
|
|
28
|
-
Requires-Dist: unique-search-proxy-core>=2026.38.0.
|
|
29
|
-
Requires-Dist: unique-search-proxy-sdk>=2026.38.0.
|
|
28
|
+
Requires-Dist: unique-search-proxy-core>=2026.38.0.dev3,<2026.38.0rc0
|
|
29
|
+
Requires-Dist: unique-search-proxy-sdk>=2026.38.0.dev2,<2026.38.0rc0
|
|
30
30
|
Requires-Dist: openai>=1.105.0,<3
|
|
31
31
|
Requires-Python: >=3.12, <4.0
|
|
32
32
|
Description-Content-Type: text/markdown
|
|
@@ -75,7 +75,7 @@ An upstream AI agent / grounded model searches and returns opaque text that this
|
|
|
75
75
|
|
|
76
76
|
| Engine | Proxy | Notes |
|
|
77
77
|
|--------|-------|-------|
|
|
78
|
-
| Bing (Azure AI Foundry grounding) | legacy + proxy | Configurable `requires_scraping`; `market` / `
|
|
78
|
+
| Bing (Azure AI Foundry grounding) | legacy + proxy | Configurable `requires_scraping`; fixed `market` / `freshness` chosen by an admin, with `market` falling back to `BING_AGENT_DEFAULT_MARKET` |
|
|
79
79
|
| VertexAI (Gemini grounding) | legacy + proxy | Configurable `requires_scraping` |
|
|
80
80
|
|
|
81
81
|
Bing's grounding knobs are baked into the hashed Foundry agent name, so changing
|
|
@@ -42,7 +42,7 @@ An upstream AI agent / grounded model searches and returns opaque text that this
|
|
|
42
42
|
|
|
43
43
|
| Engine | Proxy | Notes |
|
|
44
44
|
|--------|-------|-------|
|
|
45
|
-
| Bing (Azure AI Foundry grounding) | legacy + proxy | Configurable `requires_scraping`; `market` / `
|
|
45
|
+
| Bing (Azure AI Foundry grounding) | legacy + proxy | Configurable `requires_scraping`; fixed `market` / `freshness` chosen by an admin, with `market` falling back to `BING_AGENT_DEFAULT_MARKET` |
|
|
46
46
|
| VertexAI (Gemini grounding) | legacy + proxy | Configurable `requires_scraping` |
|
|
47
47
|
|
|
48
48
|
Bing's grounding knobs are baked into the hashed Foundry agent name, so changing
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "unique_web_search"
|
|
3
|
-
version = "2026.38.0.
|
|
3
|
+
version = "2026.38.0.dev2"
|
|
4
4
|
description = ""
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.12,<4.0"
|
|
@@ -22,7 +22,7 @@ dependencies = [
|
|
|
22
22
|
"unidecode>=1.4.0,<2",
|
|
23
23
|
"azure-ai-projects>=2.3,<3",
|
|
24
24
|
"azure-identity>=1.25.0,<2",
|
|
25
|
-
"unique-toolkit[monitoring]>=2026.38.0.
|
|
25
|
+
"unique-toolkit[monitoring]>=2026.38.0.dev11,<2026.38.0rc0",
|
|
26
26
|
"azure-core>=1.36.0,<2",
|
|
27
27
|
"google-cloud-aiplatform>=1.128.0,<2",
|
|
28
28
|
"google-auth>=2.43.0,<3",
|
|
@@ -31,8 +31,8 @@ dependencies = [
|
|
|
31
31
|
"httpx>=0.28.1",
|
|
32
32
|
"certifi>=2025.11.12",
|
|
33
33
|
"jinja2>=3.1.6",
|
|
34
|
-
"unique-search-proxy-core>=2026.38.0.
|
|
35
|
-
"unique-search-proxy-sdk>=2026.38.0.
|
|
34
|
+
"unique-search-proxy-core>=2026.38.0.dev3,<2026.38.0rc0",
|
|
35
|
+
"unique-search-proxy-sdk>=2026.38.0.dev2,<2026.38.0rc0",
|
|
36
36
|
"openai>=1.105.0,<3",
|
|
37
37
|
]
|
|
38
38
|
|
|
@@ -151,8 +151,39 @@ CUSTOM_WEB_SEARCH_API_HEADERS='{"Authorization": "Bearer ..."}'
|
|
|
151
151
|
|
|
152
152
|
| Field | Notes |
|
|
153
153
|
|-------|-------|
|
|
154
|
-
| `fetch_size` | Bing result count |
|
|
155
|
-
| `market
|
|
154
|
+
| `fetch_size` | Bing result count (`count` on the tool configuration) |
|
|
155
|
+
| `market` | Region **and** language Bing favours (Bing `mkt`). A bias, not a filter — other regions can still appear |
|
|
156
|
+
| `freshness` | Recency cut-off applied to every search in the space (Bing `freshness`): `Day` / `Week` / `Month` |
|
|
157
|
+
|
|
158
|
+
Both are optional **fixed** values an admin picks for the whole space and are
|
|
159
|
+
never offered to the LLM, and both are restricted to Bing's documented values so
|
|
160
|
+
they render as one dropdown each; blank values are omitted so Bing applies its
|
|
161
|
+
own defaults.
|
|
162
|
+
|
|
163
|
+
`freshness` also accepts absolute days and ranges (`2026-01-01..2026-03-31`),
|
|
164
|
+
which we deliberately do **not** offer: pinned space-wide, an absolute window
|
|
165
|
+
freezes the space to a range that rots the day after it is saved. Presets only
|
|
166
|
+
also keep the admin schema fully enumerated, so a typo cannot save.
|
|
167
|
+
|
|
168
|
+
`BingGroundingSearchConfiguration` also accepts `setLang`, which we deliberately
|
|
169
|
+
do **not** expose: it only localizes the labels Bing puts around results, so an
|
|
170
|
+
admin reading "language" would set it expecting French results and leave `mkt`
|
|
171
|
+
unset. Beyond these, Bing grounding has no `safeSearch`, `responseFilter`, or
|
|
172
|
+
`answerCount`, so `count` / `market` / `freshness` is the whole useful surface.
|
|
173
|
+
|
|
174
|
+
Spaces saved on 2026.36 hold an `ExposableParam` `{expose, value}` object under
|
|
175
|
+
both keys. node-chat data migration
|
|
176
|
+
`20260908120000_drop_bing_grounding_exposable_params` deletes them, and
|
|
177
|
+
`BingAgentConfig` reads that shape as unset for rows the migration has not
|
|
178
|
+
reached — an invalid tool config disables the whole tool silently, so tolerating
|
|
179
|
+
it is not optional. The migration deletes rather than unwraps, which keeps a
|
|
180
|
+
rollback to 2026.36 valid.
|
|
181
|
+
|
|
182
|
+
A blank `market` falls back to the `BING_AGENT_DEFAULT_MARKET` environment
|
|
183
|
+
variable (below), so a deployment serving a single country pins its market once
|
|
184
|
+
instead of per space. With neither set, `mkt` is left off the call entirely and
|
|
185
|
+
Bing may favour the region where the underlying Microsoft Foundry resource is
|
|
186
|
+
deployed.
|
|
156
187
|
|
|
157
188
|
Bing bakes the tool configuration into the *agent version*, so these knobs take
|
|
158
189
|
part in the hashed agent name (`unique-grounding-with-bing-<hash>`): changing one
|
|
@@ -162,7 +193,8 @@ provisions a new agent version instead of reusing a mismatched one.
|
|
|
162
193
|
AZURE_AI_PROJECT_ENDPOINT=...
|
|
163
194
|
AZURE_AI_AGENT_ID=... # optional; empty → auto-provision
|
|
164
195
|
AZURE_IDENTITY_CREDENTIAL_TYPE=workload # or default
|
|
165
|
-
|
|
196
|
+
# Market applied to spaces that fix none; omit to send no market at all.
|
|
197
|
+
BING_AGENT_DEFAULT_MARKET=fr-FR
|
|
166
198
|
```
|
|
167
199
|
|
|
168
200
|
### VertexAI (Grounding with VertexAI)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import asyncio
|
|
2
|
-
from typing import override
|
|
2
|
+
from typing import Any, override
|
|
3
3
|
|
|
4
4
|
from pydantic import Field
|
|
5
5
|
from unique_search_proxy_core.agent_engines.base import AgentEngineType
|
|
@@ -7,10 +7,8 @@ from unique_search_proxy_core.agent_engines.bing.grounding import (
|
|
|
7
7
|
BingGroundingConfiguration,
|
|
8
8
|
)
|
|
9
9
|
from unique_search_proxy_core.agent_engines.bing.schema import BingAgentConfig
|
|
10
|
+
from unique_search_proxy_core.agent_engines.bing.settings import resolve_market
|
|
10
11
|
from unique_search_proxy_core.context import LOCAL_REQUEST_CONTEXT, RequestContext
|
|
11
|
-
from unique_search_proxy_core.param_policy.exposable_param import (
|
|
12
|
-
resolve_exposable_value,
|
|
13
|
-
)
|
|
14
12
|
from unique_search_proxy_core.param_policy.exposed_params import ExposedParams
|
|
15
13
|
from unique_toolkit._common.default_language_model import DEFAULT_LANGUAGE_MODEL
|
|
16
14
|
from unique_toolkit._common.validators import LMI, get_LMI_default_field
|
|
@@ -88,25 +86,27 @@ class BingSearch(SearchEngine[BingSearchConfig]):
|
|
|
88
86
|
def requires_scraping(self) -> bool:
|
|
89
87
|
return self.config.requires_scraping
|
|
90
88
|
|
|
91
|
-
def _grounding_configuration(
|
|
92
|
-
|
|
93
|
-
params: ExposedParams | None,
|
|
94
|
-
) -> BingGroundingConfiguration:
|
|
95
|
-
"""Resolve the Bing tool knobs from deployment defaults + LLM overrides."""
|
|
96
|
-
overrides = params.model_dump(exclude_none=True) if params else {}
|
|
97
|
-
|
|
98
|
-
def knob(field_name: str) -> str | None:
|
|
99
|
-
if field_name in overrides:
|
|
100
|
-
return overrides[field_name]
|
|
101
|
-
return resolve_exposable_value(getattr(self.config, field_name))
|
|
102
|
-
|
|
89
|
+
def _grounding_configuration(self) -> BingGroundingConfiguration:
|
|
90
|
+
"""The Bing tool knobs this space has fixed, with the market resolved."""
|
|
103
91
|
return BingGroundingConfiguration(
|
|
104
92
|
fetch_size=self.config.fetch_size,
|
|
105
|
-
market=
|
|
106
|
-
|
|
107
|
-
freshness=knob("freshness"),
|
|
93
|
+
market=resolve_market(self.config.market),
|
|
94
|
+
freshness=self.config.freshness,
|
|
108
95
|
)
|
|
109
96
|
|
|
97
|
+
@override
|
|
98
|
+
def _agent_proxy_invocation(
|
|
99
|
+
self,
|
|
100
|
+
engine: AgentEngineType,
|
|
101
|
+
params: ExposedParams | None,
|
|
102
|
+
) -> dict[str, Any]:
|
|
103
|
+
"""Resolve the market here too, so the env default works on either service."""
|
|
104
|
+
invocation = super()._agent_proxy_invocation(engine, params)
|
|
105
|
+
market = resolve_market(invocation.get("market"))
|
|
106
|
+
if market is not None:
|
|
107
|
+
invocation["market"] = market
|
|
108
|
+
return invocation
|
|
109
|
+
|
|
110
110
|
@override
|
|
111
111
|
async def _legacy_search(
|
|
112
112
|
self,
|
|
@@ -119,7 +119,7 @@ class BingSearch(SearchEngine[BingSearchConfig]):
|
|
|
119
119
|
search_results = await create_and_process_run(
|
|
120
120
|
agent_client,
|
|
121
121
|
query=query,
|
|
122
|
-
grounding=self._grounding_configuration(
|
|
122
|
+
grounding=self._grounding_configuration(),
|
|
123
123
|
response_parsers_strategies=self.response_parsers,
|
|
124
124
|
generation_instructions=self.config.generation_instructions,
|
|
125
125
|
)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{unique_web_search-2026.38.0.dev0 → unique_web_search-2026.38.0.dev2}/src/unique_web_search/utils.py
RENAMED
|
File without changes
|