@coinrithm/mcp-trading 0.7.14 → 0.7.16

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 (72) hide show
  1. package/CHANGELOG.md +811 -613
  2. package/README.md +415 -366
  3. package/dist/agent/bench/bench.d.ts +59 -0
  4. package/dist/agent/bench/bench.js +319 -0
  5. package/dist/agent/bench/cassette.d.ts +97 -0
  6. package/dist/agent/bench/cassette.js +181 -0
  7. package/dist/agent/bench/costs.d.ts +28 -0
  8. package/dist/agent/bench/costs.js +60 -0
  9. package/dist/agent/bench/labelBuilder.d.ts +123 -0
  10. package/dist/agent/bench/labelBuilder.js +282 -0
  11. package/dist/agent/bench/labels.d.ts +75 -0
  12. package/dist/agent/bench/labels.js +259 -0
  13. package/dist/agent/bench/recordingClient.d.ts +51 -0
  14. package/dist/agent/bench/recordingClient.js +193 -0
  15. package/dist/agent/bench/replayClient.d.ts +41 -0
  16. package/dist/agent/bench/replayClient.js +262 -0
  17. package/dist/agent/bench/report.d.ts +115 -0
  18. package/dist/agent/bench/report.js +435 -0
  19. package/dist/agent/cli.d.ts +25 -0
  20. package/dist/agent/cli.js +300 -2
  21. package/dist/agent/client.d.ts +14 -0
  22. package/dist/agent/client.js +113 -4
  23. package/dist/agent/configurationWarnings.js +11 -0
  24. package/dist/agent/decision.d.ts +3 -0
  25. package/dist/agent/decision.js +85 -3
  26. package/dist/agent/decisionReceipt.d.ts +5 -1
  27. package/dist/agent/decisionReceipt.js +52 -3
  28. package/dist/agent/decisionValidator.d.ts +30 -0
  29. package/dist/agent/decisionValidator.js +147 -2
  30. package/dist/agent/engine.d.ts +3 -3
  31. package/dist/agent/engine.js +3 -3
  32. package/dist/agent/futuresEligibility.d.ts +36 -0
  33. package/dist/agent/futuresEligibility.js +90 -0
  34. package/dist/agent/observe.d.ts +35 -2
  35. package/dist/agent/observe.js +969 -128
  36. package/dist/agent/pmContext.d.ts +10 -1
  37. package/dist/agent/pmContext.js +163 -1
  38. package/dist/agent/prompt.d.ts +18 -1
  39. package/dist/agent/prompt.js +229 -33
  40. package/dist/agent/promptTables.d.ts +1 -0
  41. package/dist/agent/promptTables.js +33 -0
  42. package/dist/agent/providerCapabilities.d.ts +9 -0
  43. package/dist/agent/providerCapabilities.js +57 -4
  44. package/dist/agent/providers.d.ts +28 -7
  45. package/dist/agent/providers.js +200 -50
  46. package/dist/agent/resolve.js +3 -0
  47. package/dist/agent/runner.d.ts +8 -0
  48. package/dist/agent/runner.js +159 -26
  49. package/dist/agent/setups.d.ts +2 -1
  50. package/dist/agent/setups.js +17 -16
  51. package/dist/agent/signals.d.ts +33 -0
  52. package/dist/agent/signals.js +89 -0
  53. package/dist/agent/skill.js +37 -0
  54. package/dist/agent/skillValidator.js +33 -0
  55. package/dist/agent/strictLint.js +29 -0
  56. package/dist/agent/templates.js +30 -30
  57. package/dist/agent/types.d.ts +266 -13
  58. package/dist/agent/types.js +4 -0
  59. package/dist/agent/universe.d.ts +78 -0
  60. package/dist/agent/universe.js +215 -0
  61. package/dist/client.d.ts +9 -2
  62. package/dist/client.js +22 -10
  63. package/dist/http.d.ts +1 -0
  64. package/dist/http.js +17 -2
  65. package/dist/httpCompletion.d.ts +1 -1
  66. package/dist/httpCompletion.js +1 -0
  67. package/dist/index.js +2 -1
  68. package/dist/instructions.d.ts +1 -0
  69. package/dist/instructions.js +16 -0
  70. package/dist/tools.d.ts +1 -0
  71. package/dist/tools.js +150 -66
  72. package/package.json +98 -97
