neuralnode 2.1.2__tar.gz → 2.1.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 (117) hide show
  1. {neuralnode-2.1.2 → neuralnode-2.1.4}/PKG-INFO +19 -1
  2. {neuralnode-2.1.2 → neuralnode-2.1.4}/README.md +16 -0
  3. {neuralnode-2.1.2 → neuralnode-2.1.4}/docs/documentation.md +15 -0
  4. neuralnode-2.1.4/examples/horus_codes_camples/02_horus_lens.py +16 -0
  5. {neuralnode-2.1.2 → neuralnode-2.1.4}/examples/horus_codes_camples/README.md +2 -1
  6. neuralnode-2.1.4/examples/horus_download_guide.py +39 -0
  7. {neuralnode-2.1.2 → neuralnode-2.1.4}/examples/horus_transformers_features.py +6 -15
  8. {neuralnode-2.1.2 → neuralnode-2.1.4}/pyproject.toml +3 -1
  9. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/__init__.py +5 -2
  10. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/providers/__init__.py +5 -2
  11. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/providers/horus.py +216 -15
  12. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/utils/dependencies.py +8 -1
  13. neuralnode-2.1.2/examples/horus_codes_camples/02_with_token.py +0 -19
  14. neuralnode-2.1.2/examples/horus_download_guide.py +0 -233
  15. {neuralnode-2.1.2 → neuralnode-2.1.4}/.env.example +0 -0
  16. {neuralnode-2.1.2 → neuralnode-2.1.4}/.github/workflows/tests.yml +0 -0
  17. {neuralnode-2.1.2 → neuralnode-2.1.4}/Dockerfile +0 -0
  18. {neuralnode-2.1.2 → neuralnode-2.1.4}/LICENSE +0 -0
  19. {neuralnode-2.1.2 → neuralnode-2.1.4}/docker-compose.yml +0 -0
  20. {neuralnode-2.1.2 → neuralnode-2.1.4}/docs/ecosystem_plan.md +0 -0
  21. {neuralnode-2.1.2 → neuralnode-2.1.4}/docs/replica_voice_ids.csv +0 -0
  22. {neuralnode-2.1.2 → neuralnode-2.1.4}/docs/replica_voice_ids.md +0 -0
  23. {neuralnode-2.1.2 → neuralnode-2.1.4}/docs/telegram_guide.md +0 -0
  24. {neuralnode-2.1.2 → neuralnode-2.1.4}/examples/agent_with_tools.py +0 -0
  25. {neuralnode-2.1.2 → neuralnode-2.1.4}/examples/basic_chat.py +0 -0
  26. {neuralnode-2.1.2 → neuralnode-2.1.4}/examples/horus_codes_camples/01_basic_usage.py +0 -0
  27. {neuralnode-2.1.2 → neuralnode-2.1.4}/examples/horus_codes_camples/03_one_liner.py +0 -0
  28. {neuralnode-2.1.2 → neuralnode-2.1.4}/examples/horus_codes_camples/04_custom_cache.py +0 -0
  29. {neuralnode-2.1.2 → neuralnode-2.1.4}/examples/horus_codes_camples/05_4bit_quantization.py +0 -0
  30. {neuralnode-2.1.2 → neuralnode-2.1.4}/examples/horus_codes_camples/06_8bit_quantization.py +0 -0
  31. {neuralnode-2.1.2 → neuralnode-2.1.4}/examples/horus_codes_camples/07_multi_gpu.py +0 -0
  32. {neuralnode-2.1.2 → neuralnode-2.1.4}/examples/horus_codes_camples/08_flash_attention.py +0 -0
  33. {neuralnode-2.1.2 → neuralnode-2.1.4}/examples/horus_codes_camples/09_data_types.py +0 -0
  34. {neuralnode-2.1.2 → neuralnode-2.1.4}/examples/horus_codes_camples/10_generation_params.py +0 -0
  35. {neuralnode-2.1.2 → neuralnode-2.1.4}/examples/horus_codes_camples/11_streaming.py +0 -0
  36. {neuralnode-2.1.2 → neuralnode-2.1.4}/examples/horus_codes_camples/12_chat_templates.py +0 -0
  37. {neuralnode-2.1.2 → neuralnode-2.1.4}/examples/horus_codes_camples/13_offline_mode.py +0 -0
  38. {neuralnode-2.1.2 → neuralnode-2.1.4}/examples/horus_codes_camples/14_force_download.py +0 -0
  39. {neuralnode-2.1.2 → neuralnode-2.1.4}/examples/horus_codes_camples/15_model_info.py +0 -0
  40. {neuralnode-2.1.2 → neuralnode-2.1.4}/examples/horus_codes_camples/16_cpu_offloading.py +0 -0
  41. {neuralnode-2.1.2 → neuralnode-2.1.4}/examples/horus_codes_camples/17_cpu_only.py +0 -0
  42. {neuralnode-2.1.2 → neuralnode-2.1.4}/examples/horus_codes_camples/18_production_setup.py +0 -0
  43. {neuralnode-2.1.2 → neuralnode-2.1.4}/examples/horus_codes_camples/19_gguf_4bit.py +0 -0
  44. {neuralnode-2.1.2 → neuralnode-2.1.4}/examples/horus_codes_camples/20_gguf_5bit.py +0 -0
  45. {neuralnode-2.1.2 → neuralnode-2.1.4}/examples/horus_codes_camples/21_gguf_6bit.py +0 -0
  46. {neuralnode-2.1.2 → neuralnode-2.1.4}/examples/horus_codes_camples/22_gguf_8bit.py +0 -0
  47. {neuralnode-2.1.2 → neuralnode-2.1.4}/examples/horus_codes_camples/23_gguf_16bit.py +0 -0
  48. {neuralnode-2.1.2 → neuralnode-2.1.4}/examples/horus_codes_camples/24_list_models.py +0 -0
  49. {neuralnode-2.1.2 → neuralnode-2.1.4}/examples/horus_codes_camples/25_interactive_chat.py +0 -0
  50. {neuralnode-2.1.2 → neuralnode-2.1.4}/examples/horus_examples.py +0 -0
  51. {neuralnode-2.1.2 → neuralnode-2.1.4}/examples/horus_tq_ready_gguf.py +0 -0
  52. {neuralnode-2.1.2 → neuralnode-2.1.4}/examples/local_models.py +0 -0
  53. {neuralnode-2.1.2 → neuralnode-2.1.4}/examples/neuralnode_v21_complete_demo.py +0 -0
  54. {neuralnode-2.1.2 → neuralnode-2.1.4}/examples/shade_model_with_tools.py +0 -0
  55. {neuralnode-2.1.2 → neuralnode-2.1.4}/examples/telegram_bot_demo.py +0 -0
  56. {neuralnode-2.1.2 → neuralnode-2.1.4}/examples/thinking_mode_example.py +0 -0
  57. {neuralnode-2.1.2 → neuralnode-2.1.4}/examples/tts_demo.py +0 -0
  58. {neuralnode-2.1.2 → neuralnode-2.1.4}/examples/turboquant_example.py +0 -0
  59. {neuralnode-2.1.2 → neuralnode-2.1.4}/examples/v3_features.py +0 -0
  60. {neuralnode-2.1.2 → neuralnode-2.1.4}/horus_chat_voice.py +0 -0
  61. {neuralnode-2.1.2 → neuralnode-2.1.4}/neuralnode_horus_replica_telegram.ipynb +0 -0
  62. {neuralnode-2.1.2 → neuralnode-2.1.4}/publish.bat +0 -0
  63. {neuralnode-2.1.2 → neuralnode-2.1.4}/publish.sh +0 -0
  64. {neuralnode-2.1.2 → neuralnode-2.1.4}/requirements_shade.txt +0 -0
  65. {neuralnode-2.1.2 → neuralnode-2.1.4}/scripts/setup.py +0 -0
  66. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/debug_import.py +0 -0
  67. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/agents/__init__.py +0 -0
  68. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/chains/__init__.py +0 -0
  69. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/config/__init__.py +0 -0
  70. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/core/__init__.py +0 -0
  71. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/core/openai_blocker.py +0 -0
  72. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/diagnostics/__init__.py +0 -0
  73. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/integrations/discord.py +0 -0
  74. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/integrations/slack.py +0 -0
  75. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/integrations/telegram.py +0 -0
  76. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/integrations/whatsapp.py +0 -0
  77. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/memory/__init__.py +0 -0
  78. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/memory/advanced.py +0 -0
  79. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/prompts/__init__.py +0 -0
  80. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/providers/base.py +0 -0
  81. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/providers/chat/__init__.py +0 -0
  82. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/providers/chat/ai21.py +0 -0
  83. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/providers/chat/anthropic.py +0 -0
  84. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/providers/chat/cohere.py +0 -0
  85. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/providers/chat/deepseek.py +0 -0
  86. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/providers/chat/fireworks.py +0 -0
  87. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/providers/chat/google.py +0 -0
  88. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/providers/chat/groq.py +0 -0
  89. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/providers/chat/mistral.py +0 -0
  90. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/providers/chat/perplexity.py +0 -0
  91. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/providers/chat/together.py +0 -0
  92. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/providers/chat_models.py +0 -0
  93. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/providers/embeddings.py +0 -0
  94. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/providers/local/__init__.py +0 -0
  95. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/providers/local_providers.py +0 -0
  96. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/providers/text_generation.py +0 -0
  97. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/providers/universal_local.py +0 -0
  98. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/rag/__init__.py +0 -0
  99. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/rag/loaders.py +0 -0
  100. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/reasoning/__init__.py +0 -0
  101. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/replica.py +0 -0
  102. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/speech/__init__.py +0 -0
  103. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/thinking.py +0 -0
  104. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/tools/__init__.py +0 -0
  105. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/tools/advanced.py +0 -0
  106. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/tools/multisearch.py +0 -0
  107. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/tools/system/__init__.py +0 -0
  108. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/tools/system/operations.py +0 -0
  109. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/tools/web/__init__.py +0 -0
  110. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/tts/__init__.py +0 -0
  111. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/turboquant.py +0 -0
  112. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/utils/__init__.py +0 -0
  113. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/utils/logger.py +0 -0
  114. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/utils/metrics.py +0 -0
  115. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/vectorstores/__init__.py +0 -0
  116. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/neuralnode/vision/__init__.py +0 -0
  117. {neuralnode-2.1.2 → neuralnode-2.1.4}/src/nn/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: neuralnode
3
- Version: 2.1.2
3
+ Version: 2.1.4
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
@@ -92,9 +92,11 @@ Requires-Dist: groq>=0.4.0; extra == 'groq'
92
92
  Provides-Extra: horus
93
93
  Requires-Dist: accelerate>=0.24.0; extra == 'horus'
94
94
  Requires-Dist: bitsandbytes>=0.41.0; extra == 'horus'
95
+ Requires-Dist: diffusers>=0.30.0; extra == 'horus'
95
96
  Requires-Dist: einops>=0.7.0; extra == 'horus'
96
97
  Requires-Dist: huggingface-hub>=0.23.0; extra == 'horus'
97
98
  Requires-Dist: llama-cpp-python>=0.2.0; extra == 'horus'
99
+ Requires-Dist: pillow>=10.0.0; extra == 'horus'
98
100
  Requires-Dist: protobuf>=3.20.0; extra == 'horus'
99
101
  Requires-Dist: scipy>=1.10.0; extra == 'horus'
100
102
  Requires-Dist: sentencepiece>=0.1.99; extra == 'horus'
@@ -210,6 +212,8 @@ All Horus models use:
210
212
  - unified chat template: `horus_unified`
211
213
  - unified context window: `8192`
212
214
 
215
+ Horus downloads are public-only. Private or gated Hugging Face repositories are not supported.
216
+
213
217
  ```python
214
218
  import neuralnode as nn
215
219
 
@@ -243,6 +247,20 @@ Supported IDs currently include:
243
247
  - `tokenaii/Horus-1.0-4B-GGUF/Horus-1.0-4B-Q6_K.gguf`
244
248
  - `tokenaii/Horus-1.0-4B-GGUF/Horus-1.0-4B-Q8_0.gguf`
245
249
  - `tokenaii/Horus-1.0-4B-GGUF/Horus-1.0-4B-F16.gguf`
250
+ - `tokenaii/Horus-Lens-1.0`
251
+
252
+ ### Horus Lens text-to-image
253
+
254
+ ```python
255
+ import neuralnode as nn
256
+
257
+ model = nn.HorusLensModel("tokenaii/Horus-Lens-1.0").load()
258
+ model.generate_image(
259
+ "A detailed cinematic image of an ancient Egyptian AI lab, golden light",
260
+ output_path="outputs/horus_lens.png",
261
+ seed=42,
262
+ )
263
+ ```
246
264
 
247
265
  ## Replica TTS
248
266
 
@@ -44,6 +44,8 @@ All Horus models use:
44
44
  - unified chat template: `horus_unified`
45
45
  - unified context window: `8192`
46
46
 
47
+ Horus downloads are public-only. Private or gated Hugging Face repositories are not supported.
48
+
47
49
  ```python
