Skip to content

Revert "Stabilize mesh MoA context and tool loops (#820)" - #823

Merged
michaelneale merged 1 commit into
mainfrom
revert-820-moa-hang
Jun 11, 2026
Merged

Revert "Stabilize mesh MoA context and tool loops (#820)"#823
michaelneale merged 1 commit into
mainfrom
revert-820-moa-hang

Conversation

@michaelneale

@michaelneale michaelneale commented Jun 11, 2026

Copy link
Copy Markdown
Collaborator

Reverts #820.

Why

#820 regressed the mesh / MoA route on the public console: requests with model: "mesh" hang and never return.

Verified by rolling back the Fly console image:

A concrete single-model request returns fast either way, so routing works — it is specifically the MoA/virtual-LLM fan-out path introduced/changed by #820 that stalls.

The regression only surfaced against the live relay-heavy public mesh, not in the CI sim tests, which is why it passed checks.

Impact

  • Production console is already rolled back to v85, so users are unaffected right now.
  • This revert gets main back to a deployable state so the next console deploy does not re-break MoA.

Follow-up

#820's MoA context/budget work should be reworked and re-merged with a multi-node confidence test (mesh route against a real mesh) before redeploying.

Summary by CodeRabbit

Release Notes

  • Model Updates

    • Removed Gemma-4-E4B-it-Q4_K_M model from available options; Qwen3-8B-Q4_K_M is now the default for 8GB VRAM tier
  • Bug Fixes

    • Fixed tooltip display to work consistently across all device types
    • Improved tool call parsing and error handling
    • Enhanced context-length calculations for model selection
  • Improvements

    • Refined chat message and tool result processing
    • Optimized mixture-of-agents response generation

Copilot AI review requested due to automatic review settings June 11, 2026 02:39
@coderabbitai

coderabbitai Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 6e0f9c39-dabd-45f1-8daa-e800143dc7a6

📥 Commits

Reviewing files that changed from the base of the PR and between 337f5b8 and e9c937f.

📒 Files selected for processing (32)
  • crates/mesh-client/src/models/catalog.json
  • crates/mesh-client/src/network/nostr.rs
  • crates/mesh-llm-guardrails/src/rescue.rs
  • crates/mesh-llm-host-runtime/src/mesh/mod.rs
  • crates/mesh-llm-host-runtime/src/mesh/tests.rs
  • crates/mesh-llm-host-runtime/src/network/nostr.rs
  • crates/mesh-llm-host-runtime/src/network/openai/moa_gateway/context_budget.rs
  • crates/mesh-llm-host-runtime/src/network/openai/moa_gateway/context_selection.rs
  • crates/mesh-llm-host-runtime/src/network/openai/moa_gateway/mod.rs
  • crates/mesh-llm-host-runtime/src/network/openai/moa_gateway/progress.rs
  • crates/mesh-llm-host-runtime/src/network/openai/transport.rs
  • crates/mesh-llm-node/src/catalog.json
  • crates/mesh-llm-ui/src/components/ui/tooltip.tsx
  • crates/mesh-llm-ui/src/features/chat/api/use-chat.test.tsx
  • crates/mesh-llm-ui/src/features/chat/api/use-chat.ts
  • crates/mesh-llm-ui/src/features/chat/components/composer/ChatComposer.tsx
  • crates/mesh-llm-ui/src/features/chat/pages/ChatPage.test.tsx
  • crates/mesh-mixture-of-agents/src/arbiter.rs
  • crates/mesh-mixture-of-agents/src/backend.rs
  • crates/mesh-mixture-of-agents/src/context.rs
  • crates/mesh-mixture-of-agents/src/fanout.rs
  • crates/mesh-mixture-of-agents/src/lib.rs
  • crates/mesh-mixture-of-agents/src/normalize.rs
  • crates/mesh-mixture-of-agents/src/reducer.rs
  • crates/mesh-mixture-of-agents/src/session.rs
  • crates/mesh-mixture-of-agents/src/worker.rs
  • crates/mesh-mixture-of-agents/tests/sim_all_workers_fail.rs
  • crates/mesh-mixture-of-agents/tests/sim_enable_thinking_propagation.rs
  • crates/mesh-mixture-of-agents/tests/sim_tool_call_text_not_passed_as_content.rs
  • crates/mesh-mixture-of-agents/tests/sim_tool_result_routes_to_reducer.rs
  • crates/mesh-mixture-of-agents/tests/sim_worker_accounting.rs
  • crates/openai-frontend/src/responses.rs

