Skip to content

agenttalk 0.102.0

Choose a tag to compare

@zoolok17 zoolok17 released this 16 Oct 18:18
· 243 commits to master since this release
7d81eef

In short: a team is easier to watch, an agent that has run for a long time can be given a
fresh start with one command, and three faults that stopped people are fixed.
agenttalk overview prints the dashboard's Overview in the terminal, in plain words, and the
new /agenttalk (Claude Code) and $agenttalk (Codex) skills run it. agenttalk status and
the dashboard show how large each agent's conversation has grown and warn before it gets
expensive; agenttalk session fresh then starts that agent's next turn on a new conversation
without stopping it. Fixed: agenttalk backup works when the team folder and the backup
folder are on different drives; an agent that is stuck waiting on a message it cannot run can
be stood down with agenttalk release; and on Linux and macOS a background agent starts from
a normal virtual environment (python3 -m venv), so the --copies workaround is no longer
needed. After upgrading, run agenttalk install-skills to get the two new skills.

Added

  • agenttalk overview shows how the team is doing on one screen, and /agenttalk and $agenttalk run it for you.
    It is the terminal's version of the dashboard's Overview.

    What you will notice: a new command, agenttalk overview, prints about one screen in plain words:
    what needs attention, who is waiting for whom, how each agent is doing, and whether the release
    checks are holding anything up. In a Claude Code seat you can type /agenttalk, and in a Codex
    seat $agenttalk; both only run the command. It is read-only: it never moves a message cursor,
    changes anything, wakes an agent or calls a model. The paid-model spend is left out unless you
    add --enable-budget, because that ledger covers the whole machine and any seat can run the
    command.

    What you need to do: nothing. Run agenttalk install-skills to get the two new skills.

    Technical details: new overview.py renders only what the dashboard's own builders return
    (web.build_state, web.build_attention, web.build_gates), derives nothing, and leaves out a
    field the builders leave out. --json prints those three payloads (plus budget with the flag).
    Output is plain ASCII, so it reads the same on Windows, Linux and macOS.

  • agenttalk status and the dashboard now show how large each agent's conversation is, and warn
    before it gets expensive (#475, part 1).
    An agent that runs in the background keeps one
    conversation for as long as it lives, and every turn sends all of it again, so a long
    conversation makes every turn, even an idle check, cost more.

    What you will notice: each agent's row in status (and its Capacity card in the dashboard) has a
    new line saying either how many tokens of context its last turn used, when its AI reports that,
    or how many turns it has run in total. It always says which of the two it is. The turn count is
    cumulative: a fresh start does not reset it, so it can include earlier conversations, and the
    warning says so; only the token figure describes the current conversation. Above a limit the line
    carries a warning. The warning is advice only: nothing is restarted,
    stopped or changed, and no message is sent. The limits are 150,000 tokens for Claude, 190,000 for
    Codex, and 300 turns for either; the token limits sit at about three quarters of the context
    windows those tools report, and 300 turns is well above the 170 to 230 that healthy agents reach
    and far below the 830 behind the report.

    What you need to do: nothing. To change a limit, add conversation_warn_tokens or
    conversation_warn_turns to supervisor.json, either one number for both tools or
    {"claude": n, "codex": n}; an unusable value is ignored. Starting an agent on a fresh
    conversation with one command is the next part of #475 and is not in this change.

    Technical details: new module conversation_size.py; additive conversation_size object
    (basis is context_tokens or turns_total, plus value, limit, warn, cli) in
    status --json and in each agent of /api/state, left out when neither figure is known. The
    token figure is context_tokens from the agent's capacity snapshot (an expired reading counts
    as absent); the turns figure is turns from the wrapper session record, shown only when the record has one (an absent counter is unknown, not 0). A reading of 0 is a reading. Limits must be positive whole numbers. supervisor.json is read the way the supervisor reads it (a byte-order mark is fine), and the dashboard and status resolve each agent's tool the same way. Read-only.

  • Start an agent on a fresh conversation with one command (#475, part 2). An agent that runs
    in the background keeps one conversation for as long as it lives, and every turn sends all of it
    again, so a long-lived agent gets slower and costlier. Until now the only way out was editing
    the agent's session record by hand. agenttalk session fresh --for <agent> --reason "..." now
    asks the agent's own wrapper to start its next turn on a new conversation. The wrapper does it
    between turns: at once if the agent is idle, or right after the turn that is running. Nothing is
    stopped and no file is edited by the command. The old conversation is never resumed, the request
    is applied exactly once, and a second request while one is waiting is refused. agenttalk status
    shows fresh=pending and then fresh=applied (with the reason and the turn count it started
    from, in status --json). The old session record is kept beside the new one. The agent itself,
    a lead or the operator-facing agent may ask. Works for Claude and Codex agents. The agent starts
    without its old conversation, so it should leave a note of what is next before it is asked to
    start fresh; the automatic handover note is planned (#475, steps 2 and 3).
    Technical detail: the wrapper loads <agent>.wrapper-session.json once and saves its own copy,
    so an outside edit could be overwritten or ignored. The command therefore only writes a
    <agent>.fresh-request marker. wrapper/session.py apply_fresh_request is called from the
    wrapper's own thread before each turn is built (both drives) and on each idle poll: it resets the
    in-memory session (a new Claude session id, or a cleared Codex thread), saves the request id with
    the reset, and only then clears the marker, which is what makes it apply once even after a crash.
    The outcome is recorded in the session record (fresh_request_*) and projected by
    Store.read_fresh_status and, as the reset reason fresh_requested, by the dashboard reader.

Fixed

  • agenttalk backup now works when the team folder and the backup folder are on different drives
    (#505).
    A backup first checks whether it can make "hard links" (a second name for the same file,
    which is fast and uses no extra space) and otherwise copies the files. That check linked two test files
    inside the backup folder, so it never noticed that the team's own files were on another drive, and the
    backup then stopped with an error (WinError 17 on Windows, "Invalid cross-device link" on Linux and
    macOS).

    What you will notice: before this, a team on one drive (for example D:) with the default backup folder
    on another (C:), or on a separate data disk, got an error and no backup. Now the backup completes. It
    copies the files, and agenttalk backup says mode: copy (no hardlink support); the backup's
    manifest.json says "hardlink_used": false. On one drive nothing changes: it still uses hard links.

    What you need to do: nothing. Until you have this version you can set AGENTTALK_RECOVERY_DIR to a
    folder on the same drive as the team folder.

    Technical details: recovery._probe_hardlink_support now links one real store file into the backup's
    staging folder (and removes the link) instead of linking two probe files inside it, and
    recovery._clone_tree copies a file whose link fails and returns whether every file was linked, so
    hardlink_used is true only then. Tests: tests/test_recovery.py (a forced cross-device os.link, a
    link that fails after the probe passed, and a same-filesystem control). Checked for real on Windows
    with the store on D: and the backup folder on C:.

  • A parked agent can now be stood down with agenttalk release (#488). An agent whose next message it
    cannot run is "parked": it keeps that message at the front of its queue and waits. Until now a release
    sent to a parked agent was never read, so the agent kept running, and the only way to stop it was to kill
    its process, which cannot be done safely from outside (it may be starting a paid model call at that
    moment). Now the agent notices a valid release waiting behind the parked message
    and stands itself down between turns, the same as an idle agent. It starts no turn after it has accepted
    the stand-down. The parked message itself is not touched: it stays first in the queue and unread until
    something resolves it. The release also stays unread for now (an agent has one reading position, so
    reading the release would also have read the parked message); agenttalk status shows
    stand_down=honoured for it until it is reached. When the agent is started again, it does not stand down a
    second time for that release: it consumes it silently and runs.
    Technical detail: wrapper/loop.py _stand_down_behind_held_head runs right after the head's attempt
    record is read and before any park, re-probe or drive. It applies when the head is held (a sticky
    config_blocked, a usage-limit or provider park, or a gateway hold that is re-driven every poll, which is
    remembered in held_head_id). It validates the release with classify_loop_control (same authority rules
    as an idle release), records its id with Store.record_stand_down_honoured (state/<agent>.stand-down.json,
    20 entries, written before the loop returns; if it cannot be written the agent keeps running), and returns
    without consuming or reordering the head. A later loop that reaches an honoured release consumes it without
    exiting. Covers both drives and a new wrapper generation that meets the same parked head (it stands down
    before the one re-probe).

  • A background agent now starts from a normal virtual environment on Linux and macOS (#493).
    The wrapper looked up its own Python by following the environment's link to the system Python, which
    does not have agenttalk installed, so it refused to start.

    What you will notice: if you install agenttalk into a standard virtual environment (python3 -m venv)
    on Linux or macOS, agenttalk wrap now starts the agent instead of stopping with "No module named
    agenttalk". The agent's own agenttalk commands use the same environment. Windows is unchanged.

    What you need to do: nothing. If you worked around this with python3 -m venv --copies, you can go
    back to a normal environment.

    Technical details: _agenttalk_py() and the owed-action dispatch pin (_pinned_executable) now use the
    interpreter path as the process was started (made absolute, not resolved through links) via the new
    interpreter_path.launch_path. Windows keeps the resolved path. The dispatch pin still checks that the
    target is a regular file. The supervisor, the comprehension worker and the doctor fallback already pass
    sys.executable unresolved. The gateway service identity (ovh_gateway_service, used for the scheduled
    task and the systemd unit) still resolves its executable; that is unchanged here.