npcpy 1.2.36__py3-none-any.whl → 1.2.37__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: npcpy
3
- Version: 1.2.36
3
+ Version: 1.2.37
4
4
  Summary: npcpy is the premier open-source library for integrating LLMs and Agents into python systems.
5
5
  Home-page: https://github.com/NPC-Worldwide/npcpy
6
6
  Author: Christopher Agostino
@@ -607,6 +607,178 @@ else:
607
607
  The intention for this model ensembler system is to mimic human cognition: pattern-matched gut reactions (System 1 of Kahneman) for familiar queries, falling back to deliberate reasoning (System 2 of Kahneman) for novel problems. Genetic algorithms evolve both knowledge structures and model specializations over time.
608
608
 
609
609
 
610
+ ## NPCArray - NumPy for AI
611
+
612
+ `npcpy` provides `NPCArray`, a NumPy-like interface for working with populations of models (LLMs, sklearn, PyTorch) at scale. Think of it as vectorized operations over AI models.
613
+
614
+ ### Core Concepts
615
+ - Model arrays support vectorized operations
616
+ - Operations are lazy until `.collect()` is called (like Spark)
617
+ - Same interface works for single models (treated as length-1 arrays)
618
+ - Supports ensemble voting, consensus, evolution, and more
619
+
620
+ ### Basic Usage
621
+
622
+ ```python
623
+ from npcpy.npc_array import NPCArray
624
+
625
+ # Create array of LLMs
626
+ models = NPCArray.from_llms(
627
+ ['llama3.2', 'gemma3:1b'],
628
+ providers='ollama'
629
+ )
630
+
631
+ print(f"Model array shape: {models.shape}") # (2,)
632
+
633
+ # Inference across all models - returns shape (n_models, n_prompts)
634
+ result = models.infer("What is 2+2? Just the number.").collect()
635
+
636
+ print(f"Model 1: {result.data[0, 0]}")
637
+ print(f"Model 2: {result.data[1, 0]}")
638
+ ```
639
+
640
+ ### Lazy Chaining & Ensemble Operations
641
+
642
+ ```python
643
+ from npcpy.npc_array import NPCArray
644
+
645
+ models = NPCArray.from_llms(['llama3.2', 'gemma3:1b', 'mistral:7b'])
646
+
647
+ # Build lazy computation graph - nothing executed yet
648
+ result = (
649
+ models
650
+ .infer("Is Python compiled or interpreted? One word.")
651
+ .map(lambda r: r.strip().lower()) # Clean responses
652
+ .vote(axis=0) # Majority voting across models
653
+ )
654
+
655
+ # Show the computation plan
656
+ result.explain()
657
+
658
+ # Now execute
659
+ answer = result.collect()
660
+ print(f"Consensus: {answer.data[0]}")
661
+ ```
662
+
663
+ ### Parameter Sweeps with Meshgrid
664
+
665
+ ```python
666
+ from npcpy.npc_array import NPCArray
667
+
668
+ # Cartesian product over parameters
669
+ configs = NPCArray.meshgrid(
670
+ models=['llama3.2', 'gemma3:1b'],
671
+ temperatures=[0.0, 0.5, 1.0]
672
+ )
673
+
674
+ print(f"Config array shape: {configs.shape}") # (6,) = 2 models × 3 temps
675
+
676
+ # Run inference with each config
677
+ result = configs.infer("Complete: The quick brown fox").collect()
678
+ ```
679
+
680
+ ### Matrix Sampling with get_llm_response
681
+
682
+ The `get_llm_response` function supports `matrix` and `n_samples` parameters for exploration:
683
+
684
+ ```python
685
+ from npcpy.llm_funcs import get_llm_response
686
+
687
+ # Matrix parameter - cartesian product over specified params
688
+ result = get_llm_response(
689
+ "Write a creative opening line.",
690
+ matrix={
691
+ 'model': ['llama3.2', 'gemma3:1b'],
692
+ 'temperature': [0.5, 1.0]
693
+ }
694
+ )
695
+ print(f"Number of runs: {len(result['runs'])}") # 4 = 2×2
696
+
697
+ # n_samples - multiple samples from same config
698
+ result = get_llm_response(
699
+ "Pick a random number 1-100.",
700
+ model='llama3.2',
701
+ n_samples=5
702
+ )
703
+ print(f"Samples: {[r['response'] for r in result['runs']]}")
704
+
705
+ # Combine both for full exploration
706
+ result = get_llm_response(
707
+ "Flip a coin: heads or tails?",
708
+ matrix={'model': ['llama3.2', 'gemma3:1b']},
709
+ n_samples=3 # 2 models × 3 samples = 6 runs
710
+ )
711
+ ```
712
+
713
+ ### sklearn Integration
714
+
715
+ ```python
716
+ from npcpy.npc_array import NPCArray
717
+ from sklearn.ensemble import RandomForestClassifier
718
+ from sklearn.linear_model import LogisticRegression
719
+ import numpy as np
720
+
721
+ # Create sample data
722
+ X_train = np.random.randn(100, 4)
723
+ y_train = (X_train[:, 0] > 0).astype(int)
724
+
725
+ # Pre-fit models
726
+ rf = RandomForestClassifier(n_estimators=10).fit(X_train, y_train)
727
+ lr = LogisticRegression().fit(X_train, y_train)
728
+
729
+ # Create array from fitted models
730
+ models = NPCArray.from_sklearn([rf, lr])
731
+
732
+ # Vectorized prediction
733
+ X_test = np.random.randn(20, 4)
734
+ predictions = models.predict(X_test).collect()
735
+
736
+ print(f"RF predictions: {predictions.data[0]}")
737
+ print(f"LR predictions: {predictions.data[1]}")
738
+ ```
739
+
740
+ ### ML Functions with Grid Search
741
+
742
+ ```python
743
+ from npcpy.ml_funcs import fit_model, score_model, ensemble_predict
744
+
745
+ # Grid search via matrix parameter
746
+ result = fit_model(
747
+ X_train, y_train,
748
+ model='RandomForestClassifier',
749
+ matrix={
750
+ 'n_estimators': [10, 50, 100],
751
+ 'max_depth': [3, 5, 10]
752
+ }
753
+ )
754
+
755
+ print(f"Fitted {len(result['models'])} model configurations")
756
+
757
+ # Ensemble voting with multiple models
758
+ predictions = ensemble_predict(X_test, result['models'], method='vote')
759
+ ```
760
+
761
+ ### Quick Utilities
762
+
763
+ ```python
764
+ from npcpy.npc_array import infer_matrix, ensemble_vote
765
+
766
+ # Quick matrix inference
767
+ result = infer_matrix(
768
+ prompts=["Hello", "Goodbye"],
769
+ models=['llama3.2', 'gemma3:1b']
770
+ )
771
+
772
+ # Quick ensemble vote
773
+ answer = ensemble_vote(
774
+ "What is the capital of France? One word.",
775
+ models=['llama3.2', 'gemma3:1b']
776
+ )
777
+ print(f"Voted answer: {answer}")
778
+ ```
779
+
780
+ See `examples/npc_array_examples.py` for more comprehensive examples.
781
+
610
782
 
