You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
superforcaster-polymarket-v4 (and its ancestors) advertises a free-text input contract but silently depends on the valory trader's internal prompt template. Any other agent that calls the tool through the Mech Marketplace - the intended audience includes any agent paying for a prediction via Pearl Connect, not only traders - gets a degraded prior-only forecast: the web-retrieval step returns zero results and the LLM answers from its pretraining priors.
Observed in production: a mech request for a market trading at 0.875 returned p_yes = 0.60 with organic: [] in the captured Serper response. The requesting agent had stated the resolution question precisely (criteria, resolution source, deadline), exactly as the advertised contract suggests.
Root cause
The advertised contract says free text. The published tool metadata (scripts/tool_schemas.yaml, prediction kind) describes the input in its entirety as:
input:
type: textdescription: The text to make a prediction on
Nothing tells a requester that a specific prompt format is expected.
The tool assumes an undocumented template.extract_question in packages/valory/customs/superforcaster_polymarket_v4/superforcaster_polymarket_v4.py extracts the question with the regex question\s+"(.+?)"\s+and\s+the\s+yes``, which matches only the valory trader's internal prompt template. On a mismatch it falls back to using the entire prompt as the Serper search query.
Prompt-shaped queries degrade retrieval, in the worst case to zero organic results. Verified empirically against the live Serper API (2026-08-28), running the tool's own extract_question where applicable:
Prompt with instruction boilerplate and JSON-format text (580 chars)
no
full prompt
200
0
Question wrapped in exact-match quotes
n/a
quoted phrase
200
0
The trader path is healthy because extraction succeeds. For non-template prompts, degradation depends on content: a pure natural-language question usually still retrieves (fewer results); instruction boilerplate, backticks/JSON-format text, or exact-match quoting can drive results to zero. The production organic: [] case likely involved such content in the prompt; the captured searchParameters.q in the mech response is the definitive evidence for any specific incident.
Empty retrieval passes silently. The tool guards the HTTP-error path (raise_for_status()), but a 200 with organic: [] flows straight through: format_sources_data returns an empty string, the LLM receives an empty <background></background> block, and it forecasts from priors. The failure is invisible on-chain except as a poorly calibrated number.
Net effect: only the one caller whose internal template the tool happens to parse gets the intended retrieval path. Every other requester's prompt is passed raw to Serper - retrieval quality then depends on incidental prompt content, ranging from mildly degraded to silently empty, and the tool neither detects nor reports the empty case.
Why this matters
Mech Marketplace tools are meant to be callable by any agent willing to pay for a good prediction, not only the valory trader. That requires two things, and this tool currently provides neither:
The published metadata must give a requester clear, sufficient instructions to call the tool successfully.
The tool must honor those instructions - a prompt that satisfies the advertised contract must take the full-quality path, including retrieval.
Suggested fix direction
Tool-side, as a new variant (superforcaster-polymarket-v5) per the housekeeping rules, since any of this shifts the output distribution:
Honor the advertised free-text contract: when the trader-template regex does not match, treat the whole prompt as the question for the LLM but derive a proper search query from it (extract/compress the leading question, rather than passing the full prompt to Serper).
Add an explicit empty-retrieval guard: on organic: [], either retry with a simplified query, or force low confidence/info_utility (or return the null prediction) so the requester can detect and discount the answer.
Secondary, independent of the variant: make the published input description in scripts/tool_schemas.yaml state what a good prompt looks like (a single self-contained resolution question with criteria, source, and deadline), so requesters have explicit instructions to adhere to.
Summary
superforcaster-polymarket-v4(and its ancestors) advertises a free-text input contract but silently depends on the valory trader's internal prompt template. Any other agent that calls the tool through the Mech Marketplace - the intended audience includes any agent paying for a prediction via Pearl Connect, not only traders - gets a degraded prior-only forecast: the web-retrieval step returns zero results and the LLM answers from its pretraining priors.Observed in production: a mech request for a market trading at 0.875 returned
p_yes = 0.60withorganic: []in the captured Serper response. The requesting agent had stated the resolution question precisely (criteria, resolution source, deadline), exactly as the advertised contract suggests.Root cause
The advertised contract says free text. The published tool metadata (
scripts/tool_schemas.yaml,predictionkind) describes the input in its entirety as:Nothing tells a requester that a specific prompt format is expected.
The tool assumes an undocumented template.
extract_questioninpackages/valory/customs/superforcaster_polymarket_v4/superforcaster_polymarket_v4.pyextracts the question with the regexquestion\s+"(.+?)"\s+and\s+the\s+yes``, which matches only the valory trader's internal prompt template. On a mismatch it falls back to using the entire prompt as the Serper search query.Prompt-shaped queries degrade retrieval, in the worst case to zero organic results. Verified empirically against the live Serper API (2026-08-28), running the tool's own
extract_questionwhere applicable:The trader path is healthy because extraction succeeds. For non-template prompts, degradation depends on content: a pure natural-language question usually still retrieves (fewer results); instruction boilerplate, backticks/JSON-format text, or exact-match quoting can drive results to zero. The production
organic: []case likely involved such content in the prompt; the capturedsearchParameters.qin the mech response is the definitive evidence for any specific incident.Empty retrieval passes silently. The tool guards the HTTP-error path (
raise_for_status()), but a 200 withorganic: []flows straight through:format_sources_datareturns an empty string, the LLM receives an empty<background></background>block, and it forecasts from priors. The failure is invisible on-chain except as a poorly calibrated number.Net effect: only the one caller whose internal template the tool happens to parse gets the intended retrieval path. Every other requester's prompt is passed raw to Serper - retrieval quality then depends on incidental prompt content, ranging from mildly degraded to silently empty, and the tool neither detects nor reports the empty case.
Why this matters
Mech Marketplace tools are meant to be callable by any agent willing to pay for a good prediction, not only the valory trader. That requires two things, and this tool currently provides neither:
Suggested fix direction
Tool-side, as a new variant (
superforcaster-polymarket-v5) per the housekeeping rules, since any of this shifts the output distribution:organic: [], either retry with a simplified query, or force lowconfidence/info_utility(or return the null prediction) so the requester can detect and discount the answer.Secondary, independent of the variant: make the published input description in
scripts/tool_schemas.yamlstate what a good prompt looks like (a single self-contained resolution question with criteria, source, and deadline), so requesters have explicit instructions to adhere to.References
packages/valory/customs/superforcaster_polymarket_v4/superforcaster_polymarket_v4.py(extract_question,fetch_additional_sources,format_sources_data)scripts/tool_schemas.yaml(defaults.prediction.input),scripts/generate_metadata.pyis_prediction_toolpredicate - same class of implicit-contract problem, on the discovery side rather than the input side)