@coinrithm/mcp-trading 0.7.16 → 0.7.18
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.
- package/CHANGELOG.md +903 -811
- package/README.md +488 -415
- package/dist/agent/capitalSizing.d.ts +10 -1
- package/dist/agent/capitalSizing.js +28 -4
- package/dist/agent/client.d.ts +13 -0
- package/dist/agent/client.js +17 -6
- package/dist/agent/decision.d.ts +21 -16
- package/dist/agent/decision.js +7 -0
- package/dist/agent/decisionValidator.d.ts +1 -0
- package/dist/agent/decisionValidator.js +1 -1
- package/dist/agent/engine.d.ts +3 -1
- package/dist/agent/engine.js +3 -1
- package/dist/agent/futuresCloseOutcome.d.ts +19 -0
- package/dist/agent/futuresCloseOutcome.js +54 -0
- package/dist/agent/futuresEligibility.d.ts +13 -0
- package/dist/agent/futuresEligibility.js +43 -5
- package/dist/agent/observe.d.ts +2 -1
- package/dist/agent/observe.js +1 -1
- package/dist/agent/pmPaperCandidates.d.ts +17 -0
- package/dist/agent/pmPaperCandidates.js +125 -0
- package/dist/agent/pmPaperCycle.d.ts +16 -0
- package/dist/agent/pmPaperCycle.js +372 -0
- package/dist/agent/pmPaperDecision.d.ts +187 -0
- package/dist/agent/pmPaperDecision.js +101 -0
- package/dist/agent/pmPaperPolicy.d.ts +71 -0
- package/dist/agent/pmPaperPolicy.js +46 -0
- package/dist/agent/prompt.d.ts +12 -1
- package/dist/agent/prompt.js +90 -3
- package/dist/agent/providerCapabilities.d.ts +1 -0
- package/dist/agent/providerCapabilities.js +4 -1
- package/dist/agent/providers.d.ts +1 -0
- package/dist/agent/providers.js +9 -4
- package/dist/agent/runner.d.ts +9 -1
- package/dist/agent/runner.js +152 -24
- package/dist/agent/skill.js +9 -0
- package/dist/agent/skillValidator.js +23 -0
- package/dist/agent/strictLint.js +1 -0
- package/dist/agent/templates.js +30 -30
- package/dist/agent/types.d.ts +31 -0
- package/dist/agent/version.d.ts +1 -1
- package/dist/agent/version.js +1 -1
- package/dist/client.d.ts +14 -0
- package/dist/client.js +31 -1
- package/dist/http.js +1 -1
- package/dist/pmPaperV2.d.ts +81 -0
- package/dist/pmPaperV2.js +53 -0
- package/dist/tools.js +106 -14
- package/package.json +100 -98
|
@@ -1,6 +1,15 @@
|
|
|
1
|
-
import type { AgentSpec, CapitalBook, CapitalSizingAdjustment, Observation, ProposedAction, QuoteEvidence } from "./types.js";
|
|
1
|
+
import type { AgentSpec, CapitalBook, CapitalSizingPolicy, CapitalSizingAdjustment, Observation, ProposedAction, QuoteEvidence } from "./types.js";
|
|
2
2
|
export declare const CAPITAL_VALUATION_BASIS = "wallet_assets_spot_marked_futures_pm_at_collateral";
|
|
3
3
|
export declare const CAPITAL_FEE_BUFFER_BPS = 10;
|
|
4
|
+
/** The ticket and stop-risk limits for one action. Owner 2026-10-08: a
|
|
5
|
+
* risk-taker may size a futures entry it rates at or above
|
|
6
|
+
* highConviction.minConfidence far above its base ticket. Only futures_open
|
|
7
|
+
* qualifies; PM and spot sizing never read confidence. */
|
|
8
|
+
export declare function capitalLimitsFor(policy: CapitalSizingPolicy, action: ProposedAction): {
|
|
9
|
+
perTicketCapitalPct: number;
|
|
10
|
+
futuresRiskPct: number;
|
|
11
|
+
highConviction: boolean;
|
|
12
|
+
};
|
|
4
13
|
/** Reconcile the bounded open-position reads against the wallet's frozen
|
|
5
14
|
* buckets. A full page is not assumed complete: the collateral checksums must
|
|
6
15
|
* agree. No held mark, unknown status, missing bucket, or mismatched book can
|
|
@@ -16,6 +16,28 @@ const FROZEN_RESIDUE_TOLERANCE = 1e-8;
|
|
|
16
16
|
const centsDown = (n) => Math.floor(n * 100) / 100;
|
|
17
17
|
const positive = (n) => asNum(n) !== undefined && n > 0;
|
|
18
18
|
const nonnegative = (n) => asNum(n) !== undefined && n >= 0;
|
|
19
|
+
/** The ticket and stop-risk limits for one action. Owner 2026-10-08: a
|
|
20
|
+
* risk-taker may size a futures entry it rates at or above
|
|
21
|
+
* highConviction.minConfidence far above its base ticket. Only futures_open
|
|
22
|
+
* qualifies; PM and spot sizing never read confidence. */
|
|
23
|
+
export function capitalLimitsFor(policy, action) {
|
|
24
|
+
const hc = policy.highConviction;
|
|
25
|
+
if (hc &&
|
|
26
|
+
action.type === "futures_open" &&
|
|
27
|
+
typeof action.confidence === "number" &&
|
|
28
|
+
Number.isFinite(action.confidence) &&
|
|
29
|
+
action.confidence >= hc.minConfidence)
|
|
30
|
+
return {
|
|
31
|
+
perTicketCapitalPct: hc.perTicketCapitalPct,
|
|
32
|
+
futuresRiskPct: hc.futuresRiskPct,
|
|
33
|
+
highConviction: true,
|
|
34
|
+
};
|
|
35
|
+
return {
|
|
36
|
+
perTicketCapitalPct: policy.perTicketCapitalPct,
|
|
37
|
+
futuresRiskPct: policy.futuresRiskPct,
|
|
38
|
+
highConviction: false,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
19
41
|
/** Reconcile the bounded open-position reads against the wallet's frozen
|
|
20
42
|
* buckets. A full page is not assumed complete: the collateral checksums must
|
|
21
43
|
* agree. No held mark, unknown status, missing bucket, or mismatched book can
|
|
@@ -119,6 +141,7 @@ export function prepareCapitalAction(action, spec, observation, budget) {
|
|
|
119
141
|
if (validateCapitalSizingPolicy(spec.capitalSizing).length > 0)
|
|
120
142
|
return { action, rejection: "capital_policy_invalid" };
|
|
121
143
|
const policy = spec.capitalSizing;
|
|
144
|
+
const limits = capitalLimitsFor(policy, action);
|
|
122
145
|
const adjustment = {
|
|
123
146
|
version: policy.version,
|
|
124
147
|
basis: "owned_collateral_spot_marked_negative_position_marks_only",
|
|
@@ -134,7 +157,7 @@ export function prepareCapitalAction(action, spec, observation, budget) {
|
|
|
134
157
|
!nonnegative(budget.openMarginMusd))
|
|
135
158
|
return reject("capital_budget_unavailable");
|
|
136
159
|
adjustment.conservativeEquityMusd = equity;
|
|
137
|
-
const ticket = Math.min(spec.risk.perTradeMarginMusd, (equity *
|
|
160
|
+
const ticket = Math.min(spec.risk.perTradeMarginMusd, (equity * limits.perTicketCapitalPct) / 100);
|
|
138
161
|
const room = Math.min(ticket, (equity * policy.totalCapitalPct) / 100 - budget.committedCapitalMusd, budget.cashAvailableMusd - (equity * policy.cashReservePct) / 100);
|
|
139
162
|
if (!positive(room))
|
|
140
163
|
return reject("capital_allocation_or_reserve_exhausted");
|
|
@@ -161,7 +184,7 @@ export function prepareCapitalAction(action, spec, observation, budget) {
|
|
|
161
184
|
const distance = Math.abs(mark - stop) / mark;
|
|
162
185
|
const fee = CAPITAL_FEE_BUFFER_BPS / 10_000;
|
|
163
186
|
const riskPerMargin = action.leverage * (distance + fee * (1 + stop / mark));
|
|
164
|
-
const riskBudget = (equity *
|
|
187
|
+
const riskBudget = (equity * limits.futuresRiskPct) / 100;
|
|
165
188
|
const margin = centsDown(Math.min(ticket, riskBudget / riskPerMargin, spec.limits.maxOpenMarginMusd - budget.openMarginMusd, room / (1 + action.leverage * fee)));
|
|
166
189
|
Object.assign(adjustment, {
|
|
167
190
|
proposedAmountMusd: action.marginMusd,
|
|
@@ -188,6 +211,7 @@ export function validateCapitalAction(action, spec, observation, budget, quote)
|
|
|
188
211
|
!nonnegative(budget.committedCapitalMusd) ||
|
|
189
212
|
!nonnegative(budget.openMarginMusd))
|
|
190
213
|
return "capital_budget_unavailable";
|
|
214
|
+
const limits = capitalLimitsFor(p, action);
|
|
191
215
|
let cost, allocated;
|
|
192
216
|
if (action.type === "pm_open") {
|
|
193
217
|
cost = allocated = action.stakeMusd;
|
|
@@ -227,7 +251,7 @@ export function validateCapitalAction(action, spec, observation, budget, quote)
|
|
|
227
251
|
const reward = (notional * favorable) / entry -
|
|
228
252
|
entryFee -
|
|
229
253
|
((notional * target) / entry) * feeRate;
|
|
230
|
-
if (risk > (equity *
|
|
254
|
+
if (risk > (equity * limits.futuresRiskPct) / 100 + 1e-8)
|
|
231
255
|
return "capital_quote_stop_risk_exceeded";
|
|
232
256
|
if (reward / risk + 1e-8 < p.minRewardRisk)
|
|
233
257
|
return "capital_quote_reward_risk_too_low";
|
|
@@ -235,7 +259,7 @@ export function validateCapitalAction(action, spec, observation, budget, quote)
|
|
|
235
259
|
if (!positive(cost) || !positive(allocated))
|
|
236
260
|
return "capital_quote_cost_evidence_missing";
|
|
237
261
|
if (cost >
|
|
238
|
-
Math.min(spec.risk.perTradeMarginMusd, (equity *
|
|
262
|
+
Math.min(spec.risk.perTradeMarginMusd, (equity * limits.perTicketCapitalPct) / 100) +
|
|
239
263
|
1e-8)
|
|
240
264
|
return "capital_ticket_cap_exceeded";
|
|
241
265
|
if (budget.committedCapitalMusd + cost >
|
package/dist/agent/client.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type PmPaperOpen, type PmPaperClose } from "../pmPaperV2.js";
|
|
1
2
|
import { AgentTrace, ApiResult } from "./types.js";
|
|
2
3
|
export declare const DEFAULT_BASE_URL = "https://api.coinrithm.com";
|
|
3
4
|
export declare const DEFAULT_REQUEST_TIMEOUT_MS = 30000;
|
|
@@ -86,6 +87,10 @@ export declare class CoinRithmClient {
|
|
|
86
87
|
side: string;
|
|
87
88
|
quantity: number;
|
|
88
89
|
}, trace?: AgentTrace): Promise<ApiResult>;
|
|
90
|
+
discoverPmPaperV2(query?: {
|
|
91
|
+
q?: string;
|
|
92
|
+
limit?: number;
|
|
93
|
+
}, trace?: AgentTrace): Promise<ApiResult>;
|
|
89
94
|
discoverPmMarkets(query?: {
|
|
90
95
|
q?: string;
|
|
91
96
|
source?: string;
|
|
@@ -143,6 +148,14 @@ export declare class CoinRithmClient {
|
|
|
143
148
|
agentTrace?: AgentTrace;
|
|
144
149
|
}): Promise<ApiResult>;
|
|
145
150
|
cancelSpotOrder(orderId: number, idempotencyKey?: string, trace?: AgentTrace): Promise<ApiResult>;
|
|
151
|
+
openPmPaperV2(body: PmPaperOpen): Promise<ApiResult>;
|
|
152
|
+
replayPmPaperV2Open(body: PmPaperOpen): Promise<ApiResult>;
|
|
153
|
+
closePmPaperV2(body: PmPaperClose): Promise<ApiResult>;
|
|
154
|
+
pmPaperV2Positions(query?: {
|
|
155
|
+
status?: "open";
|
|
156
|
+
beforeId?: number;
|
|
157
|
+
limit?: number;
|
|
158
|
+
}): Promise<ApiResult>;
|
|
146
159
|
openPmPosition(body: {
|
|
147
160
|
source: string;
|
|
148
161
|
slug: string;
|
package/dist/agent/client.js
CHANGED
|
@@ -1,9 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
//
|
|
3
|
-
// Auth: the user's own crk_live_ key from COINRITHM_API_KEY (env only — never
|
|
4
|
-
// from an agent file). 429 backs off on Retry-After; 401/403/409/422 are
|
|
5
|
-
// FAIL-CLOSED cycle outcomes (returned, not retried). fetch + sleep are
|
|
6
|
-
// injectable so tests run with no network and no real waits.
|
|
1
|
+
import { PM_PAPER_V2_BASE, } from "../pmPaperV2.js";
|
|
7
2
|
import { createHash } from "node:crypto";
|
|
8
3
|
import { setTimeout as sleep } from "node:timers/promises";
|
|
9
4
|
import { retryAfterSeconds } from "../retryAfter.js";
|
|
@@ -328,6 +323,9 @@ export class CoinRithmClient {
|
|
|
328
323
|
});
|
|
329
324
|
}
|
|
330
325
|
// ── prediction markets ───────────────────────────────────────────────────
|
|
326
|
+
discoverPmPaperV2(query, trace) {
|
|
327
|
+
return this.request("GET", "/api/agent/pm/v2/discover", { query, trace });
|
|
328
|
+
}
|
|
331
329
|
discoverPmMarkets(query, trace) {
|
|
332
330
|
return this.request("GET", "/api/agent/pm/discover", { query, trace });
|
|
333
331
|
}
|
|
@@ -367,6 +365,19 @@ export class CoinRithmClient {
|
|
|
367
365
|
trace,
|
|
368
366
|
});
|
|
369
367
|
}
|
|
368
|
+
// Explicit opt-in contract; API derives and authorizes the configured house tuple.
|
|
369
|
+
openPmPaperV2(body) {
|
|
370
|
+
return this.request("POST", `${PM_PAPER_V2_BASE}/open`, { body });
|
|
371
|
+
}
|
|
372
|
+
replayPmPaperV2Open(body) {
|
|
373
|
+
return this.request("POST", `${PM_PAPER_V2_BASE}/open/replay`, { body });
|
|
374
|
+
}
|
|
375
|
+
closePmPaperV2(body) {
|
|
376
|
+
return this.request("POST", `${PM_PAPER_V2_BASE}/close`, { body });
|
|
377
|
+
}
|
|
378
|
+
pmPaperV2Positions(query) {
|
|
379
|
+
return this.request("GET", `${PM_PAPER_V2_BASE}/positions`, { query });
|
|
380
|
+
}
|
|
370
381
|
openPmPosition(body) {
|
|
371
382
|
return this.request("POST", "/api/agent/pm/open", { body });
|
|
372
383
|
}
|
package/dist/agent/decision.d.ts
CHANGED
|
@@ -13,24 +13,24 @@ export declare const actionSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<
|
|
|
13
13
|
thesis: z.ZodOptional<z.ZodEffects<z.ZodAny, import("./types.js").Thesis | undefined, any>>;
|
|
14
14
|
}, "strict", z.ZodTypeAny, {
|
|
15
15
|
symbol: string;
|
|
16
|
-
side: "long" | "short";
|
|
17
16
|
type: "futures_open";
|
|
17
|
+
side: "long" | "short";
|
|
18
|
+
thesis?: import("./types.js").Thesis | undefined;
|
|
18
19
|
leverage?: any;
|
|
19
20
|
marginMusd?: any;
|
|
20
21
|
stopLossPrice?: any;
|
|
21
22
|
takeProfitPrice?: any;
|
|
22
|
-
thesis?: import("./types.js").Thesis | undefined;
|
|
23
23
|
confidence?: any;
|
|
24
24
|
rationaleSummary?: string | undefined;
|
|
25
25
|
}, {
|
|
26
26
|
symbol: string;
|
|
27
|
-
side: "long" | "short";
|
|
28
27
|
type: "futures_open";
|
|
28
|
+
side: "long" | "short";
|
|
29
|
+
thesis?: any;
|
|
29
30
|
leverage?: unknown;
|
|
30
31
|
marginMusd?: unknown;
|
|
31
32
|
stopLossPrice?: unknown;
|
|
32
33
|
takeProfitPrice?: unknown;
|
|
33
|
-
thesis?: any;
|
|
34
34
|
confidence?: unknown;
|
|
35
35
|
rationaleSummary?: string | undefined;
|
|
36
36
|
}>, z.ZodObject<{
|
|
@@ -42,16 +42,16 @@ export declare const actionSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<
|
|
|
42
42
|
thesis: z.ZodOptional<z.ZodEffects<z.ZodAny, import("./types.js").Thesis | undefined, any>>;
|
|
43
43
|
}, "strict", z.ZodTypeAny, {
|
|
44
44
|
type: "futures_close";
|
|
45
|
+
thesis?: import("./types.js").Thesis | undefined;
|
|
45
46
|
positionId?: any;
|
|
46
47
|
fraction?: any;
|
|
47
|
-
thesis?: import("./types.js").Thesis | undefined;
|
|
48
48
|
confidence?: any;
|
|
49
49
|
rationaleSummary?: string | undefined;
|
|
50
50
|
}, {
|
|
51
51
|
type: "futures_close";
|
|
52
|
+
thesis?: any;
|
|
52
53
|
positionId?: unknown;
|
|
53
54
|
fraction?: unknown;
|
|
54
|
-
thesis?: any;
|
|
55
55
|
confidence?: unknown;
|
|
56
56
|
rationaleSummary?: string | undefined;
|
|
57
57
|
}>, z.ZodObject<{
|
|
@@ -64,18 +64,18 @@ export declare const actionSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<
|
|
|
64
64
|
thesis: z.ZodOptional<z.ZodEffects<z.ZodAny, import("./types.js").Thesis | undefined, any>>;
|
|
65
65
|
}, "strict", z.ZodTypeAny, {
|
|
66
66
|
type: "futures_set_sltp";
|
|
67
|
+
thesis?: import("./types.js").Thesis | undefined;
|
|
68
|
+
positionId?: any;
|
|
67
69
|
stopLossPrice?: any;
|
|
68
70
|
takeProfitPrice?: any;
|
|
69
|
-
positionId?: any;
|
|
70
|
-
thesis?: import("./types.js").Thesis | undefined;
|
|
71
71
|
confidence?: any;
|
|
72
72
|
rationaleSummary?: string | undefined;
|
|
73
73
|
}, {
|
|
74
74
|
type: "futures_set_sltp";
|
|
75
|
+
thesis?: any;
|
|
76
|
+
positionId?: unknown;
|
|
75
77
|
stopLossPrice?: unknown;
|
|
76
78
|
takeProfitPrice?: unknown;
|
|
77
|
-
positionId?: unknown;
|
|
78
|
-
thesis?: any;
|
|
79
79
|
confidence?: unknown;
|
|
80
80
|
rationaleSummary?: string | undefined;
|
|
81
81
|
}>, z.ZodObject<{
|
|
@@ -91,24 +91,24 @@ export declare const actionSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<
|
|
|
91
91
|
thesis: z.ZodOptional<z.ZodEffects<z.ZodAny, import("./types.js").Thesis | undefined, any>>;
|
|
92
92
|
}, "strict", z.ZodTypeAny, {
|
|
93
93
|
symbol: string;
|
|
94
|
+
type: "spot_order";
|
|
94
95
|
side: "buy" | "sell";
|
|
95
96
|
orderType: "limit" | "market" | "stop";
|
|
96
|
-
|
|
97
|
+
thesis?: import("./types.js").Thesis | undefined;
|
|
97
98
|
quantity?: any;
|
|
98
99
|
limitPrice?: any;
|
|
99
100
|
stopPrice?: any;
|
|
100
|
-
thesis?: import("./types.js").Thesis | undefined;
|
|
101
101
|
confidence?: any;
|
|
102
102
|
rationaleSummary?: string | undefined;
|
|
103
103
|
}, {
|
|
104
104
|
symbol: string;
|
|
105
|
+
type: "spot_order";
|
|
105
106
|
side: "buy" | "sell";
|
|
106
107
|
orderType: "limit" | "market" | "stop";
|
|
107
|
-
|
|
108
|
+
thesis?: any;
|
|
108
109
|
quantity?: unknown;
|
|
109
110
|
limitPrice?: unknown;
|
|
110
111
|
stopPrice?: unknown;
|
|
111
|
-
thesis?: any;
|
|
112
112
|
confidence?: unknown;
|
|
113
113
|
rationaleSummary?: string | undefined;
|
|
114
114
|
}>, z.ZodObject<{
|
|
@@ -145,9 +145,9 @@ export declare const actionSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<
|
|
|
145
145
|
source?: string | undefined;
|
|
146
146
|
slug?: string | undefined;
|
|
147
147
|
outcomeExternalMarketId?: string | undefined;
|
|
148
|
-
stakeMusd?: any;
|
|
149
148
|
forecastProbability?: number | undefined;
|
|
150
149
|
thesis?: import("./types.js").Thesis | undefined;
|
|
150
|
+
stakeMusd?: any;
|
|
151
151
|
confidence?: any;
|
|
152
152
|
rationaleSummary?: string | undefined;
|
|
153
153
|
ref?: string | undefined;
|
|
@@ -156,9 +156,9 @@ export declare const actionSchema: z.ZodDiscriminatedUnion<"type", [z.ZodObject<
|
|
|
156
156
|
source?: string | undefined;
|
|
157
157
|
slug?: string | undefined;
|
|
158
158
|
outcomeExternalMarketId?: string | undefined;
|
|
159
|
-
stakeMusd?: unknown;
|
|
160
159
|
forecastProbability?: any;
|
|
161
160
|
thesis?: any;
|
|
161
|
+
stakeMusd?: unknown;
|
|
162
162
|
confidence?: unknown;
|
|
163
163
|
rationaleSummary?: string | undefined;
|
|
164
164
|
ref?: string | undefined;
|
|
@@ -548,3 +548,8 @@ export type ParseDecisionResult = {
|
|
|
548
548
|
actionsStringDiagnostic?: ActionsStringDiagnostic;
|
|
549
549
|
};
|
|
550
550
|
export declare function parseDecision(text: string): ParseDecisionResult;
|
|
551
|
+
/** Only the trusted host selects a versioned contract; default stays legacy. */
|
|
552
|
+
export declare function parseDecisionForContract(text: string, contract?: "pm_paper_v2"): ParseDecisionResult | {
|
|
553
|
+
ok: true;
|
|
554
|
+
decision: z.infer<typeof import("./pmPaperDecision.js").pmPaperDecisionSchema>;
|
|
555
|
+
};
|
package/dist/agent/decision.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { parsePmPaperDecision } from "./pmPaperDecision.js";
|
|
1
2
|
// Parse the model's single text response into a strict, structured Decision.
|
|
2
3
|
// Accepts futures + spot + prediction-market actions. Anything else — invalid
|
|
3
4
|
// JSON, an unknown action type, a free-form endpoint/tool name, extra unknown
|
|
@@ -479,3 +480,9 @@ export function parseDecision(text) {
|
|
|
479
480
|
},
|
|
480
481
|
};
|
|
481
482
|
}
|
|
483
|
+
/** Only the trusted host selects a versioned contract; default stays legacy. */
|
|
484
|
+
export function parseDecisionForContract(text, contract) {
|
|
485
|
+
return contract === "pm_paper_v2"
|
|
486
|
+
? parsePmPaperDecision(text)
|
|
487
|
+
: parseDecision(text);
|
|
488
|
+
}
|
|
@@ -51,6 +51,7 @@ export declare function pmCoinHorizonOf(item: {
|
|
|
51
51
|
}, refMs: number): PmCoinHorizon | null;
|
|
52
52
|
/** Event key shared by pm_open actions, held positions and markets. */
|
|
53
53
|
export declare function pmEventKey(source: string, slug: string): string;
|
|
54
|
+
export declare const TRIGGER_PRICE_EPS = 1e-8;
|
|
54
55
|
/**
|
|
55
56
|
* True when a thesis says, in so many words, that it is betting AGAINST the
|
|
56
57
|
* outcome the action is buying. Deliberately narrow: it fires only when the
|
|
@@ -60,7 +60,7 @@ const PM_MIN_STAKE_MUSD = 10; // server minimum prediction-market stake
|
|
|
60
60
|
// Match backend-v2 validateSlTpPrices, including its boundary tolerance. This
|
|
61
61
|
// preflight uses observed evidence only; the API still checks a fresh mark and
|
|
62
62
|
// locked position at execution. Older observations can omit these prices.
|
|
63
|
-
const TRIGGER_PRICE_EPS = 1e-8;
|
|
63
|
+
export const TRIGGER_PRICE_EPS = 1e-8;
|
|
64
64
|
function validateTriggerUpdate(action, pos) {
|
|
65
65
|
// executeAction omits null as well as undefined; neither clears a trigger in
|
|
66
66
|
// this runner. Check the resulting state, including retained protection.
|
package/dist/agent/engine.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ export { runCycle, type RunnerDeps } from "./runner.js";
|
|
|
2
2
|
export { buildAgentDefinitionSnapshot, type AgentDefinitionSnapshot, } from "./definitionSnapshot.js";
|
|
3
3
|
export { DECISION_INPUT_MAX_BYTES, sanitizeDecisionInputRecord, type DecisionInputRecord, } from "./decisionReceipt.js";
|
|
4
4
|
export { selectProvider, providerForRoute, classifyProviderFailure, anthropicUsage, type ProviderUsage, type ProviderEnv, type ProviderRouteOptions, type Provider, type DecideInput, type DecideResult, type DecideRouteAttempt, type DecideRouteMeta, } from "./providers.js";
|
|
5
|
-
export { parseDecision, ACTIONS_STRING_DIAGNOSTICS, type ActionsStringDiagnostic, } from "./decision.js";
|
|
5
|
+
export { parseDecision, parseDecisionForContract, ACTIONS_STRING_DIAGNOSTICS, type ActionsStringDiagnostic, } from "./decision.js";
|
|
6
6
|
export { chatShapeFor, buildChatBody, canRetrySuperToolOutput, type ChatShape, } from "./providerCapabilities.js";
|
|
7
7
|
export { probeDecisionContract, type ProbeRoute, type ProbeDecisionResult, } from "./decisionProbe.js";
|
|
8
8
|
export { CoinRithmClient } from "./client.js";
|
|
@@ -14,3 +14,5 @@ export { makeRunId } from "./runEvidence.js";
|
|
|
14
14
|
export { parseCadenceMs } from "./util.js";
|
|
15
15
|
export { BENCHMARK_AGENTS, BENCHMARK_STRATEGIES, decideMechanical, isBenchmarkStrategy, type BenchmarkStrategy, type BenchmarkAgentDefinition, } from "./mechanical.js";
|
|
16
16
|
export type { AgentSpec, RunState, CycleResult, OpportunityReport, PostedOpportunity, PlannedAction, Venue, ProviderName, ModelConfig, } from "./types.js";
|
|
17
|
+
export { readPmHousePolicies, selectPmHousePolicy, type PmHousePolicy, } from "./pmPaperPolicy.js";
|
|
18
|
+
export { runPmPaperCycle, type PmPaperCycleResult } from "./pmPaperCycle.js";
|
package/dist/agent/engine.js
CHANGED
|
@@ -9,7 +9,7 @@ export { runCycle } from "./runner.js";
|
|
|
9
9
|
export { buildAgentDefinitionSnapshot, } from "./definitionSnapshot.js";
|
|
10
10
|
export { DECISION_INPUT_MAX_BYTES, sanitizeDecisionInputRecord, } from "./decisionReceipt.js";
|
|
11
11
|
export { selectProvider, providerForRoute, classifyProviderFailure, anthropicUsage, } from "./providers.js";
|
|
12
|
-
export { parseDecision, ACTIONS_STRING_DIAGNOSTICS, } from "./decision.js";
|
|
12
|
+
export { parseDecision, parseDecisionForContract, ACTIONS_STRING_DIAGNOSTICS, } from "./decision.js";
|
|
13
13
|
// Reliability slice A: the declarative request-capability table and the
|
|
14
14
|
// representative decision probe (route eligibility = a REAL parsed decision,
|
|
15
15
|
// never a bare HTTP 200 — the 62f3a12 lesson).
|
|
@@ -25,3 +25,5 @@ export { parseCadenceMs } from "./util.js";
|
|
|
25
25
|
// Mechanical BENCHMARK baseline agents (sol #7): the deterministic, non-LLM
|
|
26
26
|
// reference line the scheduler seeds into agent_runtime and the runner executes.
|
|
27
27
|
export { BENCHMARK_AGENTS, BENCHMARK_STRATEGIES, decideMechanical, isBenchmarkStrategy, } from "./mechanical.js";
|
|
28
|
+
export { readPmHousePolicies, selectPmHousePolicy, } from "./pmPaperPolicy.js";
|
|
29
|
+
export { runPmPaperCycle } from "./pmPaperCycle.js";
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ApiResult, ProposedAction } from "./types.js";
|
|
2
|
+
/** Future v2 producer contract; legacy responses retain their existing res.ok
|
|
3
|
+
* meaning. A filled exit closes exposure, even while accounting remains pending. */
|
|
4
|
+
export declare function executionOutcome(action: ProposedAction, result: ApiResult): {
|
|
5
|
+
executed: boolean;
|
|
6
|
+
pending: boolean;
|
|
7
|
+
newWrite: boolean;
|
|
8
|
+
v2: boolean;
|
|
9
|
+
replayed: boolean;
|
|
10
|
+
};
|
|
11
|
+
export declare function exitOutcomeMetadata(outcome: ReturnType<typeof executionOutcome>): {
|
|
12
|
+
executionPending: boolean;
|
|
13
|
+
executionReplayed: boolean;
|
|
14
|
+
writeRecorded: boolean;
|
|
15
|
+
} | {
|
|
16
|
+
executionPending?: undefined;
|
|
17
|
+
executionReplayed?: undefined;
|
|
18
|
+
writeRecorded?: undefined;
|
|
19
|
+
};
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { asObj } from "./extract.js";
|
|
2
|
+
/** Future v2 producer contract; legacy responses retain their existing res.ok
|
|
3
|
+
* meaning. A filled exit closes exposure, even while accounting remains pending. */
|
|
4
|
+
export function executionOutcome(action, result) {
|
|
5
|
+
const body = asObj(result.data);
|
|
6
|
+
if (action.type !== "futures_close" ||
|
|
7
|
+
body.executionModel !== "hl_paper_v2") {
|
|
8
|
+
return {
|
|
9
|
+
executed: result.ok,
|
|
10
|
+
pending: false,
|
|
11
|
+
newWrite: result.ok,
|
|
12
|
+
v2: false,
|
|
13
|
+
replayed: false,
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
const intent = asObj(body.intent);
|
|
17
|
+
const common = result.ok &&
|
|
18
|
+
Number.isSafeInteger(body.positionId) &&
|
|
19
|
+
body.positionId === action.positionId &&
|
|
20
|
+
(action.fraction === undefined || action.fraction === 1) &&
|
|
21
|
+
body.accepted === true &&
|
|
22
|
+
typeof body.replayed === "boolean" &&
|
|
23
|
+
typeof intent.id === "string" &&
|
|
24
|
+
/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(intent.id);
|
|
25
|
+
const pending = !!common &&
|
|
26
|
+
result.status === 202 &&
|
|
27
|
+
body.executed === false &&
|
|
28
|
+
typeof intent.status === "string" &&
|
|
29
|
+
typeof body.accountingStatus === "string" &&
|
|
30
|
+
["pending", "leased", "retry", "manual_attention"].includes(intent.status) &&
|
|
31
|
+
["open", "pending", "manual_attention"].includes(body.accountingStatus);
|
|
32
|
+
const executed = !!common &&
|
|
33
|
+
result.status === 200 &&
|
|
34
|
+
body.executed === true &&
|
|
35
|
+
intent.status === "filled" &&
|
|
36
|
+
typeof body.accountingStatus === "string" &&
|
|
37
|
+
["pending", "settled", "manual_attention"].includes(body.accountingStatus);
|
|
38
|
+
return {
|
|
39
|
+
executed,
|
|
40
|
+
pending,
|
|
41
|
+
newWrite: (executed || pending) && body.replayed === false,
|
|
42
|
+
v2: true,
|
|
43
|
+
replayed: body.replayed === true,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
export function exitOutcomeMetadata(outcome) {
|
|
47
|
+
return outcome.v2
|
|
48
|
+
? {
|
|
49
|
+
executionPending: outcome.pending,
|
|
50
|
+
executionReplayed: outcome.replayed,
|
|
51
|
+
writeRecorded: outcome.newWrite,
|
|
52
|
+
}
|
|
53
|
+
: {};
|
|
54
|
+
}
|
|
@@ -34,3 +34,16 @@ export interface FuturesEntryPreflightRejection {
|
|
|
34
34
|
* - referenceRequired false.
|
|
35
35
|
*/
|
|
36
36
|
export declare function futuresEntryPreflight(action: ProposedAction, observation: Observation): FuturesEntryPreflightRejection | null;
|
|
37
|
+
/** Prompt-only choices from the SAME reference preflight, not trade approval.
|
|
38
|
+
* Keep unknown evidence and held-position exceptions distinct from eligibility.
|
|
39
|
+
* Watch rows, setup receipts and all execution/risk checks remain unchanged. */
|
|
40
|
+
export declare function futuresEntryChoices(observation: Observation): {
|
|
41
|
+
candidates: Array<{
|
|
42
|
+
symbol: string;
|
|
43
|
+
reference: "eligible" | "unknown" | "not_required" | "held_position";
|
|
44
|
+
}>;
|
|
45
|
+
blocked: Array<{
|
|
46
|
+
symbol: string;
|
|
47
|
+
code: FuturesEntryPreflightRejection["code"];
|
|
48
|
+
}>;
|
|
49
|
+
};
|
|
@@ -66,11 +66,17 @@ export function futuresEntryEligibilityOf(marketContext) {
|
|
|
66
66
|
export function futuresEntryPreflight(action, observation) {
|
|
67
67
|
if (action.type !== "futures_open")
|
|
68
68
|
return null;
|
|
69
|
-
|
|
70
|
-
|
|
69
|
+
return futuresReferenceBlock(action.symbol, observation);
|
|
70
|
+
}
|
|
71
|
+
function holdsFutures(symbol, observation) {
|
|
72
|
+
const base = baseSymbol(symbol);
|
|
73
|
+
return (observation.openPositions ?? []).some((p) => p.venue === "futures" &&
|
|
71
74
|
(p.status ?? "open") === "open" &&
|
|
72
75
|
baseSymbol(p.symbol) === base);
|
|
73
|
-
|
|
76
|
+
}
|
|
77
|
+
function futuresReferenceBlock(symbol, observation) {
|
|
78
|
+
const base = baseSymbol(symbol);
|
|
79
|
+
if (holdsFutures(symbol, observation))
|
|
74
80
|
return null;
|
|
75
81
|
const entry = observation.watch.find((w) => baseSymbol(w.symbol) === base);
|
|
76
82
|
const e = entry?.futuresEntryEligibility;
|
|
@@ -80,11 +86,43 @@ export function futuresEntryPreflight(action, observation) {
|
|
|
80
86
|
if (e.status === "reference_stale") {
|
|
81
87
|
return {
|
|
82
88
|
code: "futures_reference_stale",
|
|
83
|
-
reason: `${
|
|
89
|
+
reason: `${symbol}: the perpetual reference${e.venue ? ` (${e.venue})` : ""} is stale or unusable for a NEW futures open${when} (too old, or its refresh time is missing, invalid or in the future); the server would refuse it (perpetual_reference_stale). Trade another coin or wait for a fresh reference.`,
|
|
84
90
|
};
|
|
85
91
|
}
|
|
86
92
|
return {
|
|
87
93
|
code: "futures_reference_unavailable",
|
|
88
|
-
reason: `${
|
|
94
|
+
reason: `${symbol}: CoinRithm has no supported perpetual reference for this coin${when}, so the server refuses a NEW futures open (perpetual_reference_unavailable). Use spot for it, or another coin for futures.`,
|
|
89
95
|
};
|
|
90
96
|
}
|
|
97
|
+
/** Prompt-only choices from the SAME reference preflight, not trade approval.
|
|
98
|
+
* Keep unknown evidence and held-position exceptions distinct from eligibility.
|
|
99
|
+
* Watch rows, setup receipts and all execution/risk checks remain unchanged. */
|
|
100
|
+
export function futuresEntryChoices(observation) {
|
|
101
|
+
const candidates = [];
|
|
102
|
+
const blocked = [];
|
|
103
|
+
const seen = new Set();
|
|
104
|
+
for (const entry of observation.watch) {
|
|
105
|
+
const base = baseSymbol(entry.symbol);
|
|
106
|
+
if (seen.has(base))
|
|
107
|
+
continue;
|
|
108
|
+
seen.add(base);
|
|
109
|
+
const rejection = futuresReferenceBlock(entry.symbol, observation);
|
|
110
|
+
if (rejection) {
|
|
111
|
+
blocked.push({ symbol: entry.symbol, code: rejection.code });
|
|
112
|
+
}
|
|
113
|
+
else {
|
|
114
|
+
const e = entry.futuresEntryEligibility;
|
|
115
|
+
candidates.push({
|
|
116
|
+
symbol: entry.symbol,
|
|
117
|
+
reference: holdsFutures(entry.symbol, observation)
|
|
118
|
+
? "held_position"
|
|
119
|
+
: !e
|
|
120
|
+
? "unknown"
|
|
121
|
+
: !e.referenceRequired
|
|
122
|
+
? "not_required"
|
|
123
|
+
: "eligible",
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
return { candidates, blocked };
|
|
128
|
+
}
|
package/dist/agent/observe.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CoinRithmClient } from "./client.js";
|
|
2
|
-
import { AgentSpec, RunState, Observation, OpenInterestContext, PositioningContext, LiquidationContext, MacroContext, ChainTvlContext, StablecoinSupplyContext, DepthContext, FundingByVenueContext, AgentTrace, PmCalibration, WhaleContext } from "./types.js";
|
|
2
|
+
import { AgentSpec, RunState, Observation, PmMarket, OpenInterestContext, PositioningContext, LiquidationContext, MacroContext, ChainTvlContext, StablecoinSupplyContext, DepthContext, FundingByVenueContext, AgentTrace, PmCalibration, WhaleContext } from "./types.js";
|
|
3
3
|
export interface ObserveOutput {
|
|
4
4
|
observation: Observation;
|
|
5
5
|
skip?: string;
|
|
@@ -34,6 +34,7 @@ export declare function depthOf(m: Record<string, unknown>, nowMs?: number): Dep
|
|
|
34
34
|
export declare function chainTvlOf(m: Record<string, unknown>, nowMs?: number): ChainTvlContext | undefined;
|
|
35
35
|
export declare function stablecoinSupplyOf(m: Record<string, unknown>, nowMs?: number): StablecoinSupplyContext | undefined;
|
|
36
36
|
export declare function macroOf(m: Record<string, unknown>, nowMs?: number): MacroContext | undefined;
|
|
37
|
+
export declare function expandPmMarkets(discData: unknown, heldPmKeys: Set<string>): Omit<PmMarket, "ref">[];
|
|
37
38
|
/** Bench-only observation overrides; live callers pass none. */
|
|
38
39
|
export interface ObserveOptions {
|
|
39
40
|
/** Read the curated PM board (depth 30, churn removed, calibration read)
|
package/dist/agent/observe.js
CHANGED
|
@@ -967,7 +967,7 @@ function titleMentionsCoin(title, symbol) {
|
|
|
967
967
|
// backend flagged not-openable (eligible === false) and markets the agent already
|
|
968
968
|
// holds (heldPmKeys). Shared by the primary board fetch and the crypto-targeted
|
|
969
969
|
// secondary fetch so both go through the exact same filters.
|
|
970
|
-
function expandPmMarkets(discData, heldPmKeys) {
|
|
970
|
+
export function expandPmMarkets(discData, heldPmKeys) {
|
|
971
971
|
const dd = asObj(discData);
|
|
972
972
|
return (asArr(dd.data ?? dd.markets ?? dd.results)
|
|
973
973
|
.map(asObj)
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** Immutable entry identity excludes aliases and the opposite order side.
|
|
2
|
+
* Unknown identities hold new entries, but do not block closing/replaying. */
|
|
3
|
+
export declare function pmHeldNativeMarkets(positions: readonly unknown[]): {
|
|
4
|
+
keys: Set<string>;
|
|
5
|
+
complete: boolean;
|
|
6
|
+
};
|
|
7
|
+
export declare function pmCandidateWithinHorizon(candidate: {
|
|
8
|
+
nativeEndAt: string | null;
|
|
9
|
+
}, maxEndDays: number | undefined, nowMs: number): boolean;
|
|
10
|
+
/** Dedicated v2 discovery only. Filter and deduplicate before the model cap;
|
|
11
|
+
* the legacy expansion and legacy agent discovery remain unchanged. */
|
|
12
|
+
export declare function pmPaperCandidates(payload: unknown, held: ReadonlySet<string>, maxEndDays: number | undefined, nowMs: number): (Omit<import("./types.js").PmMarket, "ref"> & {
|
|
13
|
+
nativeMarketKey: string;
|
|
14
|
+
nativeEndAt: string | null;
|
|
15
|
+
nativeEndBasis: "gamma_market_endDate" | "kalshi_market_close_time";
|
|
16
|
+
settlementTimeKnown: false;
|
|
17
|
+
})[];
|