heaven_base.memory.heaven_history

  1import sys
  2import uuid
  3import json
  4import os
  5import re
  6from datetime import datetime
  7from typing import List, Optional, Dict, Any, Union, Literal
  8from langchain_core.messages import (
  9    BaseMessage, 
 10    SystemMessage, 
 11    HumanMessage, 
 12    AIMessage, 
 13    ToolMessage
 14)
 15from pydantic import BaseModel, Field
 16from .base_piece import BasePiece
 17from .history import History, AgentStatus
 18from .heaven_event import HeavenEvent, is_heaven_event_dict, convert_langchain_to_heaven, convert_heaven_to_langchain
 19from ..utils.name_utils import normalize_agent_name
 20
 21# Define SystemPrompt class for HEAVEN events
 22class SystemPrompt(BaseModel):
 23    """Represents a system prompt in the HEAVEN system.
 24    
 25    System prompts provide instructions, context, and guidelines to agents.
 26    They influence the agent's behavior and responses.
 27    """
 28    content: str = ""
 29    metadata: Dict[str, Any] = Field(default_factory=dict)
 30    
 31    def to_langchain(self) -> SystemMessage:
 32        """Convert to LangChain SystemMessage."""
 33        return SystemMessage(content=self.content, additional_kwargs=self.metadata)
 34    
 35    @classmethod
 36    def from_langchain(cls, message: SystemMessage) -> 'SystemPrompt':
 37        """Create from LangChain SystemMessage."""
 38        return cls(
 39            content=message.content,
 40            metadata=message.additional_kwargs
 41        )
 42    
 43    def to_heaven_event(self) -> Dict[str, Any]:
 44        """Convert to HEAVEN event format."""
 45        return HeavenEvent(
 46            event_type="SYSTEM_MESSAGE",
 47            data={
 48                "content": self.content,
 49                "metadata": self.metadata
 50            }
 51        ).to_dict()
 52    
 53    @classmethod
 54    def from_heaven_event(cls, event: Dict[str, Any]) -> Optional['SystemPrompt']:
 55        """Create from HEAVEN event."""
 56        if not is_heaven_event_dict(event) or event.get("event_type") != "SYSTEM_MESSAGE":
 57            return None
 58        
 59        data = event.get("data", {})
 60        return cls(
 61            content=data.get("content", ""),
 62            metadata=data.get("metadata", {})
 63        )
 64
 65class HeavenHistory(History):
 66    """Enhanced History class that supports both LangChain messages and HEAVEN events"""
 67    # We keep the original messages field for backward compatibility
 68    messages: List[BaseMessage]
 69    # Add a new field for HEAVEN events
 70    heaven_events: List[Dict[str, Any]] = Field(default_factory=list)
 71    # Add a field for system prompts
 72    system_prompts: List[SystemPrompt] = Field(default_factory=list)
 73    # Flag to track the primary storage format
 74    primary_format: Literal["langchain", "heaven"] = "langchain"
 75    
 76    def __init__(self, **data):
 77        super().__init__(**data)
 78        # Initialize heaven_events if not provided
 79        if not hasattr(self, "heaven_events") or not self.heaven_events:
 80            # Convert existing messages to HEAVEN events
 81            self.heaven_events = convert_langchain_to_heaven(self.messages)
 82        
 83        # Initialize system_prompts if not provided
 84        if not hasattr(self, "system_prompts") or not self.system_prompts:
 85            # Extract system messages and convert to SystemPrompt objects
 86            system_messages = [msg for msg in self.messages if isinstance(msg, SystemMessage)]
 87            self.system_prompts = [SystemPrompt.from_langchain(msg) for msg in system_messages]
 88    
 89    def add_message(self, message: BaseMessage) -> None:
 90        """Add a LangChain message to the history."""
 91        self.messages.append(message)
 92        
 93        # Also add as HEAVEN event
 94        heaven_event = HeavenEvent.from_langchain_message(message).to_dict()
 95        self.heaven_events.append(heaven_event)
 96        
 97        # If it's a system message, also add to system_prompts
 98        if isinstance(message, SystemMessage):
 99            system_prompt = SystemPrompt.from_langchain(message)
100            self.system_prompts.append(system_prompt)
101    
102    def add_heaven_event(self, event: Union[Dict[str, Any], HeavenEvent]) -> None:
103        """Add a HEAVEN event to the history."""
104        # Convert to dict if it's a HeavenEvent object
105        if isinstance(event, HeavenEvent):
106            event_dict = event.to_dict()
107        else:
108            event_dict = event
109        
110        # Add to heaven_events
111        self.heaven_events.append(event_dict)
112        
113        # Check if it's a system message event
114        if is_heaven_event_dict(event_dict) and event_dict.get("event_type") == "SYSTEM_MESSAGE":
115            # Create a SystemPrompt from the event
116            system_prompt = SystemPrompt.from_heaven_event(event_dict)
117            if system_prompt:
118                self.system_prompts.append(system_prompt)
119        
120        # Convert to LangChain message if possible and add to messages
121        if is_heaven_event_dict(event_dict):
122            heaven_event = HeavenEvent.from_dict(event_dict)
123            message = heaven_event.to_langchain_message()
124            if message:
125                self.messages.append(message)
126    
127    def get_heaven_events(self) -> List[Dict[str, Any]]:
128        """Get all HEAVEN events in the history."""
129        return self.heaven_events
130    
131    def get_langchain_messages(self) -> List[BaseMessage]:
132        """Get all LangChain messages in the history."""
133        return self.messages
134    
135    def get_system_prompts(self) -> List[SystemPrompt]:
136        """Get all system prompts in the history."""
137        return self.system_prompts
138    
139    def get_combined_system_prompt(self) -> str:
140        """Get all system prompts combined into a single string."""
141        return "\n\n".join([sp.content for sp in self.system_prompts if sp.content])
142    
143    def add_system_prompt(self, content: str, metadata: Optional[Dict[str, Any]] = None) -> None:
144        """Add a system prompt to the history."""
145        # Create SystemPrompt object
146        system_prompt = SystemPrompt(content=content, metadata=metadata or {})
147        self.system_prompts.append(system_prompt)
148        
149        # Add as LangChain message
150        self.messages.append(system_prompt.to_langchain())
151        
152        # Add as HEAVEN event
153        self.heaven_events.append(system_prompt.to_heaven_event())
154    
155    def to_json(self) -> dict:
156        """Convert to JSON format with added HEAVEN events and system prompts."""
157        base_json = super().to_json()
158        base_json["heaven_events"] = self.heaven_events
159        base_json["primary_format"] = self.primary_format
160        base_json["system_prompts"] = [sp.dict() for sp in self.system_prompts]
161        return base_json
162    
163    @classmethod
164    def from_json(cls, data: dict, project: str = None) -> "HeavenHistory":
165        """Create HeavenHistory from JSON."""
166        # First create a standard History object
167        history = super().from_json(data, project)
168        
169        # Extract heaven_events if present
170        heaven_events = data.get("heaven_events", [])
171        primary_format = data.get("primary_format", "langchain")
172        
173        # Extract system_prompts if present
174        system_prompts_data = data.get("system_prompts", [])
175        system_prompts = [SystemPrompt(**sp_data) for sp_data in system_prompts_data]
176        
177        # Create and return a HeavenHistory
178        return cls(
179            messages=history.messages,
180            created_datetime=history.created_datetime,
181            metadata=history.metadata,
182            project=history.project,
183            agent_status=history.agent_status,
184            history_id=history.history_id,
185            json_md_path=history.json_md_path,
186            heaven_events=heaven_events,
187            primary_format=primary_format,
188            system_prompts=system_prompts
189        )
190    
191    @classmethod
192    def from_history(cls, history: History) -> "HeavenHistory":
193        """Convert a standard History to HeavenHistory."""
194        # Convert messages to HEAVEN events
195        heaven_events = convert_langchain_to_heaven(history.messages)
196        
197        # Extract system messages
198        system_messages = [msg for msg in history.messages if isinstance(msg, SystemMessage)]
199        system_prompts = [SystemPrompt.from_langchain(msg) for msg in system_messages]
200        
201        # Create and return a HeavenHistory
202        return cls(
203            messages=history.messages,
204            created_datetime=history.created_datetime,
205            metadata=history.metadata,
206            project=history.project,
207            agent_status=history.agent_status,
208            history_id=history.history_id,
209            json_md_path=history.json_md_path,
210            heaven_events=heaven_events,
211            system_prompts=system_prompts,
212            primary_format="langchain"
213        )
214    
215    @classmethod
216    def from_heaven_events(cls, events: List[Dict[str, Any]], metadata: Dict[str, Any] = None) -> "HeavenHistory":
217        """Create a HeavenHistory from a list of HEAVEN events."""
218        # Convert HEAVEN events to LangChain messages
219        messages = convert_heaven_to_langchain(events)
220        
221        # Extract system message events
222        system_events = [event for event in events 
223                        if is_heaven_event_dict(event) and event.get("event_type") == "SYSTEM_MESSAGE"]
224        system_prompts = [SystemPrompt.from_heaven_event(event) for event in system_events 
225                         if SystemPrompt.from_heaven_event(event) is not None]
226        
227        # Create and return a HeavenHistory
228        return cls(
229            messages=messages,
230            created_datetime=datetime.now(),
231            metadata=metadata or {},
232            heaven_events=events,
233            system_prompts=system_prompts,
234            primary_format="heaven"
235        )
236    
237    def _compute_heaven_iterations(self) -> Dict[str, List[Dict[str, Any]]]:
238        """Split heaven_events into iterations."""
239        iterations: Dict[str, List[Dict[str, Any]]] = {}
240        current: List[Dict[str, Any]] = []
241        idx = 0
242        
243        for event in self.heaven_events:
244            if is_heaven_event_dict(event) and event.get("event_type") == "USER_MESSAGE":
245                if current:
246                    iterations[f"iteration_{idx}"] = current
247                    idx += 1
248                    current = []
249            else:
250                current.append(event)
251        
252        if current:
253            iterations[f"iteration_{idx}"] = current
254        
255        return iterations
256    
257    @property
258    def heaven_iterations(self) -> Dict[str, List[Dict[str, Any]]]:
259        """Returns a dict of all iterations in HEAVEN event format."""
260        return self._compute_heaven_iterations()
261
262
263def get_heaven_iteration_view(
264    history: HeavenHistory,
265    start: int,
266    end: int
267) -> Dict[str, Any]:
268    """Get a view of iterations in HEAVEN event format."""
269    if start > end:
270        raise ValueError(f"start ({start}) must be <= end ({end})")
271    
272    all_iters = history.heaven_iterations
273    total = len(all_iters)
274    
275    # Build the view
276    view: Dict[str, List[Dict[str, Any]]] = {}
277    for i in range(start, end + 1):
278        key = f"iteration_{i}"
279        if key not in all_iters:
280            raise KeyError(f"Missing iteration: {key}")
281        view[key] = all_iters[key]
282    
283    return {
284        "history_id": history.history_id,
285        "total_iterations": total,
286        "view_range": {"start": start, "end": end},
287        "view": view
288    }
class SystemPrompt(pydantic.main.BaseModel):
23class SystemPrompt(BaseModel):
24    """Represents a system prompt in the HEAVEN system.
25    
26    System prompts provide instructions, context, and guidelines to agents.
27    They influence the agent's behavior and responses.
28    """
29    content: str = ""
30    metadata: Dict[str, Any] = Field(default_factory=dict)
31    
32    def to_langchain(self) -> SystemMessage:
33        """Convert to LangChain SystemMessage."""
34        return SystemMessage(content=self.content, additional_kwargs=self.metadata)
35    
36    @classmethod
37    def from_langchain(cls, message: SystemMessage) -> 'SystemPrompt':
38        """Create from LangChain SystemMessage."""
39        return cls(
40            content=message.content,
41            metadata=message.additional_kwargs
42        )
43    
44    def to_heaven_event(self) -> Dict[str, Any]:
45        """Convert to HEAVEN event format."""
46        return HeavenEvent(
47            event_type="SYSTEM_MESSAGE",
48            data={
49                "content": self.content,
50                "metadata": self.metadata
51            }
52        ).to_dict()
53    
54    @classmethod
55    def from_heaven_event(cls, event: Dict[str, Any]) -> Optional['SystemPrompt']:
56        """Create from HEAVEN event."""
57        if not is_heaven_event_dict(event) or event.get("event_type") != "SYSTEM_MESSAGE":
58            return None
59        
60        data = event.get("data", {})
61        return cls(
62            content=data.get("content", ""),
63            metadata=data.get("metadata", {})
64        )

Represents a system prompt in the HEAVEN system.

System prompts provide instructions, context, and guidelines to agents. They influence the agent's behavior and responses.

content: str = ''
metadata: Dict[str, Any] = PydanticUndefined
def to_langchain(self) -> langchain_core.messages.system.SystemMessage:
32    def to_langchain(self) -> SystemMessage:
33        """Convert to LangChain SystemMessage."""
34        return SystemMessage(content=self.content, additional_kwargs=self.metadata)

Convert to LangChain SystemMessage.

@classmethod
def from_langchain( cls, message: langchain_core.messages.system.SystemMessage) -> SystemPrompt:
36    @classmethod
37    def from_langchain(cls, message: SystemMessage) -> 'SystemPrompt':
38        """Create from LangChain SystemMessage."""
39        return cls(
40            content=message.content,
41            metadata=message.additional_kwargs
42        )

Create from LangChain SystemMessage.

def to_heaven_event(self) -> Dict[str, Any]:
44    def to_heaven_event(self) -> Dict[str, Any]:
45        """Convert to HEAVEN event format."""
46        return HeavenEvent(
47            event_type="SYSTEM_MESSAGE",
48            data={
49                "content": self.content,
50                "metadata": self.metadata
51            }
52        ).to_dict()

Convert to HEAVEN event format.