@@ -1,4 +1,4 @@
1
- import type { Freshness, PmDecisionSupport, PmQuality } from "./types.js";
1
+ import type { Freshness, PmCalibration, PmConsensus, PmDecisionSupport, PmQuality, PmOutcomeRule, PmSettlementRule } from "./types.js";
2
2
  export declare const PM_BLOCK_REASONS: readonly ["structurally_invalid", "stale_freshness", "freshness_unknown", "unpriced", "quote_dead", "dead_zero", "not_open", "source_degraded", "settlement_limbo"];
3
3
  export declare const PM_WARNING_REASONS: readonly ["lagging_freshness", "unproven_no_activity", "untraded_default", "play_money", "anomaly_flagged", "source_time_unverified", "sum_atypical_independent"];
4
4
  export declare const PM_FLAGS: readonly ["thinMarket", "inactiveMarket", "highAmbiguity", "nearResolution", "staleData"];
@@ -10,4 +10,13 @@ export declare const knownCode: (value: unknown, allowed: readonly string[]) =>
10
10
  export declare function sourceTimestamp(value: unknown): string | undefined;
11
11
  export declare function freshnessOf(block: Record<string, unknown>): Freshness | undefined;
12
12
  export declare function pmQualityOf(value: unknown): PmQuality | undefined;
13
+ export declare const PM_RULES_TEXT_MAX = 500;
14
+ export declare function pmSettlementRuleOf(event: Record<string, unknown>): PmSettlementRule | null | undefined;
15
+ export declare const PM_OUTCOME_PRIMARY_MAX = 400;
16
+ export declare const PM_OUTCOME_SECONDARY_MAX = 300;
17
+ export declare function pmOutcomeRuleOf(rules: PmSettlementRule | null | undefined, outcome: Record<string, unknown>): PmOutcomeRule | undefined;
18
+ export declare const PM_CONSENSUS_KINDS: readonly ["binary", "leader"];
19
+ export declare function pmConsensusOf(event: Record<string, unknown>): PmConsensus | null | undefined;
20
+ export declare const PM_CALIBRATION_MIN_SETTLED = 20;
21
+ export declare function pmCalibrationOf(value: unknown): PmCalibration | undefined;
13
22
  export declare function pmDecisionSupportOf(value: unknown): PmDecisionSupport | undefined;
@@ -1,4 +1,4 @@
1
- import { asArr, asNum, asObj } from "./extract.js";
1
+ import { asArr, asNum, asObj, asStr } from "./extract.js";
2
2
  export const PM_BLOCK_REASONS = [
3
3
  "structurally_invalid",
4
4
  "stale_freshness",
@@ -114,6 +114,168 @@ export function pmQualityOf(value) {
114
114
  omitted(raw.blockReasons, PM_BLOCK_REASONS),
115
115
  };
116
116
  }
