Feat/osworld2 cosplay mcp - #7791
Open
bfxh wants to merge 16 commits into
Open
Conversation
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>
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.
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 updatedocs/*.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, orhigh, 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.