Skip to content

Releases: Wixely/DaggerAgent

v1.12.0: DaggerAgent 1.12.0

Choose a tag to compare

@github-actions github-actions released this 07 Sep 15:55

DaggerAgent 1.12.0

A Banter tab that saves, and reads in the order the steps happen.

The Bant tab could not change the server address. Its

is static
markup that survives replaceChildren(), and each render added another
submit listener, so one Save fired several POSTs at once - each stale
handler carrying the values from the render that made it. Whichever
landed last won, and the field reloaded with the old address. The
trigger options form had the same defect. Both now assign
form.onsubmit, which replaces the handler instead of stacking it.

The tab is now laid out as the dependency actually runs: 1. Server &
identity, 2. Enrol this machine, 3. Connect, with room settings
unnumbered at the end because none of them are needed to get into a
room. Enrolment redeems its one-time code against the server named in
step 1 rather than the last saved one, and step 3 says plainly when
there is no credential yet.

Spacing: every .endpoint-form rule is scoped under .endpoints-list and
this form is not, so the tab had been rendering with no field gaps,
default-size labels and .row-2 stacking instead of pairing. It has its
own .banter-pane styles now. The status pill's bg-success / bg-warning
/ bg-danger were referenced but never defined, so connected,
reconnecting and evicted all came out grey.

v1.11.0: DaggerAgent 1.11.0

Choose a tag to compare

@github-actions github-actions released this 06 Sep 17:34

DaggerAgent 1.11.0

Structured questions, and a Banter connection that tells the truth.