@classmethod
def from_heaven_event( cls, event: Dict[str, Any]) -> Optional[SystemPrompt]:
54    @classmethod
55    def from_heaven_event(cls, event: Dict[str, Any]) -> Optional['SystemPrompt']:
56        """Create from HEAVEN event."""
57        if not is_heaven_event_dict(event) or event.get("event_type") != "SYSTEM_MESSAGE":
58            return None
59        
60        data = event.get("data", {})
61        return cls(
62            content=data.get("content", ""),
63            metadata=data.get("metadata", {})
64        )

Create from HEAVEN event.

class HeavenHistory(heaven_base.memory.history.History):
 66class HeavenHistory(History):
 67    """Enhanced History class that supports both LangChain messages and HEAVEN events"""
 68    # We keep the original messages field for backward compatibility
 69    messages: List[BaseMessage]
 70    # Add a new field for HEAVEN events
 71    heaven_events: List[Dict[str, Any]] = Field(default_factory=list)
 72    # Add a field for system prompts
 73    system_prompts: List[SystemPrompt] = Field(default_factory=list)
 74    # Flag to track the primary storage format
 75    primary_format: Literal["langchain", "heaven"] = "langchain"
 76    
 77    def __init__(self, **data):
 78        super().__init__(**data)
 79        # Initialize heaven_events if not provided
 80        if not hasattr(self, "heaven_events") or not self.heaven_events:
 81            # Convert existing messages to HEAVEN events
 82            self.heaven_events = convert_langchain_to_heaven(self.messages)
 83        
 84        # Initialize system_prompts if not provided
 85        if not hasattr(self, "system_prompts") or not self.system_prompts:
 86            # Extract system messages and convert to SystemPrompt objects
 87            system_messages = [msg for msg in self.messages if isinstance(msg, SystemMessage)]
 88            self.system_prompts = [SystemPrompt.from_langchain(msg) for msg in system_messages]
 89    
 90    def add_message(self, message: BaseMessage) -> None:
 91        """Add a LangChain message to the history."""
 92        self.messages.append(message)
 93        
 94        # Also add as HEAVEN event
 95        heaven_event = HeavenEvent.from_langchain_message(message).to_dict()
 96        self.heaven_events.append(heaven_event)
 97        
 98        # If it's a system message, also add to system_prompts
 99        if isinstance(message, SystemMessage):
100            system_prompt = SystemPrompt.from_langchain(message)
101            self.system_prompts.append(system_prompt)
102    
103    def add_heaven_event(self, event: Union[Dict[str, Any], HeavenEvent]) -> None:
104        """Add a HEAVEN event to the history."""
105        # Convert to dict if it's a HeavenEvent object
106        if isinstance(event, HeavenEvent):
107            event_dict = event.to_dict()
108        else:
109            event_dict = event
110        
111        # Add to heaven_events
112        self.heaven_events.append(event_dict)
113        
114        # Check if it's a system message event
115        if is_heaven_event_dict(event_dict) and event_dict.get("event_type") == "SYSTEM_MESSAGE":
116            # Create a SystemPrompt from the event
117            system_prompt = SystemPrompt.from_heaven_event(event_dict)
118            if system_prompt:
119                self.system_prompts.append(system_prompt)
120        
121        # Convert to LangChain message if possible and add to messages
122        if is_heaven_event_dict(event_dict):
123            heaven_event = HeavenEvent.from_dict(event_dict)
124            message = heaven_event.to_langchain_message()
125            if message:
126                self.messages.append(message)
127    
128    def get_heaven_events(self) -> List[Dict[str, Any]]:
129        """Get all HEAVEN events in the history."""
130        return self.heaven_events
131    
132    def get_langchain_messages(self) -> List[BaseMessage]:
133        """Get all LangChain messages in the history."""
134        return self.messages
135    
136    def get_system_prompts(self) -> List[SystemPrompt]:
137        """Get all system prompts in the history."""
138        return self.system_prompts
139    
140    def get_combined_system_prompt(self) -> str:
141        """Get all system prompts combined into a single string."""
142        return "\n\n".join([sp.content for sp in self.system_prompts if sp.content])
143    
144    def add_system_prompt(self, content: str, metadata: Optional[Dict[str, Any]] = None) -> None:
145        """Add a system prompt to the history."""
146        # Create SystemPrompt object
147        system_prompt = SystemPrompt(content=content, metadata=metadata or {})
148        self.system_prompts.append(system_prompt)
149        
150        # Add as LangChain message
151        self.messages.append(system_prompt.to_langchain())
152        
153        # Add as HEAVEN event
154        self.heaven_events.append(system_prompt.to_heaven_event())
155    
156    def to_json(self) -> dict:
157        """Convert to JSON format with added HEAVEN events and system prompts."""
158        base_json = super().to_json()
159        base_json["heaven_events"] = self.heaven_events
160        base_json["primary_format"] = self.primary_format
161        base_json["system_prompts"] = [sp.dict() for sp in self.system_prompts]
162        return base_json
163    
164    @classmethod
165    def from_json(cls, data: dict, project: str = None) -> "HeavenHistory":
166        """Create HeavenHistory from JSON."""
167        # First create a standard History object
168        history = super().from_json(data, project)
169        
170        # Extract heaven_events if present
171        heaven_events = data.get("heaven_events", [])
172        primary_format = data.get("primary_format", "langchain")
173        
174        # Extract system_prompts if present
175        system_prompts_data = data.get("system_prompts", [])
176        system_prompts = [SystemPrompt(**sp_data) for sp_data in system_prompts_data]
177        
178        # Create and return a HeavenHistory
179        return cls(
180            messages=history.messages,
181            created_datetime=history.created_datetime,
182            metadata=history.metadata,
183            project=history.project,
184            agent_status=history.agent_status,
185            history_id=history.history_id,
186            json_md_path=history.json_md_path,
187            heaven_events=heaven_events,
188            primary_format=primary_format,
189            system_prompts=system_prompts
190        )
191    
192    @classmethod
193    def from_history(cls, history: History) -> "HeavenHistory":
194        """Convert a standard History to HeavenHistory."""
195        # Convert messages to HEAVEN events
196        heaven_events = convert_langchain_to_heaven(history.messages)
197        
198        # Extract system messages
199        system_messages = [msg for msg in history.messages if isinstance(msg, SystemMessage)]
200        system_prompts = [SystemPrompt.from_langchain(msg) for msg in system_messages]
201        
202        # Create and return a HeavenHistory
203        return cls(
204            messages=history.messages,
205            created_datetime=history.created_datetime,
206            metadata=history.metadata,
207            project=history.project,
208            agent_status=history.agent_status,
209            history_id=history.history_id,
210            json_md_path=history.json_md_path,
211            heaven_events=heaven_events,
212            system_prompts=system_prompts,
213            primary_format="langchain"
214        )
215    
216    @classmethod
217    def from_heaven_events(cls, events: List[Dict[str, Any]], metadata: Dict[str, Any] = None) -> "HeavenHistory":
218        """Create a HeavenHistory from a list of HEAVEN events."""
219        # Convert HEAVEN events to LangChain messages
220        messages = convert_heaven_to_langchain(events)
221        
222        # Extract system message events
223        system_events = [event for event in events 
224                        if is_heaven_event_dict(event) and event.get("event_type") == "SYSTEM_MESSAGE"]
225        system_prompts = [SystemPrompt.from_heaven_event(event) for event in system_events 
226                         if SystemPrompt.from_heaven_event(event) is not None]
227        
228        # Create and return a HeavenHistory
229        return cls(
230            messages=messages,
231            created_datetime=datetime.now(),
232            metadata=metadata or {},
233            heaven_events=events,
234            system_prompts=system_prompts,
235            primary_format="heaven"
236        )
237    
238    def _compute_heaven_iterations(self) -> Dict[str, List[Dict[str, Any]]]:
239        """Split heaven_events into iterations."""
240        iterations: Dict[str, List[Dict[str, Any]]] = {}
241        current: List[Dict[str, Any]] = []
242        idx = 0
243        
244        for event in self.heaven_events:
245            if is_heaven_event_dict(event) and event.get("event_type") == "USER_MESSAGE":
246                if current:
247                    iterations[f"iteration_{idx}"] = current
248                    idx += 1
249                    current = []
250            else:
251                current.append(event)
252        
253        if current:
254            iterations[f"iteration_{idx}"] = current
255        
256        return iterations
257    
258    @property
259    def heaven_iterations(self) -> Dict[str, List[Dict[str, Any]]]:
260        """Returns a dict of all iterations in HEAVEN event format."""
261        return self._compute_heaven_iterations()

