Skip to content

nimgent/conversation

This page is generated from the module’s exported API and ## documentation comments.

Event-backed conversation state for reusable agents.

A Conversation owns the transcript and usage for one interaction. Agent remains immutable configuration; a conversation can be used for independent runs and is not safe for concurrent mutation from multiple callers.

Current serialized conversation format version.

conversationSchemaVersion = 1

View source

Kind of event stored in a conversation transcript.

ConversationEventKind = enum
cekUser = "user", cekAssistant = "assistant", cekToolResult = "tool_result",
cekTurnStarted = "turn_started", cekTurnFinished = "turn_finished", cekTurnFailed = "turn_failed" ## Provider-neutral append-only conversation event. Lifecycle events make an
## interrupted turn observable without putting incomplete messages into the
## model-facing transcript.

View source

One durable event in a conversation transcript.

ConversationEvent = object
turnId*: string
case kind*: ConversationEventKind
of cekUser, cekAssistant:
message*: Message
model*: string
requestId*: string
usage*: Usage
finishReason*: FinishReason
of cekToolResult:
toolResults*: seq[ContentBlock]
of cekTurnStarted:
prompt*: string
of cekTurnFinished:
response*: ProviderResponse
of cekTurnFailed:
error*: string
aborted*: bool

View source

Stable identity passed through to providers that support server sessions.

Conversation = ref object
id*: string ## Agent configuration used for each turn.
agent*: Agent ## Most recent messages sent to the model per turn; 0 sends the whole
## transcript. Counted in messages, not turns: a turn with tool calls uses
## several. The event log always keeps every turn.
historyLimit*: int ## Canonical append-only transcript.
events*: seq[ConversationEvent]
turns*: int
totalUsage*: Usage
lastResponse*: ProviderResponse ## Highest turn number issued. Kept monotonic so turn ids stay unique when
## a caller replaces the transcript.

View source

Convert completed message events into the provider-neutral request shape. Pass any slice of Conversation.events to read the part a caller wants to summarize, drop, or rewrite.

proc messages(events: openArray[ConversationEvent]): seq[Message] {.raises: [],
tags: [], forbids: [].}

Returns: seq[Message].

Name Type Default
events openArray[ConversationEvent]

View source

Create an empty conversation, or continue from an existing transcript.

proc newConversation(agent: Agent; messages: seq[Message] = @[]; id = "";
historyLimit = 0): Conversation {.raises: [ProviderError],
tags: [TimeEffect], forbids: [].}

Returns: Conversation.

Name Type Default
agent Agent
messages seq[Message] @[]
id inferred ""
historyLimit inferred 0

View source

Model-facing view of the transcript currently in the conversation.

proc messages(conversation: Conversation): seq[Message] {.raises: [], tags: [],
forbids: [].}

Returns: seq[Message].

Name Type Default
conversation Conversation

View source

Replace the transcript, for example after compacting older turns, and rebuild turns, totalUsage, and lastResponse from it.

The caller owns the new transcript: keep it provider-valid by starting at a user turn and keeping each tool call with its results. Use userEventIndices to find safe cut points.

proc replaceEvents(conversation: Conversation;
events: openArray[ConversationEvent]) {.
raises: [ProviderError], tags: [], forbids: [].}
Name Type Default
conversation Conversation
events openArray[ConversationEvent]

View source

Indices of user events, the boundaries a caller can safely cut at when compacting a transcript.

proc userEventIndices(conversation: Conversation): seq[int] {.
raises: [ProviderError], tags: [], forbids: [].}

Returns: seq[int].

Name Type Default
conversation Conversation

View source

Run one user turn and append its complete model/tool transcript.

proc runAsync(conversation: Conversation; prompt: string;
abort: AbortCheck = nil; callbacks = RunCallbacks()): Future[
ProviderResponse] {.stackTrace: false, raises: [Exception, ValueError,
ProviderError, CatchableError], tags: [RootEffect, TimeEffect], forbids: [].}

Returns: Future[ProviderResponse].

Name Type Default
conversation Conversation
prompt string
abort AbortCheck nil
callbacks inferred RunCallbacks()

View source

Blocking convenience wrapper around runAsync.

proc run(conversation: Conversation; prompt: string; abort: AbortCheck = nil;
callbacks = RunCallbacks()): ProviderResponse {.
raises: [ValueError, Exception, OSError, ProviderError, CatchableError],
tags: [TimeEffect, RootEffect], forbids: [].}

Returns: ProviderResponse.

Name Type Default
conversation Conversation
prompt string
abort AbortCheck nil
callbacks inferred RunCallbacks()

View source

Stream one user turn and append its transcript after successful completion.