48
50
  import neuralnode as nn
49
51
 
@@ -77,6 +79,20 @@ Supported IDs currently include:
77
79
  - `tokenaii/Horus-1.0-4B-GGUF/Horus-1.0-4B-Q6_K.gguf`
78
80
  - `tokenaii/Horus-1.0-4B-GGUF/Horus-1.0-4B-Q8_0.gguf`
79
81
  - `tokenaii/Horus-1.0-4B-GGUF/Horus-1.0-4B-F16.gguf`
82
+ - `tokenaii/Horus-Lens-1.0`
83
+
84
+ ### Horus Lens text-to-image
85
+
86
+ ```python
87
+ import neuralnode as nn
88
+
89
+ model = nn.HorusLensModel("tokenaii/Horus-Lens-1.0").load()
90
+ model.generate_image(
91
+ "A detailed cinematic image of an ancient Egyptian AI lab, golden light",
92
+ output_path="outputs/horus_lens.png",
93
+ seed=42,
94
+ )
95
+ ```
80
96
 
81
97
  ## Replica TTS
82
98
 
@@ -103,6 +103,7 @@ Current Horus guarantees:
103
103
  - chat template is unified as `horus_unified`
104
104
  - Horus can use Replica TTS
105
105
  - Horus can use TurboQuant on Transformers-based generation paths
106
+ - Horus downloads are public-only
106
107
 
107
108
  Example:
108
109
 
@@ -133,6 +134,20 @@ Available Horus model IDs:
133
134
  - `tokenaii/Horus-1.0-4B-GGUF/Horus-1.0-4B-Q6_K.gguf`
134
135
  - `tokenaii/Horus-1.0-4B-GGUF/Horus-1.0-4B-Q8_0.gguf`
135
136
  - `tokenaii/Horus-1.0-4B-GGUF/Horus-1.0-4B-F16.gguf`
137
+ - `tokenaii/Horus-Lens-1.0`
138
+
139
+ Horus Lens text-to-image example:
140
+
141
+ ```python
142
+ import neuralnode as nn
143
+
144
+ model = nn.HorusLensModel("tokenaii/Horus-Lens-1.0").load()
145
+ model.generate_image(
146
+ "A detailed cinematic image of an ancient Egyptian AI lab, golden light",
147
+ output_path="outputs/horus_lens.png",
148
+ seed=42,
149
+ )
150
+ ```
136
151
 
137
152
  ## Replica
138
153
 
