Commit Graph

8170 Commits

Author SHA1 Message Date
roboomp 9d3918bdac fix(collab): enabled mobile ask responses
Routed host UI requests through writable collab web guests and added mobile response controls for ask questions.

Fixes #4035
2026-07-01 05:15:37 +00:00
roboomp f70e4f1570 test(coding-agent): hoisted renderYieldSchema test imports to top level
AGENTS.md forbids inline `await import()` — move `fs`, `path`, and `prompt`
to top-level namespace/named imports. The `prompt-templates` module import
already registers the Handlebars helper as a side-effect, so the render
calls still resolve the new `renderYieldSchema` helper.
2026-07-01 05:33:02 +02:00
can1357 a36213a780 test(coding-agent): tightened line elision assertions in preview height tests
- Updated exact substring match assertions to use word-boundary regular expressions.
- Prevents false-positive test failures when target strings overlap with other generated text.
2026-07-01 05:31:34 +02:00
can1357 fccc0ed3ce chore: bump version to 16.2.12 2026-07-01 05:29:19 +02:00
can1357 05c09f6191 chore: update chanelogs 2026-07-01 05:27:25 +02:00
can1357 ccee14586a Merge remote-tracking branch 'origin/farm/d57e0533/openai-models-list-resolve-reference' 2026-07-01 05:26:00 +02:00
can1357 763f950b7f fix: streamlined tool-call cloning and validation in the stream pipeline
- Improved the leaked-thinking stream projector to clone and sync native tool-call blocks directly.
- Eliminated the need for placeholder IDs and complex rekeying logic in the event controller and argument reveal module.
- Simplified native tool-call validation in owned-stream processing by requiring only a non-empty name.
- Added comprehensive unit tests to ensure tool-call IDs and partial JSON parameters remain intact during healing.
2026-07-01 05:25:27 +02:00
can1357 ef7636805b feat(coding-agent): removed canonical model variant selection and tracking
- Removed the canonical model variant indexing, selection, and tracking logic from the model registry and resolver.
- Eliminated the `canonical` sub-command, tab view, search tokens, and equivalence configuration structures from the CLI and model selector components.
- Refined model identification, lookup, and provider fallback resolution to bind exclusively to standard, raw model IDs.
- Relocated the equivalence utility script within the catalog package to support script-only policy generation.
2026-07-01 05:22:42 +02:00
roboomp 61b0968a32 style: bun run fix 2026-07-01 03:17:04 +00:00
roboomp 57a891d014 fix(coding-agent): preserved referenced reasoning effort support
Preserved the referenced model's OpenAI-compatible reasoning-effort support when openai-models-list discovery enriches a thin /v1/models payload. The discovered model still keeps conservative proxy-local store and developer-role defaults, but known reasoning models like gpt-5 no longer force supportsReasoningEffort false and trigger the omitReasoningEffort request path.

Added a regression assertion that a thin proxied gpt-5 keeps supportsReasoningEffort true and omitReasoningEffort false after reference enrichment.

Fixes #3983
2026-07-01 03:16:56 +00:00
can1357 8e8c3e92ce Merge remote-tracking branch 'origin/farm/e0aafd27/cross-turn-tool-call-loop-guard' 2026-07-01 05:08:41 +02:00
roboomp 26c220991e style: bun run fix 2026-07-01 03:07:26 +00:00
roboomp bf75d80836 fix(coding-agent): resolve bundled reference in discoverOpenAIModelsList
Thin OpenAI-compatible proxies that omit context_length / max_model_len on
/v1/models made every discovered model fall back to
DISCOVERY_DEFAULT_CONTEXT_WINDOW (128K/33K), even when the id matched a
bundled model with a much larger intrinsic window. discoverProxyModels
and discoverLiteLLMModels already resolve ids against the bundled
reference index; discoverOpenAIModelsList (which also backs lm-studio
discovery) now does the same.

Behavior:
- Build the reference index once outside the loop and resolve each item
  via resolveModelReference().
- contextWindow precedence keeps provider-reported values authoritative:
  item.max_model_len ?? item.context_length ?? nativeMetadata?.contextWindow
  ?? reference?.contextWindow ?? DISCOVERY_DEFAULT_CONTEXT_WINDOW.
- maxTokens uses reference?.maxTokens when available, otherwise the
  api-specific discovery default, capped at contextWindow so a bundled
  ref for a larger sibling can never over-request output tokens.
