Parlora.ContextSnapshot (Parlora v0.1.0)

Copy Markdown View Source

Immutable context supplied to the application policy, not a persistence format.

Transcript entries are newest-arrival-first. arrival_order is a context revision, not a turn identifier; timestamps may overlap. Delegations include both pending and claimed entries. Task request IDs are newest-first and include older revisions, not just running work. Inspect Parlora.status/1 for job state.

Optional map keys are absent until observed. clarification is either a policy submission attempt or a backend question; it is not proof the caller heard it. Policy submissions carry delivery: :unconfirmed; their context revision marks submission, not speech or playback. Synchronous rejections create no marker. confirmation is reserved and currently nil; authorize business actions in the application. Additional adapter payload keys are not coordinator guarantees.

provider_speech is :unknown, :speaking, or :idle. Changes revise context so an in-flight policy judgment cannot apply to an older speech state. This is the provider's reported state, not downstream playback or proof of hearing.

Summary

Types

backend_clarification()

@type backend_clarification() :: %{
  :task_revision => pos_integer(),
  optional(:question) => String.t(),
  optional(atom()) => term()
}

clarification()

@type clarification() :: policy_clarification() | backend_clarification()

context_wait()

@type context_wait() :: %{
  due_at_us: integer(),
  expired?: boolean(),
  recheck_key: String.t() | nil
}

delegation()

@type delegation() :: %{
  :id => String.t(),
  :target => :client,
  :offset_ms => number() | nil,
  :provider_generation => non_neg_integer(),
  :status => :pending | :claimed | :cancelled,
  :received_at_us => integer(),
  optional(:task_id) => String.t(),
  optional(:task_revision) => pos_integer(),
  optional(:context_wait) => context_wait(),
  optional(:clarification) => policy_clarification(),
  optional(atom()) => term()
}

policy_clarification()

@type policy_clarification() :: %{
  context_revision: non_neg_integer(),
  command_id: String.t(),
  delivery: :unconfirmed,
  message: String.t(),
  input: map()
}

progress()

@type progress() :: %{
  :task_revision => pos_integer(),
  optional(:facts) => map(),
  optional(:summary) => String.t(),
  optional(atom()) => term()
}

speaker()

@type speaker() :: :user | :assistant

t()

@type t() :: %Parlora.ContextSnapshot{
  application_context: map(),
  pending_delegations: %{optional(String.t()) => delegation()},
  provider_generation: non_neg_integer(),
  provider_speech: :unknown | :speaking | :idle,
  revision: non_neg_integer(),
  session_id: String.t(),
  tasks: %{optional(String.t()) => task()},
  transcripts: [transcript()]
}

task()

@type task() :: %{
  :id => String.t(),
  :revision => pos_integer(),
  :input => map(),
  :status => task_status(),
  :request_ids => [String.t()],
  :delegation_id => String.t() | nil,
  :confirmation => nil,
  optional(:context_wait) => context_wait(),
  optional(:clarification) => clarification(),
  optional(:progress) => progress()
}

task_status()

@type task_status() :: :submitted | :uncertain | Parlora.BackendResult.status()

transcript()

@type transcript() :: %{
  :speaker => speaker(),
  :delta => String.t(),
  :start_ms => number() | nil,
  :end_ms => number() | nil,
  :provider_generation => non_neg_integer(),
  :arrival_order => non_neg_integer(),
  optional(atom()) => term()
}