Skip to content

interlens.stop.conditions

interlens.stop.conditions

ElapsedTimeStopCondition

ElapsedTimeStopCondition(seconds: float)

Bases: StopCondition

Stop once seconds of wall-clock have elapsed since the run started (monotonic clock).

Source code in src/interlens/stop/conditions.py
def __init__(self, seconds: float):
	self.seconds = seconds
	self.start = None

StopStringCondition

StopStringCondition(strings)

Bases: StopCondition

Stop when a committed message's visible content contains any of the given strings (a done-signal).

Source code in src/interlens/stop/conditions.py
def __init__(self, strings):
	self.strings = [strings] if isinstance(strings, str) else list(strings)

TokenBudget

TokenBudget(
    per_conversation: int | None = None,
    per_turn: int | None = None,
)

Bases: StopCondition

A per-conversation compute budget — the matched-compute primitive for fair solo-vs-pair comparisons.

per_conversation stops a conversation once ITS OWN cumulative generated tokens reach the budget, and per_turn caps each individual turn so the allowance is spread across real conversation turns rather than consumed by one monologue. Both are enforced via turn_cap too: the run loop shrinks the next generation to min(speaker cap, per_turn, per_conversation - spent), so the budget is respected without overshoot.

The budget is per-conversation, not a shared pool. Spend is read from the conversation's own transcript (metadata['n_tokens']), so the condition is stateless — in a rollout of N copies, each copy independently gets the full budget. Cheap to count (never re-tokenizes) and trivially picklable, so it works installed directly (run_until=TokenBudget(...)) or ambiently (with TokenBudget(per_conversation=200): conv.rollout()).

Source code in src/interlens/stop/conditions.py
def __init__(self, per_conversation: int | None = None, per_turn: int | None = None):
	if per_conversation is None and per_turn is None:
		raise ValueError("TokenBudget needs at least one of per_conversation= or per_turn=")
	self.per_conversation = per_conversation
	self.per_turn = per_turn

TokenStopCondition

TokenStopCondition(max_tokens: int)

Bases: StopCondition

Stop once the total generated tokens across turns reach max_tokens.

The per-turn count comes from Message.metadata['n_tokens'], which ModelParticipant.generate records — so the source of truth is defined, not guessed. Turns without a count (e.g. seeded messages) contribute 0.

Source code in src/interlens/stop/conditions.py
def __init__(self, max_tokens: int):
	self.max_tokens = max_tokens
	self.total = 0

TurnStopCondition

TurnStopCondition(max_turns: int)

Bases: StopCondition

Stop after max_turns committed turns.

Source code in src/interlens/stop/conditions.py
def __init__(self, max_turns: int):
	self.max_turns = max_turns
	self.count = 0