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.
- npcpy/__init__.py +10 -2
- npcpy/gen/image_gen.py +5 -2
- npcpy/gen/response.py +262 -64
- npcpy/llm_funcs.py +478 -832
- npcpy/ml_funcs.py +746 -0
- npcpy/npc_array.py +1294 -0
- npcpy/npc_compiler.py +320 -257
- npcpy/npc_sysenv.py +17 -2
- npcpy/serve.py +162 -14
- npcpy/sql/npcsql.py +96 -59
- {npcpy-1.2.36.dist-info → npcpy-1.2.37.dist-info}/METADATA +173 -1
- {npcpy-1.2.36.dist-info → npcpy-1.2.37.dist-info}/RECORD +15 -13
- {npcpy-1.2.36.dist-info → npcpy-1.2.37.dist-info}/WHEEL +0 -0
- {npcpy-1.2.36.dist-info → npcpy-1.2.37.dist-info}/licenses/LICENSE +0 -0
- {npcpy-1.2.36.dist-info → npcpy-1.2.37.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: npcpy
|
|
3
|
-
Version: 1.2.
|
|
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=
|
|
2
|
-
npcpy/llm_funcs.py,sha256=
|
|
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/
|
|
5
|
-
npcpy/
|
|
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=
|
|
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=
|
|
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=
|
|
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
|
|
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.
|
|
52
|
-
npcpy-1.2.
|
|
53
|
-
npcpy-1.2.
|
|
54
|
-
npcpy-1.2.
|
|
55
|
-
npcpy-1.2.
|
|
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
|
|
File without changes
|
|
File without changes
|