npcpy 1.2.36__tar.gz → 1.3.1__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.2.36/npcpy.egg-info → npcpy-1.3.1}/PKG-INFO +175 -4
- {npcpy-1.2.36 → npcpy-1.3.1}/README.md +174 -3
- npcpy-1.3.1/npcpy/__init__.py +14 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/gen/image_gen.py +5 -2
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/gen/response.py +262 -64
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/llm_funcs.py +478 -832
- npcpy-1.3.1/npcpy/ml_funcs.py +746 -0
- npcpy-1.3.1/npcpy/npc_array.py +1294 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/npc_compiler.py +522 -341
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/npc_sysenv.py +17 -2
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/serve.py +162 -14
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/sql/npcsql.py +96 -59
- {npcpy-1.2.36 → npcpy-1.3.1/npcpy.egg-info}/PKG-INFO +175 -4
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy.egg-info/SOURCES.txt +3 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/setup.py +1 -1
- npcpy-1.3.1/tests/test_npc_array.py +539 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/tests/test_npc_compiler.py +28 -19
- npcpy-1.2.36/npcpy/__init__.py +0 -6
- {npcpy-1.2.36 → npcpy-1.3.1}/LICENSE +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/MANIFEST.in +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/data/__init__.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/data/audio.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/data/data_models.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/data/image.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/data/load.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/data/text.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/data/video.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/data/web.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/ft/__init__.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/ft/diff.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/ft/ge.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/ft/memory_trainer.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/ft/model_ensembler.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/ft/rl.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/ft/sft.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/ft/usft.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/gen/__init__.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/gen/audio_gen.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/gen/embeddings.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/gen/ocr.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/gen/video_gen.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/main.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/memory/__init__.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/memory/command_history.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/memory/kg_vis.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/memory/knowledge_graph.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/memory/memory_processor.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/memory/search.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/mix/__init__.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/mix/debate.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/npcs.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/sql/__init__.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/sql/ai_function_tools.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/sql/database_ai_adapters.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/sql/database_ai_functions.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/sql/model_runner.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/sql/sql_model_compiler.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/tools.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/work/__init__.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/work/desktop.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/work/plan.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy/work/trigger.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy.egg-info/dependency_links.txt +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy.egg-info/requires.txt +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/npcpy.egg-info/top_level.txt +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/setup.cfg +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/tests/test_audio.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/tests/test_command_history.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/tests/test_image.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/tests/test_llm_funcs.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/tests/test_load.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/tests/test_npcsql.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/tests/test_response.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/tests/test_serve.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/tests/test_text.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/tests/test_tools.py +0 -0
- {npcpy-1.2.36 → npcpy-1.3.1}/tests/test_web.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: npcpy
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.3.1
|
|
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
|
|
@@ -275,9 +275,8 @@ output = context['research_summary']
|
|
|
275
275
|
"code": '''
|
|
276
276
|
# Access outputs from previous steps.
|
|
277
277
|
research_summary = context['initial_llm_research']
|
|
278
|
-
# The
|
|
279
|
-
|
|
280
|
-
file_summary = context['read_and_process_source_file'].get('output', 'No file summary available.')
|
|
278
|
+
# The file_reader jinx returns its output directly; also keep a fallback of file_raw_content.
|
|
279
|
+
file_summary = context.get('read_and_process_source_file', '') or context.get('file_raw_content', 'No file summary available.')
|
|
281
280
|
|
|
282
281
|
prompt = f"""Based on the following information:
|
|
283
282
|
1. Comprehensive Research Summary:
|
|
@@ -607,6 +606,178 @@ else:
|
|
|
607
606
|
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
607
|
|
|
609
608
|
|
|
609
|
+
## NPCArray - NumPy for AI
|
|
610
|
+
|
|
611
|
+
`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.
|
|
612
|
+
|
|
613
|
+
### Core Concepts
|
|
614
|
+
- Model arrays support vectorized operations
|
|
615
|
+
- Operations are lazy until `.collect()` is called (like Spark)
|
|
616
|
+
- Same interface works for single models (treated as length-1 arrays)
|
|
617
|
+
- Supports ensemble voting, consensus, evolution, and more
|
|
618
|
+
|
|
619
|
+
### Basic Usage
|
|
620
|
+
|
|
621
|
+
```python
|
|
622
|
+
from npcpy.npc_array import NPCArray
|
|
623
|
+
|
|
624
|
+
# Create array of LLMs
|
|
625
|
+
models = NPCArray.from_llms(
|
|
626
|
+
['llama3.2', 'gemma3:1b'],
|
|
627
|
+
providers='ollama'
|
|
628
|
+
)
|
|
629
|
+
|
|
630
|
+
print(f"Model array shape: {models.shape}") # (2,)
|
|
631
|
+
|
|
632
|
+
# Inference across all models - returns shape (n_models, n_prompts)
|
|
633
|
+
result = models.infer("What is 2+2? Just the number.").collect()
|
|
634
|
+
|
|
635
|
+
print(f"Model 1: {result.data[0, 0]}")
|
|
636
|
+
print(f"Model 2: {result.data[1, 0]}")
|
|
637
|
+
```
|
|
638
|
+
|
|
639
|
+
### Lazy Chaining & Ensemble Operations
|
|
640
|
+
|
|
641
|
+
```python
|
|
642
|
+
from npcpy.npc_array import NPCArray
|
|
643
|
+
|
|
644
|
+
models = NPCArray.from_llms(['llama3.2', 'gemma3:1b', 'mistral:7b'])
|
|
645
|
+
|
|
646
|
+
# Build lazy computation graph - nothing executed yet
|
|
647
|
+
result = (
|
|
648
|
+
models
|
|
649
|
+
.infer("Is Python compiled or interpreted? One word.")
|
|
650
|
+
.map(lambda r: r.strip().lower()) # Clean responses
|
|
651
|
+
.vote(axis=0) # Majority voting across models
|
|
652
|
+
)
|
|
653
|
+
|
|
654
|
+
# Show the computation plan
|
|
655
|
+
result.explain()
|
|
656
|
+
|
|
657
|
+
# Now execute
|
|
658
|
+
answer = result.collect()
|
|
659
|
+
print(f"Consensus: {answer.data[0]}")
|
|
660
|
+
```
|
|
661
|
+
|
|
662
|
+
### Parameter Sweeps with Meshgrid
|
|
663
|
+
|
|
664
|
+
```python
|
|
665
|
+
from npcpy.npc_array import NPCArray
|
|
666
|
+
|
|
667
|
+
# Cartesian product over parameters
|
|
668
|
+
configs = NPCArray.meshgrid(
|
|
669
|
+
models=['llama3.2', 'gemma3:1b'],
|
|
670
|
+
temperatures=[0.0, 0.5, 1.0]
|
|
671
|
+
)
|
|
672
|
+
|
|
673
|
+
print(f"Config array shape: {configs.shape}") # (6,) = 2 models × 3 temps
|
|
674
|
+
|
|
675
|
+
# Run inference with each config
|
|
676
|
+
result = configs.infer("Complete: The quick brown fox").collect()
|
|
677
|
+
```
|
|
678
|
+
|
|
679
|
+
### Matrix Sampling with get_llm_response
|
|
680
|
+
|
|
681
|
+
The `get_llm_response` function supports `matrix` and `n_samples` parameters for exploration:
|
|
682
|
+
|
|
683
|
+
```python
|
|
684
|
+
from npcpy.llm_funcs import get_llm_response
|
|
685
|
+
|
|
686
|
+
# Matrix parameter - cartesian product over specified params
|
|
687
|
+
result = get_llm_response(
|
|
688
|
+
"Write a creative opening line.",
|
|
689
|
+
matrix={
|
|
690
|
+
'model': ['llama3.2', 'gemma3:1b'],
|
|
691
|
+
'temperature': [0.5, 1.0]
|
|
692
|
+
}
|
|
693
|
+
)
|
|
694
|
+
print(f"Number of runs: {len(result['runs'])}") # 4 = 2×2
|
|
695
|
+
|
|
696
|
+
# n_samples - multiple samples from same config
|
|
697
|
+
result = get_llm_response(
|
|
698
|
+
"Pick a random number 1-100.",
|
|
699
|
+
model='llama3.2',
|
|
700
|
+
n_samples=5
|
|
701
|
+
)
|
|
702
|
+
print(f"Samples: {[r['response'] for r in result['runs']]}")
|
|
703
|
+
|
|
704
|
+
# Combine both for full exploration
|
|
705
|
+
result = get_llm_response(
|
|
706
|
+
"Flip a coin: heads or tails?",
|
|
707
|
+
matrix={'model': ['llama3.2', 'gemma3:1b']},
|
|
708
|
+
n_samples=3 # 2 models × 3 samples = 6 runs
|
|
709
|
+
)
|
|
710
|
+
```
|
|
711
|
+
|
|
712
|
+
### sklearn Integration
|
|
713
|
+
|
|
714
|
+
```python
|
|
715
|
+
from npcpy.npc_array import NPCArray
|
|
716
|
+
from sklearn.ensemble import RandomForestClassifier
|
|
717
|
+
from sklearn.linear_model import LogisticRegression
|
|
718
|
+
import numpy as np
|
|
719
|
+
|
|
720
|
+
# Create sample data
|
|
721
|
+
X_train = np.random.randn(100, 4)
|
|
722
|
+
y_train = (X_train[:, 0] > 0).astype(int)
|
|
723
|
+
|
|
724
|
+
# Pre-fit models
|
|
725
|
+
rf = RandomForestClassifier(n_estimators=10).fit(X_train, y_train)
|
|
726
|
+
lr = LogisticRegression().fit(X_train, y_train)
|
|
727
|
+
|
|
728
|
+
# Create array from fitted models
|
|
729
|
+
models = NPCArray.from_sklearn([rf, lr])
|
|
730
|
+
|
|
731
|
+
# Vectorized prediction
|
|
732
|
+
X_test = np.random.randn(20, 4)
|
|
733
|
+
predictions = models.predict(X_test).collect()
|
|
734
|
+
|
|
735
|
+
print(f"RF predictions: {predictions.data[0]}")
|
|
736
|
+
print(f"LR predictions: {predictions.data[1]}")
|
|
737
|
+
```
|
|
738
|
+
|
|
739
|
+
### ML Functions with Grid Search
|
|
740
|
+
|
|
741
|
+
```python
|
|
742
|
+
from npcpy.ml_funcs import fit_model, score_model, ensemble_predict
|
|
743
|
+
|
|
744
|
+
# Grid search via matrix parameter
|
|
745
|
+
result = fit_model(
|
|
746
|
+
X_train, y_train,
|
|
747
|
+
model='RandomForestClassifier',
|
|
748
|
+
matrix={
|
|
749
|
+
'n_estimators': [10, 50, 100],
|
|
750
|
+
'max_depth': [3, 5, 10]
|
|
751
|
+
}
|
|
752
|
+
)
|
|
753
|
+
|
|
754
|
+
print(f"Fitted {len(result['models'])} model configurations")
|
|
755
|
+
|
|
756
|
+
# Ensemble voting with multiple models
|
|
757
|
+
predictions = ensemble_predict(X_test, result['models'], method='vote')
|
|
758
|
+
```
|
|
759
|
+
|
|
760
|
+
### Quick Utilities
|
|
761
|
+
|
|
762
|
+
```python
|
|
763
|
+
from npcpy.npc_array import infer_matrix, ensemble_vote
|
|
764
|
+
|
|
765
|
+
# Quick matrix inference
|
|
766
|
+
result = infer_matrix(
|
|
767
|
+
prompts=["Hello", "Goodbye"],
|
|
768
|
+
models=['llama3.2', 'gemma3:1b']
|
|
769
|
+
)
|
|
770
|
+
|
|
771
|
+
# Quick ensemble vote
|
|
772
|
+
answer = ensemble_vote(
|
|
773
|
+
"What is the capital of France? One word.",
|
|
774
|
+
models=['llama3.2', 'gemma3:1b']
|
|
775
|
+
)
|
|
776
|
+
print(f"Voted answer: {answer}")
|
|
777
|
+
```
|
|
778
|
+
|
|
779
|
+
See `examples/npc_array_examples.py` for more comprehensive examples.
|
|
780
|
+
|
|
610
781
|
|
|
611
782
|
## Serving an NPC Team
|
|
612
783
|
|
|
@@ -179,9 +179,8 @@ output = context['research_summary']
|
|
|
179
179
|
"code": '''
|
|
180
180
|
# Access outputs from previous steps.
|
|
181
181
|
research_summary = context['initial_llm_research']
|
|
182
|
-
# The
|
|
183
|
-
|
|
184
|
-
file_summary = context['read_and_process_source_file'].get('output', 'No file summary available.')
|
|
182
|
+
# The file_reader jinx returns its output directly; also keep a fallback of file_raw_content.
|
|
183
|
+
file_summary = context.get('read_and_process_source_file', '') or context.get('file_raw_content', 'No file summary available.')
|
|
185
184
|
|
|
186
185
|
prompt = f"""Based on the following information:
|
|
187
186
|
1. Comprehensive Research Summary:
|
|
@@ -511,6 +510,178 @@ else:
|
|
|
511
510
|
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.
|
|
512
511
|
|
|
513
512
|
|
|
513
|
+
## NPCArray - NumPy for AI
|
|
514
|
+
|
|
515
|
+
`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.
|
|
516
|
+
|
|
517
|
+
### Core Concepts
|
|
518
|
+
- Model arrays support vectorized operations
|
|
519
|
+
- Operations are lazy until `.collect()` is called (like Spark)
|
|
520
|
+
- Same interface works for single models (treated as length-1 arrays)
|
|
521
|
+
- Supports ensemble voting, consensus, evolution, and more
|
|
522
|
+
|
|
523
|
+
### Basic Usage
|
|
524
|
+
|
|
525
|
+
```python
|
|
526
|
+
from npcpy.npc_array import NPCArray
|
|
527
|
+
|
|
528
|
+
# Create array of LLMs
|
|
529
|
+
models = NPCArray.from_llms(
|
|
530
|
+
['llama3.2', 'gemma3:1b'],
|
|
531
|
+
providers='ollama'
|
|
532
|
+
)
|
|
533
|
+
|
|
534
|
+
print(f"Model array shape: {models.shape}") # (2,)
|
|
535
|
+
|
|
536
|
+
# Inference across all models - returns shape (n_models, n_prompts)
|
|
537
|
+
result = models.infer("What is 2+2? Just the number.").collect()
|
|
538
|
+
|
|
539
|
+
print(f"Model 1: {result.data[0, 0]}")
|
|
540
|
+
print(f"Model 2: {result.data[1, 0]}")
|
|
541
|
+
```
|
|
542
|
+
|
|
543
|
+
### Lazy Chaining & Ensemble Operations
|
|
544
|
+
|
|
545
|
+
```python
|
|
546
|
+
from npcpy.npc_array import NPCArray
|
|
547
|
+
|
|
548
|
+
models = NPCArray.from_llms(['llama3.2', 'gemma3:1b', 'mistral:7b'])
|
|
549
|
+
|
|
550
|
+
# Build lazy computation graph - nothing executed yet
|
|
551
|
+
result = (
|
|
552
|
+
models
|
|
553
|
+
.infer("Is Python compiled or interpreted? One word.")
|
|
554
|
+
.map(lambda r: r.strip().lower()) # Clean responses
|
|
555
|
+
.vote(axis=0) # Majority voting across models
|
|
556
|
+
)
|
|
557
|
+
|
|
558
|
+
# Show the computation plan
|
|
559
|
+
result.explain()
|
|
560
|
+
|
|
561
|
+
# Now execute
|
|
562
|
+
answer = result.collect()
|
|
563
|
+
print(f"Consensus: {answer.data[0]}")
|
|
564
|
+
```
|
|
565
|
+
|
|
566
|
+
### Parameter Sweeps with Meshgrid
|
|
567
|
+
|
|
568
|
+
```python
|
|
569
|
+
from npcpy.npc_array import NPCArray
|
|
570
|
+
|
|
571
|
+
# Cartesian product over parameters
|
|
572
|
+
configs = NPCArray.meshgrid(
|
|
573
|
+
models=['llama3.2', 'gemma3:1b'],
|
|
574
|
+
temperatures=[0.0, 0.5, 1.0]
|
|
575
|
+
)
|
|
576
|
+
|
|
577
|
+
print(f"Config array shape: {configs.shape}") # (6,) = 2 models × 3 temps
|
|
578
|
+
|
|
579
|
+
# Run inference with each config
|
|
580
|
+
result = configs.infer("Complete: The quick brown fox").collect()
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
### Matrix Sampling with get_llm_response
|
|
584
|
+
|
|
585
|
+
The `get_llm_response` function supports `matrix` and `n_samples` parameters for exploration:
|
|
586
|
+
|
|
587
|
+
```python
|
|
588
|
+
from npcpy.llm_funcs import get_llm_response
|
|
589
|
+
|
|
590
|
+
# Matrix parameter - cartesian product over specified params
|
|
591
|
+
result = get_llm_response(
|
|
592
|
+
"Write a creative opening line.",
|
|
593
|
+
matrix={
|
|
594
|
+
'model': ['llama3.2', 'gemma3:1b'],
|
|
595
|
+
'temperature': [0.5, 1.0]
|
|
596
|
+
}
|
|
597
|
+
)
|
|
598
|
+
print(f"Number of runs: {len(result['runs'])}") # 4 = 2×2
|
|
599
|
+
|
|
600
|
+
# n_samples - multiple samples from same config
|
|
601
|
+
result = get_llm_response(
|
|
602
|
+
"Pick a random number 1-100.",
|
|
603
|
+
model='llama3.2',
|
|
604
|
+
n_samples=5
|
|
605
|
+
)
|
|
606
|
+
print(f"Samples: {[r['response'] for r in result['runs']]}")
|
|
607
|
+
|
|
608
|
+
# Combine both for full exploration
|
|
609
|
+
result = get_llm_response(
|
|
610
|
+
"Flip a coin: heads or tails?",
|
|
611
|
+
matrix={'model': ['llama3.2', 'gemma3:1b']},
|
|
612
|
+
n_samples=3 # 2 models × 3 samples = 6 runs
|
|
613
|
+
)
|
|
614
|
+
```
|
|
615
|
+
|
|
616
|
+
### sklearn Integration
|
|
617
|
+
|
|
618
|
+
```python
|
|
619
|
+
from npcpy.npc_array import NPCArray
|
|
620
|
+
from sklearn.ensemble import RandomForestClassifier
|
|
621
|
+
from sklearn.linear_model import LogisticRegression
|
|
622
|
+
import numpy as np
|
|
623
|
+
|
|
624
|
+
# Create sample data
|
|
625
|
+
X_train = np.random.randn(100, 4)
|
|
626
|
+
y_train = (X_train[:, 0] > 0).astype(int)
|
|
627
|
+
|
|
628
|
+
# Pre-fit models
|
|
629
|
+
rf = RandomForestClassifier(n_estimators=10).fit(X_train, y_train)
|
|
630
|
+
lr = LogisticRegression().fit(X_train, y_train)
|
|
631
|
+
|
|
632
|
+
# Create array from fitted models
|
|
633
|
+
models = NPCArray.from_sklearn([rf, lr])
|
|
634
|
+
|
|
635
|
+
# Vectorized prediction
|
|
636
|
+
X_test = np.random.randn(20, 4)
|
|
637
|
+
predictions = models.predict(X_test).collect()
|
|
638
|
+
|
|
639
|
+
print(f"RF predictions: {predictions.data[0]}")
|
|
640
|
+
print(f"LR predictions: {predictions.data[1]}")
|
|
641
|
+
```
|
|
642
|
+
|
|
643
|
+
### ML Functions with Grid Search
|
|
644
|
+
|
|
645
|
+
```python
|
|
646
|
+
from npcpy.ml_funcs import fit_model, score_model, ensemble_predict
|
|
647
|
+
|
|
648
|
+
# Grid search via matrix parameter
|
|
649
|
+
result = fit_model(
|
|
650
|
+
X_train, y_train,
|
|
651
|
+
model='RandomForestClassifier',
|
|
652
|
+
matrix={
|
|
653
|
+
'n_estimators': [10, 50, 100],
|
|
654
|
+
'max_depth': [3, 5, 10]
|
|
655
|
+
}
|
|
656
|
+
)
|
|
657
|
+
|
|
658
|
+
print(f"Fitted {len(result['models'])} model configurations")
|
|
659
|
+
|
|
660
|
+
# Ensemble voting with multiple models
|
|
661
|
+
predictions = ensemble_predict(X_test, result['models'], method='vote')
|
|
662
|
+
```
|
|
663
|
+
|
|
664
|
+
### Quick Utilities
|
|
665
|
+
|
|
666
|
+
```python
|
|
667
|
+
from npcpy.npc_array import infer_matrix, ensemble_vote
|
|
668
|
+
|
|
669
|
+
# Quick matrix inference
|
|
670
|
+
result = infer_matrix(
|
|
671
|
+
prompts=["Hello", "Goodbye"],
|
|
672
|
+
models=['llama3.2', 'gemma3:1b']
|
|
673
|
+
)
|
|
674
|
+
|
|
675
|
+
# Quick ensemble vote
|
|
676
|
+
answer = ensemble_vote(
|
|
677
|
+
"What is the capital of France? One word.",
|
|
678
|
+
models=['llama3.2', 'gemma3:1b']
|
|
679
|
+
)
|
|
680
|
+
print(f"Voted answer: {answer}")
|
|
681
|
+
```
|
|
682
|
+
|
|
683
|
+
See `examples/npc_array_examples.py` for more comprehensive examples.
|
|
684
|
+
|
|
514
685
|
|
|
515
686
|
## Serving an NPC Team
|
|
516
687
|
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
from . import npc_compiler
|
|
2
|
+
from . import npc_sysenv
|
|
3
|
+
from . import llm_funcs
|
|
4
|
+
from . import ml_funcs
|
|
5
|
+
from . import npc_array
|
|
6
|
+
from . import sql
|
|
7
|
+
from . import work
|
|
8
|
+
from . import gen
|
|
9
|
+
|
|
10
|
+
# Expose key classes at package level
|
|
11
|
+
from .npc_array import NPCArray, ResponseTensor, LazyResult, infer_matrix, ensemble_vote
|
|
12
|
+
from .npc_compiler import NPC, Team, Jinx
|
|
13
|
+
from .llm_funcs import get_llm_response, check_llm_command, execute_llm_command
|
|
14
|
+
from .ml_funcs import fit_model, predict_model, score_model, ensemble_predict
|
|
@@ -363,7 +363,8 @@ def generate_image(
|
|
|
363
363
|
api_url: Optional[str] = None,
|
|
364
364
|
attachments: Union[List[Union[str, bytes, Image.Image]], None] = None,
|
|
365
365
|
save_path: Optional[str] = None,
|
|
366
|
-
custom_model_path: Optional[str] = None, # <--- NEW: Accept custom_model_path
|
|
366
|
+
custom_model_path: Optional[str] = None, # <--- NEW: Accept custom_model_path,
|
|
367
|
+
|
|
367
368
|
):
|
|
368
369
|
"""
|
|
369
370
|
Unified function to generate or edit images using various providers.
|
|
@@ -429,7 +430,9 @@ def generate_image(
|
|
|
429
430
|
attachments=attachments,
|
|
430
431
|
height=height,
|
|
431
432
|
width=width,
|
|
432
|
-
n_images=n_images
|
|
433
|
+
n_images=n_images,
|
|
434
|
+
api_key=api_key
|
|
435
|
+
|
|
433
436
|
)
|
|
434
437
|
all_generated_pil_images.extend(images)
|
|
435
438
|
|