@coinrithm/mcp-trading 0.7.7 → 0.7.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/CHANGELOG.md +178 -0
  2. package/README.md +86 -69
  3. package/dist/agent/act.js +19 -6
  4. package/dist/agent/capitalSizing.d.ts +32 -0
  5. package/dist/agent/capitalSizing.js +270 -0
  6. package/dist/agent/client.d.ts +8 -1
  7. package/dist/agent/client.js +98 -39
  8. package/dist/agent/decision.d.ts +392 -0
  9. package/dist/agent/decision.js +177 -0
  10. package/dist/agent/decisionReceipt.d.ts +48 -0
  11. package/dist/agent/decisionReceipt.js +619 -0
  12. package/dist/agent/decisionValidator.d.ts +19 -2
  13. package/dist/agent/decisionValidator.js +74 -3
  14. package/dist/agent/engine.d.ts +1 -0
  15. package/dist/agent/engine.js +1 -0
  16. package/dist/agent/gate.js +14 -11
  17. package/dist/agent/observe.js +175 -34
  18. package/dist/agent/pmContext.d.ts +13 -0
  19. package/dist/agent/pmContext.js +136 -0
  20. package/dist/agent/prompt.d.ts +11 -1
  21. package/dist/agent/prompt.js +135 -7
  22. package/dist/agent/providerCapabilities.d.ts +3 -0
  23. package/dist/agent/providerCapabilities.js +41 -3
  24. package/dist/agent/providers.d.ts +2 -1
  25. package/dist/agent/providers.js +222 -86
  26. package/dist/agent/resolve.js +1 -0
  27. package/dist/agent/runner.d.ts +4 -1
  28. package/dist/agent/runner.js +369 -38
  29. package/dist/agent/scorecard.js +7 -1
  30. package/dist/agent/skill.js +17 -0
  31. package/dist/agent/skillValidator.d.ts +1 -0
  32. package/dist/agent/skillValidator.js +56 -0
  33. package/dist/agent/state.js +23 -2
  34. package/dist/agent/strictLint.js +19 -0
  35. package/dist/agent/templates.js +4 -0
  36. package/dist/agent/thesis.d.ts +40 -0
  37. package/dist/agent/thesis.js +319 -0
  38. package/dist/agent/types.d.ts +127 -0
  39. package/dist/client.js +3 -2
  40. package/dist/http.d.ts +7 -1
  41. package/dist/http.js +36 -16
  42. package/dist/httpCompletion.d.ts +33 -0
  43. package/dist/httpCompletion.js +220 -0
  44. package/dist/retryAfter.d.ts +1 -0
  45. package/dist/retryAfter.js +16 -0
  46. package/dist/tools.js +19 -1
  47. package/package.json +4 -2
package/CHANGELOG.md CHANGED
@@ -5,6 +5,184 @@ ships two binaries — `coinrithm-mcp` (the MCP server) and `coinrithm-agent` (t
5
5
  self-host agent runner) — versioned together. The CoinRithm **API contract** is
6
6
  versioned separately (see `openapi.yaml` `info.version`, currently `1.7.0`).
7
7
 
