feat(agents): route prediction-market intents via new markets_agent specialist (#2427)#2430
Conversation
…ing (tinyhumansai#2427) Introduces the `markets_agent` built-in: a narrow-scope financial-side-effect specialist for Polymarket (CTF Exchange) and Kalshi (KalshiEX). Mirrors the `crypto_agent` template — `delegate_name = "do_prediction_markets"`, named tool allowlist scoped to `polymarket` + `kalshi` + `memory_recall` + `ask_user_clarification` + `current_time`, agentic model hint, low temperature, safety preamble ON. Prompt enforces a read → browse → propose → confirm → execute contract with the venue-level `approved=true` flag as the non-negotiable gate. Refuses on missing creds, unknown ticker shape, price-out-of-band (1–99c on Kalshi, 0.01–0.99 on Polymarket), and never echoes API keys / signing secrets. Routing into orchestrator + loader registration land in follow-up commits. Refs tinyhumansai#2427
…nyhumansai#2427) Wires the new specialist into `agents/mod.rs` and the `BUILTINS` slice so `load_builtins()` parses `markets_agent/agent.toml` + binds its dynamic prompt builder. Bumps the contract count from 17 → 18 and adds a loader test pinning the venue allowlist, safety preamble, delegate_name, and the hard exclusions (no shell / wallet / delegation tools). Refs tinyhumansai#2427
…chestrator (tinyhumansai#2427) Adds `markets_agent` to the orchestrator's `subagents` list so `collect_orchestrator_tools` synthesises a `delegate_do_prediction_markets` tool at agent-build time. The orchestrator LLM now sees a first-class routing slot for Polymarket + Kalshi alongside `delegate_do_crypto` — closing the surface gap that made tinyhumansai#2145 (Polymarket) and tinyhumansai#2329 (Kalshi) tools register at the RPC layer but stay invisible to chat. Pairs the wiring with a loader-side `orchestrator_subagents_include_markets_agent` assertion and an `orchestrator_tools::tests::markets_agent_subagent_synthesises_do_prediction_markets_delegate` synthesis test that asserts the delegate name override resolves to `do_prediction_markets` (mirrors the `crypto_agent → do_crypto` precedent). Refs tinyhumansai#2427
…ute canonical (tinyhumansai#2427) Adds `disallowed_tools = ["polymarket", "kalshi"]` to `tools_agent.toml` so the generalist's wildcard inventory no longer surfaces the prediction- market venues. Prediction-market intents now have a single canonical route — `delegate_do_prediction_markets` — keeping the venue-aware approval-gate prompt in scope for every order. Without this guard the orchestrator's LLM would see two paths to `polymarket` / `kalshi` (delegate_do_prediction_markets AND delegate_tools_agent), with only the first carrying the read → propose → confirm → execute contract. Refs tinyhumansai#2427
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (9)
📝 WalkthroughWalkthroughThis pull request introduces a new built-in agent ChangesMarkets Agent Implementation & Routing
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
graycyrus
left a comment
There was a problem hiding this comment.
Looks good, nice work!
Summary
markets_agentbuilt-in specialist for prediction-market and event-contract trading (Polymarket + Kalshi) — modelled oncrypto_agent, with its own read → browse → propose → confirm → execute safety contract.markets_agentinto the orchestrator'ssubagentsso adelegate_do_prediction_marketstool is auto-synthesised; venue intents now route deterministically.polymarket/kalshiontools_agent's wildcard so each capability has exactly one canonical route — through the venue-aware approval-gate prompt.Problem
On a staging build of
feat/1398-kalshi(commite68fa585), the chat orchestrator replied touse kalshi tool to list marketswith "I don't have a kalshi tool available right now. The connected integrations I can work with are github, gmail, and slack." Same response forpolymarketdespite #2145 having shipped that capability. Trace of the runtime delegation surface confirmed exactly 9delegate_*tools visible to the orchestrator, none of which advertise prediction-market venues —delegate_tools_agent.when_to_usedescribes only "shell, file I/O, HTTP, web search, memory", so the LLM never picks it for trading intents, falls back to inspecting Composio connections, and reports "not connected."KalshiToolandPolymarketToolare both in the tools registry (src/openhuman/tools/ops.rs:541-558) and silently sit insidetools_agent's wildcard inventory (ToolScope::Wildcard => trueattool_prep.rs:165). The capabilities exist — the routing layer can't find them, so every dollar of trading work shipped on #2145 / #2329 is functionally unreachable from chat. Hyperliquid (#1398 venue 3/3) would inherit the same gap.Solution
Mirror the
crypto_agentprecedent (src/openhuman/agent/agents/crypto_agent/). New specialistmarkets_agent:delegate_name = "do_prediction_markets"→ orchestrator surfaces it asdelegate_do_prediction_marketsalongsidedelegate_do_crypto.["polymarket", "kalshi", "memory_recall", "ask_user_clarification", "current_time"]. Hyperliquid (perps) is intentionally deferred — its routing slot (markets_agent vs crypto_agent) is decided in venue 3/3's plan.approved=trueflag. Refuses on missing creds, unknown ticker shape, prices out of band (1–99c on Kalshi, 0.01–0.99 on Polymarket). Never echoes API keys / signing secrets.shell/file_write/curl/composio_*/spawn_*/delegate_*/wallet_*— keeps blast radius bounded to the same shape ascrypto_agent.Orchestrator wiring: one new entry in
orchestrator/agent.tomlsubagents list (betweencrypto_agentand the skills wildcard) with a comment explaining the route.collect_orchestrator_tools(tools/orchestrator_tools.rs) auto-emits the delegation tool — no code change there beyond a new synthesis test.Single canonical route:
tools_agentgainsdisallowed_tools = ["polymarket", "kalshi"]. The wildcard inventory still grants the generalist every other built-in tool, but the prediction-market venues are explicitly stripped so they route ONLY throughdelegate_do_prediction_markets. Without this guard the orchestrator's LLM would see two competing paths to the same capability, only one of which carries the safety preamble.Alternatives considered + rejected
crypto_agentto include polymarket/kalshi — conflates wallet-signing safety contract with USD market-buy contract; weakens routing signal as the blurb grows multi-topic. Crypto wallet RPCs and prediction-market REST/CLOB calls have different failure modes.tools_agent.when_to_useto mention prediction markets — wildcard means every future registry tool becomes implicitly trade-routable; no venue-specific safety preamble owned by the generalist.Submission Checklist
markets_agent::prompt::tests::*), 3 new loader tests (markets_agent_has_narrow_*,orchestrator_subagents_include_markets_agent,tools_agent_disallows_prediction_market_tools), the existingall_builtins_parsecount assertion (17 → 18), and 1 neworchestrator_toolssynthesis test (markets_agent_subagent_synthesises_do_prediction_markets_delegate). 50 / 50 pass locally — see Validation Run below.docs/TEST-COVERAGE-MATRIX.md.## Related— no matrix rows touched.docs/RELEASE-MANUAL-SMOKE.md) — Rust-only change, no release-cut surface modified; recommend a one-line addition to the smoke matrix in a follow-up once the markets_agent has run through a live trading flow on staging.Closes #NNNin the## Relatedsection —Closes #2427.Impact
ask_user_clarificationis in the allowlist, prompt requires it beforeapproved=true).tools_agentusers that previously accessedpolymarket/kalshivia the wildcard would be re-routed — but no callers existed (the LLM never picked that path, as the bug report shows).Related
markets_agentorcrypto_agent's exchange-trading surface; the slot inmarkets_agent's allowlist is reserved but not pre-allocated.docs/RELEASE-MANUAL-SMOKE.mdrow.AI Authored PR Metadata (required for Codex/Linear PRs)
Linear Issue
Commit & Branch
fix/2427-markets-agent-routing6702d725(tip; 4 GPG-signed commits offupstream/main @ bf6f25e6)Validation Run
pnpm --filter openhuman-app format:check— N/A: no TypeScript / app changes in this PR; pure Rust + agent definition TOML + prompt markdown.pnpm typecheck— N/A: same reason as above.cargo test --lib agent::agents::loader→ 35 passed, 0 failed in 0.04s (includes newmarkets_agent_has_narrow_prediction_market_tools_and_safety_on,orchestrator_subagents_include_markets_agent,tools_agent_disallows_prediction_market_tools).cargo test --lib tools::orchestrator_tools→ 11 passed, 0 failed in 0.00s (includes newmarkets_agent_subagent_synthesises_do_prediction_markets_delegate).cargo test --lib agent::agents::markets_agent→ 4 passed, 0 failed in 0.00s (prompt body unit tests).cargo fmt --checkclean;cargo check --libclean (pre-existing warns insecrets.rs,webview_accounts/ops.rs,mcp_clients/connections.rsare unrelated and identical to the upstream/main set).Validation Blocked
command:N/Aerror:N/Aimpact:N/ABehavior Changes
markets_agentviadelegate_do_prediction_markets) instead of falling back to "you don't have that integration." Both venues' approval gates are unchanged at the tool layer; the prompt makes them mechanically enforceable.approved=truemissing, real venue calls otherwise) instead of the misleading "no kalshi available" reply. Polymarket's gap from feat(integrations): Polymarket trading + market data (#1398, venue 1/3) #2145 closes alongside Kalshi.Parity Contract
crypto_agentroute is unchanged (testcrypto_agent_has_narrow_wallet_market_tools_and_safety_onstill passes);tools_agentretains every tool except the two explicitly disallowed venues; orchestrator's existing 9 delegations remain —delegate_do_prediction_marketsis additive, not a replacement.crypto_agent → do_cryptosynthesis pattern is preserved (testcollects_agentid_entries_and_collapses_skills_wildcardcovers it); the newmarkets_agent → do_prediction_marketssynthesis mirrors that pattern verbatim (new test asserts identical shape). Hard exclusions list onmarkets_agentmatchescrypto_agent's exclusion list (no shell / curl / wallet primitives / spawn / delegate).Summary by CodeRabbit