Skip to content

feat(agents): route prediction-market intents via new markets_agent specialist (#2427)#2430

Merged
graycyrus merged 4 commits into
tinyhumansai:mainfrom
oxoxDev:fix/2427-markets-agent-routing
May 21, 2026
Merged

feat(agents): route prediction-market intents via new markets_agent specialist (#2427)#2430
graycyrus merged 4 commits into
tinyhumansai:mainfrom
oxoxDev:fix/2427-markets-agent-routing

Conversation

@oxoxDev
Copy link
Copy Markdown
Contributor

@oxoxDev oxoxDev commented May 21, 2026

Summary

  • Closes the agent routing gap that made feat(integrations): Polymarket trading + market data (#1398, venue 1/3) #2145 (Polymarket) and feat(integrations): Kalshi trading + market data (#1398, venue 2/3) #2329 (Kalshi) tools register at the RPC layer but stay invisible to the chat agent.
  • Adds a new markets_agent built-in specialist for prediction-market and event-contract trading (Polymarket + Kalshi) — modelled on crypto_agent, with its own read → browse → propose → confirm → execute safety contract.
  • Wires markets_agent into the orchestrator's subagents so a delegate_do_prediction_markets tool is auto-synthesised; venue intents now route deterministically.
  • Disallows polymarket / kalshi on tools_agent's wildcard so each capability has exactly one canonical route — through the venue-aware approval-gate prompt.
  • All-Rust change: zero touch to RPC controllers, tool implementations, backend, or frontend.

Problem

On a staging build of feat/1398-kalshi (commit e68fa585), the chat orchestrator replied to use kalshi tool to list markets with "I don't have a kalshi tool available right now. The connected integrations I can work with are github, gmail, and slack." Same response for polymarket despite #2145 having shipped that capability. Trace of the runtime delegation surface confirmed exactly 9 delegate_* tools visible to the orchestrator, none of which advertise prediction-market venues — delegate_tools_agent.when_to_use describes 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."

KalshiTool and PolymarketTool are both in the tools registry (src/openhuman/tools/ops.rs:541-558) and silently sit inside tools_agent's wildcard inventory (ToolScope::Wildcard => true at tool_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_agent precedent (src/openhuman/agent/agents/crypto_agent/). New specialist markets_agent:

  • delegate_name = "do_prediction_markets" → orchestrator surfaces it as delegate_do_prediction_markets alongside delegate_do_crypto.
  • Named tool allowlist: ["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.
  • Prompt enforces a read → browse → propose → confirm → execute contract anchored on the venue-level approved=true flag. 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.
  • Hard exclusions in the loader test: no shell / file_write / curl / composio_* / spawn_* / delegate_* / wallet_* — keeps blast radius bounded to the same shape as crypto_agent.

Orchestrator wiring: one new entry in orchestrator/agent.toml subagents list (between crypto_agent and 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_agent gains disallowed_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 through delegate_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

  • Extend crypto_agent to 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.
  • Tweak tools_agent.when_to_use to mention prediction markets — wildcard means every future registry tool becomes implicitly trade-routable; no venue-specific safety preamble owned by the generalist.

Submission Checklist

  • Tests added or updated (happy path + at least one failure / edge case) per Testing Strategy
  • Diff coverage ≥ 80% — changed lines are exercised by 4 new prompt unit tests (markets_agent::prompt::tests::*), 3 new loader tests (markets_agent_has_narrow_*, orchestrator_subagents_include_markets_agent, tools_agent_disallows_prediction_market_tools), the existing all_builtins_parse count assertion (17 → 18), and 1 new orchestrator_tools synthesis test (markets_agent_subagent_synthesises_do_prediction_markets_delegate). 50 / 50 pass locally — see Validation Run below.
  • N/A: Coverage matrix updated — this is a routing-layer change with no new user-facing feature ID; no rows added or renamed in docs/TEST-COVERAGE-MATRIX.md.
  • N/A: All affected feature IDs from the matrix are listed in the PR description under ## Related — no matrix rows touched.
  • No new external network dependencies introduced (mock backend used per Testing Strategy) — pure agent-definition wiring, no HTTP / external services added.
  • N/A: Manual smoke checklist updated if this touches release-cut surfaces (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.
  • Linked issue closed via Closes #NNN in the ## Related section — Closes #2427.

Impact

  • Runtime: desktop only (Tauri shell hosts the in-process core per fix(core,cef): run core in-process and stop orphaning CEF helpers on Cmd+Q #1061). No mobile/web/CLI surface change.
  • Security: prediction-market venues continue to enforce their own credential guard + approval gate; this PR just routes intents to a specialist whose prompt makes the gate mechanically enforceable (ask_user_clarification is in the allowlist, prompt requires it before approved=true).
  • Performance: one extra delegation tool (10 instead of 9) in the orchestrator's function-calling schema; trivial token impact.
  • Compatibility: net-new agent registration. Existing chat flows that already worked (composio integrations, crypto agent, planner, etc.) are untouched. tools_agent users that previously accessed polymarket / kalshi via the wildcard would be re-routed — but no callers existed (the LLM never picked that path, as the bug report shows).
  • Migration: none. Agent definitions are baked into the binary at compile time.

Related


AI Authored PR Metadata (required for Codex/Linear PRs)

Linear Issue

  • Key: N/A
  • URL: N/A

Commit & Branch

  • Branch: fix/2427-markets-agent-routing
  • Commit SHA: 6702d725 (tip; 4 GPG-signed commits off upstream/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.
  • Focused tests:
    • cargo test --lib agent::agents::loader35 passed, 0 failed in 0.04s (includes new markets_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_tools11 passed, 0 failed in 0.00s (includes new markets_agent_subagent_synthesises_do_prediction_markets_delegate).
    • cargo test --lib agent::agents::markets_agent4 passed, 0 failed in 0.00s (prompt body unit tests).
  • Rust fmt/check (if changed): cargo fmt --check clean; cargo check --lib clean (pre-existing warns in secrets.rs, webview_accounts/ops.rs, mcp_clients/connections.rs are unrelated and identical to the upstream/main set).
  • Tauri fmt/check (if changed): N/A — Tauri shell untouched.

Validation Blocked

  • command: N/A
  • error: N/A
  • impact: N/A

Behavior Changes

  • Intended behavior change: orchestrator's chat agent now routes "list / trade Polymarket / Kalshi" intents to a new specialist (markets_agent via delegate_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.
  • User-visible effect: chat prompts targeting Polymarket / Kalshi now produce real tool dispatch (cred-guard error if API creds missing, approval-required error if approved=true missing, 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

  • Legacy behavior preserved: crypto_agent route is unchanged (test crypto_agent_has_narrow_wallet_market_tools_and_safety_on still passes); tools_agent retains every tool except the two explicitly disallowed venues; orchestrator's existing 9 delegations remain — delegate_do_prediction_markets is additive, not a replacement.
  • Guard/fallback/dispatch parity checks: the crypto_agent → do_crypto synthesis pattern is preserved (test collects_agentid_entries_and_collapses_skills_wildcard covers it); the new markets_agent → do_prediction_markets synthesis mirrors that pattern verbatim (new test asserts identical shape). Hard exclusions list on markets_agent matches crypto_agent's exclusion list (no shell / curl / wallet primitives / spawn / delegate).

Summary by CodeRabbit

  • New Features
    • Added a new Markets Agent specialized for prediction market trading on Polymarket and Kalshi exchanges.
    • Includes built-in safety constraints with user confirmation required before executing market trades.
    • Market trading operations now route through the dedicated Markets Agent for specialized handling and venue-specific approval gating.
    • Agent validates market conditions and enforces strict operational limits to prevent errors and unauthorized trades.

Review Change Stack

oxoxDev added 4 commits May 21, 2026 14:17
…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
@oxoxDev oxoxDev requested a review from a team May 21, 2026 08:54
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 21, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 2843279a-7366-4bec-87a6-6523eaa3cdd8

📥 Commits

Reviewing files that changed from the base of the PR and between bf6f25e and 6702d72.

📒 Files selected for processing (9)
  • src/openhuman/agent/agents/loader.rs
  • src/openhuman/agent/agents/markets_agent/agent.toml
  • src/openhuman/agent/agents/markets_agent/mod.rs
  • src/openhuman/agent/agents/markets_agent/prompt.md
  • src/openhuman/agent/agents/markets_agent/prompt.rs
  • src/openhuman/agent/agents/mod.rs
  • src/openhuman/agent/agents/orchestrator/agent.toml
  • src/openhuman/agent/agents/tools_agent/agent.toml
  • src/openhuman/tools/orchestrator_tools.rs

📝 Walkthrough

Walkthrough

This pull request introduces a new built-in agent markets_agent to handle prediction-market trading on Polymarket and Kalshi. The agent is registered with a narrowly scoped tool allowlist, configured with agentic model hint and zero-sandbox mode, and wired to receive routed requests via a dedicated delegate_do_prediction_markets orchestrator tool. The generalist tools_agent explicitly disallows those venues to ensure exclusive routing through the specialist.

Changes

Markets Agent Implementation & Routing

Layer / File(s) Summary
Markets Agent Definition & Registration
src/openhuman/agent/agents/mod.rs, src/openhuman/agent/agents/loader.rs, src/openhuman/agent/agents/markets_agent/agent.toml, src/openhuman/agent/agents/markets_agent/mod.rs
markets_agent is registered in BUILTINS with id: "markets_agent", delegate_name: "do_prediction_markets", model hint agentic, and a named tool allowlist for ["polymarket", "kalshi"]. Registration test count incremented to 18 built-ins; contract validation tests assert correct model hint, sandbox mode, safety preamble, named tool presence/absence, iteration cap, and stable delegate name.
System Prompt & Behavioral Contract
src/openhuman/agent/agents/markets_agent/prompt.md, src/openhuman/agent/agents/markets_agent/prompt.rs
Instruction prompt defines trading responsibilities (market/portfolio reading, order proposal/cancellation), hard constraints (no fabrication, read-before-write, approval gates, price sanity checks per venue, credential checks, sanitized error handling), and prescribed interaction flow (frame intent → inspect → propose → confirm → execute). Prompt builder assembles system prompt from archetype, tools, safety text, and workspace context with debug logging; unit tests verify non-empty output and required behavioral phrases.
Orchestrator Routing & Tool Isolation
src/openhuman/agent/agents/orchestrator/agent.toml, src/openhuman/agent/agents/tools_agent/agent.toml, src/openhuman/tools/orchestrator_tools.rs
Orchestrator adds markets_agent to subagents list so the agent receives a delegate_do_prediction_markets routing tool. Tools agent explicitly disallows ["polymarket", "kalshi"] to prevent those venues from being exposed via wildcard, ensuring sole canonical route through markets_agent. Routing tests verify orchestrator includes markets_agent and tools_agent blocks the venues; synthesis test confirms delegate tool is created with the correct override name and description.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Suggested labels

agent

Suggested reviewers

  • senamakel

Poem

🐰 A markets agent hops in line,
To trade those futures, oh so fine,
Polymarket, Kalshi too,
Read-before-write—the rabbit's way, it's true!
Approval gates guard every trade,
No secrets logged, no slip-ups made.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title accurately describes the main change: routing prediction-market intents through a new specialist agent called markets_agent.
Linked Issues check ✅ Passed The PR implementation satisfies all core coding objectives from issue #2427: adds markets_agent specialist with proper routing, narrow tool allowlist, approval gates, credential checks, and integrates it into the orchestrator with proper synthesis.
Out of Scope Changes check ✅ Passed All changes are narrowly scoped to agent configuration, routing, and module registration. No unrelated modifications to RPC, tools implementation, backend, frontend, or other systems were introduced.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot added the agent Built-in agents, prompts, orchestration, and agent runtime in src/openhuman/agent/. label May 21, 2026
Copy link
Copy Markdown
Contributor

@graycyrus graycyrus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, nice work!

@graycyrus graycyrus merged commit e031d85 into tinyhumansai:main May 21, 2026
30 of 33 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agent Built-in agents, prompts, orchestration, and agent runtime in src/openhuman/agent/.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Agent routing: first-party network tools invisible to chat surface (polymarket, kalshi)

2 participants