Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
34d6dc6
fix(agent): never leak raw reasoning as a reply; transport-aware prompt
Aug 31, 2026
93f6d28
fix(agent): stop sending the reasoning prefill to native-tools chat p…
Aug 31, 2026
b29105b
fix(agent): finish the transport split — rules line, repair prompt, r…
plombeer31 Aug 31, 2026
25b4b78
fix(agent): keep live reasoning and prompt shape correct across cross…
Aug 31, 2026
bc0cf21
fix(skills): honor skills.catalogTokenBudget when building the skill …
Aug 31, 2026
644d389
test(skills): regression-guard the catalog-budget wiring; clamp the e…
Aug 31, 2026
4b7986d
fix(tui): clicking a slash-palette row runs that row's command
Aug 31, 2026
bec29e7
feat(tui): steer an Ollama-shaped External URL into the provider wizard
Aug 31, 2026
aade616
fix(tui): reserve the bottom row on legacy Win10 conhost
plombeer31 Aug 31, 2026
dab833b
fix(llm): stop cutting the live reasoning stream at a brace in the CoT
Aug 31, 2026
81f2fa6
feat(local-llm): CPU llama.cpp fallback for Windows boxes whose GPU b…
Aug 31, 2026
be76a7a
docs: add MEMORY_GUIDE.md — memory end to end, with worked examples
Aug 31, 2026
0d27ae3
feat(tui): free/paid price facet on the cloud model pickers
Aug 31, 2026
8f158fa
fix(tui): keep ssh-mangled mouse reports out of the composer
Aug 31, 2026
efc9ef1
feat(cli): memory export — one-way Obsidian vault export of the memor…
Aug 31, 2026
f8106ab
feat(local-llm): multi-GPU tensor split for the managed llama-server
Aug 31, 2026
47defe6
fix(tui): match the compat-steer's key precedence to its render order
Aug 31, 2026
e083901
docs: fix lesson-recall model and dedup metric in MEMORY_GUIDE
Aug 31, 2026
5d0a242
fix(local-llm): give the TUI CPU-backend fallback download a deadline…
Aug 31, 2026
28863f1
Merge remote-tracking branch 'origin/main' into fix/discord-ssh-mouse…
Aug 31, 2026
869bcd3
fix(tui): join reads in the post-trip leak stripper too
Aug 31, 2026
39415c1
integrate #286
Aug 31, 2026
f393e42
integrate #287
Aug 31, 2026
90e76d3
integrate #288
Aug 31, 2026
45ad2de
integrate #289
Aug 31, 2026
85af3dd
integrate #290
Aug 31, 2026
f93f255
integrate #291
Aug 31, 2026
5792c6b
integrate #292
Aug 31, 2026
e9d2a4f
integrate #293
Aug 31, 2026
f0c6b85
integrate #294
Aug 31, 2026
d8a54e0
integrate #295
Aug 31, 2026
1a1f03d
integrate #296
Aug 31, 2026
5378a11
integrate #297
Aug 31, 2026
f01896f
integrate #298
Aug 31, 2026
28184d5
merge origin/main (post #271-#276) into integration/discord-fixes-202…
Aug 31, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -1862,8 +1862,8 @@ The probe is **lazy / turn-boundary driven** — `pickProvider()` reads `Date.no

A fallover can cross transports — the common `cloud (native_tools) → local (grammar)` default (`appendLocal`) does exactly that. Both the request shape and the response parse are decoupled from the primary:

- **Request.** Each attempt re-resolves `{ transport, adapter }` for the chosen link via `resolveActiveLlmSlice(providerId)`, so the wire shape is correct for whoever serves. `buildLlmStreamParams` keeps `grammar` **populated even on the native path** (it used to blank it) so a grammar-only link handed the request still has its GBNF; native providers ignore `grammar` and read `tools`, so carrying both is safe.
- **Response.** The completion is stamped with `servedTransport` — the transport of the link that actually answered — by the fallback seams in [src/runtime/llm-fallback-seam.ts](src/runtime/llm-fallback-seam.ts) (`createFallbackCompleter` / `createFallbackStreamer`). `step-executor.parseDepsFor(completion, deps)` prefers `servedTransport` over the caller's configured `toolTransport` for every parse decision (`tryParseToolCalls`, the empty-completion recovery gate). Without this, a native primary that fell over to a grammar link parsed the grammar reply as OpenAI `tool_calls` and silently broke tool-calling. The stamp is pinned directly on the real seam factories by [src/runtime/llm-fallback-seam.test.ts](src/runtime/llm-fallback-seam.test.ts) (deleting either stamp turns it red) and end-to-end through the loop by [src/llm/fallback/fallback-e2e.integration.test.ts](src/llm/fallback/fallback-e2e.integration.test.ts).
- **Request.** Each attempt re-resolves `{ transport, adapter }` for the chosen link via `resolveActiveLlmSlice(providerId)`, so the wire shape is correct for whoever serves. `buildLlmStreamParams` keeps `grammar` **populated even on the native path** (it used to blank it) so a grammar-only link handed the request still has its GBNF; native providers ignore `grammar` and read `tools`, so carrying both is safe. On a think-tag profile the prompt shape is per-link too: the main prompt for a native-tools primary is built **prefill-suppressed** (issue #283 — a literal `<think>` shipped to a chat endpoint is at best noise, at worst corrupted server-side), and `LlmStreamParams.grammarPrompt` carries a lazy, memoized prefill-carrying variant that the seams substitute for grammar links (`promptFor`), so a llama-server link still gets the shape its template + GBNF prelude expect. The one-shot repair retry rebuilds both variants repair-shaped.
- **Response.** The completion is stamped with `servedTransport` — the transport of the link that actually answered — by the fallback seams in [src/runtime/llm-fallback-seam.ts](src/runtime/llm-fallback-seam.ts) (`createFallbackCompleter` / `createFallbackStreamer`). `step-executor.parseDepsFor(completion, deps)` prefers `servedTransport` over the caller's configured `toolTransport` for every parse decision (`tryParseToolCalls`, the empty-completion recovery gate). Without this, a native primary that fell over to a grammar link parsed the grammar reply as OpenAI `tool_calls` and silently broke tool-calling. The streamer additionally stamps `servedTransport` on **every chunk** — the return-value stamp only exists after the last delta, which is too late for the live stream parser: `consumeStream` creates its parser lazily off the first chunk's stamp so a grammar-served stream (whose GBNF output starts mid-`<think>`) keeps emitting live `reasoning_delta`s under a native primary. `completionAssumesOpenReasoning` keys purely off the served/parse transport: grammar-served output always continues an open think block; a chat completion never does (so even in the unsupported grammar-primary → native-link ordering a clean chat reply is no longer swallowed whole as reasoning). The stamps are pinned directly on the real seam factories by [src/runtime/llm-fallback-seam.test.ts](src/runtime/llm-fallback-seam.test.ts) (deleting either stamp turns it red) and end-to-end through the loop by [src/llm/fallback/fallback-e2e.integration.test.ts](src/llm/fallback/fallback-e2e.integration.test.ts), including think-tag profile cases in both directions of the parse decision.

The remaining asymmetry: `tools` is populated only when the **primary's** transport is `native_tools`. Placing a native-tools provider **below** a grammar-only primary would reach it without a `tools` payload — an unusual ordering; order native-tools links at or above the first grammar-only link. Slot affinity is decided pre-request from the primary, so a cloud→local fallover runs the local link without slot-cache reuse for that turn (correctness-neutral). The grammar string itself is always built for the primary model.

Expand All @@ -1876,7 +1876,7 @@ The remaining asymmetry: `tools` is populated only when the **primary's** transp
5. **Whole-chain exhaustion rethrows the last (already-humanized) error** so `loop_failed` classification is unchanged. Pinned by [src/llm/fallback/run-with-fallback.test.ts](src/llm/fallback/run-with-fallback.test.ts).
6. **Exactly one switch notice per state transition** (away / back), none on sticky turns. Pinned by [src/llm/fallback/provider-fallback-chain.test.ts](src/llm/fallback/provider-fallback-chain.test.ts).
7. **`appendLocal` appends the local provider when configured, nothing when not.** Pinned by [src/llm/fallback/fallback-config.test.ts](src/llm/fallback/fallback-config.test.ts).
8. **A cross-transport fallover parses the response with the served link's transport, not the primary's**, and the turn reaches the fallback's answer instead of `loop_failed`. Pinned by [src/llm/fallback/fallback-e2e.integration.test.ts](src/llm/fallback/fallback-e2e.integration.test.ts) (real `AgentLoop` + `step-executor`, both unary and streaming).
8. **A cross-transport fallover parses the response with the served link's transport, not the primary's**, and the turn reaches the fallback's answer instead of `loop_failed`. On a think-tag profile the grammar link also receives the prefill-carrying `grammarPrompt` variant and its streamed reasoning stays classified live (per-chunk `servedTransport` stamp). Pinned by [src/llm/fallback/fallback-e2e.integration.test.ts](src/llm/fallback/fallback-e2e.integration.test.ts) (real `AgentLoop` + `step-executor` + the real seam factories; both unary and streaming, plain and think-tag profiles).
9. **Breaker state is partitioned by session** — one partition's success does not clear another's armed cooldown, and a keyless call shares one default partition. Pinned by [src/llm/fallback/provider-fallback-chain.test.ts](src/llm/fallback/provider-fallback-chain.test.ts) ("partition isolation").
10. **The cooldown ladder must be non-decreasing** — a decreasing `cooldownMs` is rejected at parse time so "escalating" stays true. Pinned by [src/config/llm-config.test.ts](src/config/llm-config.test.ts).

Expand Down
1 change: 1 addition & 0 deletions MEMORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

This document is the source-of-truth for how cross-session memory works in `atomic-agent`. It complements:

- `MEMORY_GUIDE.md` — the operator-facing walkthrough with worked examples; start there if you want to *use* memory rather than modify it.
- `ARCHITECTURE.md` — overall runtime topology and invariants.
- `AGENTS.md` — short engineering summary for automated contributors.
- `PROMPT.md` — full anatomy of the stable prefix and variable tail, including where the memory channels render in the prompt.
Expand Down
Loading
Loading