611
783
  ## Serving an NPC Team
612
784
 
@@ -1,10 +1,12 @@
1
- npcpy/__init__.py,sha256=9imxFtK74_6Rw9rz0kyMnZYl_voPb569tkTlYLt0Urg,131
2
- npcpy/llm_funcs.py,sha256=RtZAtX1_nvfn-X3IHVyQggDBXDzGxKEix_sS_iliNN0,87172
1
+ npcpy/__init__.py,sha256=uJcJGjR1mWvE69GySNAufkgiRwJA28zdObDBWaxp0tY,505
2
+ npcpy/llm_funcs.py,sha256=KJpjN6q5iW_qdUfgt4tzYENCAu86376io8eFZ7wp76Y,78081
3
3
  npcpy/main.py,sha256=RWoRIj6VQLxKdOKvdVyaq2kwG35oRpeXPvp1CAAoG-w,81
4
- npcpy/npc_compiler.py,sha256=mMYokNIlROl10NKsLJA_4wgO5rRr6tJQNRUwM13cnx8,101078
5
- npcpy/npc_sysenv.py,sha256=t9AswM-9_P2NaGsnlzTMc2hUfdSthi9ofbud6F1G7LM,35974
4
+ npcpy/ml_funcs.py,sha256=UI7k7JR4XOH_VXR-xxLaO4r9Kyx_jBaEnp3TUIY7ZLQ,22657
5
+ npcpy/npc_array.py,sha256=fVTxcMiXV-lvltmuwaRnTU9D3ikPq3-7k5wzp7MA5OY,40224
6
+ npcpy/npc_compiler.py,sha256=oGSn9-X-Miq-K37QfNo8_TFcWbOl8WTNHBPtkf6paws,104619
7
+ npcpy/npc_sysenv.py,sha256=rtE3KrXvIuOEpMq1CW5eK5K0o3f6mXagNXCeMnhHob4,36736
6
8
  npcpy/npcs.py,sha256=eExuVsbTfrRobTRRptRpDm46jCLWUgbvy4_U7IUQo-c,744
7
- npcpy/serve.py,sha256=3QU62spZ-yyWqWYb1iV_22Ir7shqMUSH_TKhvt8Ljkw,169725
9
+ npcpy/serve.py,sha256=wbIXUFlmfKg72ZYoX_cBJ8FVDFabHsGnbMwMIj-412Y,174839
8
10
  npcpy/tools.py,sha256=A5_oVmZkzGnI3BI-NmneuxeXQq-r29PbpAZP4nV4jrc,5303
9
11
  npcpy/data/__init__.py,sha256=1tcoChR-Hjn905JDLqaW9ElRmcISCTJdE7BGXPlym2Q,642
10
12
  npcpy/data/audio.py,sha256=3qryGXnWHa4JFMonjuX-lf0fCrF8jmbHe7mHAuOdua0,12397
