Skip to content

Commit

Permalink
Add new models, enhance search & UI components, improve providers
Browse files Browse the repository at this point in the history
feat(g4f/models.py): add sonar-reasoning and deepseek-v3 models
- Add sonar-reasoning model for Perplexity AI provider
- Add deepseek-v3 model with Blackbox and DeepInfra providers
- Refactor ModelUtils to use dynamic model discovery
- Update provider list for deepseek-chat model

---

feat(g4f/tools/web_search.py): enhance search robustness and error handling
- Add input validation for search queries with length checks
- Implement retry logic with multiple backend fallbacks
- Add better error handling and logging throughout search flow
- Improve cache handling with UTF-8 encoding and error recovery
- Add detailed debug logging for search operations
- Enhance query processing by joining keyword lists into strings

---

feat(g4f/gui/client/static/css/style.css): add collapsible component styles
- Add  class with border, radius, and margin styling
- Implement  with hover effects and flex layout
- Create  with padding and hidden state
- Add  styling for flex-based layout
- Include chevron rotation animation for active state

---

refactor(g4f/gui/client/static/js/chat.v1.js): Refactor provider settings UI
- Added collapsible container for provider options
- Moved provider API key inputs into a new collapsible section
- Added event listeners for collapsible header toggles
- Improved organization of provider settings UI elements

---

refactor(g4f/Provider/Blackbox.py): improve think tag parsing and remove duplicate model alias
- Remove duplicate deepseek-chat model alias entry
- Enhance think tag parsing logic for cleaner code organization
- Split think tag content handling into pre-think, think-content and post-think sections
- Add strip() calls to remove unnecessary whitespace from parsed content
- Update Reasoning yield to use status parameter instead of f-string formatting

---

fix(g4f/Provider/DeepInfraChat.py): update model alias for DeepSeek V3
- Rename deepseek-chat alias to deepseek-v3 for clarity

---

refactor(g4f/Provider/PerplexityLabs.py): remove unused model aliases
- Remove model_aliases dictionary and its entries
- Clean up model mapping configuration
- Improve code organization by removing deprecated aliases
  • Loading branch information
kqlio67 committed Jan 30, 2025
1 parent 9c30c4b commit 1bfe600
Show file tree
Hide file tree
Showing 6 changed files with 136 additions and 183 deletions.
20 changes: 14 additions & 6 deletions g4f/Provider/Blackbox.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,6 @@ class Blackbox(AsyncGeneratorProvider, ProviderModelMixin):
"dbrx-instruct": "DBRX-Instruct",
"qwq-32b": "Qwen-QwQ-32B-Preview",
"hermes-2-dpo": "Nous-Hermes-2-Mixtral-8x7B-DPO",
"deepseek-chat": "deepseek-v3",

### image ###
"flux": "ImageGeneration",
Expand Down Expand Up @@ -311,11 +310,20 @@ async def create_async_generator(
yield ImageResponse(images=[image_url], alt=prompt)
else:
if "<think>" in text_to_yield and "</think>" in text_to_yield:
parts = text_to_yield.split('<think>', 1)
yield parts[0]
reasoning_parts = parts[1].split('</think>', 1)
yield Reasoning(f"<think>{reasoning_parts[0]}</think>")
yield reasoning_parts[1]
pre_think, rest = text_to_yield.split('<think>', 1)
think_content, post_think = rest.split('</think>', 1)

pre_think = pre_think.strip()
think_content = think_content.strip()
post_think = post_think.strip()

if pre_think:
yield pre_think
if think_content:
yield Reasoning(status=think_content)
if post_think:
yield post_think

full_response = text_to_yield
elif "Generated by BLACKBOX.AI" in text_to_yield:
conversation.validated_value = await cls.fetch_validated(force_refresh=True)
Expand Down
2 changes: 1 addition & 1 deletion g4f/Provider/DeepInfraChat.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ class DeepInfraChat(OpenaiTemplate):
"llama-3.1-8b": "meta-llama/Meta-Llama-3.1-8B-Instruct",
"llama-3.3-70b": "meta-llama/Llama-3.3-70B-Instruct-Turbo",
"llama-3.1-70b": "meta-llama/Meta-Llama-3.1-70B-Instruct-Turbo",
"deepseek-chat": "deepseek-ai/DeepSeek-V3",
"deepseek-v3": "deepseek-ai/DeepSeek-V3",
"qwq-32b": "Qwen/QwQ-32B-Preview",
"wizardlm-2-8x22b": "microsoft/WizardLM-2-8x22B",
"wizardlm-2-7b": "microsoft/WizardLM-2-7B",
Expand Down
4 changes: 0 additions & 4 deletions g4f/Provider/PerplexityLabs.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,6 @@ class PerplexityLabs(AsyncGeneratorProvider, ProviderModelMixin):
"sonar",
"sonar-reasoning",
]
model_aliases = {
"sonar-online": default_model,
"sonar-chat": default_model,
}

@classmethod
async def create_async_generator(
Expand Down
43 changes: 43 additions & 0 deletions g4f/gui/client/static/css/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -1413,6 +1413,49 @@ form .field.saved .fa-xmark {
line-height: 30px;
}

.collapsible {
border: 1px solid var(--blur-border);
border-radius: var(--border-radius-1);
overflow: hidden;
margin-bottom: 10px;
}

.collapsible-header {
padding: 10px;
cursor: pointer;
display: flex;
justify-content: space-between;
align-items: center;
background-color: var(--blur-bg);
}

.collapsible-header:hover {
background-color: var(--button-hover);
}

.collapsible-content {
padding: 10px;
}

.collapsible-content.hidden {
display: none;
}

.provider-item {
padding: 5px 0;
display: flex;
justify-content: space-between;
align-items: center;
}

.fa-chevron-down {
transition: transform 0.3s ease;
}

.collapsible-header.active .fa-chevron-down {
transform: rotate(180deg);
}

::-webkit-scrollbar-track {
background: var(--scrollbar);
}
Expand Down
56 changes: 44 additions & 12 deletions g4f/gui/client/static/js/chat.v1.js
Original file line number Diff line number Diff line change
Expand Up @@ -1961,43 +1961,75 @@ async function on_api() {
}
}
});

let providersContainer = document.createElement("div");
providersContainer.classList.add("field", "collapsible");
providersContainer.innerHTML = `
<div class="collapsible-header">
<span class="label">Providers (Enable/Disable)</span>
<i class="fa-solid fa-chevron-down"></i>
</div>
<div class="collapsible-content hidden"></div>
`;
settings.querySelector(".paper").appendChild(providersContainer);

providers.forEach((provider) => {
if (!provider.parent) {
option = document.createElement("div");
option.classList.add("field");
let option = document.createElement("div");
option.classList.add("provider-item");
option.innerHTML = `
<span class="label">Enable ${provider.label}</span>
<input id="Provider${provider.name}" type="checkbox" name="Provider${provider.name}" value="${provider.name}" class="provider" checked="">
<label for="Provider${provider.name}" class="toogle" title="Remove provider from dropdown"></label>
`;
option.querySelector("input").addEventListener("change", (event) => load_provider_option(event.target, provider.name));
settings.querySelector(".paper").appendChild(option);
providersContainer.querySelector(".collapsible-content").appendChild(option);
provider_options[provider.name] = option;
}
});

providersContainer.querySelector(".collapsible-header").addEventListener('click', (e) => {
providersContainer.querySelector(".collapsible-content").classList.toggle('hidden');
providersContainer.querySelector(".collapsible-header").classList.toggle('active');
});
}

if (appStorage.getItem("provider")) {
await load_provider_models(appStorage.getItem("provider"))
} else {
providerSelect.selectedIndex = 0;
}

let providersListContainer = document.createElement("div");
providersListContainer.classList.add("field", "collapsible");
providersListContainer.innerHTML = `
<div class="collapsible-header">
<span class="label">Providers API key</span>
<i class="fa-solid fa-chevron-down"></i>
</div>
<div class="collapsible-content hidden"></div>
`;
settings.querySelector(".paper").appendChild(providersListContainer);

for (let [name, [label, login_url, childs]] of Object.entries(login_urls)) {
if (!login_url && !is_demo) {
continue;
}
option = document.createElement("div");
option.classList.add("field", "box");
if (!is_demo) {
option.classList.add("hidden");
}
childs = childs.map((child)=>`${child}-api_key`).join(" ");
option.innerHTML = `
let providerBox = document.createElement("div");
providerBox.classList.add("field", "box");
childs = childs.map((child) => `${child}-api_key`).join(" ");
providerBox.innerHTML = `
<label for="${name}-api_key" class="label" title="">${label}:</label>
<input type="text" id="${name}-api_key" name="${name}[api_key]" class="${childs}" placeholder="api_key" autocomplete="off"/>
` + (login_url ? `<a href="${login_url}" target="_blank" title="Login to ${label}">Get API key</a>` : "");
settings.querySelector(".paper").appendChild(option);
providersListContainer.querySelector(".collapsible-content").appendChild(providerBox);
}

providersListContainer.querySelector(".collapsible-header").addEventListener('click', (e) => {
providersListContainer.querySelector(".collapsible-content").classList.toggle('hidden');
providersListContainer.querySelector(".collapsible-header").classList.toggle('active');
});

register_settings_storage();
await load_settings_storage();
Object.entries(provider_options).forEach(
Expand Down Expand Up @@ -2596,4 +2628,4 @@ document.getElementById("showLog").addEventListener("click", ()=> {
log_storage.classList.remove("hidden");
settings.classList.add("hidden");
log_storage.scrollTop = log_storage.scrollHeight;
});
});
Loading

0 comments on commit 1bfe600

Please sign in to comment.