npcpy 1.3.3__tar.gz → 1.3.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.
- {npcpy-1.3.3/npcpy.egg-info → npcpy-1.3.4}/PKG-INFO +1 -1
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/llm_funcs.py +19 -38
- {npcpy-1.3.3 → npcpy-1.3.4/npcpy.egg-info}/PKG-INFO +1 -1
- {npcpy-1.3.3 → npcpy-1.3.4}/setup.py +1 -1
- {npcpy-1.3.3 → npcpy-1.3.4}/LICENSE +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/MANIFEST.in +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/README.md +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/__init__.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/data/__init__.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/data/audio.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/data/data_models.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/data/image.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/data/load.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/data/text.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/data/video.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/data/web.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/ft/__init__.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/ft/diff.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/ft/ge.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/ft/memory_trainer.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/ft/model_ensembler.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/ft/rl.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/ft/sft.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/ft/usft.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/gen/__init__.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/gen/audio_gen.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/gen/embeddings.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/gen/image_gen.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/gen/ocr.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/gen/response.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/gen/video_gen.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/main.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/memory/__init__.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/memory/command_history.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/memory/kg_vis.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/memory/knowledge_graph.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/memory/memory_processor.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/memory/search.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/mix/__init__.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/mix/debate.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/ml_funcs.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/npc_array.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/npc_compiler.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/npc_sysenv.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/npcs.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/serve.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/sql/__init__.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/sql/ai_function_tools.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/sql/database_ai_adapters.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/sql/database_ai_functions.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/sql/model_runner.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/sql/npcsql.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/sql/sql_model_compiler.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/tools.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/work/__init__.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/work/desktop.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/work/plan.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy/work/trigger.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy.egg-info/SOURCES.txt +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy.egg-info/dependency_links.txt +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy.egg-info/requires.txt +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/npcpy.egg-info/top_level.txt +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/setup.cfg +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/tests/test_audio.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/tests/test_command_history.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/tests/test_image.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/tests/test_llm_funcs.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/tests/test_load.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/tests/test_npc_array.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/tests/test_npc_compiler.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/tests/test_npcsql.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/tests/test_response.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/tests/test_serve.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/tests/test_text.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/tests/test_tools.py +0 -0
- {npcpy-1.3.3 → npcpy-1.3.4}/tests/test_web.py +0 -0
|
@@ -14,6 +14,8 @@ from npcpy.npc_sysenv import (
|
|
|
14
14
|
request_user_input,
|
|
15
15
|
get_system_message
|
|
16
16
|
)
|
|
17
|
+
|
|
18
|
+
|
|
17
19
|
from npcpy.gen.response import get_litellm_response
|
|
18
20
|
from npcpy.gen.image_gen import generate_image
|
|
19
21
|
from npcpy.gen.video_gen import generate_video_diffusers, generate_video_veo3
|
|
@@ -564,6 +566,7 @@ def check_llm_command(
|
|
|
564
566
|
extra_globals=None,
|
|
565
567
|
max_iterations: int = 5,
|
|
566
568
|
jinxs: Dict = None,
|
|
569
|
+
tool_capable: bool = None, # If None, will be auto-detected
|
|
567
570
|
):
|
|
568
571
|
"""
|
|
569
572
|
Simple agent loop: try tool calling first, fall back to ReAct if unsupported.
|
|
@@ -571,27 +574,21 @@ def check_llm_command(
|
|
|
571
574
|
if messages is None:
|
|
572
575
|
messages = []
|
|
573
576
|
|
|
574
|
-
# Log incoming messages
|
|
575
|
-
import logging
|
|
576
|
-
logger = logging.getLogger("npcpy.llm_funcs")
|
|
577
|
-
logger.debug(f"[check_llm_command] Received {len(messages)} messages")
|
|
578
|
-
for i, msg in enumerate(messages[-5:]): # Log last 5 messages
|
|
579
|
-
role = msg.get('role', 'unknown')
|
|
580
|
-
content = msg.get('content', '')
|
|
581
|
-
content_preview = content[:100] if isinstance(content, str) else str(type(content))
|
|
582
|
-
logger.debug(f" [{i}] role={role}, content_preview={content_preview}...")
|
|
583
|
-
|
|
584
577
|
total_usage = {"input_tokens": 0, "output_tokens": 0}
|
|
578
|
+
|
|
585
579
|
# Use provided jinxs or get from npc/team
|
|
586
580
|
if jinxs is None:
|
|
587
581
|
jinxs = _get_jinxs(npc, team)
|
|
588
|
-
|
|
582
|
+
|
|
583
|
+
# Only prepare tools if model supports them
|
|
584
|
+
tools = None
|
|
585
|
+
if tool_capable is not False and jinxs:
|
|
586
|
+
tools = _jinxs_to_tools(jinxs)
|
|
589
587
|
|
|
590
588
|
# Keep full message history, only truncate for API calls to reduce tokens
|
|
591
589
|
full_messages = messages.copy() if messages else []
|
|
592
|
-
logger.debug(f"[check_llm_command] full_messages initialized with {len(full_messages)} messages")
|
|
593
590
|
|
|
594
|
-
#
|
|
591
|
+
# Make LLM call (with or without tools based on tool_capable)
|
|
595
592
|
|
|
596
593
|
try:
|
|
597
594
|
response = get_llm_response(
|
|
@@ -609,7 +606,7 @@ def check_llm_command(
|
|
|
609
606
|
tools=tools,
|
|
610
607
|
)
|
|
611
608
|
except Exception as e:
|
|
612
|
-
print(
|
|
609
|
+
print(f"[check_llm_command] EXCEPTION in get_llm_response: {type(e).__name__}: {e}", "red")
|
|
613
610
|
return {
|
|
614
611
|
"messages": full_messages,
|
|
615
612
|
"output": f"LLM call failed: {e}",
|
|
@@ -617,8 +614,6 @@ def check_llm_command(
|
|
|
617
614
|
"usage": total_usage,
|
|
618
615
|
}
|
|
619
616
|
|
|
620
|
-
if response.get("error"):
|
|
621
|
-
logger.warning(f"[check_llm_command] Error in response: {response.get('error')}")
|
|
622
617
|
|
|
623
618
|
if response.get("usage"):
|
|
624
619
|
total_usage["input_tokens"] += response["usage"].get("input_tokens", 0)
|
|
@@ -634,7 +629,6 @@ def check_llm_command(
|
|
|
634
629
|
# For streaming, the caller (process_result) handles appending after consumption
|
|
635
630
|
if assistant_response and isinstance(assistant_response, str):
|
|
636
631
|
full_messages.append({"role": "assistant", "content": assistant_response})
|
|
637
|
-
logger.debug(f"[check_llm_command] No tool calls - returning {len(full_messages)} messages")
|
|
638
632
|
return {
|
|
639
633
|
"messages": full_messages,
|
|
640
634
|
"output": assistant_response,
|
|
@@ -670,8 +664,7 @@ def check_llm_command(
|
|
|
670
664
|
assistant_msg["tool_calls"] = _serialize_tool_calls(tool_calls)
|
|
671
665
|
full_messages.append(assistant_msg)
|
|
672
666
|
current_messages = full_messages
|
|
673
|
-
|
|
674
|
-
for iteration in range(max_iterations):
|
|
667
|
+
for _ in range(max_iterations):
|
|
675
668
|
for tc in tool_calls:
|
|
676
669
|
# Handle both dict and object formats
|
|
677
670
|
if hasattr(tc, 'function'):
|
|
@@ -692,15 +685,12 @@ def check_llm_command(
|
|
|
692
685
|
|
|
693
686
|
if jinx_name in jinxs:
|
|
694
687
|
try:
|
|
695
|
-
|
|
696
|
-
print(
|
|
688
|
+
|
|
689
|
+
print((f" ⚡ {jinx_name}", "cyan"), end="", flush=True)
|
|
697
690
|
except:
|
|
698
691
|
pass
|
|
699
692
|
output = _execute_jinx(jinxs[jinx_name], inputs, npc, team, current_messages, extra_globals)
|
|
700
|
-
|
|
701
|
-
print(colored(" ✓", "green"), flush=True)
|
|
702
|
-
except:
|
|
703
|
-
pass
|
|
693
|
+
|
|
704
694
|
|
|
705
695
|
# Add tool result to messages
|
|
706
696
|
# Include name for Gemini compatibility
|
|
@@ -745,8 +735,6 @@ def check_llm_command(
|
|
|
745
735
|
)
|
|
746
736
|
except Exception as e:
|
|
747
737
|
# If continuation fails, return what we have so far
|
|
748
|
-
# The tool was already executed successfully
|
|
749
|
-
logger.warning(f"[check_llm_command] Continuation failed: {e}")
|
|
750
738
|
return {
|
|
751
739
|
"messages": current_messages,
|
|
752
740
|
"output": f"Tool executed successfully. (Continuation error: {type(e).__name__})",
|
|
@@ -767,14 +755,12 @@ def check_llm_command(
|
|
|
767
755
|
|
|
768
756
|
if not tool_calls:
|
|
769
757
|
# Done - return full message history
|
|
770
|
-
logger.debug(f"[check_llm_command] Tool loop done - returning {len(current_messages)} messages")
|
|
771
758
|
return {
|
|
772
759
|
"messages": current_messages,
|
|
773
760
|
"output": assistant_response,
|
|
774
761
|
"usage": total_usage,
|
|
775
762
|
}
|
|
776
763
|
|
|
777
|
-
logger.debug(f"[check_llm_command] Max iterations - returning {len(current_messages)} messages")
|
|
778
764
|
return {
|
|
779
765
|
"messages": current_messages,
|
|
780
766
|
"output": response.get("response", "Max iterations reached"),
|
|
@@ -867,16 +853,11 @@ Use EXACT parameter names from the tool definitions above."""
|
|
|
867
853
|
context = f"Error: '{jinx_name}' not found. Available: {list(jinxs.keys())}"
|
|
868
854
|
continue
|
|
869
855
|
|
|
870
|
-
|
|
871
|
-
|
|
872
|
-
print(colored(f" ⚡ {jinx_name}", "cyan"), end="", flush=True)
|
|
873
|
-
except:
|
|
874
|
-
pass
|
|
856
|
+
|
|
857
|
+
|
|
875
858
|
output = _execute_jinx(jinxs[jinx_name], inputs, npc, team, current_messages, extra_globals)
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
except:
|
|
879
|
-
pass
|
|
859
|
+
|
|
860
|
+
|
|
880
861
|
context = f"Tool '{jinx_name}' returned: {output}"
|
|
881
862
|
command = f"{command}\n\nPrevious: {context}"
|
|
882
863
|
|
|
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
|