mirror of
https://github.com/zhayujie/chatgpt-on-wechat.git
synced 2026-07-17 11:07:11 +08:00
feat(web): add custom provider support for embedding & vision models, and fix memory_get Windows path bug!
1. Embedding model: support custom provider - Add "custom" entry to EMBEDDING_VENDORS with supports_dim_param=False - Parse custom:<id> credentials and model fallback in agent_initializer - Expand custom_providers as custom:<id> entries in Web UI dropdown 2. Vision model: support custom provider - Add custom:<id> routing in _route_by_provider_id - Add _build_custom_provider reading credentials from custom_providers - Expand custom_providers in Web UI dropdown, add validation in _set_vision 3. Fix memory_get Windows path validation bug! - str.startswith(path+'/') always False on Windows due to backslashes, So All Users can not use "memory_get" tool in Windows. - Use os.path.realpath + os.sep, consistent with MemoryService 4. Fix historical needsModel:false bug preventing embedding provider switch - Change embedding needsModel to true in console.js - Support custom:<id> resolution in cow_cli /memory status, also for adding custom provider support Closes #2908, Closes #2880
This commit is contained in:
@@ -331,6 +331,12 @@ class Vision(BaseTool):
|
||||
- None : unknown provider id, or the bot can't be created.
|
||||
Caller falls through to model-name-based routing.
|
||||
"""
|
||||
# Custom OpenAI-compatible providers — read credentials from
|
||||
# custom_providers list, same pattern as embedding.
|
||||
if provider_id.startswith("custom:"):
|
||||
p = self._build_custom_provider(provider_id, user_model)
|
||||
return [p] if p else None
|
||||
|
||||
display_name = _PROVIDER_ID_TO_DISPLAY.get(provider_id)
|
||||
if not display_name:
|
||||
return None
|
||||
@@ -596,6 +602,34 @@ class Vision(BaseTool):
|
||||
model_override=preferred_model,
|
||||
)
|
||||
|
||||
def _build_custom_provider(self, provider_id: str, preferred_model: Optional[str] = None) -> Optional[VisionProvider]:
|
||||
"""Build a VisionProvider from a custom:<id> entry in custom_providers.
|
||||
Uses the standard OpenAI /chat/completions endpoint — any
|
||||
OpenAI-compatible multimodal endpoint works."""
|
||||
from models.custom_provider import parse_custom_bot_type, get_custom_providers, _find_provider_by_id
|
||||
_, custom_id = parse_custom_bot_type(provider_id)
|
||||
if not custom_id:
|
||||
return None
|
||||
entry = _find_provider_by_id(get_custom_providers(), custom_id)
|
||||
if not entry:
|
||||
logger.warning(f"[Vision] custom provider '{provider_id}' not found in custom_providers")
|
||||
return None
|
||||
api_key = (entry.get("api_key") or "").strip()
|
||||
api_base = (entry.get("api_base") or "").strip()
|
||||
if not api_key or not api_base:
|
||||
logger.warning(f"[Vision] custom provider '{provider_id}' missing api_key or api_base")
|
||||
return None
|
||||
model = preferred_model or entry.get("model") or ""
|
||||
if not model:
|
||||
logger.warning(f"[Vision] custom provider '{provider_id}' has no model configured")
|
||||
return None
|
||||
return VisionProvider(
|
||||
name=entry.get("name") or provider_id,
|
||||
api_key=api_key,
|
||||
api_base=self._ensure_v1(api_base.rstrip("/")),
|
||||
model_override=model,
|
||||
)
|
||||
|
||||
def _call_via_bot(self, model: str, question: str, image_content: dict,
|
||||
provider: Optional[VisionProvider] = None) -> ToolResult:
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user