arkaos 2.1.0 → 2.1.1

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.
package/VERSION CHANGED
@@ -1 +1 @@
1
- 2.1.0
1
+ 2.1.1
@@ -0,0 +1,6 @@
1
+ """Persona system — create, store, and clone personas as agents."""
2
+
3
+ from core.personas.schema import Persona
4
+ from core.personas.manager import PersonaManager
5
+
6
+ __all__ = ["Persona", "PersonaManager"]
@@ -0,0 +1,102 @@
1
+ """Persona manager — CRUD operations and cloning to agents."""
2
+
3
+ import json
4
+ from datetime import datetime
5
+ from pathlib import Path
6
+ from typing import Optional
7
+
8
+ import yaml
9
+
10
+ from core.personas.schema import Persona
11
+
12
+
13
+ class PersonaManager:
14
+ """Manages persona lifecycle: create, store, list, clone to agent."""
15
+
16
+ def __init__(self, storage_path: str | Path = "") -> None:
17
+ self._personas: dict[str, Persona] = {}
18
+ self._storage_path = Path(storage_path) if storage_path else None
19
+ if self._storage_path and self._storage_path.exists():
20
+ self._load()
21
+
22
+ def create(self, persona: Persona) -> Persona:
23
+ """Create a new persona."""
24
+ persona.created_at = datetime.now().isoformat()
25
+ persona.updated_at = persona.created_at
26
+ self._personas[persona.id] = persona
27
+ self._save()
28
+ return persona
29
+
30
+ def get(self, persona_id: str) -> Optional[Persona]:
31
+ return self._personas.get(persona_id)
32
+
33
+ def list_all(self) -> list[Persona]:
34
+ return list(self._personas.values())
35
+
36
+ def update(self, persona_id: str, updates: dict) -> Optional[Persona]:
37
+ persona = self._personas.get(persona_id)
38
+ if not persona:
39
+ return None
40
+ for key, value in updates.items():
41
+ if hasattr(persona, key):
42
+ setattr(persona, key, value)
43
+ persona.updated_at = datetime.now().isoformat()
44
+ self._save()
45
+ return persona
46
+
47
+ def delete(self, persona_id: str) -> bool:
48
+ if persona_id in self._personas:
49
+ del self._personas[persona_id]
50
+ self._save()
51
+ return True
52
+ return False
53
+
54
+ def clone_to_agent(
55
+ self,
56
+ persona_id: str,
57
+ department: str = "strategy",
58
+ tier: int = 2,
59
+ agents_dir: str | Path = "",
60
+ ) -> Optional[str]:
61
+ """Clone a persona to an ArkaOS agent YAML file.
62
+
63
+ Returns the agent ID if successful, None if persona not found.
64
+ """
65
+ persona = self._personas.get(persona_id)
66
+ if not persona:
67
+ return None
68
+
69
+ agent_data = persona.to_agent_yaml(department=department, tier=tier)
70
+ agent_id = agent_data["id"]
71
+
72
+ if agents_dir:
73
+ output_dir = Path(agents_dir)
74
+ output_dir.mkdir(parents=True, exist_ok=True)
75
+ output_path = output_dir / f"{agent_id}.yaml"
76
+ with open(output_path, "w") as f:
77
+ yaml.dump(agent_data, f, default_flow_style=False, allow_unicode=True, sort_keys=False)
78
+
79
+ # Track the clone
80
+ persona.cloned_to_agents.append(agent_id)
81
+ persona.updated_at = datetime.now().isoformat()
82
+ self._save()
83
+
84
+ return agent_id
85
+
86
+ def _save(self) -> None:
87
+ if self._storage_path is None:
88
+ return
89
+ self._storage_path.parent.mkdir(parents=True, exist_ok=True)
90
+ data = {pid: p.model_dump(mode="json") for pid, p in self._personas.items()}
91
+ with open(self._storage_path, "w") as f:
92
+ json.dump(data, f, indent=2)
93
+
94
+ def _load(self) -> None:
95
+ if self._storage_path is None or not self._storage_path.exists():
96
+ return
97
+ content = self._storage_path.read_text().strip()
98
+ if not content:
99
+ return
100
+ data = json.loads(content)
101
+ for pid, pdata in data.items():
102
+ self._personas[pid] = Persona.model_validate(pdata)
@@ -0,0 +1,127 @@
1
+ """Persona schema — models for persona creation and cloning."""
2
+
3
+ from datetime import datetime
4
+ from typing import Optional, Any
5
+
6
+ from pydantic import BaseModel, Field
7
+
8
+
9
+ class PersonaDISC(BaseModel):
10
+ primary: str = "C"
11
+ secondary: str = "S"
12
+ communication_style: str = ""
13
+ under_pressure: str = ""
14
+ motivator: str = ""
15
+
16
+
17
+ class PersonaEnneagram(BaseModel):
18
+ type: int = 5
19
+ wing: int = 6
20
+ core_motivation: str = ""
21
+ core_fear: str = ""
22
+ subtype: str = "self-preservation"
23
+
24
+
25
+ class PersonaBigFive(BaseModel):
26
+ openness: int = 50
27
+ conscientiousness: int = 50
28
+ extraversion: int = 50
29
+ agreeableness: int = 50
30
+ neuroticism: int = 50
31
+
32
+
33
+ class PersonaCommunication(BaseModel):
34
+ tone: str = ""
35
+ vocabulary_level: str = "specialist"
36
+ preferred_format: str = ""
37
+ avoid: list[str] = Field(default_factory=list)
38
+
39
+
40
+ class Persona(BaseModel):
41
+ """A persona based on a real person or archetype."""
42
+ id: str
43
+ name: str
44
+ title: str = "" # e.g., "Business Strategy", "Growth Marketing"
45
+ tagline: str = "" # e.g., "The Natural Commander with emotional depth"
46
+ source: str = "" # e.g., "Alex Hormozi", "Naval Ravikant"
47
+ avatar_url: str = ""
48
+
49
+ # Behavioral DNA
50
+ disc: PersonaDISC = Field(default_factory=PersonaDISC)
51
+ enneagram: PersonaEnneagram = Field(default_factory=PersonaEnneagram)
52
+ big_five: PersonaBigFive = Field(default_factory=PersonaBigFive)
53
+ mbti: str = "INTJ"
54
+
55
+ # Knowledge
56
+ mental_models: list[str] = Field(default_factory=list)
57
+ expertise_domains: list[str] = Field(default_factory=list)
58
+ frameworks: list[str] = Field(default_factory=list)
59
+ key_quotes: list[str] = Field(default_factory=list)
60
+
61
+ # Communication
62
+ communication: PersonaCommunication = Field(default_factory=PersonaCommunication)
63
+
64
+ # Metadata
65
+ created_at: str = ""
66
+ updated_at: str = ""
67
+ cloned_to_agents: list[str] = Field(default_factory=list)
68
+
69
+ def to_agent_yaml(self, department: str = "strategy", tier: int = 2) -> dict:
70
+ """Convert persona to an ArkaOS agent YAML structure."""
71
+ agent_id = f"persona-{self.id}"
72
+ return {
73
+ "id": agent_id,
74
+ "name": self.name,
75
+ "role": self.title or f"{self.source} Persona",
76
+ "department": department,
77
+ "tier": tier,
78
+ "behavioral_dna": {
79
+ "disc": {
80
+ "primary": self.disc.primary,
81
+ "secondary": self.disc.secondary,
82
+ "communication_style": self.disc.communication_style,
83
+ "under_pressure": self.disc.under_pressure,
84
+ "motivator": self.disc.motivator,
85
+ },
86
+ "enneagram": {
87
+ "type": self.enneagram.type,
88
+ "wing": self.enneagram.wing,
89
+ "core_motivation": self.enneagram.core_motivation,
90
+ "core_fear": self.enneagram.core_fear,
91
+ "subtype": self.enneagram.subtype,
92
+ },
93
+ "big_five": {
94
+ "openness": self.big_five.openness,
95
+ "conscientiousness": self.big_five.conscientiousness,
96
+ "extraversion": self.big_five.extraversion,
97
+ "agreeableness": self.big_five.agreeableness,
98
+ "neuroticism": self.big_five.neuroticism,
99
+ },
100
+ "mbti": {"type": self.mbti},
101
+ },
102
+ "mental_models": {
103
+ "primary": self.mental_models[:3],
104
+ "secondary": self.mental_models[3:6],
105
+ },
106
+ "authority": {
107
+ "veto": False,
108
+ "approve_budget": False,
109
+ "approve_architecture": False,
110
+ "orchestrate": False,
111
+ "delegates_to": [],
112
+ "escalates_to": None,
113
+ },
114
+ "expertise": {
115
+ "domains": self.expertise_domains[:5],
116
+ "frameworks": self.frameworks[:5],
117
+ "depth": "advanced",
118
+ "years_equivalent": 10,
119
+ },
120
+ "communication": {
121
+ "language": "en",
122
+ "tone": self.communication.tone,
123
+ "vocabulary_level": self.communication.vocabulary_level,
124
+ "preferred_format": self.communication.preferred_format,
125
+ "avoid": self.communication.avoid,
126
+ },
127
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "arkaos",
3
- "version": "2.1.0",
3
+ "version": "2.1.1",
4
4
  "description": "The Operating System for AI Agent Teams",
5
5
  "type": "module",
6
6
  "bin": {
package/pyproject.toml CHANGED
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "arkaos-core"
3
- version = "2.1.0"
3
+ version = "2.1.1"
4
4
  description = "Core engine for ArkaOS — The Operating System for AI Agent Teams"
5
5
  readme = "README.md"
6
6
  license = {text = "MIT"}