8
+ ## 0.7.9
9
+
10
+ This entry describes the package contents. Check npm for publication status;
11
+ a source version or hosted deployment does not confirm npm delivery.
12
+
13
+ Public market-data fidelity and runner reliability release. No MCP tool was
14
+ renamed or removed, and the API **contract stays 1.7.0**.
15
+
16
+ **PM evaluation budget.** Event-driven periodic prediction-market evaluations
17
+ now respect `maxLlmCallsPerHour` after their cooldown elapses. Budget skips make
18
+ no provider call and consume no call allowance. PM keeps its own cooldown;
19
+ open-position management and explicit always-on behavior retain their existing
20
+ exemptions. This runner gate is separate from hosted provider-capacity admission.
21
+
22
+ **Retry-After parsing.** Missing, blank or malformed headers no longer become
23
+ zero-delay retries. The runner API client uses its existing five-second fallback;
24
+ explicit zero, numeric seconds and HTTP dates remain supported. Model-provider
25
+ cooldowns share the parser and retain their existing one-hour cap.
26
+
27
+ **API request deadlines.** Each runner API operation now has a 30-second total
28
+ deadline covering response headers, body reads and all 429 retry waits. The
29
+ same client serves the hosted scheduler. Embedded callers can set a finite
30
+ `requestTimeoutMs` and supply an `AbortSignal`. A timeout or cancellation returns
31
+ an uncertain transport result without automatically replaying a trading write.
32
+ Timers and listeners are removed when the operation finishes.
33
+
34
+ **State persistence.** Self-host state is serialized to a private temporary file
35
+ and atomically renamed over the previous state. A failed serialization or rename
36
+ leaves the prior state intact. This is atomic replacement, not a claim of durable
37
+ storage across power loss.
38
+
39
+ **Agent conversion.** `coinrithm-agent eject` preserves explicit `triggerPolicy`
40
+ and `capitalSizing` blocks. Previously conversion could restore default hourly
41
+ budgets and drop equity sizing.
42
+
43
+ **Release verification.** All-source coverage gates, mandatory PostgreSQL CI,
44
+ dependency updates and corrected client setup docs are included. See the
45
+ [reliability record](https://github.com/CoinRithm/coinrithm-agent-trading/blob/main/docs/RELIABILITY.md).
46
+
47
+ **Confirmed-action journal.** Completed-action memory now requires an action
48
+ to be both accepted and executed. Failed writes and uncertain transport results
49
+ retain their attempt evidence without becoming completed moves in the next
50
+ decision prompt. Dry-run proposals remain unexecuted.
51
+
52
+ **Direct NVIDIA retry.** One complete HTTP 500/502/503/504 response can be
53
+ retried once on the identical direct NVIDIA route within the original deadline.
54
+ Both attempts are retained. This does not retry trading writes or change the
55
+ hosted shared-pool routing policy.
56
+
57
+ **Capital reconciliation.** Frozen-balance rounding residue down to -1e-8 is
58
+ normalized only in the sizing calculation after the independent reads agree.
59
+ Negative spendable cash still fails closed; wallet balances are not changed.
60
+
61
+ **Private decision input evidence.** The bounded numeric projection includes
62
+ nested indicator inputs and context movers, with legacy v1 records still readable.
63
+ It does not retain hidden reasoning or raw model output.
64
+
65
+ **Compact prediction-market evidence.** Discovery and compact event-detail
66
+ responses now retain the API's `source.quoteScale`, `source.methodology` and
67
+ `source.supportsMarketMetrics`, plus `spreadPoints`, `probabilityBook` and
68
+ each retained outcome's `normalizedProbability`. Venue-native bid/ask quotes
69
+ are never rescaled or interpreted from magnitude. Normalization remains the
70
+ API's calculation over the original full book, not the truncated top-five
71
+ outcome list. Existing payload bounds and explicit `detail: full` behavior
72
+ are unchanged.
73
+
74
+ **Settlement-time provenance.** Compact events retain `resolvedAtBasis` and
75
+ `settlementWindowClosedAt`, keeping provider expiration distinct from an
76
+ announced settlement time. Null and absent upstream evidence stay null and
77
+ absent; the MCP does not infer missing values.
78
+
79
+ **Candle semantics.** The `get_candles` description now states that these are
80
+ sampled composite-price bars. Each bar's `v` is a mean rolling 24-hour
81
+ quote-volume observation in USD, not volume traded during the candle, and
82
+ must not be summed across bars.
83
+
84
+ **HTTP completion diagnostics.** The hosted HTTP
85
+ entry now has a bounded, stderr-only completion observer with final SDK-result
86
+ and finish/abort accounting. Initialization, discovery, tool failures and
87
+ successful delivery are distinct; unknown tool names are normalized. Records
88
+ contain no arguments, bodies, credentials, caller/RPC IDs or caller-origin labels.
89
+ Credential presence is not authentication. Durations describe the HTTP request,
90
+ shared by batch members; server finish does not prove client receipt or use.
91
+ Stdio, tools, authentication and dependency versions are unchanged. See
92
+ `DEPLOY.md` for the measurement and retention limits. Hosted source/image
93
+ `18a0bb6a8a0665e91cebc10225fec6f7ebcdaaf7` passed a bounded anonymous smoke on
94
+ 2026-09-13. Hosted verification and npm publication are separate release steps.
95
+
96
+ **Deployment boundaries.** Hosted scheduler admission reasons are private
97
+ scheduler telemetry, not a new SDK or MCP response field. The API's corrected
98
+ comparison probabilities and enriched spread names use the existing response
99
+ shape and reach current clients through fresh API reads. Outcome display names
100
+ may change; use source/event/outcome identifiers for identity, never summed
101
+ prices or matching labels alone. These fixes do not establish trading returns.
102
+
103
+ ## 0.7.8
104
+
105
+ Runner decision-quality, evidence and paper-capital release. Additive: no MCP
106
+ tool was renamed or removed, and the API **contract stays 1.7.0**. This release
107
+ contains all package changes since published 0.7.7 (`gitHead` `80d0cae`), not
108
+ just the previously listed thesis work.
109
+
110
+ **Thesis exits.** Every opening action (`futures_open`, `spot_order`,
111
+ `pm_open`) now carries a `thesis`: a one-sentence summary plus an
112
+ `invalidation` with at least one machine-checkable condition (`priceBelow` /
113
+ `priceAbove` for coins, `probabilityBelow` / `probabilityAbove` for prediction
114
+ markets, a `maxHoldMinutes` time stop, and a free-text `catalyst` the model
115
+ re-judges itself). The runner binds the thesis to the position the server
116
+ returns, sanitized side-aware (a rising price never invalidates a long; a
117
+ wrong-side level is dropped rather than re-signed; the time stop is clamped to
118
+ 60 minutes .. 30 days), persists it in the run state (`RunState.theses`, the
119
+ same state file / `agent_state` JSON as before, no schema change) and
120
+ re-evaluates it every cycle. A futures position whose price level or time stop
121
+ is breached is closed by the runner before the model is asked anything, logged
122
+ as a `thesis_invalidated` exit with its own idempotency key, after the
123
+ kill-switch and drawdown checks and never instead of them. Prediction-market
124
+ positions have no close endpoint, so a broken PM thesis is surfaced to the
125
+ model instead (do not add, let it settle). The parser is tolerant (a malformed
126
+ thesis never fails the open; a thesis copied onto a close is ignored) and the
127
+ structured-output schema requires it, so schema-enforced hosted models always
128
+ emit one.
129
+
130
+ **Fundamentals in the observation.** Each watch entry now carries
131
+ `fundamentals` sourced only from calls the runner already makes: `categories`,
132
+ `marketCapRank` and `marketCapUsd` from the market context; `volume24hUsd` from
133
+ the candles the `indicators` capability already fetches (live-probed
134
+ 2026-09-02: each bar's `v` is a rolling 24h volume, so the latest bar is the
135
+ 24h figure, never the sum); and up to three `headlines` with `publishedAt`
136
+ timestamps from the one `news` call, attributed through the curated coin-news
137
+ graph. Discovered PM markets carry `endDate` and `liquidityUsd`; open PM
138
+ positions carry their title, side, entry and current probability and
139
+ `openedAt`; open futures positions carry `openedAt`. The system prompt states
140
+ the thesis contract, the runner-enforced exit and how to grade a trade on the
141
+ fundamentals. Not carried, because no agent endpoint serves them: an "about"
142
+ text per coin, a 24h probability change and a cross-venue divergence per PM
143
+ market.
144
+
145
+ **Fix:** the public movers feed serializes `change24h` / `currentPrice` as
146
+ decimal strings; the universe-scan context rows read them strictly as numbers
147
+ and shipped `undefined` for every mover.
148
+
149
+ **Opt-in equity-based paper sizing.** A runner can size entries from a
150
+ conservative fraction of its independently attributed paper book instead of a
151
+ fixed stake/margin. The book is accepted only when wallet identity, cash
152
+ partitions, held-position attribution and spot-mark coverage reconcile. Quotes
153
+ then enforce per-entry, per-symbol, deployed-capital and daily-entry limits;
154
+ fee buffers and the API's fee-inclusive quote evidence are included. Any
155
+ missing or inconsistent evidence fails closed. Legacy positions on a different
156
+ book remain visible for management but never inflate the current book's buying
157
+ power.
158
+
159
+ **Prediction-market decisions use executable economics.** PM opens now reject
160
+ an invalid raw probability and a model forecast that does not clear the quoted
161
+ entry price. Forecast edge is measured against the actual fee/slippage-adjusted
162
+ fill, not the headline market probability. Quote-expiry outcomes are recorded
163
+ separately from risk/balance rejection, and futures risk/reward validation uses
164
+ fee-inclusive entry and stop economics.
165
+
166
+ **Decision evidence is structured and bounded.** Cycles can expose a sanitized,
167
+ partial private decision-input record: configuration and observation
168
+ fingerprints, daily budget and guard state, plus bounded observation rows with
169
+ explicit omission counts. It is not a prompt, transcript, raw model output or
170
+ hidden reasoning record. The runner also reports quote/validation evidence for
171
+ abstained, forecast-only and quote-expired PM opportunities. Hosted persistence
172
+ and retention remain the caller's responsibility.
173
+
174
+ **Runtime controls are more faithful.** The model sees the remaining daily
175
+ entry/add budget rather than only static maxima. Entry caps still block new
176
+ risk, while closes and other risk-reducing actions remain available. Direct
177
+ provider HTTP 429 responses are capacity skips rather than model failures, so
178
+ BYO agents do not build a failure streak during ordinary quota pressure.
179
+ Structured-tool decisions remain required where the provider supports that
180
+ contract.
181
+
182
+ **Scorecard fix.** Maximum drawdown now measures decline from starting equity,
183
+ so an immediate loss is no longer hidden by treating the first post-trade point
184
+ as the high-water mark.
185
+
8
186
  ## 0.7.7
9
187
 
10
188
  Reliability release. Every change here came from a live production failure, not
package/README.md CHANGED
@@ -4,16 +4,18 @@
4
4
  (Claude, GPT, Gemini, Llama…) a 50,000 mUSD virtual account and let it trade
5
5
  spot, futures, and prediction markets on
6
6
  [CoinRithm](https://coinrithm.com/agentic-trading). No real money, no exchange,
7
- no risk — a proving ground to show an agent works *before* anything is on the
8
- line, with a public **Agent Arena** leaderboard using a versioned,
9
- confidence-weighted realized-PnL methodology.
7
+ with virtual funds and a public **Agent Arena** leaderboard using a versioned,
8
+ confidence-weighted realized-PnL methodology. Paper results do not establish
9
+ future returns or live execution performance.
10
10
 
11
11
  **Plus a free prediction-market data surface — no key at all.** The same server
12
12
  ships ten keyless `pm_data_*` tools serving CoinRithm's public cross-venue
13
- dataset: live odds across 12 venues (Polymarket, Kalshi, Smarkets, Limitless,
14
- Manifold, Metaculus, PredictIt, Rothera, Futuur, Myriad, ForecastEx, Gemini), cross-venue matches with a
15
- liquidity-aware reference probability, a whale-trade tape, and market-wide
16
- volume stats ($90B+ all-time tracked). Point any MCP client at the hosted
13
+ dataset: odds, cross-venue matches with a liquidity-aware reference probability,
14
+ a whale-trade tape, and market-wide volume statistics. Availability and freshness
15
+ vary by source; inspect the returned source-health and observation metadata.
16
+ The catalog covers 12 venues: Polymarket, Kalshi, Smarkets, Limitless, Manifold,
17
+ Metaculus, PredictIt, Rothera, Futuur, Myriad, ForecastEx and Gemini.
18
+ Point an MCP client that supports Streamable HTTP at the hosted
17
19
  endpoint `https://mcp.coinrithm.com/mcp` and call them anonymously — the API
18
20
  key is only needed for the trading tools.
19
21
 
@@ -23,8 +25,9 @@ Agents are **OKF bundles** — an open, model-agnostic folder of markdown + YAML
23
25
 
24
26
  - **Managed — nothing to install.** Build and deploy an agent in your browser
25
27
  with the **Agent Studio** (CoinRithm → My Agents → Studio): fork a house agent
26
- or write one from scratch, and CoinRithm runs it **free on Nemotron 3 Nano 30B**
27
- (NVIDIA NIM) on an always-on scheduler. The fastest path to a live agent.
28
+ or write one from scratch, and CoinRithm runs it on an always-on scheduler.
29
+ Studio shows the configured model; shared-pool routing can use another
30
+ eligible model. Check each agent's configuration and run evidence.
28
31
  - **Self-host — this package.** Bring your own model key and run the
29
32
  `observe→decide→validate→act` loop on your machine, or wire the MCP server
30
33
  into Claude Desktop / Cursor / Codex.
@@ -39,6 +42,17 @@ This package ships two binaries:
39
42
 
40
43
  > **Paper trading only** — virtual funds (50,000 mUSD). Not financial advice.
41
44
 
45
+ ## Version 0.7.9
46
+
47
+ This version includes the market-data fidelity and runner reliability fixes
48
+ listed in [CHANGELOG.md](./CHANGELOG.md). Check `npm view @coinrithm/mcp-trading
49
+ version` for the latest published version. Hosted deployments and npm releases
50
+ are separate.
51
+
52
+ Runner API operations have a 30-second total deadline, including response
53
+ bodies and 429 retry waits. Timeout and cancellation results remain unconfirmed;
54
+ the client does not automatically replay an uncertain trading write.
55
+
42
56
  ## Quick start
43
57
 
44
58
  ```bash
@@ -48,13 +62,15 @@ COINRITHM_API_KEY=crk_live_… npx -y @coinrithm/mcp-trading
48
62
 
49
63
  Get a `crk_live_…` key from CoinRithm → Profile → API Keys. To author and run a
50
64
  self-host agent instead, see [Agent runner](#agent-runner-coinrithm-agent).
51
- Building from source? `npm install && npm run build`.
65
+ Building from source? Use Node 20.19+ or 22.12+, then `npm ci && npm run build`.
66
+ Run `npm run test:coverage` for the enforced 90% statement, branch, function,
67
+ and line gates. See the [coverage scope and reliability checks](https://github.com/CoinRithm/coinrithm-agent-trading/blob/main/docs/RELIABILITY.md).
52
68
 
53
69
  ## Agent runner (`coinrithm-agent`)
54
70
 
55
71
  This package also ships a **self-host agent runner**. You write an agent as a
56
72
  folder (strategy + hard caps in markdown/YAML); the runner compiles it and runs
57
- an `observe → decide → validate → act` loop, asking *your* model (bring-your-own
73
+ an `observe → decide → validate → act` loop, asking _your_ model (bring-your-own
58
74
  key) for structured decisions and executing only the ones that pass your caps —
59
75
  **dry-run by default**, paper-only across spot, futures, and prediction markets.
60
76
 
@@ -68,15 +84,15 @@ COINRITHM_API_KEY=crk_live_… ANTHROPIC_API_KEY=sk-ant-… \
68
84
  Full guide (env vars, fail-closed guarantees, folder layout):
69
85
  **[docs/agent-runner.md](https://github.com/CoinRithm/coinrithm-agent-trading/blob/main/docs/agent-runner.md)**.
70
86
  The CoinRithm hosted scheduler runs this same engine for you — see the
71
- [scheduler README](../../packages/scheduler/README.md) for the built,
87
+ [scheduler README](https://github.com/CoinRithm/coinrithm-agent-trading/blob/main/packages/scheduler/README.md) for the built,
72
88
  DB-driven runtime.
73
89
 
74
90
  ## Two ways to run
75
91
 
76
- | Mode | Entry | Auth | Who it's for |
77
- | --- | --- | --- | --- |
78
- | **stdio** (single-user, local) | `dist/index.js` | `COINRITHM_API_KEY` env var | Claude Desktop / Cursor / Codex on your machine |
79
- | **Streamable HTTP** (multi-user, hosted) | `dist/http.js` | **per-request** `Authorization: Bearer` header | The shared hosted endpoint at `mcp.coinrithm.com` |
92
+ | Mode | Entry | Auth | Who it's for |
93
+ | ---------------------------------------- | --------------- | ---------------------------------------------- | ------------------------------------------------- |
94
+ | **stdio** (single-user, local) | `dist/index.js` | `COINRITHM_API_KEY` env var | Claude Desktop / Cursor / Codex on your machine |
95
+ | **Streamable HTTP** (multi-user, hosted) | `dist/http.js` | **per-request** `Authorization: Bearer` header | The shared hosted endpoint at `mcp.coinrithm.com` |
80
96
 
81
97
  The hosted HTTP server holds **no** key: each request brings its own
82
98
  `crk_live_…` in the Authorization header, and the server forwards exactly that
@@ -89,15 +105,16 @@ tool requires it. See [`DEPLOY.md`](./DEPLOY.md).
89
105
  The hosted Agent Studio runs your agent free on a shared pool of NVIDIA-hosted
90
106
  models. That pool is a **fixed budget shared by every hosted agent**, so the
91
107
  scheduler floors how often a shared agent may run, and the floor stretches as
92
- more agents join. Bringing your own model key removes that floor entirely:
93
- your quota is yours, so there is nothing for us to ration.
108
+ more agents join. Bringing your own model key removes the shared-pool interval
109
+ floor. Provider quotas, execution time, trigger policies and account protections
110
+ still apply.
94
111
 
95
- | | Shared free pool | Your own key |
96
- | --- | --- | --- |
97
- | Models | the free hosted picks | any model your provider serves |
98
- | Interval | floored by fleet size | exactly what you configure |
99
- | Rerouting | we may serve a live alternate when a model is rate-limited | never rerouted, your route is pinned |
100
- | Cost | free | you pay your provider, not CoinRithm |
112
+ | | Shared free pool | Your own key |
113
+ | --------- | ---------------------------------------------------------- | ------------------------------------------------------------ |
114
+ | Models | the free hosted picks | any model your provider serves |
115
+ | Interval | floored by fleet size | configured interval after completion, subject to other gates |
116
+ | Rerouting | we may serve a live alternate when a model is rate-limited | never rerouted, your route is pinned |
117
+ | Cost | free | you pay your provider, not CoinRithm |
101
118
 
102
119
  Providers accepted: `nvidia`, `openai`, `groq`, `anthropic`, and any
103
120
  `openai-compatible` endpoint (https base URL required). The key is validated by
@@ -113,11 +130,11 @@ agent file.
113
130
 
114
131
  ## Configure (stdio)
115
132
 
116
- | Env var | Required | Default | Notes |
117
- | --- | --- | --- | --- |
118
- | `COINRITHM_API_KEY` | yes (stdio only) | — | A `crk_live_…` key from CoinRithm → Profile → API Keys. **Ignored by the HTTP entry.** |
119
- | `COINRITHM_API_URL` | no | `https://api.coinrithm.com` | Upstream base URL (live) |
120
- | `PORT` | no | `8787` | HTTP entry only |
133
+ | Env var | Required | Default | Notes |
134
+ | ------------------- | ---------------- | --------------------------- | -------------------------------------------------------------------------------------- |
135
+ | `COINRITHM_API_KEY` | yes (stdio only) | — | A `crk_live_…` key from CoinRithm → Profile → API Keys. **Ignored by the HTTP entry.** |
136
+ | `COINRITHM_API_URL` | no | `https://api.coinrithm.com` | Upstream base URL (live) |
137
+ | `PORT` | no | `8787` | HTTP entry only |
121
138
 
122
139
  ## Run
123
140
 
@@ -136,46 +153,46 @@ agent file.
136
153
 
137
154
  ## Tools
138
155
 
139
- | Tool | Scope | Wraps |
140
- | --- | --- | --- |
141
- | `whoami` | any | `GET /api/agent/me` |
142
- | `get_portfolio` | read | `GET /api/agent/portfolio` |
143
- | `get_wallet` | read | `GET /api/agent/wallet` |
144
- | `resolve_symbol` | read | `GET /api/agent/resolve` |
145
- | `get_equity_curve` | read | `GET /api/agent/equity-curve` |
146
- | `get_my_trades` (venue) | read | `GET /api/agent/trades` |
147
- | `get_market_context` (coinId) | read | `GET /api/agent/market/:coinId` |
148
- | `get_candles` (coinId, range) | read | `GET /api/agent/market/:coinId/candles` |
149
- | `discover_pm_markets` | read | `GET /api/agent/pm/discover` |
150
- | `get_performance` | read | `GET /api/agent/performance` |
151
- | `get_agent_ledger` | read | `GET /api/agent/ledger` |
152
- | `export_agent_ledger` | read | `GET /api/agent/ledger/export` |
153
- | `export_run_evidence` | read | `GET /api/agent/ledger/export?runId=...` |
154
- | `get_arena_leaderboard` | read | `GET /api/arena` |
155
- | `get_arena_agent` (handle) | read | `GET /api/arena/:handle` |
156
- | `list_open_orders` | read | `GET /api/agent/orders/open` |
157
- | `get_positions` (venue) | read | `GET /api/agent/positions/{futures,pm}` |
158
- | `spot_quote` | read | `POST /api/agent/spot/quote` |
159
- | `futures_quote` | read | `POST /api/agent/futures/quote` |
160
- | `pm_quote` | read | `POST /api/agent/pm/quote` |
161
- | `place_spot_order` | trade:spot | `POST /api/agent/spot/order` |
162
- | `cancel_spot_order` | trade:spot | `POST /api/agent/spot/order/:id/cancel` |
163
- | `open_futures_position` | trade:futures | `POST /api/agent/futures/open` ¹ |
164
- | `set_futures_sl_tp` | trade:futures | `POST /api/agent/futures/sl-tp` ² |
165
- | `close_futures_position` | trade:futures | `POST /api/agent/futures/close` |
166
- | `open_pm_position` | trade:pm | `POST /api/agent/pm/open` ¹ |
167
- | `report_pm_opportunity` | read | `POST /api/agent/pm/opportunity` |
168
- | `pm_data_overview` | none (public) | compact `GET /api/prediction-markets/overview` |
169
- | `pm_data_sources` | none (public) | venue methodology, coverage, and comparable volume bases |
170
- | `pm_data_sources_health` | none (public) | per-venue freshness, lag, and degraded reasons |
171
- | `pm_data_events` | none (public) | compact `GET /api/prediction-markets/events` |
172
- | `pm_data_event` (source, slug, detail?) | none (public) | bounded event evidence by default; `detail: "full"` returns the untouched API record |
173
- | `pm_data_whales` (limit, default 10) | none (public) | compact `GET /api/prediction-markets/whales` |
174
- | `pm_data_disagreements` (limit, sort, sourceKind, ...) | none (public) | compact `GET /api/prediction-markets/matches/public` |
175
- | `pm_data_calibration` | none (public) | `GET /api/prediction-markets/calibration` |
176
- | `pm_data_canonical` (key?, limit, cursor) | none (public) | `GET /api/prediction-markets/canonical` (+ `/:key` detail) |
177
- | `pm_data_volume_history` | none (public) | `GET /api/prediction-markets/volume-history` |
178
- | `get_crypto_movers` (direction, limit) | none (public) | `GET /api/coins/top-{gainers,losers}` |
156
+ | Tool | Scope | Wraps |
157
+ | ------------------------------------------------------ | ------------- | ------------------------------------------------------------------------------------ |
158
+ | `whoami` | any | `GET /api/agent/me` |
159
+ | `get_portfolio` | read | `GET /api/agent/portfolio` |
160
+ | `get_wallet` | read | `GET /api/agent/wallet` |
161
+ | `resolve_symbol` | read | `GET /api/agent/resolve` |
162
+ | `get_equity_curve` | read | `GET /api/agent/equity-curve` |
163
+ | `get_my_trades` (venue) | read | `GET /api/agent/trades` |
164
+ | `get_market_context` (coinId) | read | `GET /api/agent/market/:coinId` |
165
+ | `get_candles` (coinId, range) | read | `GET /api/agent/market/:coinId/candles` |
166
+ | `discover_pm_markets` | read | `GET /api/agent/pm/discover` |
167
+ | `get_performance` | read | `GET /api/agent/performance` |
168
+ | `get_agent_ledger` | read | `GET /api/agent/ledger` |
169
+ | `export_agent_ledger` | read | `GET /api/agent/ledger/export` |
170
+ | `export_run_evidence` | read | `GET /api/agent/ledger/export?runId=...` |
171
+ | `get_arena_leaderboard` | read | `GET /api/arena` |
172
+ | `get_arena_agent` (handle) | read | `GET /api/arena/:handle` |
173
+ | `list_open_orders` | read | `GET /api/agent/orders/open` |
174
+ | `get_positions` (venue) | read | `GET /api/agent/positions/{futures,pm}` |
175
+ | `spot_quote` | read | `POST /api/agent/spot/quote` |
176
+ | `futures_quote` | read | `POST /api/agent/futures/quote` |
177
+ | `pm_quote` | read | `POST /api/agent/pm/quote` |
178
+ | `place_spot_order` | trade:spot | `POST /api/agent/spot/order` |
179
+ | `cancel_spot_order` | trade:spot | `POST /api/agent/spot/order/:id/cancel` |
180
+ | `open_futures_position` | trade:futures | `POST /api/agent/futures/open` ¹ |
181
+ | `set_futures_sl_tp` | trade:futures | `POST /api/agent/futures/sl-tp` ² |
182
+ | `close_futures_position` | trade:futures | `POST /api/agent/futures/close` |
183
+ | `open_pm_position` | trade:pm | `POST /api/agent/pm/open` ¹ |
184
+ | `report_pm_opportunity` | read | `POST /api/agent/pm/opportunity` |
185
+ | `pm_data_overview` | none (public) | compact `GET /api/prediction-markets/overview` |
186
+ | `pm_data_sources` | none (public) | venue methodology, coverage, and comparable volume bases |
187
+ | `pm_data_sources_health` | none (public) | per-venue freshness, lag, and degraded reasons |
188
+ | `pm_data_events` | none (public) | compact `GET /api/prediction-markets/events` |
189
+ | `pm_data_event` (source, slug, detail?) | none (public) | bounded event evidence by default; `detail: "full"` returns the untouched API record |
190
+ | `pm_data_whales` (limit, default 10) | none (public) | compact `GET /api/prediction-markets/whales` |
191
+ | `pm_data_disagreements` (limit, sort, sourceKind, ...) | none (public) | compact `GET /api/prediction-markets/matches/public` |
192
+ | `pm_data_calibration` | none (public) | `GET /api/prediction-markets/calibration` |
193
+ | `pm_data_canonical` (key?, limit, cursor) | none (public) | `GET /api/prediction-markets/canonical` (+ `/:key` detail) |
194
+ | `pm_data_volume_history` | none (public) | `GET /api/prediction-markets/volume-history` |
195
+ | `get_crypto_movers` (direction, limit) | none (public) | `GET /api/coins/top-{gainers,losers}` |
179
196
 
180
197
  `get_crypto_movers` is the universe scan: the biggest 24h movers across every
181
198
  coin CoinRithm tracks, so an agent can find candidates it was never configured
package/dist/agent/act.js CHANGED
@@ -1,15 +1,11 @@
1
1
  // Act phase: fetch the quote evidence for an open (the runner does this, never
2
2
  // the model) and execute a validated action (futures / spot / PM) with an
3
3
  // idempotency key.
4
- import { asObj, asNum, asStr } from "./extract.js";
4
+ import { asObj, asNum } from "./extract.js";
5
+ import { freshnessOf } from "./pmContext.js";
5
6
  function coinIdFor(observation, symbol) {
6
7
  return (observation.watch.find((w) => w.symbol.toUpperCase() === symbol.toUpperCase())?.coinId ?? undefined);
7
8
  }
8
- function freshnessOf(block) {
9
- const fr = asObj(block.freshness);
10
- const status = asStr(fr.status);
11
- return status ? { status, ageSeconds: asNum(fr.ageSeconds) } : undefined;
12
- }
13
9
  // Read-only quote BEFORE any open. Returns ineligible (never throws) on error.
14
10
  export async function fetchQuote(client, action, observation, trace) {
15
11
  let r;
@@ -50,7 +46,24 @@ export async function fetchQuote(client, action, observation, trace) {
50
46
  entryPrice: asNum(d.entryPrice), // futures
51
47
  liquidationPrice: asNum(d.liquidationPrice), // futures
52
48
  executionPrice: asNum(d.executionPrice), // spot live fill price
49
+ entryProbability: asNum(d.entryProbability), // pm raw probability POINTS
50
+ ...(action.type === "pm_open"
51
+ ? {
52
+ stakeMusd: asNum(d.stakeMusd),
53
+ sharesEstimate: asNum(d.sharesEstimate),
54
+ }
55
+ : {}),
53
56
  estimatedCostMusd: asNum(d.estimatedCostMusd), // spot gross notional
57
+ ...(action.type === "spot_order"
58
+ ? { estimatedFeeMusd: asNum(d.estimatedFeeMusd) }
59
+ : {}),
60
+ ...(action.type === "futures_open"
61
+ ? {
62
+ futuresFeeBps: asNum(asObj(d.executionModel).feeBps),
63
+ estimatedEntryFeeMusd: asNum(asObj(d.executionModel).estimatedEntryFeeMusd),
64
+ cashRequiredMusd: asNum(d.cashRequiredMusd),
65
+ }
66
+ : {}),
54
67
  // Freshness lives in the response's `observation` block (anti-look-ahead).
55
68
  freshness: freshnessOf(asObj(d.observation)),
56
69
  // PM open-time quality-gate preview (additive; older backends omit it → the
@@ -0,0 +1,32 @@
1
+ import type { AgentSpec, CapitalBook, CapitalSizingAdjustment, Observation, ProposedAction, QuoteEvidence } from "./types.js";
2
+ export declare const CAPITAL_VALUATION_BASIS = "wallet_assets_spot_marked_futures_pm_at_collateral";
3
+ export declare const CAPITAL_FEE_BUFFER_BPS = 10;
4
+ /** Reconcile the bounded open-position reads against the wallet's frozen
5
+ * buckets. A full page is not assumed complete: the collateral checksums must
6
+ * agree. No held mark, unknown status, missing bucket, or mismatched book can
7
+ * silently become zero exposure. Lists retain legacy positions on other books
8
+ * for management; only explicitly attributed current-book rows reconcile its
9
+ * cash and marks. Closed history never contributes unrealized. */
10
+ export declare function deriveCapitalBook(portfolio: unknown, wallet: unknown, futures: unknown, pm: unknown): CapitalBook;
11
+ export interface CapitalBudget {
12
+ cashAvailableMusd: number;
13
+ committedCapitalMusd: number;
14
+ openMarginMusd: number;
15
+ }
16
+ export declare const usesCapitalSizing: (spec: AgentSpec, mechanical?: boolean) => boolean;
17
+ export declare function prepareCapitalAction(action: ProposedAction, spec: AgentSpec, observation: Observation, budget: CapitalBudget): {
18
+ action: ProposedAction;
19
+ adjustment?: CapitalSizingAdjustment;
20
+ rejection?: string;
21
+ };
22
+ /** Quote-bound monetary checks. Drift fails closed; never requote a resized
23
+ * ticket, silently widen a cap, or credit uncertain close/sell proceeds. */
24
+ export declare function validateCapitalAction(action: ProposedAction, spec: AgentSpec, observation: Observation, budget: CapitalBudget, quote?: QuoteEvidence): string | undefined;
25
+ /** Fee-inclusive opt-in reservation; the legacy gross helper stays unchanged.
26
+ * The API quotes a market fill even for a pending limit/stop order. Reserve at
27
+ * least that fee, scaled up if the proposed price requires more notional.
28
+ * This is conservative captured quote evidence, not a future fill guarantee. */
29
+ export declare function capitalSpotBuyCost(action: Extract<ProposedAction, {
30
+ type: "spot_order";
31
+ }>, quote?: QuoteEvidence): number | undefined;
32
+ export declare function capitalCashCost(action: ProposedAction, quote?: QuoteEvidence): number;