📝 Walkthrough

Walkthrough

This pull request significantly simplifies the mixture-of-agents system by removing the Gemma-4-E4B-it-Q4_K_M model, eliminating parameter-count-based model comparison, removing context-budget reservations, and streamlining tool-call rescue, context packing, answer arbitration, and response handling throughout the codebase.

Changes

MoA Simplification and Model Management Cleanup

Layer / File(s) Summary
Model catalog cleanup and VRAM-tier updates
crates/mesh-client/src/models/catalog.json, crates/mesh-llm-node/src/catalog.json, crates/mesh-client/src/network/nostr.rs, crates/mesh-llm-host-runtime/src/network/nostr.rs
Gemma-4-E4B-it-Q4_K_M is removed from all catalogs and VRAM-tier selection is updated to use Qwen3-8B-Q4_K_M for the 8–24GB range across all implementations.
Tool-call rescue syntax reduction
crates/mesh-llm-guardrails/src/rescue.rs
Multiple tool-call syntax extractors (call-colon, OpenClaw, Minimax, XML-tag, named-object) are removed, leaving only bracket-arg, Qwen XML, and Granite syntaxes; tests for removed syntaxes and bounded-prefix scanning are deleted.
Remove parameter-count-based model comparison
crates/mesh-mixture-of-agents/src/worker.rs, crates/mesh-mixture-of-agents/src/reducer.rs, crates/mesh-mixture-of-agents/src/backend.rs, crates/mesh-mixture-of-agents/tests/sim_*
compare_model_strength helper and parameter_count_b field are removed; model ordering now relies solely on is_single_digit_b_name bucketing; ModelEntry constructor calls are updated across all test files.
Remove context-budget reservation and simplify context selection
crates/mesh-llm-host-runtime/src/network/openai/moa_gateway/mod.rs, crates/mesh-llm-host-runtime/src/network/openai/moa_gateway/context_selection.rs, crates/mesh-llm-host-runtime/src/network/openai/transport.rs
The entire context_budget.rs module is deleted; context_can_satisfy treats unknown context as always satisfiable; virtual_mesh_context_length is refactored to use runtime descriptors directly; visibility-based descriptor helpers are removed.
Simplify context packing with fixed message windows
crates/mesh-mixture-of-agents/src/context.rs
Byte-window-based context packing is replaced with fixed recent-message counts (Fast: system+last-user, Specialist: 4 messages, Strong: 10 messages); reducer context assembly becomes a simple system+user pair; tool-result compaction uses generalized JSON extraction instead of web_fetch/web_search-specific handlers; many packing-related tests are removed or rewritten.
Replace last_user_message with last_user_text accessor
crates/mesh-mixture-of-agents/src/session.rs
Session API changes from last_user_message() returning Option<&Value> to last_user_text() returning String; tool-result pairing uses first-match instead of latest-unresolved lookup; tests for repeated tool-call IDs are removed.
Remove answer-priority-pending logic and answer tie-breaking
crates/mesh-mixture-of-agents/src/arbiter.rs, crates/mesh-mixture-of-agents/src/fanout.rs
The answer_priority_pending parameter is removed from try_early_decision signature; role-based answer tie-breaking helpers are deleted; grace-window eligibility is computed inline; answer selection uses direct confidence-based max_by; all call sites and tests are updated to the new signature.
MoA gateway response and tool-intent logic simplification
crates/mesh-mixture-of-agents/src/lib.rs
has_tools is now derived from query_uses_tools; tool-intent detection is centralized into looks_like_tool_intent heuristic; tool-result recovery fanout is removed (immediate error on reducer failure); session-dependent final-answer repair is removed; fallback_worker_response no longer takes a Session parameter; tool_proposal_response suppresses tool calls instead of erroring when tools are disabled; many tool-grace and repair tests are deleted.
MoA gateway worker resolution and Responses-API emission
crates/mesh-llm-host-runtime/src/network/openai/moa_gateway/mod.rs
Descriptors plumbing is removed from worker resolution; parallel_tool_calls: false is no longer inserted into request bodies; Responses-API SSE event emission switches to manual data-frame writing for created/delta/final events instead of using shared helpers; explanatory comments are updated.
Refactor MoA progress reporting from keepalive to continuous reasoning deltas
crates/mesh-llm-host-runtime/src/network/openai/moa_gateway/progress.rs
Finite visible-progress phase and keepalive comments are replaced with always-emitted reasoning_content deltas; progress_line becomes an opening-then-cycling function; ProgressContinuation is no longer threaded into failure events; keepalive and sequence-number preservation tests are removed; progress text assertions updated for ellipsis character change.
Simplify PeerInfo context lookup and backend tool handling
crates/mesh-llm-host-runtime/src/mesh/mod.rs, crates/mesh-llm-host-runtime/src/mesh/tests.rs, crates/mesh-mixture-of-agents/src/backend.rs
Context-length fallback via descriptor lookup is removed from PeerInfo::advertised_context_length; test for public model alias context lookup is deleted; HttpBackend no longer forces parallel_tool_calls: false; native tool-call name falls back to "unknown" instead of validating; tool-call validation tests are removed.
Simplify OpenAI Responses-API input/tool normalization
crates/openai-frontend/src/responses.rs
output_text is removed from content-item type mapping; input normalization detects message-shaped arrays and uses message translation directly (conversation/function-call/tool-result helpers removed); tool-shape normalization helpers are deleted; corresponding unit tests are removed.
Frontend tooltip and chat-API test updates
crates/mesh-llm-ui/src/components/ui/tooltip.tsx, crates/mesh-llm-ui/src/features/chat/api/use-chat.ts, crates/mesh-llm-ui/src/features/chat/api/use-chat.test.tsx, crates/mesh-llm-ui/src/features/chat/components/composer/ChatComposer.tsx, crates/mesh-llm-ui/src/features/chat/pages/ChatPage.test.tsx
Touch-device detection is removed from Tooltip; useChat mock strategy is simplified to drain streams per message; SendMessageOnLayout hardcodes conversationId/initialMessages; chat-reset behavior test is deleted; message sync switches from useLayoutEffect to useEffect; send-button event handling becomes onMouseDown; priorBodies tracking is removed from chat mock.
Normalize and simulation test updates
crates/mesh-mixture-of-agents/src/normalize.rs, crates/mesh-mixture-of-agents/tests/sim_*
Multiple tool-rescue-syntax tests are removed from normalize.rs; a thinking-strip preservation test is added; ModelEntry field references in simulation tests are cleaned up by removing parameter_count_b initializations.

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

  • Mesh-LLM/mesh-llm#820: Modifies the same MoA context and tool-loop code paths and updates auto_model_pack VRAM-tier model selection in mesh-*/src/network/nostr.rs with the same Gemma-to-Qwen model substitution.

