Repository navigation
agenttalk 0.98.0
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,
/v2on 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 keysj,k,
Enterandlonly 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">inrender_console2
(src/agenttalk/web.py);buildTabs/setTabinconsole2.jssetdata-c2-taband
data-c2-modeon#app. Tests:tests/console2_render.test.mjsand 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. Startingdashboardor
servewith--enable-budgetnow makes those recorded money figures and
limits available atGET /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--gatestoday
(#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 itssupervisor.jsonentry; 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 throughagenttalk 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 --applycan save a
worktree's uncommitted changes as a commit on its branch. - Lanes need the bus folder inside the code repository (#245).
janitor --applycan 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).
- The bundled supervisor runs on Windows only (#356 tracks a monitor for Linux and
-
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 statusflags the seatprovider_wait_parked(kind=...,retry=<time>);
attention,doctor,supervisorand 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 saysprovider_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, setAGENTTALK_STOP_RETRIES_AT_LIMIT=0(orfalse,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
sample exists.Technical detail: new fields in the message's attempt record (added only:
park_kind,
cooldown_step,soft_run,park_rev,park_detail), the health reasonprovider_wait_parked
with an optional closedreason_detail, and the additive keyskind,next_try_epochand
park_revin the park view and instatus --json, andkindandnext_try_epoch(notpark_rev)
in the supervisor row and the doctor data (older records have none and read as a usage limit). The version-1 marker file is unchanged and a
cool-down writes none. The next try is the record'swake_epoch, written by one function that
validates the final time.
Fixed
-
Slow budget-reader startup no longer looks like a busy ledger. Before,
starting Python used up the same short deadline as reading the figures,
which could hide valid figures or mislabel a damaged ledger on a loaded
machine. The helper now gets ten seconds to start, then a separate 150 ms
read deadline. A failed startup reports unavailable, with no figures.
Nothing needs configuring. Technical details:budget.pyand
docs/BUDGET-FEED.md; tests cover deliberately delayed startup and cleanup. -
The dashboard server no longer calls slightly old data an error (#361). The server keeps a
background picture of the team's messages. When that picture was more than 15 seconds old, it
answered/api/statewith the error "snapshot stale" instead of the data, even though nothing had
failed and a rebuild was simply still running. A script reading/api/statecould not tell
"rebuilding" from "broken", and the new console (/v2) showed "Can't read this team".What you will notice: before this, old data during a rebuild came back as an error and no data.
Now it comes back as data, with a newfreshnessentry on each team:snapshot_age_s(how old
the data is),stale(older than 15 seconds),rebuilding(a rebuild is running) and
scan_error(only for a real failure - one with no message text still reports its type, such as
"MemoryError" - not for a routine retry after a concurrent write or a
requested rebuild). The classic page shows a banner fromfreshness(its words follow the facts:
"Updating…" only when the server says a refresh is running, an out-of-date warning from the age,
failure words fromscan_error; when the server could not say whether a refresh runs, it shows
"Showing last known data" with the age and the failure), and the new console (/v2) greys the team under an "old messages" or "last
scan failed" banner; neither shows a green verdict while it shows. The data and its age always
come from the same snapshot. Real failures are still errors: a config change, no picture yet,
and a failed scan once the data is also more than 15 seconds old (named by its real cause, no
longer "snapshot stale"). The board's coverage keeps its 15-second rule.What you need to do: nothing. A script that detected old data through the "snapshot stale"
error should readfreshness.staleinstead.Technical details:
SnapshotService.freshness()insrc/agenttalk/envelope_snapshot.py;
active()no longer raises "snapshot stale";_root_stateinsrc/agenttalk/web.pyadds the
freshnessentry to each root (from one snapshot, one lock:active_with_freshness); the
classicconsole.jsreads it inkeepLastGoodRootsandkeptRootNote;console2-model.js
reads it infreshness()(stateold). -
The classic dashboard no longer replaces the whole page with a red "Degraded" message
while it is only refreshing, and it asks for new data less often. The dashboard keeps a
picture of the team's messages and rebuilds it every few seconds. On a large message store a
rebuild can take about as long as the picture is allowed to be old, so now and then the server
answered "snapshot stale" and the page threw away everything on screen to show that message.
It looked like a fault when nothing was wrong, and it hid the data you were reading.What you will notice: before this, a red "Degraded: snapshot stale" box replaced the page every
few seconds on a big store. Now, when an answer comes back with an error and the page already
has good data for that team, the page keeps showing that data. A banner on top says "Updating...
showing data from UTC" and gives the server's message in brackets. If that goes on for
more than a minute, the banner turns into a warning ("The data is out of date and not
refreshing"); the data still stays on screen. The top bar never says "Healthy" while data is
being kept this way. If there is no earlier good data (for example right after you open the
page), you still see the "Degraded" message as before. The page now asks for new data every 10
seconds instead of every 2, and the top bar has a Refresh live data button that fetches the latest
team data on demand, including the lists of the view you are looking at (it only reads; it
changes nothing). It does not refresh the Archived list in Sessions.What you need to do: nothing.
Technical details: client only, in
src/agenttalk/web_static/console.jsandconsole.css.
keepLastGoodRootsremembers each root's last answer without errors and, when the next answer
for that root has errors, substitutes it (marked_keptErrorsand_keptAt); every error keeps
the data, and the banner text never depends on the error's wording.POLL_MSis now 10000, so
ATTENTION_STALE_MSandSTATE_STALE_MS(4 xPOLL_MS) are 40 s. The server still answers
"snapshot stale" after 15 s; reporting freshness as data is a separate follow-up. Issue #359.