Skip to content

feat/fix: faster first agent task, accurate errors, RAG sources in the CLI, no false network notice, safe test suite - #56

Merged
TrinaxCode merged 42 commits into
mainfrom
ccr-fe2460a0-c0akjx
Oct 26, 2026
Merged

TrinaxCode merged 42 commits into
mainfrom
ccr-fe2460a0-c0akjx

Conversation

@TrinaxCode

@TrinaxCode TrinaxCode commented Oct 24, 2026 •

Copy link
Copy Markdown
Owner

Description

Improvements found by using TrinaxAI the way a new user would: a real Ollama (0.40.10) with qwen3.5:4b and qwen3-embedding:0.6b on 4 CPU cores, the real CLI, the real web app in a browser, and real indexed documents. 41 commits; every CI run that finished is green. Everything is in the 1.4.0 section of docs/CHANGELOG.md (EN/ES).

First round

  1. Faster first agent task: the interactive agent sends its fixed prompt prefix with a one-token reply while the user types (82.6 s → 35.2 s first task, measured).
  2. Errors name the real cause: stopped service, missing model (CLI and API), "Please retry" only when a retry can help.
  3. RAG answers cite their sources in the CLI (Sources: aurora.md, manual.pdf (p. 3)).
  4. ask/chat use the installer-chosen model (no pinned qwen3.5:2b; a saved legacy qwen3.5:2b now means automatic).
  5. Output polish: no TRINAXAI_PROGRESS lines in index, readable dates and sizes, stopped instead of stopped not found, honest dry-run LAN line.
  6. No false "different network" notice while the gateway is bound to this computer only.
  7. Terminal router: file and git requests go to the agent, URLs and conceptual questions stay chat (second review fixed too-broad vetoes and path-vs-URL).
  8. A long, correct answer is no longer mistaken for a refusal.
  9. The test suite no longer shuts down the developer's own services (guards in tests/conftest.py, now also covering os.kill/os.killpg).

