summaryrefslogtreecommitdiff
AgeCommit message (Collapse)Author
2026-06-15docs: note openai_responses serializer/parser scope and reasoning-continuity ↵t
limitation
2026-06-15auth: openai_responses provider for Codex subscription (Tier 2)t
Add the OpenAI Responses API wire dialect (openai_responses APIStyle + OpenAIResponsesConfig), a request serializer (instructions/input items, flat function tools, reasoning, store:false, include encrypted reasoning), and a streaming state machine over the typed response.* SSE events mapping to the shared block model. Wire dispatch, buildProviderConfig, the C-ABI free switch, and the reasoning selectors. Ship a commented Codex example in the default config. Implemented from the Responses API docs + the open-source Codex client and covered by fixture tests; live verification against a ChatGPT plan is still required (documented).
2026-06-15docs: as-built status for OAuth provider autht
Record resolved open questions (clean break, key_env_var, codex dialect, file-backed storage), the core/CLI split, verified device-flow specifics for Copilot and Codex, the Codex Responses-API finding, and verification status.
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-15auth: OAuth device flows, refresh, and Copilot exchange (C5)t
Implement the device-authorization flow for both dialects (GitHub `token` direct-poll; Codex `codex` poll→authorization-code→PKCE exchange), refresh_token grant, Copilot secondary token exchange, JWT exp parsing, Codex account-id extraction, and pure credential-building/refresh predicates. Adds a Presenter hook for rendering the device-code prompt. Exported from public.zig.
2026-06-15auth: HTTP helper + token storage (C3, C4)t
Add libpanto http_helper (non-streaming request/response over the global client, plus dotted-JSON-path readers) and token persistence in auth.zig (load/save/delete TokenSet under an embedder-chosen auth dir, owner-only files). Add $PANTO_HOME/auth to the panto_home layout.
2026-06-15auth: thread provider extra_headers into request headers (C6)t
Add provider.mergeHeaders and use it in both the openai_chat and anthropic_messages providers so config extra_headers ride on the model request, merged onto the built-in header set.
2026-06-15auth: clean-break named [auth.<name>] sessions + extra_headerst
Replace provider-level api_key/api_key_env_var with named auth sessions: providers now reference `auth = "<name>"` and credentials live under `[auth.<name>]`. Adds the libpanto auth type surface (AuthConfig, TokenSet, ResolvedCredential), a Header type and provider `extra_headers`, and rewires the CLI config loader (parse [auth.<name>], require auth=, providers always survive, eager api_key resolution). Updates the shipped default config.
2026-06-13oauth provider doct
2026-06-12improve errors: retries, surfacing provider errors to the usert
2026-06-12anthropic prompt cachingt
2026-06-12add latest output into footer context window displayt
2026-06-12fuzzy selectors for models and reasoning levelst
2026-06-12Replace Footer FPS display with model dimension and dim stylingt
Remove setFrameTime() method and fps-related rendering from Footer. Replace with setModel() to display model name with dim styling. Update all Footer tests accordingly, adjusting line counts and expectations for new layout with top/bottom rules wrapping content. Remove reverse video styling from footer.
2026-06-11some go bindings fixes and an example appt
2026-06-11expand libpanto-go and -c to the full libpanto API surfacet
2026-06-11libpanto-got
some libpanto-c coverage expansion was needed
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-10libpanto-ct
2026-06-10example full application through the lua apit
2026-06-10fix anthropic thinking effort json placementt
2026-06-10fix: eliminate scrollback-clearing flash when streaming with expanded tool ↵t
output The root cause was a two-part bug: 1. Engine slot management (tui_engine.zig): The app rebuilds its full component list on every new transcript entry. The old approach drained every slot then re-added them all, resetting every component's render baseline. When earlier content had scrolled into native scrollback (viewport_top > 0), the engine's viewport-escape rule escalated any cut above the viewport top to a scrollback-clearing full redraw — the visible flash on every streamed block while a tool call was expanded. Fix: replace drain+rebuild with syncComponents(), which reconciles the live slot list in place by finding the longest common prefix and suffix (matched by component pointer). Prefix and suffix slots keep their baselines verbatim; only the changed region in the middle gets new empty slots. A pure insertion (the dominant case: a new transcript entry appended just before the pinned input+footer suffix) stays on the differential path with no clear. A structural change (slot replaced or removed) sets force_full for correctness. 2. RenderCache dirty signal (tui_component.zig): firstLineChanged() was returning the retained changed_from diff index even when the cache was clean. A first-paint store records changed_from == 0, so a clean but previously-rendered component was pegging the differential cut to line 0 on every subsequent frame, making unchanged slots above the insertion point drag the cut all the way up. Fix: when the cache is clean, firstLineChanged() returns null unconditionally. The recorded changed_from is now internal render bookkeeping only, not a live signal. Additional changes: - ToolUse.collapsed_tail_lines raised from 5 to 8 lines. - ToolUse collapsed-view test updated to use 12 output lines and collapsed_tail_lines symbolically so the numbers self-document. - tui_app.zig: override-slot test comment and assertion clarified to reflect that the override owns the slot pointer (not just renders it), and the SWAPPED-AT-DETAILS render check replaced with a pointer-equality check. - lua_event_bridge.zig: minor related fixes. - New tests: syncComponents middle-insertion no-clear, syncComponents structural removal forces full, syncComponents override swap; streaming expanded-tools no-clear regression test in tui_app.
2026-06-10better document that the read tool works with binary typest
2026-06-10strip ANSI color sequences from tool output for displayt
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-10language bindings doc libpanto-lua plant
2026-06-10expose `panto` to extensions as a require()able module, not a globalt
2026-06-10mark done todost
2026-06-09accurately count message widtht
2026-06-09color themet
2026-06-09fix streaming renderingt
2026-06-09anthropic thinkingt
2026-06-09archive the tui refactor doct
2026-06-09finalize cursor on quitt
2026-06-09event lifecyclet
2026-06-08keybinding fixest
2026-06-08proper terminal capability negotiationt
determine support for the kitty protocol and then pick output sequences accordingly. tested on ghostty (supports kitty) and tmux-in-ghostty (tmux does not support kitty protocol) with shift+enter as newline.
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-08tui plant
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-07Add public.zig as the libpanto root; delete root.zigt
public.zig is now the sole exported root (build.zig points the panto module at it). It defines the curated public API allowlist: behavioral facades (Agent/Stream/Conversation wrapping a pointer to the heap-pinned internal), the ResultParts struct, Pricing, the session seam, and data-type aliases for the Config/Conversation/Event families. A clearly-marked transitional block re-exports the internal module namespaces and the freestanding result-part helpers the panto CLI still imports directly; Phase 4 trims these as the CLI migrates onto the curated surface. Stream.Phase is now pub so State can alias it. The refAllDecls test contract moved from root.zig into public.zig.
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-07lib cleanup doct
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.