unique-search-proxy 2026.44.0.dev5__tar.gz → 2026.44.0.dev7__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 (118) hide show
  1. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/PKG-INFO +2 -2
  2. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/pyproject.toml +2 -2
  3. unique_search_proxy-2026.44.0.dev7/unique_search_proxy_client/web/core/agent_engines/vertexai/redirects.py +30 -0
  4. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/agent_engines/vertexai/service.py +13 -3
  5. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/crawlers/basic/service.py +12 -12
  6. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/crawlers/jina/service.py +1 -2
  7. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/search_engines/brave/service.py +1 -1
  8. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/search_engines/google/service.py +1 -1
  9. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/search_engines/perplexity/service.py +1 -1
  10. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/README.md +0 -0
  11. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/__init__.py +0 -0
  12. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/__init__.py +0 -0
  13. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/api/__init__.py +0 -0
  14. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/api/health.py +0 -0
  15. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/api/v1/__init__.py +0 -0
  16. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/api/v1/agent_search.py +0 -0
  17. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/api/v1/configuration.py +0 -0
  18. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/api/v1/context_headers.py +0 -0
  19. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/api/v1/crawl.py +0 -0
  20. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/api/v1/openapi_examples.py +0 -0
  21. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/api/v1/search.py +0 -0
  22. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/app.py +0 -0
  23. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/context.py +0 -0
  24. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/__init__.py +0 -0
  25. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/agent_engines/__init__.py +0 -0
  26. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/agent_engines/bing/cleanup.py +0 -0
  27. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/agent_engines/bing/client.py +0 -0
  28. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/agent_engines/bing/runner.py +0 -0
  29. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/agent_engines/bing/service.py +0 -0
  30. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/agent_engines/factory.py +0 -0
  31. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/agent_engines/service_base.py +0 -0
  32. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/agent_engines/structured_output.py +0 -0
  33. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/agent_engines/vertexai/client.py +0 -0
  34. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/agent_engines/vertexai/gemini.py +0 -0
  35. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/client/__init__.py +0 -0
  36. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/client/azure_transport.py +0 -0
  37. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/client/credentials.py +0 -0
  38. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/client/service.py +0 -0
  39. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/crawlers/__init__.py +0 -0
  40. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/crawlers/basic/__init__.py +0 -0
  41. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/crawlers/basic/processing/__init__.py +0 -0
  42. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/crawlers/basic/processing/errors.py +0 -0
  43. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/crawlers/basic/processing/html_markdown.py +0 -0
  44. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/crawlers/basic/processing/processors/__init__.py +0 -0
  45. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/crawlers/basic/processing/processors/html.py +0 -0
  46. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/crawlers/basic/processing/processors/pdf.py +0 -0
  47. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/crawlers/basic/processing/processors/plain_text.py +0 -0
  48. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/crawlers/basic/processing/registry.py +0 -0
  49. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/crawlers/basic/settings.py +0 -0
  50. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/crawlers/basic/user_agent.py +0 -0
  51. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/crawlers/factory.py +0 -0
  52. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/crawlers/firecrawl/polling.py +0 -0
  53. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/crawlers/firecrawl/request_body.py +0 -0
  54. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/crawlers/firecrawl/service.py +0 -0
  55. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/crawlers/jina/request_body.py +0 -0
  56. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/crawlers/pinned_egress.py +0 -0
  57. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/crawlers/tavily/request_body.py +0 -0
  58. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/crawlers/tavily/service.py +0 -0
  59. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/provider_response.py +0 -0
  60. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/providers.py +0 -0
  61. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/registry.py +0 -0
  62. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/search_engines/__init__.py +0 -0
  63. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/search_engines/brave/__init__.py +0 -0
  64. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/search_engines/brave/pagination.py +0 -0
  65. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/search_engines/brave/query_params.py +0 -0
  66. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/search_engines/custom_api/__init__.py +0 -0
  67. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/search_engines/custom_api/service.py +0 -0
  68. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/search_engines/descriptor.py +0 -0
  69. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/search_engines/factory.py +0 -0
  70. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/search_engines/google/__init__.py +0 -0
  71. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/search_engines/google/pagination.py +0 -0
  72. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/search_engines/google/query_params.py +0 -0
  73. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/search_engines/pagination.py +0 -0
  74. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/search_engines/perplexity/__init__.py +0 -0
  75. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/search_engines/perplexity/request_body.py +0 -0
  76. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/search_engines/service_base.py +0 -0
  77. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/url_safety/__init__.py +0 -0
  78. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/core/url_safety/gate.py +0 -0
  79. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/error_handlers.py +0 -0
  80. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/helm/__init__.py +0 -0
  81. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/helm/generator/__init__.py +0 -0
  82. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/helm/generator/introspect.py +0 -0
  83. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/helm/generator/schema.py +0 -0
  84. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/helm/generator/template.py +0 -0
  85. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/helm/generator/templates/provider_values_yaml.j2 +0 -0
  86. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/helm/generator/values_yaml.py +0 -0
  87. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/helm/metadata.py +0 -0
  88. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/helm/registry.py +0 -0
  89. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/helm/url_safety_registration.py +0 -0
  90. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/logging_config.py +0 -0
  91. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/middleware/context.py +0 -0
  92. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/monitoring/__init__.py +0 -0
  93. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/monitoring/metrics.py +0 -0
  94. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/monitoring/setup.py +0 -0
  95. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/presets/__init__.py +0 -0
  96. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/presets/common.py +0 -0
  97. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/presets/crawl.py +0 -0
  98. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/presets/search.py +0 -0
  99. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/presets/types.py +0 -0
  100. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/settings/__init__.py +0 -0
  101. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/settings/app.py +0 -0
  102. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/settings/base.py +0 -0
  103. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/settings/client.py +0 -0
  104. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/settings/monitoring.py +0 -0
  105. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/settings/providers/__init__.py +0 -0
  106. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/settings/providers/base.py +0 -0
  107. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/settings/providers/bing_agent.py +0 -0
  108. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/settings/providers/brave.py +0 -0
  109. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/settings/providers/firecrawl.py +0 -0
  110. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/settings/providers/google.py +0 -0
  111. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/settings/providers/jina.py +0 -0
  112. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/settings/providers/perplexity.py +0 -0
  113. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/settings/providers/tavily.py +0 -0
  114. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/settings/providers/vertexai_agent.py +0 -0
  115. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/settings/secret_str.py +0 -0
  116. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/startup_report.py +0 -0
  117. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/utils/__init__.py +0 -0
  118. {unique_search_proxy-2026.44.0.dev5 → unique_search_proxy-2026.44.0.dev7}/unique_search_proxy_client/web/utils/url.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: unique-search-proxy
