| Age | Commit message (Collapse) | Author |
|
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.
|
|
|
|
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.
|
|
|
|
The kept-verbatim suffix is no longer copied with stale usage. After
compaction the conversation begins [summary(user), kept_user,
kept_assistant, ...]; we rewrite each kept assistant's usage so the window
reads as a fresh conversation anchored at the summary.
- runSingleCompactionTurn returns the summary text plus its size (the
provider-reported output token count for the summary turn, falling back
to the word-count heuristic when usage is absent).
- rewriteWithSummary takes summary_size and forward-walks the kept suffix
maintaining a synthetic cumulative input: non-assistant messages add
their messageTokenEstimate; each assistant gets input = running
cumulative total, with the full prompt (input+cache_read+cache_write
worth) collapsed into input and cache buckets zeroed (a rewrite busts the
provider prefix cache). output/reasoning are copied verbatim; assistants
without prior usage stay null.
This keeps the cumulative-delta sizing (computeSplit/turnTokenEstimate) and
any future TUI context-window readout correct without special-casing
compaction. Tests cover the single- and multi-turn restated chains
(including cache-bucket collapse).
Test stub ScriptedTurn gains an optional usage stamp.
|
|
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.
|
|
Introduce a neutral persistence seam (session_store.zig) following the
{ptr, vtable} shape of the other libpanto seams. The interface traffics in
DiskMessage so non-JSONL backends (e.g. Postgres) can implement it.
- session_store.zig: SessionStore vtable (appendMessages, loadConversation,
sessionId, activeModel), LoadedSession{conversation, dangling_user},
re-exported disk types, and an FSJSONLStore alias.
- session_manager.zig: add store() wrapper + loadConversation() with
dangling trailing-user detection (excluded from the rebuilt conversation,
returned as dangling_user).
- null_store.zig: no-op backend, stateless singleton.
- root.zig: export session_store + null_store.
Phase 1+2 of docs/pluggable-session-store.md. Behavior-preserving; CLI not
yet rewired.
|
|
* note on the claude subscription provider plan that this is an
extension, not panto core, not to be published
* archive that old "overview" doc
* new doc: pluggable session stores
* new doc: libpanto C wrappers, FFI wrappers for python and go
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
|
|
- 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
|
|
|
|
|
|
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.
|
|
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.
|
|
- 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
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|