PtcRunner.SubAgent.Definition (PtcRunner v0.11.0)

Copy Markdown View Source

Struct and type definitions for SubAgent configuration.

Defines the t() struct used throughout the SubAgent pipeline — from compilation through loop execution. Also defines shared types like language_spec(), system_prompt_opts(), llm_callback(), etc.

You typically don't build this struct directly; use PtcRunner.SubAgent.Compiler.compile/2 or the DSL macros instead.

Summary

Types

Compaction configuration for multi-turn agents.

Completion contract for PTC-Lisp SubAgents.

Output format options for truncation and display.

Language spec for system prompts.

LLM reference for SubAgent execution.

LLM response format.

Output mode for SubAgent execution.

Plan step definition.

PTC-Lisp reference card mode for combined-mode (output: :text, ptc_transport: :tool_call) system prompts.

Transport mode for output: :ptc_lisp agents.

t()

Types

compaction_opts()

@type compaction_opts() :: nil | false | true | keyword()

Compaction configuration for multi-turn agents.

Pressure-triggered context compaction. Compaction reduces the LLM-input message list when turn count or estimated token usage crosses a threshold.

Can be:

  • nil or false - Compaction disabled (default)
  • true - Use the :trim strategy with default options
  • keyword() - Use the :trim strategy with custom options

See PtcRunner.SubAgent.Compaction for option details and validation rules. Phase 1 supports strategy: :trim only; custom strategy modules and :summarize are deferred.

completion_mode()

@type completion_mode() :: :implicit | :explicit

Completion contract for PTC-Lisp SubAgents.

  • :implicit preserves historic behavior: a final bare expression can complete single-shot agents.
  • :explicit is reserved for hosts that require (return ...) or (fail ...) terminal forms. Phase 0 defines the contract; Worker A owns full explicit-mode enforcement.

format_options()

@type format_options() :: [
  feedback_limit: pos_integer(),
  feedback_max_chars: pos_integer(),
  history_max_bytes: pos_integer(),
  result_limit: pos_integer(),
  result_max_chars: pos_integer(),
  max_print_length: pos_integer()
]

Output format options for truncation and display.

Fields:

  • feedback_limit - Max collection items in turn feedback (default: 10)
  • feedback_max_chars - Max chars in turn feedback (default: 512)
  • history_max_bytes - Truncation limit for *1/*2/*3 history (default: 512)
  • result_limit - Inspect :limit for final result (default: 50)
  • result_max_chars - Final string truncation (default: 500)
  • max_print_length - Max chars per println call (default: 2000)

language_spec()

@type language_spec() ::
  String.t()
  | atom()
  | {:profile, atom()}
  | {:profile, atom(), keyword()}
  | (map() -> String.t())

Language spec for system prompts.

Can be:

llm_callback()

@type llm_callback() :: (map() -> {:ok, llm_response()} | {:error, term()})

llm_ref()

@type llm_ref() :: String.t() | atom() | llm_callback()

LLM reference for SubAgent execution.

Can be:

  • String.t() — Model alias (e.g., "haiku") or full ID (e.g., "openrouter:anthropic/claude-haiku-4.5")
  • atom() — Registry key (e.g., :haiku) that looks up in llm_registry
  • llm_callback() — Direct callback function

llm_registry()

@type llm_registry() :: %{required(atom()) => llm_callback()}

llm_response()

@type llm_response() ::
  String.t()
  | %{
      :content => String.t(),
      optional(:tokens) => %{
        optional(:input) => pos_integer(),
        optional(:output) => pos_integer()
      }
    }
  | %{
      :tool_calls => [map()],
      optional(:content) => String.t() | nil,
      optional(:tokens) => map()
    }

LLM response format.

Can be either a plain string (backward compatible) or a map with content and optional tokens. When tokens are provided, they are included in telemetry measurements and accumulated in Step.usage.

For :tool_calling mode, the LLM callback may also return tool calls: %{tool_calls: [%{id: "call_1", name: "search", args: %{"q" => "foo"}}], content: nil | "...", tokens: %{...}}

output_mode()

@type output_mode() :: :ptc_lisp | :text

Output mode for SubAgent execution.

  • :ptc_lisp - Default. LLM generates PTC-Lisp code that is executed.
  • :text - Auto-detects behavior from tools and signature return type:
    • No tools + :string/no signature → raw text response
    • No tools + complex return type → JSON response (validated)
    • Tools + :string/no signature → tool loop → text answer
    • Tools + complex return type → tool loop → JSON answer

plan_step()

@type plan_step() :: {String.t(), String.t()}

Plan step definition.

Each step is a {id, description} tuple where:

  • id is a string identifier (used as key in summaries)
  • description is a human-readable description of the step

ptc_reference()

@type ptc_reference() :: :compact

PTC-Lisp reference card mode for combined-mode (output: :text, ptc_transport: :tool_call) system prompts.

  • :compact — bounded reference card (≤300 tokens), default in combined mode. Describes the core forms (def, tool/, return, println) and the full_result_cached: true cache-reuse pattern.

v1 supports only :compact; :full is deferred (the validator raises ArgumentError on :full). See Addendum #1 of Plans/text-mode-ptc-compute-tool.md.

ptc_transport()

@type ptc_transport() :: :content | :tool_call

Transport mode for output: :ptc_lisp agents.

  • :content - Default. LLM emits a markdown-fenced PTC-Lisp program in the assistant message content; the loop parses and executes it.
  • :tool_call - LLM invokes the internal lisp_eval native tool with a program argument; final answers are returned as direct content and validated against signature:. Valid only with output: :ptc_lisp.

See docs/plans/ptc-lisp-tool-call-transport.md for the full design.

system_prompt_opts()

@type system_prompt_opts() ::
  %{
    optional(:prefix) => String.t(),
    optional(:suffix) => String.t(),
    optional(:language_spec) => language_spec(),
    optional(:output_format) => String.t()
  }
  | (String.t() -> String.t())
  | String.t()

t()

@type t() :: %PtcRunner.SubAgent.Definition{
  builtin_tools: [atom()],
  compaction: compaction_opts(),
  completion_mode: completion_mode(),
  context_descriptions: map() | nil,
  description: String.t() | nil,
  field_descriptions: map() | nil,
  float_precision: non_neg_integer(),
  format_options: format_options(),
  journaling: boolean(),
  llm: llm_ref() | nil,
  llm_query: boolean(),
  llm_retry: map() | nil,
  max_depth: pos_integer(),
  max_heap: pos_integer() | nil,
  max_tool_calls: pos_integer() | nil,
  max_turns: pos_integer(),
  memory_limit: pos_integer() | nil,
  memory_strategy: :strict | :rollback,
  mission_timeout: pos_integer() | nil,
  name: String.t() | nil,
  output: output_mode(),
  parsed_signature: {:signature, list(), term()} | nil,
  plan: [plan_step()],
  pmap_max_concurrency: pos_integer(),
  pmap_timeout: term(),
  progress_fn: (map(), term() -> {String.t(), term()}) | nil,
  prompt: String.t(),
  prompt_limit: map() | nil,
  ptc_reference: ptc_reference(),
  ptc_transport: ptc_transport(),
  retry_turns: non_neg_integer(),
  schema: term(),
  signature: String.t() | nil,
  system_prompt: system_prompt_opts() | nil,
  thinking: boolean(),
  timeout: pos_integer(),
  tools: map(),
  turn_budget: pos_integer()
}