@@ -0,0 +1,16 @@
1
+ """
2
+ Generate an image with Horus Lens.
3
+ """
4
+
5
+ import neuralnode as nn
6
+
7
+
8
+ model = nn.HorusLensModel("tokenaii/Horus-Lens-1.0").load()
9
+
10
+ model.generate_image(
11
+ "A detailed cinematic image of an ancient Egyptian AI lab, golden light",
12
+ output_path="outputs/horus_lens.png",
13
+ seed=42,
14
+ )
15
+
16
+ print("Saved image to outputs/horus_lens.png")
@@ -12,6 +12,7 @@ This folder contains code examples for downloading and using Horus models.
12
12
  | `tokenaii/Horus-1.0-4B-GGUF/Horus-1.0-4B-Q6_K.gguf` | 3.71 GB | GGUF 6-bit | Better quality with reasonable memory |
13
13
  | `tokenaii/Horus-1.0-4B-GGUF/Horus-1.0-4B-Q8_0.gguf` | 4.8 GB | GGUF 8-bit | Good quality with ~50% memory savings |
14
14
  | `tokenaii/Horus-1.0-4B-GGUF/Horus-1.0-4B-F16.gguf` | 9.83 GB | GGUF 16-bit | Maximum quality, same as original |
15
+ | `tokenaii/Horus-Lens-1.0` | Unknown | Text-to-image | Image generation from prompts |
15
16
 
16
17
  ## Installation
17
18
 
@@ -33,7 +34,7 @@ print(response.content)
33
34
 
34
35
  ### Basic Usage
35
36
  - `01_basic_usage.py` - Simple download and use
36
- - `02_with_token.py` - Private models with HF token
37
+ - `02_horus_lens.py` - Generate an image with Horus Lens
37
38
  - `03_one_liner.py` - One-liner usage
38
39
  - `04_custom_cache.py` - Custom download location
39
40
 
@@ -0,0 +1,39 @@
1
+ """
2
+ Horus public model download and usage guide.
3
+
4
+ NeuralNode Horus downloads are public-only. If a Hugging Face repository is
5
+ private or gated, loading fails instead of using credentials.
6
+ """
7
+
8
+ import neuralnode as nn
9
+
10
+
11
+ def example_simple_chat_model():
12
+ model = nn.HorusModel("tokenaii/horus").load()
13
+ response = model.chat([{"role": "user", "content": "Hello!"}])
14
+ print(response.content)
15
+
16
+
17
+ def example_custom_cache():
18
+ model = nn.HorusModel(
19
+ "tokenaii/horus",
20
+ cache_dir="D:/Models/Horus",
21
+ ).load()
22
+ print(model.get_model_info())
23
+
24
+
25
+ def example_lens_image():
26
+ model = nn.HorusLensModel("tokenaii/Horus-Lens-1.0").load()
27
+ model.generate_image(
28
+ "A cinematic portrait of an ancient Egyptian AI oracle, detailed, warm light",
29
+ output_path="outputs/horus_lens.png",
30
+ seed=42,
31
+ )
32
+ print("Saved image to outputs/horus_lens.png")
33
+
34
+
35
+ if __name__ == "__main__":
36
+ print(nn.HorusModel.list_available_models())
37
+ example_simple_chat_model()
38
+ example_custom_cache()
39
+ example_lens_image()
@@ -292,21 +292,12 @@ def example_8_generation_params():
292
292
  print()
293
293
 
294
294
 
295
- def example_9_network_auth():
296
- """Network and authentication options."""
295
+ def example_9_network_options():
296
+ """Network and download options."""
297
297
  print("=" * 70)
298
- print("Example 9: Network & Authentication")
298
+ print("Example 9: Network & Download Options")
299
299
  print("=" * 70)
300
-
301
- # With HuggingFace token (for private/gated models)
302
- model_token = nn.HorusModel(
303
- "tokenaii/horus",
304
- token="hf_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
305
- ).load()
306
-
307
- # Via environment variable (recommended):
308
- # export HF_TOKEN="your_token_here"
309
-
300
+
310
301
  # With proxy
311
302
  model_proxy = nn.HorusModel(
312
303
  "tokenaii/horus",
@@ -328,7 +319,7 @@ def example_9_network_auth():
328
319
  resume_download=True,
329
320
  ).load()
330
321
 
331
- print("[OK] Network & auth options demonstrated")
322
+ print("[OK] Network and download options demonstrated")
332
323
  print()
333
324
 
334
325
 
@@ -492,7 +483,7 @@ if __name__ == "__main__":
492
483
  # example_6_attention_options()
493
484
  # example_7_advanced_loading()
494
485
  # example_8_generation_params()
495
- # example_9_network_auth()
486
+ # example_9_network_options()
496
487
  # example_10_model_info()
497
488
  example_11_list_models()
498
489
  # example_12_chat_templates()
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "neuralnode"
7
- version = "2.1.2"
7
+ version = "2.1.4"
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"
@@ -66,12 +66,14 @@ horus = [
66
66
  "huggingface_hub>=0.23.0",
67
67
  "torch>=2.0.0",
68
68
  "transformers>=4.35.0",
69
+ "diffusers>=0.30.0",
69
70
  "accelerate>=0.24.0",
70
71
  "bitsandbytes>=0.41.0", # 4-bit/8-bit quantization
71
72
  "sentencepiece>=0.1.99", # Tokenization
72
73
  "protobuf>=3.20.0", # Model serialization
73
74
  "scipy>=1.10.0", # Math operations
74
75
  "einops>=0.7.0", # Tensor operations
76
+ "pillow>=10.0.0", # Image output
75
77
  ]
76
78
 
77
79
  # Flash Attention (Windows requires special install)
@@ -42,7 +42,7 @@ Quick Start::
42
42
  text = sr.listen()
43
43
  """
44
44
 
45
- __version__ = "2.1.2"
45
+ __version__ = "2.1.4"
46
46
  __author__ = "NeuralNode Contributors"
47
47
 
48
48
  # ── Core types ────────────────────────────────────────────────────────────────
@@ -83,8 +83,11 @@ from .providers import (
83
83
  UniversalLocalProvider,
84
84
  # Custom models
85
85
  Horus,
86
+ HorusLensModel,
86
87
  HorusModel,
87
88
  HorusProvider,
89
+ load_horus_lens,
90
+ print_model_list,
88
91
  )
89
92
 
90
93
  # ── Memory ────────────────────────────────────────────────────────────────────
@@ -648,7 +651,7 @@ __all__ = [
648
651
  "OllamaProvider", "AnthropicProvider", "GoogleProvider",
649
652
  "GroqProvider", "MistralProvider", "CohereProvider", "DeepSeekProvider",
650
653
  "LlamaCppProvider", "TransformersProvider", "UniversalLocalProvider",
651
- "Horus", "HorusModel", "HorusProvider",
654
+ "Horus", "HorusLensModel", "HorusModel", "HorusProvider", "load_horus_lens", "print_model_list",
652
655
 
653
656
  # Memory
654
657
  "ConversationMemory", "FileMemory", "SlidingWindowMemory", "SummaryMemory",
@@ -108,12 +108,15 @@ from .universal_local import UniversalLocalProvider, load_local_model
108
108
 
109
109
  # ── Custom Model Providers ─────────────────────────────────────────────────────
110
110
  try:
111
- from .horus import HorusProvider, HorusModel, Horus, load_horus
111
+ from .horus import HorusProvider, HorusModel, HorusLensModel, Horus, load_horus, load_horus_lens, print_model_list
112
112
  except ImportError:
113
113
  HorusProvider = None # type: ignore
114
114
  HorusModel = None # type: ignore
115
+ HorusLensModel = None # type: ignore
115
116
  Horus = None # type: ignore
116
117
  load_horus = None # type: ignore
118
+ load_horus_lens = None # type: ignore
119
+ print_model_list = None # type: ignore
117
120
 
118
121
  # MLX Provider (Apple Silicon — optional)
119
122
  try:
@@ -235,5 +238,5 @@ __all__ = [
235
238
  "UniversalLocalProvider", "load_local_model",
236
239
 
237
240
  # Custom Models
238
- "HorusProvider", "HorusModel", "Horus", "load_horus",
241
+ "HorusProvider", "HorusModel", "HorusLensModel", "Horus", "load_horus", "load_horus_lens", "print_model_list",
239
242
  ]
@@ -34,6 +34,14 @@ except ImportError:
34
34
  AutoTokenizer = None
35
35
  TextIteratorStreamer = None
36
36
 
37
+ try:
38
+ from diffusers import DiffusionPipeline
39
+
40
+ DIFFUSERS_AVAILABLE = True
41
+ except ImportError:
42
+ DIFFUSERS_AVAILABLE = False
43
+ DiffusionPipeline = None
44
+
37
45
  try:
38
46
  import llama_cpp
39
47
  from llama_cpp import Llama
@@ -70,6 +78,17 @@ def _refresh_transformers_imports() -> None:
70
78
  TRANSFORMERS_AVAILABLE = False
71
79
 
72
80
 
81
+ def _refresh_diffusers_imports() -> None:
82
+ global DIFFUSERS_AVAILABLE, DiffusionPipeline
83
+ try:
84
+ from diffusers import DiffusionPipeline as _DiffusionPipeline
85
+
86
+ DiffusionPipeline = _DiffusionPipeline
87
+ DIFFUSERS_AVAILABLE = True
88
+ except ImportError:
89
+ DIFFUSERS_AVAILABLE = False
90
+
91
+
73
92
  def _refresh_llama_imports() -> None:
74
93
  global LLAMA_CPP_AVAILABLE, llama_cpp, Llama
75
94
  try:
@@ -205,6 +224,14 @@ class HorusProvider(BaseLLMProvider):
205
224
  "quantization": "F16",
206
225
  "file_size": "9.83 GB",
207
226
  },
227
+ "tokenaii/Horus-Lens-1.0": {
228
+ "name": "Horus-Lens-1.0",
229
+ "official_name": "Horus-Lens-1.0",
230
+ "size": "Unknown",
231
+ "type": "text-to-image",
232
+ "repo_id": "tokenaii/Horus-Lens-1.0",
233
+ "task": "text-to-image",
234
+ },
208
235
  }
209
236
 
210
237
  CHAT_TEMPLATES = {
@@ -276,20 +303,36 @@ class HorusProvider(BaseLLMProvider):
276
303
  **kwargs,
277
304
  ):
278
305
  self.auto_install_deps = auto_install_deps
279
- if not self._is_gguf_model_id(model_id) and not TRANSFORMERS_AVAILABLE and self.auto_install_deps:
306
+
307
+ # `create_provider("horus", model="...")` passes `model`; map it to Horus `model_id`.
308
+ forwarded_model = kwargs.pop("model", None)
309
+ if forwarded_model:
310
+ model_id = str(forwarded_model)
311
+
312
+ # Case-insensitive normalization of model_id to match keys in HORUS_MODELS
313
+ matched_key = None
314
+ for k in self.HORUS_MODELS.keys():
315
+ if k.lower() == model_id.lower():
316
+ matched_key = k
317
+ break
318
+ if matched_key:
319
+ model_id = matched_key
320
+
321
+ is_lens_model = self._is_text_to_image_model_id(model_id)
322
+ if (
323
+ not is_lens_model
324
+ and not self._is_gguf_model_id(model_id)
325
+ and not TRANSFORMERS_AVAILABLE
326
+ and self.auto_install_deps
327
+ ):
280
328
  ensure_feature_dependencies("horus_transformers", auto_install=True)
281
329
  _refresh_transformers_imports()
282
- if not self._is_gguf_model_id(model_id) and not TRANSFORMERS_AVAILABLE:
330
+ if not is_lens_model and not self._is_gguf_model_id(model_id) and not TRANSFORMERS_AVAILABLE:
283
331
  raise ImportError(
284
332
  "transformers and torch are required for Horus transformers models. "
285
333
  "Install with: pip install transformers torch"
286
334
  )
287
335
 
288
- # `create_provider("horus", model="...")` passes `model`; map it to Horus `model_id`.
289
- forwarded_model = kwargs.pop("model", None)
290
- if forwarded_model:
291
- model_id = str(forwarded_model)
292
-
293
336
  super().__init__(model=model_id, **kwargs)
294
337
 
295
338
  self.model_id = model_id
@@ -316,7 +359,9 @@ class HorusProvider(BaseLLMProvider):
316
359
  self.local_files_only = local_files_only
317
360
  self.trust_remote_code = trust_remote_code
318
361
 
319
- self.token = token or os.getenv("HF_TOKEN") or os.getenv("HUGGINGFACE_TOKEN")
362
+ if token and not suppress_warnings:
363
+ logger.warning("Horus downloads are public-only; the provided credential was ignored.")
364
+ self.token = None
320
365
  self.proxies = proxies
321
366
  self.force_download = force_download
322
367
  self.resume_download = resume_download
@@ -414,12 +459,26 @@ class HorusProvider(BaseLLMProvider):
414
459
  def _is_gguf_model_id(model_id: str) -> bool:
415
460
  return model_id.lower().endswith(".gguf")
416
461
 
462
+ @classmethod
463
+ def _is_text_to_image_model_id(cls, model_id: str) -> bool:
464
+ if not model_id:
465
+ return False
466
+ info = cls.HORUS_MODELS.get(model_id, {})
467
+ if str(info.get("type", "")).lower() == "text-to-image":
468
+ return True
469
+ return "lens" in model_id.lower()
470
+
417
471
  def _build_model_info(self) -> Dict[str, Any]:
418
472
  base = dict(self.HORUS_MODELS.get(self.model_id, {}))
419
473
  base.setdefault("name", self.model_id.split("/")[-1])
420
474
  base.setdefault("official_name", self._infer_official_name(self.model_id))
421
475
  base.setdefault("size", "Unknown")
422
- base.setdefault("type", "gguf" if self._is_gguf_model_id(self.model_id) else "safetensors")
476
+ base.setdefault(
477
+ "type",
478
+ "text-to-image"
479
+ if self._is_text_to_image_model_id(self.model_id)
480
+ else ("gguf" if self._is_gguf_model_id(self.model_id) else "safetensors"),
481
+ )
423
482
  if base.get("type") == "gguf" and "quantization" not in base:
424
483
  _, filename = self._split_repo_and_filename(self.model_id)
425
484
  quant_match = re.search(r"-(Q\d(?:_[A-Z0-9]+)?|TQ\d(?:_[A-Z0-9]+)?|F16|BF16)\.gguf$", filename, flags=re.IGNORECASE)
@@ -443,6 +502,8 @@ class HorusProvider(BaseLLMProvider):
443
502
  self._configure_external_logging()
444
503
  if self.model is not None:
445
504
  return self
505
+ if self._is_text_to_image_model_id(self.model_id):
506
+ return self._load_text_to_image()
446
507
  if self._is_gguf_model_id(self.model_id):
447
508
  return self._load_gguf()
448
509
  return self._load_transformers()
@@ -460,6 +521,85 @@ class HorusProvider(BaseLLMProvider):
460
521
  except Exception:
461
522
  pass
462
523
 
524
+ def _load_text_to_image(self) -> "HorusProvider":
525
+ if not DIFFUSERS_AVAILABLE and self.auto_install_deps:
526
+ ensure_feature_dependencies("horus_lens", auto_install=True)
527
+ _refresh_diffusers_imports()
528
+ _refresh_transformers_imports()
529
+ if not DIFFUSERS_AVAILABLE:
530
+ raise ImportError(
531
+ "diffusers, transformers, torch, accelerate, and pillow are required for Horus Lens.\n"
532
+ "Install with:\n"
533
+ " pip install \"neuralnode[horus]\"\n"
534
+ "or:\n"
535
+ " pip install diffusers transformers torch accelerate pillow"
536
+ )
537
+ if torch is None:
538
+ _refresh_transformers_imports()
539
+ if torch is None:
540
+ raise ImportError("torch is required for Horus Lens text-to-image generation.")
541
+
542
+ repo_id = self._model_info.get("repo_id", self.model_id)
543
+ pipeline_kwargs: Dict[str, Any] = {
544
+ "cache_dir": self.cache_dir,
545
+ "local_files_only": self.local_files_only,
546
+ "trust_remote_code": self.trust_remote_code,
547
+ }
548
+ if self.revision:
549
+ pipeline_kwargs["revision"] = self.revision
550
+ if self.variant:
551
+ pipeline_kwargs["variant"] = self.variant
552
+ if self.torch_dtype is not None:
553
+ pipeline_kwargs["torch_dtype"] = self.torch_dtype
554
+
555
+ try:
556
+ # Check if this model is Horus-Lens-1.0 which requires custom component mapping
557
+ if "horus-lens-1.0" in repo_id.lower():
558
+ try:
559
+ try:
560
+ from diffusers import ZImagePipeline
561
+ except ImportError:
562
+ from diffusers.pipelines.z_image.pipeline_z_image import ZImagePipeline
563
+
564
+ class PatchedZImagePipeline(ZImagePipeline):
565
+ def __init__(
566
+ self,
567
+ horus_scheduler,
568
+ horus_text_encoder,
569
+ horus_tokenizer,
570
+ horus_transformer,
571
+ horus_vae,
572
+ ):
573
+ super().__init__(
574
+ scheduler=horus_scheduler,
575
+ text_encoder=horus_text_encoder,
576
+ tokenizer=horus_tokenizer,
577
+ transformer=horus_transformer,
578
+ vae=horus_vae,
579
+ )
580
+
581
+ self.model = DiffusionPipeline.from_pretrained(
582
+ repo_id,
583
+ pipeline_class=PatchedZImagePipeline,
584
+ **pipeline_kwargs
585
+ )
586
+ except Exception:
587
+ # Fallback to default load if patch fails
588
+ self.model = DiffusionPipeline.from_pretrained(repo_id, **pipeline_kwargs)
589
+ else:
590
+ self.model = DiffusionPipeline.from_pretrained(repo_id, **pipeline_kwargs)
591
+ except Exception as exc:
592
+ raise RuntimeError(
593
+ f"Failed to load Horus Lens from '{repo_id}'. "
594
+ "Only public Hugging Face repositories are supported."
595
+ ) from exc
596
+
597
+ if hasattr(self.model, "to"):
598
+ self.model = self.model.to(self.device)
599
+ if hasattr(self.model, "set_progress_bar_config") and self.suppress_native_output:
600
+ self.model.set_progress_bar_config(disable=True)
601
+ return self
602
+
463
603
  def _load_gguf(self) -> "HorusProvider":
464
604
  if not HF_HUB_AVAILABLE and self.auto_install_deps:
465
605
  ensure_feature_dependencies("horus_gguf", auto_install=True)
@@ -501,7 +641,6 @@ class HorusProvider(BaseLLMProvider):
501
641
  filename=filename,
502
642
  cache_dir=self.cache_dir,
503
643
  local_files_only=self.local_files_only,
504
- token=self.token,
505
644
  )
506
645
  if self.suppress_native_output:
507
646
  if prev_disable_progress is None:
@@ -616,8 +755,6 @@ class HorusProvider(BaseLLMProvider):
616
755
  "resume_download": self.resume_download,
617
756
  "use_fast": True,
618
757
  }
619
- if self.token:
620
- tokenizer_kwargs["token"] = self.token
621
758
  if resolved_subfolder:
622
759
  tokenizer_kwargs["subfolder"] = resolved_subfolder
623
760
  if self.revision:
@@ -643,8 +780,6 @@ class HorusProvider(BaseLLMProvider):
643
780
  "proxies": self.proxies,
644
781
  "force_download": self.force_download,
645
782
  }
646
- if self.token:
647
- model_kwargs["token"] = self.token
648
783
  if resolved_subfolder:
649
784
  model_kwargs["subfolder"] = resolved_subfolder
650
785
  if self.revision:
@@ -1027,6 +1162,53 @@ class HorusProvider(BaseLLMProvider):
1027
1162
  return "Hello! How can I help you?"
1028
1163
  return cleaned
1029
1164
 
1165
+ def generate_image(
1166
+ self,
1167
+ prompt: str,
1168
+ output_path: Optional[str] = None,
1169
+ negative_prompt: Optional[str] = None,
1170
+ width: Optional[int] = None,
1171
+ height: Optional[int] = None,
1172
+ num_inference_steps: int = 30,
1173
+ guidance_scale: float = 7.5,
1174
+ seed: Optional[int] = None,
1175
+ **kwargs,
1176
+ ) -> Any:
1177
+ """Generate an image with a Horus text-to-image model and optionally save it."""
1178
+ if not self._is_text_to_image_model_id(self.model_id):
1179
+ raise RuntimeError("generate_image is only available for Horus text-to-image models.")
1180
+ self.load()
1181
+ if self.model is None:
1182
+ raise RuntimeError("Horus text-to-image model is not loaded.")
1183
+
1184
+ call_kwargs: Dict[str, Any] = {
1185
+ "prompt": prompt,
1186
+ "num_inference_steps": num_inference_steps,
1187
+ "guidance_scale": guidance_scale,
1188
+ **kwargs,
1189
+ }
1190
+ if negative_prompt:
1191
+ call_kwargs["negative_prompt"] = negative_prompt
1192
+ if width is not None:
1193
+ call_kwargs["width"] = int(width)
1194
+ if height is not None:
1195
+ call_kwargs["height"] = int(height)
1196
+ if seed is not None and torch is not None:
1197
+ generator_device = self.device if self.device == "cuda" else "cpu"
1198
+ call_kwargs["generator"] = torch.Generator(device=generator_device).manual_seed(int(seed))
1199
+
1200
+ with self._quiet_native_output():
1201
+ result = self.model(**call_kwargs)
1202
+ images = getattr(result, "images", None)
1203
+ if not images:
1204
+ raise RuntimeError("Horus text-to-image generation did not return an image.")
1205
+ image = images[0]
1206
+ if output_path:
1207
+ path = Path(output_path)
1208
+ path.parent.mkdir(parents=True, exist_ok=True)
1209
+ image.save(path)
1210
+ return image
1211
+
1030
1212
  def chat(
1031
1213
  self,
1032
1214
  messages: List[Dict[str, Any]],
@@ -1043,6 +1225,9 @@ class HorusProvider(BaseLLMProvider):
1043
1225
  response_format: Optional[Dict] = None,
1044
1226
  **kwargs,
1045
1227
  ) -> Union[LLMResponse, Iterator[StreamingChunk]]:
1228
+ if self._is_text_to_image_model_id(self.model_id):
1229
+ raise RuntimeError("Horus Lens is a text-to-image model. Use generate_image(prompt) instead of chat().")
1230
+
1046
1231
  normalized = self._normalize_messages(messages)
1047
1232
 
1048
1233
  # Add tool descriptions to system prompt if tools are provided
@@ -1108,6 +1293,9 @@ class HorusProvider(BaseLLMProvider):
1108
1293
  return self.chat([{"role": "user", "content": prompt}], model=model, **kwargs)
1109
1294
 
1110
1295
  def stream_chat(self, messages: List[Dict[str, str]], **kwargs) -> Iterator[StreamingChunk]:
1296
+ if self._is_text_to_image_model_id(self.model_id):
1297
+ raise RuntimeError("Horus Lens is a text-to-image model. Use generate_image(prompt) instead of stream_chat().")
1298
+
1111
1299
  normalized = self._normalize_messages(messages)
1112
1300
  prompt = self._render_prompt(normalized)
1113
1301
 
@@ -1515,10 +1703,23 @@ class HorusModel(HorusProvider):
1515
1703
 
1516
1704
 
1517
1705
  Horus = HorusModel
1706
+ HorusLensModel = HorusModel
1518
1707
 
1519
1708
 
1520
1709
  def load_horus(model_id: str = "tokenaii/horus", **kwargs) -> HorusProvider:
1521
1710
  return HorusProvider(model_id=model_id, **kwargs).load()
1522
1711
 
1523
1712
 
1524
- __all__ = ["HorusProvider", "HorusModel", "Horus", "load_horus", "print_model_list"]
1713
+ def load_horus_lens(model_id: str = "tokenaii/Horus-Lens-1.0", **kwargs) -> HorusProvider:
1714
+ return HorusProvider(model_id=model_id, **kwargs).load()
1715
+
1716
+
1717
+ __all__ = [
1718
+ "HorusProvider",
1719
+ "HorusModel",
1720
+ "HorusLensModel",
1721
+ "Horus",
1722
+ "load_horus",
1723
+ "load_horus_lens",
1724
+ "print_model_list",
1725
+ ]
@@ -22,6 +22,14 @@ FEATURE_DEPENDENCIES: Dict[str, List[Tuple[str, str]]] = {
22
22
  ("llama_cpp", "llama-cpp-python>=0.2.0"),
23
23
  ("huggingface_hub", "huggingface_hub>=0.23.0"),
24
24
  ],
25
+ "horus_lens": [
26
+ ("torch", "torch>=2.0.0"),
27
+ ("diffusers", "diffusers>=0.30.0"),
28
+ ("transformers", "transformers>=4.35.0"),
29
+ ("accelerate", "accelerate>=0.24.0"),
30
+ ("PIL", "pillow>=10.0.0"),
31
+ ("huggingface_hub", "huggingface_hub>=0.23.0"),
32
+ ],
25
33
  "replica_tts": [
26
34
  ("edge_tts", "edge-tts>=6.1.0"),
27
35
  ],
@@ -77,4 +85,3 @@ def ensure_feature_dependencies(feature: str, auto_install: bool = True) -> bool
77
85
 
78
86
 
79
87
  __all__ = ["FEATURE_DEPENDENCIES", "ensure_feature_dependencies"]
80
-