3
- Version: 2026.44.0.dev5
3
+ Version: 2026.44.0.dev7
4
4
  Summary: Web Search Proxy implementation
5
5
  Author: ThePhilAz
6
6
  Author-email: ThePhilAz <rami.azouz@philico.com>
@@ -21,7 +21,7 @@ Requires-Dist: google-genai>=1.73.0,<2
21
21
  Requires-Dist: google-auth>=2.43.0,<3
22
22
  Requires-Dist: jinja2>=3.1.6,<4
23
23
  Requires-Dist: unique-toolkit[monitoring]>=2026.44.0.dev9,<2026.44.0rc0
24
- Requires-Dist: unique-search-proxy-core>=2026.44.0.dev4,<2026.44.0rc0
24
+ Requires-Dist: unique-search-proxy-core>=2026.44.0.dev6,<2026.44.0rc0
25
25
  Requires-Dist: openai>=1.105.0,<3
26
26
  Requires-Python: >=3.12
27
27
  Description-Content-Type: text/markdown
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "unique-search-proxy"
3
- version = "2026.44.0.dev5"
3
+ version = "2026.44.0.dev7"
4
4
  description = "Web Search Proxy implementation"
5
5
  authors = [{ name = "ThePhilAz", email = "rami.azouz@philico.com" }]
6
6
  readme = "README.md"
@@ -23,7 +23,7 @@ dependencies = [
23
23
  "google-auth>=2.43.0,<3",
24
24
  "jinja2>=3.1.6,<4",
25
25
  "unique-toolkit[monitoring]>=2026.44.0.dev9,<2026.44.0rc0",
26
- "unique-search-proxy-core>=2026.44.0.dev4,<2026.44.0rc0",
26
+ "unique-search-proxy-core>=2026.44.0.dev6,<2026.44.0rc0",
27
27
  "openai>=1.105.0,<3",
28
28
  ]
29
29
 
@@ -0,0 +1,30 @@
1
+ from __future__ import annotations
2
+
3
+ from httpx import AsyncClient
4
+ from unique_search_proxy_core.agent_engines.output_schema import AgentSearchOutput
5
+ from unique_search_proxy_core.url_safety import UrlSafetyService
6
+
7
+
8
+ async def resolve_vertex_result_urls(
9
+ answer: str,
10
+ *,
11
+ http_client: AsyncClient,
12
+ ) -> str:
13
+ """Resolve structured Vertex result URLs through Search Proxy URL safety."""
14
+ try:
15
+ output = AgentSearchOutput.model_validate_json(answer)
16
+ except ValueError:
17
+ return answer
18
+
19
+ outcomes = await UrlSafetyService.validate_urls_individually(
20
+ [result.source_url for result in output.results],
21
+ redirect_http_client=http_client,
22
+ )
23
+ for result, outcome in zip(output.results, outcomes, strict=True):
24
+ if outcome.resolved is not None:
25
+ result.source_url = outcome.resolved.normalized_url
26
+
27
+ return output.model_dump_json()
28
+
29
+
30
+ __all__ = ["resolve_vertex_result_urls"]
@@ -4,6 +4,7 @@ import logging
4
4
  from collections.abc import AsyncIterator
5
5
  from typing import Any
6
6
 
7
+ from httpx import AsyncClient
7
8
  from unique_search_proxy_core.agent_engines.base import AgentEngineType