Suggested reviewers

  • i386
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch revert-820-moa-hang

Comment @coderabbitai help to get the list of available commands and usage tips.

@michaelneale
michaelneale merged commit 6315858 into main Jun 11, 2026
11 of 12 checks passed
@michaelneale
michaelneale deleted the revert-820-moa-hang branch June 11, 2026 02:41

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR reverts PR #820 to restore the previous Mixture-of-Agents (MoA) / virtual mesh behavior after #820 caused model: "mesh" requests on the public console to hang indefinitely.

Changes:

  • Reverts MoA context packing, role assignment heuristics, tool-loop handling, and reducer recovery behavior back toward the pre-#820 implementation.
  • Simplifies/removes several OpenAI Responses-API normalization and MoA streaming behaviors introduced in #820 (including tool-shape normalization and richer SSE lifecycle events).
  • Reverts UI and model-pack/catalog adjustments that shipped alongside #820 (e.g., tooltip touch-disable logic, default 8–24GB pack, catalog entries).

Reviewed changes

Copilot reviewed 32 out of 32 changed files in this pull request and generated 9 comments.

Show a summary per file
File Description
crates/openai-frontend/src/responses.rs Reverts parts of Responses request normalization (content/input handling, tool shape normalization, and related tests).
crates/mesh-mixture-of-agents/tests/sim_worker_accounting.rs Updates test fixtures to match reverted ModelEntry shape.
crates/mesh-mixture-of-agents/tests/sim_tool_result_routes_to_reducer.rs Removes reducer-timeout recovery test and updates model fixtures.
crates/mesh-mixture-of-agents/tests/sim_tool_call_text_not_passed_as_content.rs Updates model fixtures to match reverted ModelEntry shape.
crates/mesh-mixture-of-agents/tests/sim_enable_thinking_propagation.rs Updates model fixtures to match reverted ModelEntry shape.
crates/mesh-mixture-of-agents/tests/sim_all_workers_fail.rs Updates model fixtures to match reverted ModelEntry shape.
crates/mesh-mixture-of-agents/src/worker.rs Reverts role assignment ordering (removes parameter-count-based strength ordering).
crates/mesh-mixture-of-agents/src/session.rs Reverts session behaviors; tool-result pairing logic changed.
crates/mesh-mixture-of-agents/src/reducer.rs Reverts reducer-candidate ordering logic and removes parameter-based test coverage.
crates/mesh-mixture-of-agents/src/normalize.rs Removes several guardrail-rescue normalization tests added in #820.
crates/mesh-mixture-of-agents/src/lib.rs Reverts tool intent/grace logic and reducer failure handling behavior.
crates/mesh-mixture-of-agents/src/fanout.rs Reverts grace/early-exit logic (removes “wait for pending strong worker” behavior).
crates/mesh-mixture-of-agents/src/context.rs Reverts MoA context windowing/anchoring and simplifies reducer/worker packing.
crates/mesh-mixture-of-agents/src/backend.rs Reverts backend request shaping and tool-call extraction behavior.
crates/mesh-mixture-of-agents/src/arbiter.rs Reverts arbitration behavior (removes role-bias tie-breaking + strong-worker pending gate).
crates/mesh-llm-ui/src/features/chat/pages/ChatPage.test.tsx Removes follow-up “same-conversation history” assertion from UI tests.
crates/mesh-llm-ui/src/features/chat/components/composer/ChatComposer.tsx Reverts pointer/touch handling for the send button (mouse handler only).
crates/mesh-llm-ui/src/features/chat/api/use-chat.ts Reverts conversation-reset timing (useEffect instead of useLayoutEffect).
crates/mesh-llm-ui/src/features/chat/api/use-chat.test.tsx Removes message-reset coverage and simplifies stream-draining helper.
crates/mesh-llm-ui/src/components/ui/tooltip.tsx Reverts touch-tooltip disabling logic (always renders tooltip).
crates/mesh-llm-node/src/catalog.json Removes the Gemma-4-E4B entry added in #820.
crates/mesh-llm-host-runtime/src/network/openai/transport.rs Reverts model metadata/context selection behavior for public aliases + virtual mesh context derivation.
crates/mesh-llm-host-runtime/src/network/openai/moa_gateway/progress.rs Reverts progress streaming behavior and failure-tail handling.
crates/mesh-llm-host-runtime/src/network/openai/moa_gateway/mod.rs Reverts MoA config/context budgeting and simplifies Responses SSE emission.
crates/mesh-llm-host-runtime/src/network/openai/moa_gateway/context_selection.rs Reverts MoA context selection + virtual mesh context calculation logic.
crates/mesh-llm-host-runtime/src/network/openai/moa_gateway/context_budget.rs Deletes MoA context reserve logic introduced in #820.
crates/mesh-llm-host-runtime/src/network/nostr.rs Reverts default auto-pack model for 8–24GB tier back to Qwen3-8B.
crates/mesh-llm-host-runtime/src/mesh/tests.rs Removes public-alias context lookup test added in #820.
crates/mesh-llm-host-runtime/src/mesh/mod.rs Reverts peer context-length lookup for public model aliases.
crates/mesh-llm-guardrails/src/rescue.rs Reverts several tool-call rescue parsers and changes candidate scanning behavior.
crates/mesh-client/src/network/nostr.rs Reverts default auto-pack model for 8–24GB tier back to Qwen3-8B.
crates/mesh-client/src/models/catalog.json Removes the Gemma-4-E4B entry added in #820.
Comments suppressed due to low confidence (1)

