Feat/agon everywhere#236
Merged
Merged
Conversation
…annel
Browser-agent brain (agentic-brain-client). Two threads on the ReAct loop:
FLAIL/DISPATCH FIXES
- normalizeToolSchema: coerce the lent SHORTHAND inputSchema ({url:'string'}) into a real
JSON Schema. Wire-proven root cause of kimi 'produced no answer (exit 1)' — kimi's endpoint
400s an invalid tools.function.parameters; minimax tolerated it but flailed. Detect a real
schema by type==='object' only (no type/properties-named-field false-positive); keep object-
valued per-property schemas; reject arrays; skip __proto__/constructor/prototype.
- unwrapToolInputEnvelope: strip the redundant {input:{…}} the marker engines double-wrap
(navigate({input:{url}}) → navigate({url})), schema-aware so a tool that really takes 'input'
is never stripped. This is what fixes the live navigate/click 'invalid url' / 'needs a string
selector' loop on minimax/kimi.
- stuck-guards: consecutive-failure cap (MAX_CONSECUTIVE_TOOL_FAILURES) + unknown-tool calls now
count toward it; bounded read fingerprints + a size cap on the re-view map; MAX_AGENT_STEPS 30→60.
MID-TURN ASK-USER CHANNEL (implements the BrainClient contract's question-request/provideAnswer)
- A deferral now PAUSES the turn: yield question-request, register-before-yield, waitForUserAnswer,
inject the answer, CONTINUE. questionArbitration flips to 'host-only'; provideAnswer resolves by
requestId with FAIL-SAFE clientId arbitration (the empty-owner short-circuit dropped here AND in
provideApproval/provideCapabilityResult). Bounded (MAX_USER_QUESTIONS=6); on timeout it falls back
to the autonomous nudge (no dead-end). Narration still nudges.
96→ tests across the loop, schema, unwrap, ask-user, and host-only arbitration.
⚔️ Forged by [Agon](https://github.com/KERNlang/agon)
Co-Authored-By: agon (KERN) <292465531+KERN-Agon@users.noreply.github.com>
AgonServe gains POST /answer {requestId, answer} → BrainClient.provideAnswer (host-only
arbitration enforced in the brain), and flushes the question-request event over SSE like an
approval so the panel sees it immediately. +2 wire tests (/answer ack + missing-requestId 400).
⚔️ Forged by [Agon](https://github.com/KERNlang/agon)
Co-Authored-By: agon (KERN) <292465531+KERN-Agon@users.noreply.github.com>
…all) The terminal driver (agon drive) and the REPL /chrome handler both SUBMIT turns to the agentic brain but have no mid-turn free-text answer UI. So when the engine defers and the brain asks, they immediately reply over /answer with the autonomous-proceed guidance (the same push the old nudge gave) instead of leaving the turn paused for QUESTION_TIMEOUT_MS. The browser panel still answers interactively; these headless clients proceed on their own — preserving pre-feature behavior. ⚔️ Forged by [Agon](https://github.com/KERNlang/agon) Co-Authored-By: agon (KERN) <292465531+KERN-Agon@users.noreply.github.com>
…imax/zai) The coding-plan engines were sent BOTH the native tools[] array AND the strict __AGON_TOOL__ text-marker system prompt, so they obeyed the louder text instruction — typed a marker as prose and narrated-and-stopped. Native function-calling was wired but dormant; the browser agent only drove reliably on the CLI engines (claude/codex), defeating Agon's multi-AI premise. buildAgentSystemPrompt is now transport-aware: an engine that actually dispatches via the adapter's API path is told to CALL its native function-calling tools instead of typing the marker. runTurn derives that with the adapter's EXACT predicate — no usable binary (engine.binary ? registry.findBinary(engine) : null is null) AND an api block with its key present — so a declared-but-uninstalled binary that falls back to API also gets the native prompt (codex 0.92), and the empty-api-object case resolves correctly (kimi 0.85). The mid-turn nudge/deferral reminders are phrased per transport too. Marker-parse fallback + tool_choice:auto stay, so zero regression for claude/codex/agy and a native engine that still emits a marker is still caught. Also hardens normalizeToolSchema with a bounded recursive sanitizeSchemaNode that strips __proto__/constructor/prototype at every depth from object-valued per-property schemas (kimi 0.85). +5 tests (transport-aware prompt + missing-binary API fallback + native nudge phrasing + deep proto-strip); 93 brain tests green, full tsc -b build, 3547 unit tests pass (2 pre-existing env failures: *.bin gitignore + claude-auth-down live probe). ⚔️ Forged by [Agon](https://github.com/KERNlang/agon) Co-Authored-By: agon (KERN) <292465531+KERN-Agon@users.noreply.github.com>
Anthropic no longer meters `claude -p` under the subscription, so the billing reason the PTY subscription brain was the default is gone — and -p is far more reliable than scraping the interactive TUI (the scrape was 40-60% flaky for short tool-answers). Flip the default for the brain/dispatch path (chat, forge, orchestration, interactive Cesar) from PTY → --print.
All three gates (adapter shouldUseClaudePty, persistent-session factory, cesar/session DeliverAnswer wiring) now read ONE core helper, claudeBrainUsesPty(cwd?), so the policy lives in a single place. Precedence: AGON_CLAUDE_PTY env (1/true→pty, 0/false→print) overrides the persisted `claudeBackend` setting ('pty'|'print', default 'print'); pass cwd to honor a project-local .agon.json override. Switch back to the PTY brain with `agon config claudeBackend pty` or AGON_CLAUDE_PTY=1, or flip the one default in claudeBrainUsesPty.
SCOPE GUARD: the /model live model probe (cli-models-registry __pty:/model) is untouched — it always uses the TUI to read the live model list, independent of this switch. The browser extension needs no change; it inherits -p through the served brain's adapter.dispatch.
Review-hardened (two 6-engine passes): codegen duplicate-JSDoc removed (raw handler); shouldUseClaudePty now identifies claude by id OR binary (agrees with the other gates, kimi 0.85); claudeBrainUsesPty(cwd) honors project-local config (codex 0.90); only claude consults the switch so a non-claude stream-json companion is never coupled to claude's setting (minimax 0.85). +new claudeBackend setting + tests (env/config/precedence + shouldUseClaudePty id-or-binary). 3550 unit tests pass (2 pre-existing env failures only).
⚔️ Forged by [Agon](https://github.com/KERNlang/agon)
Co-Authored-By: agon (KERN) <292465531+KERN-Agon@users.noreply.github.com>
…ailure A 401 under workspace-pure isolation (claude's clean config dir is stale or never logged in, or an API engine's key is missing) used to surface as a bare "produced no answer" / raw `API Error: 401`, with no clue that `agon login <engine>` is the fix — a silent, undiscoverable hang. This adds one generic, metadata-driven checker and wires it into every dispatch surface so the exact recovery command is always shown. - `authLoginHint(engine)` + `authFailureHint(engine, signal)` in engine-health (next to classifyDispatchFailure). Derived from the engine's OWN metadata, no per-engine special-casing: a CLI engine with an isolated config dir + loginArgs (claude/codex) → `agon login <id> --force` (--force because a 401 after a present authMarker means the marker is STALE, which plain login would skip); an API-only engine → set its apiKeyEnv / `agon provider`; else → `agon doctor`. Null-safe (optional-chained) so an undefined engine degrades, never throws. - Wired into all three surfaces: the browser/serve panel notice (agentic-brain-client), the panel seat detail for review/forge/brainstorm/ tribunal (seat-dispatch), and the REPL Cesar quarantine warning (cesar/brain, reusing the already-resolved engine to avoid a throwing registry.get). - seat-dispatch no longer burns a doomed retry on an auth failure — a 401 can't recover by retrying, so the credential fix surfaces on the first attempt. Tests: auth-failure-hint (8) covers CLI/API/fallback/precedence + non-auth → null; seat-dispatch gains a no-retry-on-401 case. Full unit suite green (only the pre-existing *.bin gitignore env test fails, untouched here). ⚔️ Forged by [Agon](https://github.com/KERNlang/agon) Co-Authored-By: agon (KERN) <292465531+KERN-Agon@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.