8
9
  from unique_search_proxy_core.agent_engines.resolve import (
9
10
  resolve_output_schema_for_engine,
@@ -30,6 +31,9 @@ from unique_search_proxy_client.web.core.agent_engines.vertexai.gemini import (
30
31
  serialize_vertex_response,
31
32
  stream_vertexai_response,
32
33
  )
34
+ from unique_search_proxy_client.web.core.agent_engines.vertexai.redirects import (
35
+ resolve_vertex_result_urls,
36
+ )
33
37
  from unique_search_proxy_client.web.core.provider_response import transport_error_raw
34
38
 
35
39
  _LOGGER = logging.getLogger(__name__)
@@ -40,9 +44,10 @@ class VertexAIAgentSearchService(
40
44
  ):
41
45
  engine_id = AgentEngineType.VERTEXAI.value
42
46
 
43
- def __init__(self, **kwargs: Any) -> None:
44
- super().__init__(**kwargs)
45
- self._client = get_vertex_client(self._http_client)
47
+ def __init__(self, *, http_client: AsyncClient) -> None:
48
+ super().__init__(http_client=http_client)
49
+ self._egress_http_client = http_client
50
+ self._client = get_vertex_client(http_client)
46
51
 
47
52
  async def search(self, request: VertexAIAgentSearchRequest) -> AgentSearchResponse: # type: ignore[override]
48
53
  response: AgentSearchResponse | None = None
@@ -52,6 +57,11 @@ class VertexAIAgentSearchService(
52
57
  if response is None:
53
58
  msg = "VertexAI agent search stream ended without a done event"
54
59
  raise UpstreamError(msg)
60
+ if request.enable_redirect_resolution:
61
+ response.answer = await resolve_vertex_result_urls(
62
+ response.answer,
63
+ http_client=self._egress_http_client,
64
+ )
55
65
  return response
56
66
 
57
67
  async def stream(
@@ -124,7 +124,10 @@ class BasicCrawlerService(BaseCrawler[BasicCrawlRequest]):
124
124
  )
125
125
  return crawl_forbidden_target(display_url, blocked.reason)
126
126
  except httpx.TimeoutException as exc:
127
- _LOGGER.warning("Basic crawl timed out for %s: %s", display_url, exc)
127
+ _LOGGER.warning(
128
+ "Basic crawl timed out error_type=%s",
129
+ type(exc).__name__,
130
+ )
128
131
  return crawl_upstream_error(
129
132
  display_url,
130
133
  f"Crawl timed out after {timeout}s",
@@ -133,7 +136,10 @@ class BasicCrawlerService(BaseCrawler[BasicCrawlRequest]):
133
136
  raw=transport_error_raw(exc),
134
137
  )
135
138
  except httpx.HTTPError as exc:
136
- _LOGGER.warning("Basic crawl failed for %s: %s", display_url, exc)
139
+ _LOGGER.warning(
140
+ "Basic crawl failed error_type=%s",
141
+ type(exc).__name__,
142
+ )
137
143
  return crawl_upstream_error(
138
144
  display_url,
139
145
  str(exc),
@@ -145,8 +151,7 @@ class BasicCrawlerService(BaseCrawler[BasicCrawlRequest]):
145
151
  raw_body = response.text
146
152
  if response.is_error:
147
153
  _LOGGER.warning(
148
- "Basic crawl HTTP error for %s: %s",
149
- display_url,
154
+ "Basic crawl HTTP error http_status=%s",
150
155
  response.status_code,
151
156
  )
152
157
  return crawl_upstream_error(
@@ -195,11 +200,7 @@ class BasicCrawlerService(BaseCrawler[BasicCrawlRequest]):
195
200
  timeout=float(timeout),
196
201
  )
197
202
  except ContentProcessingTimeoutError as exc:
198
- _LOGGER.warning(
199
- "Basic crawl processing timed out for %s: %s",
200
- request_url,
201
- exc,
202
- )
203
+ _LOGGER.warning("Basic crawl processing timed out: %s", exc)
203
204
  return crawl_upstream_error(
204
205
  request_url,
205
206
  str(exc),
@@ -209,9 +210,8 @@ class BasicCrawlerService(BaseCrawler[BasicCrawlRequest]):
209
210
  )
210
211
  except ContentProcessingError as exc:
211
212
  _LOGGER.warning(
212
- "Basic crawl processing failed for %s: %s",
213
- request_url,
214
- exc,
213
+ "Basic crawl processing failed error_type=%s",
214
+ type(exc.__cause__ or exc).__name__,
215
215
  )
216
216
  return crawl_upstream_error(
217
217
  request_url,
@@ -139,8 +139,7 @@ class JinaCrawlerService(BaseCrawler[JinaCrawlRequest]):
139
139
  if reader_response.code != 200:
140
140
  message = _jina_reader_error_message(payload, reader_response.code)
141
141
  _LOGGER.warning(
142
- "Jina reader failure url=%s endpoint=%s http_status=%s code=%s",
143
- url,
142
+ "Jina reader failure endpoint=%s http_status=%s code=%s",
144
143
  credentials.reader_endpoint,
145
144
  response.status_code,
146
145
  reader_response.code,
@@ -81,7 +81,7 @@ class BraveSearchService(SearchEngineService[BraveSearchRequest]):
81
81
  if not page_results:
82
82
  if not len(curated.results):
83
83
  raise EmptySearchResultsError(
84
- f"Brave search returned no results for query {request.query!r}",
84
+ "Brave search returned no results",
85
85
  )
86
86
  break
87
87
  curated = curated.extend(page_results)
@@ -82,7 +82,7 @@ class GoogleSearchService(SearchEngineService[GoogleSearchRequest]):
82
82
  if not page_results:
83
83
  if not len(curated.results):
84
84
  raise EmptySearchResultsError(
85
- f"Google search returned no results for query {request.query!r}",
85
+ "Google search returned no results",
86
86
  )
87
87
  break
88
88
  curated = curated.extend(page_results)
@@ -93,7 +93,7 @@ class PerplexitySearchService(SearchEngineService[PerplexitySearchRequest]):
93
93
  curated = WebSearchResults(results=self._extract_results(payload))
94
94
  if not curated.results:
95
95
  raise EmptySearchResultsError(
96
- f"Perplexity search returned no results for query {request.query!r}",
96
+ "Perplexity search returned no results",
97
97
  )
98
98
 
99
99
  curated = curated.dedupe()