feat: Add condensation configuration with provider/model/rotation support (v0.3.2)

- Add 'condensation' section to providers.json for dedicated provider/model
- Support rotation-based condensation by specifying rotation ID in model field
- Update ContextManager to use dedicated condensation handler
- Update handlers to pass condensation configuration
- Bump version to 0.3.2
parent d9772366
...@@ -650,18 +650,11 @@ For support and questions: ...@@ -650,18 +650,11 @@ For support and questions:
The extension includes multiple donation options to support its development: The extension includes multiple donation options to support its development:
### Web3/MetaMask Donation ### Ethereum Donation
Works on any website - The Web3 donation is completely independent of the current page ETH to 0xdA6dAb526515b5cb556d20269207D43fcc760E51
Click the "🦊 Donate with MetaMask" button in the extension popup (only appears if MetaMask is detected)
Supports both modern window.ethereum and legacy window.web3 providers
Default donation: 0.1 ETH to 0xdA6dAb526515b5cb556d20269207D43fcc760E51
Users can modify the amount in MetaMask before confirming
### PayPal Donation ### PayPal Donation
Click the "💳 Donate with PayPal" button in the extension popup https://paypal.me/nexlab
Opens PayPal donation page for info@nexlab.net
Traditional payment method for users without cryptocurrency wallets
Always available regardless of browser setup
### Bitcoin Donation ### Bitcoin Donation
Address: bc1qcpt2uutqkz4456j5r78rjm3gwq03h5fpwmcc5u Address: bc1qcpt2uutqkz4456j5r78rjm3gwq03h5fpwmcc5u
......
...@@ -141,18 +141,11 @@ See `config/providers.json` and `config/rotations.json` for configuration exampl ...@@ -141,18 +141,11 @@ See `config/providers.json` and `config/rotations.json` for configuration exampl
## Donations ## Donations
The project includes multiple donation options to support its development: The project includes multiple donation options to support its development:
### Web3/MetaMask Donation ### Ethereum Donation
Works on any website - The Web3 donation is completely independent of the current page ETH to 0xdA6dAb526515b5cb556d20269207D43fcc760E51
Click the "🦊 Donate with MetaMask" button in the extension popup (only appears if MetaMask is detected)
Supports both modern window.ethereum and legacy window.web3 providers
Default donation: 0.1 ETH to 0xdA6dAb526515b5cb556d20269207D43fcc760E51
Users can modify the amount in MetaMask before confirming
### PayPal Donation ### PayPal Donation
Click the "💳 Donate with PayPal" button in the extension popup https://paypal.me/nexlab
Opens PayPal donation page for info@nexlab.net
Traditional payment method for users without cryptocurrency wallets
Always available regardless of browser setup
### Bitcoin Donation ### Bitcoin Donation
Address: bc1qcpt2uutqkz4456j5r78rjm3gwq03h5fpwmcc5u Address: bc1qcpt2uutqkz4456j5r78rjm3gwq03h5fpwmcc5u
......
...@@ -23,7 +23,7 @@ Why did the programmer quit his job? Because he didn't get arrays! ...@@ -23,7 +23,7 @@ Why did the programmer quit his job? Because he didn't get arrays!
A modular proxy server for managing multiple AI provider integrations. A modular proxy server for managing multiple AI provider integrations.
""" """
from .config import config, Config, ProviderConfig, RotationConfig, AppConfig, AutoselectConfig, AutoselectModelInfo from .config import config, Config, ProviderConfig, RotationConfig, AppConfig, AutoselectConfig, AutoselectModelInfo, CondensationConfig
from .context import ContextManager, get_context_config_for_model from .context import ContextManager, get_context_config_for_model
from .database import DatabaseManager, get_database, initialize_database from .database import DatabaseManager, get_database, initialize_database
from .models import ( from .models import (
...@@ -46,7 +46,7 @@ from .providers import ( ...@@ -46,7 +46,7 @@ from .providers import (
from .handlers import RequestHandler, RotationHandler, AutoselectHandler from .handlers import RequestHandler, RotationHandler, AutoselectHandler
from .utils import count_messages_tokens, split_messages_into_chunks, get_max_request_tokens_for_model from .utils import count_messages_tokens, split_messages_into_chunks, get_max_request_tokens_for_model
__version__ = "0.3.0" __version__ = "0.3.2"
__all__ = [ __all__ = [
# Config # Config
"config", "config",
......
...@@ -35,6 +35,14 @@ class ProviderModelConfig(BaseModel): ...@@ -35,6 +35,14 @@ class ProviderModelConfig(BaseModel):
max_request_tokens: Optional[int] = None max_request_tokens: Optional[int] = None
class CondensationConfig(BaseModel):
"""Configuration for context condensation"""
provider_id: Optional[str] = None
model: Optional[str] = None
rotation_id: Optional[str] = None
enabled: bool = True
class ProviderConfig(BaseModel): class ProviderConfig(BaseModel):
id: str id: str
name: str name: str
...@@ -63,6 +71,7 @@ class AppConfig(BaseModel): ...@@ -63,6 +71,7 @@ class AppConfig(BaseModel):
providers: Dict[str, ProviderConfig] providers: Dict[str, ProviderConfig]
rotations: Dict[str, RotationConfig] rotations: Dict[str, RotationConfig]
autoselect: Dict[str, AutoselectConfig] autoselect: Dict[str, AutoselectConfig]
condensation: Optional[CondensationConfig] = None
error_tracking: Dict[str, Dict] error_tracking: Dict[str, Dict]
class Config: class Config:
...@@ -71,6 +80,7 @@ class Config: ...@@ -71,6 +80,7 @@ class Config:
self._load_providers() self._load_providers()
self._load_rotations() self._load_rotations()
self._load_autoselect() self._load_autoselect()
self._load_condensation()
self._initialize_error_tracking() self._initialize_error_tracking()
def _get_config_source_dir(self): def _get_config_source_dir(self):
...@@ -209,6 +219,30 @@ class Config: ...@@ -209,6 +219,30 @@ class Config:
data = json.load(f) data = json.load(f)
self.autoselect = {k: AutoselectConfig(**v) for k, v in data.items()} self.autoselect = {k: AutoselectConfig(**v) for k, v in data.items()}
def _load_condensation(self):
"""Load condensation configuration from providers.json"""
import logging
logger = logging.getLogger(__name__)
logger.info(f"=== Config._load_condensation START ===")
providers_path = Path.home() / '.aisbf' / 'providers.json'
if not providers_path.exists():
# Fallback to source config if user config doesn't exist
try:
source_dir = self._get_config_source_dir()
providers_path = source_dir / 'providers.json'
except FileNotFoundError:
logger.warning("Could not find providers.json for condensation config")
self.condensation = CondensationConfig()
return
with open(providers_path) as f:
data = json.load(f)
condensation_data = data.get('condensation', {})
self.condensation = CondensationConfig(**condensation_data)
logger.info(f"Loaded condensation config: provider_id={self.condensation.provider_id}, model={self.condensation.model}, enabled={self.condensation.enabled}")
logger.info(f"=== Config._load_condensation END ===")
def _initialize_error_tracking(self): def _initialize_error_tracking(self):
self.error_tracking = {} self.error_tracking = {}
for provider_id in self.providers: for provider_id in self.providers:
...@@ -236,4 +270,7 @@ class Config: ...@@ -236,4 +270,7 @@ class Config:
def get_autoselect(self, autoselect_id: str) -> AutoselectConfig: def get_autoselect(self, autoselect_id: str) -> AutoselectConfig:
return self.autoselect.get(autoselect_id) return self.autoselect.get(autoselect_id)
def get_condensation(self) -> CondensationConfig:
return self.condensation
config = Config() config = Config()
This diff is collapsed.
...@@ -263,7 +263,7 @@ class RequestHandler: ...@@ -263,7 +263,7 @@ class RequestHandler:
# Apply context condensation if needed # Apply context condensation if needed
if context_config.get('condense_context', 0) > 0: if context_config.get('condense_context', 0) > 0:
context_manager = ContextManager(context_config, handler) context_manager = ContextManager(context_config, handler, self.config.get_condensation())
if context_manager.should_condense(messages, model): if context_manager.should_condense(messages, model):
logger.info("Context condensation triggered") logger.info("Context condensation triggered")
messages = await context_manager.condense_context(messages, model) messages = await context_manager.condense_context(messages, model)
...@@ -369,7 +369,7 @@ class RequestHandler: ...@@ -369,7 +369,7 @@ class RequestHandler:
# Apply context condensation if needed # Apply context condensation if needed
if context_config.get('condense_context', 0) > 0: if context_config.get('condense_context', 0) > 0:
context_manager = ContextManager(context_config, handler) context_manager = ContextManager(context_config, handler, self.config.get_condensation())
if context_manager.should_condense(messages, model): if context_manager.should_condense(messages, model):
import logging import logging
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
...@@ -1017,7 +1017,7 @@ class RotationHandler: ...@@ -1017,7 +1017,7 @@ class RotationHandler:
# Apply context condensation if needed # Apply context condensation if needed
if context_config.get('condense_context', 0) > 0: if context_config.get('condense_context', 0) > 0:
context_manager = ContextManager(context_config, handler) context_manager = ContextManager(context_config, handler, self.config.get_condensation())
if context_manager.should_condense(messages, model_name): if context_manager.should_condense(messages, model_name):
logger.info("Context condensation triggered") logger.info("Context condensation triggered")
messages = await context_manager.condense_context(messages, model_name) messages = await context_manager.condense_context(messages, model_name)
......
{ {
"condensation": {
"provider_id": "gemini",
"model": "gemini-1.5-flash",
"enabled": true
},
"providers": { "providers": {
"gemini": { "gemini": {
"id": "gemini", "id": "gemini",
......
...@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" ...@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project] [project]
name = "aisbf" name = "aisbf"
version = "0.3.0" version = "0.3.2"
description = "AISBF - AI Service Broker Framework || AI Should Be Free - A modular proxy server for managing multiple AI provider integrations" description = "AISBF - AI Service Broker Framework || AI Should Be Free - A modular proxy server for managing multiple AI provider integrations"
readme = "README.md" readme = "README.md"
license = "GPL-3.0-or-later" license = "GPL-3.0-or-later"
......
...@@ -49,7 +49,7 @@ class InstallCommand(_install): ...@@ -49,7 +49,7 @@ class InstallCommand(_install):
setup( setup(
name="aisbf", name="aisbf",
version="0.3.0", version="0.3.2",
author="AISBF Contributors", author="AISBF Contributors",
author_email="stefy@nexlab.net", author_email="stefy@nexlab.net",
description="AISBF - AI Service Broker Framework || AI Should Be Free - A modular proxy server for managing multiple AI provider integrations", description="AISBF - AI Service Broker Framework || AI Should Be Free - A modular proxy server for managing multiple AI provider integrations",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment