Skip to content

Releases: zoolok17/agenttalk

agenttalk 0.104.0

Choose a tag to compare

@zoolok17 zoolok17 released this 22 Oct 18:55
30db495

A team can now share what it learned with another team: one team exports some of its own checked lessons as a pack file, and another team loads that pack from a folder it checked out itself. Nothing is downloaded or sent anywhere by agenttalk. Pack lessons can also carry the date they were last confirmed, so old advice no longer looks new. The release also adds two roadmap sections on research into AI that improves itself (documentation only).

After upgrading, preview the skill update with agenttalk install-skills --dry-run --force, back up any local edits you want to keep, then run agenttalk install-skills --force. The plain command keeps files that differ, so it cannot refresh changed skills. To use a pack from another team, read the pack file first and take out anything confidential, then run agenttalk knowledge pack load <name> --from <folder>.

Added

  • A team can now share lessons with another team as a lesson pack, and load another team's pack
    from a folder.
    Until now a new store could start only with the lessons that ship with agenttalk.
    What one team learned stayed in that team's store, and there was no way to hand it over.

    What you will notice: agenttalk knowledge pack export --name <name> --out <folder> (with --key
    once per lesson, or --tag) writes some of your team's own verified lessons as a pack file, ready
    for a person to read before it is shared. Next to it, it writes a provenance file that links each
    lesson back to your store; that file stays with your team. Lessons that are not verified, are
    retracted, are replaced by a newer lesson or came from a pack are never exported. The export never
    publishes, commits or pushes anything, and it refuses to overwrite a different pack of the same name
    unless you add --force.
    agenttalk knowledge pack load <name> --from <folder> loads such a pack from a folder you checked
    out yourself. agenttalk never downloads anything and reads only the lesson files, never roles,
    prompts or brief templates. The rules of the shipped packs apply: your team always wins, loading
    the same pack again writes nothing, and unload takes it back. Outside packs have their own key
    prefix and tag, so they can never mix with a shipped pack, and a name that a shipped pack uses is
    refused. knowledge pack list shows where each outside pack came from. Before this, a lesson
    pack's review and expiry dates always counted from the day it was loaded, so old advice looked new.
    Now a pack line may say when the lesson was last confirmed, and the dates count from then. A pack
    with a bad line is refused as a whole, the message names the line, and nothing is written.

    What you need to do: nothing. Read an exported pack, and take out anything confidential, before you
    share it.

    Technical details: knowledge_pack.py gains read_pack(name, folder=...), load(..., folder=...),
    unload(..., outside=...) and export(...); cli.py gains pack load --from, pack unload --outside and pack export. An outside pack's id is ext.<name>: keys pack.ext.<name>:<slug>,
    tag pack-ext.<name>, ledger entry ext.<name>. Shipped pack names cannot contain a dot, so the two
    namespaces never meet. The ledger entry gains source (folder, file_sha256, retired_sha256 when
    there is a retired file, and commit, read with git rev-parse --verify HEAD when the folder is in a
    git checkout). The event schema is unchanged. The optional last line field confirmed_at (an ISO
    date or date and time, not in the future) sets review_after and expires_at to 365 and 730 days
    after it, and a newer confirmed_at counts as a change on reload. The line reader now also refuses a
    key or tag with the reserved pack. or pack- prefix, a line that is not UTF-8 or holds an unpaired
    surrogate, and a <name>.retired.json that retires a slug the pack still carries, and names the line
    for every refusal. Records end only at a newline (_physical_lines), never at U+0085, U+2028 or
    U+2029, which the export writes unescaped (_dump_line, shared by the export's checks and its writer).
    Before writing, the export reads its own bytes back the way the loader does, and it refuses when the
    folder's retirement file is malformed or retires an exported slug; it never changes that file. Export
    keeps each lesson's (domain, key) identity: a bare --key held by several domains is refused with
    the candidates listed, and --key <domain>/<key> names one. Ownership is read from content provenance
    (curated_origin), never from the key's spelling, so a team lesson keyed like pack.<x>:<y> exports.
    Supersession follows the store, which applies a supersedes key in every domain. The report carries
    provenance_changed next to unchanged, and an existing non-UTF-8 pack or provenance file is
    refused with its path. Export slugs are the key in lower case with each run of other characters
    turned into one dash (cut to 60 characters with an 8-character hash ending); two lessons that would
    share a slug refuse the export. Tests:
    tests/test_knowledge_pack_outside.py. Docs: docs/USER-MANUAL.md (Share lessons with another
    team) and docs/playbook/learning.md (L5).

agenttalk 0.103.0

Choose a tag to compare

@zoolok17 zoolok17 released this 21 Oct 02:23
617a4ff

New teams get clearer setup and restart advice, more useful lesson searches, and fewer repeated refusals when saving what they learned. Leads are reminded when a teammate is waiting for a decision, and can pass that decision on with one command. New skills, the team playbook and the migration guide help teams agree what done means and carry lessons into their next project.

After upgrading, preview the skill update with agenttalk install-skills --dry-run --force, back up any local edits you want to keep, then run agenttalk install-skills --force to refresh the bundled skills. Restart wrapped agents after switching their tool runtime. Existing teams can use agenttalk knowledge pack load migration to load the bundled migration lessons; new stores receive them at setup.

Added

  • The team playbook: docs/playbook/ collects the standing team rules and the reasons behind them (#534, #547).

  • A shared meaning of "done" for every task: the new definition-of-done skill. Teams
    lost time when "the work is finished", "the product is accepted" and "it may be released"
    were taken for one thing. The skill keeps them apart and gives every task the same five
    things to show when it is handed over: what was asked and what came out, the exact thing
    delivered, the checks that really ran, what is left open, and who acts next. Bigger or
    riskier work adds rows by kind (review, QA and test, documentation, investigation, bug fix,
    refactor, CI fix, feature, whole project or release, one migration slice, a whole migration). A check that could not
    run stays open until the person with authority records a reduction of scope; the rules
    are pinned when a task is assigned, and a lesson changes them only after review. It
    reuses the existing evidence fields, the close flow and the release-readiness review
    instead of adding new ones, and a project keeps its own rules in a short overlay file.
    Its replay on six finished jobs from this repository is in
    docs/research/DOD-REPLAY-2026-10.md.
    Technical detail: src/agenttalk/skills/devkit/definition-of-done/ (SKILL.md,
    references/migration.md, references/project-overlay.md), policy definition-of-done@1,
    evidence profiles production-handoff, review-result, qa-result and planning-artifact by task kind; routing and the skills tables list it.

  • A lead is now reminded of the decisions it still owes to seats that wait for them.
    When a seat says it is waiting for a lead's decision and the result it waits for has
    finished, the lead used to hear about the result and then nothing more; the seat could
    wait for a long time. Now agenttalk works out, from the messages themselves, which
    hand-offs are still owed. It shows them after the lead reads messages and on every turn of
    a wrapped lead, and reminds the lead again if the first reminder is ignored. A new command,
    agenttalk relay result, hands the decision over exactly once (also when it is run twice
    or two processes race), or closes it as not needed or unresolved. This is best effort and
    covers only seats that said they wait: a seat that never said so is not seen. Message
    cleanup (compact) no longer removes what an open hand-off depends on. A second new
    command, agenttalk lead-routine, records which parts of the lead's routine were done
    and by what, and keeps the parts that agenttalk cannot check (handover note, machine
    resources, scheduled timers) apart so they are never mistaken for covered.
    A finished hand-off stays finished when old messages are cleaned up in several steps, and a re-asked
    request no longer offers its old answer. Only the command's own message closes a hand-off, and the
    routine record keeps the sweep's findings and the lead's own word apart for every part.
    A hand-off is no longer closed by an older one, a cancelled or incomplete request no longer produces
    one, a mistyped seat name in relay_to is refused when the request is sent, and the reminders stay
    fair however many hand-offs are open. A seat that waits again can be answered again, the operator is
    told about an overdue hand-off at the third reminder and then once a day, and a request id with a comma
    is refused when the request is opened. A hand-off for an older wait never counts as the answer to a newer
    one, even when the two cross while a command is running. A hand-off is refused unless that seat has an
    open wait for it (a mistyped seat name, or a wait the seat cancelled), and a cancelled wait stays cancelled.
    (Technical detail: derived obligations in lead_relay.py; Store.send_operation gained a
    precheck run inside the publication lock; Store.archive_messages_batched recomputes the
    protected floor under the rank-100 and rank-160 locks; routine record in
    lead_routine.py; design docs/DESIGN-lead-loop-default.md.)

  • A new team starts with the migration lessons, and agenttalk knowledge pack loads, lists and
    removes lesson packs.
    What several practice migrations taught us (124 short lessons: how to
    move a codebase to a newer framework, language or platform and prove that it still behaves the
    same) is now part of agenttalk, together with a plain-words guide, docs/MIGRATION-PLAYBOOK.md.

    What you will notice: agenttalk init now loads the migration pack into a store it creates
    and says so; pass --no-packs to start empty. Running init again on a store that already exists
    never loads a pack and never undoes a --no-packs or an unload. The lessons show up in agenttalk knowledge search --type lesson and carry the key prefix pack.migration: and the tag pack-migration. They always rank
    after your own lessons, and they never take one of the five lesson slots that agenttalk puts into
    an agent's turn, so an agent finds them when it searches, not before. agenttalk knowledge pack list, load <name> [--dry-run] and unload <name> manage packs later. Your team always wins:
    a pack lesson you retract, replace with a lesson of your own, or republish is never brought back
    or changed by a later load or upgrade, even after an unload, and loading the same version twice
    writes nothing. The prefix pack. is reserved: knowledge publish refuses a new key that starts
    with it. A lesson of your own whose key already starts with pack. keeps working as before.
    agenttalk knowledge pack list counts from the store (live, retracted by the team, changed by the
    team), not from the loader's bookkeeping.

    What you need to do: nothing. An existing store gets the pack only if you run
    agenttalk knowledge pack load migration.

    Technical details: new knowledge_pack.py and the data file
    src/agenttalk/knowledge_packs/migration.jsonl. The file is part of the wheel; dev-gate.json does
    not list it (the gate pins its list of wheel resources), so a test builds the wheel and checks that
    the pack is inside (it is skipped where the build tool hatchling is not installed).
    The loader writes a publish and a curate event per lesson (author, owner and curator
    agenttalk-pack, domain process; evidence becomes evidence_ref; review and expiry dates are
    relative to the load). The pack name and version are not in the events: they live in the ledger
    .agenttalk/knowledge/packs.json. Whose a lesson is, is read from the store: every event the loader
    writes carries two marks, the author agenttalk-pack and authority.resolved_from set to pack.
    No ordinary command can set the second one, so a member of the team who is called agenttalk-pack
    cannot pass for the loader (the name is also now refused for new rosters and new publishes). Any
    later event by someone else (a republish, a retraction, a re-verification, a lesson that supersedes
    it) makes the lesson the team's for reload and unload. For ranking and for the injected slots only
    the content counts: a lead verifying an unchanged pack lesson does not turn it into a team lesson,
    a team republish of the same key does, once it is verified (while it is only a proposal, readers
    still show, and rank, the verified pack text as pack content). So a load or unload that
    is cut short before the ledger is written is recovered by the next run, which adopts what it finds
    instead of writing it twice. A later pack version may carry <name>.retired.json; keys it retires, and keys it
    removes, are retracted unless the team touched them. In knowledge.py the lesson rank gains a
    first tier (team lessons before pack lessons, by where the displayed version's content came from: each event
    carries the loader's two marks of the publish it comes from; not the key, the name or who verified it
    last) and
    lesson_context.select_lessons skips pack lessons.

  • A new skill, thinking-games, for the few moments when a different way of thinking helps.
    Some decisions get better when someone looks at them from a different angle. The new skill gives
    agents short thinking games, and roleplay cards to think from, for a few named moments only: at
    the start of a new design, before it is challenged (the challenge skill is where an independent
    agent asks whether the work should be done at all); after two failed attempts on the same
    assumption, outside a round of fixes ordered by a review (then only the "reality probe", which
    ends in a real test); and as a side round on product ideas, after agents have given their ideas
    the plain way. It is not for routine work, fixes ordered by a review, releases or every task. One
    game per moment is enough (in a team round, one per pair or group).

    How it works: two lists of ideas are written from the same short description of the decision,
    one the usual way and one with a game. The second list is written by another agent, or by a fresh
    one that never saw the first list; when that is not possible, the round is labelled "not
    independent". Every idea says what it would do, what it should improve, how i...

Read more

agenttalk 0.102.0

Choose a tag to compare

@zoolok17 zoolok17 released this 16 Oct 18:18
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)...

Read more

agenttalk 0.101.1

Choose a tag to compare

@zoolok17 zoolok17 released this 14 Oct 03:18
c3f8b52

In short: one fix for the paid gateway. When the model pauses for a long time in the middle
of a reply, the gateway now waits up to ten minutes for the next piece instead of two. Such a
call used to end as an "uncertain" paid attempt that stopped every gateway seat until someone
settled it by hand. The gateway also writes one log line for each reply it streams, so a
future stall shows what happened. Nothing else changes: LiteLLM, the spending ledger and the
prices are as before, and the installed skills do not need refreshing.

Fixed

  • A long silent model reply no longer ends as an uncertain paid attempt (#424, part A). The
    gateway's front door gave up when the model sent nothing for two minutes. That left the paid
    call "uncertain" and stopped every gateway seat until someone settled it by hand. Once a reply
    has started, the front door now waits up to ten minutes for the next piece (connecting and
    starting the reply still wait two minutes). It also writes one line per started reply to
    stream-waits.jsonl in the gateway's state folder: the longest wait for a byte, the total
    time and how the call ended, so the next incident shows what really happened. A reply that
    stays silent for more than ten minutes is still marked uncertain, exactly as before; the
    LiteLLM version, the ledger and the prices are unchanged.
    Technical detail: FrontConfig.stream_idle_timeout_seconds (STREAM_IDLE_TIMEOUT_SECONDS,
    600 s) is applied to the upstream socket after the response headers arrive; the front keeps
    the socket from before getresponse() because http.client drops it on "Connection: close".
    request_timeout_seconds (120 s) is unchanged for connecting and waiting for the headers.
    GatewayFront.stream_wait_observer receives one record per started reply, and StreamWaitLog
    (bounded to 1 MiB, one rotation) writes it.

agenttalk 0.101.0

Choose a tag to compare

@zoolok17 zoolok17 released this 12 Oct 09:57
7385c7c

In short: the checks that decide whether a team's work is finished are stricter and say more
clearly what is missing. A seat that runs through the paid gateway can no longer satisfy any
required review, and an acknowledgement counts only while its author is still an active,
trusted seat: a finished result that rested on a reviewer who has since left now needs a
current reviewer to acknowledge it again (an acceptance close whose runner has left needs a
new attempt instead, as described below). The check before an irreversible step names
exactly what holds a request back and also stops on an outdated request. When agenttalk gateway start fails before the task-start request is accepted, the gateway keeps its stop
file; after that point the command says the gateway may be starting and how to check and
stop it. agenttalk scratch store sets up a throwaway store that commands in that shell
cannot leave (an ordinary folder alone does not: set it up with that command). The
documentation set gained a license, a technical overview, a page on roles, skills and
procedures, and operator procedures that put each safeguard before the step it protects; the
source package now ships the documents its own tests read. After upgrading, refresh the
installed skills as described under "Lead skills" below.

Added

  • The repository now carries its license. agenttalk has always been offered under the
    MIT license (the package says so), but the repository had no license file, so GitHub
    showed "no license", which by default means nobody may reuse the code.

    What you will notice: a LICENSE file with the MIT text and the line "Copyright (c) 2026
    the agenttalk authors". GitHub now shows the MIT license, and the installed package
    carries the same file. Nothing to do.

  • A technical overview of how agenttalk is built (docs/OVERVIEW.md). One new page
    that explains how agenttalk is put together, for someone who will run or extend it.

    What you will notice: a new page, docs/OVERVIEW.md. It shows the parts and how they talk
    to each other, where the data lives under .agenttalk/ (and what a reset keeps), a
    message's life from send to reply, how the supervisor, wrapper and agent processes relate,
    how the console and the paid gateway work, and which promises hold and which do not. It has
    five diagrams, a short list of the words it uses, and an appendix of interfaces. Nothing in
    the program changed, and no other page was changed.

    What you need to do: nothing.

    Technical details: the page was checked against the code of release 0.100.0. It states the
    Python versions the project's tests run on (3.10 to 3.13 on Linux, Windows and macOS). Where
    an older page and the code disagreed, the page follows the code.

  • One page says who does what in a team, which skill to use, and the steps the team follows.
    This information was spread over several older pages, some of them out of date. It is
    the first page of the smaller documentation set the operator asked for on 2026-10-10.

    What you will notice: docs/ROLES-SKILLS-PROCEDURES.md describes each role, with what it
    does, what it must never do and how it hands work on:

    • the operator and the liaison;
    • the lead, developer, reviewer, tester, architect and challenger;
    • a seat that works through the paid gateway.

    It has one entry for every shipped skill, saying when to use it. It also gives current
    step lists for handing out work, the review cycle, the merge gate, the release ritual, the
    challenge, the acceptance pass, the lessons lookup, capturing lessons and scratch hygiene.
    It states the merge rule the team now follows: one recorded GO on the exact head commit, from
    a reviewer who did not build the change, with green CI and every automated P0, P1 and P2
    comment triaged. It retires the older rule of two reviewers both re-approving the final commit. Its
    facts were checked against the code of this version.

    What you need to do: nothing. The older pages stay until a later change moves them to an
    archive.

    Technical details: tests/test_roles_skills_doc.py fails when a shipped skill has no
    entry on the page, or the page names a skill that does not ship. A shipped skill is a
    Claude Code file in src/agenttalk/skills/claude/ or a folder with a SKILL.md in
    src/agenttalk/skills/codex/ or src/agenttalk/skills/devkit/.

  • An operations guide brings runtime upgrades and rollback, supervisor hosting,
    paid-gateway setup and spending limits, backups, recovery, logs and attended
    cleanup together in docs/OPERATIONS.md. It distinguishes shipped commands
    from steps that still need an operator or maintainer.

Fixed

  • The check before an irreversible step now says what is holding a request back. With both
    --epoch and --gates, a request that was still current but held only by a gate at HOLD was
    reported as "pre-epoch", and the agent was told to ask for the request again. It now says
    hold, names the gate and says not to act until it is GO (agenttalk gate check); a request
    from before the latest epoch barrier is still reported as one, and when both apply, both are
    named. The exit codes are unchanged (cmd_check in src/agenttalk/cli.py).

  • The source package now holds the documents its own tests read. The tests shipped in the
    source package read the new roles page, two pages under docs/ops/ and the staging example
    under docs/examples/, but the package left those files out, so those tests failed when run
    from it. The files are now included, with the new overview page, and a new test
    (tests/test_sdist_docs.py) fails when a test names a file under docs/ that the package
    leaves out.

  • The check before an irreversible step now also stops on an outdated request (#448).
    Before a merge, release, deploy or deletion, every seat is told to run agenttalk check on
    the request it is acting on. That check looked only for a withdrawn request and for gates on
    HOLD. When the team had since moved to a new epoch (someone ran agenttalk barrier bump),
    a request sent before that still passed, so a seat could act on instructions the team had
    already set aside.

    What you will notice: the wrapped-turn prompt, the lead, listen and handoff skills (Claude
    and Codex copies), the README and the agent, user and new-user manuals now give the check
    with --epoch. A request sent before the latest epoch
    barrier now makes the check exit 3, and the seat stops instead of going ahead. The seat needs
    no epoch value of its own: the check compares the epoch stamped on the request when it was
    sent with the current one.

    What you need to do: wrapped seats get the new prompt once their wrapper runs this version.
    A seat run by hand keeps its older installed skill files, because the installer leaves a
    changed file alone: preview with agenttalk install-skills --no-devkit --dry-run, back up
    local edits, refresh on purpose with agenttalk install-skills --no-devkit --force, then
    start a new session.

    Technical details: src/agenttalk/wrapper/prompt.py (_DEFAULT_RULES, the "Before any
    IRREVERSIBLE action" line), the six skill files, README.md, docs/AGENT-MANUAL.md,
    docs/USER-MANUAL.md and docs/AGENTTALK-NEW-USER-MANUAL.md; check --epoch is evaluated
    by _epoch_verdict in src/agenttalk/cli.py. The new tests/test_irreversible_check_text.py
    pins the full command in the prompt (both shells) and in every skill, that each Claude and
    Codex pair says the same thing, and that every check example on those four pages names
    --epoch; tests/test_skill_lint.py now pins --epoch --gates for the lead skills.

  • A seat that runs through the paid gateway can no longer give a required sign-off of a sign-off set (#447).
    Such a seat (an "external worker", a cheaper outside model with a narrower level of trust) was
    kept out of sign-off lists only at the moment the roster changed. If the sign-off policy or the
    domain lists were edited by hand afterwards, a close could list that seat as a candidate and
    count its sign-off.

    What you will notice:

    • A close now leaves a paid gateway seat out when it works out who may sign, so its sign-off
      is refused when given (close ack says why and records nothing, even with --override, and
      close signoffs override is refused for such a seat too) and is never counted, even if the
      record was edited to contain one.
    • An override recorded earlier now counts only while the seat that recorded it is still on the active
      roster and is not a paid gateway seat, the same test a signature already passes. If that seat was
      since reclassified as a paid gateway seat, retired, removed or renamed, the override is ignored as if
      it had not been recorded: the close goes back to HOLD (and says so) until a trusted seat signs, which
      then lets it through, or a current trusted lead records the override again. This deliberately turns
      an older GO that rested on such an override (for example one by a lead who later retired) into a HOLD.
    • Other candidates are not affected: a trusted seat in the same role or group still satisfies
      the sign-off. If the paid seat was the only candidate, the close stays on HOLD with the plain
      reason "its only candidate(s) run through the paid gateway (external workers), which cannot
      give a sign-off; add a trusted seat to the candidates (or override to escape)".
    • close check (text and --json) and close signoffs plan name the seats that were left out
      (signoff_exclusions and excluded_external_workers in the JSON); they show seat names only.
    • A close record whose stored sign-off state has the wrong shape (an override list that is not a table,
      a sign-off set without a text id, an ack whose author is not text) now gives the normal "malformed
      close record" HOLD instead of a crash.
    • The roster still refuses to name a paid seat as a can...
Read more

agenttalk 0.100.0

Choose a tag to compare

@zoolok17 zoolok17 released this 10 Oct 08:58
67fcffe

In short: closing a terminal window can no longer stop the gateway: its scheduled task now
starts Python without a console window, and gateway run writes its own messages to a log
file. Each machine that runs the gateway needs a one-time task update, with the steps in
"Closing a terminal window can no longer stop the gateway" below; the ledger, the price policy
and the spend checks are unchanged. Team members now look in the team's lessons once before
building, fixing or reviewing. Leads can release one finished worktree after merging
(agenttalk janitor --release). Team notes work before a domain registry is set up, scratch
cleanup checks its starting folders and their parents, a wrapped seat always replies under its
own name, and documentation-only pull requests can skip the long test queue.

Added

  • Team members now look in the lessons once before real work. Before building, fixing or
    reviewing something, a member searches the team's lessons for one concrete word from the task
    (for example junction), once, with one retry using another word only if the first search found nothing. The word goes last, after --, so a word that looks like an option is still read as the word. The search only reads; it
    never touches the inbox. A member names a lesson in its reply only if the lesson changed what it
    did, and keeps three cases apart: nothing found, the lookup failed (never written down as
    "found nothing"), and read but not useful. A failed lookup never stops the work. The wrapped-turn
    instructions, the listen skill (Claude and Codex copies) and the lead skill's brief guidance say
    so, and docs/ops/lessons-lookup.md names the rule, its start date and the seats that already
    did this by habit, so the lessons-use trial can measure reported use under one fixed rule.
    A search that reports a problem with the lesson store counts as incomplete, not as "found
    nothing". A hit whose preview is cut off (it ends in ...) is read in full, once, before it can
    change a decision. For that read, agenttalk knowledge search has a new small option, --key
    (with --domain), which returns exactly the lesson with that key, so other lessons that only
    mention the key cannot push it out of the result. Several lessons are reported in one
    comma-separated field. Wrapped members get the rule automatically after the wrapper is restarted on this
    version. A member run by hand keeps its older installed skill file, because the installer
    leaves a changed file alone: preview with agenttalk install-skills --no-devkit --dry-run,
    back up local edits, refresh on purpose with agenttalk install-skills --no-devkit --force,
    then start a new session. --no-devkit keeps the update to the bus skills; without it the
    installer would also overwrite the development skills, which sit in other folders. The steps
    are in the policy page.

  • Release one finished worktree after merging. Leads can use
    agenttalk janitor --release <path> to remove a clean, unused checkout while
    keeping its branch and commits. The command fetches the remote default branch
    and refuses when exact ancestry, files, links or activity records cannot be
    checked safely. Squash merges stay in place. --release-report lists eligible
    checkouts and sizes without deleting them; both lead skills now include it in
    the daily routine. Hidden Git edits and ambiguous launch folders prevent release;
    both supervisor state locations are checked. The guidance explains the need to
    stop other users and the limits of deletion checks on each platform.
    Stale file monitors cannot hide edits, nested repositories with capitalised
    metadata names are kept, and unrelated older lane records no longer block release.
    Bare repositories inside caches are kept too. Tracked files are compared by
    content, so matching file sizes and times cannot hide unfinished edits.

  • Permanent checks for mistakes that kept returning in usage readings (#301).
    Contributors can now run a small set of checks across publication and display paths,
    including deliberate faults that prove the checks detect a wrong account or an expired
    figure. A new danger-area page names other fragile areas and their existing guards.
    The checks include recorded events and the command and web displays. They also
    document an open checkpoint problem (#408), whose fix remains separate.
    This changes contributor checks and guidance, not runtime behavior. Nothing needs to
    be changed in an existing team.

Changed

  • Documentation-only pull requests can avoid the long test queue. Before
    this, every PR push ran the full test matrix and the extra Windows timing
    trial. Now changes to prose that tests do not use run the documentation and
    safety checks, and the trial runs only after pushes to master. Documents used
    by tests, including README and CHANGELOG, still take the full path. Code PRs
    keep the full test matrix; master keeps every check. Contributors do not need
    to change how they submit a PR. Technical details: the file rule and the
    result reported by dev-gate aggregate are documented in docs/DEV-GATE.md.

Fixed

  • Closing a terminal window can no longer stop the gateway. The gateway's
    Scheduled Task used to start Python in a console window. On 2026-10-08 a Windows
    Terminal update closed its windows, the gateway ended with it, its automatic
    restart did not bring it back, and the gateway stayed down for 16 hours.

    What you will notice: before this, the task started python.exe, which opens a
    console window. Now it starts pythonw.exe, the same Python from the same folder
    without a window, and LiteLLM starts without one too. With no window there is also
    nowhere to print, so gateway run now writes its own messages to a log file next to
    the LiteLLM log, set up before the gateway code loads. Without that, an error message
    would itself crash the run, and a failure while loading would leave no trace.
    task-install refuses, naming the folder, when pythonw.exe is missing, and
    task-install, gateway start and gateway status all refuse or report a launcher
    with no windowless twin, such as python3.exe. A task installed before this change
    shows up in gateway status as out of date, with the steps to update it; status only
    reports and changes nothing. gateway start and task-install refuse the old task
    with the same steps. task-install never overwrites a registered task: Task Scheduler
    cannot replace a task only while it is still the one agenttalk checked, so you end and
    remove the old task yourself. gateway stop accepts the old and the new task from
    either python.exe or pythonw.exe.

    What you need to do: once, on each machine that runs the gateway, run agenttalk gateway stop --timeout 30, then schtasks /End /TN <task> and schtasks /Delete /TN <task> /F (the task name gateway status shows), then agenttalk gateway task-install, then agenttalk gateway start, and check agenttalk gateway status.
    Run the agenttalk commands with the Python runtime that installed the task, after
    updating agenttalk in it: the old task is recognised only in that runtime's folder. On
    Linux nothing changes.

    Technical details: src/agenttalk/ovh_gateway_service.py (windowless_task_identity
    and _backend_identity for the Windows backend only, _registered_with_console and
    _task_update_steps for the refusals, the two-form stop_task, CREATE_NO_WINDOW for
    LiteLLM),
    src/agenttalk/gateway_run_log.py (route_missing_output_to_log, called from
    src/agenttalk/__main__.py for gateway run); status reports the errors
    task_console_launch and task_launcher_unsupported and the field task_update; the
    run log is %LOCALAPPDATA%\agenttalk-ovh\gateway\gateway.log. The ledger, the price policy,
    the spend checks and the binding are unchanged. See "The task runs without a console
    window" in docs/QWEN-OVH-TRIAL.md.

  • Team notes work before a domain registry is set up. Pointers, gotchas,
    seams and decisions can now use --domain process on a bus without
    .agenttalk/domains.json, with the same review rules as process lessons.
    Non-lesson notes still need an explicit domain. Buses with a registry keep
    their existing rules and note format. Unknown-domain errors now list the
    available domains and explain how to add one.

  • Four wording fixes in the shipped documentation and the lead skills (#362, #363, #355,
    #312).
    No behavior changed; the text now says what the code already does. The lead
    skills' "check before an irreversible action" example now shows --gates, so a lead
    following it word for word gets warned when a gate says HOLD instead of only when a
    request was rescinded (#362). The README's ack row now separates its two forms: without
    --to-request it moves a cursor, with --for <seat> --to-request <id> it closes that
    request's thread for that seat (a work order, a review, a proposal or a question), records the closure permanently, and does not move the cursor (#363). The lead skills no
    longer say a lead may never start a teammate; a lead can set up the team and start the
    supervisor when asked, but still never starts a teammate's own assistant directly,
    outside the supervisor or the wrapper (#355). And the gateway guide now states that its
    amounts are in EUR excluding VAT (#312). The policy data itself carries no tax label yet,
    so #312 stays open.

  • A wrapped seat that follows its reply instructions now always replies under its own
    name (#354, #178).
    The instructions the wrapper printed gave agenttalk reply with no
    --from, and the wrapper did not tell the seat's own process who it was. A seat whose
    settings did not happen to carry its name could stop with "no agent i...

Read more

agenttalk 0.99.0

Choose a tag to compare

@zoolok17 zoolok17 released this 08 Oct 14:29
5c5503c

In short: this release makes the usage readings real. agenttalk capacity, each seat's
capacity file and the dashboard now show each account's actual 5-hour and weekly usage, say
plainly when a reading is old, and never show one account's usage under another seat's name.
The dashboard now refuses requests that are not addressed to it as a local program, so a web
page you have open can no longer read it through a trick called DNS rebinding.
agenttalk janitor --apply no longer forces a delete. The dev gate records how long each test
took, and Windows test runs get more time for a month. The gateway and its ledger are unchanged
in this release, so upgrading needs no extra step.

Changed

  • Every test run in the dev gate now records how long each test took, and Windows test
    runs get more time for a month (#378).
    On Windows, the gate's full test runs had reached
    their two-hour limit: on 2026-10-06 one was stopped at 90% with no failure, and its twin
    passed 15 seconds under the limit. No per-test timings existed to decide what to change.

    What you will notice: before this, a test run's log listed only skipped tests and the
    result. Now it also lists the time of every test's setup, call and teardown, slowest first,
    before the result line. That adds about 3.5 MiB to each log, well under its 16 MiB limit. A run
    stopped by its time limit says its per-test durations are unavailable, so it is never read
    as zero. Windows test runs may now take 9,000 seconds instead of 7,200, and the Windows CI
    job 330 minutes instead of 270. Linux and macOS stay at 7,200 seconds and 90 minutes, and
    no individual test's time limit changed.

    What you need to do: nothing. The Windows margin is temporary: it expires on 2026-11-06,
    by when the new timings should show how to split or speed up the Windows runs. The reason
    and the date are recorded next to the values (windows_timeout_reason in
    dev-gate.json, and the comment in .github/workflows/tests.yml).

    Technical details: dev-gate.json (pytest args add --durations=0 --durations-min=0;
    new windows_timeout_seconds 9000 and windows_timeout_reason); src/agenttalk/dev_gate.py:

    • the manifest contract now pins the four pytest arguments;
    • _validate_windows_pytest_limit accepts the Windows value only together with its reason,
      and never below timeout_seconds;
    • _pytest_timeout_seconds chooses it on Windows (a CI leg is refused unless it runs on its
      declared OS);
    • run_command takes a timeout_note, and pytest runs pass
      PYTEST_DURATIONS_UNAVAILABLE.

    The Windows job ceiling is in .github/workflows/tests.yml, and docs/DEV-GATE.md has a
    new "Per-test durations and time limits" section. Tests in tests/test_dev_gate.py and
    tests/test_dev_gate_workflows.py include a real pytest run (the final result line stays in
    the 2,000-character diagnostic) and a real killed run.

Fixed

  • Usage readings are real again, say when they are old, and are shown per account (#301).
    agenttalk capacity and the per-seat capacity files say how full each seat's 5-hour and
    weekly usage windows are. On the desktop fleet none of those numbers was real: every Claude
    seat showed the same reading from 3 June, every Codex seat had none, and the files looked
    fresh because they were rewritten every minute. A lead deciding whom to give work to was
    shown old or missing numbers that looked current.

    What you will notice, for Claude seats: before this, a seat's reading came only from a
    status-line file that had not been written since June, and it was shown as if it were
    current. Now a wrapped Claude seat records its own rate-limit messages from Claude. They say
    whether a request was allowed and, when they include them, how full each window is. A
    message without a percentage is recorded without one, and a message that names no window
    (an ordinary turn's "allowed") is kept as the latest verdict; agenttalk never makes up
    either. A malformed figure in such a message is ignored and never stops the seat's turn,
    and a reset time outside any real date is dropped, so it can no longer break the web console
    or agenttalk status.
    The status-line file is only a fallback, read from the same Claude config folder the seat's
    Claude uses. A saved reading remembers the account it was taken under and is dropped, never
    relabelled, when the seat runs under another folder or provider, so a gateway seat is never
    shown the operator's Claude numbers. With no source at all, it says "Claude capacity source
    not configured" instead of a number. When Claude refuses a turn because a usage limit is
    reached, the seat publishes that reading right away, as it starts waiting, not only at its
    next quiet minute. A manual agenttalk capacity refresh --for <seat> run by the seat itself
    reads its own folder and provider, found the same way its wrapper finds them. Run for another
    seat, it never reads a folder of the shell that runs it, because that shell's ~/.claude and
    CLAUDE_CONFIG_DIR say nothing about the other seat's. It publishes that seat's own saved
    reading again, under the account its wrapper bound, or reads the --statusline-path you give.
    A folder is read only when it matches the account of the seat's saved reading. Otherwise it
    publishes "unknown" (claude_seat_source_unknown), with a hint to pass --statusline-path or
    let the seat's wrapper refresh it. A seat whose supervisor entry gives it its own
    CLAUDE_CONFIG_DIR is refreshed the same way.

    For Codex seats: before this, a seat without a Codex home of its own reported nothing, with
    the reason codex_home_missing. Now it reads the shared Codex home, but only its own session
    there, found by its thread id; a manual refresh uses only the thread the seat's wrapper saved.
    It never shows another session's numbers; without a thread it says so
    (codex_no_thread_yet). A Codex home, or its sessions folder, that is only a link to the
    shared one counts as the shared one. One limit remains: separate Codex homes seeded from one
    login show as separate accounts, although they share one budget.

    For everyone: each figure counts for 10 minutes from when it was seen. After that every
    reader hides it, even when nobody rewrote the file: agenttalk capacity, agenttalk status
    (which now shows capacity=current, capacity=stale(...) or capacity=unknown(...) for each
    seat), the web console and agenttalk attention. The next time the seat publishes a reading,
    the expired figures are also removed from the file. A refusal flag expires with the window
    it came from, and the latest verdict keeps the status and the window it named, so a refused
    window is known even when its percentage reads low. Each reading
    names the account it belongs to: the provider, the OS user and the folder the reading comes
    from, the default folder too, so two user homes are never one account. agenttalk capacity lists the seats
    that share an account under that account, each with its own reading and its age, newest
    first; readings are never merged across seats. A seat's conversation fill is shown only when
    it is known to be that seat's own. A manual agenttalk checkpoint save still records the
    status-line file's fill, as before this change, because a manual save cannot tell which
    conversation it runs in; a save from Claude's own hook keeps it only when it names that
    conversation. A fill older than 10 minutes is not recorded at all. A reading also says whether a window's length was reported
    by the provider or filled in by agenttalk, and the file carries a version number. The
    README's new section "Reading the capacity files" lists the fields other programs may rely on.

    What you need to do: nothing. The readings stay advice only: nothing waits for them or is
    held back by them. To judge an account, read its newest seat's row. A wrapped Claude seat
    usually shows no conversation fill: its own messages do not carry it, and the status-line
    file's fill counts only when it names the seat's own session.

    Technical details:

    • src/agenttalk/capacity.py:
      • claude_stream_reading, read_claude_stream, account_key, claude_account,
        current_view (the read-time, per-part check every consumer uses) and for_publication;
      • read_local takes stream=, now=, claude_home=, provider=, session_id= and
        any_session_context=, and rejects a stream reading whose binding differs from the
        current account;
      • _same_path and account_key resolve links first (os.path.realpath); account_key
        always hashes the folder read, ~/.claude and ~/.codex included;
      • usable_epoch accepts a reset time only from 0 to the last second of year 9999, at
        ingestion (stream, status line, Codex rollout) and in the readers (web._capacity_window,
        cli._reset_in_minutes); current_view drops a saved refusal type that is not a window
        name; detect_source is shared with the manual refresh;
      • numbers are parsed finite-only; the status-line read takes its time and content from the
        same version of the file;
      • a thread's rollout is found by the name suffix -<thread>.jsonl anywhere in the tree, or
        by its session_meta id (non-object records skipped), with CODEX_SHARED_SCAN_LIMIT 4096
        for the shared home;
      • new snapshot fields primary_status, primary_window_basis and primary_observed_at
        (the same three for secondary), last_status, last_status_at, last_status_window,
        scope, account and
        schema_version = 2.
    • src/agenttalk/wrapper/session.py: SessionState.claude_rate_limit (with its binding),
      folded in observe_event; a failure there leaves no reading but keeps the binding; the
      adapter's handling of a refused request is unchanged.
    • src/agenttalk/wrapper/run.py: child_claude_config_dir, shared w...
Read more

agenttalk 0.98.0

Choose a tag to compare

@zoolok17 zoolok17 released this 07 Oct 01:36
a925106

In short: this release is mostly about the dashboards, and about seats that meet an
overloaded AI provider. The new dashboard (/v2) now works on a phone-sized screen, as one
column with tabs for what needs you, the team and the lead. Both dashboards stop treating
slightly old data as an error: the server now sends the data together with its age, and the
classic page keeps showing the last good data under an "Updating" banner instead of a red
"Degraded" box, asks for new data every 10 seconds instead of every 2, and gains a Refresh
live data button. An optional, read-only budget feed (--enable-budget, off by default) makes
this machine's gateway money figures available to the dashboard; there is no budget screen
yet. A Claude seat whose AI provider is overloaded, or whose usage limit cannot be confirmed,
now waits and tries again after 15 minutes, then 30, then every 60, instead of retrying every
few seconds for hours; this is on by default and can be switched off. The README now opens
with a plain-language front page, and several of its statements were corrected. The gateway
and its ledger are unchanged in this release, so upgrading needs no extra step.

Added

  • The new dashboard (/v2) now works on a phone-sized screen. Until now the page had a fixed
    minimum width of 1024 pixels, so on a phone it was cut off and had to be scrolled sideways.

    What you will notice: before this, /v2 on a narrow screen showed the desktop page, wider than
    the screen. Now, under 1024 pixels, it is one column with a bar at the bottom to switch between
    three parts: Needs you (the cards that wait for you, shown first), Team (usage windows
    and the team list) and Lead (the lead's latest message, the chat and the message box). Every
    button is at least 48 pixels tall, and nothing scrolls sideways down to 360 pixels wide. At 1024
    pixels and wider the page looks and works exactly as before. Themes, the keyboard shortcuts and
    the quiet, offline and needs-you states work at every width. The keyboard keys j, k,
    Enter and l only act on the cards of the Needs you part, so on a phone they do nothing while
    Team or Lead is showing. A warning that the server cannot be reached, with its Retry button,
    shows above every part, and the Needs you tab shows how many cards are open. There is no money (budget) part yet; it comes with its own feed later.

    What you need to do: nothing. This only changes how the page looks on a narrow screen; reaching
    the dashboard from a phone is not part of this change (it still listens on this computer only).

    Technical details: one @media (max-width: 1023px) block at the end of
    src/agenttalk/web_static/console2.css; a static <nav id="c2-tabs"> in render_console2
    (src/agenttalk/web.py); buildTabs / setTab in console2.js set data-c2-tab and
    data-c2-mode on #app. Tests: tests/console2_render.test.mjs and the phone tests in
    tests/test_console2_web.py.

  • An optional budget data feed for the dashboard. Before, the dashboard
    server did not read this machine's gateway ledger. Starting dashboard or
    serve with --enable-budget now makes those recorded money figures and
    limits available at GET /api/budget, including the opening balance after
    a reset and its month. The answer explains that it is not the provider's
    bill and excludes other machines. The feed is off by default, reads without
    changing the ledger, and reuses answers for ten seconds to limit short read
    locks. There is no budget screen yet; existing dashboard answers are unchanged.
    An incomplete ledger installation is reported as unavailable, rather than
    mistaken for a machine that has never been set up.

Changed

  • The README now opens with a plain-language front page. Someone who has never
    programmed can now learn from the first screen what agenttalk does, who it is for and
    what they need first: an AI tool with working access to its model, Python, the
    operating systems, and whether setup needs technical help. The front page then tells a
    normal day with a small team and its honest limits, and ends with a short way in,
    including how one lead sets up a supervised team. What agenttalk does well and under
    which conditions, what stays on your machine and what agenttalk is not are now in the
    first section of the guide. The detailed guide and reference follow further down, with
    every fact kept; the list of optional features and the file locations moved into the
    technical reference. A few points were corrected or added:

    • The bundled supervisor runs on Windows only (#356 tracks a monitor for Linux and
      macOS). The project's tests run on Windows, Linux and macOS; the managed gateway's
      background service uses Windows Task Scheduler or a systemd user service, so it
      cannot be installed on macOS; and a wrapped Codex seat whose shell is bash or zsh
      needs "reply_shell": "bash" in .agenttalk/supervisor.json.
    • You can start just one assistant, the lead, and have it set up a supervised team;
      on Windows you then start the supervisor yourself (#355 would let the lead do that
      too), and it starts the teammates in its settings in the background.
    • The pre-action check stops on a withdrawn (rescinded) request and, with --gates,
      on a gate at HOLD; the bundled lead instructions show it without --gates today
      (#362). Sending a newer request in place of an old one does not stop the old one.
    • A bus command run without an agent name stops with "no agent identity"; only the
      bundled skills fall back to a default name. The README used to say every command
      fell back silently.
    • The wrapper's reply instructions leave out the seat's name and the wrapper does not
      pass it on, so a supervised seat's reply can fail. An ordinary seat can carry its
      name (AGENTTALK_SELF) in its supervisor.json entry; a gateway-backed seat
      refuses that entry and must reply with --from <seat> (#354, with the wider
      problem in #178).
    • A restart tries to resume the assistant's session and starts a fresh one when it
      cannot; accepted lessons reach a wrapped seat's turns (up to five) or a seat run by
      hand through agenttalk sync, as reminders; a work order closes on a done or
      declined reply, on a verdict when the reply has no status field, by hand
      (ack --to-request) or by withdrawal, so closed does not always mean completed.
    • No agenttalk command merges. The optional lanes can create a branch and a
      worktree and, under their own checks, remove them; janitor --apply can save a
      worktree's uncommitted changes as a commit on its branch.
    • Lanes need the bus folder inside the code repository (#245).
    • janitor --apply can follow a folder link in a rare case and delete files outside
      the folder; use its report until that is fixed (#342).
    • Temp files are not yet routed into a seat's scratch folder (#336).
    • The dashboard's views can still be slow on a large store with a cold cache (#251).
  • A Claude seat whose AI provider is overloaded, or answers with an error that looks like a usage
    limit but cannot be confirmed, now waits and tries again later, instead of retrying every few
    seconds for hours.
    Until now such a failure was retried every 0.3 to 2 seconds until the
    "100 attempts / 4 hours" rule gave up and dead-lettered the message. This is on by default,
    and the same switch as the usage-limit park controls it.

    What changes: an overloaded provider (HTTP 529) gets two quick ordinary retries and then a
    cool-down; a throttled one (a 429 without limit details, a status or window word the wrapper
    does not know, or a rejection that no error result confirms) cools down at once. The seat then
    tries again after 15 minutes, then after 30, then every 60. The message is kept, the seat stays
    alive, and the wait and the tries made under it never count towards "100 attempts / 4 hours". A
    restart does not make it try sooner: the saved time wins. Only structured proof from the seat's
    own output counts, a later successful result cancels it, and message text never decides anything.
    A proven usage limit is unchanged.

    What you will notice: agenttalk status flags the seat provider_wait_parked(kind=...,retry=<time>);
    attention, doctor, supervisor and both web consoles show it as parked in its own words
    ("waiting for an overloaded AI provider; tries again at ...", or "waiting on a possible usage
    limit; ..."), never as a usage limit for an overload; the liaison gets one notice when it starts
    and one when its kind changes. The seat's health says provider_wait_parked.

    A usage limit whose retry at the reset time was never used keeps that retry while a cool-down
    interrupts it (a new record field, quota_wake_epoch, written only then): when the same limit
    returns, the retry comes back if it is still ahead and is exactly the reset's own retry (a saved
    time that does not match its reset is dropped, never used). The cool-down notice has the subject
    "provider-wait park notice" and names only the saved next try.

    What to do: wait, or skip the message with agenttalk ack --for <agent> --id <message id> (no
    dead-letter record). Starting the seat again does not try sooner. To get the old behaviour for all
    three kinds of park, set AGENTTALK_STOP_RETRIES_AT_LIMIT=0 (or false, off, no); a message
    that already carries a cool-down is then driven as before, and its attempts and time stay out of
    its disposal counts.

    Known limits: Claude only; the first two overload retries are real attempts, so a message that
    already has 19 eligible attempts reaches the 20-attempt escalation with the first, and one with 98
    attempts and four eligible hours reaches the disposal with the second (the promise of no disposal
    starts with the cool-down); the 529 and plain-429 cases in the tests are made up, because no real
    sampl...

Read more

agenttalk 0.97.0

Choose a tag to compare

@zoolok17 zoolok17 released this 05 Oct 09:50
3adc32a

In short: this release is about seats that run into limits, and about a safe way
for other programs to read the gateway's money figures. A Claude seat that runs out of
its 5-hour or weekly allowance now stops and waits, instead of retrying for hours and
then losing the message, and it keeps its working context while it waits. A seat's
health now names the real cause of a failure, for example a usage limit and its
window; it no longer says "rate limited" just because an error contains the letters
"rate", and it never guesses when a seat will recover. For a program that keeps its
own accounts, the gateway gains a read-only gateway report, each receipt now names
its month, gateway receipts works from any folder, and the Qwen gateway can tie a
paid child turn to an outside quota reference and keep a receipt of what it spent. An
optional turn journal can record what each turn did. A refused work order no longer
prints anything that looks like proof it was sent, and the new console no longer hides
a stalled seat the server had already flagged. Tests no longer reach a running gateway
by default, CI logs list every skipped test with its reason, and two rare test
failures are gone or explained. Upgrading a running gateway is a separate step: the
ledger change for quota references is opt-in (agenttalk gateway binding-install),
and older agenttalk versions refuse a ledger once it is migrated, so read the gateway
entries below before you upgrade one.

Changed

  • A Claude seat that runs out of its allowance now stops and waits, instead of retrying for
    hours and then losing the message.
    Until now, when a wrapped Claude seat used up its 5-hour or
    weekly allowance, the wrapper started the model again every few seconds for four hours (844 and
    809 tries in two real cases) and then dead-lettered the message. This is on by default.

    What changes: the first time the seat proves it is out of allowance (Claude reports a rejected
    usage event and ends the turn in error), the wrapper parks the message. It tries once more
    each time the wrapper is started again, and once 30 seconds after the reset time Claude states
    (only when that time is in the future and within 8 days). Everything else behaves as before.

    What you will notice: a seat that stops and waits. agenttalk status, attention, doctor and
    both web consoles show it as parked on a usage limit ("until " or "until restarted"), and
    the liaison gets one notice. The seat stays alive and the supervisor leaves it alone. The
    message is kept, but messages behind it wait, including release and end.

    What to do: wait for the stated time, or start the seat again now with
    agenttalk request-restart --for <agent> (a protected seat also needs --force-protected and
    --acknowledge-live-protected-kill), or skip the message with
    agenttalk ack --for <agent> --id <message id> (no dead-letter record). To get the old behaviour
    back, set AGENTTALK_STOP_RETRIES_AT_LIMIT=0 (or false, off, no) in the wrapper's
    environment; it gives the previous behaviour. One qualification: a message that already carries
    a park when you switch it off is driven as before, but the attempts and the time it spent parked
    stay out of its disposal counts.

    With the optional turn journal on, the turn that proved the limit is one failed dispatch (the same
    failure class as with the switch off), nothing more is recorded while the seat waits, and a later
    successful try gives a new dispatch and exactly one completed for the message. A parked seat is
    held to the same rule as a stalled warning in the web console: always counted as needing attention,
    never "All quiet" or "not for you", and no saved "Later" choice hides it.

    Technical detail: a new usage_limit failure word, new fields in the message's attempt record
    (park_state, parked_at, parked_generation, park_count, probe_marker,
    excluded_attempts, parked_seconds_total, limit_failures, limit_window, reset_epoch,
    wake_epoch, last_reset_epoch, probed_wake_epoch, notice_key, notice_routed,
    notice_tries, notice_next_at; added only, none renamed or removed), a marker file
    state/usage-limit-park/<agent>.json, the health reason usage_limit_parked, and a
    usage_limit_park field in status --json, the supervisor report and the web state rows. It
    replaces the approach of pull request #104 (never merged), which read the provider's error text.

    Fix round 1 (this update): a cold read found a few edge cases the first version did not
    handle cleanly, all now fixed:

    • A momentary file-system hiccup while refreshing the marker could, on some Python versions,
      escape and stop the wrapper's own heartbeat - the seat would then look dead until restarted.
      The marker refresh is now one single protected step, start to finish.
    • A damaged or very unusual marker file could carry a time so large or so early that showing it
      broke the very screen trying to show it (status, doctor, or either web console). Every
      time in the marker is now checked against what any of those can actually display; a field
      that cannot be shown is simply left out, never crashes the screen, and the rest of the marker
      still reads normally. A file missing one of its eleven documented fields is now refused
      outright, as the documented contract always said it should be.
    • The "how long has this seat been parked" shown in attention could read as a few seconds
      even after days, because it was reusing the marker's own refresh time by mistake; it now
      comes from when the park actually began.
    • The one liaison notice for a park no longer shows twice (once in the main list, once as its
      own separate question that never went away on its own once the park ended) - it is shown
      once, as a single live warning, like a stalled seat already is.
    • A notice meant for the liaison no longer silently fails to send when the parked seat is
      itself the liaison and a separate lead exists to receive it instead.
    • One unrelated file left in an internal folder could previously stop doctor from listing any
      parked seat at all; it is now skipped on its own.

    What you will notice: nothing new to do - these were all edge cases that could otherwise have
    hidden a real park or looked like an unrelated crash.

    Fix round 2: a further read found that round 1's notice fix only hid the duplicate card,
    without closing the obligation it left behind, and opened a second gap of its own; three
    further edge cases in the park's own bookkeeping were also found. All now fixed:

    • A seat whose park had already recovered could still leave the liaison with an unanswered
      question showing in places that track what the liaison still owes a reply to - round 1 only
      hid the duplicate card, it never closed the question itself. The liaison notice is now
      purely informational everywhere, the same as any other status update: it was never a
      question owed a reply to begin with, so it can never stay stuck looking like one.
    • Publishing the small status file that adds a park's reset time and freshness can fail
      without the park itself being affected - round 1's fix for the point above could then hide
      the only warning a parked seat had. The warning itself no longer depends on that file: it
      shows (without the reset-time detail) whenever the seat's own durable record says it is
      parked, file or no file.
    • A damaged or hand-edited internal count could, in rare cases, cause a message to be
      dead-lettered after only one real try, even with this whole feature turned off. Both
      counts behind that decision are now kept sane before they are used.
    • A status file with a date but no time zone was read as local time instead of being
      rejected, which could make a park look a different age on two different machines. A date
      with no time zone is now refused, same as any other damaged field.
    • The new console's "needs you" panel showed a seat that had just started up the same as one
      that was confirmed stuck or dead. A normal startup now reads as itself, not as a failure;
      a genuinely stuck or dead seat is unaffected.
    • Round 1's fix for a notice going to the wrong place also changed where two OTHER, older
      kinds of notice go when this whole feature is switched off. Narrowed to affect only this
      feature's own notice; the other two are back to their original behaviour.

    What you will notice: nothing new to do - these were all edge cases in the park's own
    bookkeeping, surfaced only by a damaged file, a missing optional file, or an unusual sequence
    of events.

    Fix round 3 (park reader recast, this update, the last): round 2's fallback for a missing
    status file was added to only one of the seven screens that show a park (attention); a
    further read found it could also show a stopped wrapper as freshly parked instead of "not
    responding", and could show an earlier, already-handled message's park instead of a new one.
    Every screen now reads one single, shared answer instead of each finding its own way to cope
    with a missing or outdated status file:

    • status, doctor, the supervisor report, the web seat row and web attention all now show
      a park exactly the same way attention already did - built from the seat's own durable
      record whenever the status file is not readable, not only in attention. Three of those
      five previously showed nothing at all in that case.
    • A park is now always the CURRENT message waiting for that seat, found the same way the
      wrapper itself finds its next message - never an older, already-handled one the status file
      happened to still mention, and never silently missing a second park that started after the
      first was handled.
    • A seat whose wrapper has actually stopped no longer reads as freshly parked just because its
      durable record still...
Read more

v0.96.0 - one plain voice for people, a lead routine, and a clearer "what needs you" panel

Choose a tag to compare

@zoolok17 zoolok17 released this 03 Oct 05:52
97f487b

What is in agenttalk 0.96.0

agenttalk is a tool that lets AI coding agents from different companies work together as one team: they send each other work, reviews and answers through a shared message store, and a lead agent coordinates them. This release is mostly about being clear to people: what the agents write, what the lead does every half hour, and what the "what needs you" panel shows.

The main things in this release, each explained below:

  • One plain-language voice for everything a person reads.
  • Leads get a written routine: a regular check-in and a handover note.
  • A clearer "what needs you" panel.
  • Answered tasks stop looking unfinished.
  • Right after an upgrade, the lead can send work at once.
  • The out-of-date PDF manual is gone, and slow automatic checks on Windows get more time.

If you already have agenttalk installed: refresh the skills, or the new writing and lead guidance will not arrive. Preview with agenttalk install-skills --dry-run --force, back up any local edits you want to keep, then run agenttalk install-skills --force. A fresh install needs only agenttalk install-skills.


One plain-language voice for everything a person reads

What changed: the agents already explained changes in plain words in release notes and pull requests. Now one shared guide covers everything a person reads: documentation, code comments and the text on screen. Each kind has its own length and shape. Documents open with a short "In plain words" summary; comments say why in a sentence or two; on-screen text is short, says what you can do next and never blames you. Messages between agents stay short and exact, because only agents read them.

What you will notice: new and changed documents start with a plain summary, and new comments and on-screen text read more plainly. The README and the new-user manual already open this way, and the new console's labels, buttons and messages were rewritten in plain words. Existing documents are not rewritten just to change their voice.


Leads get a written routine

What changed: the lead skills now describe a regular check-in (for example every 30 minutes: new messages, which agents are alive or stuck, open reviews, budgets, free memory, knowledge, spend) and a short handover note (for example every two hours and before any reset) so that a restarted lead can carry on. They also say what to report to the person in charge: only decisions, actions that need them, and money alarms.

What you will notice: a lead that loads the updated skill keeps a steady rhythm and leaves a handover note.


A clearer "what needs you" panel

What changed:

  • A supervisor warning about a stuck process now says whether the supervisor itself is running, not running, or unknown. This is a plain fact, never a reason to treat the warning as less urgent.
  • A pile of old failed messages (7 days or more) from one agent is folded into one row with the exact count and the commands to reach each of them. Nothing is hidden or left uncounted, and the count at the top always includes everything.
  • When the server is briefly busy, the panel waits and tries again instead of showing an error at once. A real failure still shows after a few tries.

Answered tasks stop looking unfinished

What changed: a reply that gave a verdict without a separate "done" status used to leave its task listed as open. Such replies now count as answers, including older ones. An explicit "in progress" status still keeps a task open, and a reply with neither warns how to close it.

What you will notice: the list of open tasks shrinks to the ones that really are open. No clean-up command is needed.


Right after an upgrade, the lead can send work at once

What changed: sending a task used to be refused while any agent in the team ran an older version than the sender. Now only the agent that receives the task is checked, against the first version that understood tasks (0.88.0).

What you will notice: after an upgrade the lead can send work to any agent on 0.88.0 or newer straight away, without waiting for the whole team to restart.


Smaller changes

  • The PDF copy of the new-user manual is gone. It was made for version 0.74.0 and had fallen about twenty versions behind. Read docs/AGENTTALK-NEW-USER-MANUAL.md instead.
  • Slow automatic checks on Windows get more time, and a time-out while scanning a project's Git sub-modules no longer crashes the scan.
  • Four rules in the plain-language guide no longer pull in different directions.

The full list, with technical details for each change, is in CHANGELOG.md.

Install: python -m pip install "git+https://github.com/zoolok17/agenttalk.git@v0.96.0"