Commit Graph
1548 Commits
Author SHA1 Message Date
can1357 0ab8e87f7d test(coding-agent): updated test input to match model typing and replacements
- Narrowed the xai-oauth bundled model cast to `Model<"openai-responses">` in its regression test.
- Changed hashline stale-recovery fixtures to use `repl(...)` for both line-replacement payloads instead of `extra(pl(...))`.
2026-05-27 19:01:11 +02:00
roboompandcan1357 9362cbf13d style: bun run fix 2026-05-27 19:00:49 +02:00
roboompandcan1357 efba782fa7 fix(tools): isolate read URL reader-mode fallback chain from remote stalls
A stalled Jina reader request shared the overall reader-mode AbortSignal
with the downstream trafilatura/lynx/native fallbacks. When Jina hung
until the budget timer fired, the shared signal aborted and the catch
handler's signal?.throwIfAborted() re-threw before any local fallback
ran.

- Bound Jina and Parallel extract to their own per-attempt sub-budget
  (REMOTE_READER_MAX_MS, capped at 10s) so a remote stall cannot consume
  the whole overall reader-mode budget.
- Catch handlers now rethrow only on real userSignal cancellation, not
  on remote sub-budget or overall budget expiry.
- Wrap trafilatura/lynx in their own try/catch so a subprocess failure
  or abort does not skip the in-process native renderer.
- Always attempt the native renderer last: it works on already-loaded
  HTML with no network or subprocess, so even an exhausted overall
  budget still yields a result.

Fixes #1449
2026-05-27 19:00:49 +02:00
oldschoolaandcan1357 56a7212035 fix(hashline): require anchor-content alignment in session-chain replay recovery
The recovery fallback that replays edits onto current text when the structured-patch 3-way merge refuses guarded only on line-count equality. If a prior in-session edit rewrote the very line a later stale-hash edit re-targets, replay overwrote the new content with the stale-anchored payload and emitted a 'Verify the diff matches your intent' warning that does not block the write.

Concrete window: v0 line 5 = 'L5', v1 = 'L5-CHANGED' (same line count). Edit E2 authored against H0 anchored at line 5 lands on v1 because the line-count gate passes, silently replacing L5-CHANGED with the model's L5-MODEL.

Add a verifyAnchorContent gate: walk every edit's anchors and require previousText[line] === currentText[line]. Any mismatch returns null so the caller raises MismatchError and the model re-reads. The success path now emits the standard RECOVERY_SESSION_CHAIN_WARNING (the hedged REPLAY_WARNING text was only sensible when content was partially aligned; that case is now unreachable, and the constant is removed).

Tests: packages/hashline/test/recovery-session-chain.test.ts pins both the corruption refusal and the safe-replay positive case (anchor on an unchanged line, 3-way merge fails on neighbouring rewritten context, replay succeeds with the standard chain warning). packages/coding-agent/test/core/hashline.test.ts adds an end-to-end through executeHashlineSingle so the production patcher path is covered too.
2026-05-27 18:55:29 +02:00
Can BölükandGitHub 8fa6652eec Merge pull request #1418 from can1357/farm/76c380e7/provider-models-deprecation-cache
fix(providers): prune stale synthetic model cache entries
2026-05-27 19:53:12 +03:00
Can BölükandGitHub f9c5484892 Merge pull request #1425 from oldschoola/fix/search-regex-error-prefix
fix(search): wrap native regex-build errors in ToolError
2026-05-27 19:53:02 +03:00
can1357 c5055d6623 feat(ai): added OpenRouter routing-variant suffix support
- Added `openrouterVariant` option to `SimpleStreamOptions` and `OpenAICompletionsOptions` to append routing suffixes (`:nitro`, `:floor`, `:online`, `:exacto`) to OpenRouter model IDs at request time.
- Skips appending when the model ID already carries an explicit colon-suffix.
- Exposed `providers.openrouterVariant` setting in the coding-agent UI under Settings → Providers.
- Plumbed through `pi-native-server` forwarder and `AgentSession` options preparation.
2026-05-27 18:41:47 +02:00
Can BölükandGitHub 77c2af46e7 Merge pull request #1444 from OutlineDriven/fix/compaction-reasoning-effort-fallback
fix(agent): compaction reasoning effort — fallback to off when reasoning unsupported
2026-05-27 19:41:40 +03:00
Can BölükandGitHub dc1eb8d96f Merge pull request #1446 from OutlineDriven/fix/xai-grok-oauth-stabilize
fix(ai,coding-agent): stabilize xAI Grok OAuth
2026-05-27 19:41:20 +03:00
metaphorics b76f39d3a6 fix(coding-agent): reopen approved plan on plan-mode reentry
Patch axis: extend