- name / reasoning / thinking / input inherit from the reference; native
  lm-studio metadata still wins for input modality.
- Provider-specific baseUrl, headers, and local-unknown cost stay local.
- OpenAI-compat flags stay conservative (supportsStore / supportsDeveloperRole
  / supportsReasoningEffort all false) to match the proxy sibling.

Also updated two pre-existing regression tests that used
deepseek-v4-pro / deepseek-r1 / DeepSeek-V4-Flash as stand-in "fictional"
ids to exercise the default-fallback branch. Those model names have since
been added to the bundled catalog, so the tests were renamed to
vllm-lab-fork-* ids that unambiguously miss the reference index while
preserving each test's original default-fallback intent.

Fixes #3983
2026-07-01 03:07:14 +00:00
can1357 d6e62591cf chore: update chanelogs 2026-07-01 04:47:55 +02:00
roboomp cf52840c18 fix(agent): detected repeated tool-call turns
Added a cross-turn tool-call loop guard that hashes canonical tool names and arguments, ignores intent metadata, and injects a hidden redirect when identical calls reach the configured threshold.

Fixes #3971
2026-07-01 02:47:08 +00:00
can1357 2ad5a433ea Merge remote-tracking branch 'origin/farm/3fc23c45/linear-session-path-rebuild' 2026-07-01 04:47:04 +02:00
can1357 d562f28c1b Merge remote-tracking branch 'origin/farm/795471ef/cancel-timed-out-browser-run' 2026-07-01 04:46:41 +02:00
can1357 b8a996ac56 Merge branch 'farm/af5c9fdb/fix-eval-spawn-default' 2026-07-01 04:46:23 +02:00
can1357 99346570ba Merge remote-tracking branch 'origin/farm/4b964ee9/mcp-http-body-timeout' 2026-07-01 04:46:20 +02:00
can1357 3c477a6d0c Merge remote-tracking branch 'origin/farm/60bab21a/fix-subagent-yield-schema-wrapping' 2026-07-01 04:46:17 +02:00
can1357 23c81ead9b refactor(coding-agent/config): cached edit model variants and optimize settings parsing
- Introduced an `#editVariantCache` to memoize resolved edit modes for model variants.
- Replaced the generic `shallowStringRecord` helper with specialized, type-safe parsing methods for model variants and roles.
- Invalidated the cached edit variants during settings rebuilds and verified correct cache refreshment across project directories.
2026-07-01 04:45:59 +02:00
can1357 db8c79cc93 style: apply formatter and fix devin test enum
biome + cargo fmt over merge-sweep eval-fix commits; correct StopReason.END_TURN (nonexistent) to StopReason.FUNCTION_CALL in devin streaming test
2026-07-01 04:45:28 +02:00
roboomp 8614b4c086 fix(task): respected restricted spawn defaults
Resolved eval agent() and task tool defaults from the active spawn policy so restricted agents advertise and execute an allowed default.

Fixes #3973
2026-07-01 02:44:08 +00:00
roboomp 5d2f9ae5a3 fix(mcp): kept http timeouts active through body reads
- Moved Streamable HTTP request and notify timeout cleanup after response body consumption.\n- Added regression coverage for stalled request JSON bodies and stalled notify error bodies.\n\nFixes #3974
2026-07-01 02:43:00 +00:00
can1357 ea36c7256a chore(changelog): normalize merge-sweep entries 2026-07-01 04:41:38 +02:00
can1357 23e0512e7a fix(coding-agent): sanitize write progress preview 2026-07-01 04:40:55 +02:00
can1357 5888bccba0 fix(eval): truncate oversized Python shell output 2026-07-01 04:40:55 +02:00
can1357 2b9d2ca44e merge PR #3968: fix(browser): reap Chromium/Puppeteer on aborted open and session dispose 2026-07-01 04:40:46 +02:00
can1357 68a2c023bc merge PR #3967: fix(lsp): honor tool signal in cold-start initialize and notification writes 2026-07-01 04:40:46 +02:00
can1357 446d5dcba4 merge PR #3965: fix(coding-agent): streamed write progress 2026-07-01 04:40:46 +02:00
can1357 b105782744 merge PR #3957: fix(eval): bound python shell helper output 2026-07-01 04:40:45 +02:00
can1357 7f6b48068c merge PR #3956: fix(mcp): route stdio write/flush failures without parking request() 2026-07-01 04:40:39 +02:00
can1357 8cc7520e47 merge PR #3954: fix(pi-shell): wired fd directory walk to observe scope cancellation 2026-07-01 04:40:39 +02:00
can1357 0e37bd7212 merge PR #3951: fix(extensions): bound tool_call handlers by extensionHandlerTimeoutMs 2026-07-01 04:40:39 +02:00
roboomp af1a31f02b style: bun run fix 2026-07-01 02:34:07 +00:00
roboomp 35958a67ed fix(coding-agent): wrapped subagent output schema in result.data for yield prompt
The subagent system prompt rendered `{{jtdToTypeScript outputSchema}}` as a
bare TypeScript interface with the text "Your result MUST match this
TypeScript interface". The yield tool actually nests the user schema under
`result.data`, so the LLM pattern-matched on the visually dominant code
block and put the payload directly in `result.data`, tripping schema
validation repeatedly. In the worst reported case a subagent used all 3
retry attempts, had validation dropped, and lost its audit output entirely.

