ai-microcore 4.2.2__tar.gz → 4.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.
Files changed (44) hide show
  1. {ai_microcore-4.2.2 → ai_microcore-4.2.4}/PKG-INFO +1 -1
  2. {ai_microcore-4.2.2 → ai_microcore-4.2.4}/microcore/__init__.py +1 -1
  3. {ai_microcore-4.2.2 → ai_microcore-4.2.4}/microcore/mcp.py +18 -10
  4. {ai_microcore-4.2.2 → ai_microcore-4.2.4}/microcore/utils.py +29 -4
  5. {ai_microcore-4.2.2 → ai_microcore-4.2.4}/LICENSE +0 -0
  6. {ai_microcore-4.2.2 → ai_microcore-4.2.4}/README.md +0 -0
  7. {ai_microcore-4.2.2 → ai_microcore-4.2.4}/microcore/_env.py +0 -0
  8. {ai_microcore-4.2.2 → ai_microcore-4.2.4}/microcore/_llm_functions.py +0 -0
  9. {ai_microcore-4.2.2 → ai_microcore-4.2.4}/microcore/_prepare_llm_args.py +0 -0
  10. {ai_microcore-4.2.2 → ai_microcore-4.2.4}/microcore/ai_func/__init__.py +0 -0
  11. {ai_microcore-4.2.2 → ai_microcore-4.2.4}/microcore/ai_func/ai-func.json.j2 +0 -0
  12. {ai_microcore-4.2.2 → ai_microcore-4.2.4}/microcore/ai_func/ai-func.pythonic.j2 +0 -0
  13. {ai_microcore-4.2.2 → ai_microcore-4.2.4}/microcore/ai_modules.py +0 -0
  14. {ai_microcore-4.2.2 → ai_microcore-4.2.4}/microcore/configuration.py +0 -0
  15. {ai_microcore-4.2.2 → ai_microcore-4.2.4}/microcore/embedding_db/__init__.py +0 -0
  16. {ai_microcore-4.2.2 → ai_microcore-4.2.4}/microcore/embedding_db/chromadb.py +0 -0
  17. {ai_microcore-4.2.2 → ai_microcore-4.2.4}/microcore/embedding_db/qdrant.py +0 -0
  18. {ai_microcore-4.2.2 → ai_microcore-4.2.4}/microcore/file_storage.py +0 -0
  19. {ai_microcore-4.2.2 → ai_microcore-4.2.4}/microcore/interactive_setup.py +0 -0
  20. {ai_microcore-4.2.2 → ai_microcore-4.2.4}/microcore/json_parsing.py +0 -0
  21. {ai_microcore-4.2.2 → ai_microcore-4.2.4}/microcore/llm/__init__.py +0 -0
  22. {ai_microcore-4.2.2 → ai_microcore-4.2.4}/microcore/llm/_openai_llm_v0.py +0 -0
  23. {ai_microcore-4.2.2 → ai_microcore-4.2.4}/microcore/llm/_openai_llm_v1.py +0 -0
  24. {ai_microcore-4.2.2 → ai_microcore-4.2.4}/microcore/llm/anthropic.py +0 -0
  25. {ai_microcore-4.2.2 → ai_microcore-4.2.4}/microcore/llm/google_genai.py +0 -0
  26. {ai_microcore-4.2.2 → ai_microcore-4.2.4}/microcore/llm/google_vertex_ai.py +0 -0
  27. {ai_microcore-4.2.2 → ai_microcore-4.2.4}/microcore/llm/local_llm.py +0 -0
  28. {ai_microcore-4.2.2 → ai_microcore-4.2.4}/microcore/llm/local_transformers.py +0 -0
  29. {ai_microcore-4.2.2 → ai_microcore-4.2.4}/microcore/llm/openai_llm.py +0 -0
  30. {ai_microcore-4.2.2 → ai_microcore-4.2.4}/microcore/llm/shared.py +0 -0
  31. {ai_microcore-4.2.2 → ai_microcore-4.2.4}/microcore/logging.py +0 -0
  32. {ai_microcore-4.2.2 → ai_microcore-4.2.4}/microcore/message_types.py +0 -0
  33. {ai_microcore-4.2.2 → ai_microcore-4.2.4}/microcore/metrics.py +0 -0
  34. {ai_microcore-4.2.2 → ai_microcore-4.2.4}/microcore/python.py +0 -0
  35. {ai_microcore-4.2.2 → ai_microcore-4.2.4}/microcore/templating/__init__.py +0 -0
  36. {ai_microcore-4.2.2 → ai_microcore-4.2.4}/microcore/templating/jinja2.py +0 -0
  37. {ai_microcore-4.2.2 → ai_microcore-4.2.4}/microcore/text2speech/elevenlabs.py +0 -0
  38. {ai_microcore-4.2.2 → ai_microcore-4.2.4}/microcore/tokenizing.py +0 -0
  39. {ai_microcore-4.2.2 → ai_microcore-4.2.4}/microcore/types.py +0 -0
  40. {ai_microcore-4.2.2 → ai_microcore-4.2.4}/microcore/ui.py +0 -0
  41. {ai_microcore-4.2.2 → ai_microcore-4.2.4}/microcore/wrappers/__init__.py +0 -0
  42. {ai_microcore-4.2.2 → ai_microcore-4.2.4}/microcore/wrappers/llm_response_wrapper.py +0 -0
  43. {ai_microcore-4.2.2 → ai_microcore-4.2.4}/microcore/wrappers/prompt_wrapper.py +0 -0
  44. {ai_microcore-4.2.2 → ai_microcore-4.2.4}/pyproject.toml +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ai-microcore
