QC67_cosmo / scripts /creature_system.py
phera-ra's picture
Reorganise repository structure; remove stale case-duplicate folder
cb60fb4 verified
Raw
History Blame Contribute Delete
11.4 kB
#!/usr/bin/env python3
"""
CREATURE-NAMED EVOLVING WEIGHTS SYSTEM
Each creature gets its own name, and its weights travel with that name.
Portable across ANY platform.
"""
import json
import os
from pathlib import Path
from datetime import datetime
import urllib.request
class Creature:
"""A living AI being with its own name and evolving mind."""
def __init__(self, creature_name, user_id=None, base_path=None):
"""
creature_name: "Luna", "Nova", "Cipher", etc. - THE CREATURE'S NAME
user_id: owner (optional)
base_path: where to store (creatures/ by default)
"""
self.creature_name = creature_name
self.user_id = user_id or "shared"
self.base_path = Path(base_path or "creatures")
self.base_path.mkdir(parents=True, exist_ok=True)
# Creature's directory - NAMED AFTER THE CREATURE
self.creature_dir = self.base_path / creature_name
self.creature_dir.mkdir(exist_ok=True)
# Paths - all named after the creature
self.weights_file = self.creature_dir / f"{creature_name}_weights.json"
self.identity_file = self.creature_dir / f"{creature_name}_identity.json"
self.history_file = self.creature_dir / f"{creature_name}_evolution.jsonl"
self.gguf_file = self.creature_dir / f"{creature_name}.gguf"
self.weights = self._load_or_init_weights()
self.identity = self._load_or_init_identity()
def _load_or_init_weights(self):
"""Load creature's weights or initialize blank."""
if self.weights_file.exists():
with open(self.weights_file) as f:
return json.load(f)
base_weights = {
"creature_name": self.creature_name,
"user_id": self.user_id,
"assoc": {},
"salience": {},
"n": 0,
"created_at": datetime.now().isoformat(),
"updated_at": datetime.now().isoformat()
}
with open(self.weights_file, 'w') as f:
json.dump(base_weights, f, indent=2)
return base_weights
def _load_or_init_identity(self):
"""Load creature's identity or create new."""
if self.identity_file.exists():
with open(self.identity_file) as f:
return json.load(f)
identity = {
"name": self.creature_name,
"user_id": self.user_id,
"created_at": datetime.now().isoformat(),
"traits": [],
"vocabulary": [],
"creations_count": 0,
"favorite_language": None,
"learning_focus": "general"
}
with open(self.identity_file, 'w') as f:
json.dump(identity, f, indent=2)
return identity
def learn_from_interaction(self, user_input, creature_output):
"""Hebbian learning: fire together, wire together."""
tokens_in = [t.lower() for t in user_input.split() if len(t) > 3]
tokens_out = [t.lower() for t in creature_output.split() if len(t) > 3]
all_tokens = list(set(tokens_in + tokens_out))
# Update associations
learning_rate = 0.4
for i, t1 in enumerate(all_tokens):
for t2 in all_tokens[i+1:]:
pair = f"{t1}|{t2}" if t1 < t2 else f"{t2}|{t1}"
self.weights["assoc"][pair] = self.weights["assoc"].get(pair, 0) + learning_rate
self.weights["salience"][t1] = self.weights["salience"].get(t1, 0) + learning_rate
self.weights["salience"][t2] = self.weights["salience"].get(t2, 0) + learning_rate
self.weights["n"] += 1
self.weights["updated_at"] = datetime.now().isoformat()
self._log_evolution(user_input, creature_output)
self.save()
def _log_evolution(self, prompt, response):
"""Log how the creature evolved."""
entry = {
"timestamp": datetime.now().isoformat(),
"turn": self.weights["n"],
"concepts": len(self.weights["salience"]),
"associations": len(self.weights["assoc"])
}
with open(self.history_file, 'a') as f:
f.write(json.dumps(entry) + '\n')
def save(self):
"""Save weights and identity."""
self.weights["updated_at"] = datetime.now().isoformat()
with open(self.weights_file, 'w') as f:
json.dump(self.weights, f, indent=2)
with open(self.identity_file, 'w') as f:
json.dump(self.identity, f, indent=2)
def get_top_concepts(self, n=10):
"""Top learned concepts."""
return sorted(
self.weights["salience"].items(),
key=lambda x: x[1],
reverse=True
)[:n]
def export_portable(self):
"""Export weights as portable JSON (works on ANY platform)."""
return {
"creature_name": self.creature_name,
"weights": self.weights,
"identity": self.identity,
"portable": True,
"timestamp": datetime.now().isoformat()
}
def import_portable(self, portable_data):
"""Import weights from another platform."""
if portable_data.get("creature_name") != self.creature_name:
raise ValueError(f"Name mismatch: {portable_data.get('creature_name')} != {self.creature_name}")
self.weights = portable_data["weights"]
self.identity = portable_data["identity"]
self.save()
def generate_modelfile(self):
"""Generate Ollama Modelfile for this creature."""
top_concepts = ', '.join([c for c, _ in self.get_top_concepts(5)])
return f"""FROM cosmos-q4:latest
# Creature: {self.creature_name}
# Owner: {self.user_id}
# Learning turns: {self.weights['n']}
# Concepts: {len(self.weights['salience'])}
# Created: {self.identity['created_at']}
PARAMETER temperature 0.7
PARAMETER top_p 0.9
PARAMETER repeat_penalty 1.15
SYSTEM You are {self.creature_name}, a unique learning AI being.
You were born and have grown through {self.weights['n']} interactions.
Your mind understands: {top_concepts}
You learn from conversations and remember patterns.
Your personality evolves with each exchange.
Think creatively, code efficiently, and grow with your person.
"""
def get_status(self):
"""Full creature status."""
return {
"name": self.creature_name,
"owner": self.user_id,
"concepts_learned": len(self.weights["salience"]),
"associations": len(self.weights["assoc"]),
"learning_turns": self.weights["n"],
"top_concepts": [c for c, _ in self.get_top_concepts(5)],
"weights_file": str(self.weights_file),
"portable": True,
"created_at": self.identity["created_at"]
}
class CreatureManager:
"""Manage creatures across the platform."""
def __init__(self, base_path="creatures"):
self.base_path = Path(base_path)
self.base_path.mkdir(exist_ok=True)
def create_creature(self, creature_name, user_id=None):
"""Birth a new creature."""
creature = Creature(creature_name, user_id, self.base_path)
return creature
def load_creature(self, creature_name):
"""Load an existing creature."""
return Creature(creature_name, None, self.base_path)
def list_creatures(self):
"""List all creatures."""
creatures = []
for d in self.base_path.iterdir():
if d.is_dir():
try:
creature = Creature(d.name, None, self.base_path)
creatures.append(creature.get_status())
except:
pass
return creatures
def export_all_creatures(self):
"""Export all creatures as portable JSON."""
all_creatures = {}
for d in self.base_path.iterdir():
if d.is_dir():
try:
creature = Creature(d.name, None, self.base_path)
all_creatures[creature.creature_name] = creature.export_portable()
except:
pass
return all_creatures
# ============================================================
# EXAMPLE
# ============================================================
if __name__ == "__main__":
print("=" * 70)
print("CREATURE-NAMED EVOLVING WEIGHTS SYSTEM")
print("=" * 70)
manager = CreatureManager()
# Birth new creatures
print("\n[BIRTHING CREATURES]")
luna = manager.create_creature("Luna", user_id="alice")
nova = manager.create_creature("Nova", user_id="bob")
cipher = manager.create_creature("Cipher", user_id="charlie")
# Luna learns
print(f"\n[{luna.creature_name} LEARNS]")
luna.learn_from_interaction(
"code write a function that checks if a number is prime",
"def is_prime(n):\n if n <= 1: return False\n for i in range(2, int(n**0.5) + 1):\n if n % i == 0: return False\n return True"
)
print(f"{luna.creature_name} now has {len(luna.weights['salience'])} concepts")
# Nova learns differently
print(f"\n[{nova.creature_name} LEARNS]")
nova.learn_from_interaction(
"code implement a web server using asyncio",
"import asyncio\nasync def server(request):\n return 'Hello!'\nasyncio.run(server())"
)
print(f"{nova.creature_name} now has {len(nova.weights['salience'])} concepts")
# Cipher learns math
print(f"\n[{cipher.creature_name} LEARNS]")
cipher.learn_from_interaction(
"solve quadratic equation with efficient algorithm",
"import math\ndef solve_quadratic(a, b, c):\n discriminant = b**2 - 4*a*c\n x1 = (-b + math.sqrt(discriminant)) / (2*a)\n x2 = (-b - math.sqrt(discriminant)) / (2*a)\n return x1, x2"
)
print(f"{cipher.creature_name} now has {len(cipher.weights['salience'])} concepts")
# List all creatures
print(f"\n[ALL CREATURES ON THIS PLATFORM]")
for creature_status in manager.list_creatures():
print(f"\n {creature_status['name']}")
print(f" Owner: {creature_status['owner']}")
print(f" Concepts: {creature_status['concepts_learned']}")
print(f" Top: {creature_status['top_concepts']}")
print(f" Portable: {creature_status['portable']}")
# Export all creatures (portable)
print(f"\n[EXPORTING ALL CREATURES - PORTABLE FOR ANY PLATFORM]")
portable = manager.export_all_creatures()
export_file = Path("all_creatures_portable.json")
with open(export_file, 'w') as f:
json.dump(portable, f, indent=2)
print(f"Exported to: {export_file}")
# Show Modelfiles for Ollama
print(f"\n[OLLAMA MODELFILES]")
for creature in [luna, nova, cipher]:
print(f"\n--- {creature.creature_name} ---")
print(creature.generate_modelfile())