132 Commits
Author SHA1 Message Date
snowspeederandClaude Fable 5 28a2629c43 feat: speak answers sentence by sentence and never speak reasoning
CI / Verify and package (ubuntu-latest) (push) Canceled after 0s
CI / Verify and package (windows-latest) (push) Canceled after 0s
Segment the final answer as it streams and synthesize each completed
sentence immediately, so a listener hears the reply begin while the model
is still writing it. Sentences share the progress clips' FIFO chain and
output-sequence counter; only text left unspoken (a hit budget) is
synthesized after settle, so audio is never sent twice. A message that
grows a tool call stops answer-streaming without re-speaking what already
played.

Reasoning models inline their chain of thought as <think> blocks in the
same delta stream. Strip it while streaming -- carrying a partial tag
across delta boundaries -- so it is neither spoken nor shown as answer
text.

The fixed "Hang on while I work on that." is now a rotation of short
natural phrases that never repeats twice running, and a long silent think
gets a spoken "still on it" roughly every 45 seconds until real speech
begins. Turn timeout rises to five minutes to match the client.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-08-07 14:20:21 -04:00
snowspeederandClaude Fable 5 a7033f9076 feat: speak a progress update during long voice turns
CI / Verify and package (ubuntu-latest) (push) Canceled after 0s
CI / Verify and package (windows-latest) (push) Canceled after 0s
After two seconds of agent work, send one agent.progress frame with a
synthesized "Hang on while I work on that." clip over the same binary
audio channel (shared output-sequence counter), at most once per turn;
screen-only agent.working heartbeats continue every 15 seconds. This is
the change the 15:11 rebuild already shipped to the running server —
committing it pins the protocol addition to the client that now
tolerates and plays it.

Co-Authored-By: Claude Fable 5 <[email protected]>
2026-08-06 23:10:07 -04:00
snowspeeder a71cb8334a feat: extend voice API workspace and speech controls
CI / Verify and package (ubuntu-latest) (push) Canceled after 0s
CI / Verify and package (windows-latest) (push) Canceled after 0s
2026-08-06 12:09:34 -04:00
snowspeeder 1adb459e04 feat: harden voice API conversations and progress 2026-08-06 00:42:55 -04:00
snowspeeder 0793fa0ac4 feat: add authenticated voice pipeline API docs
CI / Verify and package (ubuntu-latest) (push) Canceled after 0s
CI / Verify and package (windows-latest) (push) Canceled after 0s
2026-08-04 19:09:33 -04:00
Federico Jaramillo Martinez c2b7cce2d3 feat(sessions): inherit thinking level in spawned sessions
spawn_session and spawn_subsession now forward the dispatching session's
current thinking level to the new session, clamped by pi to the spawned
model's capabilities, instead of falling back to the configured default.
2026-07-30 12:54:24 +02:00
Federico Jaramillo Martinez 5f4d81352f feat(sessions): optional model for spawn tools and # model completion in composer
spawn_session and spawn_subsession accept an optional model parameter as
an exact provider/model-id (strict matching; unknown specs fail listing
available models; omitting it keeps the inherited model). The chat
composer opens a model completion menu on # and inserts a
#provider/model-id reference into the draft, which agents forward as
the model parameter.
2026-07-29 23:58:38 +02:00
Federico Jaramillo Martinez 7a426571b8 docs(sessions): document settled extension dialog cards as dismiss-stay records 2026-07-29 07:52:21 +02:00
Federico Jaramillo Martinez 5759201a39 docs: document Pi extension dialogs and extensionDialogsTimeoutMs
Add the close-out documentation for extension dialog support:

- docs/config.md (+ synchronized config.html): extensionDialogsTimeoutMs
  in the config matrix, reload/restart guidance, the global config
  example, and a new Extension dialogs key-detail section covering the
  unattended-dialog safety valve (default 5 min, 0 = forever, effective
  deadline is the sooner of the extension's own timeout and this knob).
- docs/plugins.md (+ synchronized plugins.html): new Pi extension
  dialogs in PI WEB behavior note for extension authors — confirm/select/
  input render inline in the transcript and resolve with the real answer,
  answers use a dedicated daemon channel (never the prompt queue, so
  tool_call hooks park safely), session_start dialogs are reachable
  during create and open, reload rehydration, first-answer-wins across
  tabs, abort/runtime-replacement settlement, and the reload-mid-startup
  browser-local caveat.
- Add the extension-dialogs changeset (patch) for the release notes.
2026-07-29 07:52:21 +02:00
Federico Jaramillo Martinez 87c09982e9 feat(plugins): add bundled relays workspace panel plugin 2026-07-28 23:14:21 +02:00
Federico Jaramillo Martinez d19fca4090 feat(plugins): add files.listFiles directory listing to the plugin API 2026-07-28 23:14:21 +02:00
Federico Jaramillo Martinez 12f25282fc fix(sessions): void the open ask_user form when a chat message arrives
An ordinary chat message answers the session's open ask in the user's
own words, so keeping the form open would invite answers to questions
the conversation has already moved past. The form now closes as
cancelled, browsers clear the live card, and the model is told without
being woken so the notice rides into the turn the message itself
starts. Ignored duplicate queued messages skip the void on purpose:
they must not void an ask posted after the queued original.
2026-07-28 23:14:21 +02:00
Federico Jaramillo Martinez 5b717ed542 docs(config): state data directory behavior positively
Documentation should describe what the software does, not enumerate
what it does not do. Rephrase the data-directory wording around the
positive facts (each directory is independent; a new root starts with
empty state) and drop the "never moves or copies" constructions from
config.md, the config.html env table, and the changeset.
2026-07-28 19:43:22 +02:00
Federico Jaramillo Martinez 741b55117b docs(config): document independent data directories
Changing PI_WEB_DATA_DIR selects where managed state lives but never
moves or copies existing state. Explain how to carry session archives
over manually, and fix the stale "moves managed state location" claim
in the config.html env table.
2026-07-28 16:21:51 +02:00
Federico Jaramillo Martinez 8517800a24 feat(plugins): turn Info panel into a PI WEB status view
Rework the bundled Info plugin from a demo into an always-available
status view: running and installed versions, installation details,
release state, and per-service health rendered from host-provided
state, plus machine and workspace details. Replace the window.alert
demo action with a Copy PI WEB Diagnostics action that copies a
plain-text summary for bug reports.

Add state.selectedMachine to the stable plugin runtime state so
actions and other runtime callbacks can read the selected machine's
identity, and split the plugin into a copy-paste-friendly skeleton
(pi-web-plugin.ts) and replaceable internals (infoInternals.ts).
2026-07-27 18:03:25 +02:00
Federico Jaramillo Martinez e567d43042 feat(settings): add Ask Questions toggle 2026-07-27 12:39:40 +02:00
Federico Jaramillo Martinez 0e83146315 fix(ui): streamline ask_user question forms 2026-07-27 10:55:49 +02:00
Federico Jaramillo Martinez 4e47c23f23 Merge remote-tracking branch 'origin/main' into feat/model-questions-ux
# Conflicts:
#	src/server/sessiond.ts
#	src/server/sessions/sessionRoutes.test.ts
2026-07-27 09:44:40 +02:00
Federico Jaramillo Martinez 9191f59146 docs: document ask_user question forms 2026-07-27 01:17:48 +02:00
Federico Jaramillo Martinez 8a24a7c4a5 feat(workspaces): refresh worktrees on browser resume
Call WorkspaceController.refreshSelectedProjectTopology() from the existing
browser-resume refresh and the plugin-facing refreshAppData path, so worktrees
created or removed outside PI WEB become visible with no user action. No new
timer, watcher, process, or push channel; the resume path is already debounced
per animation frame and collapses concurrent requests.

Document the resume-scoped detection and the hiding of gone checkouts in the
FAQ, and add the changeset for the user-visible behavior.
2026-07-26 22:25:59 +02:00
Federico Jaramillo Martinez 49e7c390f3 feat(sessions): tell the user what a session start is waiting on
Creating or opening a session could stall for reasons the daemon knew
about and never shared. The browser invented the whole message it showed
while waiting -- "Creating session: Waiting for the backend session to be
ready" -- which says that we are waiting but never what for. A shared
ModelRuntime read during startup can be handed a network refresh that is
already in flight, and extensions may do their own network I/O while
loading, so the wait is real and previously unattributable.

The pre-session gap turned out to be a missing shared key rather than a
missing channel: publishActivity needs the PiAgentSession being built, but
the session id and cwd are both known before the first await. So create()
now publishes a new global session.startup event carrying an ordinary
SessionActivity, routed by cwd -- the one identity a browser row waiting
for a session id can match, since the client-invented pending id is
unknown to the daemon and the daemon's id is unknown to the browser.

Two phases are reported, each published before the await it describes so
the label changes during the wait rather than after it: "Starting the Pi
session" and "Loading session extensions". Both are facts, because the
service awaits exactly one call for each. A concurrent background catalog
refresh is appended as a note ("provider model lists are refreshing"),
never as the cause: the refresher can prove a refresh is running but not
that this startup joined it. ModelCatalogRefresher gains only a read-only
isRefreshInFlight() getter; cadence, timeout, and coalescing are untouched.

Reporting is event-only and synchronous. It writes no activities entry, no
workspace activity, and no unread state, so a failed creation leaves
nothing stranded, no await is added, and creation ordering and semantics
are unchanged. The window-ending idle report is skipped when a real
activity was published during startup, so an extension error survives.

The browser applies startup progress only when it can prove the target:
one non-discarded pending start in that cwd on the selected machine, or a
session whose id it already knows. A foreign workspace, another machine,
or two concurrent starts in one workspace keep today's generic wording
rather than showing one row the phase of another. An idle report restores
that generic wording, including the queued-messages variant.

docs/config.md said nothing a request triggers waits on a catalog fetch.
That is not strictly true for a refresh already in flight, so both it and
the generated docs/config.html now state the exception and say PI WEB
reports it while it happens.
2026-07-26 16:19:05 +02:00
Federico Jaramillo Martinez 36d67262ec docs(config): describe the model list refresh exception
The Pi extension provider baseline section stated that every later
provider registration is a no-op, naming session_start as an example.
That is now the exact case that is allowed, so the shipped configuration
reference contradicted the behavior. docs/config.md is in the package
files allowlist, so this text reaches users.

Describe what stays frozen, the two conditions under which a known
provider's model list refresh is applied, and why function-valued fields
are always rejected. Record the accepted trade-offs: catalogs are shared
daemon-wide state with last-registration-wins, and a model entry's own
baseUrl/headers take precedence over the provider-level values. Split
the log behavior out and note that ignored mutations are de-duplicated
per provider while applied refreshes are always logged.

Also correct the reload-behavior bullet: a restart is needed to add or
remove a provider or change its connection settings, but not for a known
provider refreshing only its model list.
2026-07-26 14:14:30 +02:00
Federico Jaramillo Martinez e7eb5383b2 docs: correct the model catalog refresh retry claim
The five-minute retry recovers from timeouts and unreachable providers,
but not from a provider that answers with an HTTP error status: pi
re-stamps checkedAt on that path, so the unforced retry lands inside a
fresh freshness window. Tracked in #100.
2026-07-25 22:12:53 +02:00
Federico Jaramillo Martinez 92854489cf docs: require pi 0.82.1 in user-facing requirements 2026-07-25 22:10:42 +02:00
Federico Jaramillo Martinez 90dd7ce401 docs(sessions): document background catalog refresh and contain offline env window
Finding 6: serialize createOfflineModelRuntime so overlapping calls cannot
interleave their PI_OFFLINE save/restore pairs and leave the process offline,
and name the process-wide visibility of that window in the docblock.

Finding 7: assert the offline construction through the public refresh seam via
reloadConfig() — the request path that regressed — instead of reading upstream's
private modelNetworkEnabled field.

Finding 8.4/8.5: document the background provider-catalog refresh in
docs/config.md and docs/config.html (cadence, timeout, single retry, offline
opt-out via PI_WEB_OFFLINE / PI_OFFLINE only), and update the changeset to
match the behavior after the earlier fixes.
2026-07-25 13:07:02 +02:00
Federico Jaramillo Martinez e8d418a71a docs: distinguish Pi extensions from PI WEB plugins 2026-07-22 23:53:30 +02:00
Federico Jaramillo Martinez ee8d9e5359 docs: document immutable provider bootstrap 2026-07-22 20:46:41 +02:00
Federico Jaramillo Martinez c2bf595999 feat(sessions): allow global-extension providers, require Pi 0.81
Relaxes the provider policy from 'global config only' to 'global sources':
providers registered by agent-dir (global) extensions are learned once at
daemon startup and allowed on the shared runtime; project-extension
registrations are still rejected with a session warning. Global extensions
load identically for every session, so their providers are daemon-consistent
and cannot leak project state (#76).

- Shim now allows allowlisted ids through and also covers Pi 0.81's native
  provider path (registerNativeProvider), closing a bypass.
- Startup learning step loads only global extensions against a scratch cwd
  and diffs the runtime's registered provider ids.
- Bumps @earendil-works/* dev/peer ranges to >=0.81.1 <0.82; adapts to the
  Agent.streamFn -> streamFunction rename.
- Docs, changeset, unit and acceptance tests updated (global-extension allow
  path, late re-registration a la pi-tensorx, native provider rule).
2026-07-22 17:13:57 +02:00
Federico Jaramillo Martinez 242911331a docs: document global provider policy and extension registration rejection 2026-07-22 09:36:32 +02:00
Federico Jaramillo Martinez b48b147b5b fix(install): allow node-pty scripts with npm 12 2026-07-20 11:57:39 +02:00
Federico Jaramillo Martinez d2e2d512cd Merge pull request #64 from jmfederico/fix/issue-62-authstorage
fix: migrate auth/model plumbing to ModelRuntime (fixes #62)
2026-07-18 18:20:03 +02:00
Federico Jaramillo Martinez 5ebcd34690 docs: clarify supported Pi range 2026-07-18 08:40:12 +02:00
Federico Jaramillo Martinez aca168a311 fix(runtime): align supported requirements and release hygiene 2026-07-18 00:10:47 +02:00
Federico Jaramillo Martinez caaa8c4ebc docs(test): audit testing-guide compliance gaps for fix relay 2026-07-17 19:35:40 +02:00
Federico Jaramillo Martinez 15d25d8c2e fix(subsessions): omit oversized completion output 2026-07-17 09:22:54 +02:00
Federico Jaramillo Martinez ca07e48c0a docs: clarify Pi-compatible agent profiles 2026-07-14 00:30:09 +02:00
Federico Jaramillo Martinez c0465c4a5c fix: delimit subsession output from guidance 2026-07-14 00:04:53 +02:00
Federico Jaramillo Martinez 0761e1509a fix: report remaining subsessions on completion 2026-07-13 23:41:20 +02:00
Federico Jaramillo Martinez d5154dfb3a feat: add explicit tracked subsession yielding 2026-07-13 22:45:07 +02:00
Federico Jaramillo Martinez a1a019e7b1 chore: merge origin/main 2026-07-13 22:36:36 +02:00
Federico Jaramillo Martinez f2ed8c82de Merge branch 'main' into review-issue-48 2026-07-13 21:08:17 +02:00
Federico Jaramillo Martinez cfa9f5a2fa Merge remote-tracking branch 'origin/main' into pr-36-generic-agent-config
# Conflicts:
#	docs/config.html
#	docs/config.md
#	src/cli.test.ts
#	src/cli.ts
#	src/client/src/components/settings/SettingsSessiondPanel.ts
#	src/client/src/components/settings/settingsConfigDraft.test.ts
#	src/client/src/components/settings/settingsConfigDraft.ts
#	src/server/app.test.ts
#	src/server/app.ts
#	src/server/configRoutes.test.ts
#	src/server/configRoutes.ts
#	src/server/piWebPluginService.test.ts
#	src/server/piWebPluginService.ts
#	src/server/piWebStatus.test.ts
#	src/server/piWebStatus.ts
#	src/server/piWebStatusCache.ts
#	src/server/sessions/authService.test.ts
#	src/server/sessions/piSessionService.ts
#	src/server/sessions/sessionRoutes.test.ts
2026-07-13 20:30:08 +02:00
Federico Jaramillo Martinez 47c24ed850 Merge branch 'main' into fix/pr-46-base-path 2026-07-13 19:55:14 +02:00
Federico Jaramillo Martinez 1cad424b07 docs: keep managed data reference timeless 2026-07-13 19:55:09 +02:00
Federico Jaramillo Martinez 4df7f430d4 Merge branch 'main' into review-issue-48 2026-07-13 19:48:21 +02:00
Federico Jaramillo Martinez 050b053d23 test(sessiond): harden archive migration safety 2026-07-13 14:45:14 +02:00
Federico Jaramillo Martinez a9bcfe25ff fix: preserve plugin manifest compatibility 2026-07-13 12:29:21 +02:00
Federico Jaramillo Martinez 767e653028 fix(cli): harden native service manager preflight 2026-07-13 01:28:04 +02:00
Federico Jaramillo Martinez dde48b3b11 fix(cli): diagnose native service plans in manager context 2026-07-13 00:41:51 +02:00
Federico Jaramillo Martinez da680f41e1 docs: trim README reverse proxy example 2026-07-12 23:57:26 +02:00