Skip to content

feat(miner): add read-only chat grounding over the existing miner MCP tools - #6570

Merged
loopover-orb[bot] merged 1 commit into
JSONbored:mainfrom
davion-knight:sn-6517-chat-grounding
Jul 16, 2026
Merged

feat(miner): add read-only chat grounding over the existing miner MCP tools#6570
loopover-orb[bot] merged 1 commit into
JSONbored:mainfrom
davion-knight:sn-6517-chat-grounding

Conversation

@davion-knight

Copy link
Copy Markdown
Contributor

Summary

  • Adds POST /api/chat, a streaming, read-only conversational endpoint for the miner-ui chat rail. It answers natural-language questions about the miner's own local state, grounded exclusively in the 11 existing read-only loopover_miner_* MCP tools. Backend only — no chat UI, no action-dispatch, no new tool, no conversation store.
  • packages/loopover-engine/src/miner/chat-grounding.ts (new): resolves the provider through driver-factory.ts (never reading MINER_CODING_AGENT_* directly), drives @anthropic-ai/claude-agent-sdk's query() against the miner's own stdio MCP server so the 11 tools' implementations are called rather than reimplemented, and exposes an injectable ChatQueryFn seam so every test drives a fake async-iterable and CI never makes a real model call.
  • Fails closed on provider. claude-cli/codex-cli are single-turn, buffered coding drivers, not a conversational streaming tool-calling loop; when the resolved provider is either of those (or nothing is configured) the stream emits exactly one error event (chat_requires_agent_sdk_provider / no_coding_agent_configured) then done — never a partial, mock, or echoed answer.
  • Privacy is enforced twice. A conversational surface adds a leak vector the tools themselves don't have: a user can simply ask "what's my trust score" and an ungrounded model could hallucinate one. The system prompt instructs the model to decline those terms, and — because a prompt is not enforcement — every outgoing text chunk is checked against track-record-summary.ts's PUBLIC_FIELD_BLOCKLIST and redacted on a hit. That constant is now exported and reused rather than copied, so the instruction and the enforcement cannot drift apart.
  • apps/loopover-miner-ui/vite-chat-api.ts (new) is transport only: route match, body validation, and re-emitting the engine's events as text/event-stream data: <json>\n\n frames. Registered after authPlugin() in vite.config.ts, so the existing session-cookie gate (Add auth to the local miner-ui API #4858) covers it with no new auth mechanism.

Closes #6517

Scope

  • The PR title follows type(scope): short summary Conventional Commit format, for example fix(api): restore profile access checks.
  • This PR is focused and does not mix unrelated backend, UI, MCP, docs, dependency, and deploy changes.
  • This follows CONTRIBUTING.md and does not reintroduce GitHub Pages, VitePress, site/, or CNAME.
  • I linked a currently open issue this PR resolves (e.g. Closes #123) — a linked open issue is required for every contributor PR.

Validation

  • git diff --check
  • npm run typecheck — 0 errors
  • npm run test:coverage locally; codecov/patch requires ≥99% coverage of the lines AND branches you changedchat-grounding.ts is at 100%: 77/77 statements, 35/35 branches, no partials
  • npm run build --workspace @loopover/engine
  • npm run test --workspace @loopover/engine — 578/578 pass (includes the new test/chat-grounding.test.ts)
  • npm run ui:lint — 0 errors
  • npm run ui:typecheck — 0 errors
  • npm run miner:env-reference:check / npm run selfhost:env-reference:check / npm run docs:drift-check
  • New or changed behavior has unit/integration tests for new branches, fallback paths, and sanitizer boundaries

If any required check was skipped, explain why:

  • npm audit --audit-level=moderate could not complete locally — the registry audit endpoint was unreachable from this environment (npm error audit endpoint returned an error), not a reported advisory. No dependencies are added or changed by this PR.

Safety

  • No secrets, wallet details, hotkeys, coldkeys, user PATs, private keys, raw trust scores, private rankings, or private maintainer evidence are exposed. This PR's whole point is the opposite: it adds a blocklist-backed redaction backstop so a conversational surface cannot emit them even when asked directly.
  • Public GitHub text stays sanitized, low-noise, and does not imply compensation guarantees or optimization tactics.
  • Auth, cookie, CORS, GitHub App, Cloudflare, or session changes include negative-path tests — src/chat-api.test.ts asserts an unauthenticated /api/chat is rejected with the 401 body before the handler runs, and that an authenticated one falls through to it.
  • API/OpenAPI/MCP behavior is updated and tested where needed — no MCP tool is added or edited; the endpoint only calls the existing 11.
  • Public docs/changelogs are updated where needed; changelogs are only edited for release-prep PRs.

Notes for review

Tool allowlist is asserted, not just reviewed. An invariant test pins the session's allowlist to exactly the 11 read-only names — a future accidental 12th tool (or a write-capable one) fails the suite.

Test seam coverage. resolveChatQuery() is split out of runChatGrounding() deliberately: the generator invokes its query immediately, so an inline options.query ?? defaultQuery would only be branch-coverable by opening a live session. Resolving it in a separate exported function lets the default arm be exercised by binding it, never by calling it — the same "resolve, don't invoke" shape agent-sdk-driver.ts's factory uses to reach 100% branch coverage.

Dual test suites per the engine convention: packages/loopover-engine/test/chat-grounding.test.ts (node:test, against dist/) and test/unit/chat-grounding-engine.test.ts (the vitest mirror against src/, which is what codecov/patch actually measures for packages/loopover-engine/src/**).

… tools

Adds POST /api/chat, a streaming read-only conversational endpoint for the
miner-ui chat rail. Answers are grounded exclusively in the 11 existing
read-only loopover_miner_* MCP tools -- their implementations are called
directly via the miner's own stdio MCP server, never reimplemented here.
Backend only: no chat UI, no action-dispatch, no new tool, and no
conversation store (the caller supplies full history per request).

chat-grounding.ts resolves the provider through driver-factory.ts rather
than reading MINER_CODING_AGENT_* directly, and drives the agent-sdk
query() loop behind an injectable ChatQueryFn seam so every test runs a
fake async-iterable and CI never makes a real model call.

Fails closed on provider: claude-cli/codex-cli are single-turn, buffered
coding drivers rather than a conversational streaming tool-calling loop, so
either of those (or nothing configured) emits exactly one error event --
chat_requires_agent_sdk_provider / no_coding_agent_configured -- followed by
done, never a partial, mock, or echoed answer.

Privacy is enforced twice. A conversational surface adds a leak vector the
tools themselves lack: a user can simply ask for a trust score and an
ungrounded model could hallucinate one. The system prompt instructs the
model to decline those terms, and because a prompt is not enforcement every
outgoing text chunk is checked against track-record-summary.ts's
PUBLIC_FIELD_BLOCKLIST and redacted on a hit. That constant is now exported
and reused rather than copied, so instruction and enforcement cannot drift.

vite-chat-api.ts is transport only -- route match, body validation, and
re-emitting the engine's events as text/event-stream frames. It is
registered after authPlugin(), so the existing session-cookie gate covers
it with no new auth mechanism.

An invariant test pins the session allowlist to exactly the 11 read-only
tool names, so an accidental 12th (or a write-capable one) fails the suite.

Closes JSONbored#6517
@davion-knight
davion-knight requested a review from JSONbored as a code owner July 16, 2026 14:14
@superagent-security

Copy link
Copy Markdown
Contributor

Superagent didn't find any vulnerabilities or security issues in this PR.

@codecov

codecov Bot commented Jul 16, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.61%. Comparing base (93f3467) to head (891fa06).

Additional details and impacted files
@@           Coverage Diff           @@
##             main    #6570   +/-   ##
=======================================
  Coverage   93.60%   93.61%           
=======================================
  Files         675      676    +1     
  Lines       67764    67835   +71     
  Branches    18627    18654   +27     
=======================================
+ Hits        63431    63502   +71     
  Misses       3360     3360           
  Partials      973      973           
Flag Coverage Δ
shard-1 43.88% <9.72%> (-0.16%) ⬇️
shard-2 36.95% <9.72%> (+0.16%) ⬆️
shard-3 32.47% <9.72%> (+0.04%) ⬆️
shard-4 34.73% <9.72%> (-0.17%) ⬇️
shard-5 31.08% <9.72%> (-0.04%) ⬇️
shard-6 45.71% <100.00%> (+0.09%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...ckages/loopover-engine/src/miner/chat-grounding.ts 100.00% <100.00%> (ø)
...ckages/loopover-engine/src/track-record-summary.ts 6.16% <100.00%> (ø)

@loopover-orb loopover-orb Bot added the gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier. label Jul 16, 2026
@loopover-orb

loopover-orb Bot commented Jul 16, 2026

Copy link
Copy Markdown
Contributor

Warning

⏸️ LoopOver review result - manual review recommended

Review updated: 2026-07-16 14:21:47 UTC

8 files · no blockers · CI green · clean

⏸️ Suggested Action - Manual Review

  • AI review already in progress for this PR head: Another LoopOver pass is already running the AI review for this exact PR head. This pass is skipping to avoid a duplicate LLM call.

Review summary
AI review is already running for this PR head in another LoopOver pass. LoopOver is holding this PR for manual review until that pass completes.

Nits — 2 non-blocking
  • AI review already in progress for this PR head — The gate is held for a human reviewer rather than passed automatically; it re-evaluates once the in-flight review completes or on the next update.
  • Possible secret-shaped assignment in the diff (generic_secret_assignment) — Verify the value is not a real credential.

Decision drivers

  • ✅ Code review — No blockers (No AI review summary)
  • ⚠️ Gate result — Not blocking (Advisory; not blocking this PR.)
Context & advisory signals — never blocks the verdict
Signal Result Evidence
Linked issue ✅ Linked #6517
Related work ⚠️ 1 scoped overlap Top overlaps are listed below; lower-confidence bulk is hidden.
Change scope ❌ 8/20 High review scope from cached public metadata (1 linked issue).
Validation posture ✅ 25/25 PR body includes validation/test evidence.
Contributor workload ✅ 10/10 Author activity: 162 registered-repo PR(s), 104 merged, 0 issue(s).
Contributor context ✅ Confirmed Gittensor contributor davion-knight; Gittensor profile; 162 PR(s), 0 issue(s).
Improvement ✅ Minor risk: clean · value: minor
Review context
  • Author: davion-knight
  • Role context: outside_contributor
  • Public audience mode: oss maintainer
  • Lane context: Repository is configured for direct PR review.
  • Public profile languages: not available
  • Official Gittensor activity: 162 PR(s), 0 issue(s).
  • Related work: Titles/paths share 7 meaningful terms. (issue #6489, issue #6517)
Contributor next steps
  • Start here: Review top overlaps.
  • Then work through the remaining 2 steps in the Signals table above.
Signal definitions
  • Related work = same linked issue, overlapping active PRs, or title/path similarity.
  • Change scope = cached public metadata such as size labels, draft state, and review-burden hints.
  • Validation posture = whether the PR provides enough public validation/test evidence for maintainer review.
  • Contributor workload = public contributor activity and cleanup pressure, not a repo-wide quality failure.
  • Contributor context = public GitHub/Gittensor identity context; non-Gittensor status is not a blocker.
🧪 Chat with LoopOver

Ask LoopOver a question about this PR directly in a comment — grounded only in the same cached, public-safe facts shown above, never a new claim.

  • @loopover ask &lt;question&gt; answers contribution-quality Q&A with source citations and freshness.
  • @loopover chat &lt;question&gt; answers in natural prose from cached decision-pack facts via local inference (maintainer/collaborator; read-only).
  • A plain-language @loopover mention with a real question is routed to the closest matching read-only command automatically — no exact syntax required.

Full command reference: https://loopover.ai/docs/loopover-commands

🧪 Experimental — new and may change.

Visual preview
Route Viewport Before (production) After (this PR's preview) Diff
/ desktop before /
before /
after /
after /
diff /
diff /
/ mobile before / (mobile)
before / (mobile)
after / (mobile)
after / (mobile)

Click any thumbnail to open the full-size screenshot. Before = production · After = this PR's preview deploy · Diff highlights exactly what changed.

🟩 Safe / merged · 🟦 Advisory · 🟨 Held for review · 🟥 Blocked / closed


💰 Earn for open-source contributions like this. Gittensor lets GitHub contributors earn for the work they already do — register to start earning →.

Checked by LoopOver, a quiet PR intelligence layer for OSS maintainers.

  • Re-run LoopOver review

@loopover-orb loopover-orb Bot 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.

LoopOver approves — the gate is satisfied and CI is green.

@loopover-orb
loopover-orb Bot merged commit ed16fef into JSONbored:main Jul 16, 2026
16 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

gittensor:feature Gittensor-scored feature linked to a feature issue — scores a 0.25x multiplier.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Chat backend: read-only conversational grounding over the 11 existing loopover_miner_* tools

1 participant