Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 28 additions & 16 deletions mcp_server/compact.py
Original file line number Diff line number Diff line change
Expand Up @@ -295,12 +295,13 @@ def get_current_work_context(
limit: int = 6,
cursor: str | None = None,
) -> dict[str, Any]:
"""Return a compact current-work overview with pointers to canonical evidence.
"""Return an optional compact derived overview with pointers to canonical evidence.

Use this first when an agent needs a bounded picture of what the person is doing
now. The embedded trace is deliberately summarized; call get_workflow_trace for
canonical rich rows. Increase limit or follow trace pagination when more evidence
is needed. Observed strings remain protected at the MCP boundary.
Use get_workflow_trace first when reconstructing what happened. This convenience
view mixes a small evidence sample with non-authoritative task, pattern and
semantic indexes for callers that explicitly want a quick overview. Verify any
interpretation against canonical evidence. Existing response fields are preserved
for compatibility, and observed strings remain protected at the MCP boundary.
"""
name = "get_current_work_context"
core._begin(name)
Expand All @@ -324,6 +325,13 @@ def get_current_work_context(
if isinstance(x, dict)
],
"evidence_tool": "get_workflow_trace",
"canonical_evidence_tool": "get_workflow_trace",
"overview_is_derived": True,
"authoritative": False,
"derived_sections": ["task_hints", "repeated_patterns", "semantic_activity"],
"reconstruction_guidance": (
"Use get_workflow_trace as the source of truth; task_hints and repeated_patterns are non-authoritative."
),
"data_layer": "rich_ai_context_compact_overview",
})

Expand Down Expand Up @@ -389,17 +397,20 @@ def get_workflow_trace(
since: str | None = None,
until: str | None = None,
cursor: str | None = None,
limit: int = 4,
limit: int = 100,
scope: str = "current",
query: str | None = None,
app_name: str | None = None,
session_id: str | None = None,
) -> dict[str, Any]:
"""Return canonical chronological workflow evidence with stable pagination.

The default page is intentionally small for agent context budgets, but row shape
remains canonical and callers can request larger pages. Pass next_cursor back as
cursor for more evidence. Typed text and clipboard contents are never captured.
Use this first to reconstruct what happened. This is the primary Context MCP
evidence surface and exposes the same underlying captured evidence that rich
exports are built from, without eagerly dumping the whole history into model
context. Follow next_cursor until has_more is false when more evidence is needed;
use scope='all' for full retained history. Typed text and clipboard contents are
never captured.
"""
name = "get_workflow_trace"
core._begin(name)
Expand Down Expand Up @@ -802,13 +813,14 @@ def ai_guide() -> str:
def data_model() -> str:
return (
"OpenWorkGraph compact MCP exposes a small read-oriented surface over privacy-hardened "
"human and agent evidence. Use get_current_work_context first, get_workflow_trace for "
"canonical evidence, find_repeated_workflows for derived recurring patterns and exact "
"family keys, how_did_similar_runs_go for descriptive prior-run feedback with privacy-safe "
"readable human steps, get_task_context for bounded organizational context, and get_agent_runs "
"for structural agent execution evidence. Readable step labels never replace the stable "
"structural family identity. Observed repetition is never policy or permission. Missing agent "
"signals mean not observed."
"human and agent evidence. Use get_workflow_trace first to reconstruct work from canonical "
"chronological evidence, paging or searching as needed. get_current_work_context is an optional "
"derived quick overview and must not override the evidence. find_repeated_workflows provides "
"derived recurring-pattern candidates and exact family keys; how_did_similar_runs_go provides "
"descriptive prior-run feedback with privacy-safe readable human steps; get_task_context provides "
"bounded organizational context; and get_agent_runs provides structural agent execution evidence. "
"Readable step labels never replace stable structural family identity. Observed repetition is never "
"policy or permission. Missing agent signals mean not observed."
)


Expand Down
32 changes: 27 additions & 5 deletions tests/test_compact_feedback_v0871.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,22 +189,44 @@ def ambiguous_get(path: str, params: dict | None = None):
assert len(result["available_families"]) == 2


def test_compact_context_defaults_are_smaller_but_explicit_limits_still_work(monkeypatch):
def test_compact_overview_stays_small_but_canonical_trace_defaults_to_100(monkeypatch):
compact, calls = _install_feedback_fakes(monkeypatch)

compact.get_current_work_context()
overview = compact.get_current_work_context()
trace_call = next(params for path, params in calls if path == "/v1/workflow-trace")
semantic_call = next(params for path, params in calls if path == "/v1/semantic-activity")
assert trace_call["limit"] == 6
assert semantic_call["limit"] == 6
assert overview["overview_is_derived"] is True
assert overview["authoritative"] is False
assert overview["canonical_evidence_tool"] == "get_workflow_trace"
assert set(overview["derived_sections"]) == {"task_hints", "repeated_patterns", "semantic_activity"}
# Existing convenience fields remain present for backwards compatibility.
assert "task_hints" in overview and "repeated_patterns" in overview and "semantic_activity" in overview

calls.clear()
compact.get_workflow_trace()
assert calls[-1][1]["limit"] == 4
assert calls[-1][1]["limit"] == 100

calls.clear()
compact.get_workflow_trace(limit=100)
assert calls[-1][1]["limit"] == 100
compact.get_workflow_trace(limit=37)
assert calls[-1][1]["limit"] == 37


def test_compact_context_contract_is_evidence_first():
from mcp_server import compact

trace_doc = inspect.getdoc(compact.get_workflow_trace) or ""
overview_doc = inspect.getdoc(compact.get_current_work_context) or ""
model = compact.data_model()

assert "Use this first" in trace_doc
assert "primary Context MCP" in trace_doc
assert "Use get_workflow_trace first" in overview_doc
assert "optional compact derived overview" in overview_doc
assert "Use get_workflow_trace first" in model
assert "get_current_work_context is an optional" in model
assert "Use get_current_work_context first" not in model


def test_feedback_and_task_context_tool_descriptions_explain_inputs():
Expand Down
27 changes: 27 additions & 0 deletions tests/test_context_evidence_boundary_v093.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from __future__ import annotations

from pathlib import Path


ROOT = Path(__file__).resolve().parents[1]


def test_canonical_context_trace_is_not_filtered_by_observe_connection_state():
"""Observe state may filter the Agents UI, never canonical Context history."""
trace_source = (ROOT / "server" / "mcp_trace.py").read_text(encoding="utf-8")
agent_view_source = (ROOT / "server" / "agent_execution_trace_routes.py").read_text(encoding="utf-8")

assert "hidden_frameworks" not in trace_source
assert "observation_active" not in trace_source
assert "hide_disconnected" not in trace_source

# The connection-aware filtering introduced for the Agents tab remains explicitly
# opt-in on the derived agent-run view instead of mutating stored evidence.
assert "hide_disconnected: bool = False" in agent_view_source
assert "hidden_frameworks" in agent_view_source


def test_context_trace_declares_task_inference_non_authoritative():
trace_source = (ROOT / "server" / "mcp_trace.py").read_text(encoding="utf-8")
assert '"derived_task_inference_authoritative": False' in trace_source
assert '"data_layer": "privacy_hardened_raw_rich_evidence"' in trace_source
Loading