npcpy 1.2.19__tar.gz → 1.2.20__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.
Files changed (67) hide show
  1. {npcpy-1.2.19/npcpy.egg-info → npcpy-1.2.20}/PKG-INFO +1 -1
  2. npcpy-1.2.20/npcpy/ft/memory_trainer.py +171 -0
  3. {npcpy-1.2.19 → npcpy-1.2.20/npcpy.egg-info}/PKG-INFO +1 -1
  4. {npcpy-1.2.19 → npcpy-1.2.20}/setup.py +1 -1
  5. npcpy-1.2.19/npcpy/ft/memory_trainer.py +0 -164
  6. {npcpy-1.2.19 → npcpy-1.2.20}/LICENSE +0 -0
  7. {npcpy-1.2.19 → npcpy-1.2.20}/MANIFEST.in +0 -0
  8. {npcpy-1.2.19 → npcpy-1.2.20}/README.md +0 -0
  9. {npcpy-1.2.19 → npcpy-1.2.20}/npcpy/__init__.py +0 -0
  10. {npcpy-1.2.19 → npcpy-1.2.20}/npcpy/data/__init__.py +0 -0
  11. {npcpy-1.2.19 → npcpy-1.2.20}/npcpy/data/audio.py +0 -0
  12. {npcpy-1.2.19 → npcpy-1.2.20}/npcpy/data/data_models.py +0 -0
  13. {npcpy-1.2.19 → npcpy-1.2.20}/npcpy/data/image.py +0 -0
  14. {npcpy-1.2.19 → npcpy-1.2.20}/npcpy/data/load.py +0 -0
  15. {npcpy-1.2.19 → npcpy-1.2.20}/npcpy/data/text.py +0 -0
  16. {npcpy-1.2.19 → npcpy-1.2.20}/npcpy/data/video.py +0 -0
  17. {npcpy-1.2.19 → npcpy-1.2.20}/npcpy/data/web.py +0 -0
  18. {npcpy-1.2.19 → npcpy-1.2.20}/npcpy/ft/__init__.py +0 -0
  19. {npcpy-1.2.19 → npcpy-1.2.20}/npcpy/ft/diff.py +0 -0
  20. {npcpy-1.2.19 → npcpy-1.2.20}/npcpy/ft/ge.py +0 -0
  21. {npcpy-1.2.19 → npcpy-1.2.20}/npcpy/ft/rl.py +0 -0
  22. {npcpy-1.2.19 → npcpy-1.2.20}/npcpy/ft/sft.py +0 -0
  23. {npcpy-1.2.19 → npcpy-1.2.20}/npcpy/gen/__init__.py +0 -0
  24. {npcpy-1.2.19 → npcpy-1.2.20}/npcpy/gen/audio_gen.py +0 -0
  25. {npcpy-1.2.19 → npcpy-1.2.20}/npcpy/gen/embeddings.py +0 -0
  26. {npcpy-1.2.19 → npcpy-1.2.20}/npcpy/gen/image_gen.py +0 -0
  27. {npcpy-1.2.19 → npcpy-1.2.20}/npcpy/gen/response.py +0 -0
  28. {npcpy-1.2.19 → npcpy-1.2.20}/npcpy/gen/video_gen.py +0 -0
  29. {npcpy-1.2.19 → npcpy-1.2.20}/npcpy/llm_funcs.py +0 -0
  30. {npcpy-1.2.19 → npcpy-1.2.20}/npcpy/main.py +0 -0
  31. {npcpy-1.2.19 → npcpy-1.2.20}/npcpy/memory/__init__.py +0 -0
  32. {npcpy-1.2.19 → npcpy-1.2.20}/npcpy/memory/command_history.py +0 -0
  33. {npcpy-1.2.19 → npcpy-1.2.20}/npcpy/memory/kg_vis.py +0 -0
  34. {npcpy-1.2.19 → npcpy-1.2.20}/npcpy/memory/knowledge_graph.py +0 -0
  35. {npcpy-1.2.19 → npcpy-1.2.20}/npcpy/memory/memory_processor.py +0 -0
  36. {npcpy-1.2.19 → npcpy-1.2.20}/npcpy/memory/search.py +0 -0
  37. {npcpy-1.2.19 → npcpy-1.2.20}/npcpy/mix/__init__.py +0 -0
  38. {npcpy-1.2.19 → npcpy-1.2.20}/npcpy/mix/debate.py +0 -0
  39. {npcpy-1.2.19 → npcpy-1.2.20}/npcpy/npc_compiler.py +0 -0
  40. {npcpy-1.2.19 → npcpy-1.2.20}/npcpy/npc_sysenv.py +0 -0
  41. {npcpy-1.2.19 → npcpy-1.2.20}/npcpy/npcs.py +0 -0
  42. {npcpy-1.2.19 → npcpy-1.2.20}/npcpy/serve.py +0 -0
  43. {npcpy-1.2.19 → npcpy-1.2.20}/npcpy/sql/__init__.py +0 -0
  44. {npcpy-1.2.19 → npcpy-1.2.20}/npcpy/sql/model_runner.py +0 -0
  45. {npcpy-1.2.19 → npcpy-1.2.20}/npcpy/sql/npcsql.py +0 -0
  46. {npcpy-1.2.19 → npcpy-1.2.20}/npcpy/tools.py +0 -0
  47. {npcpy-1.2.19 → npcpy-1.2.20}/npcpy/work/__init__.py +0 -0
  48. {npcpy-1.2.19 → npcpy-1.2.20}/npcpy/work/desktop.py +0 -0
  49. {npcpy-1.2.19 → npcpy-1.2.20}/npcpy/work/plan.py +0 -0
  50. {npcpy-1.2.19 → npcpy-1.2.20}/npcpy/work/trigger.py +0 -0
  51. {npcpy-1.2.19 → npcpy-1.2.20}/npcpy.egg-info/SOURCES.txt +0 -0
  52. {npcpy-1.2.19 → npcpy-1.2.20}/npcpy.egg-info/dependency_links.txt +0 -0
  53. {npcpy-1.2.19 → npcpy-1.2.20}/npcpy.egg-info/requires.txt +0 -0
  54. {npcpy-1.2.19 → npcpy-1.2.20}/npcpy.egg-info/top_level.txt +0 -0
  55. {npcpy-1.2.19 → npcpy-1.2.20}/setup.cfg +0 -0
  56. {npcpy-1.2.19 → npcpy-1.2.20}/tests/test_audio.py +0 -0
  57. {npcpy-1.2.19 → npcpy-1.2.20}/tests/test_command_history.py +0 -0
  58. {npcpy-1.2.19 → npcpy-1.2.20}/tests/test_image.py +0 -0
  59. {npcpy-1.2.19 → npcpy-1.2.20}/tests/test_llm_funcs.py +0 -0
  60. {npcpy-1.2.19 → npcpy-1.2.20}/tests/test_load.py +0 -0
  61. {npcpy-1.2.19 → npcpy-1.2.20}/tests/test_npc_compiler.py +0 -0
  62. {npcpy-1.2.19 → npcpy-1.2.20}/tests/test_npcsql.py +0 -0
  63. {npcpy-1.2.19 → npcpy-1.2.20}/tests/test_response.py +0 -0
  64. {npcpy-1.2.19 → npcpy-1.2.20}/tests/test_serve.py +0 -0
  65. {npcpy-1.2.19 → npcpy-1.2.20}/tests/test_text.py +0 -0
  66. {npcpy-1.2.19 → npcpy-1.2.20}/tests/test_tools.py +0 -0
  67. {npcpy-1.2.19 → npcpy-1.2.20}/tests/test_web.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: npcpy
