Execution loop for JSON output mode.
JSON mode is a simpler alternative to PTC-Lisp execution where the LLM returns structured JSON directly, validated against the agent's signature.
Flow
- Build prompt using JSON templates (no PTC-Lisp spec)
- Call LLM with
%{output: :json, schema: ...}in input - Parse JSON from response
- Validate against signature
- If invalid and turns remaining → retry with error feedback
- Return
Stepstruct with parsed JSON (atom keys)
Differences from PTC-Lisp Mode
| Aspect | PTC-Lisp | JSON Mode |
|---|---|---|
| System prompt | Full spec + tool docs | Minimal (json-system.md) |
| Response parsing | ResponseHandler.parse | Jason.decode |
| Execution | Lisp.run/2 | None (direct validation) |
| Return value | From (return ...) | Parsed JSON |
| Memory | Accumulated | Always %{} |
| Retries | On execution error | On validation error |
This is an internal module called by SubAgent.run/2 when output: :json.
Summary
Functions
@spec preview_prompt(PtcRunner.SubAgent.t(), map()) :: %{ system: String.t(), user: String.t(), schema: map() | nil }
Generate a preview of the JSON mode prompts.
Returns the system and user messages that would be sent to the LLM, plus the JSON schema used for validation.
@spec run(PtcRunner.SubAgent.t(), term(), map()) :: {:ok, PtcRunner.Step.t()} | {:error, PtcRunner.Step.t()}
Execute a SubAgent in JSON mode.
Parameters
agent- A%SubAgent{}struct withoutput: :jsonllm- LLM callback functionstate- Initial loop state from Loop.run/2
Returns
{:ok, Step.t()}on success{:error, Step.t()}on failure