npcpy 1.2.26__py3-none-any.whl → 1.2.28__py3-none-any.whl

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/serve.py CHANGED
@@ -502,56 +502,73 @@ def get_global_settings():
502
502
  except Exception as e:
503
503
  print(f"Error in get_global_settings: {str(e)}")
504
504
  return jsonify({"error": str(e)}), 500
505
-
505
+ def _get_jinx_files_recursively(directory):
506
+ """Helper to recursively find all .jinx file paths."""
507
+ jinx_paths = []
508
+ if os.path.exists(directory):
509
+ for root, _, files in os.walk(directory):
510
+ for filename in files:
511
+ if filename.endswith(".jinx"):
512
+ jinx_paths.append(os.path.join(root, filename))
513
+ return jinx_paths
506
514
 
507
515
  @app.route("/api/jinxs/available", methods=["GET"])
508
516
  def get_available_jinxs():
509
- """
510
- Get all available jinxs for a given NPC and/or team.
511
- Returns a list of jinx names that can be executed.
512
- """
513
517
  try:
514
518
  current_path = request.args.get('currentPath')
515
- npc_name = request.args.get('npc')
516
-
517
- jinx_names = set() # Use set to avoid duplicates
518
-
519
- # Get team jinxs from project directory
519
+ jinx_names = set()
520
+
520
521
  if current_path:
521
522
  team_jinxs_dir = os.path.join(current_path, 'npc_team', 'jinxs')
522
- if os.path.exists(team_jinxs_dir):
523
- for file in os.listdir(team_jinxs_dir):
524
- if file.endswith('.jinx'):
525
- jinx_names.add(file[:-5]) # Remove .jinx extension
526
-
527
- # Get global jinxs
523
+ jinx_paths = _get_jinx_files_recursively(team_jinxs_dir)
524
+ for path in jinx_paths:
525
+ jinx_names.add(os.path.basename(path)[:-5])
526
+
528
527
  global_jinxs_dir = os.path.expanduser('~/.npcsh/npc_team/jinxs')
529
- if os.path.exists(global_jinxs_dir):
530
- for file in os.listdir(global_jinxs_dir):
531
- if file.endswith('.jinx'):
532
- jinx_names.add(file[:-5])
533
-
534
- # Get NPC-specific jinxs if NPC is specified
535
- if npc_name:
536
- # Try to load the NPC and get its jinxs
537
- db_conn = get_db_connection()
538
- npc_object = load_npc_by_name_and_source(npc_name, 'project', db_conn, current_path)
539
- if not npc_object:
540
- npc_object = load_npc_by_name_and_source(npc_name, 'global', db_conn)
541
-
542
- if npc_object and hasattr(npc_object, 'jinxs_dict') and npc_object.jinxs_dict:
543
- jinx_names.update(npc_object.jinxs_dict.keys())
544
-
545
- return jsonify({
546
- 'jinxs': sorted(list(jinx_names)),
547
- 'error': None
548
- })
549
-
528
+ jinx_paths = _get_jinx_files_recursively(global_jinxs_dir)
529
+ for path in jinx_paths:
530
+ jinx_names.add(os.path.basename(path)[:-5])
531
+
532
+ return jsonify({'jinxs': sorted(list(jinx_names)), 'error': None})
550
533
  except Exception as e:
551
534
  print(f"Error getting available jinxs: {str(e)}")
552
535
  traceback.print_exc()
553
536
  return jsonify({'jinxs': [], 'error': str(e)}), 500
554
537
 
538
+ @app.route("/api/jinxs/global", methods=["GET"])
539
+ def get_global_jinxs():
540
+ jinxs_dir = os.path.join(os.path.expanduser("~"), ".npcsh", "npc_team", "jinxs")
541
+ jinx_paths = _get_jinx_files_recursively(jinxs_dir)
542
+ jinxs = []
543
+ for path in jinx_paths:
544
+ try:
545
+ with open(path, "r") as f:
546
+ jinx_data = yaml.safe_load(f)
547
+ jinxs.append(jinx_data)
548
+ except Exception as e:
549
+ print(f"Error loading global jinx {path}: {e}")
550
+ return jsonify({"jinxs": jinxs})
551
+
552
+ @app.route("/api/jinxs/project", methods=["GET"])
553
+ def get_project_jinxs():
554
+ current_path = request.args.get("currentPath")
555
+ if not current_path:
556
+ return jsonify({"jinxs": []})
557
+
558
+ if not current_path.endswith("npc_team"):
559
+ current_path = os.path.join(current_path, "npc_team")
560
+
561
+ jinxs_dir = os.path.join(current_path, "jinxs")
562
+ jinx_paths = _get_jinx_files_recursively(jinxs_dir)
563
+ jinxs = []
564
+ for path in jinx_paths:
565
+ try:
566
+ with open(path, "r") as f:
567
+ jinx_data = yaml.safe_load(f)
568
+ jinxs.append(jinx_data)
569
+ except Exception as e:
570
+ print(f"Error loading project jinx {path}: {e}")
571
+ return jsonify({"jinxs": jinxs})
555
572
 
556
573
  @app.route("/api/jinx/execute", methods=["POST"])
557
574
  def execute_jinx():
@@ -568,8 +585,11 @@ def execute_jinx():
568
585
  with cancellation_lock:
569
586
  cancellation_flags[stream_id] = False
570
587
 
588
+ print(data)
589
+
571
590
  jinx_name = data.get("jinxName")
572
591
  jinx_args = data.get("jinxArgs", [])
592
+ print(jinx_args)
573
593
  conversation_id = data.get("conversationId")
574
594
  model = data.get("model")
575
595
  provider = data.get("provider")
@@ -616,8 +636,45 @@ def execute_jinx():
616
636
 
617
637
  # Extract inputs from args
618
638
  from npcpy.npc_compiler import extract_jinx_inputs
619
- input_values = extract_jinx_inputs(jinx_args, jinx)
620
-
639
+
640
+ # --- Start of Fix ---
641
+ # Re-assemble arguments that were incorrectly split by spaces.
642
+ fixed_args = []
643
+ i = 0
644
+ while i < len(jinx_args):
645
+ arg = jinx_args[i]
646
+ if arg.startswith('-'):
647
+ fixed_args.append(arg)
648
+ value_parts = []
649
+ i += 1
650
+ # Collect all subsequent parts until the next flag or the end of the list.
651
+ while i < len(jinx_args) and not jinx_args[i].startswith('-'):
652
+ value_parts.append(jinx_args[i])
653
+ i += 1
654
+
655
+ if value_parts:
656
+ # Join the parts back into a single string.
657
+ full_value = " ".join(value_parts)
658
+ # Clean up the extraneous quotes that the initial bad split left behind.
659
+ if full_value.startswith("'") and full_value.endswith("'"):
660
+ full_value = full_value[1:-1]
661
+ elif full_value.startswith('"') and full_value.endswith('"'):
662
+ full_value = full_value[1:-1]
663
+ fixed_args.append(full_value)
664
+ # The 'i' counter is already advanced, so the loop continues from the next flag.
665
+ else:
666
+ # This handles positional arguments, just in case.
667
+ fixed_args.append(arg)
668
+ i += 1
669
+ # --- End of Fix ---
670
+
671
+ # Now, use the corrected arguments to extract inputs.
672
+ input_values = extract_jinx_inputs(fixed_args, jinx)
673
+
674
+
675
+
676
+
677
+ print('executing jinx with input_values ,', input_values)
621
678
  # Get conversation history
622
679
  command_history = CommandHistory(app.config.get('DB_PATH'))
623
680
  messages = fetch_messages_for_conversation(conversation_id)
@@ -966,49 +1023,6 @@ def get_npc_team_global():
966
1023
  return jsonify({"npcs": [], "error": str(e)})
967
1024
 
968
1025
 
969
- @app.route("/api/jinxs/global", methods=["GET"])
970
- def get_global_jinxs():
971
-
972
- user_home = os.path.expanduser("~")
973
- jinxs_dir = os.path.join(user_home, ".npcsh", "npc_team", "jinxs")
974
- jinxs = []
975
- if os.path.exists(jinxs_dir):
976
- for file in os.listdir(jinxs_dir):
977
- if file.endswith(".jinx"):
978
- with open(os.path.join(jinxs_dir, file), "r") as f:
979
- jinx_data = yaml.safe_load(f)
980
- jinxs.append(jinx_data)
981
- print("file", file)
982
-
983
- return jsonify({"jinxs": jinxs})
984
-
985
-
986
-
987
-
988
-
989
-
990
- @app.route("/api/jinxs/project", methods=["GET"])
991
- def get_project_jinxs():
992
- current_path = request.args.get(
993
- "currentPath"
994
- )
995
- if not current_path:
996
- return jsonify({"jinxs": []})
997
-
998
- if not current_path.endswith("npc_team"):
999
- current_path = os.path.join(current_path, "npc_team")
1000
-
1001
- jinxs_dir = os.path.join(current_path, "jinxs")
1002
- jinxs = []
1003
- if os.path.exists(jinxs_dir):
1004
- for file in os.listdir(jinxs_dir):
1005
- if file.endswith(".jinx"):
1006
- with open(os.path.join(jinxs_dir, file), "r") as f:
1007
- jinx_data = yaml.safe_load(f)
1008
- jinxs.append(jinx_data)
1009
- return jsonify({"jinxs": jinxs})
1010
-
1011
-
1012
1026
  @app.route("/api/jinxs/save", methods=["POST"])
1013
1027
  def save_jinx():
1014
1028
  try: