Commit Graph
9801 Commits
Author SHA1 Message Date
Márton Danóczyandcan1357 0ca0739eeb fix(acp): sync model config option on internal model changes
Zed (and any other ACP client) never learned about a model switch that
happened from inside the agent loop — prewalk hand-offs, retry-fallback,
model cycling — because #pushConfigOptionUpdate was only ever wired to
the client-initiated setSessionConfigOption/setSessionMode RPCs and to
the thinking_level_changed lifetime event. The model itself did switch
correctly (subsequent requests used the new model), but the client's
model picker/status bar kept showing the session's starting model.

#handleLifetimeEvent now also reacts to the model_changed event added
in the previous commit and re-pushes config_option_update. Extend the
existing thinking-only subscription dedupe in setSessionConfigOption to
cover the model config id too, so a client-initiated model change still
produces exactly one notification once the lifetime subscription is
installed.

Regression tests mirror the existing thinking-level coverage:
- 'pushes config_option_update when the model changes internally'
- 'emits a single config_option_update per setSessionConfigOption(model) call'

Verified: bun test test/acp-agent.test.ts (57/57), plus
agent-session-prewalk.test.ts, agent-session-retry-fallback.test.ts,
retry-fallback.test.ts, model-resolver.test.ts, and the other acp-*.test.ts
files all still pass; tsgo --noEmit and biome check clean.

(cherry picked from commit f5c5081088e8cbac2650a9de89049731de1b2777)
2026-07-29 23:08:25 +02:00
Márton Danóczyandcan1357 bce1ff55a7 feat(session): emit model_changed event on every internal model switch
AgentSession#setModelWithProviderSessionReset is the single choke point
every model mutation runs through (explicit /model, prewalk hand-offs,
retry-fallback, model cycling). It previously changed agent.state.model
silently — no session event told subscribers (ACP, RPC, TUI) that the
active model moved.

Emit a new model_changed AgentSessionEvent from that choke point
whenever the model actually changes, and wire it into every consumer
that must exhaustively handle AgentSessionEvent: the TUI event
controller (invalidates the status line, same as thinking_level_changed)
and the RPC client's forwarded-event allowlist.

(cherry picked from commit f76325de2c7821dd7046ddb67546577c3575a263)
2026-07-29 23:08:25 +02:00
can1357 ab48f43783 Merge PR #6888: fix(ttsr): flag text-source inference for unlisted file extensions (@roboomp) 2026-07-29 23:08:24 +02:00
can1357 b5ad903788 fix(ttsr): exclude deleted patch text from matcher digest
(cherry picked from commit b4812365368368a5706131c3ff1ecd52fd64662d)
2026-07-29 23:08:24 +02:00
can1357 3a61aa727f fix(coding-agent): keep Advisor retry sleep on Bun
(cherry picked from commit 31b9090f901b520b57d5dacec3f8c7dba271decc)
2026-07-29 23:08:23 +02:00
can1357 8c45df1cdd Merge PR #6883: fix(coding-agent): scope Advisor cost to the active session (@paolomazzitti) 2026-07-29 23:08:23 +02:00
can1357 7338be4d67 Merge PR #6845: fix(launch): isolate legacy xterm replay (@usr-bin-roygbiv) 2026-07-29 23:08:22 +02:00
can1357 2c99f2f2e8 fix(git): preserve effective character locale
(cherry picked from commit ef7abf60ad1b80642ba1731e043f8eeb82c6a6aa)
2026-07-29 23:08:21 +02:00
usr-bin-roygbivandcan1357 8b81b1c0a0 fix(launch): preserve logs on replay failure
(cherry picked from commit 2bebc32a05553e75edef16f71218fa2bfbfc1f77)
2026-07-29 23:08:21 +02:00
usr-bin-roygbivandcan1357 77e90e458d fix(launch): reject early replay worker exits
(cherry picked from commit d5bbebb22485a118c5efb690ec40033583a38d81)
2026-07-29 23:08:21 +02:00
usr-bin-roygbivandcan1357 4436038127 fix(launch): isolate legacy xterm replay
(cherry picked from commit 47baab894a224f3354085b4794337a211d3cf5c8)
2026-07-29 23:08:21 +02:00
can1357 3bce6527b3 Merge PR #6842: fix(git): force stable locale for non-interactive commands (@rolando439) 2026-07-29 23:08:20 +02:00
Rolando Diazandcan1357 b1c3ba8b8e fix(git): preserve UTF-8 locale for gh subprocesses
(cherry picked from commit e703aa00892b4589baa6c9dcb5f3ab2a3afb1662)
2026-07-29 23:08:20 +02:00
Rolando Diazandcan1357 62cffde87a fix(git): treat empty LC_CTYPE as unset
(cherry picked from commit 02364899ad23031d0ffe47be574ed547e249efa5)
2026-07-29 23:08:20 +02:00
Rolando Diazandcan1357 6ddea85d07 fix(git): preserve inherited UTF-8 character locale
(cherry picked from commit 4d51427cf144dd6415ee3b61158b5650011a796e)
2026-07-29 23:08:19 +02:00
Rolando Diazandcan1357 a38160e245 fix(git): preserve UTF-8 locale for child processes
(cherry picked from commit f7c46ea55fb016daf6c34ecadf87443dadc61047)
2026-07-29 23:08:19 +02:00
Rolando Diazandcan1357 fc093871c0 fix(git): force stable locale for non-interactive commands
(cherry picked from commit 29afa4c859ec89db5b6d3101495eb505cf85cb36)
2026-07-29 23:08:19 +02:00
can1357 2be93e7c84 fix(coding-agent): filter disabled MCP completions
(cherry picked from commit 33886ad9691cf4d330cf1a645e19cae7681c8e94)
2026-07-29 23:07:53 +02:00
can1357 0617ff6e80 Merge PR #6454: feat(coding-agent): autocomplete MCP server names in /mcp subcommands (@Mathews-Tom) 2026-07-29 23:07:52 +02:00
Frederico Luz 1e96750437 fix(rpc): report Anthropic fast fallback honestly
Anthropic's provider-scoped fastModeDisabled state was omitted from the session active predicate, and the unchanged-tier guard prevented explicit retries.
2026-07-29 20:58:01 +01:00
Frederico Luz 511524e3e4 fix(rpc): normalize legacy get_state fields 2026-07-29 20:39:25 +01:00
Frederico Luz 7b8001e5c4 fix(rpc): address fast-mode review feedback 2026-07-29 19:47:56 +01:00
Frederico Luz 37a8102219 feat(rpc): expose token throughput in state 2026-07-29 19:14:59 +01:00
Frederico Luz abc2159d80 feat(rpc): support live fast mode 2026-07-29 18:20:35 +01:00
metaphorics 6cd48aca74 fix(ai): address Anthropic retry cap review 2026-07-30 01:38:23 +09:00
roboomp 7cb608b72a fix(coding-agent): re-key streamed tool cards on mid-stream id change
GitHub Copilot's call_id|id transport (and any stream that delivers a tool's name/args before its id) makes a streamed tool-call block appear with an empty or partial id, then rewrites it in a later delta. The transcript keyed the live card by that mutable content.id, so the changed id passed the creation guard and spawned a second card: the old-id card orphaned as a blue pending preview while the new-id card took the result.

Track the streamed id per tool-call block position (reset per assistant message) and migrate the live card's id-keyed trackers (pendingTools, tool timeline, args reveal, read tracking, and the shared read group's entry) when the id changes, so the populated id reuses the existing card.

Fixes #6879
2026-07-29 14:32:51 +00:00
Nik Divjak 408f0d352f feat(tools): add a browser.cdpUrl setting for the default automation target
Attaching to a long-running browser (a signed-in profile, an Electron app kept
open for a session) meant repeating app.cdp_url on every browser call, and any
call that omitted it silently launched a fresh headless Chromium instead.

browser.cdpUrl supplies that endpoint once. It is a default rather than an
override: app.cdp_url and app.path still win, and an unset or blank value leaves
cmux and headless resolution exactly as before.
2026-07-29 11:28:26 +02:00
Nik Divjak b8b0d342da fix(tools): stop browser automation from stealing focus in an attached browser
Attaching over app.cdp_url points automation at a browser the user is driving,
so two behaviors that are correct for a browser we own are wrong there.

pickElectronTarget enumerated CDP targets and took the first usable one, which
is not necessarily the tab in front of the user, and #captureScreenshot always
called page.bringToFront(), which switches the user's visible tab and pulls
window focus on every screenshot.

Connected browsers now prefer a tab that reports document.visibilityState
"visible" and skip the pre-capture activation, accepting the compositor stall
risk that activation avoids. Headless and spawned browsers are unchanged.
2026-07-29 11:26:13 +02:00
Nik Divjak da1d393c39 fix(tools): navigate to the requested url when opening an attached browser tab
buildInitPayload dropped opts.url, opts.waitUntil and opts.timeoutMs on the
attach branch, so `browser open` with a url against app.cdp_url or app.path
adopted the existing target without navigating and reported its current url as
the result. Reusing the same tab name afterwards did navigate, because the reuse
path issues tab.goto, so the same call behaved differently on first open.

Thread the navigation fields through the attach arm of WorkerInitPayload and
goto after the page is adopted and the dialog policy is installed, mirroring the
headless arm.
2026-07-29 11:20:52 +02:00
Paolo Mazzitti 3c7233af44 fix(coding-agent): scope advisor cost to active session 2026-07-29 07:18:48 +00:00
joshrzemien c24e3d53e9 Address Codex fireworks review feedback 2026-07-29 00:30:10 -04:00
joshrzemien 7a9f8da3f8 Fix Codex fireworks workspace account matching 2026-07-28 23:31:52 -04:00
Slava Zavadsky fdd46bd971 fix(coding-agent): pair checkpoint/rewind for restricted sessions too
The !restrictToolNames guard on the pairing blocks was wrong: a restricted
session with tools:[checkpoint] passes isToolAllowed (requestedTools is
defined) but the pairing is skipped, stranding the agent without rewind.
Remove the guard — this is a safety pairing, not a convenience widening.
Added restricted-session tests in both createTools and SDK active-set paths.
2026-07-28 21:18:43 -04:00
Slava Zavadsky 4364cfa5b3 fix(coding-agent): mirror checkpoint/rewind pairing in SDK active-tool path
Address Codex review: createTools auto-includes the sister tool in the
registry, but createAgentSession rebuilds the active set from the original
toolNames — so a one-sided tools: entry left the sister tool registered
but inactive. Mirror the pairing into explicitlyRequestedToolNames, gated
to !restrictToolNames for consistency with the manage_skill/learn mirror.

Also gate the index.ts pairing block with !restrictToolNames to match its
AST/auto-learn siblings, and fix the prompt to say 'or' not 'and'.
2026-07-28 20:27:14 -04:00
usr-bin-roygbiv 085f870faa feat(extensions): expose session async job snapshots 2026-07-28 23:12:28 +00:00
Slava Zavadsky abef08116e fix(coding-agent): auto-pair checkpoint/rewind and add changelog
Address review feedback on PR #6938:
- One-sided tools: list checkpoint without rewind (or vice versa) now
  auto-includes the sister tool, preventing a stuck subagent
- Add changelog entry under [Unreleased]
2026-07-28 18:12:01 -04:00
Slava Zavadsky afa76546a6 feat(coding-agent): allow checkpoint/rewind/learn/manage_skill in subagents when explicitly requested
Closes #3762

When an agent definition's frontmatter  list explicitly includes
checkpoint, rewind, learn, or manage_skill, allow them in subagents.
Previously all four were hard-gated to top-level sessions.

- Relax taskDepth gates in isToolAllowed using the already-captured
  requestedTools variable (no signature change needed)
- Remove isTopLevelSession function and its 4 guard sites from checkpoint.ts
- Update checkpoint prompt with enablement docs
- Add tests for subagent explicit-request, no-request, disabled-setting,
  and top-level paths