3
- Version: 1.2.19
3
+ Version: 1.2.20
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
@@ -0,0 +1,171 @@
1
+ try:
2
+ from torch.utils.data import Dataset
3
+ import torch
4
+ import torch.nn as nn
5
+ from transformers import AutoTokenizer, AutoModelForSequenceClassification, Trainer, TrainingArguments
6
+
7
+ import json
8
+ from typing import List, Dict, Tuple
9
+ import random
10
+
11
+ class MemoryDataset(Dataset):
12
+ def __init__(self, examples: List[Dict], tokenizer, max_length=512):
13
+ self.examples = examples
14
+ self.tokenizer = tokenizer
15
+ self.max_length = max_length
16
+
17
+ def __len__(self):
18
+ return len(self.examples)
19
+
20
+ def __getitem__(self, idx):
21
+ example = self.examples[idx]
22
+
23
+
24
+ text = f"Memory: {example['memory']}\nContext: {example.get('context', '')}"
25
+
26
+ encoding = self.tokenizer(
27
+ text,
28
+ truncation=True,
29
+ padding='max_length',
30
+ max_length=self.max_length,
31
+ return_tensors='pt'
32
+ )
33
+
34
+ return {
35
+ 'input_ids': encoding['input_ids'].flatten(),
36
+ 'attention_mask': encoding['attention_mask'].flatten(),
37
+ 'labels': torch.tensor(example['label'], dtype=torch.long)
38
+ }
39
+
40
+ class MemoryTrainer:
41
+ def __init__(self, model_name="google/gemma-2b", device="cpu"):
42
+ self.device = device
43
+ self.tokenizer = AutoTokenizer.from_pretrained(model_name)
44
+ if self.tokenizer.pad_token is None:
45
+ self.tokenizer.pad_token = self.tokenizer.eos_token
46
+
47
+
48
+ self.model = AutoModelForSequenceClassification.from_pretrained(
49
+ model_name,
50
+ num_labels=3
51
+ ).to(device)
52
+
53
+ def prepare_training_data(self, approved_memories: List[Dict],
54
+ rejected_memories: List[Dict]) -> List[Dict]:
55
+ """Prepare training data from memory examples"""
56
+ examples = []
57
+
58
+
59
+ for memory in approved_memories:
60
+ examples.append({
61
+ "memory": memory.get("final_memory") or memory.get("initial_memory"),
62
+ "context": memory.get("context", ""),
63
+ "label": 1
64
+ })
65
+
66
+
67
+ for memory in rejected_memories:
68
+ examples.append({
69
+ "memory": memory.get("initial_memory"),
70
+ "context": memory.get("context", ""),
71
+ "label": 0
72
+ })
73
+
74
+
75
+ edited_examples = []
76
+ for memory in approved_memories[:len(rejected_memories)//2]:
77
+ if memory.get("final_memory") and memory.get("initial_memory"):
78
+
79
+ edited_examples.append({
80
+ "memory": memory.get("initial_memory"),
81
+ "context": memory.get("context", ""),
82
+ "label": 2
83
+ })
84
+
85
+ examples.extend(edited_examples)
86
+ random.shuffle(examples)
87
+ return examples
88
+
89
+ def train(self, approved_memories: List[Dict], rejected_memories: List[Dict],
90
+ output_dir: str = "./memory_model", epochs: int = 3):
91
+ """Train the memory classification model"""
92
+
93
+ if len(approved_memories) < 10 or len(rejected_memories) < 10:
94
+ print("Not enough training data. Need at least 10 approved and 10 rejected memories.")
95
+ return False
96
+
97
+ training_data = self.prepare_training_data(approved_memories, rejected_memories)
98
+
99
+
100
+ split_idx = int(0.8 * len(training_data))
101
+ train_data = training_data[:split_idx]
102
+ val_data = training_data[split_idx:]
103
+
104
+ train_dataset = MemoryDataset(train_data, self.tokenizer)
105
+ val_dataset = MemoryDataset(val_data, self.tokenizer)
106
+
107
+ training_args = TrainingArguments(
108
+ output_dir=output_dir,
109
+ num_train_epochs=epochs,
110
+ per_device_train_batch_size=4,
111
+ per_device_eval_batch_size=4,
112
+ warmup_steps=100,
113
+ weight_decay=0.01,
114
+ logging_dir='./logs',
115
+ evaluation_strategy="epoch",
116
+ save_strategy="epoch",
117
+ load_best_model_at_end=True,
118
+ )
119
+
120
+ trainer = Trainer(
121
+ model=self.model,
122
+ args=training_args,
123
+ train_dataset=train_dataset,
124
+ eval_dataset=val_dataset,
125
+ )
126
+
127
+ trainer.train()
128
+ trainer.save_model()
129
+ self.tokenizer.save_pretrained(output_dir)
130
+
131
+ print(f"Model trained and saved to {output_dir}")
132
+ return True
133
+
134
+ def predict_memory_action(self, memory_content: str, context: str = "") -> Tuple[str, float]:
135
+ """Predict what action to take on a memory"""
136
+ text = f"Memory: {memory_content}\nContext: {context}"
137
+
138
+ encoding = self.tokenizer(
139
+ text,
140
+ truncation=True,
141
+ padding=True,
142
+ max_length=512,
143
+ return_tensors='pt'
144
+ ).to(self.device)
145
+
146
+ with torch.no_grad():
147
+ outputs = self.model(**encoding)
148
+ probabilities = torch.softmax(outputs.logits, dim=-1)
149
+ predicted_class = torch.argmax(probabilities, dim=-1).item()
150
+ confidence = probabilities[0][predicted_class].item()
151
+
152
+ actions = {0: "model-rejected", 1: "model-approved", 2: "needs-editing"}
153
+ return actions[predicted_class], confidence
154
+
155
+ def auto_approve_memory(self, memory_content: str, context: str = "",
156
+ confidence_threshold: float = 0.8) -> Dict:
157
+ """Auto-approve memory if confidence is high enough"""
158
+ action, confidence = self.predict_memory_action(memory_content, context)
159
+
160
+ if confidence >= confidence_threshold:
161
+ return {"action": action, "confidence": confidence, "auto_processed": True}
162
+ else:
163
+ return {"action": "pending_approval", "confidence": confidence, "auto_processed": False}
164
+ except:
165
+ Dataset = None
166
+ nn = None
167
+ Trainer = None
168
+ TrainingArguments = None
169
+
170
+ MemoryDataset = None
171
+ MemoryTrainer = None
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: npcpy
3
- Version: 1.2.19
3
+ Version: 1.2.20
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
@@ -82,7 +82,7 @@ extra_files = package_files("npcpy/npc_team/")
82
82
 
83
83
  setup(
84
84
  name="npcpy",
85
- version="1.2.19",
85
+ version="1.2.20",
86
86
  packages=find_packages(exclude=["tests*"]),
87
87
  install_requires=base_requirements,
88
88
  extras_require={
@@ -1,164 +0,0 @@
1
- try:
2
- from torch.utils.data import Dataset
3
- import torch
4
- import torch.nn as nn
5
- from transformers import AutoTokenizer, AutoModelForSequenceClassification, Trainer, TrainingArguments
6
- except:
7
- pass
8
- import json
9
- from typing import List, Dict, Tuple
10
- import random
11
-
12
- class MemoryDataset(Dataset):
13
- def __init__(self, examples: List[Dict], tokenizer, max_length=512):
14
- self.examples = examples
15
- self.tokenizer = tokenizer
16
- self.max_length = max_length
17
-
18
- def __len__(self):
19
- return len(self.examples)
20
-
21
- def __getitem__(self, idx):
22
- example = self.examples[idx]
23
-
24
-
25
- text = f"Memory: {example['memory']}\nContext: {example.get('context', '')}"
26
-
27
- encoding = self.tokenizer(
28
- text,
29
- truncation=True,
30
- padding='max_length',
31
- max_length=self.max_length,
32
- return_tensors='pt'
33
- )
34
-
35
- return {
36
- 'input_ids': encoding['input_ids'].flatten(),
37
- 'attention_mask': encoding['attention_mask'].flatten(),
38
- 'labels': torch.tensor(example['label'], dtype=torch.long)
39
- }
40
-
41
- class MemoryTrainer:
42
- def __init__(self, model_name="google/gemma-2b", device="cpu"):
43
- self.device = device
44
- self.tokenizer = AutoTokenizer.from_pretrained(model_name)
45
- if self.tokenizer.pad_token is None:
46
- self.tokenizer.pad_token = self.tokenizer.eos_token
47
-
48
-
49
- self.model = AutoModelForSequenceClassification.from_pretrained(
50
- model_name,
51
- num_labels=3
52
- ).to(device)
53
-
54
- def prepare_training_data(self, approved_memories: List[Dict],
55
- rejected_memories: List[Dict]) -> List[Dict]:
56
- """Prepare training data from memory examples"""
57
- examples = []
58
-
59
-
60
- for memory in approved_memories:
61
- examples.append({
62
- "memory": memory.get("final_memory") or memory.get("initial_memory"),
63
- "context": memory.get("context", ""),
64
- "label": 1
65
- })
66
-
67
-
68
- for memory in rejected_memories:
69
- examples.append({
70
- "memory": memory.get("initial_memory"),
71
- "context": memory.get("context", ""),
72
- "label": 0
73
- })
74
-
75
-
76
- edited_examples = []
77
- for memory in approved_memories[:len(rejected_memories)//2]:
78
- if memory.get("final_memory") and memory.get("initial_memory"):
79
-
80
- edited_examples.append({
81
- "memory": memory.get("initial_memory"),
82
- "context": memory.get("context", ""),
83
- "label": 2
84
- })
85
-
86
- examples.extend(edited_examples)
87
- random.shuffle(examples)
88
- return examples
89
-
90
- def train(self, approved_memories: List[Dict], rejected_memories: List[Dict],
91
- output_dir: str = "./memory_model", epochs: int = 3):
92
- """Train the memory classification model"""
93
-
94
- if len(approved_memories) < 10 or len(rejected_memories) < 10:
95
- print("Not enough training data. Need at least 10 approved and 10 rejected memories.")
96
- return False
97
-
98
- training_data = self.prepare_training_data(approved_memories, rejected_memories)
99
-
100
-
101
- split_idx = int(0.8 * len(training_data))
102
- train_data = training_data[:split_idx]
103
- val_data = training_data[split_idx:]
104
-
105
- train_dataset = MemoryDataset(train_data, self.tokenizer)
106
- val_dataset = MemoryDataset(val_data, self.tokenizer)
107
-
108
- training_args = TrainingArguments(
109
- output_dir=output_dir,
110
- num_train_epochs=epochs,
111
- per_device_train_batch_size=4,
112
- per_device_eval_batch_size=4,
113
- warmup_steps=100,
114
- weight_decay=0.01,
115
- logging_dir='./logs',
116
- evaluation_strategy="epoch",
117
- save_strategy="epoch",
118
- load_best_model_at_end=True,
119
- )
120
-
121
- trainer = Trainer(
122
- model=self.model,
123
- args=training_args,
124
- train_dataset=train_dataset,
125
- eval_dataset=val_dataset,
126
- )
127
-
128
- trainer.train()
129
- trainer.save_model()
130
- self.tokenizer.save_pretrained(output_dir)
131
-
132
- print(f"Model trained and saved to {output_dir}")
133
- return True
134
-
135
- def predict_memory_action(self, memory_content: str, context: str = "") -> Tuple[str, float]:
136
- """Predict what action to take on a memory"""
137
- text = f"Memory: {memory_content}\nContext: {context}"
138
-
139
- encoding = self.tokenizer(
140
- text,
141
- truncation=True,
142
- padding=True,
143
- max_length=512,
144
- return_tensors='pt'
145
- ).to(self.device)
146
-
147
- with torch.no_grad():
148
- outputs = self.model(**encoding)
149
- probabilities = torch.softmax(outputs.logits, dim=-1)
150
- predicted_class = torch.argmax(probabilities, dim=-1).item()
151
- confidence = probabilities[0][predicted_class].item()
152
-
153
- actions = {0: "model-rejected", 1: "model-approved", 2: "needs-editing"}
154
- return actions[predicted_class], confidence
155
-
156
- def auto_approve_memory(self, memory_content: str, context: str = "",
157
- confidence_threshold: float = 0.8) -> Dict:
158
- """Auto-approve memory if confidence is high enough"""
159
- action, confidence = self.predict_memory_action(memory_content, context)
160
-
161
- if confidence >= confidence_threshold:
162
- return {"action": action, "confidence": confidence, "auto_processed": True}
163
- else:
164
- return {"action": "pending_approval", "confidence": confidence, "auto_processed": False}
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