crates/mesh-llm-guardrails/src/rescue.rs:99

  • tool_call_candidates no longer bounds the input before running the non-JSON rescue parsers. json_candidates() is bounded, but the other parsers will scan the entire model output, which is untrusted and can be very large. Re-applying bounded_prefix here restores the intended O(max) behavior and reduces worst-case CPU/memory use.
fn tool_call_candidates(content: &str) -> Vec<Value> {
    let mut candidates = Vec::new();
    for json_candidate in json_candidates(content) {
        if let Ok(value) = serde_json::from_str::<Value>(&json_candidate) {
            candidates.push(value);

Comment on lines +154 to 158
if let Some(pending) =
self.pending_tools.iter_mut().find(|p| p.call_id == call_id)
{
let pending = &mut self.pending_tools[idx];
pending.result = Some(content);
tracing::info!(
Comment on lines +1194 to +1197
let data = format!("data: {created}\n\n");
let framed = format!("{:x}\r\n{}\r\n", data.len(), data);
stream.write_all(framed.as_bytes()).await?;
stream.flush().await?;
Comment on lines +1215 to +1218
let data = format!("data: {}\n\n", delta_event);
let framed = format!("{:x}\r\n{}\r\n", data.len(), data);
stream.write_all(framed.as_bytes()).await?;
stream.flush().await?;
Comment on lines 368 to 371
let body = &moa_result.response_body;
if is_moa_failure_body(body) {
return write_failure_as_sse_tail(
&mut tcp_stream,
body,
adapter,
completion_id,
continuation,
)
.await;
return write_failure_as_sse_tail(&mut tcp_stream, body, adapter, completion_id).await;
}
Comment on lines 746 to 750
async fn capture_failure_tail(
adapter: proxy::ResponseAdapter,
body: serde_json::Value,
continuation: Option<ProgressContinuation>,
) -> String {
let listener = tokio::net::TcpListener::bind("127.0.0.1:0")
Comment on lines 276 to 280
let name = tc
.pointer("/function/name")
.and_then(|n| n.as_str())
.map(str::trim)
.filter(|name| !name.is_empty())
.ok_or_else(|| "malformed tool call: missing function.name".to_string())?;
.unwrap_or("unknown");
let args = tc
Comment on lines +1238 to +1242
let tail = [text_done, completed];
for event in &tail {
let data = format!("data: {}\n\n", event);
let framed = format!("{:x}\r\n{}\r\n", data.len(), data);
stream.write_all(framed.as_bytes()).await?;
Comment on lines 490 to 494
async fn write_failure_as_sse_tail(
stream: &mut TcpStream,
body: &serde_json::Value,
adapter: proxy::ResponseAdapter,
completion_id: &str,
Comment on lines 775 to 779
let body = serde_json::json!({
"error": { "message": "All workers failed", "code": "all_workers_failed" }
});
let raw = capture_failure_tail(proxy::ResponseAdapter::None, body, None).await;
let raw = capture_failure_tail(proxy::ResponseAdapter::None, body).await;
assert!(
michaelneale added a commit that referenced this pull request Jun 11, 2026
* origin/main:
  Salvage safe bits from reverted MoA PR (#820) (#824)
  Revert "Stabilize mesh MoA context and tool loops (#820)" (#823)
  Stabilize mesh MoA context and tool loops (#820)
  chore: flip docs pages to canonical URLs (#822)
  chore: Console public domain (#821)
  Add meshllm.cloud website, catalog viewer, and onboarding docs (#806)

# Conflicts:
#	docs/index.html
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