Enhanced History class that supports both LangChain messages and HEAVEN events

messages: List[langchain_core.messages.base.BaseMessage] = PydanticUndefined
heaven_events: List[Dict[str, Any]] = PydanticUndefined
system_prompts: List[SystemPrompt] = PydanticUndefined
primary_format: Literal['langchain', 'heaven'] = 'langchain'
def add_message(self, message: langchain_core.messages.base.BaseMessage) -> None:
 90    def add_message(self, message: BaseMessage) -> None:
 91        """Add a LangChain message to the history."""
 92        self.messages.append(message)
 93        
 94        # Also add as HEAVEN event
 95        heaven_event = HeavenEvent.from_langchain_message(message).to_dict()
 96        self.heaven_events.append(heaven_event)
 97        
 98        # If it's a system message, also add to system_prompts
 99        if isinstance(message, SystemMessage):
100            system_prompt = SystemPrompt.from_langchain(message)
101            self.system_prompts.append(system_prompt)

Add a LangChain message to the history.

def add_heaven_event( self, event: Union[Dict[str, Any], heaven_base.memory.heaven_event.HeavenEvent]) -> None:
103    def add_heaven_event(self, event: Union[Dict[str, Any], HeavenEvent]) -> None:
104        """Add a HEAVEN event to the history."""
105        # Convert to dict if it's a HeavenEvent object
106        if isinstance(event, HeavenEvent):
107            event_dict = event.to_dict()
108        else:
109            event_dict = event
110        
111        # Add to heaven_events
112        self.heaven_events.append(event_dict)
113        
114        # Check if it's a system message event
115        if is_heaven_event_dict(event_dict) and event_dict.get("event_type") == "SYSTEM_MESSAGE":
116            # Create a SystemPrompt from the event
117            system_prompt = SystemPrompt.from_heaven_event(event_dict)
118            if system_prompt:
119                self.system_prompts.append(system_prompt)
120        
121        # Convert to LangChain message if possible and add to messages
122        if is_heaven_event_dict(event_dict):
123            heaven_event = HeavenEvent.from_dict(event_dict)
124            message = heaven_event.to_langchain_message()
125            if message:
126                self.messages.append(message)

Add a HEAVEN event to the history.

def get_heaven_events(self) -> List[Dict[str, Any]]:
128    def get_heaven_events(self) -> List[Dict[str, Any]]:
129        """Get all HEAVEN events in the history."""
130        return self.heaven_events

Get all HEAVEN events in the history.

def get_langchain_messages(self) -> List[langchain_core.messages.base.BaseMessage]:
132    def get_langchain_messages(self) -> List[BaseMessage]:
133        """Get all LangChain messages in the history."""
134        return self.messages

Get all LangChain messages in the history.

def get_system_prompts(self) -> List[SystemPrompt]:
136    def get_system_prompts(self) -> List[SystemPrompt]:
137        """Get all system prompts in the history."""
138        return self.system_prompts

Get all system prompts in the history.

def get_combined_system_prompt(self) -> str:
140    def get_combined_system_prompt(self) -> str:
141        """Get all system prompts combined into a single string."""
142        return "\n\n".join([sp.content for sp in self.system_prompts if sp.content])

Get all system prompts combined into a single string.

def add_system_prompt(self, content: str, metadata: Optional[Dict[str, Any]] = None) -> None:
144    def add_system_prompt(self, content: str, metadata: Optional[Dict[str, Any]] = None) -> None:
145        """Add a system prompt to the history."""
146        # Create SystemPrompt object
147        system_prompt = SystemPrompt(content=content, metadata=metadata or {})
148        self.system_prompts.append(system_prompt)
149        
150        # Add as LangChain message
151        self.messages.append(system_prompt.to_langchain())
152        
153        # Add as HEAVEN event
154        self.heaven_events.append(system_prompt.to_heaven_event())

Add a system prompt to the history.

def to_json(self) -> dict:
156    def to_json(self) -> dict:
157        """Convert to JSON format with added HEAVEN events and system prompts."""
158        base_json = super().to_json()
159        base_json["heaven_events"] = self.heaven_events
160        base_json["primary_format"] = self.primary_format
161        base_json["system_prompts"] = [sp.dict() for sp in self.system_prompts]
162        return base_json

Convert to JSON format with added HEAVEN events and system prompts.

@classmethod
def from_json( cls, data: dict, project: str = None) -> HeavenHistory:
164    @classmethod
165    def from_json(cls, data: dict, project: str = None) -> "HeavenHistory":
166        """Create HeavenHistory from JSON."""
167        # First create a standard History object
168        history = super().from_json(data, project)
169        
170        # Extract heaven_events if present
171        heaven_events = data.get("heaven_events", [])
172        primary_format = data.get("primary_format", "langchain")
173        
174        # Extract system_prompts if present
175        system_prompts_data = data.get("system_prompts", [])
176        system_prompts = [SystemPrompt(**sp_data) for sp_data in system_prompts_data]
177        
178        # Create and return a HeavenHistory
179        return cls(
180            messages=history.messages,
181            created_datetime=history.created_datetime,
182            metadata=history.metadata,
183            project=history.project,
184            agent_status=history.agent_status,
185            history_id=history.history_id,
186            json_md_path=history.json_md_path,
187            heaven_events=heaven_events,
188            primary_format=primary_format,
189            system_prompts=system_prompts
190        )

Create HeavenHistory from JSON.

@classmethod
def from_history( cls, history: heaven_base.memory.history.History) -> HeavenHistory:
192    @classmethod
193    def from_history(cls, history: History) -> "HeavenHistory":
194        """Convert a standard History to HeavenHistory."""
195        # Convert messages to HEAVEN events
196        heaven_events = convert_langchain_to_heaven(history.messages)
197        
198        # Extract system messages
199        system_messages = [msg for msg in history.messages if isinstance(msg, SystemMessage)]
200        system_prompts = [SystemPrompt.from_langchain(msg) for msg in system_messages]
201        
202        # Create and return a HeavenHistory
203        return cls(
204            messages=history.messages,
205            created_datetime=history.created_datetime,
206            metadata=history.metadata,
207            project=history.project,
208            agent_status=history.agent_status,
209            history_id=history.history_id,
210            json_md_path=history.json_md_path,
211            heaven_events=heaven_events,
212            system_prompts=system_prompts,
213            primary_format="langchain"
214        )

Convert a standard History to HeavenHistory.

@classmethod
def from_heaven_events( cls, events: List[Dict[str, Any]], metadata: Dict[str, Any] = None) -> HeavenHistory:
216    @classmethod
217    def from_heaven_events(cls, events: List[Dict[str, Any]], metadata: Dict[str, Any] = None) -> "HeavenHistory":
218        """Create a HeavenHistory from a list of HEAVEN events."""
219        # Convert HEAVEN events to LangChain messages
220        messages = convert_heaven_to_langchain(events)
221        
222        # Extract system message events
223        system_events = [event for event in events 
224                        if is_heaven_event_dict(event) and event.get("event_type") == "SYSTEM_MESSAGE"]
225        system_prompts = [SystemPrompt.from_heaven_event(event) for event in system_events 
226                         if SystemPrompt.from_heaven_event(event) is not None]
227        
228        # Create and return a HeavenHistory
229        return cls(
230            messages=messages,
231            created_datetime=datetime.now(),
232            metadata=metadata or {},
233            heaven_events=events,
234            system_prompts=system_prompts,
235            primary_format="heaven"
236        )

Create a HeavenHistory from a list of HEAVEN events.

heaven_iterations: Dict[str, List[Dict[str, Any]]]
258    @property
259    def heaven_iterations(self) -> Dict[str, List[Dict[str, Any]]]:
260        """Returns a dict of all iterations in HEAVEN event format."""
261        return self._compute_heaven_iterations()

Returns a dict of all iterations in HEAVEN event format.

def get_heaven_iteration_view( history: HeavenHistory, start: int, end: int) -> Dict[str, Any]:
264def get_heaven_iteration_view(
265    history: HeavenHistory,
266    start: int,
267    end: int
268) -> Dict[str, Any]:
269    """Get a view of iterations in HEAVEN event format."""
270    if start > end:
271        raise ValueError(f"start ({start}) must be <= end ({end})")
272    
273    all_iters = history.heaven_iterations
274    total = len(all_iters)
275    
276    # Build the view
277    view: Dict[str, List[Dict[str, Any]]] = {}
278    for i in range(start, end + 1):
279        key = f"iteration_{i}"
280        if key not in all_iters:
281            raise KeyError(f"Missing iteration: {key}")
282        view[key] = all_iters[key]
283    
284    return {
285        "history_id": history.history_id,
286        "total_iterations": total,
287        "view_range": {"start": start, "end": end},
288        "view": view
289    }

Get a view of iterations in HEAVEN event format.