aisbf 0.2.2__tar.gz → 0.2.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aisbf
3
- Version: 0.2.2
3
+ Version: 0.2.4
4
4
  Summary: AISBF - AI Service Broker Framework || AI Should Be Free - A modular proxy server for managing multiple AI provider integrations
5
5
  Home-page: https://git.nexlab.net/nexlab/aisbf.git
6
6
  Author: AISBF Contributors
@@ -34,6 +34,7 @@ class ProviderConfig(BaseModel):
34
34
  endpoint: str
35
35
  type: str
36
36
  api_key_required: bool
37
+ rate_limit: float = 0.0
37
38
 
38
39
  class RotationConfig(BaseModel):
39
40
  providers: List[Dict]
@@ -111,32 +112,78 @@ class Config:
111
112
  print(f"Created default config file: {dst}")
112
113
 
113
114
  def _load_providers(self):
115
+ import logging
116
+ logger = logging.getLogger(__name__)
117
+ logger.info(f"=== Config._load_providers START ===")
118
+
114
119
  providers_path = Path.home() / '.aisbf' / 'providers.json'
120
+ logger.info(f"Looking for providers at: {providers_path}")
121
+
115
122
  if not providers_path.exists():
123
+ logger.info(f"User config not found, falling back to source config")
116
124
  # Fallback to source config if user config doesn't exist
117
125
  try:
118
126
  source_dir = self._get_config_source_dir()
119
127
  providers_path = source_dir / 'providers.json'
128
+ logger.info(f"Using source config at: {providers_path}")
120
129
  except FileNotFoundError:
130
+ logger.error("Could not find providers.json configuration file")
121
131
  raise FileNotFoundError("Could not find providers.json configuration file")
122
132
 
133
+ logger.info(f"Loading providers from: {providers_path}")
123
134
  with open(providers_path) as f:
124
135
  data = json.load(f)
125
136
  self.providers = {k: ProviderConfig(**v) for k, v in data['providers'].items()}
137
+ logger.info(f"Loaded {len(self.providers)} providers: {list(self.providers.keys())}")
138
+ for provider_id, provider_config in self.providers.items():
139
+ logger.info(f" - {provider_id}: type={provider_config.type}, endpoint={provider_config.endpoint}")
140
+ logger.info(f"=== Config._load_providers END ===")
126
141
 
127
142
  def _load_rotations(self):
143
+ import logging
144
+ logger = logging.getLogger(__name__)
145
+ logger.info(f"=== Config._load_rotations START ===")
146
+
128
147
  rotations_path = Path.home() / '.aisbf' / 'rotations.json'
148
+ logger.info(f"Looking for rotations at: {rotations_path}")
149
+
129
150
  if not rotations_path.exists():
151
+ logger.info(f"User config not found, falling back to source config")
130
152
  # Fallback to source config if user config doesn't exist
131
153
  try:
132
154
  source_dir = self._get_config_source_dir()
133
155
  rotations_path = source_dir / 'rotations.json'
156
+ logger.info(f"Using source config at: {rotations_path}")
134
157
  except FileNotFoundError:
158
+ logger.error("Could not find rotations.json configuration file")
135
159
  raise FileNotFoundError("Could not find rotations.json configuration file")
136
160
 
161
+ logger.info(f"Loading rotations from: {rotations_path}")
137
162
  with open(rotations_path) as f:
138
163
  data = json.load(f)
139
164
  self.rotations = {k: RotationConfig(**v) for k, v in data['rotations'].items()}
165
+ logger.info(f"Loaded {len(self.rotations)} rotations: {list(self.rotations.keys())}")
166
+
167
+ # Validate that all providers referenced in rotations exist
168
+ logger.info(f"=== VALIDATING ROTATION PROVIDERS ===")
169
+ available_providers = list(self.providers.keys())
170
+ logger.info(f"Available providers: {available_providers}")
171
+
172
+ for rotation_id, rotation_config in self.rotations.items():
173
+ logger.info(f"Validating rotation: {rotation_id}")
174
+ for provider in rotation_config.providers:
175
+ provider_id = provider['provider_id']
176
+ if provider_id not in self.providers:
177
+ logger.warning(f"!!! CONFIGURATION WARNING !!!")
178
+ logger.warning(f"Rotation '{rotation_id}' references provider '{provider_id}' which is NOT defined in providers.json")
179
+ logger.warning(f"Available providers: {available_providers}")
180
+ logger.warning(f"This provider will be SKIPPED during rotation requests")
181
+ logger.warning(f"Please add the provider to providers.json or remove it from the rotation configuration")
182
+ logger.warning(f"!!! END WARNING !!!")
183
+ else:
184
+ logger.info(f" ✓ Provider '{provider_id}' is available")
185
+
186
+ logger.info(f"=== Config._load_rotations END ===")
140
187
 
141
188
  def _load_autoselect(self):
142
189
  autoselect_path = Path.home() / '.aisbf' / 'autoselect.json'
@@ -162,7 +209,16 @@ class Config:
162
209
  }
163
210
 
164
211
  def get_provider(self, provider_id: str) -> ProviderConfig:
165
- return self.providers.get(provider_id)
212
+ import logging
213
+ logger = logging.getLogger(__name__)
214
+ logger.info(f"Config.get_provider called with provider_id: {provider_id}")
215
+ logger.info(f"Available providers: {list(self.providers.keys())}")
216
+ result = self.providers.get(provider_id)
217
+ if result:
218
+ logger.info(f"Found provider: {result}")
219
+ else:
220
+ logger.warning(f"Provider {provider_id} not found!")
221
+ return result
166
222
 
167
223
  def get_rotation(self, rotation_id: str) -> RotationConfig:
168
224
  return self.rotations.get(rotation_id)