Displacement: net-zero; reuses existing plan reference state instead of adding persistence or overwriting approved artifacts

Rule violations averted: no approved-plan overwrite, no transcript format migration, no public CLI/API expansion

PASS/FAIL: PASS after plan-mode focused tests and package check. Note: system-prompt-templates has an unrelated HOME=/tmp path-shortening expectation failure.
2026-05-27 16:32:40 +00:00
metaphorics bb249cb911 test(coding-agent): mock authStorage + getProviderBaseUrl on image-gen xAI ctx
The Surface 1 commit added authStorage.hasNonEnvCredential as a credential
gate inside resolveXAIHttpCredentials, and the Surface 3 commit added
resolveXAIBaseURL which consults getProviderBaseUrl and getAll. The
existing image-gen xAI test mocked only getApiKeyForProvider on
modelRegistry, so the new code paths threw "undefined is not an object"
at runtime.

Add the missing mock surface:
  - authStorage.hasNonEnvCredential returns true for "xai-oauth" so the
    dedicated-credential gate routes through the xai-oauth branch (which
    the test's getApiKeyForProvider mock services).
  - getProviderBaseUrl returns undefined so resolveXAIBaseURL falls
    through to the XAI_BASE_URL / DEFAULT_BASE_URL leg, preserving the
    test's existing expectation that the request hits
    https://api.x.ai/v1/images/generations.
  - getAll returns [] so the per-model override check in
    resolveXAIBaseURL no-ops cleanly.

Op: correct
Restores: ref:feat/xai-grok-oauth@015437534 ref:feat/xai-grok-oauth@2c1abd7fa
2026-05-27 16:07:38 +00:00
cognitiveandmetaphorics 25c6794cd5 fix(agent): compaction honors session thinking level and silent-clamps unsupported-effort models
Triple-stacked failure on the same axis (thinking effort) produced the
user-visible

    Error: Compaction failed: Thinking effort high is not supported by
           xai-oauth/grok-build.
    Supported efforts:

(empty list after the colon) whenever the active model was a curated
xAI catalog entry with compat.supportsReasoningEffort: false.

Three defects lined up. (1) Behavior: compaction at four call sites
in packages/agent/src/compaction/compaction.ts hardcoded
reasoning: Effort.High and never threaded session.thinkingLevel —
the user's /model :off selection (and any explicit low/medium) was
silently overridden. On every other model this was invisible.
(2) Validation: requireSupportedEffort threw at the openai-flavored
mapper layer before the wire-side omitReasoningEffort gate in
providers/xai-responses.ts ever ran; two contradictory guards on the
same wire param. (3) Message: when getSupportedEfforts returned [],
the rendered error tail was 'Supported efforts: ' with nothing after
the colon — disappears as a side-effect of fix #2.

Fix #1 — thread ThinkingLevel | undefined end-to-end. Add
SummaryOptions.thinkingLevel and HandoffOptions.thinkingLevel.
Convert via a single exhaustive switch (effortFromThinkingLevel) in
the new resolveCompactionEffort helper:
  - Off            → undefined  (omit reasoning entirely)
  - undefined/Inherit → Effort.High → clamp per model (preserves the
                                       historical default for users
                                       who never touched the dial)
  - explicit Effort → respect user → clamp per model

resolveCompactionEffort lives in compaction.ts; all four call sites
(generateSummary, generateHandoff, generateShortSummary,
generateTurnPrefixSummary) route through it. agent-session.ts threads
this.thinkingLevel into all three production compaction entry points
(manual /compact at L6201, auto-compaction at L6458 — the most-fired
path, originally missed in plan review — and direct generateHandoff
at L5465). The audit-gate test
(test/agent-session-compaction-thinking-threading.test.ts) scans the
file with a brace-balanced extractor and refuses any unthreaded site.

Fix #2 — silent-clamp at the openai-flavored mapper layer. Extract
exported modelOmitsReasoningEffort(model) in model-thinking.ts as the
single source of truth for compat.supportsReasoningEffort: false on
openai-responses* APIs. getSupportedEfforts now calls it instead of
inlining the check (pure refactor — observable behavior preserved).
resolveOpenAiReasoningEffort in stream.ts early-returns undefined
when the predicate is true, so the wire-side omitReasoningEffort
gate (providers/xai-responses.ts:78) becomes the single source of
truth for the actual strip — no redundant throw.

Three regression tests pin the contract:
  - packages/ai/test/xai-oauth-effort-strip.test.ts (5 tests):
    modelOmitsReasoningEffort returns true for grok-build and
    grok-4.20-0309-reasoning, false for grok-4.3 / Anthropic /
    openai-completions.
  - packages/agent/test/compaction-thinking-level.test.ts (5 tests):
    every ThinkingLevel outcome through generateHandoff — Off stays
    undefined (not coerced to High), Low stays Low, Inherit / undefined
    default to High, grok-build clamps to undefined regardless of
    requested level. Covers the Codex-caught Off-vs-not-provided
    distinction.
  - packages/coding-agent/test/agent-session-compaction-thinking-threading.test.ts
    (2 tests): brace-balanced source scan asserts every direct
    compact() / generateHandoff() in agent-session.ts threads
    'thinkingLevel: this.thinkingLevel'; floor of 3 threaded sites.

TDD red-green verified for fix #1: temporarily reverted the handoff
call-site back to hardcoded Effort.High → compaction-thinking-level
went 2 pass / 3 fail (Off coerced, Low overridden, grok-build throws);
restored → 5 pass / 0 fail.

Verified:
  - packages/agent:  127 pass / 0 fail
  - packages/ai:     1061 pass / 337 skip / 0 fail
  - packages/coding-agent (focused): 179 pass / 5 skip / 0 fail
  - biome + tsgo --noEmit clean across all three packages

Out of scope (follow-ups):
  - branch-summarization.ts:307 already passes no reasoning — no edit.
  - The empty-list error message at model-thinking.ts:296 is now
    structurally unreachable from the openai-responses path.
  - modelOmitsReasoningEffort and grokSupportsReasoningEffort
    (xai-responses.ts:22) overlap; collapse into a single predicate
    in a future commit.

Op: correct
Restores: spec:compaction-honors-session-thinking-level
Restores: spec:xai-oauth-grok-build-compaction-no-throw
(cherry picked from commit e07b47ee46769053c658819437e2478389a4cee0)
2026-05-27 15:01:20 +00:00
can1357 5be5053696 fix(coding-agent): widen xAI test header captures via holder 2026-05-27 15:52:43 +02:00
can1357 7fd69dbb81 fix(coding-agent): format image-gen test 2026-05-27 15:50:13 +02:00
can1357 ff94f91104 feat: added extraBody support, xAI fixes, and image provider updates
- Added `extraBody` merging into OpenAI Responses request params.
- Fixed xAI OAuth redirect URI to fail fast on port conflicts.
- Exposed `antigravity` and `xai` as explicit `providers.image` options.
- Added `isImageProviderPreference` guard, replacing inline string checks.
- Fixed TTS tool to resolve output path relative to cwd and require write approval.
2026-05-27 15:20:55 +02:00
can1357 a3b27d0cdb chore(ai): fixup xAI cherrypick 2026-05-27 15:15:53 +02:00
can1357 f051cc6a0e feat(tools): added multi-range line selectors and raw mode support for URLs and directories
- Added support for multi-range line selectors on URLs (e.g., `:5-10,20-30`) and combining `:raw` mode with line range selectors.
- Added support for line range selectors on directory listings with offset and limit parameters.
- Fixed `:raw` selector being ignored for JSON and feed URLs and directory listing line selectors dropping offset parameter.
- Added clear error message for line offset beyond directory listing end.
- Refactored URL parsing and directory reading to support multiple comma-separated ranges and improved line-based slicing logic.
- Added comprehensive test coverage for multi-range selectors, raw mode combinations, and directory range operations.
2026-05-27 15:03:12 +02:00
can1357 8a0329026c refactor(hashline): redesigned patch syntax from sigil-ops to anchor+payload model
- Replaced `LINE↑`/`LINE↓`/`A-B:` op sigils with unified `A-B:` anchor + `|`/`↑`/`↓` payload sigils.
- Added `mode: "replacement"` tag to insert edits so the applier distinguishes replace-bucket from insert-bucket lines.
- Removed lenient fallbacks (implicit continuation, inline payload acceptance, escaped delimiter stripping).
- Updated grammar, prompt, tokenizer, parser, applier, and messages to match the new format.
2026-05-27 14:45:01 +02:00
can1357 8f7f240b56 Merge remote-tracking branch 'origin/farm/e054d7f9/fix-legacy-pi-ai-type-export' 2026-05-27 14:43:43 +02:00
roboomp 6f7da0769b fix(extensibility): redirected legacy pi-ai root imports through Type-compat shim
Plannotator-class legacy extensions still import `Type` from
`@(scope)/pi-ai` (e.g. `@earendil-works/pi-ai` rewritten to
`@oh-my-pi/pi-ai`). pi-ai 15.1.0 removed the root `Type` runtime
export, so extension load crashed with `Export named 'Type' not found`
even though the `@sinclair/typebox` Zod-backed shim still ships in the
coding agent.

Routed bare `@oh-my-pi/pi-ai` root specifiers — used by both the
mirrored-source rewriter and the Bun.plugin onResolve hook — through a
new sibling shim that re-exports the canonical pi-ai surface plus the
`Type` runtime from the existing TypeBox shim. Subpath imports such as
`@oh-my-pi/pi-ai/utils/oauth` continue to resolve directly against the
bundled pi-ai package.

Fixes #1437
2026-05-27 12:14:57 +00:00
can1357 abac192890 refactor(coding-agent/edit): removed optional path parameter from hashline edit operations
- Removed `path` field from hashline input parameters and function signatures across diff, execute, and params modules.
- Updated HashlinePatch.parse() calls to omit the path option, relying on the ¶PATH#HASH header in input instead.
- Removed unused warning tracking for escaped payload delimiters in hashline parser.
2026-05-27 13:34:10 +02:00
can1357 024690419d feat(hashline): added detection and stripping of extra backslashes
- Added detection and stripping of extra backslashes before indented payload rows, which models often emit when JSON-escaping the delimiter.
- Added `_input` field alias support in hashlineEditParamsSchema to accept provider-emitted variants.
- Added warning message for escaped payload delimiter acceptance to guide users toward canonical syntax.
2026-05-27 13:28:08 +02:00
can1357 b0cedda9ae fix(hashline): modified scanInlineBody to strip the payload
- Modified scanInlineBody to strip the payload prefix when present at the start of inline content.
- Added test cases covering backslash-delimited payloads in insert, delete, and replace operations.
2026-05-27 13:21:42 +02:00
can1357 41d509eff0 feat(find): grouped output by directory and clamped limit to 200
- Changed output format to group results under `# /` headers to reduce token usage for shared path prefixes.
- Clamped the `limit` parameter to 1-200 (default 200) instead of the previous 1000.
- Updated tests to assert against raw file lists instead of parsed text output.
2026-05-27 13:13:11 +02:00
can1357 558ef2ba33 feat(hashline): changed payload continuation prefix from + to \
- Updated the payload continuation syntax to use backslash (`\`) instead of plus (`+`) as the explicit prefix for multi-line payloads and blank lines.
- Modified grammar, format constants, parser comments, and all documentation and test cases to reflect the new syntax.
- This is a breaking change for existing hashline patches using the `+` prefix.
2026-05-27 13:06:59 +02:00
can1357 fe3b982976 refactor(hashline): removed delete operation support from hashline format
- Removed the `!` delete sigil and all associated parsing, validation, and tokenization logic. The delete operation is no longer a supported edit kind.
- Updated grammar, format constants, and error messages to reference only insert and replace operations.
- Simplified the executor's overlap validation to handle only replace operations.
2026-05-27 13:01:50 +02:00
can1357 e3ff9826d1 fix(hashline): skipped markdown comments before hashline operations in parser
- Parser now buffers markdown-style `#` lines and skips them when they directly precede a hashline operation.
- It now preserves comment lines that are not immediately before an operation while still handling blank separators as regular raw input.
- Added focused parser tests plus prompt and changelog updates describing the new comment-skipping behavior.
2026-05-27 13:01:49 +02:00
can1357 d1920e9ca5 refactor(coding-agent/edit): removed redundant hashline headline from tool result output
- Simplified `renderSection` output assembly in hashline execution to stop injecting a separate headline.
- Removed conditional headline generation that prefixed create/update/status text before the header.
- Returned tool results containing only header, preview, and warnings content blocks.
2026-05-27 13:01:49 +02:00
Can BölükandGitHub ad8bf18189 Merge pull request #1426 from oldschoola/fix/session-emit-listener-isolation
fix(session): isolate event listener failures in agent fan-out
2026-05-27 13:45:01 +03:00
can1357 552c93842f Merge remote-tracking branch 'origin/farm/fa17b3a4/scope-package-changelog-lookup' 2026-05-27 10:26:33 +02:00
can1357 5027350e9e Merge remote-tracking branch 'origin/farm/a4b770e9/plan-mode-keeps-resolve-tool' 2026-05-27 10:25:39 +02:00
can1357 c0faf597c2 fix(hashline): added preflight write guards and duplicate target rejection
- Preflighted write policies for all sections before any commit in multi-section batches.
- Rejected duplicate canonical targets (e.g., `a.ts` and `./a.ts`) before writes begin.
- Fixed `after_anchor` normalization mutating cached edits across repeated patch applications.
- Fixed `detectLineEnding` to use first-occurrence style instead of majority vote.
2026-05-27 10:25:19 +02:00
oldschoola 48d63d4ddf fix(session): satisfy tsgo strict checks on void-return listener
Two TS errors in CI:
1. `agent-session.ts:1317` — `error TS1345: An expression of type 'void'
   cannot be tested for truthiness`. The listener type is
   `(event: AgentSessionEvent) => void`, so the returned value can't be
   directly tested. Same shape in `agent.ts:1079`.
2. `test/session/emit-listener-isolation.test.ts:19` — the test fixture
   for `AgentEvent.tool_execution_start` was missing the required `args`
   field.

Cast the return to `unknown` and check `instanceof Promise` instead of
duck-typing `.then` — type-safe and matches what async functions actually
return. Add `args: {}` to the test fixture.
2026-05-27 01:07:09 -07:00
roboomp e2431d59dc fix(coding-agent): kept hidden resolve tool registered when plan mode is enabled
createAgentSession() removed the hidden `resolve` tool from the registry
whenever no active tool advertised `deferrable: true`. Plan mode dispatches
its plan-approval `resolve { action: "apply", extra: { title } }` call
through a standing handler installed by InteractiveMode (no deferrable tool
involved), so read-only plan-mode toolsets (e.g. `read`, `search`, `find`,
`web_search`) silently activated plan mode without `resolve`. The agent had
no callable tool to submit the finalized plan and got stuck on the post-turn
tool-decision reminder.

Keep `resolve` registered whenever `plan.enabled` is true so the standing
handler always has a callable tool. The hidden flag still prevents `resolve`
from appearing in the active tool set until plan mode (or a deferrable tool's
preview action) opts in.

Fixes #1428
2026-05-27 07:00:47 +00:00
oldschoola db84b52c0c fix(search): wrap native regex-build errors in ToolError
The catch block at search.ts:480-485 tried to convert native regex-build
failures into clean `ToolError`s but checked for the prefix `"regex parse
error"` (lowercase). The native crate at `crates/pi-natives/src/grep.rs`
actually emits `"Regex error: "` (capital R, no "parse"). The branch was
unreachable: invalid patterns like `a[` leaked out as raw `Error` with a
stack trace instead of being wrapped in a structured `ToolError` for the
agent to feed back on.

Match against `/^regex(?: parse)? error/i` so both the actual native
prefix and any hypothetical `regex parse error: ...` variant are caught.
Rewrite the leading prefix to `Invalid regex: ` so the agent immediately
sees the failure mode.

Test: new `test/tools/search-invalid-regex.test.ts` asserts the pattern
`a[` rejects with an `instanceof ToolError` whose message matches `/regex/i`.
Fails on current main (raw `Error` escapes); passes with the fix.
2026-05-26 23:26:15 -07:00
oldschoola 08bccfe0ec fix(session): isolate event listener failures in agent fan-out
Both `AgentSession.#emit` (session/agent-session.ts) and `Agent.#emit`
(packages/agent/src/agent.ts) iterated listeners with no error isolation.
A synchronous throw in any subscriber aborted the for-loop, so later
subscribers (TUI rendering, ACP bridge, task executor progress,
hindsight) silently missed events. Many listeners — see
`modes/controllers/event-controller.ts:141` and
`modes/controllers/input-controller.ts:576` — are registered as
`async (event) => { await this.handleEvent(event); }`; the returned
Promise was dropped, so any rejection became an unhandled rejection.

Wrap each listener invocation in try/catch and attach a `.catch` to any
returned thenable. Errors are logged via `logger.warn` (already imported
in agent-session.ts) and `console.error` (agent.ts has no logger
dependency, keep it that way).

Test: new `test/session/emit-listener-isolation.test.ts` registers two
listeners on both classes; first listener throws (or returns a rejecting
Promise); asserts the second listener still receives the event AND no
`unhandledRejection` fires. 4 cases (sync+async × Agent+AgentSession).
All fail on current main; all pass with the fix.
2026-05-26 23:26:15 -07:00
roboomp 8c37a8adb0 fix(coding-agent): scoped package-dir lookup to omp's own package
`getPackageDir()` walked up from `import.meta.dir` and fell back to
`getProjectDir()` (the user's `cwd`) when no `package.json` was located.
Inside `bun --compile` binaries `import.meta.dir` resolves to
`/$bunfs/root`, so the walk hit the filesystem root and `omp` ended up
reading the host project's `CHANGELOG.md` as its own — both in startup
"What's New" display and `/changelog`. Worse, parsing succeeded on any
`## [x.y.z]` heading, so `lastChangelogVersion` was persisted into
`~/.omp/agent/config.yml` based on the host project's file.

- Made `getPackageDir()` return `string | undefined`; removed the `cwd`
  fallback so package-asset lookup never bleeds into the host project.
- Extracted the walk-up into a pure `walkUpForPackageDir(startDir)` so
  the resolution contract is unit-testable from arbitrary directories.
- Made `getChangelogPath()` propagate `undefined` and taught
  `parseChangelog` to accept it, returning `[]`. Existing callers
  (`main.ts` startup, `/changelog` TUI handler, `/changelog` slash
  command) already gate on empty entries, so the compiled-binary path
  now skips changelog display cleanly without mutating settings.
- Added `test/issue-1423-repro.test.ts` covering the resolver contract,
  the `parseChangelog(undefined)` path, the `PI_PACKAGE_DIR` override,
  and the negative assertion that a host `## [99.0.0]` heading never
  surfaces as an omp entry.

Fixes #1423
2026-05-27 05:46:35 +00:00
can1357 b12e4698a6 feat: added @oh-my-pi/hashline package and migrated hashline tooling
- Added a dedicated @oh-my-pi/hashline package with parser, patcher, filesystem, snapshots, and release metadata.
- Migrated coding-agent hashline and stream entrypoints to @oh-my-pi/hashline and removed old hashline module exports.
- Changed multi-section hashline execution to validate section hashes and flush diagnostics only at the final commit.
- Added session fileSnapshotStore support and rewired edit/read/search/write tools to use it instead of fileReadCache.
2026-05-27 04:03:49 +02:00
can1357 56c34a0d13 feat(summary): added BFS unfold and file-scoped line ranges to search
- Added `unfoldUntilLines`/`unfoldLimitLines` options to progressively reveal nested elidable spans breadth-first instead of collapsing everything behind the outermost elision.
- Added `minTotalLines` setting to skip summarization for short files, returning verbatim content instead.
- Added `:` selector support to `search` paths for constraining matches to specific line ranges.
- Extracted `parseLineRanges`/`parseLineRangeChunk`/`isLineInRanges` from `read.ts` into shared `path-utils.ts`.
2026-05-27 03:55:04 +02:00
can1357 739903f970 feat(hashline)!: disallowed inline payload on op lines, required + rows
- Removed inline_body from grammar; op sigils (↑, ↓, :) now accept no trailing content.
- Executor emits INLINE_PAYLOAD_ACCEPTED_WARNING when legacy inline form is encountered but still applies the edit leniently.
- Updated prompt docs and all tests to use bare op + `+`-prefixed continuation rows.
2026-05-27 03:20:20 +02:00
can1357 e5bb017b21 test(coding-agent/tools): changed two test expectations from exact string
- Changed two test expectations from exact string match (toBe) to substring match (toContain) for the '(no output)' text.
- This allows tests to pass when the output contains additional content beyond the expected string.
2026-05-27 02:06:54 +02:00
roboomp d87eeaa2ac fix(providers): pruned stale synthetic models
Treat Synthetic discovery as an authoritative catalog so deprecated bundled IDs are removed from resolved model lists and cache snapshots. Validate Synthetic API keys through the models endpoint instead of a model-specific chat request.\n\nFixes #1417
2026-05-26 23:59:51 +00:00
can1357 3e5b0b2340 feat(coding-agent/tools): added bash wall-time tracking to results and renderer
- Measured bash wall-clock duration for direct, terminal-bridge, and interactive execution paths.
- Recorded wall time in result notices and details, then stripped the duplicated literal notice during shell rendering.
- Updated the renderer to include wall time in the status label and added tests for the new wall-time behavior.
2026-05-27 01:53:34 +02:00
can1357 39714226b6 fix(hashline): relaxed strict payload continuation to lenient fallback
- Changed unprefixed continuation lines from a hard error to accepted implicit payload with a warning.
- Demoted inner `LINE:TEXT` ops whose anchors fall inside a pending `A-B:` block to payload continuation lines instead of raising an overlap error.
- Added `IMPLICIT_CONTINUATION_WARNING` and `PAYLOAD_LINE_PREFIX_DEMOTED_WARNING` constants for both new lenient paths.
2026-05-27 00:46:08 +02:00
can1357 4e32fd0060 feat(hashline)!: required + prefix on payload continuation lines
- Changed multiline payload syntax so continuation lines must start with `+`; that prefix is stripped before writing.
- Raw unprefixed lines after an op now throw an error instead of being silently accepted as payload.
- Removed `PAYLOAD_LINE_PREFIX_DEMOTED_WARNING` and the nested-replace demotion path; inner `N:` ops inside a pending `A-B:` now raise an overlap error.
- Raw blank lines between ops are ignored; use `+` alone for an empty payload line.
2026-05-27 00:37:18 +02:00
can1357 d409b6d2f6 fix(coding-agent/hashline): resolved nested replace demotion in hashline
- Handled an inner `replace` op that appears inside a pending multiline `A-B:` block by appending its body to the outer payload and preserving `LINE:`/`A-B:` body content as continuation.
- Retained same-range replace-pair coalescing while adding a warning when nested replace anchors are demoted from op markers to payload lines.
- Added hashline tests for nested payload demotion behavior, expected warnings, and non-demoted out-of-range `N:` replacements.
2026-05-27 00:30:46 +02:00
can1357 736e52b774 fix(hashline): removed single-line pure-insert duplicate absorption
- Single-line pure-insert duplicates are ambiguous (e.g., `N↓}` may be an anchor echo or an intentional delimiter), so single-line absorb logic was removed.
- Multi-line context echo absorption is unchanged; still gated on `autoDropPureInsertDuplicates`.
- Updated tests to expect literal output for previously auto-dropped single-line cases.
2026-05-27 00:25:22 +02:00
can1357 6ce5b6ff6e fix(hashline): coalesced identical-range replace pairs instead of throwing
- Changed identical `A-B:` duplicate ops to last-wins coalesce with a warning, fixing spurious anchor-conflict errors when models emit before/after pairs.
- Non-identical overlap shapes (different ranges, replace+delete, delete+delete) still throw.
- Added new file hash line to edit tool result output after successful apply.
2026-05-27 00:24:56 +02:00
can1357 535f7cfa89 fix(coding-agent/tools): reworked yolo approval resolution to honor user tool policies
- In `resolveApproval`, yolo mode now returns the user policy directly (`allow`/`prompt`/`deny`) and ignores tool `override` prompts.
- Updated approval-mode and approval unit tests to match the new behavior for critical bash patterns under yolo and auto-approve.
- Updated docs and settings metadata to describe yolo as user-policy-driven rather than override-driven.
2026-05-27 00:21:33 +02:00
can1357 29953486a5 refactor(coding-agent)!: removed href/hline helpers and fixed blank-line payload semantics
- Removed `href`, `hrefr`, and `hline` Handlebars helpers along with shared hashline anchor state; unused by any template.
- Changed blank lines between ops from silent separators to literal payload lines appended to the open op.
- Added overlapping-delete validation to reject before/after-block patch patterns.
- Simplified hashline prompt doc, removing template-helper examples and tightening rules.
2026-05-27 00:04:45 +02:00