proc streamAsync(conversation: Conversation; prompt: string;
onEvent: StreamCallback; abort: AbortCheck = nil;
callbacks = RunCallbacks()): Future[ProviderResponse] {.
stackTrace: false,
raises: [Exception, ValueError, ProviderError, CatchableError],
tags: [RootEffect, TimeEffect], forbids: [].}

Returns: Future[ProviderResponse].

Name Type Default
conversation Conversation
prompt string
onEvent StreamCallback
abort AbortCheck nil
callbacks inferred RunCallbacks()

View source

Blocking convenience wrapper around streamAsync.

proc stream(conversation: Conversation; prompt: string; onEvent: StreamCallback;
abort: AbortCheck = nil; callbacks = RunCallbacks()): ProviderResponse {.
raises: [ValueError, Exception, OSError, ProviderError, CatchableError],
tags: [TimeEffect, RootEffect], forbids: [].}

Returns: ProviderResponse.

Name Type Default
conversation Conversation
prompt string
onEvent StreamCallback
abort AbortCheck nil
callbacks inferred RunCallbacks()

View source

Run one conversation turn while receiving lifecycle events.

proc runEventsAsync(conversation: Conversation; prompt: string;
abort: AbortCheck = nil; callbacks = RunCallbacks();
onEvent: AgentEventCallback = nil): Future[ProviderResponse] {.
stackTrace: false,
raises: [Exception, ValueError, ProviderError, CatchableError],
tags: [RootEffect, TimeEffect], forbids: [].}

Returns: Future[ProviderResponse].

Name Type Default
conversation Conversation
prompt string
abort AbortCheck nil
callbacks inferred RunCallbacks()
onEvent AgentEventCallback nil

View source

Stream one conversation turn while receiving lifecycle events.

proc streamAsync(conversation: Conversation; prompt: string;
onEvent: AgentEventCallback; abort: AbortCheck = nil;
callbacks = RunCallbacks()): Future[ProviderResponse] {.
stackTrace: false,
raises: [Exception, ValueError, ProviderError, CatchableError],
tags: [RootEffect, TimeEffect], forbids: [].}

Returns: Future[ProviderResponse].

Name Type Default
conversation Conversation
prompt string
onEvent AgentEventCallback
abort AbortCheck nil
callbacks inferred RunCallbacks()

View source

Synchronously stream one conversation turn with lifecycle events.

proc stream(conversation: Conversation; prompt: string;
onEvent: AgentEventCallback; abort: AbortCheck = nil;
callbacks = RunCallbacks()): ProviderResponse {.
raises: [ValueError, Exception, OSError, ProviderError, CatchableError],
tags: [TimeEffect, RootEffect], forbids: [].}

Returns: ProviderResponse.

Name Type Default
conversation Conversation
prompt string
onEvent AgentEventCallback
abort AbortCheck nil
callbacks inferred RunCallbacks()

View source

Persist the transcript independently of the consumer’s event-draining loop, while keeping the stream’s result Future authoritative.

proc events(conversation: Conversation; prompt: string; abort: AbortCheck = nil;
callbacks = RunCallbacks()): AgentEventStream {.
raises: [ProviderError, Exception, ValueError], tags: [RootEffect],
forbids: [].}

Returns: AgentEventStream.

Name Type Default
conversation Conversation
prompt string
abort AbortCheck nil
callbacks inferred RunCallbacks()

View source

Serialize the event log. Agent configuration is intentionally excluded.

proc conversationJson(conversation: Conversation): JsonNode {.
raises: [ProviderError, KeyError], tags: [], forbids: [].}

Returns: JsonNode.

Name Type Default
conversation Conversation

View source

Serialize a conversation transcript as a JSON string.

proc conversationJsonString(conversation: Conversation): string {.
raises: [ProviderError, KeyError], tags: [], forbids: [].}

Returns: string.

Name Type Default
conversation Conversation

View source

Rehydrate a conversation with a caller-supplied Agent configuration.

proc conversationFromJson(agent: Agent; node: JsonNode): Conversation {.
raises: [ProviderError, ValueError, KeyError], tags: [TimeEffect],
forbids: [].}

Returns: Conversation.

Name Type Default
agent Agent
node JsonNode

View source

Rehydrate a conversation from a JSON string and agent configuration.

proc conversationFromJson(agent: Agent; raw: string): Conversation {.raises: [
ProviderError, ValueError, KeyError, IOError, OSError, JsonParsingError],
tags: [TimeEffect, ReadIOEffect, WriteIOEffect], forbids: [].}

Returns: Conversation.

Name Type Default
agent Agent
raw string

View source

Clear the transcript, counters, and last response while retaining the agent configuration and history window.

proc reset(conversation: Conversation) {.raises: [ProviderError], tags: [],
forbids: [].}
Name Type Default
conversation Conversation

View source