Add a `renderYieldSchema` Handlebars helper that renders the schema inside
`result: { data: … }` and swap the system-prompt block to use it, so the
model sees the exact envelope the yield tool expects. Multi-line object
schemas, scalars, unions, and array-of-object schemas all round-trip
cleanly with the new helper.

Fixes #3972
2026-07-01 02:33:55 +00:00
roboomp f7398a1aa8 fix(browser): bound cmux facades to runs
Wrapped cmux page, browser, and tab globals with per-run abort checks so stale continuations cannot reuse the long-lived CmuxTab after timeout.

Fixes #3964
2026-07-01 02:30:07 +00:00
roboomp 09625b1ca8 style: bun run fix 2026-07-01 02:21:41 +00:00
roboomp 769a9e5807 fix(lsp): only teardown clients on in-flight flush aborts
Distinguish aborts that race an active sink.flush() from aborts that happen
before a queued write starts. Only the former leaves the sink flush pending
and requires killing/evicting the LSP client; pre-write aborts should reject
that caller without disrupting unrelated in-flight operations.

Add a regression with one notification blocked in flush and a second queued
notification whose signal aborts before its write starts, asserting the shared
client is not killed and only the first message is written.
2026-07-01 02:21:40 +00:00
roboomp db8560f934 fix(browser): stopped stale timed-out runs
Aborted browser run helpers and recycled timed-out workers so losing JavaScript continuations cannot mutate a live tab after timeout.

Fixes #3964
2026-07-01 02:21:19 +00:00
roboomp 0a1392de4b fix(lsp): skip init failure cache on caller abort
Caller cancellations and tool timeout signals are transient initialize failures.
Do not put them in the three-minute init failure backoff, so a later normal
LSP call can retry the server/cwd instead of failing fast as recently failed.

Add a regression that aborts a wedged initialize and then retries the same
server/cwd with a short explicit timeout, asserting it does not hit the
negative-cache error.
2026-07-01 02:13:59 +00:00
roboomp 7282230094 style: bun run fix 2026-07-01 02:09:17 +00:00
roboomp 19b85bca70 fix(browser): reap Chromium/Puppeteer on aborted open and session dispose
Two termination boundaries in the browser tool leaked browser-owned OS resources into the long-lived coding-agent process.

1. Aborted 'open' published an orphan. #open wrapped acquisition in untilAborted, which rejects its outer wrapper on abort but lets the inner launch resolve in the background; acquireBrowser then unconditionally stored the resolved handle in the module-global browsers map. releaseAllTabs walks tabs, not browsers, so the refCount:0 handle stayed alive to process exit.

2. Session dispose had no browser teardown. Browser/tab state lives in module-global maps, and AgentSession.dispose() had no hook to walk them, so headless/spawned Chromium the session opened survived it.

acquireBrowser now short-circuits before launch on a pre-aborted signal and disposes the handle when the launch completes after abort. TabSession records the creating session's id (opts.ownerSessionId, threaded through BrowserTool.#open), preserved across reuse so a subagent re-driving an existing tab does not yank teardown responsibility. AgentSession.dispose() invokes releaseTabsForOwner bounded by withTimeout(3s), mirroring the async-job/MCP disposal pattern.

Regression tests exercise both boundaries via spied CmuxSocketClient (no real puppeteer/socket) and cover: pre-aborted open short-circuit, aborted-mid-launch cleanup, releaseTabsForOwner reaping only owned tabs, and reuse preserving original ownership.

Fixes #3963
2026-07-01 02:09:04 +00:00
roboomp e06fe92649 fix(lsp): normalize sink.flush return to Promise for strict typecheck
sink.flush()'s type is number | Promise<number>, so calling .then/.catch
directly failed under tsgo. Wrap in Promise.resolve() and annotate the
rejection handler's err parameter to satisfy strict noImplicitAny.
2026-07-01 02:06:59 +00:00
roboomp 11edbe01c2 style: bun run fix 2026-07-01 02:06:16 +00:00
roboomp 442ee57283 fix(lsp): honor tool signal in cold-start initialize and notification writes
Two client-level paths in the LSP tool bypassed the combined tool-timeout/
caller abort signal built in `LspTool.execute`, so a wedged server hung
past the advertised tool deadline and past user cancellation:

- `getOrCreateClient` took no `AbortSignal` and its `initialize`
  `sendRequest` was invoked with `signal = undefined`. With no signal
  and no explicit `timeoutMs`, `sendRequest` fell back to the hard-coded
  `DEFAULT_REQUEST_TIMEOUT_MS = 30000` internal timer, so a first-use
  `lsp` call against a server that wedged in `initialize` ignored the
  20s tool default (and any user-supplied shorter `timeout`) until the
  30s internal timer fired.
- `writeMessage`/`queueWriteMessage`/`sendNotification` had no timeout
  and no signal, so a `textDocument/didOpen`/`didChange`/`didSave` sent
  to a server that stopped draining stdin awaited `sink.flush()`
  forever. Because writes serialize through `client.writeQueue`, every
  later op on the client stalled behind the stuck flush too.

Thread the caller `AbortSignal` through `getOrCreateClient` (initialize
+ initialized notification) and through `sendNotification` /
`queueWriteMessage` / `writeMessage` so the sink flush is raced against
the signal. On abort, tear the client down: kill the process and evict
it from the active-clients map so the next `getOrCreateClient` call
spawns a fresh server instead of queueing behind the wedged sink.

Update the LSP tool callsites and internal helpers
(`captureDiagnosticVersions`, `captureOpenFileVersions`,
`syncFileContent`, `notifyFileSaved`, `formatContent`,
`getDiagnosticsForFile`, `reloadServer`, and the rename didClose /
didRenameFiles path) to forward their operation signal.

Warmup keeps its short explicit `initTimeoutMs` and passes no caller
signal; `sendRequest`'s existing `timeoutMs ?? (signal ? undefined : DEFAULT)`
policy still uses that fixed timer.

Fixes #3962
2026-07-01 02:06:03 +00:00
roboomp a1a393cdc5 fix(session): linearized session path rebuilds
- Replaced leaf-to-root unshift path assembly with push plus one reverse in buildSessionContext and SessionEntryIndex.pathTo.
- Added regression coverage that keeps deep linear context and branch paths root-to-leaf without Array.unshift work.

Fixes #3961
2026-07-01 01:59:34 +00:00
roboomp 58c84e4c94 fix(coding-agent): streamed write progress
Emitted partial write-tool updates before filesystem, archive, SQLite, internal URL, and conflict writes so the TUI can render execution-phase progress instead of waiting for the final result.

Updated the write renderer to keep partial results pending, show the progress snapshot, and suppress diagnostics until the final result.

Fixes #3960
2026-07-01 01:57:14 +00:00
roboomp 822314dea5 fix(mcp): attach stdin.write rejection handler before flush()
In the request() send path, stdin.write() could return a pending thenable while stdin.flush() threw synchronously. Control jumped to the outer catch before wrote.then(undefined, failFromSend) was ever installed, so a later async EPIPE on the write would fire as an unhandled rejection — reintroducing the very orphan path the parent fix removes.

Attach the rejection handler on the write result immediately after dispatching it, before calling flush(). If flush() then throws synchronously, wrote is already covered; if write() itself throws, flush() was never called and there is no flushed thenable to orphan.
2026-07-01 01:16:19 +00:00
roboomp e348e8d9b5 fix(eval): bound python shell helper output
Stream Python eval shell helper stdout in fixed-size chunks instead of buffering through subprocess.run or newline-bound text iteration.

Added regression coverage for !cmd and newline-free %%bash streaming.

Fixes #3950
2026-07-01 01:15:38 +00:00