Later rounds (found by running the product, then by three independent code reviews)

  • Agent sandbox: python3, python, cc, awk were "not found" on Debian/Ubuntu (links through /etc/alternatives); that one read-only folder is now mounted. "Run the tests" works.
  • Agent follow-through: the "create one file" shortcut no longer cuts short a request for several files or a run; it is asked once to run what it was asked to run; a failed run is chased up to twice (not after an edit, not hidden by an unrelated passing command); after "rename X to Y" it searches for the old name and goes back to finish. Verified with the real model: create module + tests + run (5 passed), rename across three files (all updated, tests pass).
  • trinaxai network off and an honest network status (no unreachable LAN URLs); .env read like the service reads it.
  • CLI: reaches a local API served without HTTPS (loopback, TrinaxAI's own /health, no token sent); names a missing collection; a wait-limit timeout is no longer reported as a network failure (TRINAXAI_CLI_TIMEOUT); research takes plain words, has --web, and lets the server choose reasoning (a web lookup went from 2m43 and no answer to 44 s with citations); a scripted agent run says on stderr why an edit was refused.
  • Indexing names files skipped for size and says why a file with no text is left out.
  • Installer scripts print plain text when piped or with NO_COLOR; test-installers.sh guards the no-color block.
  • Security review of this branch's own changes: no credentials over the unverified plain-HTTP fallback; the rename search skips symlinks.
  • Docs: README command table, CLI reference, environment variables, troubleshooting, network pairing.

Verified end to end (real models, 4 CPU cores)

  • RAG over documents (PDF, DOCX, PPTX, XLSX): correct answers with the right source; unanswerable questions refused with no sources.
  • Agent: create + test + run, rename across files, HTTP agent asking approval for git add/git commit.
  • Web app in Chromium: onboarding, a real chat, mobile layout, 0 axe-core violations.
  • Interactive installer in a pseudo-terminal; status/stop against live services.
  • Limitations measured, not fixed: code Q&A with a 4B model has citation precision 0.6 and can miss the chunk holding the answer; the model can leave things undone on long tasks (the checks above catch the common cases); trinaxai research synthesis takes minutes on CPU; Windows end to end, GPU hosts and larger models are not measured.

Type of change

  • Bug fix
  • New feature
  • Documentation update

Checklist

  • Tested locally: full Python suite (coverage 98.11% with CI's scope), ruff, mypy, installer checks.
  • CI green on every finished run of this branch; the latest commits are still running.
  • Changelog (EN/ES), CLI reference and environment-variable docs updated.
  • Security implications considered (see above); error texts remain fixed strings.

🤖 Generated with Claude Code

https://claude.ai/code/session_01SZ4EYrCPbq3hhNsUVRT46K

The first agent request pays for loading the model and processing the system
prompt and tool schemas (about 1,700 tokens). Measured on 4 CPU cores with
qwen3.5:4b: 82.6 s for the first task cold, 35.2 s after a background warm-up
that ran while the user was typing. Best-effort and silent on failure; one-shot
runs are unchanged.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZ4EYrCPbq3hhNsUVRT46K
Signed-off-by: Claude <noreply@anthropic.com>
…staller's model

Found by using the CLI against a real Ollama and indexed corpus.

- Stopped service: "Cannot reach the local TrinaxAI service. Start it with:
  trinaxai start" instead of "the internet connection is unavailable".
- Missing model: "The model 'x' is not installed. Install it with: ollama pull x"
  in the CLI, and AI_MODEL_UNAVAILABLE (not external-service) in the API, which
  also stops suggesting "Please retry" for errors a retry cannot fix.
- RAG answers list the files they cite, as the web app does.
- ask/chat default to the installer-chosen model instead of a pinned qwen3.5:2b.
- index no longer prints TRINAXAI_PROGRESS telemetry; collections list shows
  readable dates.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZ4EYrCPbq3hhNsUVRT46K
Signed-off-by: Claude <noreply@anthropic.com>
With the gateway bound to this computer only (the installer default), a
changed Wi-Fi address or stale LAN certificate affects nobody, but the web
app still showed "A different network was detected" every time the laptop
changed network. needsRefresh is now false unless the gateway is reachable
from the local network. The gateway test no longer assumes a private LAN
interface exists.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZ4EYrCPbq3hhNsUVRT46K
Signed-off-by: Claude <noreply@anthropic.com>
Running the tests on a machine with TrinaxAI up stopped its Ollama and API.
test_shutdown_endpoint_requires_auth posted /system/shutdown from loopback
without patching the spawner, which launched a real detached
`service_manager.py stop-ai`; a launchctl test ran the real stop-by-name over
the machine's process table. Both are isolated, and two autouse guards (in a
new tests/conftest.py) make any future test that signals a process it did not
start, or launches the real service manager, fail loudly instead.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZ4EYrCPbq3hhNsUVRT46K
Signed-off-by: Claude <noreply@anthropic.com>
@TrinaxCode TrinaxCode changed the title feat/fix: faster first agent task, accurate CLI errors, RAG sources, installer-chosen model feat/fix: faster first agent task, accurate errors, RAG sources in the CLI, no false network notice, safe test suite Oct 24, 2026
claude added 25 commits October 24, 2026 09:51
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZ4EYrCPbq3hhNsUVRT46K
Signed-off-by: Claude <noreply@anthropic.com>
The terminal router sent "fix the bug in calc.py", "read main.py and tell me
what it does" and "commit these changes" to plain chat. A named file with a
code/text extension is now a workspace target (framework names such as node.js
are not files), reading a named file counts as agent work, and git orders go to
the agent only when they open the message or follow a verb such as run/ejecuta,
so "explain what a git commit is" and "commit message conventions" stay chat.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZ4EYrCPbq3hhNsUVRT46K
Signed-off-by: Claude <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZ4EYrCPbq3hhNsUVRT46K
Signed-off-by: Claude <noreply@anthropic.com>
…ess is off

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZ4EYrCPbq3hhNsUVRT46K
Signed-off-by: Claude <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZ4EYrCPbq3hhNsUVRT46K
Signed-off-by: Claude <noreply@anthropic.com>
A correct, long answer about TrinaxAI's own code was treated as a refusal and
lost its sources because "no está disponible" appeared mid-explanation
("si esto falla o no está disponible en el entorno ..."). Found by evaluating
questions over source files with a real model. Markers are now matched in the
first 300 characters, where a refusal opens an answer; both directions are tested.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZ4EYrCPbq3hhNsUVRT46K
Signed-off-by: Claude <noreply@anthropic.com>
The installer asks whether other devices may reach TrinaxAI and 'network
refresh' turns that on later, but there was no command to turn it back off:
the only way was to edit .env by hand. 'trinaxai network off' binds the web
app to this computer only and restarts it, 'trinaxai network' reports the
current state, and both are translated and documented (EN/ES).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZ4EYrCPbq3hhNsUVRT46K
Signed-off-by: Claude <noreply@anthropic.com>
…k to this-computer-only

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZ4EYrCPbq3hhNsUVRT46K
Signed-off-by: Claude <noreply@anthropic.com>
A tool that ran but failed (a degraded result, or a command that exited
non-zero) was shown with the same green check as a success. Seen in a real
browser run where the agent's first git commit failed with "Changes not staged
for commit" yet carried a check mark. The step card now shows a labelled
warning icon for those results; clean exits, plain results and denials are
unchanged. Covered by a component test.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZ4EYrCPbq3hhNsUVRT46K
Signed-off-by: Claude <noreply@anthropic.com>
…) and how to fix it

With a real model the first git commit fails because nothing is staged in every
CLI, HTTP and web run. A prompt line telling it to stage first did not change
that (0 of 2 runs), so it is not shipped; the failed result now carries a
[hint] naming the fix, which the model and the user both read.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZ4EYrCPbq3hhNsUVRT46K
Signed-off-by: Claude <noreply@anthropic.com>
…ing the user

A model's first git commit fails for lack of staged changes in nearly every
real run (CLI, HTTP, web), costing the user an approval click and a round trip.
A new optional Tool.state_check, which can see the workspace, refuses a plain
`commit -m <msg>` when `git diff --cached --quiet` reports nothing staged, with
the fix in the message. It is deliberately narrow: only commit -m with harmless
flags, never during a merge/cherry-pick/revert/rebase, and any doubt (no
repository, git failing) lets the normal flow run. Tools without the hook are
unaffected.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZ4EYrCPbq3hhNsUVRT46K
Signed-off-by: Claude <noreply@anthropic.com>
…y gives it

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZ4EYrCPbq3hhNsUVRT46K
Signed-off-by: Claude <noreply@anthropic.com>
Found by an independent review: matching "trinaxai start" in the message would
drop the hint for any error that merely mentions the command and break if the
wording changed. The unreachable-service error is now recognised by its
category, the Spanish message is registered for translation, and the missing
cases (Spanish, HTTP error, timeout, message that mentions the command) are
tested.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZ4EYrCPbq3hhNsUVRT46K
Signed-off-by: Claude <noreply@anthropic.com>
…ons stay in chat

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZ4EYrCPbq3hhNsUVRT46K
Signed-off-by: Claude <noreply@anthropic.com>
…S message, test guards)

- network/network off read .env like the service manager
- short RAG answers are checked whole for a refusal
- agent git runs with English messages so hints match
- legacy pinned qwen3.5:2b config means automatic
- untrusted local certificate is no longer reported as a stopped service
- tests: guard os.kill/os.killpg directly

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZ4EYrCPbq3hhNsUVRT46K
Signed-off-by: Claude <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZ4EYrCPbq3hhNsUVRT46K
Signed-off-by: Claude <noreply@anthropic.com>
…ps listing unreachable LAN URLs

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZ4EYrCPbq3hhNsUVRT46K
Signed-off-by: Claude <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZ4EYrCPbq3hhNsUVRT46K
Signed-off-by: Claude <noreply@anthropic.com>
…treaming

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZ4EYrCPbq3hhNsUVRT46K
Signed-off-by: Claude <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZ4EYrCPbq3hhNsUVRT46K
Signed-off-by: Claude <noreply@anthropic.com>
…ter plain-HTTP probe, locale)

- only a question-form prompt keeps git/read requests in chat; 'read x.yaml and tell me what is in it' goes to the agent
- bare domains count as URLs only with well-known endings, so my.app/src/main.py stays a path
- the plain-HTTP fallback requires TrinaxAI's own /health answer, covers ::1, and probes once per client
- git keeps the user's character set (LC_ALL moves to LC_CTYPE) while forcing English messages
- router comment no longer claims lockstep with the web app

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZ4EYrCPbq3hhNsUVRT46K
Signed-off-by: Claude <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZ4EYrCPbq3hhNsUVRT46K
Signed-off-by: Claude <noreply@anthropic.com>
… or NO_COLOR is set

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZ4EYrCPbq3hhNsUVRT46K
Signed-off-by: Claude <noreply@anthropic.com>
…ndbox on Debian/Ubuntu

Found by asking the agent to run a project's tests: every attempt ended in
'python3: not found'. /usr/bin/python3 (and cc, awk, ...) are links through
/etc/alternatives, which the sandbox did not mount, so they dangled. Mount that
one read-only folder of links into /usr; the rest of /etc stays hidden.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZ4EYrCPbq3hhNsUVRT46K
Signed-off-by: Claude <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZ4EYrCPbq3hhNsUVRT46K
Signed-off-by: Claude <noreply@anthropic.com>
claude added 13 commits October 24, 2026 12:50
…_TIMEOUT raises it

trinaxai research on a 4-core CPU runs past its 180 s wait and was reported as
'The network request timed out. Check the connection', though web search answered
in 2 s and the local model was simply still working. The message now says
TrinaxAI did not finish within the wait limit and suggests --depth 1 or a higher
TRINAXAI_CLI_TIMEOUT.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZ4EYrCPbq3hhNsUVRT46K
Signed-off-by: Claude <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZ4EYrCPbq3hhNsUVRT46K
Signed-off-by: Claude <noreply@anthropic.com>
…/--no-thinking is given

The CLI's default 'thinking on' was sent with every research request. On a CPU
the model then spent its budget reasoning and the web synthesis never finished
(2m28 and only a list of sources, against 48 s and a cited answer when the
server chooses).

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZ4EYrCPbq3hhNsUVRT46K
Signed-off-by: Claude <noreply@anthropic.com>
…acks real edits

A small model asked to create files and run their tests stopped after the first
file with 'Archivo creado'. If the request asks to run something and no command
has run, the agent is now asked once to run it. The 'mutated' flag, which gates
the phantom-edit nudge, was never set, so the nudge could fire after a real edit;
it now turns true when write_file/edit_file succeeds.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZ4EYrCPbq3hhNsUVRT46K
Signed-off-by: Claude <noreply@anthropic.com>
…several files or a run

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZ4EYrCPbq3hhNsUVRT46K
Signed-off-by: Claude <noreply@anthropic.com>
In a real rename across three files the agent left one call unrenamed, saw the
tests fail, and still reported the project as functional. When the last
run_command failed and the user asked for a change or a run, the model is now
asked (at most twice) to read the error, fix the cause and run it again.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZ4EYrCPbq3hhNsUVRT46K
Signed-off-by: Claude <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZ4EYrCPbq3hhNsUVRT46K
Signed-off-by: Claude <noreply@anthropic.com>
…l back to finish it

In a real rename across three files the model left one call to the old name that no
test covers and reported the project as updated. After a 'rename X to Y' request the
engine now looks for X as a whole word and, if it is still used, asks (at most twice)
for those places to be updated.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZ4EYrCPbq3hhNsUVRT46K
Signed-off-by: Claude <noreply@anthropic.com>
…; rename search skips symlinks

Found by reviewing this branch's own changes: the automatic http fallback could hand the
admin/device token in clear text to a program squatting on the port, and the leftover-name
search would read through a symlink that leads outside the workspace.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZ4EYrCPbq3hhNsUVRT46K
Signed-off-by: Claude <noreply@anthropic.com>
…, CLI timeout scope, docs)

- update.sh, uninstall.sh and setup_trinaxai.sh assigned a literal '=' to NC/BOLD in their no-color block; a test now guards it
- failed-run nudge only while no file was edited since; a different passing command no longer hides a failed run
- rename: a noun without an old name is not an identifier; the search counts files it actually read
- 'test file'/'sample file' requests stay one-file requests
- TRINAXAI_CLI_TIMEOUT now applies to every API request (30 s minimum), as documented
- docs: research reasoning contract, token-less plain-HTTP fallback

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZ4EYrCPbq3hhNsUVRT46K
Signed-off-by: Claude <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZ4EYrCPbq3hhNsUVRT46K
Signed-off-by: Claude <noreply@anthropic.com>
Found by running 'trinaxai agent -p' without --yolo: the refusal notice was hidden because
stdout was a pipe, so the model blamed 'a system restriction'. The notice now goes to stderr.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZ4EYrCPbq3hhNsUVRT46K
Signed-off-by: Claude <noreply@anthropic.com>
…g an exception chain

No behavior change: three copies of 'append the reply, then one corrective instruction' in the
engine and two copies of the cause-chain loop in the client are now one helper each.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SZ4EYrCPbq3hhNsUVRT46K
Signed-off-by: Claude <noreply@anthropic.com>
@TrinaxCode
TrinaxCode marked this pull request as ready for review October 26, 2026 01:24
@TrinaxCode
TrinaxCode merged commit 6c41665 into main Oct 26, 2026
24 checks passed
@TrinaxCode
TrinaxCode deleted the ccr-fe2460a0-c0akjx branch October 26, 2026 01:26
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.

2 participants