Skip to content

Feature/fuzzy model matching#108

Merged
OEvortex merged 7 commits intomainfrom
feature/fuzzy-model-matching
Dec 19, 2025
Merged

Feature/fuzzy model matching#108
OEvortex merged 7 commits intomainfrom
feature/fuzzy-model-matching

Conversation

@OEvortex
Copy link
Owner

This pull request introduces several improvements, new features, and maintenance updates across the project, focusing on enhancing the unified client interface, expanding provider support, and cleaning up the provider registry. The most significant change is the removal of the GeminiProxy provider, with all related documentation and references updated accordingly. Additional notable improvements include robust model discovery and failover logic in the client, new OpenAI-compatible providers, and fixes for HTTP header handling in several providers.

Provider registry and documentation cleanup:

  • Removed the GeminiProxy provider implementation (webscout/Provider/GeminiProxy.py), its documentation entries in Provider.md and webscout/Provider/OPENAI/README.md, and all references from the provider registry. This also updates provider counts and statistics throughout the documentation. [1] [2] [3] [4] [5]

Client and core feature enhancements:

  • Enhanced the unified client interface (webscout/client.py) to support OpenAI-compatible chat completions, unified image generation, intelligent model resolution (including fuzzy model matching), simplified authentication detection, improved auto-failover (including on empty responses), dynamic provider discovery, and support for custom exclusion lists.
  • Improved model discovery logic in the client to robustly handle various model listing mechanisms and cleaned up internal implementation.
  • Added support for tools/tool calling and dynamic model fetching, and integrated LitAgent for browser fingerprinting.

Provider additions and improvements:

  • Added new OpenAI-compatible providers: TypliAI, Easemate, and FreeAssist, including streaming and non-streaming support for multiple advanced models.
  • Refactored Sambanova provider to align with the TextPollinationsAI pattern, implemented robust SSE parsing, and added dynamic model fetching with update_available_models.

Bug fixes and maintenance:

  • Fixed the "Accept-Encoding" HTTP header in several OpenAI-compatible providers to prevent decompression errors and empty responses. [1] [2] [3] [4] [5] [6]
  • Various minor documentation, statistics, and code cleanups, including updating provider model lists and removing unused code in provider implementations. [1] [2] [3]

These changes collectively streamline provider management, improve reliability and flexibility for end users, and keep the documentation accurate and up to date.

- Added fuzzy search logic to ClientCompletions using difflib for better model resolution.
- Improved model discovery to safely handle class attributes, instance properties, and .models.list() methods.
- Enhanced Client initialization to include auth-required providers when an API key is present.
- Updated changelog with new features and improvements.
- Added verify_fuzzy.py for real-world verification of resolution logic.
…olution and add multiple new OpenAI-compatible providers, fixing Accept-Encoding issues.
…ulti-provider chat completions and image generation.
…rface and fixing provider issues

Signed-off-by: OEvortex <[email protected]>
Copilot AI review requested due to automatic review settings December 19, 2025 05:26
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This pull request introduces a major enhancement to the webscout unified client interface with fuzzy model matching, improves provider reliability through HTTP header fixes, refactors the Sambanova provider, and performs maintenance cleanup by removing the GeminiProxy provider. The PR adds substantial new functionality while addressing technical debt and improving the overall robustness of the provider ecosystem.

Key Changes

  • Enhanced Unified Client Interface: Implemented intelligent model resolution with fuzzy matching using difflib, automatic provider failover on empty responses, dynamic provider discovery, and support for custom exclusion lists
  • Provider Improvements: Fixed Accept-Encoding header issues across 6+ OpenAI-compatible providers to prevent decompression errors, refactored Sambanova with sanitize_stream and tool calling support, added 3 new OpenAI-compatible providers
  • Maintenance Cleanup: Removed GeminiProxy provider and updated all documentation/statistics accordingly

Reviewed changes

Copilot reviewed 19 out of 19 changed files in this pull request and generated 21 comments.

Show a summary per file
File Description
webscout/client.py Complete rewrite with 583 lines of new unified client interface featuring fuzzy model matching, intelligent provider/model resolution, automatic failover, and support for both chat and image generation
webscout/Provider/Sambanova.py Major refactor aligning with TextPollinationsAI pattern, adding sanitize_stream for SSE parsing, tool calling support, and dynamic model fetching
webscout/Provider/OPENAI/zenmux.py Removed Accept-Encoding header to fix decompression errors
webscout/Provider/OPENAI/yep.py Removed Accept-Encoding header to fix decompression errors
webscout/Provider/OPENAI/venice.py Removed unused models() classmethod
webscout/Provider/OPENAI/oivscode.py Cleaned up fetch_available_models() to remove debug prints
webscout/Provider/OPENAI/llmchatco.py Removed Accept-Encoding header to fix decompression errors
webscout/Provider/OPENAI/deepinfra.py Changed Accept-Encoding to "gzip, deflate" to prevent decompression errors
webscout/Provider/OPENAI/akashgpt.py Removed Accept-Encoding header to fix decompression errors
webscout/Provider/OPENAI/K2Think.py Removed Accept-Encoding header to fix decompression errors
webscout/Provider/OPENAI/README.md Removed GeminiProxy from provider list
webscout/Provider/GeminiProxy.py Deleted entire GeminiProxy provider implementation (168 lines removed)
webscout/Provider/init.py Removed GeminiProxy imports and exports
webscout/Provider/llmchat.py Added new model "@cf/ibm-granite/granite-4.0-h-micro"
webscout/Provider/QwenLM.py Added new model "qwen3-max-2025-10-30"
webscout/Provider/UNFINISHED/grammerchecker.py New grammar checking utility (unfinished)
webscout/Provider/UNFINISHED/aihumanizer.py New AI humanizer utility (unfinished)
changelog.md Updated with comprehensive changelog for this release
Provider.md Updated provider statistics from 60 to 59 total providers
Comments suppressed due to low confidence (6)

webscout/client.py:37

  • Import of 'time' is not used.
import time

webscout/client.py:38

  • Import of 'uuid' is not used.
import uuid

webscout/Provider/Sambanova.py:52

  • 'except' clause does nothing but pass and there is no explanatory comment.
        except Exception:

webscout/client.py:86

  • 'except' clause does nothing but pass and there is no explanatory comment.
            except Exception: pass

webscout/client.py:87

  • 'except' clause does nothing but pass and there is no explanatory comment.
    except Exception: pass

webscout/client.py:336

  • 'except' clause does nothing but pass and there is no explanatory comment.
            except Exception: pass

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

else:
# Raise exception to trigger failover loop
raise ValueError(f"Provider {resolved_provider.__name__} returned empty content")
except Exception: pass
Copy link

Copilot AI Dec 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The exception handling at line 336 silently catches all exceptions with a bare except Exception: pass. This means any error from the primary provider (network errors, timeouts, authentication failures, etc.) is silently ignored and triggers failover. While this is intentional for robustness, it can make debugging difficult. Consider logging these exceptions at a debug level so users can understand why failover occurred.

Copilot uses AI. Check for mistakes.
Comment on lines +30 to +31
response = requests.post(url, headers=headers, files=files)
return response.json()
Copy link

Copilot AI Dec 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The function lacks error handling. If the API request fails, returns a non-200 status, or returns invalid JSON, the function will raise an unhandled exception. Consider adding try-except blocks and proper error handling to make the function more robust.

Suggested change
response = requests.post(url, headers=headers, files=files)
return response.json()
try:
response = requests.post(url, headers=headers, files=files, timeout=10)
response.raise_for_status()
return response.json()
except requests.RequestException as exc:
# Network-related or HTTP-level error
return {"error": f"Request failed: {exc}"}
except ValueError as exc:
# JSON decoding error
return {"error": f"Invalid JSON response: {exc}"}

Copilot uses AI. Check for mistakes.
'origin': 'https://aihumanizer.work',
'priority': 'u=1, i',
'referer': 'https://aihumanizer.work/?via=topaitools',
'sec-ch-ua': '"Not(A:Brand";v="8", "Chromium";v="144", "Microsoft Edge";v="144"',
Copy link

Copilot AI Dec 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The hardcoded headers include browser version information (Chrome 144, Edge 144) which references browser versions from the future that don't exist yet. This is a pattern seen in the codebase and might cause API rejections. Consider using LitAgent for dynamic fingerprinting as done in other providers, or use current/existing browser versions.

Suggested change
'sec-ch-ua': '"Not(A:Brand";v="8", "Chromium";v="144", "Microsoft Edge";v="144"',
'sec-ch-ua': '"Not(A:Brand";v="8", "Chromium";v="120", "Microsoft Edge";v="120"',

Copilot uses AI. Check for mistakes.
Comment on lines +86 to +87
except Exception: pass
except Exception: pass
Copy link

Copilot AI Dec 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The provider loading functions load_openai_providers() and load_tti_providers() have nested bare except Exception: pass blocks (lines 86, 87 for OPENAI and similar for TTI). While this prevents initialization failures, it silently suppresses all errors including import errors, attribute errors, and other issues that could indicate problems with provider implementations. Consider logging these exceptions at a debug level to help developers identify provider loading issues.

Copilot uses AI. Check for mistakes.
provider_map[attr_name] = attr
if hasattr(attr, 'required_auth') and attr.required_auth:
auth_required_providers.add(attr_name)
except Exception: pass
Copy link

Copilot AI Dec 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'except' clause does nothing but pass and there is no explanatory comment.

Copilot uses AI. Check for mistakes.
if hasattr(attr, 'required_auth') and attr.required_auth:
auth_required_providers.add(attr_name)
except Exception: pass
except Exception: pass
Copy link

Copilot AI Dec 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'except' clause does nothing but pass and there is no explanatory comment.

Copilot uses AI. Check for mistakes.
models.append(m)
elif isinstance(m, dict) and "id" in m:
models.append(m["id"])
except Exception:
Copy link

Copilot AI Dec 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'except' clause does nothing but pass and there is no explanatory comment.

Copilot uses AI. Check for mistakes.
try:
instance = self._get_provider_instance(p_cls)
p_models = _get_models_safely(p_cls, instance)
except Exception:
Copy link

Copilot AI Dec 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'except' clause does nothing but pass and there is no explanatory comment.

Suggested change
except Exception:
except Exception:
# If we cannot instantiate this provider to fetch its models,
# silently skip it and continue with other providers.

Copilot uses AI. Check for mistakes.
try:
instance = self._get_provider_instance(p_cls)
p_models = _get_models_safely(p_cls, instance)
except Exception:
Copy link

Copilot AI Dec 19, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

'except' clause does nothing but pass and there is no explanatory comment.

Suggested change
except Exception:
except Exception:
# Intentionally ignore providers that fail during instantiation or model discovery

Copilot uses AI. Check for mistakes.
@OEvortex OEvortex merged commit 688e614 into main Dec 19, 2025
2 checks passed
@OEvortex OEvortex deleted the feature/fuzzy-model-matching branch December 19, 2025 05:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant