neuralnode 2.1.11__tar.gz → 2.1.13__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 (116) hide show
  1. {neuralnode-2.1.11 → neuralnode-2.1.13}/PKG-INFO +1 -1
  2. {neuralnode-2.1.11 → neuralnode-2.1.13}/pyproject.toml +1 -1
  3. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/__init__.py +1 -1
  4. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/providers/horus.py +97 -33
  5. neuralnode-2.1.13/temp_header.gguf +0 -0
  6. {neuralnode-2.1.11 → neuralnode-2.1.13}/.env.example +0 -0
  7. {neuralnode-2.1.11 → neuralnode-2.1.13}/.github/workflows/tests.yml +0 -0
  8. {neuralnode-2.1.11 → neuralnode-2.1.13}/Dockerfile +0 -0
  9. {neuralnode-2.1.11 → neuralnode-2.1.13}/LICENSE +0 -0
  10. {neuralnode-2.1.11 → neuralnode-2.1.13}/README.md +0 -0
  11. {neuralnode-2.1.11 → neuralnode-2.1.13}/docker-compose.yml +0 -0
  12. {neuralnode-2.1.11 → neuralnode-2.1.13}/docs/documentation.md +0 -0
  13. {neuralnode-2.1.11 → neuralnode-2.1.13}/docs/ecosystem_plan.md +0 -0
  14. {neuralnode-2.1.11 → neuralnode-2.1.13}/docs/replica_voice_ids.csv +0 -0
  15. {neuralnode-2.1.11 → neuralnode-2.1.13}/docs/replica_voice_ids.md +0 -0
  16. {neuralnode-2.1.11 → neuralnode-2.1.13}/docs/telegram_guide.md +0 -0
  17. {neuralnode-2.1.11 → neuralnode-2.1.13}/examples/agent_with_tools.py +0 -0
  18. {neuralnode-2.1.11 → neuralnode-2.1.13}/examples/basic_chat.py +0 -0
  19. {neuralnode-2.1.11 → neuralnode-2.1.13}/examples/horus_codes_camples/01_basic_usage.py +0 -0
  20. {neuralnode-2.1.11 → neuralnode-2.1.13}/examples/horus_codes_camples/02_horus_lens.py +0 -0
  21. {neuralnode-2.1.11 → neuralnode-2.1.13}/examples/horus_codes_camples/03_one_liner.py +0 -0
  22. {neuralnode-2.1.11 → neuralnode-2.1.13}/examples/horus_codes_camples/04_custom_cache.py +0 -0
  23. {neuralnode-2.1.11 → neuralnode-2.1.13}/examples/horus_codes_camples/05_4bit_quantization.py +0 -0
  24. {neuralnode-2.1.11 → neuralnode-2.1.13}/examples/horus_codes_camples/06_8bit_quantization.py +0 -0
  25. {neuralnode-2.1.11 → neuralnode-2.1.13}/examples/horus_codes_camples/07_multi_gpu.py +0 -0
  26. {neuralnode-2.1.11 → neuralnode-2.1.13}/examples/horus_codes_camples/08_flash_attention.py +0 -0
  27. {neuralnode-2.1.11 → neuralnode-2.1.13}/examples/horus_codes_camples/09_data_types.py +0 -0
  28. {neuralnode-2.1.11 → neuralnode-2.1.13}/examples/horus_codes_camples/10_generation_params.py +0 -0
  29. {neuralnode-2.1.11 → neuralnode-2.1.13}/examples/horus_codes_camples/11_streaming.py +0 -0
  30. {neuralnode-2.1.11 → neuralnode-2.1.13}/examples/horus_codes_camples/12_chat_templates.py +0 -0
  31. {neuralnode-2.1.11 → neuralnode-2.1.13}/examples/horus_codes_camples/13_offline_mode.py +0 -0
  32. {neuralnode-2.1.11 → neuralnode-2.1.13}/examples/horus_codes_camples/14_force_download.py +0 -0
  33. {neuralnode-2.1.11 → neuralnode-2.1.13}/examples/horus_codes_camples/15_model_info.py +0 -0
  34. {neuralnode-2.1.11 → neuralnode-2.1.13}/examples/horus_codes_camples/16_cpu_offloading.py +0 -0
  35. {neuralnode-2.1.11 → neuralnode-2.1.13}/examples/horus_codes_camples/17_cpu_only.py +0 -0
  36. {neuralnode-2.1.11 → neuralnode-2.1.13}/examples/horus_codes_camples/18_production_setup.py +0 -0
  37. {neuralnode-2.1.11 → neuralnode-2.1.13}/examples/horus_codes_camples/19_gguf_4bit.py +0 -0
  38. {neuralnode-2.1.11 → neuralnode-2.1.13}/examples/horus_codes_camples/20_gguf_5bit.py +0 -0
  39. {neuralnode-2.1.11 → neuralnode-2.1.13}/examples/horus_codes_camples/21_gguf_6bit.py +0 -0
  40. {neuralnode-2.1.11 → neuralnode-2.1.13}/examples/horus_codes_camples/22_gguf_8bit.py +0 -0
  41. {neuralnode-2.1.11 → neuralnode-2.1.13}/examples/horus_codes_camples/23_gguf_16bit.py +0 -0
  42. {neuralnode-2.1.11 → neuralnode-2.1.13}/examples/horus_codes_camples/24_list_models.py +0 -0
  43. {neuralnode-2.1.11 → neuralnode-2.1.13}/examples/horus_codes_camples/25_interactive_chat.py +0 -0
  44. {neuralnode-2.1.11 → neuralnode-2.1.13}/examples/horus_codes_camples/README.md +0 -0
  45. {neuralnode-2.1.11 → neuralnode-2.1.13}/examples/horus_download_guide.py +0 -0
  46. {neuralnode-2.1.11 → neuralnode-2.1.13}/examples/horus_examples.py +0 -0
  47. {neuralnode-2.1.11 → neuralnode-2.1.13}/examples/horus_tq_ready_gguf.py +0 -0
  48. {neuralnode-2.1.11 → neuralnode-2.1.13}/examples/horus_transformers_features.py +0 -0
  49. {neuralnode-2.1.11 → neuralnode-2.1.13}/examples/local_models.py +0 -0
  50. {neuralnode-2.1.11 → neuralnode-2.1.13}/examples/neuralnode_v21_complete_demo.py +0 -0
  51. {neuralnode-2.1.11 → neuralnode-2.1.13}/examples/shade_model_with_tools.py +0 -0
  52. {neuralnode-2.1.11 → neuralnode-2.1.13}/examples/telegram_bot_demo.py +0 -0
  53. {neuralnode-2.1.11 → neuralnode-2.1.13}/examples/thinking_mode_example.py +0 -0
  54. {neuralnode-2.1.11 → neuralnode-2.1.13}/examples/tts_demo.py +0 -0
  55. {neuralnode-2.1.11 → neuralnode-2.1.13}/examples/turboquant_example.py +0 -0
  56. {neuralnode-2.1.11 → neuralnode-2.1.13}/examples/v3_features.py +0 -0
  57. {neuralnode-2.1.11 → neuralnode-2.1.13}/horus_chat_voice.py +0 -0
  58. {neuralnode-2.1.11 → neuralnode-2.1.13}/neuralnode_horus_replica_telegram.ipynb +0 -0
  59. {neuralnode-2.1.11 → neuralnode-2.1.13}/publish.bat +0 -0
  60. {neuralnode-2.1.11 → neuralnode-2.1.13}/publish.sh +0 -0
  61. {neuralnode-2.1.11 → neuralnode-2.1.13}/requirements_shade.txt +0 -0
  62. {neuralnode-2.1.11 → neuralnode-2.1.13}/scripts/setup.py +0 -0
  63. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/debug_import.py +0 -0
  64. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/agents/__init__.py +0 -0
  65. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/chains/__init__.py +0 -0
  66. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/config/__init__.py +0 -0
  67. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/core/__init__.py +0 -0
  68. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/core/openai_blocker.py +0 -0
  69. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/diagnostics/__init__.py +0 -0
  70. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/integrations/discord.py +0 -0
  71. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/integrations/slack.py +0 -0
  72. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/integrations/telegram.py +0 -0
  73. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/integrations/whatsapp.py +0 -0
  74. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/memory/__init__.py +0 -0
  75. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/memory/advanced.py +0 -0
  76. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/prompts/__init__.py +0 -0
  77. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/providers/__init__.py +0 -0
  78. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/providers/base.py +0 -0
  79. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/providers/chat/__init__.py +0 -0
  80. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/providers/chat/ai21.py +0 -0
  81. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/providers/chat/anthropic.py +0 -0
  82. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/providers/chat/cohere.py +0 -0
  83. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/providers/chat/deepseek.py +0 -0
  84. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/providers/chat/fireworks.py +0 -0
  85. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/providers/chat/google.py +0 -0
  86. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/providers/chat/groq.py +0 -0
  87. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/providers/chat/mistral.py +0 -0
  88. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/providers/chat/perplexity.py +0 -0
  89. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/providers/chat/together.py +0 -0
  90. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/providers/chat_models.py +0 -0
  91. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/providers/embeddings.py +0 -0
  92. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/providers/local/__init__.py +0 -0
  93. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/providers/local_providers.py +0 -0
  94. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/providers/text_generation.py +0 -0
  95. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/providers/universal_local.py +0 -0
  96. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/rag/__init__.py +0 -0
  97. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/rag/loaders.py +0 -0
  98. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/reasoning/__init__.py +0 -0
  99. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/replica.py +0 -0
  100. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/speech/__init__.py +0 -0
  101. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/thinking.py +0 -0
  102. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/tools/__init__.py +0 -0
  103. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/tools/advanced.py +0 -0
  104. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/tools/multisearch.py +0 -0
  105. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/tools/system/__init__.py +0 -0
  106. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/tools/system/operations.py +0 -0
  107. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/tools/web/__init__.py +0 -0
  108. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/tts/__init__.py +0 -0
  109. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/turboquant.py +0 -0
  110. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/utils/__init__.py +0 -0
  111. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/utils/dependencies.py +0 -0
  112. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/utils/logger.py +0 -0
  113. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/utils/metrics.py +0 -0
  114. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/vectorstores/__init__.py +0 -0
  115. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/neuralnode/vision/__init__.py +0 -0
  116. {neuralnode-2.1.11 → neuralnode-2.1.13}/src/nn/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: neuralnode
3
- Version: 2.1.11
3
+ Version: 2.1.13
4
4
  Summary: Comprehensive AI Framework with 50+ LLM Providers, Advanced Agents, Chains, Memory, RAG, and 100+ Tools
5
5
  Project-URL: Homepage, https://assem.cloud/
6
6
  Project-URL: Documentation, https://neuralnode.readthedocs.io
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "neuralnode"
7
- version = "2.1.11"
7
+ version = "2.1.13"
8
8
  description = "Comprehensive AI Framework with 50+ LLM Providers, Advanced Agents, Chains, Memory, RAG, and 100+ Tools"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -42,7 +42,7 @@ Quick Start::
42
42
  text = sr.listen()
43
43
  """
44
44
 
45
- __version__ = "2.1.11"
45
+ __version__ = "2.1.12"
46
46
  __author__ = "NeuralNode Contributors"
47
47
 
48
48
  # ── Core types ────────────────────────────────────────────────────────────────
@@ -477,13 +477,23 @@ class HorusProvider(BaseLLMProvider):
477
477
  with redirect_stdout(devnull), redirect_stderr(devnull):
478
478
  yield
479
479
  finally:
480
- if old_stdout_fd is not None:
481
- os.dup2(old_stdout_fd, 1)
482
- os.close(old_stdout_fd)
483
- if old_stderr_fd is not None:
484
- os.dup2(old_stderr_fd, 2)
485
- os.close(old_stderr_fd)
486
- devnull.close()
480
+ # Always restore fds and close devnull, even if yield raised.
481
+ try:
482
+ if old_stdout_fd is not None:
483
+ os.dup2(old_stdout_fd, 1)
484
+ os.close(old_stdout_fd)
485
+ except OSError:
486
+ pass
487
+ try:
488
+ if old_stderr_fd is not None:
489
+ os.dup2(old_stderr_fd, 2)
490
+ os.close(old_stderr_fd)
491
+ except OSError:
492
+ pass
493
+ try:
494
+ devnull.close()
495
+ except OSError:
496
+ pass
487
497
 
488
498
  def _resolve_device(self) -> str:
489
499
  if torch is not None and torch.cuda.is_available():
@@ -494,6 +504,8 @@ class HorusProvider(BaseLLMProvider):
494
504
  if torch is None:
495
505
  return None
496
506
  if torch_dtype is None:
507
+ if self.device == "cuda" and torch.cuda.is_available() and torch.cuda.is_bf16_supported():
508
+ return torch.bfloat16
497
509
  return torch.float16 if self.device == "cuda" else torch.float32
498
510
  if isinstance(torch_dtype, str):
499
511
  mapping = {
@@ -532,10 +544,12 @@ class HorusProvider(BaseLLMProvider):
532
544
  return False
533
545
  if not cls._is_gguf_model_id(model_id):
534
546
  return False
535
- # Check the registry first
547
+ # Check the registry first (both 'task' and 'type' fields)
536
548
  info = cls.HORUS_MODELS.get(model_id, {})
537
549
  if str(info.get("task", "")).lower() == "text-to-image":
538
550
  return True
551
+ if str(info.get("type", "")).lower() == "gguf" and "lens" in model_id.lower():
552
+ return True
539
553
  # Heuristic: "lens" in the model path means text-to-image
540
554
  return "lens" in model_id.lower()
541
555
 
@@ -689,6 +703,9 @@ class HorusProvider(BaseLLMProvider):
689
703
 
690
704
  if hasattr(self.model, "to"):
691
705
  self.model = self.model.to(self.device)
706
+ if hasattr(self.model, "vae") and self.model.vae is not None:
707
+ if self.device == "cuda" and self.torch_dtype == torch.float16:
708
+ self.model.vae.to(dtype=torch.float32)
692
709
  if hasattr(self.model, "set_progress_bar_config") and self.suppress_native_output:
693
710
  self.model.set_progress_bar_config(disable=True)
694
711
  return self
@@ -731,13 +748,28 @@ class HorusProvider(BaseLLMProvider):
731
748
  "Install with: pip install gguf"
732
749
  )
733
750
 
734
- # Force diffusers to recognize the newly installed gguf package
751
+ # Force diffusers to recognize the newly installed gguf package.
752
+ # Guard against versions like 'N/A' (local/editable builds) that break
753
+ # packaging.version.parse and cause an InvalidVersion crash inside
754
+ # diffusers.quantizers.gguf.gguf_quantizer.validate_environment().
735
755
  try:
736
756
  import sys
757
+ import importlib.metadata
758
+ from packaging.version import Version
759
+ try:
760
+ raw_version = importlib.metadata.version("gguf")
761
+ # Validate the version string before injecting it.
762
+ Version(raw_version)
763
+ version = raw_version
764
+ except Exception:
765
+ # Fall back to a known-good sentinel that satisfies diffusers >= 0.10.0 check
766
+ version = "0.19.0"
737
767
  if "diffusers.utils.import_utils" in sys.modules:
738
768
  sys.modules["diffusers.utils.import_utils"]._gguf_available = True
769
+ sys.modules["diffusers.utils.import_utils"]._gguf_version = version
739
770
  import diffusers.utils.import_utils as diffusers_import_utils
740
771
  diffusers_import_utils._gguf_available = True
772
+ diffusers_import_utils._gguf_version = version
741
773
  except Exception:
742
774
  pass
743
775
 
@@ -801,13 +833,35 @@ class HorusProvider(BaseLLMProvider):
801
833
  **transformer_kwargs
802
834
  )
803
835
  except Exception as exc:
836
+ # Try without quantization_config first (handles shape mismatch
837
+ # caused by mismatched ZImageTransformer2DModel config when
838
+ # the GGUF was built with a different architecture variant).
839
+ plain_kwargs = {"torch_dtype": compute_dtype}
804
840
  try:
805
841
  transformer = ZImageTransformer2DModel.from_single_file(
806
842
  model_path,
807
- torch_dtype=compute_dtype
843
+ **plain_kwargs
808
844
  )
809
845
  except Exception:
810
- raise RuntimeError(f"Failed to load GGUF transformer from '{model_path}': {exc}")
846
+ # Last resort: allow size mismatch so at least something loads
847
+ try:
848
+ transformer = ZImageTransformer2DModel.from_single_file(
849
+ model_path,
850
+ ignore_mismatched_sizes=True,
851
+ low_cpu_mem_usage=False,
852
+ **plain_kwargs
853
+ )
854
+ logger.warning(
855
+ "Loaded GGUF transformer with ignored size mismatches. "
856
+ "Image quality may be degraded. Consider using the full (non-GGUF) "
857
+ "Horus-Lens-1.0 model for best results."
858
+ )
859
+ except Exception:
860
+ raise RuntimeError(
861
+ f"Failed to load GGUF transformer from '{model_path}': {exc}\n"
862
+ "Hint: The GGUF file may be incompatible with the installed diffusers "
863
+ "version. Try: pip install --upgrade diffusers"
864
+ )
811
865
 
812
866
  base_repo_id = "tokenaii/Horus-Lens-1.0"
813
867
  pipeline_kwargs: Dict[str, Any] = {
@@ -876,6 +930,9 @@ class HorusProvider(BaseLLMProvider):
876
930
 
877
931
  if hasattr(self.model, "to"):
878
932
  self.model = self.model.to(self.device)
933
+ if hasattr(self.model, "vae") and self.model.vae is not None:
934
+ if self.device == "cuda" and self.torch_dtype == torch.float16:
935
+ self.model.vae.to(dtype=torch.float32)
879
936
  if hasattr(self.model, "set_progress_bar_config") and self.suppress_native_output:
880
937
  self.model.set_progress_bar_config(disable=True)
881
938
  return self
@@ -911,23 +968,25 @@ class HorusProvider(BaseLLMProvider):
911
968
  prev_disable_progress = os.environ.get("HF_HUB_DISABLE_PROGRESS_BARS")
912
969
  if self.suppress_native_output:
913
970
  os.environ["HF_HUB_DISABLE_PROGRESS_BARS"] = "1"
914
- with warnings.catch_warnings():
915
- warnings.filterwarnings(
916
- "ignore",
917
- message=r".*You are sending unauthenticated requests to the HF Hub.*",
918
- )
919
- model_path = hf_hub_download(
920
- repo_id=repo_id,
921
- filename=filename,
922
- cache_dir=self.cache_dir,
923
- local_files_only=self.local_files_only,
924
- token=self.token,
925
- )
926
- if self.suppress_native_output:
927
- if prev_disable_progress is None:
928
- os.environ.pop("HF_HUB_DISABLE_PROGRESS_BARS", None)
929
- else:
930
- os.environ["HF_HUB_DISABLE_PROGRESS_BARS"] = prev_disable_progress
971
+ try:
972
+ with warnings.catch_warnings():
973
+ warnings.filterwarnings(
974
+ "ignore",
975
+ message=r".*You are sending unauthenticated requests to the HF Hub.*",
976
+ )
977
+ model_path = hf_hub_download(
978
+ repo_id=repo_id,
979
+ filename=filename,
980
+ cache_dir=self.cache_dir,
981
+ local_files_only=self.local_files_only,
982
+ token=self.token,
983
+ )
984
+ finally:
985
+ if self.suppress_native_output:
986
+ if prev_disable_progress is None:
987
+ os.environ.pop("HF_HUB_DISABLE_PROGRESS_BARS", None)
988
+ else:
989
+ os.environ["HF_HUB_DISABLE_PROGRESS_BARS"] = prev_disable_progress
931
990
 
932
991
  llama_kwargs: Dict[str, Any] = {
933
992
  "model_path": model_path,
@@ -1538,17 +1597,23 @@ class HorusProvider(BaseLLMProvider):
1538
1597
  # Add tool descriptions to system prompt if tools are provided
1539
1598
  if tools:
1540
1599
  tool_desc = self._format_tool_descriptions(tools)
1600
+ tool_section = (
1601
+ "\n\nAvailable tools:\n"
1602
+ + tool_desc
1603
+ + "\n\nTo call a tool, respond with valid JSON: "
1604
+ '{"tool": "<name>", "arguments": {"<param>": "<value>"}}'
1605
+ )
1541
1606
  # Find system message or add one
1542
1607
  has_system = False
1543
1608
  for m in normalized:
1544
1609
  if m["role"] == "system":
1545
- m["content"] = m["content"] + "\n\n" + TOOL_CALLING_PROMPT.format(tool_descriptions=tool_desc)
1610
+ m["content"] = m["content"] + tool_section
1546
1611
  has_system = True
1547
1612
  break
1548
1613
  if not has_system:
1549
1614
  normalized.insert(0, {
1550
1615
  "role": "system",
1551
- "content": UNIFIED_SYSTEM_PROMPT + "\n\n" + TOOL_CALLING_PROMPT.format(tool_descriptions=tool_desc)
1616
+ "content": UNIFIED_SYSTEM_PROMPT + tool_section
1552
1617
  })
1553
1618
 
1554
1619
  prompt = self._render_prompt(normalized)
@@ -1591,7 +1656,7 @@ class HorusProvider(BaseLLMProvider):
1591
1656
  )
1592
1657
 
1593
1658
  async def achat(self, messages: List[Dict[str, Any]], **kwargs) -> Union[LLMResponse, Iterator[StreamingChunk]]:
1594
- loop = asyncio.get_event_loop()
1659
+ loop = asyncio.get_running_loop()
1595
1660
  return await loop.run_in_executor(None, lambda: self.chat(messages, **kwargs))
1596
1661
 
1597
1662
  def complete(self, prompt: str, model: Optional[str] = None, **kwargs) -> LLMResponse:
@@ -1719,8 +1784,7 @@ class HorusProvider(BaseLLMProvider):
1719
1784
 
1720
1785
  async def aembed(self, texts: Union[str, List[str]], model: Optional[str] = None, **kwargs) -> Union[List[float], List[List[float]]]:
1721
1786
  """Async version of embed - runs in executor."""
1722
- import asyncio
1723
- loop = asyncio.get_event_loop()
1787
+ loop = asyncio.get_running_loop()
1724
1788
  return await loop.run_in_executor(None, lambda: self.embed(texts, model=model, **kwargs))
1725
1789
 
1726
1790
  def get_model_info(self) -> Dict[str, Any]:
Binary file
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes