neuralnode 2.0.3__tar.gz → 2.0.5__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.
- {neuralnode-2.0.3 → neuralnode-2.0.5}/PKG-INFO +1 -1
- neuralnode-2.0.5/horus_chat_voice.py +61 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/pyproject.toml +1 -1
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/__init__.py +1 -1
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/providers/horus.py +73 -17
- {neuralnode-2.0.3 → neuralnode-2.0.5}/.env.example +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/.github/workflows/tests.yml +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/Dockerfile +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/LICENSE +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/README.md +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/docker-compose.yml +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/docs/documentation.md +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/docs/ecosystem_plan.md +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/docs/replica_voice_ids.csv +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/docs/replica_voice_ids.md +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/docs/telegram_guide.md +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/examples/agent_with_tools.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/examples/basic_chat.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/examples/horus_codes_camples/01_basic_usage.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/examples/horus_codes_camples/02_with_token.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/examples/horus_codes_camples/03_one_liner.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/examples/horus_codes_camples/04_custom_cache.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/examples/horus_codes_camples/05_4bit_quantization.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/examples/horus_codes_camples/06_8bit_quantization.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/examples/horus_codes_camples/07_multi_gpu.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/examples/horus_codes_camples/08_flash_attention.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/examples/horus_codes_camples/09_data_types.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/examples/horus_codes_camples/10_generation_params.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/examples/horus_codes_camples/11_streaming.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/examples/horus_codes_camples/12_chat_templates.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/examples/horus_codes_camples/13_offline_mode.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/examples/horus_codes_camples/14_force_download.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/examples/horus_codes_camples/15_model_info.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/examples/horus_codes_camples/16_cpu_offloading.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/examples/horus_codes_camples/17_cpu_only.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/examples/horus_codes_camples/18_production_setup.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/examples/horus_codes_camples/19_gguf_4bit.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/examples/horus_codes_camples/20_gguf_5bit.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/examples/horus_codes_camples/21_gguf_6bit.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/examples/horus_codes_camples/22_gguf_8bit.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/examples/horus_codes_camples/23_gguf_16bit.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/examples/horus_codes_camples/24_list_models.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/examples/horus_codes_camples/25_interactive_chat.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/examples/horus_codes_camples/README.md +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/examples/horus_download_guide.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/examples/horus_examples.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/examples/horus_tq_ready_gguf.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/examples/horus_transformers_features.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/examples/local_models.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/examples/neuralnode_v21_complete_demo.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/examples/shade_model_with_tools.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/examples/telegram_bot_demo.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/examples/thinking_mode_example.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/examples/tts_demo.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/examples/turboquant_example.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/examples/v3_features.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/neuralnode_horus_replica_telegram.ipynb +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/nn.md +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/publish.bat +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/publish.sh +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/replica_output_85218.mp3 +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/requirements_shade.txt +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/scripts/setup.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/debug_import.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/agents/__init__.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/chains/__init__.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/config/__init__.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/core/__init__.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/core/openai_blocker.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/diagnostics/__init__.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/integrations/discord.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/integrations/slack.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/integrations/telegram.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/integrations/whatsapp.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/memory/__init__.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/memory/advanced.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/prompts/__init__.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/providers/__init__.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/providers/base.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/providers/chat/__init__.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/providers/chat/ai21.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/providers/chat/anthropic.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/providers/chat/cohere.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/providers/chat/deepseek.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/providers/chat/fireworks.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/providers/chat/google.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/providers/chat/groq.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/providers/chat/mistral.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/providers/chat/perplexity.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/providers/chat/together.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/providers/chat_models.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/providers/embeddings.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/providers/local/__init__.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/providers/local_providers.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/providers/text_generation.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/providers/universal_local.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/rag/__init__.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/rag/loaders.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/reasoning/__init__.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/replica.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/speech/__init__.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/thinking.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/tools/__init__.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/tools/advanced.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/tools/multisearch.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/tools/system/__init__.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/tools/system/operations.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/tools/web/__init__.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/tts/__init__.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/turboquant.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/utils/__init__.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/utils/dependencies.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/utils/logger.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/utils/metrics.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/vectorstores/__init__.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/neuralnode/vision/__init__.py +0 -0
- {neuralnode-2.0.3 → neuralnode-2.0.5}/src/nn/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: neuralnode
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.5
|
|
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
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Horus Chat with Replica TTS (Female EN-US Voice)
|
|
3
|
+
Run: pip install edge-tts>=6.1.0
|
|
4
|
+
"""
|
|
5
|
+
import neuralnode as nn
|
|
6
|
+
import os
|
|
7
|
+
import platform
|
|
8
|
+
|
|
9
|
+
# Initialize Replica TTS with female EN-US voice
|
|
10
|
+
tts = nn.ReplicaTTS(voice_id="replic-aria-language{en-us}")
|
|
11
|
+
|
|
12
|
+
def play_audio(file_path):
|
|
13
|
+
"""Play audio file based on OS"""
|
|
14
|
+
system = platform.system()
|
|
15
|
+
try:
|
|
16
|
+
if system == "Windows":
|
|
17
|
+
import winsound
|
|
18
|
+
winsound.PlaySound(file_path, winsound.SND_FILENAME | winsound.SND_ASYNC)
|
|
19
|
+
elif system == "Darwin": # macOS
|
|
20
|
+
os.system(f"afplay '{file_path}' &")
|
|
21
|
+
else: # Linux
|
|
22
|
+
os.system(f"mpg321 '{file_path}' & 2>/dev/null || aplay '{file_path}' & 2>/dev/null || cvlc '{file_path}' --play-and-exit & 2>/dev/null")
|
|
23
|
+
except Exception as e:
|
|
24
|
+
print(f"⚠️ Could not play audio: {e}")
|
|
25
|
+
print(f"📁 Audio saved to: {file_path}")
|
|
26
|
+
|
|
27
|
+
# Load Horus model
|
|
28
|
+
model = nn.HorusModel(
|
|
29
|
+
model_id="tokenaii/Hours-1.0-4B-GGUF/Horus-1.0-4B-Q4_K_M.gguf"
|
|
30
|
+
).load()
|
|
31
|
+
|
|
32
|
+
messages = [
|
|
33
|
+
{"role": "system", "content": "You're a medical AI assistant."}
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
print("Horus chat started. Type 'exit' to quit.\n")
|
|
37
|
+
|
|
38
|
+
while True:
|
|
39
|
+
user_text = input("You: ").strip()
|
|
40
|
+
if not user_text:
|
|
41
|
+
continue
|
|
42
|
+
if user_text.lower() in {"exit", "quit", "q"}:
|
|
43
|
+
print("Bye.")
|
|
44
|
+
break
|
|
45
|
+
|
|
46
|
+
messages.append({"role": "user", "content": user_text})
|
|
47
|
+
resp = model.chat(messages)
|
|
48
|
+
assistant_text = resp.content.strip()
|
|
49
|
+
|
|
50
|
+
print(f"Horus: {assistant_text}\n")
|
|
51
|
+
|
|
52
|
+
# Generate and play audio
|
|
53
|
+
print("🔊 Generating audio...")
|
|
54
|
+
audio_file = tts.speak(assistant_text, blocking=True)
|
|
55
|
+
print(f"🎵 Playing: {audio_file}")
|
|
56
|
+
play_audio(audio_file)
|
|
57
|
+
|
|
58
|
+
messages.append({"role": "assistant", "content": assistant_text})
|
|
59
|
+
|
|
60
|
+
# optional cleanup
|
|
61
|
+
model.unload()
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "neuralnode"
|
|
7
|
-
version = "2.0.
|
|
7
|
+
version = "2.0.5"
|
|
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"
|
|
@@ -112,6 +112,7 @@ UNIFIED_SYSTEM_PROMPT = (
|
|
|
112
112
|
"6) For instructions that require steps, provide clear actionable steps without filler.\n"
|
|
113
113
|
"7) If the user asks for code, produce correct runnable code and mention assumptions briefly.\n"
|
|
114
114
|
"8) If the user request is unsafe or harmful, refuse briefly and offer a safe alternative.\n"
|
|
115
|
+
"9) Do not repeatedly introduce yourself. Only provide your identity if the user explicitly asks who you are.\n"
|
|
115
116
|
"\n"
|
|
116
117
|
"Quality checks before responding:\n"
|
|
117
118
|
"- Is the answer grounded in provided context or clearly stated assumptions?\n"
|
|
@@ -237,10 +238,10 @@ class HorusProvider(BaseLLMProvider):
|
|
|
237
238
|
force_download: bool = False,
|
|
238
239
|
resume_download: bool = False,
|
|
239
240
|
max_new_tokens: int = 512,
|
|
240
|
-
temperature: float = 0.
|
|
241
|
-
top_p: float = 0.
|
|
241
|
+
temperature: float = 0.3,
|
|
242
|
+
top_p: float = 0.85,
|
|
242
243
|
top_k: int = 50,
|
|
243
|
-
repetition_penalty: float = 1.
|
|
244
|
+
repetition_penalty: float = 1.2,
|
|
244
245
|
do_sample: bool = True,
|
|
245
246
|
num_beams: int = 1,
|
|
246
247
|
early_stopping: bool = False,
|
|
@@ -433,13 +434,18 @@ class HorusProvider(BaseLLMProvider):
|
|
|
433
434
|
repo_id, filename = self._split_repo_and_filename(self.model_id)
|
|
434
435
|
model_path = filename
|
|
435
436
|
if repo_id and HF_HUB_AVAILABLE:
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
437
|
+
with warnings.catch_warnings():
|
|
438
|
+
warnings.filterwarnings(
|
|
439
|
+
"ignore",
|
|
440
|
+
message=r".*You are sending unauthenticated requests to the HF Hub.*",
|
|
441
|
+
)
|
|
442
|
+
model_path = hf_hub_download(
|
|
443
|
+
repo_id=repo_id,
|
|
444
|
+
filename=filename,
|
|
445
|
+
cache_dir=self.cache_dir,
|
|
446
|
+
local_files_only=self.local_files_only,
|
|
447
|
+
token=self.token,
|
|
448
|
+
)
|
|
443
449
|
|
|
444
450
|
llama_kwargs: Dict[str, Any] = {
|
|
445
451
|
"model_path": model_path,
|
|
@@ -788,20 +794,61 @@ class HorusProvider(BaseLLMProvider):
|
|
|
788
794
|
output = self.model(
|
|
789
795
|
prompt,
|
|
790
796
|
max_tokens=int(settings.get("max_new_tokens", 512)),
|
|
791
|
-
temperature=settings.get("temperature", 0.
|
|
792
|
-
top_p=settings.get("top_p", 0.
|
|
797
|
+
temperature=settings.get("temperature", 0.3),
|
|
798
|
+
top_p=settings.get("top_p", 0.85),
|
|
793
799
|
top_k=settings.get("top_k", 50),
|
|
794
|
-
repeat_penalty=settings.get("repetition_penalty", 1.
|
|
795
|
-
stop=["
|
|
800
|
+
repeat_penalty=settings.get("repetition_penalty", 1.2),
|
|
801
|
+
stop=["<|end|>", "<|user|>", "\n<|user|>", "<|assistant|>", "\n<|assistant|>"],
|
|
796
802
|
echo=False,
|
|
797
803
|
)
|
|
798
|
-
return output["choices"][0]["text"]
|
|
804
|
+
return self._clean_generated_text(output["choices"][0]["text"])
|
|
805
|
+
|
|
806
|
+
def _clean_generated_text(self, text: str) -> str:
|
|
807
|
+
"""Clean generation artifacts from Horus outputs."""
|
|
808
|
+
cleaned = text or ""
|
|
809
|
+
cleaned = cleaned.replace("<|assistant|>", "").replace("<|user|>", "").replace("<|end|>", "")
|
|
810
|
+
cleaned = re.sub(r"(?im)^\s*assistant\s*[::]?\s*", "", cleaned)
|
|
811
|
+
cleaned = re.sub(r"\n{3,}", "\n\n", cleaned)
|
|
812
|
+
cleaned = cleaned.strip()
|
|
813
|
+
# Cut obvious accidental next-turn continuation if present.
|
|
814
|
+
for marker in ("\nUser:", "\nSystem:", "\nTool:"):
|
|
815
|
+
idx = cleaned.find(marker)
|
|
816
|
+
if idx > 0:
|
|
817
|
+
cleaned = cleaned[:idx].strip()
|
|
818
|
+
return cleaned
|
|
819
|
+
|
|
820
|
+
@staticmethod
|
|
821
|
+
def _is_identity_question(user_text: str) -> bool:
|
|
822
|
+
q = (user_text or "").strip().lower()
|
|
823
|
+
identity_markers = (
|
|
824
|
+
"who are you",
|
|
825
|
+
"what are you",
|
|
826
|
+
"your name",
|
|
827
|
+
"من انت",
|
|
828
|
+
"مين انت",
|
|
829
|
+
"ما اسمك",
|
|
830
|
+
"اسمك ايه",
|
|
831
|
+
"عرف نفسك",
|
|
832
|
+
)
|
|
833
|
+
return any(marker in q for marker in identity_markers)
|
|
834
|
+
|
|
835
|
+
@staticmethod
|
|
836
|
+
def _strip_redundant_identity_prefix(text: str) -> str:
|
|
837
|
+
patterns = [
|
|
838
|
+
r"^\s*i(?:\s*am|'m)\s+horus,\s*an ai model developed by tokenai\.?\s*",
|
|
839
|
+
r"^\s*i(?:\s*am|'m)\s+horus\.?\s*",
|
|
840
|
+
r"^\s*أنا\s+horus[^.!\n]*[.!\n]\s*",
|
|
841
|
+
]
|
|
842
|
+
cleaned = text
|
|
843
|
+
for pattern in patterns:
|
|
844
|
+
cleaned = re.sub(pattern, "", cleaned, flags=re.IGNORECASE)
|
|
845
|
+
return cleaned.strip() or text
|
|
799
846
|
|
|
800
847
|
def chat(
|
|
801
848
|
self,
|
|
802
849
|
messages: List[Dict[str, Any]],
|
|
803
850
|
model: Optional[str] = None,
|
|
804
|
-
temperature: float =
|
|
851
|
+
temperature: Optional[float] = None,
|
|
805
852
|
max_tokens: Optional[int] = None,
|
|
806
853
|
top_p: Optional[float] = None,
|
|
807
854
|
frequency_penalty: Optional[float] = None,
|
|
@@ -833,7 +880,7 @@ class HorusProvider(BaseLLMProvider):
|
|
|
833
880
|
|
|
834
881
|
prompt = self._render_prompt(normalized)
|
|
835
882
|
generation_kwargs = {
|
|
836
|
-
"temperature": temperature,
|
|
883
|
+
"temperature": temperature if temperature is not None else self.generation_config["temperature"],
|
|
837
884
|
"max_new_tokens": max_tokens or self.generation_config["max_new_tokens"],
|
|
838
885
|
"top_p": top_p if top_p is not None else self.generation_config["top_p"],
|
|
839
886
|
**kwargs,
|
|
@@ -847,6 +894,15 @@ class HorusProvider(BaseLLMProvider):
|
|
|
847
894
|
else:
|
|
848
895
|
content = self._generate_transformers_text(prompt, **generation_kwargs)
|
|
849
896
|
|
|
897
|
+
# Reduce repetitive self-introduction unless identity was explicitly requested.
|
|
898
|
+
last_user_message = ""
|
|
899
|
+
for m in reversed(normalized):
|
|
900
|
+
if m.get("role") == "user":
|
|
901
|
+
last_user_message = m.get("content", "")
|
|
902
|
+
break
|
|
903
|
+
if not self._is_identity_question(last_user_message):
|
|
904
|
+
content = self._strip_redundant_identity_prefix(content)
|
|
905
|
+
|
|
850
906
|
# Parse tool calls from response if tools were provided
|
|
851
907
|
tool_calls = []
|
|
852
908
|
if tools:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|