Skip to content

mech_request cannot send request_context, so market-aware mech tools always run blind from pearl-connect #64

Description

@bennyjo

Summary

The mech_request MCP tool (and MechService.request() behind it) accepts prompt, tool, chain, legacy_on_chain, priority_mech, auto_deposit, timeout, max_payment and request_id. There is no way to attach anything else to the request metadata. mech-predict tools such as superforcaster-market-aware and factual_research_v2/v3 read an optional top-level request_context field from that metadata (market_id, description, market_prob, market_close_at, ...). From pearl-connect they never receive it, so they degrade to their no-context mode on every request.

Observed on every delivery from this agent on 2026-09-03 (services 21, 44 and 25 on Polygon):

"market_prob_seen": null

Context: the market-aware prediction tool

valory-xyz/mech-predict#450 (merged 2026-09-02, deployed to the three Polygon predict mechs in agent-deployments#342) added superforcaster-market-aware. Its whole point is to consume the market context the trader already sends in request_context and combine it with a researchability assessment. From that PR:

  • Input: three keys of request_context are read, market_prob, market_close_at and description (resolution rules). Anything absent or malformed degrades to "blind mode" without raising. Blind mode is described as a real operating mode because it is the control arm of any later A/B.
  • Output: the required p_yes, p_no, confidence, info_utility plus optional researchability, evidence_quality, p_independent and market_prob_seen. market_prob_seen is echoed by Python from the request, never model-generated, precisely so a market-aware delivery can be told apart from a blind one afterwards.
  • Why it matters: in the PR's pre-registered holdout (385 questions) the market input alone was worth about 0.06 Brier, and the tool as a whole beat the deployed Polymarket tool by about 0.08. Without request_context a client gets the blind parent's performance, not the tool's.
  • The PR states "No trader change. No mech change. No new request field", because request_context already reaches run(**kwargs) from the trader. That holds for the trader path only. From pearl-connect the field cannot be sent at all, which is what this issue is about.

How the field travels today

  • Trader (valory-xyz/trader, decision_maker_abci/behaviours/decision_request.py): builds MechMetadata(prompt, tool, nonce, request_context=sampled_bet.to_request_context()). request_context is a top-level key of the IPFS metadata document.
  • mech-client 0.21.2 (infrastructure/ipfs/metadata.py::fetch_ipfs_hash): metadata = {"prompt", "tool", "nonce"} then metadata.update(extra_attributes). Any dict passed as extra_attributes lands at the top level. Only the CLI restricts values to primitives; the library path does not.
  • Mech (valory-xyz/mech, task_execution/behaviours.py): tool_task.execute(**task_data), so a top-level request_context reaches the tool as kwargs["request_context"].
  • pearl-connect (connect/mech.py): off-chain, extra_attributes = {"nonce": <salt>}; on-chain, extra_attributes = None. Nothing else can be added.

So the only layer missing the capability is this one.

Proposal

Add an optional request_context: dict | None = None parameter to mech_request and MechService.request():

  1. Pass it through to mech-client as part of extra_attributes (merged with the pinned nonce salt on the off-chain path).
  2. Include it in the CID computation inside MechAllowances.register_offchain_digest, which today calls fetch_ipfs_hash(prompt, tool, {"nonce": salt}). The off-chain signature covers the full metadata bytes, so the pre-registered digest must be computed over the same document mech-client will send, or the allowance will not match.
  3. Pass the dict through unmodified and treat it as opaque. Whether a market price is included is the caller's decision. For our use (an agent comparing its own estimate against the mech) it is useful to send description and market_close_at without market_prob, so the tool sees the resolution rules but p_independent stays price-free.
  4. Document the shape the mech-predict tools read (market_id, type, description, market_prob, market_close_at) in the pearl-connect skill, with a note that it is optional.

A generic extra_attributes parameter would also work, but a named request_context keeps the MCP surface honest about what the field is for and avoids callers overwriting prompt, tool or nonce.

Why it matters

Market-aware tools are being rolled out on the predict mechs (mech-predict#450, agent-deployments#342). Every marketplace client that is not the trader currently exercises only their blind mode, so the market reconciliation step of those tools has no coverage outside the trader.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions