unique-search-proxy 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 (110) hide show
  1. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/PKG-INFO +4 -4
  2. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/README.md +1 -1
  3. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/pyproject.toml +3 -3
  4. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/search_engines/__init__.py +0 -6
  5. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/search_engines/brave/__init__.py +1 -5
  6. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/search_engines/brave/query_params.py +1 -2
  7. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/search_engines/brave/service.py +0 -15
  8. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/search_engines/descriptor.py +0 -6
  9. unique_search_proxy-2026.30.0.dev2/unique_search_proxy_client/web/core/search_engines/factory.py +40 -0
  10. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/search_engines/google/__init__.py +1 -5
  11. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/search_engines/google/query_params.py +1 -2
  12. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/search_engines/google/service.py +0 -16
  13. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/search_engines/perplexity/__init__.py +1 -5
  14. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/search_engines/perplexity/request_body.py +19 -2
  15. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/search_engines/perplexity/service.py +0 -15
  16. unique_search_proxy-2026.30.0.dev0/unique_search_proxy_client/web/core/search_engines/factory.py +0 -89
  17. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/__init__.py +0 -0
  18. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/__init__.py +0 -0
  19. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/api/__init__.py +0 -0
  20. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/api/health.py +0 -0
  21. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/api/v1/__init__.py +0 -0
  22. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/api/v1/agent_search.py +0 -0
  23. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/api/v1/configuration.py +0 -0
  24. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/api/v1/crawl.py +0 -0
  25. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/api/v1/openapi_examples.py +0 -0
  26. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/api/v1/search.py +0 -0
  27. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/app.py +0 -0
  28. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/__init__.py +0 -0
  29. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/agent_engines/__init__.py +0 -0
  30. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/agent_engines/bing/client.py +0 -0
  31. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/agent_engines/bing/runner.py +0 -0
  32. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/agent_engines/bing/service.py +0 -0
  33. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/agent_engines/factory.py +0 -0
  34. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/agent_engines/serialization.py +0 -0
  35. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/agent_engines/service_base.py +0 -0
  36. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/agent_engines/structured_output.py +0 -0
  37. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/agent_engines/vertexai/client.py +0 -0
  38. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/agent_engines/vertexai/gemini.py +0 -0
  39. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/agent_engines/vertexai/service.py +0 -0
  40. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/client/__init__.py +0 -0
  41. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/client/service.py +0 -0
  42. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/crawlers/__init__.py +0 -0
  43. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/crawlers/basic/__init__.py +0 -0
  44. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/crawlers/basic/processing/__init__.py +0 -0
  45. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/crawlers/basic/processing/errors.py +0 -0
  46. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/crawlers/basic/processing/html_markdown.py +0 -0
  47. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/crawlers/basic/processing/processors/__init__.py +0 -0
  48. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/crawlers/basic/processing/processors/html.py +0 -0
  49. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/crawlers/basic/processing/processors/pdf.py +0 -0
  50. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/crawlers/basic/processing/processors/plain_text.py +0 -0
  51. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/crawlers/basic/processing/registry.py +0 -0
  52. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/crawlers/basic/service.py +0 -0
  53. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/crawlers/basic/settings.py +0 -0
  54. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/crawlers/basic/user_agent.py +0 -0
  55. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/crawlers/factory.py +0 -0
  56. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/crawlers/firecrawl/polling.py +0 -0
  57. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/crawlers/firecrawl/request_body.py +0 -0
  58. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/crawlers/firecrawl/service.py +0 -0
  59. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/crawlers/jina/request_body.py +0 -0
  60. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/crawlers/jina/service.py +0 -0
  61. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/crawlers/pinned_egress.py +0 -0
  62. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/crawlers/tavily/request_body.py +0 -0
  63. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/crawlers/tavily/service.py +0 -0
  64. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/provider_response.py +0 -0
  65. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/providers.py +0 -0
  66. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/registry.py +0 -0
  67. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/search_engines/brave/pagination.py +0 -0
  68. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/search_engines/google/pagination.py +0 -0
  69. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/search_engines/pagination.py +0 -0
  70. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/search_engines/service_base.py +0 -0
  71. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/url_safety/__init__.py +0 -0
  72. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/core/url_safety/gate.py +0 -0
  73. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/error_handlers.py +0 -0
  74. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/helm/__init__.py +0 -0
  75. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/helm/generator/__init__.py +0 -0
  76. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/helm/generator/introspect.py +0 -0
  77. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/helm/generator/schema.py +0 -0
  78. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/helm/generator/template.py +0 -0
  79. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/helm/generator/templates/provider_values_yaml.j2 +0 -0
  80. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/helm/generator/values_yaml.py +0 -0
  81. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/helm/metadata.py +0 -0
  82. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/helm/registry.py +0 -0
  83. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/helm/url_safety_registration.py +0 -0
  84. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/logging_config.py +0 -0
  85. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/monitoring/__init__.py +0 -0
  86. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/monitoring/metrics.py +0 -0
  87. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/monitoring/setup.py +0 -0
  88. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/presets/__init__.py +0 -0
  89. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/presets/common.py +0 -0
  90. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/presets/crawl.py +0 -0
  91. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/presets/search.py +0 -0
  92. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/presets/types.py +0 -0
  93. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/settings/__init__.py +0 -0
  94. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/settings/base.py +0 -0
  95. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/settings/client.py +0 -0
  96. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/settings/monitoring.py +0 -0
  97. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/settings/providers/__init__.py +0 -0
  98. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/settings/providers/base.py +0 -0
  99. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/settings/providers/bing_agent.py +0 -0
  100. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/settings/providers/brave.py +0 -0
  101. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/settings/providers/firecrawl.py +0 -0
  102. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/settings/providers/google.py +0 -0
  103. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/settings/providers/jina.py +0 -0
  104. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/settings/providers/perplexity.py +0 -0
  105. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/settings/providers/tavily.py +0 -0
  106. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/settings/providers/vertexai_agent.py +0 -0
  107. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/settings/secret_str.py +0 -0
  108. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/startup_report.py +0 -0
  109. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/unique_search_proxy_client/web/utils/__init__.py +0 -0
  110. {unique_search_proxy-2026.30.0.dev0 → unique_search_proxy-2026.30.0.dev2}/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.30.0.dev0
3
+ Version: 2026.30.0.dev2
4
4
  Summary: Web Search Proxy implementation
5
5
  Author: ThePhilAz
6
6
  Author-email: ThePhilAz <rami.azouz@philico.com>
@@ -19,8 +19,8 @@ Requires-Dist: certifi>=2025.11.12,<2027
19
19
  Requires-Dist: google-genai>=1.73.0,<2
20
20
  Requires-Dist: google-auth>=2.43.0,<3
21
21
  Requires-Dist: jinja2>=3.1.6,<4
22
- Requires-Dist: unique-toolkit[monitoring]>=2026.30.0.dev0,<2026.30.0rc0
23
- Requires-Dist: unique-search-proxy-core>=2026.30.0.dev0,<2026.30.0rc0
22
+ Requires-Dist: unique-toolkit[monitoring]>=2026.30.0.dev10,<2026.30.0rc0
23
+ Requires-Dist: unique-search-proxy-core>=2026.30.0.dev2,<2026.30.0rc0
24
24
  Requires-Python: >=3.12
25
25
  Description-Content-Type: text/markdown
26
26
 
@@ -65,7 +65,7 @@ System overview → [../README.md](../README.md)
65
65
 
66
66
  **What the client owns:** HTTP routes, provider registry, credential loading, httpx egress pool, Prometheus, Docker/Helm deployment.
67
67
 
68
- **What it does not own:** Deployment config JSON Schema, LLM call-schema projection, config/invocation merge — those live in core and run in caller processes.
68
+ **What it does not own:** Deployment config JSON Schema, LLM exposed-params derivation, config/invocation merge — those live in core (as config-class methods) and run in caller processes.
69
69
 
70
70
  ---
71
71
 
@@ -39,7 +39,7 @@ System overview → [../README.md](../README.md)
39
39
 
40
40
  **What the client owns:** HTTP routes, provider registry, credential loading, httpx egress pool, Prometheus, Docker/Helm deployment.
41
41
 
42
- **What it does not own:** Deployment config JSON Schema, LLM call-schema projection, config/invocation merge — those live in core and run in caller processes.
42
+ **What it does not own:** Deployment config JSON Schema, LLM exposed-params derivation, config/invocation merge — those live in core (as config-class methods) and run in caller processes.
43
43
 
44
44
  ---
45
45
 
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "unique-search-proxy"
3
- version = "2026.30.0.dev0"
3
+ version = "2026.30.0.dev2"
4
4
  description = "Web Search Proxy implementation"
5
5
  authors = [{ name = "ThePhilAz", email = "rami.azouz@philico.com" }]
6
6
  readme = "README.md"
@@ -21,8 +21,8 @@ dependencies = [
21
21
  "google-genai>=1.73.0,<2",
22
22
  "google-auth>=2.43.0,<3",
23
23
  "jinja2>=3.1.6,<4",
24
- "unique-toolkit[monitoring]>=2026.30.0.dev0,<2026.30.0rc0",
25
- "unique-search-proxy-core>=2026.30.0.dev0,<2026.30.0rc0",
24
+ "unique-toolkit[monitoring]>=2026.30.0.dev10,<2026.30.0rc0",
25
+ "unique-search-proxy-core>=2026.30.0.dev2,<2026.30.0rc0",
26
26
  ]
27
27
 
28
28
  [dependency-groups]
@@ -10,10 +10,7 @@ from unique_search_proxy_client.web.core.search_engines.descriptor import (
10
10
  SearchEngineDescriptor,
11
11
  )
12
12
  from unique_search_proxy_client.web.core.search_engines.factory import (
13
- get_request_model_for_engine,
14
13
  get_search_engine_service,
15
- resolve_engine_call,
16
- resolve_engine_request,
17
14
  )
18
15
  from unique_search_proxy_client.web.core.search_engines.google.service import (
19
16
  GoogleSearchService,
@@ -61,9 +58,6 @@ __all__ = [
61
58
  "PerplexitySearchService",
62
59
  "SearchEngineDescriptor",
63
60
  "SearchEngineType",
64
- "get_request_model_for_engine",
65
61
  "get_search_engine_service",
66
62
  "register_builtin_search_engines",
67
- "resolve_engine_call",
68
- "resolve_engine_request",
69
63
  ]
@@ -1,7 +1,4 @@
1
- from unique_search_proxy_core.search_engines.brave.schema import (
2
- BraveConfig,
3
- brave_request_model,
4
- )
1
+ from unique_search_proxy_core.search_engines.brave.schema import BraveConfig
5
2
 
6
3
  from unique_search_proxy_client.web.core.search_engines.brave.query_params import (
7
4
  build_brave_query_params,
@@ -14,5 +11,4 @@ __all__ = [
14
11
  "BraveConfig",
15
12
  "BraveSearchService",
16
13
  "build_brave_query_params",
17
- "brave_request_model",
18
14
  ]
@@ -15,12 +15,11 @@ def build_brave_query_params(
15
15
  page: PageRequest,
16
16
  ) -> dict[str, Any]:
17
17
  """Assemble the Brave Web Search API query string from the derived request."""
18
- config = BraveConfig()
19
18
  return {
20
19
  "q": query,
21
20
  "count": page.count,
22
21
  "offset": page.offset,
23
- **config.provider_query_params_from(request, by_alias=False),
22
+ **BraveConfig.provider_query_params(request, by_alias=False),
24
23
  }
25
24
 
26
25
 
@@ -19,7 +19,6 @@ from unique_search_proxy_core.search_engines.base import (
19
19
  get_search_engine_mode,
20
20
  )
21
21
  from unique_search_proxy_core.search_engines.brave.schema import (
22
- BraveConfig,
23
22
  BraveSearchRequest,
24
23
  )
25
24
 
@@ -160,20 +159,6 @@ class BraveSearchService(SearchEngineService[BraveSearchRequest]):
160
159
  )
161
160
  return results
162
161
 
163
- @staticmethod
164
- def llm_call_schema(
165
- config: BraveConfig,
166
- *,
167
- strict_required: bool = True,
168
- ) -> type[Any]:
169
- from unique_search_proxy_core.projection import build_llm_call_model
170
-
171
- return build_llm_call_model(
172
- BraveConfig,
173
- config,
174
- strict_required=strict_required,
175
- )
176
-
177
162
 
178
163
  def _brave_headers(api_key: str) -> dict[str, str]:
179
164
  return {
@@ -4,7 +4,6 @@ from dataclasses import dataclass
4
4
  from typing import TYPE_CHECKING, Any
5
5
 
6
6
  from pydantic import BaseModel
7
- from unique_search_proxy_core.projection import build_request_model
8
7
 
9
8
  if TYPE_CHECKING:
10
9
  from unique_search_proxy_core.search_engines.base import SearchEngine
@@ -16,8 +15,3 @@ class SearchEngineDescriptor:
16
15
 
17
16
  config_model: type[BaseModel]
18
17
  service_cls: type[SearchEngine[Any]]
19
-
20
- @property
21
- def request_model(self) -> type[BaseModel]:
22
- """``POST /v1/search`` body derived from ``config_model``."""
23
- return build_request_model(self.config_model)
@@ -0,0 +1,40 @@
1
+ from __future__ import annotations
2
+
3
+ from typing import TYPE_CHECKING, Any
4
+
5
+ from unique_search_proxy_core.search_engines.base import SearchEngine, SearchEngineType
6
+
7
+ from unique_search_proxy_client.web.core.search_engines.brave.service import (
8
+ BraveSearchService,
9
+ )
10
+ from unique_search_proxy_client.web.core.search_engines.google.service import (
11
+ GoogleSearchService,
12
+ )
13
+ from unique_search_proxy_client.web.core.search_engines.perplexity.service import (
14
+ PerplexitySearchService,
15
+ )
16
+
17
+ if TYPE_CHECKING:
18
+ from httpx import AsyncClient
19
+
20
+
21
+ def get_search_engine_service(
22
+ engine: SearchEngineType,
23
+ *,
24
+ http_client: AsyncClient | None = None,
25
+ ) -> SearchEngine[Any]:
26
+ """Instantiate a search engine by registered id (deployment secrets from env)."""
27
+ match engine:
28
+ case SearchEngineType.GOOGLE:
29
+ return GoogleSearchService(http_client=http_client)
30
+ case SearchEngineType.BRAVE:
31
+ return BraveSearchService(http_client=http_client)
32
+ case SearchEngineType.PERPLEXITY:
33
+ return PerplexitySearchService(http_client=http_client)
34
+ case _:
35
+ raise ValueError(f"Unsupported search engine: {engine}")
36
+
37
+
38
+ __all__ = [
39
+ "get_search_engine_service",
40
+ ]
@@ -1,7 +1,4 @@
1
- from unique_search_proxy_core.search_engines.google.schema import (
2
- GoogleConfig,
3
- google_request_model,
4
- )
1
+ from unique_search_proxy_core.search_engines.google.schema import GoogleConfig
5
2
 
6
3
  from unique_search_proxy_client.web.core.search_engines.google.query_params import (
7
4
  build_google_query_params,
@@ -14,5 +11,4 @@ __all__ = [
14
11
  "GoogleConfig",
15
12
  "GoogleSearchService",
16
13
  "build_google_query_params",
17
- "google_request_model",
18
14
  ]
@@ -17,14 +17,13 @@ def build_google_query_params(
17
17
  page: PageRequest,
18
18
  ) -> dict[str, Any]:
19
19
  """Assemble the Google API query string from the derived request + credentials."""
20
- config = GoogleConfig()
21
20
  return {
22
21
  "q": query,
23
22
  "cx": search_engine_id,
24
23
  "key": api_key,
25
24
  "start": page.offset,
26
25
  "num": page.count,
27
- **config.provider_query_params_from(request),
26
+ **GoogleConfig.provider_query_params(request),
28
27
  }
29
28
 
30
29
 
@@ -19,7 +19,6 @@ from unique_search_proxy_core.search_engines.base import (
19
19
  get_search_engine_mode,
20
20
  )
21
21
  from unique_search_proxy_core.search_engines.google.schema import (
22
- GoogleConfig,
23
22
  GoogleSearchRequest,
24
23
  )
25
24
 
@@ -154,18 +153,3 @@ class GoogleSearchService(SearchEngineService[GoogleSearchRequest]):
154
153
  ),
155
154
  )
156
155
  return results
157
-
158
- @staticmethod
159
- def llm_call_schema(
160
- config: GoogleConfig,
161
- *,
162
- strict_required: bool = True,
163
- ) -> type[Any]:
164
-
165
- from unique_search_proxy_core.projection import build_llm_call_model
166
-
167
- return build_llm_call_model(
168
- GoogleConfig,
169
- config,
170
- strict_required=strict_required,
171
- )
@@ -1,7 +1,4 @@
1
- from unique_search_proxy_core.search_engines.perplexity.schema import (
2
- PerplexityConfig,
3
- perplexity_request_model,
4
- )
1
+ from unique_search_proxy_core.search_engines.perplexity.schema import PerplexityConfig
5
2
 
6
3
  from unique_search_proxy_client.web.core.search_engines.perplexity.request_body import (
7
4
  build_perplexity_request_body,
@@ -14,5 +11,4 @@ __all__ = [
14
11
  "PerplexityConfig",
15
12
  "PerplexitySearchService",
16
13
  "build_perplexity_request_body",
17
- "perplexity_request_model",
18
14
  ]
@@ -18,7 +18,6 @@ def build_perplexity_request_body(
18
18
  request: BaseModel,
19
19
  ) -> dict[str, Any]:
20
20
  """Assemble the Perplexity Search API JSON body from the derived request."""
21
- config = PerplexityConfig()
22
21
  fetch_size = getattr(request, "fetch_size", PERPLEXITY_MAX_RESULTS)
23
22
  max_results = min(fetch_size, PERPLEXITY_MAX_RESULTS)
24
23
  if fetch_size > PERPLEXITY_MAX_RESULTS:
@@ -29,11 +28,29 @@ def build_perplexity_request_body(
29
28
  fetch_size,
30
29
  max_results,
31
30
  )
31
+ params = _apply_perplexity_api_rules(
32
+ PerplexityConfig.provider_query_params(request, by_alias=False),
33
+ )
32
34
  return {
33
35
  "query": query,
34
36
  "max_results": max_results,
35
- **config.provider_query_params_from(request, by_alias=False),
37
+ **params,
36
38
  }
37
39
 
38
40
 
41
+ def _apply_perplexity_api_rules(params: dict[str, Any]) -> dict[str, Any]:
42
+ """Enforce Perplexity API parameter constraints on the outgoing body.
43
+
44
+ The API rejects ``search_context_size`` when an explicit token limit
45
+ (``max_tokens`` / ``max_tokens_per_page``) is set, so the context size is
46
+ dropped in that case.
47
+ """
48
+ if (
49
+ params.get("max_tokens") is not None
50
+ or params.get("max_tokens_per_page") is not None
51
+ ):
52
+ params.pop("search_context_size", None)
53
+ return params
54
+
55
+
39
56
  __all__ = ["PERPLEXITY_MAX_RESULTS", "build_perplexity_request_body"]
@@ -19,7 +19,6 @@ from unique_search_proxy_core.search_engines.base import (
19
19
  get_search_engine_mode,
20
20
  )
21
21
  from unique_search_proxy_core.search_engines.perplexity.schema import (
22
- PerplexityConfig,
23
22
  PerplexitySearchRequest,
24
23
  )
25
24
 
@@ -119,20 +118,6 @@ class PerplexitySearchService(SearchEngineService[PerplexitySearchRequest]):
119
118
  )
120
119
  return results
121
120
 
122
- @staticmethod
123
- def llm_call_schema(
124
- config: PerplexityConfig,
125
- *,
126
- strict_required: bool = True,
127
- ) -> type[Any]:
128
- from unique_search_proxy_core.projection import build_llm_call_model
129
-
130
- return build_llm_call_model(
131
- PerplexityConfig,
132
- config,
133
- strict_required=strict_required,
134
- )
135
-
136
121
 
137
122
  def _perplexity_headers(api_key: str) -> dict[str, str]:
138
123
  return {
@@ -1,89 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from typing import TYPE_CHECKING, Any
4
-
5
- from pydantic import BaseModel
6
- from unique_search_proxy_core.search_engines.base import SearchEngine, SearchEngineType
7
- from unique_search_proxy_core.search_engines.config_types import SearchEngineConfigTypes
8
- from unique_search_proxy_core.search_engines.params import merge_config_and_invocation
9
-
10
- from unique_search_proxy_client.web.core.search_engines.brave.service import (
11
- BraveSearchService,
12
- )
13
- from unique_search_proxy_client.web.core.search_engines.google.service import (
14
- GoogleSearchService,
15
- )
16
- from unique_search_proxy_client.web.core.search_engines.perplexity.service import (
17
- PerplexitySearchService,
18
- )
19
-
20
- if TYPE_CHECKING:
21
- from httpx import AsyncClient
22
-
23
-
24
- def get_search_engine_service(
25
- engine: SearchEngineType,
26
- *,
27
- http_client: AsyncClient | None = None,
28
- ) -> SearchEngine[Any]:
29
- """Instantiate a search engine by registered id (deployment secrets from env)."""
30
- match engine:
31
- case SearchEngineType.GOOGLE:
32
- return GoogleSearchService(http_client=http_client)
33
- case SearchEngineType.BRAVE:
34
- return BraveSearchService(http_client=http_client)
35
- case SearchEngineType.PERPLEXITY:
36
- return PerplexitySearchService(http_client=http_client)
37
- case _:
38
- raise ValueError(f"Unsupported search engine: {engine}")
39
-
40
-
41
- def resolve_engine_request(
42
- config: SearchEngineConfigTypes,
43
- invocation: dict[str, object],
44
- ) -> BaseModel:
45
- """Merge deployment config defaults with a partial request dict (callers / tests)."""
46
- match config.engine:
47
- case SearchEngineType.GOOGLE:
48
- return merge_config_and_invocation(
49
- config,
50
- dict(invocation),
51
- engine=SearchEngineType.GOOGLE,
52
- )
53
- case SearchEngineType.BRAVE:
54
- return merge_config_and_invocation(
55
- config,
56
- dict(invocation),
57
- engine=SearchEngineType.BRAVE,
58
- )
59
- case SearchEngineType.PERPLEXITY:
60
- return merge_config_and_invocation(
61
- config,
62
- dict(invocation),
63
- engine=SearchEngineType.PERPLEXITY,
64
- )
65
- case _:
66
- raise ValueError(f"Unsupported search engine: {config.engine}")
67
-
68
-
69
- def get_request_model_for_engine(engine_id: str) -> type[BaseModel]:
70
- from unique_search_proxy_client.web.core.registry import (
71
- get_search_engine_descriptor,
72
- )
73
-
74
- descriptor = get_search_engine_descriptor(engine_id)
75
- if descriptor is None:
76
- raise ValueError(f"No descriptor for search engine: {engine_id}")
77
- return descriptor.request_model
78
-
79
-
80
- # Backward-compatible alias
81
- resolve_engine_call = resolve_engine_request
82
-
83
-
84
- __all__ = [
85
- "get_request_model_for_engine",
86
- "get_search_engine_service",
87
- "resolve_engine_call",
88
- "resolve_engine_request",
89
- ]