2026-07-28 17:57:02 -04:00
Gy-Hu e404102acc fix: forward parseArgs and CONFIG_DIR_NAME from the legacy pi shim
Legacy pi extensions import both from the `@earendil-works/pi-coding-agent`
package root, which omp aliases to legacy-pi-coding-agent-shim.ts. `parseArgs`
lives in ../cli/args and CONFIG_DIR_NAME in @oh-my-pi/pi-utils, and neither is
reachable through `export * from "../index"`, so Bun's static export check
rejects such extensions during validation.

Same class of barrel gap as issues #5968 and #6583.
2026-07-28 22:14:23 +08:00
roboomp 43534b25bc fix(ttsr): flag text-source inference for unlisted file extensions
`omp ttsr test <file>` inferred the match source from the path extension
against a hardcoded allowlist (`SOURCE_FILE_EXT`); a supplied source file
whose extension was absent silently fell through to the text (prose)
context, where tool-scoped rules can never match. The result was a false
negative indistinguishable from a non-matching regex, contradicting the
documented "a positional that resolves to a file defaults to tool/edit
context" contract.

- Emit an explanatory note when a resolvable file path is supplied and the
  source is inferred as `text`, pointing at `--source tool --tool edit`.
  Surfaced in both text and `--json` output via `TestReport.inferenceNote`.
- Extend the allowlist with the .NET family and other common source
  languages (cs, razor, cshtml, fs, fsx, vb, sh, bash, sql, zig, dart,
  scala, ex, exs, proto, tf).

Left the fall-through default itself unchanged (inverting the test is a
behaviour change and a maintainer call).

Fixes #6887
2026-07-28 10:35:31 +00:00
can1357 a10fe079ce fix(coding-agent): suppressed credential disable tombstones for active accounts
- Update isActionableDisable in usage-cli.ts to accept active accounts and check identity matches.
- Suppress credential disable tombstones when an active account exists for the same provider and identity.
- Add test coverage for suppressing tombstones when active accounts share the same identity.
2026-07-28 11:47:08 +02:00
can1357 b778617178 chore: reformat + rewrite changelogs 2026-07-28 11:19:34 +02:00
roboomp cd716e1896 fix(coding-agent): prevented duplicate fallback reads
When a successful read result was persisted before its live tool_execution_end reached the UI, a transcript rebuild replayed the completed card and removed the pending handle. The delayed read completion then created a fallback ReadToolGroupComponent beside replay.

Treat the existing tool timeline entry as proof that the read already had a card; clear stale read tracking and skip fallback creation. Added an exact memory:// success -> persisted replay -> delayed completion regression.

Fixes #6879
2026-07-28 09:01:09 +00:00
can1357 ef13efc1ab Merge PR #6750: perf(coding-agent): load HTML export assets on first use (@usr-bin-roygbiv) 2026-07-28 10:59:38 +02:00
can1357 c7b10c3340 Merge PR #6763: fix(cli): preserve live task-isolation sandboxes on worktree clear (@roboomp) 2026-07-28 10:59:37 +02:00
can1357 ac6cd57bd4 Merge PR #6820: fix(coding-agent): preserve parent todos in vibe mode (@Iron-Ham) 2026-07-28 10:59:37 +02:00
can1357 be0e593428 Merge PR #6880: fix(session): preserve auto-thinking level on classifier failure (@roboomp) 2026-07-28 10:59:37 +02:00
can1357 2b759b89e3 Merge PR #6838: fix(session): attribute user bang executions in advisor transcripts (@roboomp) 2026-07-28 10:59:36 +02:00
can1357 83dc01eb79 Merge PR #6823: fix(cli): wrap streaming-phase download timeout with friendly message (@roboomp) 2026-07-28 10:59:36 +02:00
can1357 84a7937325 docs(tools): note the literal-path escape in the selector-list guard
The guard now probes the full target before refusing, so an existing file
named like a selector list stays writable. Say so in the CHANGELOG entry
and the readSelectorListMisfire doc comment.
2026-07-28 10:59:36 +02:00
can1357 c66fac2ddd fix(tools): let an existing literal selector-list filename stay writable
Probe the full target with probeLiteralPathExists before classifying it as a
mis-dispatched read-selector list, matching the single-selector guard, so an
existing POSIX file like 'report:1-2;archive:3-4' can still be overwritten.
2026-07-28 10:59:36 +02:00