QueryEnginePort holds live in-memory state, TranscriptStore maintains an ordered entry log, and StoredSession serialises that state to disk between runs.
QueryEnginePort session fields
QueryEnginePort (in query_engine.py) is the stateful centre of a session:
QueryEnginePort.from_workspace(). An existing session is restored with QueryEnginePort.from_saved_session(session_id).
QueryEngineConfig
QueryEngineConfig controls turn-loop behaviour:
max_turns
max_turns
When
len(mutable_messages) >= max_turns, submit_message() returns immediately with stop_reason='max_turns_reached' without processing the prompt.max_budget_tokens
max_budget_tokens
After each turn, projected token usage is compared against this limit. If
input_tokens + output_tokens would exceed the budget, the turn is recorded but stop_reason is set to 'max_budget_reached'.compact_after_turns
compact_after_turns
When
mutable_messages grows beyond compact_after_turns, it is trimmed to the most recent compact_after_turns entries. The TranscriptStore is compacted by the same amount.structured_output
structured_output
When
True, submit_message() returns JSON instead of plain text. Failed serialisation is retried up to structured_retry_limit times before raising RuntimeError.TurnResult
Every call tosubmit_message() returns a TurnResult:
Stop reasons
| Value | Meaning |
|---|---|
"completed" | Turn processed normally; budget and turn limits not exceeded. |
"max_turns_reached" | mutable_messages length hit config.max_turns before the prompt was processed. |
"max_budget_reached" | Projected token usage after this turn would exceed config.max_budget_tokens. |
run_turn_loop(), the loop exits early on any stop reason other than "completed":
UsageSummary
UsageSummary accumulates token counts across turns. It is immutable — each call to add_turn() returns a new instance:
Token counts are currently estimated from word counts (
len(text.split())), not from a tokeniser. They serve as a lightweight budget proxy during porting; replace add_turn() with a real tokeniser for production use.TranscriptStore
TranscriptStore (in transcript.py) is a lightweight ordered log:
| Method | Behaviour |
|---|---|
append(entry) | Adds a string entry; sets flushed=False. |
compact(keep_last) | Trims entries to the most recent keep_last items. |
replay() | Returns all entries as an immutable tuple. |
flush() | Sets flushed=True without clearing entries. |
compact_messages_if_needed() after each turn, which delegates compaction to both mutable_messages and the transcript store. flush() is called automatically by persist_session() before writing to disk.
StoredSession and disk persistence
StoredSession (in session_store.py) is the serialisation envelope:
.port_sessions/<session_id>.json:
.port_sessions/ relative to the working directory. Pass a custom directory argument to either function to override this.
HistoryLog
HistoryLog (in history.py) is a simple runtime event journal attached to a RuntimeSession:
PortRuntime.bootstrap_session() records events at each stage of the session lifecycle:
RuntimeSession.as_markdown().