summaryrefslogtreecommitdiff
path: root/src/main.zig
AgeCommit message (Collapse)Author
2026-06-15model registry sync via models.devt
2026-06-15Add Codex Responses support and session debuggingt
Teach provider config and auth resolution about the Codex Responses dialect, including user-facing `style = "openai_responses"` with `dialect = "codex"`. Serialize and parse Responses traffic with provider-specific reasoning replay, assistant phase metadata, and robust function-call assembly keyed by `output_index` so streamed tool inputs survive proxy quirks and empty terminal payloads. Also persist thinking origins and message metadata across sessions, add the Anthropic interleaved-thinking header switch, write per-session debug logs, and improve the TUI and scripts for inspecting tool output and session costs.
2026-06-15auth: turn-time resolution in the TUI (inline login + 401 retry)t
Resolve the active provider's auth before each turn via the AuthManager, rendering an inline device-code prompt when login is needed, and force a single refresh/exchange retry on a provider auth failure. Wire the manager through RunOptions from main.zig.
2026-06-15auth: CLI auth manager + `panto auth` subcommandst
Add src/auth_manager.zig (turn-time resolution: load→login→refresh→exchange→ build credential, patch live config) and `panto auth status|login|logout` subcommands with a line-based device-code presenter. Add config_file.loadFromString.
2026-06-12fuzzy selectors for models and reasoning levelst
2026-06-11libpanto API fixest
- FSJSONLStore: don't require `cwd`, instead panto CLI provides it in the session metadata - Lua: expose the `SessionStore` interface and the `FSJSONLStore` and `NullStore` implementations - C: use idiomatic `const char *` for incoming strings - C: expose the `FSJSONLStore` and `NullStore` implementations
2026-06-10Add addUserText helper; update all call sitest
Conversation.addUserMessage now takes a []ContentBlock (symmetric with addAssistantMessage). Introduce a thin addUserText wrapper in agent.zig for the plain-text case and update every call site in agent.zig and anthropic_messages_json.zig accordingly.
2026-06-09event lifecyclet
2026-06-08keybinding fixest
2026-06-08Replace print CLIRenderer with differential TUI enginet
Implement TUI Phase 1: a raw-mode terminal, differential render engine, pinned input box + footer, and component model wired into the libpanto event stream. Adds foundation modules (theme, key, component, input, terminal), the render engine, components, and the app loop; removes the old print CLIRenderer and driveTurn REPL from main.zig. Also removes scratch status reports (tui-p1/, progress.md) for the now completed work.
2026-06-07further libpanto public API name cleanupt
2026-06-07Sync Agent/Stream internals to public names; alias Streamt
Push the API-shaping we'd done in the public facade down into the internal types, collapsing the wrappers: - Stream: rename phase->state, Phase->State; underscore-prefix the internal fields (_agent/_queue/_response/_start/_persisted/_pending_error). state is the one intended-public field. public.zig now aliases Stream; run returns *Stream. - Agent compaction: pure transform compact()->private _compactInPlace; compactAndPersist()->compact() (the public name, persists). - Agent system prompt: addSystemMessage(text,mode) split into addSystemMessage(text) + setSystemPrompt(text) over a private _persistSystemMessage. - UserMessage moved off Agent to module scope. - Underscore-prefix pure-internal Agent fields: _open_stream_fn, _auto_compacted, _retry_prng. The Agent facade is now pure 1:1 forwarders; it stays a wrapper only because init heap-pins the inner (copyable, move-safe handle) and conversation()/ sessionId() are accessors. Conversation and Stream are plain aliases.
2026-06-07Alias Conversation instead of facading it; merge addAssistantMessaget
A facade that forwards every method 1:1 is worse than paring the real type down to the intended surface and aliasing it. conversation.Conversation's interface is already the public surface we want (init/deinit, the add*/replace* builders, and messages/allocator as plain data fields), so public.zig now aliases it straight through and Agent.conversation() returns a borrowed *Conversation for in-place surgery. Drops the ConversationData alias and the pointer-wrapper. Merged addAssistantMessageWithUsage into addAssistantMessage(blocks, ?usage) on the real type (separate method deleted), so the alias has the intended one-method shape; all call sites updated. Only Agent and Stream remain true facades -- they have genuinely-internal fields plus API-shaping renames (Stream.phase->state, Phase->State) an alias can't express.
2026-06-07Plug the deep-embedder holes; remove public.zig escape hatcht
Close the gap that forced the CLI to import internal libpanto namespaces, then delete the transitional re-exports. The CLI now uses only the curated public surface. Additions to the public Agent facade: - init/deinit (heap-pin the inner; the handle is a copyable value). - addSystemMessage (.append) and setSystemPrompt (.replace). - compact(override_system_prompt, extra) falling back to the config prompt. - sessionId() accessor. CompactionConfig gains compaction_prompt, which owns the compaction system prompt for both auto-compaction and the explicit compact() default; the Agent.compaction_system_prompt field is deleted. ConversationData is the public name for the owned conversation value type (Session.load returns it, Agent.init adopts it), distinct from the borrowed Conversation handle. Agent.addSystemMessage/setSystemPrompt are kept on Agent (they persist with the SystemMode) rather than dropped as the plan first proposed.
2026-06-07Migrate panto CLI onto the public.zig surfacet
Move the CLI off the internal libpanto module namespaces onto the curated public API: data-type aliases (Config family, Message/MessageRole/ effectiveSystemBlocks, Event, Pricing/PricingRegistry, the session seam, FileSystemJSONLStore, ContentBlockType), process lifecycle (panto.init/ deinit), and ResultParts.fromText/fromTextOwned/deinit in place of the freestanding textResult/ownedTextResult/freeResultParts. The CLI remains on two flagged internal namespaces, panto.agent and panto.conversation: it is a deep embedder that drives the loop below the curated Agent/Conversation facades (system-prompt seeding through the agent, compaction_system_prompt, the open_stream_fn test seam, standalone Conversation values, compactAndPersist). These stay re-exported from public.zig as a documented deep-embedder escape hatch; trimming the transitional block removed every other internal re-export.
2026-06-07R2: redesign session store with wire-format identityt
Replace the single-session SessionManager seam with a directory-backed catalog. session_manager.zig -> file_system_jsonl_store.zig; the old machinery becomes internal SessionFile, and a new FileSystemJSONLStore implements the redesigned SessionStore vtable (create/list/resolve/latest/ load/appendMessages) minting Session/SessionInfo handles. Session logs now record wire-format provider identity ({api_style, base_url, model, reasoning}) instead of a single provider string or CLI aliases; no api_key material is ever stored. Disk* content types renamed Stored*; the rich audit-oriented write record is PersistentMessage (in-memory Message + WireIdentity + provenance). Agent.init now takes a Session; persist_provider/persist_model display strings deleted (banner stays alias-based, resume picks default model). Message.metadata round-trips. Dangling-prompt recovery dropped. CLI migrated to the catalog store for run/resume/list. Clean break, no version bump (old logs wiped).
2026-06-07R1: move tool registry off Config onto Agentt
The tool set is no longer part of the per-turn Config snapshot. Agent now owns a ToolRegistry (created empty at init), populated via the new Agent.registerTool / registerToolSource methods. openStream and OpenStreamFn take the registry as an explicit parameter rather than reading it from cfg.registry, so swapping provider/model between turns (setConfig) no longer disturbs the tool set. CLI migrated to register the Lua tool source onto the agent instead of a locally-owned registry. Test harnesses updated to stage tools on the agent.
2026-06-05refactor: Agent.run() -> Stream -> Stream.next() -> Eventt
converted the main agent loop from push-based (into callbacks on a Receiver vtable) to pull-based, where `next()` re-enters a state-machine Stream until the next event can be returned.
2026-06-05Move session persistence into the Agent; collapse CLI plumbingt
The Agent now owns its Conversation and a SessionStore, and persists everything it generates as turns progress. Embedders get persistence for free; the CLI no longer drives the session log. libpanto: - Agent.init takes a SessionStore + optional Conversation to adopt (resume path). Agent owns/tears down the conversation; turn-driving methods drop the *Conversation param and operate on self.conversation. - New Agent methods: submitUserMessage (adds+persists the user prompt immediately), addSystemMessage(text, mode), runStep persists the turn on every exit path (incl. partial turns on error), compactAndPersist for the explicit /compact path. Auto-compaction persists its window via runStep's tail. - turn_persist.zig: DiskMessage mapping moved out of the CLI; reads usage off Message.usage (no per-message-usage list). System mode rides on DiskMessage.mode, derived from the System block. - NullStore is now an allocator-bearing struct (frees consumed messages per the store-consumes-messages contract). - Tests: in-memory CapturingStore round-trip + NullStore turn test. panto CLI: - Delete src/session_persist.zig. REPL is submitUserMessage + runStep. - Reorder construction: store -> registry -> agent -> bootstrap -> seed/ reconcile system prompt through the agent -> load extensions. - command.Context drops conv/session_mgr; commands reach ctx.agent. - system_prompt seed/reconcile call agent.addSystemMessage. - CLIReceiver is display-only (per_message_usage removed). Phases 3-5 of docs/pluggable-session-store.md. Behavior preserved; full build + test suite green.
2026-06-04failure retries schemet
2026-06-02lua /commandst
2026-06-02compactiont
2026-06-02tool call resiliencyt
2026-06-02system prompt building and loggingt
2026-06-01Rename system extension layer to base for clarityt
Replace all references to the "system" layer with "base" to better reflect its role as the foundational extension/tool layer in panto's hierarchy. The layer hierarchy now consistently uses: project > user > base. Includes: - Update agent README and build.zig documentation - Refactor tool registry and config module to support layered lookups - Add TestHarness abstraction for cleaner test setup - Improve JSON serialization with wire-encoded tool names - Add glob pattern matching for tool/extension discovery
2026-05-27real coding agent toolsT
2026-05-27system agent definition scaffoldingT
2026-05-27session filesT
2026-05-27Finish the hard parts of the lua makeoverT
- bundle luarocks source in the panto binary - bootstrap process (intended for first `panto` run): - make ~/.local/share/panto/... - write out luarocks sources into it - run luarocks to install luv - new `panto bootstrap` command just runs the bootstrap - `panto bootstrap --force` removes everything and re-bootstraps - new `panto lua` command just runs panto's embedded lua
2026-05-27separate event for providing tool detailsT
OpenAI and Anthropic have tool details (id, name) converge on different timelines. In all cases they are available in `onBlockComplete` which comes with the full block, and previously we had an optional `BlockMeta` argument to `onBlockStart` - the anthropic timeline. We removed the `BlockMeta` from `onBlockStart` since it was always going to be unreliable, and now have an explicit `onToolDetails` instead. This allows us to provide the tool id and name as early as possible from the openai provider (could be in the middle of content deltas), and provide a reliable signal across providers. Also, fix test output.
2026-05-27Stream OpenAI tool_use as discrete blocks; drop BlockMetaT
Close each tool_use on next-index delta (and at finalize) so receivers see one start/delta/complete trio per tool, matching Anthropic. Log+drop fragments for already-closed indices. Remove BlockMeta from the Receiver interface: tool id/name can't be reliably known at onBlockStart under OpenAI's streaming model. Receivers get identity from the assembled ContentBlock at onBlockComplete. CLI renders 'tool: {args} : (name)' accordingly.
2026-05-27finish lua runtime makeoverT
- new multi-tool registration via ToolSource - thread per source-or-standalone-tool - switched to zig 0.16 Io threading interface - cli: include `luv` package and run concurrent lua tools via libuv - one single long-lived lua_State for the whole cli program
2026-05-26extension loading from lua files/directoriesT
2026-05-26basic lua toolsT
2026-05-26include and link lua 5.4, smoke test in panto cli main.zigT
2026-05-26phase 3 part 1T
2026-05-25phase 2 doneT
2026-05-25phase 1 doneT
2026-05-25workT
2026-05-25Initial work, and name change to pantographT