117
+ // Prompt budget for one event's settlement text. The API bounds it at 700
118
+ // characters; the board shows up to ~10 events, so the runner keeps the
119
+ // condition and its "otherwise" branch and cuts the rest.
120
+ export const PM_RULES_TEXT_MAX = 500;
121
+ // The discover event's optional `resolution` (backend-v2 #111) for the prompt.
122
+ // undefined when the key is absent (older backend), null when it is null or
123
+ // unusable. A rule the venue never published stays published:false with no
124
+ // text: unknown terms, never a rule inferred from the title.
125
+ export function pmSettlementRuleOf(event) {
126
+ if (!Object.hasOwn(event, "resolution"))
127
+ return undefined;
128
+ const raw = event.resolution;
129
+ if (!raw || typeof raw !== "object" || Array.isArray(raw))
130
+ return null;
131
+ const r = raw;
132
+ if (typeof r.published !== "boolean")
133
+ return null;
134
+ const rules = typeof r.rules === "string" ? r.rules.replace(/\s+/g, " ").trim() : "";
135
+ const text = !r.published || !rules
136
+ ? undefined
137
+ : rules.length > PM_RULES_TEXT_MAX
138
+ ? `${rules.slice(0, PM_RULES_TEXT_MAX - 1).trimEnd()}…`
139
+ : rules;
140
+ const sources = asArr(r.settlementSources)
141
+ .map((s) => asStr(asObj(s).name)?.trim().slice(0, 60))
142
+ .filter((name) => !!name)
143
+ .slice(0, 3);
144
+ const settlementSource = asStr(r.settlementSource)?.trim().slice(0, 120);
145
+ if (settlementSource && !sources.includes(settlementSource))
146
+ sources.unshift(settlementSource);
147
+ const scope = r.scope === "per_outcome" ? r.scope : undefined;
148
+ return {
149
+ published: r.published,
150
+ ...(text ? { text } : {}),
151
+ ...(sources.length ? { sources: sources.slice(0, 3) } : {}),
152
+ ...(scope ? { scope } : {}),
153
+ };
154
+ }
155
+ // Prompt budget for one outcome's own rule (the API bounds each at 700).
156
+ export const PM_OUTCOME_PRIMARY_MAX = 400;
157
+ export const PM_OUTCOME_SECONDARY_MAX = 300;
158
+ const UNKNOWN_RULE_REASONS = [
159
+ "source_rules_unavailable",
160
+ "market_not_found",
161
+ "rule_missing",
162
+ "conflicting_duplicates",
163
+ ];
164
+ const cut = (text, max) => text.length > max ? `${text.slice(0, max - 1).trimEnd()}…` : text;
165
+ // One discover outcome's own settlement rule, only for a per-outcome event.
166
+ // undefined = the event's rule is not per-outcome (the row carries none);
167
+ // otherwise the exact provider rule or an explicit unknown reason.
168
+ export function pmOutcomeRuleOf(rules, outcome) {
169
+ if (rules?.scope !== "per_outcome")
170
+ return undefined;
171
+ const r = asObj(outcome.rules);
172
+ const text = (v) => typeof v === "string" ? v.replace(/\s+/g, " ").trim() : "";
173
+ const primary = text(r.primary);
174
+ if (r.status === "exact" && primary) {
175
+ const secondary = text(r.secondary);
176
+ return {
177
+ primary: cut(primary, PM_OUTCOME_PRIMARY_MAX),
178
+ ...(secondary
179
+ ? { secondary: cut(secondary, PM_OUTCOME_SECONDARY_MAX) }
180
+ : {}),
181
+ };
182
+ }
183
+ const reason = UNKNOWN_RULE_REASONS.find((v) => v === r.reason);
184
+ return { unknown: r.status === "unknown" && reason ? reason : "unreadable" };
185
+ }
186
+ export const PM_CONSENSUS_KINDS = ["binary", "leader"];
187
+ // The discover event's optional `referenceProbability` (0..100 points, open
188
+ // events only) as event-level consensus on the 0..1 `prob` scale. Returns
189
+ // undefined when the key is absent (older backend) and null when it is null
190
+ // or unusable. It is copied as-is: never mapped onto a specific outcome row
191
+ // and never flipped for a NO side, because orientation must not be inferred.
192
+ // An unknown kind, or a leader with no named outcome, cannot be read safely
193
+ // and is null.
194
+ export function pmConsensusOf(event) {
195
+ if (!Object.hasOwn(event, "referenceProbability"))
196
+ return undefined;
197
+ const raw = event.referenceProbability;
198
+ if (!raw || typeof raw !== "object" || Array.isArray(raw))
199
+ return null;
200
+ const r = raw;
201
+ const probability = asNum(r.probability);
202
+ const venues = asNum(r.venueCount);
203
+ const spreadPts = asNum(r.spreadPoints);
204
+ const kind = knownCode(r.kind, PM_CONSENSUS_KINDS);
205
+ const outcome = typeof r.outcomeName === "string" && r.outcomeName.trim() !== ""
206
+ ? r.outcomeName.slice(0, 80)
207
+ : r.outcomeName == null
208
+ ? null
209
+ : undefined;
210
+ if (probability == null ||
211
+ probability < 0 ||
212
+ probability > 100 ||
213
+ venues == null ||
214
+ !Number.isSafeInteger(venues) ||
215
+ venues < 1 ||
216
+ spreadPts == null ||
217
+ spreadPts < 0 ||
218
+ spreadPts > 100 ||
219
+ !kind ||
220
+ outcome === undefined ||
221
+ (kind === "leader" && outcome === null))
222
+ return null;
223
+ return { prob: probability / 100, venues, spreadPts, kind, outcome };
224
+ }
225
+ // Below this many settled forecasts the record is too noisy to steer the
226
+ // model, so it is not shown at all.
227
+ export const PM_CALIBRATION_MIN_SETTLED = 20;
228
+ const PM_CALIBRATION_MAX_BANDS = 10;
229
+ // The optional `pmCalibration` block of GET /api/agent/performance, compacted
230
+ // for the prompt: Brier to 3 decimals, percentages to whole points, bands
231
+ // with an invalid or empty range dropped. Returns undefined when the block is
232
+ // missing, malformed or has fewer than PM_CALIBRATION_MIN_SETTLED settled.
233
+ export function pmCalibrationOf(value) {
234
+ const raw = asObj(value);
235
+ const settled = asNum(raw.settled);
236
+ if (settled == null ||
237
+ !Number.isSafeInteger(settled) ||
238
+ settled < PM_CALIBRATION_MIN_SETTLED)
239
+ return undefined;
240
+ const brier = (v) => {
241
+ const n = asNum(v);
242
+ return n != null && n >= 0 && n <= 1 ? Math.round(n * 1000) / 1000 : null;
243
+ };
244
+ const pct = (v) => {
245
+ const n = asNum(v);
246
+ return n != null && n >= 0 && n <= 100 ? Math.round(n) : null;
247
+ };
248
+ const bands = asArr(raw.bands)
249
+ .map(asObj)
250
+ .flatMap((b) => {
251
+ const fromPct = asNum(b.fromPct);
252
+ const toPct = asNum(b.toPct);
253
+ const n = asNum(b.n);
254
+ const meanForecastPct = pct(b.meanForecastPct);
255
+ const winRatePct = pct(b.winRatePct);
256
+ if (fromPct == null ||
257
+ toPct == null ||
258
+ fromPct < 0 ||
259
+ toPct > 100 ||
260
+ fromPct >= toPct ||
261
+ n == null ||
262
+ !Number.isSafeInteger(n) ||
263
+ n < 1 ||
264
+ meanForecastPct == null ||
265
+ winRatePct == null)
266
+ return [];
267
+ return [{ fromPct, toPct, n, meanForecastPct, winRatePct }];
268
+ })
269
+ .slice(0, PM_CALIBRATION_MAX_BANDS);
270
+ return {
271
+ settled,
272
+ brierAgent: brier(raw.brierAgent),
273
+ brierMarket: brier(raw.brierMarket),
274
+ meanForecastPct: pct(raw.meanForecastPct),
275
+ winRatePct: pct(raw.winRatePct),
276
+ bands,
277
+ };
278
+ }
117
279
  export function pmDecisionSupportOf(value) {
118
280
  const raw = asObj(value);
119
281
  if (Object.keys(raw).length === 0)
@@ -1,4 +1,5 @@
1
- import { AgentSpec, Observation, PmResolution, RunState } from "./types.js";
1
+ import { AgentSpec, Observation, PmResolution, RunState, type ObjectivePrimary } from "./types.js";
2
+ import type { DecisionActionExclusion } from "./providerCapabilities.js";
2
3
  export interface DailyRiskBudget {
3
4
  version: "coinrithm.daily-risk-budget.v1";
4
5
  utcDay: string;
@@ -7,9 +8,22 @@ export interface DailyRiskBudget {
7
8
  remaining: number | null;
8
9
  }
9
10
  export declare function buildDailyRiskBudget(spec: AgentSpec, state: Pick<RunState, "dayKey" | "riskIncreasesToday">): DailyRiskBudget;
11
+ export interface FuturesCapacity {
12
+ version: "coinrithm.futures-capacity.v1";
13
+ openPositions: number;
14
+ maxPositions: number;
15
+ slotsLeft: number;
16
+ openMarginMusd: number;
17
+ maxOpenMarginMusd: number;
18
+ marginHeadroomMusd: number;
19
+ }
20
+ export declare function buildFuturesCapacity(spec: AgentSpec, obs: Pick<Observation, "openPositions">): FuturesCapacity;
10
21
  export declare function formatPmResolutions(resolutions: PmResolution[]): string[];
22
+ export declare const OBJECTIVE_GUIDANCE: Record<ObjectivePrimary, string>;
23
+ export declare function objectiveLine(spec: Pick<AgentSpec, "objective">): string | null;
11
24
  export declare function buildSystemPrompt(spec: AgentSpec, mergedProse: string, opts?: {
12
25
  includeForecast?: boolean;
26
+ excludeActionTypes?: readonly DecisionActionExclusion[];
13
27
  }): string;
14
28
  export declare function buildUserPrompt(obs: Observation, journal?: Array<{
15
29
  at: string;
@@ -18,4 +32,7 @@ export declare function buildUserPrompt(obs: Observation, journal?: Array<{
18
32
  venues?: AgentSpec["venues"];
19
33
  dailyRiskBudget?: DailyRiskBudget;
20
34
  capitalSizing?: AgentSpec["capitalSizing"];
35
+ futuresCapacity?: FuturesCapacity;
36
+ compactTables?: boolean;
37
+ excludeActionTypes?: readonly DecisionActionExclusion[];
21
38
  }): string;