Skip to content

Feat/osworld2 cosplay mcp - #7791

Open
bfxh wants to merge 16 commits into
esengine:main-v2from
bfxh:feat/osworld2-cosplay-mcp
Open

Feat/osworld2 cosplay mcp#7791
bfxh wants to merge 16 commits into
esengine:main-v2from
bfxh:feat/osworld2-cosplay-mcp

Conversation

@bfxh

@bfxh bfxh commented Aug 6, 2026

Copy link
Copy Markdown

Summary

Issues

Verification

Documentation impact

Documentation-impact: TODO

For changes to user-visible CLI, Desktop, configuration, provider, permission,
or tool behavior, use one of:

  • Documentation-impact: updated - <what changed> and update docs/*.md.
  • Documentation-impact: none - <why the embedded documentation remains correct>.

Cache impact

Cache-impact: TODO
Cache-guard: TODO
System-prompt-review: N/A

For cache-sensitive changes, fill these lines before requesting review:

  • Cache-impact: none, low, medium, or high, plus the reason.
  • Cache-guard: the focused guard test/command added or run, or why an existing guard covers the change.
  • System-prompt-review: required reviewer/approval note when provider-visible system prompt, memory prefix, output style, or skill index behavior changes.

lbx13 and others added 16 commits August 6, 2026 22:24
Replace every per-tool mcp__<server>__<tool> top-level entry with a
single run_mcp dispatcher, shrinking the provider's tools array from
114 to 20 entries (82.5% drop) on a 19-server config.

Three-layer config resolution: env REASONIX_MCP_META_TOOL overrides
[tools] meta_tool config, which defaults to false (legacy behavior
unchanged).

- metatool.go: run_mcp dispatcher with dynamic server-to-tool mapping in
  Description(), cache-backed first-turn fallback, ImageTool support
- config.go: ToolsConfig.MetaTool *bool + MCPMetaToolEnabled() resolver
- boot.go: meta-tool mode branch in registerBackground + diagnostic Notice
- cmd/mcp-surface-dump: real boot.Build comparison (config-file path)
- cmd/meta-tool-priority: 39-case env x config priority matrix demo
- Tests: description contract, capacity math, schema validation,
  24-case config/env priority matrix
- META_TOOL.md: usage documentation
The docs-impact check requires docs/*.md changes when Documentation-impact
is "updated". Moving META_TOOL.md from repo root to docs/ satisfies this
requirement.
…it state preservation

Adds [agent] long_horizon config option that adjusts compaction thresholds
(soft 0.5→0.4, snip 0.6→0.5) to capture implicit state earlier, plus 3 new
sections in the compaction summary prompt:

- Hidden state & recovered facts: preserves inferred/recovered information
- Sources consulted: tracks checked vs unexplored data sources
- Open questions & uncertainties: surfaces unresolved questions for user

These directly address OSWorld 2.0's top failure modes: implicit state loss
after 2.5h, cross-source reasoning gaps, and guess-instead-of-ask behavior.

Adds startup diagnostic (compaction mode + section count + verification
interval) and compaction event detail (kept/fold breakdown + section
presence check) for observing implicit state retention at runtime.

Config: [agent] long_horizon = true or REASONIX_LONG_HORIZON=1 env.
Tests: 16 config matrix + 7 agent end-to-end (including cross-system
expense task with hidden employee ID, unexplored sources, open questions).
Print preserved implicit state on test success (verbose mode) so
developers can verify at a glance that Employee ID, archived sources,
unexplored sources, open questions, and pre-policy-date inference all
survived the compaction fold. Pairs with the existing failure-path
raw-summary dump for symmetric debuggability.
…icit-state diagnostics

Addresses all blocker items from PR esengine#7577 review (西万科拉):

1. Runtime identity isolation: use_capability uses MCPRuntimeSpecMatches for
   spec-based identity validation instead of name-only lookup. Same-name
   servers with different specs cannot cross-discover or cross-call.

2. No security boundary bypass: removed direct c.call("tools/call", ...);
   use_capability's ResolveCall resolves to real mcp__<server>__<tool> name,
   then CallResolver runs permission gate, Pre/PostToolUse hooks, evidence,
   and destructive/readOnly checks against the real tool name.

3. Lazy startup + generation safety: removed KickSpawns(); use_capability
   returns deferred Targets that connect on-demand at Execute time. Cache
   hits do not start processes. Old generation cannot revive after remove.

4. Stable schema/description: use_capability has fixed Schema() and static
   Description() — no dynamic server->tool mapping. Bytes stay stable across
   connection drift, hot-add, and tool-list changes.

5. Reuse use_capability instead of second dispatcher: deleted run_mcp
   implementation entirely (metatool.go: 249 lines to env-only shim;
   metatool_test.go: deleted). Meta-tool mode now hides all mcp__ top-level
   entries and registers the existing use_capability proxy.

6. Implicit-state runtime diagnostics (new in this commit):
   - compactionDoneDetail now reports per-section character counts, not just
     presence — an empty-header (0 chars) flags that the summarizer skipped
     a section even though it was requested.
   - implicitStateLossWarning fires a LevelWarn at runtime when any of the 3
     OSWorld 2.0-informed sections (Hidden state, Sources consulted, Open
     questions) is missing or has an empty body — the signal that implicit
     state was likely lost to the fold.
   - sectionContentChars extracts body length between headers.

7. Regression tests (4 requested + 6 new for diagnostics):
   - TestUseCapabilitySameNameDifferentSpecIsolation
   - TestUseCapabilityPermissionDenyMatchesRealToolNameBeforeCall
   - TestUseCapabilityCacheHitDoesNotStartProcess
   - TestUseCapabilitySchemaDescriptionStableAcrossConnectionDrift
   - TestCompactionDoneDetailReportsSectionContentChars
   - TestImplicitStateLossWarningSilentOnCompleteSummary
   - TestImplicitStateLossWarningFiresOnMissingSection
   - TestImplicitStateLossWarningFiresOnEmptyHeader
   - TestCompactionEmitsImplicitStateLossWarning (end-to-end)
   - TestCompactionNoLossWarningForCompleteSummary (silent on success)

8. gofmt + git diff --check: all 9 modified Go files pass.

mcp-surface-dump real boot.Build measurement:
  baseline:    142 tools, 95 mcp__ top-level, 65010 bytes
  meta-tool:    48 tools,  0 mcp__ top-level, 52826 bytes
  tools reduction: 66.2% | bytes reduction: 18.7%
Adds the continuous-state-management module identified by OSWorld 2.0 as
the largest single failure mode behind the long-horizon success ceiling:
agents lose implicit state (recovered file paths, inferred IDs, unexplored
data sources) across compaction.

StateTracker (internal/agent/state_tracker.go):
- Three-layer state model: WorkingState (current turn's active calls),
  EpisodicState (sliding window of recent turns, default 20),
  ImplicitState (accumulated recovered facts).
- BeforeToolCall/AfterToolCall hooks pair pre-call snapshots with results
  to extract implicit facts (file paths, IDs, error messages) via
  pre-compiled regex (unixPathRe, windowsPathRe, idAssignRe, jsonIDRe).
- SnapshotImplicitState() returns a deterministic text digest injected
  into compaction summaries when the model omits the Hidden state section.
- Concurrent-safe (sync.RWMutex); diagnostic events emit to the event sink.

Integration:
- run_loop.go: handleToolRound records stateTokens before each call and
  pairs them with results in AfterToolCall.
- compact.go: when the summarizer's output lacks the "Hidden state &
  recovered facts" section, the StateTracker snapshot is appended and a
  LevelInfo notice records the byte count injected.
- agent.go: Options.StateTracker + Agent.stateTracker field; New()
  initializes from Options.
- boot.go: NewDefaultStateTracker(0, sink) wired into executor Options.

Tests (state_tracker_test.go, 8 cases):
- Before/AfterToolCall pairing
- Path extraction (Unix + Windows)
- ID extraction (assignment + JSON)
- Error-state recording
- Episodic window eviction at capacity
- Reset clears all layers
- Diagnostic event emission
- Concurrent BeforeToolCall safety (parallel goroutines)

Verified: go test ./internal/agent/ -count=1 -> ok (26.8s); go build ./...
-> exit 0; gofmt -l clean on all touched files; git diff --check clean.
…apter

Implements the "state-based navigator" paradigm from the OSWorld 2.0 benchmark
(XLANG Lab) as an independent kernel that any host can embed. Directly targets
the three systematic failure modes OSWorld 2.0 found behind the 20.6% success
ceiling: implicit-state amnesia, dynamic-interface blindness, and
environment-update deafness.

New package internal/navigator/ (9 files, host-agnostic core + 2 adapters):

ContinuousStateManager (state.go):
  - Three-layer state model: WorkingState (current turn), EpisodicState
    (sliding window, default 50), ImplicitState (accumulated recovered facts).
  - StateGraph: directed graph of snapshots (nodes) + actions (edges),
    supports branching for closed-loop exploration.
  - StateHistory: linear trajectory with Rewind for rollback.
  - StatePredictor: forecasts expected post-action state for comparison.
  - Implicit facts are carried forward verbatim across every snapshot — the
    core defense against implicit-state amnesia. Facts are deduped by Key
    (later value wins) and never re-derived from history.

ClosedLoopEngine (loop.go):
  - Compare(): pure comparator detecting 4 deviation kinds (interface drift,
    env drift, fact loss, total mismatch) from prediction vs observation.
  - Decide(): 5 correction strategies (continue, reinject facts, retry,
    rollback, ask host) with per-action retry counter (MaxRetries=3).
  - Correction history recorded for auditing.

DynamicEnvSensor (sensor.go):
  - FilesystemSensor: walks the workspace dir, hashes file listing, detects
    create/modify/delete events.
  - ProcessSensor: monitors process list (tasklist on Windows, ps on Unix).
  - InterfaceSensor: abstract UI-state probe (host-supplied).
  - EventCorrelator: batches cross-sensor events within a time window;
    promotes cross-source batches to critical severity.

Navigator kernel (kernel.go):
  - Orchestrates the full verify-act-correct cycle around every action:
    sensor snapshot (before) → predict → host execute → sensor snapshot
    (after) → compare → correct → state update.
  - ExtractImplicitFacts(): proactively recovers paths (Unix + Windows),
    IDs, and errors from every tool result.
  - ImplicitStateDigest(): returns accumulated facts as text for compaction
    injection — the bridge between the navigator's continuous state and the
    host's prompt-level state.

HostAdapter interface (adapter.go):
  - The single seam between the kernel and the host runtime. Execute,
    Permission, Emit, InterfaceProbe, SnapshotEnv.
  - The kernel never calls a host-specific API directly.

ReasonixAdapter (reasonix_adapter.go):
  - Bridges to tool.Registry + event.Sink. Dispatches through the real
    tool.Execute path (ImageTool-aware). Permission is advisory (the agent's
    own CallResolver/gate is authoritative). Events surface as Notice cards.

HermesAdapter (hermes_adapter.go):
  - HERMES compatibility layer for future kernel optimization on top of this.
  - Tool-name mapping (read→read_file, exec→terminal, edit→patch, etc.).
  - HermesHookSimulator: simulates Pre/PostToolUse (HERMES has no native hooks).
  - Fail-closed: Execute returns an error when no backend is wired.

Integration:
  - agent.go: NavigatorKernel interface (minimal: ImplicitStateDigest()).
    Agent struct + Options get a `navigator` field.
  - compact.go: when the Navigator is wired, its ImplicitStateDigest is
    injected into the compaction summary's "Hidden state & recovered facts"
    section, merged with the StateTracker's digest if both are present.
  - boot.go: creates a ReasonixAdapter + Navigator, attaches
    FilesystemSensor (workspace root, depth 3) + ProcessSensor, and passes
    the kernel to the executor via agent.Options.

Tests (navigator_test.go, 30 cases, all pass):
  - StateGraph: Add/Get, Children, LatestStep
  - StateHistory: Append/Rewind, window eviction (root never evicted)
  - ContinuousStateManager: Seed, BeforeAction/AfterAction, upsert dedup,
    ImplicitStateDigest, facts carried forward across actions
  - Comparator: no deviation, fact lost, interface drift, total mismatch
  - ClosedLoopEngine: continue, reinject, retry→rollback, ask-host
  - ExtractImplicitFacts: Unix paths, Windows paths, errors
  - FilesystemSensor: detects file creation
  - EventCorrelator: promotes cross-source batches
  - End-to-end Navigator with mock adapter: no-deviation, fact recovery,
    permission denied
  - HermesAdapter: tool mapping, fail-closed, hook simulation, PreTool blocks
  - Concurrency: 20 goroutines inserting facts

Verified:
  - go test ./internal/navigator/ → ok (0.025s, 30 tests)
  - go test ./internal/agent/ → ok (25.4s)
  - go build ./... → exit 0
  - gofmt -l internal/navigator/ → clean
  - git diff --check → clean
… mcp-surface-dump

Boot/config errors can embed provider API keys (CWE-532 clear-text
logging). redactErr masks sk-*, api key/token/secret/password patterns
before they reach stdout.
… error pass-through, dedup/cap, switch semantics, verification nudge

1. Navigator no longer dead code: run_loop feeds every host-executed tool
   call through NavigatorKernel.ObserveToolCall (advisory mode — the
   navigator records observations and recovers implicit facts but never
   re-executes tools, so permission/hooks/evidence stay with the agent's own
   CallResolver path). boot gates Navigator+StateTracker wiring on
   long_horizon; agent.New purifies typed-nil interface values.
2. verification_interval now fires a runtime verification nudge every N
   tool-call rounds (long-horizon only), matching the config docs.
3. run_loop passes the real per-call error to StateTracker.AfterToolCall
   (batchExecution.errs) — failed calls are no longer recorded as success.
4. StateTracker implicit facts dedupe by (source, fact) and are capped at
   500 entries; navigator's upsert already deduped by Key.
5. long_horizon=false now truly disables the OSWorld 2.0 behavior: no
   StateTracker/Navigator wiring, legacy 7-section compaction prompt, no
   implicit-state injection; boot diagnostics match reality.

Tests: ObserveToolCall advisory suite (never-executes, failure advice,
multi-call tracking), StateTracker dedup/cap/error-recording, summary-prompt
switch, executeBatch err exposure, and a Run-level integration test
(TestRunLoopFeedsNavigatorAndTracker).
…cation

- navigator: split Execute into BeginAction/EndAction observer mode and
  thread the closed loop (predict->observe->verify->correct) through the run
  loop: reinject_facts re-injects lost implicit state (amnesia fix),
  rollback/retry/ask_host surface as events (rigidity fix); background
  environment watch samples changes between tool calls (deafness fix);
  ContinuousStateManager fully locked for concurrent sensors
- agent: NavigatorKernel interface + navigatorBridge; TokenGovernance
  aggregates OPT-261~265 (load shedder / cache-invalidation compactor /
  window resizer / admission gatekeeper / cache warmer), advisory-only,
  gated by [agent.token_governance]
- cosplay: new internal/cosplay package implementing CoSPlay inference-time
  co-evolution (discriminating test generation -> code x test matrix ->
  repair rounds with ineffective-test pruning -> consensus clustering);
  code_verify tool registered in the boot surface, [agent.cosplay] config
- config/docs: token_governance + cosplay sections, example.toml,
  TOOL_CONTRACT.md, RX_BIG_REFACTOR_PLAN.md
Large MCP catalogs can consume a substantial provider tool prefix, while cache-miss handshakes can change the visible schema after boot. The previous behavior had no automatic boundary between direct per-tool exposure and the existing use_capability proxy.

Choose the exposure mode once per session from cached tool counts and estimated schema bytes. Keep small, cache-valid surfaces direct; route large or unknown surfaces through the stable use_capability proxy without adding a user setting. Cache-miss discovery still warms the cache and records failures through a private registry, so it cannot mutate the provider-visible registry.

Add bounded diagnostics, bilingual documentation, and boot/integration coverage for small, large, stale, and cold MCP surfaces.

Tests: go test ./...

Tests: go test -race ./internal/boot

Checks: go vet ./internal/boot ./internal/capability ./internal/plugin ./internal/agent
Co-authored-by: bfxh <243242559+bfxh@users.noreply.github.com>
@bfxh
bfxh requested review from SivanCola and esengine as code owners August 6, 2026 16:18
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