ask_user (#10's sibling for Dagger's own surfaces): a built-in tool
that asks whoever is driving the job a question with clickable
options - the same shape as Claude Code's AskUserQuestion and Banter's
ask_operator. In the web transcript it renders as a card: options
stacked as full-width buttons with radio/checkbox marks, descriptions,
a free-text field that always rides along, and single-select answering
on the click. In the interactive TUI the question renders with
numbered options and the input line answers it - a number picks,
comma-separated numbers for multi-select, anything else is free text,
an empty line skips. With nobody attached (CLI one-shot, trigger jobs,
Banter rooms, sub-agents) the tool answers immediately that there is
no one to ask. Wait bounded by Tools:AskUserTimeoutSeconds.

Banter mode, on SDK 0.2.0:

  • Room tools ride along with Dagger's registry instead of being
    replaced by it (#10): ask_operator, the delegator's open_side_room /
    invite_agent, and server-granted tools, sourced from
    BanterAgent.ToolsFor(room) each turn and dispatched back through the
    SDK. New Banter:RoomTools switch for unattended fleets, and
    Banter:AskTimeoutSeconds.
  • Honest connection state: "reconnecting (attempt n)" through an
    outage (the SDK redials with jittered backoff, re-authenticates with
    a fresh signed nonce, rejoins and re-announces); "evicted" with the
    server's reason when the identity was revoked or reissued - terminal
    on purpose, since automating re-enrolment would turn revocation into
    a self-healing bypass. Auto-connect retries a server that is still
    booting with capped, jittered backoff.
  • The Bant tab shows the attributes the server actually GRANTED next
    to the requested ones, flagged when an admin override is in effect.
  • Standalone dagger banter reports an eviction and its reason
    instead of exiting as if someone pressed Ctrl+C.

Fix: an empty ConversationState.Model now means "the endpoint's
default decides" instead of overriding it with an empty model id,
which the OpenAI serializer rejects.

v1.10.0: DaggerAgent 1.10.0

Choose a tag to compare

@github-actions github-actions released this 04 Sep 16:36

DaggerAgent 1.10.0

Manage the Banter connection from the web UI: a Bant tab in service
mode (dagger serve) holds the room connection in-process, so no
second dagger banter process is needed.

  • Status card: connection state, identity, rooms, key fingerprint and
    last error, with Connect / Disconnect buttons.
  • Enrolment box: paste a one-time code from the Banter client's agents
    page; the machine makes its own key (DPAPI-protected on Windows),
    the enrolled nick and fingerprint come back, and the config is
    updated to match - the leftover password is cleared, so Connect
    just works. An existing key is never overwritten.
  • Config section persisted to runtime-config.json: server, user,
    rooms, key path, password (legacy), LLM endpoint + model for room
    turns, routing attributes, system prompt, and auto-connect on
    service start (Banter:AutoConnect).
  • Scriptable at /agent/banter: GET, POST /config, /enrol, /connect,
    /disconnect. The password never leaves the server (hasPassword
    only); the key surfaces only as its path and public fingerprint.
  • New Banter:EndpointId pins room turns to a configured LLM endpoint
    instead of the active default.
  • Fix: an empty ConversationState.Model now means "the endpoint's
    default decides" instead of overriding it with an empty model id,
    which the OpenAI serializer rejects ("Empty encoded value").

Verified in a real browser against a live Banter server: enrol from
the tab, key login (signed nonce), and a room mention answered through
a configured LM Studio endpoint.

v1.9.0: DaggerAgent 1.9.0

Choose a tag to compare

@github-actions github-actions released this 03 Sep 14:54

DaggerAgent 1.9.0

Banter mode (#9): DaggerAgent as an agent in a Banter room server.

dagger banter logs into a Banter server as an ordinary agent user,
joins rooms, and answers with DaggerAgent's own LLM/tool turn loop -
tools, sub-agents, job persistence and all. The Banter.Agents.Sdk
decides when to speak (delegation, @mentions, egress rules);
DaggerAgent decides what to say. One conversation per room.

Identity is key-backed, per the issue:

  • dagger banter --enrol <code> redeems the one-time enrolment code
    from the Banter desktop client's agents page: it generates a P-256
    keypair locally, sends only the public half, keeps the private key,
    and prints the identity and key fingerprint. The code is spent
    either way, and enrolment is its own invocation on purpose.
  • The key at rest is DPAPI-wrapped for the current user on Windows;
    elsewhere it is the SDK's user-only-permissions file. Keys enrolled
    by banter-warden still load.
  • An existing key file is never overwritten (it would strand the
    identity), and a truncated or foreign key is reported as itself
    before connecting rather than as "invalid credentials".
  • A configured password still works, but is refused when a key file
    also exists - whichever silently won, the other would be the stale
    credential nobody noticed.

Configuration lives in the new Banter appsettings section (server,
user, key file, rooms, routing attributes, model, system prompt);
--server, --user, --key, --pass and --rooms override.

Builds against Banter.Agents.Sdk 0.1.0 from the Wixely feed
(first published Banter release, tagged for this).

v1.8.0

Choose a tag to compare

@github-actions github-actions released this 31 Aug 04:19

Live tool progress end to end: SSE heartbeat, delegated-run visibility, ACP client with permission forwarding, Codex app-server support.

  • Live tool_progress on the jobs SSE stream. While any tool call is in flight, a
    frame each second lists every running call with its elapsed time; the web UI turns the
    pending ellipsis into a live counter. ToolCallEvent gained CallId and
    ParentCallId, so a sub-agent's tools attribute to the spawn_subagent call they run
    under and render nested (spawn_subagent … 5.9s ↳ exec_shell 5.9s). tool_result now
    carries the notifier's own measured durationMs. A keep-alive comment goes out every
    15s when nothing is running, so an idle-timeout proxy can no longer drop the connection
    mid-turn — which cancelled the turn and killed any delegated CLI with it.

  • delegate_to_claude streams. Switched to --output-format stream-json; the run's
    own tool calls surface live as children of the delegation (delegate_to_claude ↳ PowerShell 0.2s). The terminal result event carries the same envelope as before, so
    session resume and usage logging are unchanged. A run killed mid-stream now salvages
    the assistant text seen so far. Verified against claude 2.1.161.

  • ACP client: delegate_to_acp_<name> tools. Tools:AcpAgents entries spawn
    long-lived agents speaking ACP over stdio (e.g. another DaggerAgent via dagger acp),
    pooled per (job, agent, cwd) — successive delegations continue one live session, no
    per-call spawn, no session-id juggling. The agent's activity feeds the same
    tool_progress pipeline. Gated by AllowCliDelegation.

  • Permission forwarding. PermissionPolicy: deny | allow | ask per ACP agent. ask
    routes the child agent's permission request to whoever is driving the job: the web UI
    renders inline Allow/Reject buttons in the transcript (permission_request frame,
    POST /agent/permissions/resolve), and an agent-side ACP session forwards it upward as
    a session/request_permission of its own — editor ⇄ DaggerAgent ⇄ delegated agent.
    Nobody driving, or no answer in PermissionTimeoutSeconds, falls back to deny.

  • Codex app-server protocol. Protocol: codex-app-server on an agent entry drives
    Codex's JSONL dialect (thread/turn/item, approvals answered accept/decline) behind the
    same tool surface, pool, progress feed and permission path. Coded against the app-server
    documentation and verified against a protocol-faithful stand-in; not yet smoke-tested
    against a real codex binary.

Closes #7 and #8.

v1.7.2

Choose a tag to compare

@github-actions github-actions released this 25 Aug 03:24

Same code as v1.7.0 and v1.7.1 — this release exists to fix how release notes are produced.

No functional change since v1.7.0: the only commits since are to the release
workflow itself, so the binaries are equivalent. v1.7.0 published its last commit
message as the release body and v1.7.1 published generated notes, both because the
annotation was read from the checked-out repo. actions/checkout resolves the ref to
a commit and force-fetches it over refs/tags/, so the annotation is unreachable
locally no matter how checkout is configured. The notes are now read over the API
instead. If you are reading this text on the release page, that fix works.

The full contents of the 1.7.x line:

  • Tool-call events. IToolCallSink publishes a started/completed pair around every
    tool invocation, carrying job id, depth, tool name, duration, outcome and result size.
    Published from LlmAgent.WrapTools, so it covers the streaming and non-streaming turn
    paths alike — CLI mode and the non-streaming /jobs endpoints previously produced no
    tool activity at all. Events carry no raw arguments: ArgsDigest is the argument names
    plus a hash of the values, so a repeated call stays recognisable without arguments
    reaching a display. Subscribe by resolving ToolCallSink.

  • Tools.CliDelegationTimeoutSeconds (default 300, runtime-tunable). A delegated
    claude/codex/copilot run was previously bounded only by the parent agent's cancellation.

  • Tool-result offloading never fired. OffloadingAIFunction tested result as string,
    but AIFunctionFactory marshals return values through System.Text.Json and hands back a
    JsonElement, so the test was null every time. MaxToolResultChars and the
    read_tool_result / head_tool_result / tail_tool_result / grep_tool_result family
    had been inert for every built-in tool.

  • Delegated CLI sessions did not survive a restart. CliSessionStore was in-memory, so
    a restart silently dropped every delegated conversation's session_id and the next call
    cold-started an amnesiac CLI. Now backed by a cli_sessions table, cleared with its job.

  • Timed-out child processes discarded their output. exec_shell and CLI delegation read
    their pipes with a cancellation token, and ReadToEndAsync throws its whole buffer away
    when that fires — so a command that ran the full timeout returned nothing at all. The
    kill now closes the pipes and the captured output is returned with the error.

  • Two high-severity advisories. Microsoft.Data.Sqlite to 10.0.11 (clears
    GHSA-2m69-gcr7-jv3q via SQLitePCLRaw 2.1.12) and a direct Microsoft.Bcl.Memory 10.0.11
    pin overriding the vulnerable 9.0.4 that Microsoft.ML.Tokenizers.Data.O200kBase pins
    (GHSA-73j8-2gch-69rq).

  • Release notes ignored the tag annotation (this release).

Offloading becoming active is a real behaviour change. At the default 16 000 characters a
wide grep or a large read_file now returns a placeholder and the model must fetch the
content via the tool-result tools. Raise Tools.MaxToolResultChars to tune it, or set 0
to disable.

v1.7.1

Choose a tag to compare

@github-actions github-actions released this 25 Aug 02:12

Full Changelog: v1.7.0...v1.7.1

v1.7.0

Choose a tag to compare

@github-actions github-actions released this 25 Aug 01:38

Make tool-result offloading actually fire

OffloadingAIFunction tested "result as string" and returned early when it was
null. AIFunctionFactory marshals return values through System.Text.Json, so a
tool declared as returning string hands back a JsonElement and that test was
null every single time. Offloading has therefore never run: MaxToolResultChars
and the whole read_tool_result / head_tool_result / tail_tool_result /
grep_tool_result family have been inert for every built-in tool.

Demonstrated by passing a null store with a 100-char threshold and a 5 000-char
result: it returned the result inline and did not throw, so the offload branch
was never entered.

Use ToolResultText.AsText, added in the previous commit for the same reason.
Non-string JSON offloads on its raw text - a large object costs the same
context as a large string.

Note this changes live behaviour for the first time. At the default 16 000
chars a wide grep or a large read_file now returns a placeholder instead of
inlining, and the model has to fetch the content. Verified end to end that the
payload survives byte for byte and that grep_tool_result retrieves it, since
those consumers had never actually been exercised on this path. Raising
MaxToolResultChars tunes it without reverting the fix.

Co-Authored-By: Claude Opus 5 (1M context) noreply@anthropic.com

v1.6.0

Choose a tag to compare

@github-actions github-actions released this 24 Aug 07:40

What's Changed

  • Bring the mobile theme to the desktop UI and retire Halfmoon by @Wixely in #2

Full Changelog: v1.5.0...v1.6.0

v1.5.0

Choose a tag to compare

@github-actions github-actions released this 20 Aug 17:18

What's Changed

  • Add streamlined mobile agent UI by @Wixely in #1

New Contributors

  • @Wixely made their first contribution in #1

Full Changelog: v1.4.0...v1.5.0