@@ -25,9 +27,9 @@ npcpy/ft/usft.py,sha256=O025GGYGZQf2ZVLowyAmBwh5bJyuy2dUAM6v03YcboY,3435
25
27
  npcpy/gen/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
26
28
  npcpy/gen/audio_gen.py,sha256=w4toESu7nmli1T5FOwRRCGC_QK9W-SMWknYYkbRv9jE,635
27
29
  npcpy/gen/embeddings.py,sha256=QStTJ2ELiC379OEZsLEgGGIIFD267Y8zQchs7HRn2Zg,2089
28
- npcpy/gen/image_gen.py,sha256=PFaJAjMB0P1DV_x4tWXh25qGyjkntRejFLBnVPKSsqY,21730
30
+ npcpy/gen/image_gen.py,sha256=VflU_wJsKWJarOVwZtL2M8ymDFfKNz8WX66Rwk4obeo,21778
29
31
  npcpy/gen/ocr.py,sha256=rgmXWHrCYX1Po-qG_LrNFbVYEZ8aaupxFTgparcoB_Y,6554
30
- npcpy/gen/response.py,sha256=6iAOi4hxUxkTZ1d2suBUASOssT6pQnr3HFwZWrvmATg,31925
32
+ npcpy/gen/response.py,sha256=xSFHNZTDsebFo_nptWwSahpCU9_4pbCqabMFZ3X4_Bg,39979
31
33
  npcpy/gen/video_gen.py,sha256=RFi3Zcq_Hn3HIcfoF3mijQ6G7RYFZaM_9pjPTh-8E64,3239
32
34
  npcpy/memory/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
35
  npcpy/memory/command_history.py,sha256=vWzZ4F4o0XOSHn50SkdP885jG1aZIZvfcPAh8EZWlQk,54497
@@ -42,14 +44,14 @@ npcpy/sql/ai_function_tools.py,sha256=ZCpjVHtaMRdL2dXxbQy5NhhjtPrVViGT1wyEl8ADrk
42
44
  npcpy/sql/database_ai_adapters.py,sha256=CMlNGOhmJZhGB47RPvLIMqB61m_eYPVg1lwx42_b0jQ,6865
43
45
  npcpy/sql/database_ai_functions.py,sha256=XQCmaFOE1lNCnwrLTNpotYOlv6sx41bb8hxZI_sqpy8,6335
44
46
  npcpy/sql/model_runner.py,sha256=hJZ7hx2mwI-8DAh47Q6BwOsRjx30-HzebL4ajEUO4HA,5734
45
- npcpy/sql/npcsql.py,sha256=-PmV7AXSKwRog4gPHTeHzmvPrnDZOiccjgkUGv4DwEU,35614
47
+ npcpy/sql/npcsql.py,sha256=YRBbcsMPNWLhzZqoF0wAL2MaT6OOc0wh33Z0hb01rjc,36591
46
48
  npcpy/sql/sql_model_compiler.py,sha256=G-0dpTlgzc-dXy9YEsdWGjO8xaQ3jFNbc6oUja1Ef4M,5364
47
49
  npcpy/work/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
48
50
  npcpy/work/desktop.py,sha256=F3I8mUtJp6LAkXodsh8hGZIncoads6c_2Utty-0EdDA,2986
49
51
  npcpy/work/plan.py,sha256=QyUwg8vElWiHuoS-xK4jXTxxHvkMD3VkaCEsCmrEPQk,8300
50
52
  npcpy/work/trigger.py,sha256=P1Y8u1wQRsS2WACims_2IdkBEar-iBQix-2TDWoW0OM,9948
51
- npcpy-1.2.36.dist-info/licenses/LICENSE,sha256=j0YPvce7Ng9e32zYOu0EmXjXeJ0Nwawd0RA3uSGGH4E,1070
52
- npcpy-1.2.36.dist-info/METADATA,sha256=TclDTn6w0nbPuQXtbOTFwxfpHVgjYYc49EVDHTiMW64,33537
53
- npcpy-1.2.36.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
54
- npcpy-1.2.36.dist-info/top_level.txt,sha256=g1pbSvrOOncB74Bg5-J0Olg4V0A5VzDw-Xz5YObq8BU,6
55
- npcpy-1.2.36.dist-info/RECORD,,
53
+ npcpy-1.2.37.dist-info/licenses/LICENSE,sha256=j0YPvce7Ng9e32zYOu0EmXjXeJ0Nwawd0RA3uSGGH4E,1070
54
+ npcpy-1.2.37.dist-info/METADATA,sha256=xviLiFxgZ1uK876GGrIIm-P3uEJlwBvCtbbgn0vFUP4,37940
55
+ npcpy-1.2.37.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
56
+ npcpy-1.2.37.dist-info/top_level.txt,sha256=g1pbSvrOOncB74Bg5-J0Olg4V0A5VzDw-Xz5YObq8BU,6
57
+ npcpy-1.2.37.dist-info/RECORD,,
File without changes