QueryEnginePort is the stateful conversation layer of Claw Code. It accumulates messages across turns, enforces token-budget and turn-count limits, handles structured output serialisation, and persists sessions to disk.
QueryEngineConfig
Configuration dataclass forQueryEnginePort. All fields have defaults; pass an instance to override behaviour.
Maximum number of messages stored before new
submit_message calls return stop_reason="max_turns_reached".Token budget across the entire session (input + output, word-count approximation). When a turn would exceed this value,
stop_reason="max_budget_reached" is returned.After each turn, if the stored message count exceeds this value the oldest messages are dropped to keep only the most recent
compact_after_turns entries.When
True, turn output is serialised as a JSON object containing summary lines and session_id.Number of attempts to serialise structured output before raising
RuntimeError.Factory methods
QueryEnginePort.from_workspace
PortManifest built from the current working directory.
QueryEnginePort.from_saved_session
.port_sessions/<session_id>.json and restores the message history and token usage.
The hex session ID returned by
persist_session() or RuntimeSession.persisted_session_path.The transcript is marked as already flushed when restoring from a saved session, so
persist_session() will not double-write the transcript.submit_message
TurnResult.
The user message for this turn.
Names of commands that were routed for this prompt (from
PortRuntime.route_prompt).Names of tools that were routed for this prompt.
Tools that were blocked before the turn was processed. See ToolPermissionContext.
TurnResult
The prompt submitted for this turn.
Formatted turn output. Plain text by default; JSON when
structured_output=True.Echo of the
matched_commands argument.Echo of the
matched_tools argument.Echo of the
denied_tools argument.Cumulative token counts after this turn.
One of
"completed", "max_turns_reached", or "max_budget_reached".Stop reasons
| Value | Meaning |
|---|---|
"completed" | Turn processed normally. |
"max_turns_reached" | mutable_messages length has reached max_turns; prompt was not processed. |
"max_budget_reached" | The turn would push cumulative tokens over max_budget_tokens; output is still returned but no further turns should be submitted. |
stream_submit_message
submit_message internally.
| Event type | When emitted | Key fields |
|---|---|---|
message_start | Always, first | session_id, prompt |
command_match | When matched_commands is non-empty | commands: tuple[str, ...] |
tool_match | When matched_tools is non-empty | tools: tuple[str, ...] |
permission_denial | When denied_tools is non-empty | denials: list[str] (tool names) |
message_delta | Always, after submit | text: str |
message_stop | Always, last | usage, stop_reason, transcript_size |
persist_session
.port_sessions/<session_id>.json. Returns the file path as a string.
persist_session can be restored with QueryEnginePort.from_saved_session.
compact_messages_if_needed
submit_message turn. If the number of stored messages exceeds compact_after_turns, the oldest messages are dropped so that only the most recent compact_after_turns entries are kept. The TranscriptStore is compacted by the same amount.
replay_user_messages
TranscriptStore, in submission order. Useful for auditing or reconstructing the conversation.
flush_transcript
TranscriptStore as flushed without writing anything to disk. Called automatically by persist_session. Call directly when you want to reset the flush flag without persisting.