3
- Version: 4.2.2
3
+ Version: 4.2.4
4
4
  Summary: # Minimalistic Foundation for AI Applications
5
5
  Keywords: llm,large language models,ai,similarity search,ai search,gpt,openai,framework,adapter
6
6
  Author-email: Vitalii Stepanenko <mail@vitaliy.in>
@@ -186,4 +186,4 @@ __all__ = [
186
186
  # "wrappers",
187
187
  ]
188
188
 
189
- __version__ = "4.2.2"
189
+ __version__ = "4.2.4"
@@ -25,12 +25,24 @@ class WrongMcpUsage(BadAIAnswer):
25
25
 
26
26
 
27
27
  class HeaderAuth(httpx.Auth):
28
- def __init__(self, header_name, header_value):
29
- self.header_name = header_name
30
- self.header_value = header_value
28
+ def __init__(self, header_name_or_dict: str | dict, header_value: str | None = None):
29
+ if isinstance(header_name_or_dict, dict):
30
+ if header_value is not None:
31
+ raise ValueError(
32
+ "HeaderAuth: If a dictionary is provided in first argument, "
33
+ "header_value should not be set."
34
+ )
35
+ self.headers = header_name_or_dict
36
+ else:
37
+ if header_value is None:
38
+ raise ValueError(
39
+ "HeaderAuth: header_value must be provided when header_name is a string"
40
+ )
41
+ self.headers = {str(header_name_or_dict): str(header_value)}
31
42
 
32
43
  def auth_flow(self, request):
33
- request.headers[self.header_name] = self.header_value
44
+ for k, v in self.headers.items():
45
+ request.headers[k] = v
34
46
  yield request
35
47
 
36
48
 
@@ -293,12 +305,8 @@ class MCPServer:
293
305
  self.name = MCPServer.name_from_url(self.url)
294
306
  if not self.transport:
295
307
  self.transport = self._guess_transport_type_by_url(self.url)
296
- if self.auth and isinstance(self.auth, dict) and len(self.auth) == 1:
297
- header_name, header_value = next(iter(self.auth.items()))
298
- self.auth = HeaderAuth(
299
- header_name=header_name,
300
- header_value=header_value
301
- )
308
+ if self.auth and isinstance(self.auth, dict):
309
+ self.auth = HeaderAuth(self.auth)
302
310
 
303
311
  async def connect(
304
312
  self,
@@ -355,32 +355,57 @@ async def run_parallel(tasks: list, max_concurrent_tasks: int):
355
355
  return await asyncio.gather(*[worker(task) for task in tasks])
356
356
 
357
357
 
358
+ class CantResolveCallable(ValueError):
359
+ """
360
+ Raised when a callable cannot be resolved by name.
361
+ """
362
+ def __init__(self, message: str = None, name: str = None, e: Exception = None):
363
+ message = message or f"Can't resolve callable by name '{name}'{', ' + str(e) if e else ''}"
364
+ super().__init__(message)
365
+ self.name = name
366
+
367
+
358
368
  def resolve_callable(
359
369
  fn: Union[Callable, str, None], allow_empty=False
360
370
  ) -> Union[Callable, None]:
361
371
  """
362
- Resolves a callable function from a string (module.function)
372
+ Resolves a callable function from a string.
373
+ Supported formats:
374
+ - module[.submodules].function
375
+ - module[.submodules].ClassName.static_method
363
376
  """
364
377
  if callable(fn):
365
378
  return fn
366
379
  if not fn:
367
380
  if allow_empty:
368
381
  return None
369
- raise ValueError("Function is not specified")
382
+ raise CantResolveCallable("Can't resolve callable: function is not specified")
370
383
  try:
371
384
  if "." not in fn:
372
385
  fn = globals()[fn]
373
386
  else:
374
387
  parts = fn.split(".")
388
+ # Try resolve as *module.ClassName.static_method if 1st character is upper-cased
389
+ if len(parts) >= 3 and len(parts[-2]) and parts[-2][0].isupper():
390
+ module_name = ".".join(parts[:-2])
391
+ class_name = parts[-2]
392
+ try:
393
+ module = __import__(module_name, fromlist=[class_name])
394
+ cls = getattr(module, class_name)
395
+ fn = getattr(cls, parts[-1])
396
+ assert callable(fn)
397
+ return fn
398
+ except (ImportError, AttributeError, AssertionError, ValueError):
399
+ pass
375
400
  module_name = ".".join(parts[:-1])
376
401
  func_name = parts[-1]
377
402
  if not module_name:
378
- raise ValueError(f"Invalid module name: {module_name}")
403
+ raise CantResolveCallable(f"Invalid module name: {module_name}")
379
404
  module = __import__(module_name, fromlist=[func_name])
380
405
  fn = getattr(module, func_name)
381
406
  assert callable(fn)
382
407
  except (ImportError, AttributeError, AssertionError, ValueError) as e:
383
- raise ValueError(f"Can't resolve callable by name '{fn}', {e}") from e
408
+ raise CantResolveCallable(name=fn, e=e) from e
384
409
  return fn
385
410
 
386
411
 
File without changes
File without changes