@@ -348,15 +348,18 @@ class ContextTurn:
348348
349349
350350class Context (abc .ABC ):
351- """A `Context` is used to track the state of a `MelleaSession`."""
351+ """A `Context` is used to track the state of a `MelleaSession`.
352+
353+ A context is immutable. Every alteration leads to a new context.
354+ """
352355
353356 _previous : Context | None
354357 _data : Component | CBlock | None
355358 _is_root : bool
356359 _is_chat_context : bool = True
357360
358361 def __init__ (self ):
359- """Constructs a new context."""
362+ """Constructs a new root context with no content ."""
360363 self ._previous = None
361364 self ._data = None
362365 self ._is_root = True
@@ -403,18 +406,24 @@ def data(self) -> Component | CBlock | None:
403406 """Returns the data associated with this context."""
404407 return self ._data
405408
406- def full_data_as_list (self ) -> list [Component | CBlock ]:
407- """Returns a list of all components in the context from root to current context."""
409+ def as_list (self , last_n_components : int | None = None ) -> list [Component | CBlock ]:
410+ """Returns a list of the last n components in the context sorted from FIRST TO LAST.
411+
412+ If `last_n_elements` is `None`, then all components are returned."""
408413 context_list : list [Component | CBlock ] = []
409414 current_context : Context = self
410415
411- while not current_context .is_root :
416+ last_n_count = 0
417+ while not current_context .is_root and (
418+ last_n_components is None or last_n_count < last_n_components
419+ ):
412420 data = current_context .data
413421 assert data is not None , "Data cannot be None (except for root context)."
414422 assert data not in context_list , (
415423 "There might be a cycle in the context tree. That is not allowed."
416424 )
417425 context_list .append (data )
426+ last_n_count += 1
418427
419428 current_context = current_context .previous # type: ignore
420429 assert current_context is not None , (
@@ -429,20 +438,20 @@ def actions_for_available_tools(self) -> list[Component | CBlock] | None:
429438
430439 Can be used to make the available tools differ from the tools of all the actions in the context. Can be overwritten by subclasses.
431440 """
432- return self .render_for_generation ()
441+ return self .view_for_generation ()
433442
434443 def last_output (self ) -> ModelOutputThunk | None :
435444 """The last output thunk of the context."""
436445
437- for c in self .full_data_as_list ()[::- 1 ]:
446+ for c in self .as_list ()[::- 1 ]:
438447 if isinstance (c , ModelOutputThunk ):
439448 return c
440449 return None
441450
442451 def last_turn (self ):
443452 """The last input/output turn of the context."""
444453
445- history = self .full_data_as_list ()
454+ history = self .as_list ()
446455
447456 if len (history ) == 0 :
448457 return None
@@ -467,7 +476,7 @@ def add(self, c: Component | CBlock) -> Context:
467476 ...
468477
469478 @abc .abstractmethod
470- def render_for_generation (self ) -> list [Component | CBlock ] | None :
479+ def view_for_generation (self ) -> list [Component | CBlock ] | None :
471480 """Provides a linear list of context components to use for generation, or None if that is not possible to construct."""
472481 ...
473482
@@ -480,26 +489,22 @@ def __init__(self, *, window_size: int | None = None):
480489 super ().__init__ ()
481490 self ._window_size = window_size
482491
483- def render_for_generation (self ) -> list [Component | CBlock ] | None :
484- all_events = self .full_data_as_list ()
485- ws = self ._window_size
486- ws = ws if ws is not None else len (all_events )
487-
488- return all_events [- ws :]
489-
490492 def add (self , c : Component | CBlock ) -> ChatContext :
491493 new = ChatContext .from_previous (self , c )
492494 new ._window_size = self ._window_size
493495 return new
494496
497+ def view_for_generation (self ) -> list [Component | CBlock ] | None :
498+ return self .as_list (self ._window_size )
499+
495500
496501class SimpleContext (Context ):
497502 """A `SimpleContext` is a context in which each interaction is a separate and independent turn. The history of all previous turns is NOT saved.."""
498503
499504 def add (self , c : Component | CBlock ) -> SimpleContext :
500505 return SimpleContext .from_previous (self , c )
501506
502- def render_for_generation (self ) -> list [Component | CBlock ] | None :
507+ def view_for_generation (self ) -> list [Component | CBlock ] | None :
503508 return []
504509
505510
0 commit comments