-
-
Notifications
You must be signed in to change notification settings - Fork 59
Feature/better client #109
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
…ng chat and image generation providers
…roviders and remove deprecated ChatGPTClone.
…ctive provider fixes - Removed hardcoded model fallbacks in Client class - Improved fuzzy model matching with substring support - Centralized model discovery to strictly use models.list() - Implemented provider instance cache for performance - Cleaned up TextPollinations and e2b providers (silent mode, docstrings) - Fixed potential IndexError in 10+ providers across the codebase
…letions and streaming support.
…s and update changelog.
…t, proof-of-work, and response parsing.
…e, and relocate the reverse engineering prompt.
…ace API with multi-language and multi-model support.
… and added required_auth flags
…iders, and refactor testing and documentation.
…, update documentation, and remove deprecated files.
…e_stream` in Monica, and update provider documentation.
…odules, update documentation, and remove obsolete files.
…ftcli`, `scout`, and `litagent` core modules, and expand chat sandbox tests and documentation.
…is, and remove obsolete `test_chatsandbox` files.
…nd fix text_utils formatting
… improving response extraction.
- Fixed critical bug in webscout/Provider/typefully.py where TypefullyAI provider was returning empty responses due to incorrect streaming parser - Root cause: Wrong regex pattern expecting format instead of actual Typefully AI SSE format - Solution: Implemented _typefully_extractor method and updated streaming logic to use sanitize_stream with proper content extraction - Updated bug.md status from FAILED to SUCCESS - Also improved IBM provider authentication with dynamic token fetching
… `bug.md`, and update `changelog.md`.
…, julius, ExaAI, Gemini, Cerebras, and Andi.
There was a problem hiding this 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 comprehensive improvements to text-to-speech (TTS) and text-to-image (TTI) providers, along with updates to OpenAI-compatible provider implementations. The changes focus on standardizing debug output, adding new providers, removing deprecated ones, and improving error handling across the codebase.
Key Changes:
- Standardized debug logging across TTS providers by replacing print statements with
ic.configureOutput()calls - Added new TTS providers (QwenTTS, SherpaTTS) and OpenAI-compatible providers (Nvidia, HuggingFace, LLMChat, HadadXYZ)
- Removed deprecated/non-working providers (GesseritTTS, SciraChat, ExaChat, ChatGPTClone, and several TTI providers)
- Enhanced error handling and stream processing across multiple providers
- Updated provider authentication requirements and working status flags
Reviewed changes
Copilot reviewed 102 out of 151 changed files in this pull request and generated 16 comments.
Show a summary per file
| File | Description |
|---|---|
| webscout/Provider/TTS/*.py | Standardized debug output to use ic.configureOutput() instead of print statements; added required_auth flags |
| webscout/Provider/TTS/qwen.py | New QwenTTS provider with 40+ voices and multiple language support |
| webscout/Provider/TTS/sherpa.py | New SherpaTTS provider using Sherpa-ONNX API with 50+ languages |
| webscout/Provider/TTI/*.py | Removed non-working providers; added status flags; introduced MiragicAI provider |
| webscout/Provider/OPENAI/*.py | Improved stream parsing with better empty choices handling; added new providers |
| webscout/Provider/OPENAI/nvidia.py | New Nvidia NIM API provider implementation |
| webscout/Provider/OPENAI/huggingface.py | New HuggingFace Inference API provider |
| webscout/Provider/OPENAI/llmchat.py | New LLMChat provider with 50+ Cloudflare models |
| webscout/Provider/OPENAI/hadadxyz.py | New HadadXYZ provider with reasoning support |
| webscout/Provider/QwenLM.py | Refactored to use sanitize_stream utility |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| ic.configureOutput(prefix='DEBUG| '); ic(f"Processing {len(sentences)} sentences") | ||
| ic.configureOutput(prefix='DEBUG| '); ic(f"Model: {model}") | ||
| ic.configureOutput(prefix='DEBUG| '); ic(f"Voice: {voice} -> {speechma_voice}") | ||
| ic.configureOutput(prefix='DEBUG| '); ic(f"Format: {response_format}") |
Copilot
AI
Dec 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The ic.configureOutput(prefix='DEBUG| ') call is repeated before every ic() call. This is inefficient and makes the code harder to maintain. Configure the output prefix once at the module or class level, or at the start of the verbose block.
| "csukuangfj/vits-piper-en_US-ryan-medium|1 speaker", | ||
| "csukuangfj/vits-piper-en_GB-alan-low|1 speaker", | ||
| "csukuangfj/vits-piper-en_GB-alan-medium|1 speaker", | ||
| "csukuangfj/vits-piper-en_GB-alan-medium", |
Copilot
AI
Dec 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This model entry appears twice in SUPPORTED_MODELS (lines 86-88). The second occurrence on line 88 is missing the speaker count suffix ("1 speaker"), making it inconsistent with other entries.
| "csukuangfj/vits-piper-en_GB-alan-medium", |
| return filename.as_posix() | ||
| with httpx.Client(**client_kwargs) as client: | ||
| # Step 1: Join the queue | ||
| join_url = f"{self.BASE_URL}/queue/join?__theme=system" |
Copilot
AI
Dec 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The hardcoded __theme=system query parameter appears to be a UI-specific parameter that shouldn't be necessary for API calls. Consider removing it or making it configurable.
| join_url = f"{self.BASE_URL}/queue/join?__theme=system" | |
| join_url = f"{self.BASE_URL}/queue/join" |
| ) | ||
|
|
||
| if not self._client.api_key: | ||
| raise ValueError("API key is required for TogetherImage. Please provide it in __init__.") |
Copilot
AI
Dec 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The error message refers to __init__ but the actual parameter name is api_key. Consider updating to: "API key is required for TogetherImage. Please provide it via the api_key parameter."
| raise ValueError("API key is required for TogetherImage. Please provide it in __init__.") | |
| raise ValueError("API key is required for TogetherImage. Please provide it via the api_key parameter.") |
| choices = data.get('choices') | ||
| if not choices and choices is not None: |
Copilot
AI
Dec 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The condition if not choices and choices is not None will never be True when choices is an empty list because empty lists are falsy but not None. This should be if choices is not None and not choices or if choices is not None and len(choices) == 0 to correctly handle empty lists.
| data = json.loads(json_str) | ||
| choice_data = data.get('choices', [{}])[0] | ||
| choices = data.get('choices') | ||
| if not choices and choices is not None: |
Copilot
AI
Dec 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same condition issue - will never be True for empty lists. This bug pattern appears in multiple files and should be fixed consistently.
| if not choices and choices is not None: | |
| if not choices: |
| total_tokens = usage_data.get('total_tokens', total_tokens) | ||
|
|
||
| choices = data.get('choices') | ||
| if not choices and choices is not None: |
Copilot
AI
Dec 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same condition bug pattern repeated here.
| if not choices and choices is not None: | |
| if not choices: |
| if isinstance(data, dict): | ||
| if "reasoning_content" in data and data["reasoning_content"]: | ||
| return data["reasoning_content"] | ||
| if "content" in data and data["content"]: | ||
| return data["content"] |
Copilot
AI
Dec 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The nested if statements can be flattened using early returns or combined with and operators for better readability. Consider: if isinstance(data, dict) and data.get("reasoning_content"): return data["reasoning_content"]
| if isinstance(data, dict): | |
| if "reasoning_content" in data and data["reasoning_content"]: | |
| return data["reasoning_content"] | |
| if "content" in data and data["content"]: | |
| return data["content"] | |
| if not isinstance(data, dict): | |
| return chunk | |
| if data.get("reasoning_content"): | |
| return data["reasoning_content"] | |
| if data.get("content"): | |
| return data["content"] |
| data = json.loads(json_str) | ||
| choice_data = data.get('choices', [{}])[0] | ||
| choices = data.get('choices') | ||
| if not choices and choices is not None: |
Copilot
AI
Dec 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same condition bug pattern.
| if not choices and choices is not None: | |
| if not choices: |
| data = json.loads(json_str) | ||
| choice_data = data.get('choices', [{}])[0] | ||
| choices = data.get('choices') | ||
| if not choices and choices is not None: |
Copilot
AI
Dec 20, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same condition bug pattern.
| if not choices and choices is not None: | |
| if not choices: |
This pull request introduces several documentation and configuration improvements, along with updates to the provider listings and CLI usage examples. The most significant changes include expanding the list of supported providers, enhancing the documentation structure and coverage, updating the
.dockerignoreandDockerfilefor better Docker support, and providing a new prompt for automated provider class generation.Provider listing and documentation updates:
Provider.mdto include new providers (such asAyle,HuggingFace,Nvidia,LLMChat, andHadadXYZ), increasing the total number of unique providers and updating the implementation coverage statistics accordingly. [1] [2] [3] [4]README.mdfor features like the Documentation Hub, Awesome Prompts Manager, GitAPI, Python Client API, and CLI documentation. Updated developer tools and improved the command-line interface documentation with more examples and supported search providers. [1] [2] [3] [4] [5] [6]Configuration and Docker improvements:
.dockerignoreto allow essential documentation files (likeREADME.md,LICENSE.md, etc.) while still ignoring other documentation and markdown files.Dockerfilewith new environment variables for debug mode, request logging, and CORS origins, improving configuration flexibility for deployments.Prompts and automation:
Prompts/ReverseEngineering.md, which provides a detailed directive for automatic, production-ready Python Provider class generation using reverse engineering techniques.