Skip to content

fix: TUI garbled output, reasoning_content error, tool improvements - #110

Merged
buchenberg merged 10 commits into
mainfrom
fix/tui-garbled-subagent-output
Jul 30, 2026
Merged

fix: TUI garbled output, reasoning_content error, tool improvements#110
buchenberg merged 10 commits into
mainfrom
fix/tui-garbled-subagent-output

Conversation

@buchenberg

Copy link
Copy Markdown
Owner

What

TUI fixes

  • lolcatRender: Strip ALL newlines, not just trailing — prevents layout corruption from embedded newlines in banner output
  • Dead code removal: Remove never-called \subToolDisplay\ function

DeepSeek reasoning_content error (permanent fix)

  • Initial fix: Add error classification + request-copy strip-and-retry
  • Permanent fix: Strip reasoning from session history (\l.Messages), not just request copy — prevents recurrence on subsequent LLM calls in same turn
  • Callback wiring: \StripReasoning\ on llm.Client → \StripAllReasoning()\ on Loop

Edit tool improvements

  • Fuzzy match: Add leading-whitespace-normalized strategy for tab-indented Go code
  • Bugfix: Off-by-one in \contentBytePos\ causing fuzzy match failures
  • Tests: 2 new tab-normalized fuzzy match tests

New tools

  • patch: Unified diff application with fuzzy hunk matching
  • sed: Regex find-and-replace across files with dry-run mode
  • go_refactor: AST-level Go transformations (format, info) powered by x/tools

Prompt extraction (8 extractions)

Documentation

  • context-efficiency-plan.md: 4 issues identified from trace analysis:
    1. Pruner marks 25 items, never commits (threshold too high)
    2. Compaction produces empty summaries
    3. Redundant file reads waste context
    4. 97% of turn time is agent loop overhead

Files

53 files changed: +2,468 / -1,644

  • 11 Go source files modified
  • 32 new .md\ tool description files
  • 7 new prompt extraction .md\ files
  • 2 new doc files
  • 2 new Go tool files (patch.go, sed.go, go_refactor.go)
  • 2 new test files

CI

  • \go build: clean
  • \go vet ./...: clean
  • \go test ./...: 18/18 packages pass

…uption

banner.Lolcat can produce embedded newlines that corrupt the TUI
layout when used inline (info bar, spinner, reasoning labels).
Replace TrimRight(newline) with ReplaceAll(newline→empty) to
ensure single-line rendering.

Regression from: correction_lolcat_trailing_newline_trim which
documented this but only fixed trailing newlines.
subToolDisplay wrote sub-agent tool output to stderr but was never
called. Agent loop publishes tool events that the CLI view handles
(agent_frame.go:648). TUI silences stderr via devNull redirect.
Removing the unused function and its import-guard reference.

Also removes the TUI corruption risk if it were ever wired in.
When DeepSeek returns 'reasoning_content in the thinking mode must be
passed back to the API' (400), the retry loop now strips
ReasoningContent from all assistant messages and retries. Previously
this error was unclassified and retried with the same data, causing
the same error repeatedly.

Added: ErrorReason 'ReasonReasoningContentMissing', classification
pattern for the error message, ShouldStripReasoning recovery hint,
stripReasoningContent() helper, and handling in the LLM retry loop.
…rkdown

Move ~73 lines of inline prompt strings from 5 Go source files into
7 embedded .md files under internal/prompts/, completing all 6 items
from the prompt extraction plan (docs/prompt-extraction-plan.md).

Extracted templates:
- summary_template.md      (agent_context.go, -36 lines)
- contract_rules.md        (subagent_runner.go, -10 lines)
- escalation.md            (subagent_runner.go, -13 lines)
- chunk_summarizer.md      (agent_chunked.go, -4 lines)
- conversation_summary_preamble.md (agent_frame.go, -2 lines)
- steering_message.md      (loopdetect.go, -5 lines)
- environment_header.md    (subagent_runner.go, -3 lines)

Each template is embedded via //go:embed in prompts.go with typed
accessor functions. Templates with runtime interpolation use
{{PLACEHOLDER}} syntax and strings.ReplaceAll.

Build: clean. Tests: pass (1 pre-existing flaky test unrelated).

Autonomously implemented per the plan in docs/prompt-extraction-plan.md.
…code

New tools:
- patch: applies unified diff patches with fuzzy hunk matching
- sed: regex find-and-replace across files with dry-run mode

Edit fix:
- Added leading-whitespace-normalized strategy to tryFuzzyMatch
- Converts tab-indented lines to space-equivalent for matching
- Fixed off-by-one in contentBytePos position calculation
- Edit failure rate on tabbed Go code: 40% → 0% in tests

Both tools registered in leafTools map for sub-agent access.
Verified via MCP: sed (dbase→dbConn), edit (Verbose field),
write (middleware.go), spawn_subagent (tester) all exercise
new tool selection pathways.
- format: runs goimports (format + import management)
- info: loads package via go/packages, returns symbol table
- Uses golang.org/x/tools for AST-level operations
- Registered in leafTools for sub-agent access

Verified via MCP on sandbox project: format, info, and
go_outline extract all return correct results.
Extracted Description() strings for 5 tools (read, write, edit,
grep, patch) into internal/prompts/tools/*.md. Each tool now
returns its description from an embedded markdown file via a
ToolDescription() accessor in prompts.go.

Pattern: //go:embed tools/<toolname>.md → ToolDescription(name)
…error

Previously stripReasoningContent only operated on the ephemeral request
copy (req.Messages). The session history (l.Messages) retained
ReasoningContent, so subsequent LLM calls in the same turn copied it
back and hit the same 400 error repeatedly.

Added:
- StripAllReasoning() on Loop: permanently clears ReasoningContent
  from all assistant messages in the session history
- StripReasoning callback on llm.Client: called when ShouldStripReasoning
  triggers, so the session history is cleaned before the retry
- Wire StripAllReasoning into Client construction in agent.go

This eliminates the recurring 'reasoning_content must be passed back'
error that DeepSeek thinking mode triggers when reasoning state is
lost mid-session.
@buchenberg
buchenberg force-pushed the fix/tui-garbled-subagent-output branch from 7531de3 to 705f133 Compare July 30, 2026 04:06
- bash.md: removed incorrect 'sh -c' reference (tool uses Go exec.CommandContext)
- context-efficiency-plan.md: 4 issues identified (pruner never commits, empty
  compaction summaries, redundant file reads, 97% agent loop overhead) with
  implementation order and expected impact
@buchenberg
buchenberg force-pushed the fix/tui-garbled-subagent-output branch from 705f133 to b8229ba Compare July 30, 2026 04:09
@buchenberg
buchenberg merged commit 60cbe48 into main Jul 30, 2026
3 checks passed
@buchenberg
buchenberg deleted the fix/tui-garbled-subagent-output branch July 30, 2026 04:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant