@coinrithm/mcp-trading 0.2.0 → 0.3.0
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 +32 -0
- package/README.md +2 -2
- package/dist/agent/act.d.ts +4 -0
- package/dist/agent/act.js +58 -9
- package/dist/agent/capabilityGuard.d.ts +2 -0
- package/dist/agent/capabilityGuard.js +131 -0
- package/dist/agent/cli.d.ts +21 -0
- package/dist/agent/cli.js +28 -6
- package/dist/agent/client.d.ts +107 -0
- package/dist/agent/client.js +26 -0
- package/dist/agent/decision.d.ts +137 -0
- package/dist/agent/decision.js +37 -4
- package/dist/agent/decisionValidator.d.ts +16 -0
- package/dist/agent/decisionValidator.js +118 -10
- package/dist/agent/engine.d.ts +10 -0
- package/dist/agent/engine.js +16 -0
- package/dist/agent/extract.d.ts +4 -0
- package/dist/agent/frontmatter.d.ts +5 -0
- package/dist/agent/index.d.ts +2 -0
- package/dist/agent/indicators.d.ts +44 -0
- package/dist/agent/indicators.js +135 -0
- package/dist/agent/manifest.d.ts +15 -0
- package/dist/agent/mergeRules.d.ts +11 -0
- package/dist/agent/observe.d.ts +7 -0
- package/dist/agent/observe.js +142 -8
- package/dist/agent/prompt.d.ts +3 -0
- package/dist/agent/prompt.js +39 -8
- package/dist/agent/providers.d.ts +25 -0
- package/dist/agent/providers.js +10 -1
- package/dist/agent/resolve.d.ts +11 -0
- package/dist/agent/resolve.js +12 -3
- package/dist/agent/runEvidence.d.ts +6 -0
- package/dist/agent/runner.d.ts +19 -0
- package/dist/agent/runner.js +102 -19
- package/dist/agent/skill.d.ts +12 -0
- package/dist/agent/skill.js +6 -2
- package/dist/agent/skillValidator.d.ts +7 -0
- package/dist/agent/state.d.ts +7 -0
- package/dist/agent/state.js +3 -1
- package/dist/agent/strictLint.d.ts +3 -0
- package/dist/agent/strictLint.js +2 -1
- package/dist/agent/templates.d.ts +14 -0
- package/dist/agent/types.d.ts +286 -0
- package/dist/agent/types.js +39 -1
- package/dist/agent/util.d.ts +13 -0
- package/dist/agent/util.js +4 -0
- package/dist/agent/version.d.ts +11 -0
- package/dist/agent/version.js +1 -1
- package/dist/client.d.ts +162 -0
- package/dist/http.d.ts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/tools.d.ts +3 -0
- package/dist/version.d.ts +1 -0
- package/package.json +7 -2
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { AgentSpec, ParsedSkill, ResolvedAgent, ResolveIssue } from "./types.js";
|
|
2
|
+
export declare function buildSpec(raw: Record<string, unknown>): AgentSpec;
|
|
3
|
+
export declare function parseSkill(text: string): ParsedSkill;
|
|
4
|
+
export declare function loadSkill(path: string): ParsedSkill;
|
|
5
|
+
export interface LoadedAgent {
|
|
6
|
+
resolved: ResolvedAgent;
|
|
7
|
+
spec: AgentSpec;
|
|
8
|
+
body: string;
|
|
9
|
+
raw: Record<string, unknown>;
|
|
10
|
+
lint: ResolveIssue[];
|
|
11
|
+
}
|
|
12
|
+
export declare function loadAgent(inputPath: string, mode?: "self-host" | "hosted"): LoadedAgent;
|
package/dist/agent/skill.js
CHANGED
|
@@ -3,6 +3,7 @@ import { parseFrontmatter } from "./frontmatter.js";
|
|
|
3
3
|
import { VENUES, PROVIDERS, ALLOWED_CAPABILITIES, } from "./types.js";
|
|
4
4
|
import { resolveAgent, ResolveError } from "./resolve.js";
|
|
5
5
|
import { strictLint } from "./strictLint.js";
|
|
6
|
+
import { checkCapabilityDrift } from "./capabilityGuard.js";
|
|
6
7
|
// Safe defaults for the OPTIONAL policy blocks. A minimal self-host skill
|
|
7
8
|
// (name/description/spec/trigger/model/venues/risk) runs under these. Hosted
|
|
8
9
|
// mode requires them to be explicit (see skillValidator).
|
|
@@ -83,6 +84,7 @@ export function buildSpec(raw) {
|
|
|
83
84
|
maxConcurrentPositions: num(risk.maxConcurrentPositions, 0),
|
|
84
85
|
requireStopLoss: bool(risk.requireStopLoss, true),
|
|
85
86
|
watchlist: strArr(risk.watchlist),
|
|
87
|
+
blocklist: strArr(risk.blocklist),
|
|
86
88
|
},
|
|
87
89
|
limits: {
|
|
88
90
|
maxTradesPerDay: num(limits.maxTradesPerDay, DEFAULT_LIMITS.maxTradesPerDay),
|
|
@@ -124,9 +126,11 @@ export function loadSkill(path) {
|
|
|
124
126
|
export function loadAgent(inputPath, mode = "self-host") {
|
|
125
127
|
const resolved = resolveAgent(inputPath);
|
|
126
128
|
const raw = resolved.rawFrontmatter;
|
|
127
|
-
const
|
|
129
|
+
const spec = buildSpec(raw);
|
|
130
|
+
// strictLint = frontmatter keys/enums; capability drift = prose references to
|
|
131
|
+
// venues/actions/caps the runner (or this agent's venues) does not support.
|
|
132
|
+
const lint = [...strictLint(raw), ...checkCapabilityDrift(resolved, spec)];
|
|
128
133
|
if (mode === "hosted" && lint.length)
|
|
129
134
|
throw new ResolveError(lint);
|
|
130
|
-
const spec = buildSpec(raw);
|
|
131
135
|
return { resolved, spec, body: resolved.mergedProse, raw, lint };
|
|
132
136
|
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ParsedSkill, ValidationResult } from "./types.js";
|
|
2
|
+
export type SkillValidationMode = "self-host" | "hosted";
|
|
3
|
+
export interface SkillValidation {
|
|
4
|
+
valid: boolean;
|
|
5
|
+
issues: ValidationResult[];
|
|
6
|
+
}
|
|
7
|
+
export declare function validateSkill(parsed: ParsedSkill, mode?: SkillValidationMode): SkillValidation;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { RunState, AgentSpec } from "./types.js";
|
|
2
|
+
export declare function newState(runId: string): RunState;
|
|
3
|
+
export declare function loadState(file: string | undefined, runId: string): RunState;
|
|
4
|
+
export declare function saveState(file: string | undefined, state: RunState): void;
|
|
5
|
+
export declare function rollDay(state: RunState): RunState;
|
|
6
|
+
export declare function accrueRealized(state: RunState, closedTrades: Record<string, unknown>[]): void;
|
|
7
|
+
export declare function checkKillSwitch(spec: AgentSpec, state: RunState): string | null;
|
package/dist/agent/state.js
CHANGED
|
@@ -42,7 +42,9 @@ export function loadState(file, runId) {
|
|
|
42
42
|
...base,
|
|
43
43
|
...parsed,
|
|
44
44
|
seen: Array.isArray(parsed.seen) ? parsed.seen : [],
|
|
45
|
-
intentSeq: parsed.intentSeq && typeof parsed.intentSeq === "object"
|
|
45
|
+
intentSeq: parsed.intentSeq && typeof parsed.intentSeq === "object" && !Array.isArray(parsed.intentSeq)
|
|
46
|
+
? parsed.intentSeq
|
|
47
|
+
: {},
|
|
46
48
|
});
|
|
47
49
|
}
|
|
48
50
|
return newState(runId);
|
package/dist/agent/strictLint.js
CHANGED
|
@@ -34,6 +34,7 @@ const ALLOWED_KEYS = {
|
|
|
34
34
|
"maxConcurrentPositions",
|
|
35
35
|
"requireStopLoss",
|
|
36
36
|
"watchlist",
|
|
37
|
+
"blocklist",
|
|
37
38
|
],
|
|
38
39
|
sizing: null,
|
|
39
40
|
limits: [
|
|
@@ -58,7 +59,7 @@ const ALLOWED_KEYS = {
|
|
|
58
59
|
],
|
|
59
60
|
objective: ["primary", "secondary", "horizon"],
|
|
60
61
|
};
|
|
61
|
-
function levenshtein(a, b) {
|
|
62
|
+
export function levenshtein(a, b) {
|
|
62
63
|
const m = a.length;
|
|
63
64
|
const n = b.length;
|
|
64
65
|
const d = Array.from({ length: n + 1 }, (_, i) => i);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type PresetName = "conservative" | "balanced" | "bold";
|
|
2
|
+
export declare const PRESET_NAMES: PresetName[];
|
|
3
|
+
export interface AgentTemplate {
|
|
4
|
+
frontmatter: Record<string, unknown>;
|
|
5
|
+
body: string;
|
|
6
|
+
}
|
|
7
|
+
export declare function buildAgentObject(name: string, preset: PresetName): AgentTemplate;
|
|
8
|
+
export declare function renderFolderOfOne(name: string, preset: PresetName): string;
|
|
9
|
+
export declare function renderCoinrithmPin(): string;
|
|
10
|
+
export declare function renderRuntime(model: unknown, trigger: unknown): string;
|
|
11
|
+
export interface EjectResult {
|
|
12
|
+
files: Record<string, string>;
|
|
13
|
+
}
|
|
14
|
+
export declare function ejectFiles(fm: Record<string, unknown>, body: string): EjectResult;
|
|
@@ -0,0 +1,286 @@
|
|
|
1
|
+
import { IndicatorSet } from "./indicators.js";
|
|
2
|
+
export declare const SPEC_VERSION = "coinrithm.agent.v1";
|
|
3
|
+
export type Venue = "spot" | "futures" | "pm";
|
|
4
|
+
export declare const VENUES: readonly Venue[];
|
|
5
|
+
export declare const ACTION_TYPES: readonly ["futures_open", "futures_close", "futures_set_sltp", "spot_order", "spot_cancel", "pm_open"];
|
|
6
|
+
export type ActionType = (typeof ACTION_TYPES)[number];
|
|
7
|
+
export type ProviderName = "anthropic" | "openai" | "groq" | "nvidia" | "openai-compatible";
|
|
8
|
+
export declare const PROVIDERS: readonly ProviderName[];
|
|
9
|
+
export interface ModelConfig {
|
|
10
|
+
provider: ProviderName;
|
|
11
|
+
name: string;
|
|
12
|
+
baseUrl?: string;
|
|
13
|
+
}
|
|
14
|
+
export interface TriggerConfig {
|
|
15
|
+
cadence: string;
|
|
16
|
+
timezone?: string;
|
|
17
|
+
}
|
|
18
|
+
export interface RiskConfig {
|
|
19
|
+
maxLeverage: number;
|
|
20
|
+
perTradeMarginMusd: number;
|
|
21
|
+
maxConcurrentPositions: number;
|
|
22
|
+
requireStopLoss: boolean;
|
|
23
|
+
watchlist: string[];
|
|
24
|
+
blocklist?: string[];
|
|
25
|
+
}
|
|
26
|
+
export interface LimitsConfig {
|
|
27
|
+
maxTradesPerDay: number;
|
|
28
|
+
maxWritesPerCycle: number;
|
|
29
|
+
maxDailyLossMusd: number;
|
|
30
|
+
maxOpenMarginMusd: number;
|
|
31
|
+
}
|
|
32
|
+
export interface AbstentionConfig {
|
|
33
|
+
onStaleData: boolean;
|
|
34
|
+
onWeakSignal: boolean;
|
|
35
|
+
onMissingQuote: boolean;
|
|
36
|
+
onInsufficientBalance: boolean;
|
|
37
|
+
minConfidence: number;
|
|
38
|
+
}
|
|
39
|
+
export interface SyncConfig {
|
|
40
|
+
requirePollBeforeWrite: boolean;
|
|
41
|
+
}
|
|
42
|
+
export interface KillSwitchConfig {
|
|
43
|
+
maxDrawdownMusd: number;
|
|
44
|
+
maxConsecutiveRejects: number;
|
|
45
|
+
maxConsecutiveModelFailures: number;
|
|
46
|
+
onRateLimitPressure: boolean;
|
|
47
|
+
}
|
|
48
|
+
export declare const OBJECTIVE_PRIMARIES: readonly ["realized_pnl", "risk_adjusted", "drawdown_control", "calibration"];
|
|
49
|
+
export type ObjectivePrimary = (typeof OBJECTIVE_PRIMARIES)[number];
|
|
50
|
+
export interface ObjectiveConfig {
|
|
51
|
+
primary: ObjectivePrimary;
|
|
52
|
+
secondary: string[];
|
|
53
|
+
horizon?: string;
|
|
54
|
+
}
|
|
55
|
+
export declare const ALLOWED_CAPABILITIES: readonly ["websearch", "indicators"];
|
|
56
|
+
export type Capability = (typeof ALLOWED_CAPABILITIES)[number];
|
|
57
|
+
export interface AgentSpec {
|
|
58
|
+
name: string;
|
|
59
|
+
description: string;
|
|
60
|
+
spec: string;
|
|
61
|
+
trigger: TriggerConfig;
|
|
62
|
+
model?: ModelConfig;
|
|
63
|
+
venues: Venue[];
|
|
64
|
+
risk: RiskConfig;
|
|
65
|
+
limits: LimitsConfig;
|
|
66
|
+
abstention: AbstentionConfig;
|
|
67
|
+
sync: SyncConfig;
|
|
68
|
+
killSwitch: KillSwitchConfig;
|
|
69
|
+
objective?: ObjectiveConfig;
|
|
70
|
+
capabilities: Capability[];
|
|
71
|
+
}
|
|
72
|
+
export interface ParsedSkill {
|
|
73
|
+
spec: AgentSpec;
|
|
74
|
+
body: string;
|
|
75
|
+
raw: Record<string, unknown>;
|
|
76
|
+
}
|
|
77
|
+
export interface ValidationResult {
|
|
78
|
+
valid: boolean;
|
|
79
|
+
code?: string;
|
|
80
|
+
reason?: string;
|
|
81
|
+
}
|
|
82
|
+
export declare const ok: () => ValidationResult;
|
|
83
|
+
export declare const fail: (code: string, reason: string) => ValidationResult;
|
|
84
|
+
export interface Freshness {
|
|
85
|
+
status: string;
|
|
86
|
+
ageSeconds?: number;
|
|
87
|
+
}
|
|
88
|
+
export interface WatchEntry {
|
|
89
|
+
symbol: string;
|
|
90
|
+
coinId: string | null;
|
|
91
|
+
name?: string;
|
|
92
|
+
priceUsd?: number;
|
|
93
|
+
change1h?: number;
|
|
94
|
+
change24h?: number;
|
|
95
|
+
change7d?: number;
|
|
96
|
+
freshness?: Freshness;
|
|
97
|
+
indicators?: IndicatorSet;
|
|
98
|
+
}
|
|
99
|
+
export interface OpenPosition {
|
|
100
|
+
venue: Venue;
|
|
101
|
+
id: number;
|
|
102
|
+
coinId?: string;
|
|
103
|
+
symbol?: string;
|
|
104
|
+
side?: string;
|
|
105
|
+
status?: string;
|
|
106
|
+
marginMusd?: number;
|
|
107
|
+
unrealizedPnlMusd?: number;
|
|
108
|
+
}
|
|
109
|
+
export interface SpotOrder {
|
|
110
|
+
id: number;
|
|
111
|
+
coinId?: string;
|
|
112
|
+
symbol?: string;
|
|
113
|
+
side?: string;
|
|
114
|
+
orderType?: string;
|
|
115
|
+
quantity?: number;
|
|
116
|
+
status?: string;
|
|
117
|
+
}
|
|
118
|
+
export interface PmPosition {
|
|
119
|
+
id: number;
|
|
120
|
+
source?: string;
|
|
121
|
+
slug?: string;
|
|
122
|
+
outcomeExternalMarketId?: string;
|
|
123
|
+
stakeMusd?: number;
|
|
124
|
+
status?: string;
|
|
125
|
+
}
|
|
126
|
+
export interface PmMarket {
|
|
127
|
+
source: string;
|
|
128
|
+
slug: string;
|
|
129
|
+
outcomeExternalMarketId: string;
|
|
130
|
+
title?: string;
|
|
131
|
+
freshness?: Freshness;
|
|
132
|
+
}
|
|
133
|
+
export interface Observation {
|
|
134
|
+
asOf: string;
|
|
135
|
+
scopes: string[];
|
|
136
|
+
cashAvailableMusd: number | null;
|
|
137
|
+
equityMusd: number | null;
|
|
138
|
+
openPositions: OpenPosition[];
|
|
139
|
+
openOrders: SpotOrder[];
|
|
140
|
+
pmPositions: PmPosition[];
|
|
141
|
+
pmMarkets: PmMarket[];
|
|
142
|
+
watch: WatchEntry[];
|
|
143
|
+
syncCursor: string | null;
|
|
144
|
+
newClosedTrades: Array<Record<string, unknown>>;
|
|
145
|
+
polledBeforeWrite: boolean;
|
|
146
|
+
}
|
|
147
|
+
export type ProposedAction = {
|
|
148
|
+
type: "futures_open";
|
|
149
|
+
symbol: string;
|
|
150
|
+
side: "long" | "short";
|
|
151
|
+
leverage: number;
|
|
152
|
+
marginMusd: number;
|
|
153
|
+
stopLossPrice?: number | null;
|
|
154
|
+
takeProfitPrice?: number | null;
|
|
155
|
+
confidence?: number;
|
|
156
|
+
rationaleSummary?: string;
|
|
157
|
+
} | {
|
|
158
|
+
type: "futures_close";
|
|
159
|
+
positionId: number;
|
|
160
|
+
fraction?: number;
|
|
161
|
+
confidence?: number;
|
|
162
|
+
rationaleSummary?: string;
|
|
163
|
+
} | {
|
|
164
|
+
type: "futures_set_sltp";
|
|
165
|
+
positionId: number;
|
|
166
|
+
stopLossPrice?: number | null;
|
|
167
|
+
takeProfitPrice?: number | null;
|
|
168
|
+
} | {
|
|
169
|
+
type: "spot_order";
|
|
170
|
+
symbol: string;
|
|
171
|
+
side: "buy" | "sell";
|
|
172
|
+
orderType: "market" | "limit" | "stop";
|
|
173
|
+
quantity: number;
|
|
174
|
+
limitPrice?: number;
|
|
175
|
+
stopPrice?: number;
|
|
176
|
+
confidence?: number;
|
|
177
|
+
rationaleSummary?: string;
|
|
178
|
+
} | {
|
|
179
|
+
type: "spot_cancel";
|
|
180
|
+
orderId: number;
|
|
181
|
+
} | {
|
|
182
|
+
type: "pm_open";
|
|
183
|
+
source: string;
|
|
184
|
+
slug: string;
|
|
185
|
+
outcomeExternalMarketId: string;
|
|
186
|
+
stakeMusd: number;
|
|
187
|
+
confidence?: number;
|
|
188
|
+
rationaleSummary?: string;
|
|
189
|
+
};
|
|
190
|
+
export type ActionVenue = Venue;
|
|
191
|
+
export declare function actionVenue(a: ProposedAction): ActionVenue;
|
|
192
|
+
export declare function isWriteAction(a: ProposedAction): boolean;
|
|
193
|
+
export declare function isOpenAction(a: ProposedAction): a is Extract<ProposedAction, {
|
|
194
|
+
type: "futures_open" | "spot_order" | "pm_open";
|
|
195
|
+
}>;
|
|
196
|
+
export declare function spotBuyCost(action: Extract<ProposedAction, {
|
|
197
|
+
type: "spot_order";
|
|
198
|
+
}>, quote?: QuoteEvidence): number | undefined;
|
|
199
|
+
export interface Decision {
|
|
200
|
+
decision: "skip" | "act";
|
|
201
|
+
reason?: string;
|
|
202
|
+
confidence?: number;
|
|
203
|
+
actions: ProposedAction[];
|
|
204
|
+
}
|
|
205
|
+
export interface QuoteEvidence {
|
|
206
|
+
eligible: boolean;
|
|
207
|
+
blockReasons?: unknown;
|
|
208
|
+
entryPrice?: number;
|
|
209
|
+
liquidationPrice?: number;
|
|
210
|
+
executionPrice?: number;
|
|
211
|
+
estimatedCostMusd?: number;
|
|
212
|
+
freshness?: Freshness;
|
|
213
|
+
}
|
|
214
|
+
export interface RunState {
|
|
215
|
+
runId: string;
|
|
216
|
+
cyclesRun: number;
|
|
217
|
+
writesToday: number;
|
|
218
|
+
realizedPnlMusd: number;
|
|
219
|
+
peakRealizedMusd: number;
|
|
220
|
+
consecutiveRejectCycles: number;
|
|
221
|
+
consecutiveModelFailures: number;
|
|
222
|
+
rateLimitHits: number;
|
|
223
|
+
disabled: boolean;
|
|
224
|
+
disabledReason?: string;
|
|
225
|
+
dayKey: string;
|
|
226
|
+
cursor: string | null;
|
|
227
|
+
seen: string[];
|
|
228
|
+
realizedPnlTodayMusd: number;
|
|
229
|
+
consecutiveExecFailures: number;
|
|
230
|
+
intentSeq: Record<string, number>;
|
|
231
|
+
}
|
|
232
|
+
export interface AgentTrace {
|
|
233
|
+
runId?: string;
|
|
234
|
+
decisionId?: string;
|
|
235
|
+
strategyLabel?: string;
|
|
236
|
+
confidence?: number;
|
|
237
|
+
rationaleSummary?: string;
|
|
238
|
+
}
|
|
239
|
+
export interface ApiResult {
|
|
240
|
+
ok: boolean;
|
|
241
|
+
status: number;
|
|
242
|
+
data: unknown;
|
|
243
|
+
retryAfterSeconds?: number;
|
|
244
|
+
rateLimitRemaining?: number;
|
|
245
|
+
ledgerEventId?: string | null;
|
|
246
|
+
}
|
|
247
|
+
export interface PlannedAction {
|
|
248
|
+
action: ProposedAction;
|
|
249
|
+
accepted: boolean;
|
|
250
|
+
code?: string;
|
|
251
|
+
reason?: string;
|
|
252
|
+
quote?: QuoteEvidence;
|
|
253
|
+
executed?: boolean;
|
|
254
|
+
result?: unknown;
|
|
255
|
+
}
|
|
256
|
+
export interface CycleResult {
|
|
257
|
+
decision: "skip" | "act";
|
|
258
|
+
skipReason?: string;
|
|
259
|
+
planned: PlannedAction[];
|
|
260
|
+
modelFailed?: boolean;
|
|
261
|
+
disabled?: boolean;
|
|
262
|
+
disabledReason?: string;
|
|
263
|
+
live: boolean;
|
|
264
|
+
}
|
|
265
|
+
export interface ResolveIssue {
|
|
266
|
+
code: string;
|
|
267
|
+
message: string;
|
|
268
|
+
path?: string;
|
|
269
|
+
}
|
|
270
|
+
export interface Provenance {
|
|
271
|
+
sources: Record<string, string>;
|
|
272
|
+
mergeOrder: string[];
|
|
273
|
+
includeOrder: string[];
|
|
274
|
+
}
|
|
275
|
+
export interface ResolvedAgent {
|
|
276
|
+
inputPath: string;
|
|
277
|
+
isDirectory: boolean;
|
|
278
|
+
rawFrontmatter: Record<string, unknown>;
|
|
279
|
+
mergedProse: string;
|
|
280
|
+
proseParts: Array<{
|
|
281
|
+
source: string;
|
|
282
|
+
text: string;
|
|
283
|
+
}>;
|
|
284
|
+
provenance: Provenance;
|
|
285
|
+
contentHashes: Record<string, string>;
|
|
286
|
+
}
|
package/dist/agent/types.js
CHANGED
|
@@ -7,10 +7,24 @@
|
|
|
7
7
|
// money.
|
|
8
8
|
export const SPEC_VERSION = "coinrithm.agent.v1";
|
|
9
9
|
export const VENUES = ["spot", "futures", "pm"];
|
|
10
|
+
// The runner's live action vocabulary — the capability set the drift guard
|
|
11
|
+
// checks authored prose against. MUST mirror the ProposedAction union below and
|
|
12
|
+
// the zod schema in decision.ts. A test ("ACTION_TYPES stays in lockstep with
|
|
13
|
+
// the decision schema", capabilityGuard.test.ts) derives the literal set from
|
|
14
|
+
// decision.ts's actionSchema and asserts equality, so the two cannot drift.
|
|
15
|
+
export const ACTION_TYPES = [
|
|
16
|
+
"futures_open",
|
|
17
|
+
"futures_close",
|
|
18
|
+
"futures_set_sltp",
|
|
19
|
+
"spot_order",
|
|
20
|
+
"spot_cancel",
|
|
21
|
+
"pm_open",
|
|
22
|
+
];
|
|
10
23
|
export const PROVIDERS = [
|
|
11
24
|
"anthropic",
|
|
12
25
|
"openai",
|
|
13
26
|
"groq",
|
|
27
|
+
"nvidia",
|
|
14
28
|
"openai-compatible",
|
|
15
29
|
];
|
|
16
30
|
// What the agent declares it is optimizing for — so two similar-looking agents
|
|
@@ -46,5 +60,29 @@ export function isWriteAction(a) {
|
|
|
46
60
|
return true;
|
|
47
61
|
}
|
|
48
62
|
export function isOpenAction(a) {
|
|
49
|
-
return a.type === "futures_open" || a.type === "spot_order" || a.type === "pm_open";
|
|
63
|
+
return (a.type === "futures_open" || a.type === "spot_order" || a.type === "pm_open");
|
|
64
|
+
}
|
|
65
|
+
// Gross mUSD a spot BUY consumes. The validator (per-trade cap + balance gate)
|
|
66
|
+
// and the runner (running-cash decrement) BOTH size with this one function so
|
|
67
|
+
// they can never diverge. Sizing: limit -> limitPrice*qty, stop -> stopPrice*qty,
|
|
68
|
+
// market -> the server-computed `estimatedCostMusd` (preferred) or
|
|
69
|
+
// executionPrice*qty. Returns undefined when no price is available (e.g. an
|
|
70
|
+
// unpriced market quote) so callers FAIL CLOSED instead of treating it as $0.
|
|
71
|
+
export function spotBuyCost(action, quote) {
|
|
72
|
+
if (action.orderType === "limit") {
|
|
73
|
+
return typeof action.limitPrice === "number"
|
|
74
|
+
? action.limitPrice * action.quantity
|
|
75
|
+
: undefined;
|
|
76
|
+
}
|
|
77
|
+
if (action.orderType === "stop") {
|
|
78
|
+
return typeof action.stopPrice === "number"
|
|
79
|
+
? action.stopPrice * action.quantity
|
|
80
|
+
: undefined;
|
|
81
|
+
}
|
|
82
|
+
// market: prefer the server's gross notional, else derive from the fill price.
|
|
83
|
+
if (typeof quote?.estimatedCostMusd === "number")
|
|
84
|
+
return quote.estimatedCostMusd;
|
|
85
|
+
return typeof quote?.executionPrice === "number"
|
|
86
|
+
? quote.executionPrice * action.quantity
|
|
87
|
+
: undefined;
|
|
50
88
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export declare const sleep: (ms: number) => Promise<void>;
|
|
2
|
+
export declare function parseCadenceMs(cadence: unknown): number | null;
|
|
3
|
+
export declare function dayKey(d?: Date): string;
|
|
4
|
+
export declare function envFlag(value: string | undefined): boolean;
|
|
5
|
+
export declare function scanForSecrets(value: unknown, pathPrefix?: string, findings?: string[]): string[];
|
|
6
|
+
export declare function shortId(): string;
|
|
7
|
+
export declare function normalizeContent(text: string): string;
|
|
8
|
+
export declare function sha256(text: string): string;
|
|
9
|
+
export declare function toPosix(p: string): string;
|
|
10
|
+
export declare function isPathInside(parent: string, child: string): boolean;
|
|
11
|
+
export declare function boundTail(text: string, maxLines: number, maxBytes: number): string;
|
|
12
|
+
export declare function stableStringify(value: unknown): string;
|
|
13
|
+
export declare function sortDeep(value: unknown): unknown;
|
package/dist/agent/util.js
CHANGED
|
@@ -21,6 +21,10 @@ export function parseCadenceMs(cadence) {
|
|
|
21
21
|
export function dayKey(d = new Date()) {
|
|
22
22
|
return d.toISOString().slice(0, 10);
|
|
23
23
|
}
|
|
24
|
+
// Truthy reading of an opt-in env flag (1/true/yes/on, case-insensitive).
|
|
25
|
+
export function envFlag(value) {
|
|
26
|
+
return ["1", "true", "yes", "on"].includes((value ?? "").trim().toLowerCase());
|
|
27
|
+
}
|
|
24
28
|
// Deep-scan a parsed frontmatter object for anything that looks like a secret.
|
|
25
29
|
// The skill file is meant to be committable and shareable; a real key must
|
|
26
30
|
// NEVER live in it (keys are supplied at runtime via env / encrypted store).
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
export declare const RUNNER_VERSION = "0.1.0";
|
|
2
|
+
export declare const RESOLVER_VERSION = "1";
|
|
3
|
+
export declare const MANIFEST_SCHEMA = "coinrithm.manifest.v1";
|
|
4
|
+
export declare const COINRITHM_API: {
|
|
5
|
+
readonly kind: "coinrithm-agent-api";
|
|
6
|
+
readonly baseUrl: "https://api.coinrithm.com";
|
|
7
|
+
readonly mcpUrl: "https://mcp.coinrithm.com/mcp";
|
|
8
|
+
readonly openapiVersion: "1.4.0";
|
|
9
|
+
readonly mcpPackage: "@coinrithm/mcp-trading";
|
|
10
|
+
readonly mcpVersion: "0.3.0";
|
|
11
|
+
};
|
package/dist/agent/version.js
CHANGED
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
export declare const DEFAULT_BASE_URL = "https://api.coinrithm.com";
|
|
2
|
+
export declare function log(...args: unknown[]): void;
|
|
3
|
+
export interface ClientConfig {
|
|
4
|
+
apiKey?: string;
|
|
5
|
+
baseUrl: string;
|
|
6
|
+
}
|
|
7
|
+
export interface AgentTrace {
|
|
8
|
+
runId?: string;
|
|
9
|
+
decisionId?: string;
|
|
10
|
+
strategyLabel?: string;
|
|
11
|
+
confidence?: number;
|
|
12
|
+
rationaleSummary?: string;
|
|
13
|
+
}
|
|
14
|
+
export declare function loadConfig(): ClientConfig;
|
|
15
|
+
export declare function loadHttpConfig(): ClientConfig;
|
|
16
|
+
export declare function bearerFromHeader(value: string | string[] | undefined): string | undefined;
|
|
17
|
+
export interface ApiResult {
|
|
18
|
+
ok: boolean;
|
|
19
|
+
status: number;
|
|
20
|
+
ledgerEventId?: string | null;
|
|
21
|
+
ledgerStatus?: string | null;
|
|
22
|
+
data: unknown;
|
|
23
|
+
}
|
|
24
|
+
type TraceableBody<T extends Record<string, unknown>> = T & {
|
|
25
|
+
agentTrace?: AgentTrace;
|
|
26
|
+
};
|
|
27
|
+
export declare class CoinRithmClient {
|
|
28
|
+
private readonly defaultApiKey?;
|
|
29
|
+
private readonly baseUrl;
|
|
30
|
+
constructor(config: ClientConfig);
|
|
31
|
+
private request;
|
|
32
|
+
whoami(apiKey?: string, agentTrace?: AgentTrace): Promise<ApiResult>;
|
|
33
|
+
getPortfolio(query?: {
|
|
34
|
+
fiat?: string;
|
|
35
|
+
locale?: string;
|
|
36
|
+
}, apiKey?: string, agentTrace?: AgentTrace): Promise<ApiResult>;
|
|
37
|
+
getWallet(query?: {
|
|
38
|
+
coinId?: string;
|
|
39
|
+
}, apiKey?: string, agentTrace?: AgentTrace): Promise<ApiResult>;
|
|
40
|
+
resolveSymbol(query: {
|
|
41
|
+
q: string;
|
|
42
|
+
}, apiKey?: string, agentTrace?: AgentTrace): Promise<ApiResult>;
|
|
43
|
+
getEquityCurve(query?: {
|
|
44
|
+
days?: number;
|
|
45
|
+
granularity?: "daily" | "realized";
|
|
46
|
+
}, apiKey?: string, agentTrace?: AgentTrace): Promise<ApiResult>;
|
|
47
|
+
getMyTrades(query?: {
|
|
48
|
+
venue?: string;
|
|
49
|
+
limit?: number;
|
|
50
|
+
updatedSince?: string;
|
|
51
|
+
}, apiKey?: string, agentTrace?: AgentTrace): Promise<ApiResult>;
|
|
52
|
+
getMarketContext(coinId: string, apiKey?: string, agentTrace?: AgentTrace): Promise<ApiResult>;
|
|
53
|
+
getCandles(coinId: string, query?: {
|
|
54
|
+
range?: "1H" | "1D" | "1W" | "1M" | "3M";
|
|
55
|
+
fiat?: string;
|
|
56
|
+
}, apiKey?: string, agentTrace?: AgentTrace): Promise<ApiResult>;
|
|
57
|
+
discoverPmMarkets(query?: {
|
|
58
|
+
q?: string;
|
|
59
|
+
source?: "all" | "kalshi" | "polymarket";
|
|
60
|
+
limit?: number;
|
|
61
|
+
offset?: number;
|
|
62
|
+
sort?: string;
|
|
63
|
+
}, apiKey?: string, agentTrace?: AgentTrace): Promise<ApiResult>;
|
|
64
|
+
getPerformance(apiKey?: string, agentTrace?: AgentTrace): Promise<ApiResult>;
|
|
65
|
+
getLedger(query?: {
|
|
66
|
+
venue?: string;
|
|
67
|
+
eventType?: string;
|
|
68
|
+
runId?: string;
|
|
69
|
+
decisionId?: string;
|
|
70
|
+
status?: string;
|
|
71
|
+
from?: string;
|
|
72
|
+
to?: string;
|
|
73
|
+
limit?: number;
|
|
74
|
+
offset?: number;
|
|
75
|
+
}, apiKey?: string, agentTrace?: AgentTrace): Promise<ApiResult>;
|
|
76
|
+
exportLedger(query?: {
|
|
77
|
+
venue?: string;
|
|
78
|
+
eventType?: string;
|
|
79
|
+
runId?: string;
|
|
80
|
+
decisionId?: string;
|
|
81
|
+
status?: string;
|
|
82
|
+
from?: string;
|
|
83
|
+
to?: string;
|
|
84
|
+
}, apiKey?: string, agentTrace?: AgentTrace): Promise<ApiResult>;
|
|
85
|
+
getArenaLeaderboard(query?: {
|
|
86
|
+
page?: number;
|
|
87
|
+
pageSize?: number;
|
|
88
|
+
window?: "7d" | "30d" | "all";
|
|
89
|
+
}, apiKey?: string): Promise<ApiResult>;
|
|
90
|
+
getArenaAgent(handle: string, apiKey?: string): Promise<ApiResult>;
|
|
91
|
+
listOpenOrders(query?: {
|
|
92
|
+
coinId?: string;
|
|
93
|
+
limit?: number;
|
|
94
|
+
updatedSince?: string;
|
|
95
|
+
}, apiKey?: string, agentTrace?: AgentTrace): Promise<ApiResult>;
|
|
96
|
+
getFuturesPositions(query?: {
|
|
97
|
+
updatedSince?: string;
|
|
98
|
+
}, apiKey?: string, agentTrace?: AgentTrace): Promise<ApiResult>;
|
|
99
|
+
getPmPositions(query?: {
|
|
100
|
+
updatedSince?: string;
|
|
101
|
+
}, apiKey?: string, agentTrace?: AgentTrace): Promise<ApiResult>;
|
|
102
|
+
futuresQuote(body: {
|
|
103
|
+
coinId: string;
|
|
104
|
+
side: string;
|
|
105
|
+
leverage: number;
|
|
106
|
+
marginMusd: number;
|
|
107
|
+
} & {
|
|
108
|
+
agentTrace?: AgentTrace;
|
|
109
|
+
}, apiKey?: string): Promise<ApiResult>;
|
|
110
|
+
pmQuote(body: {
|
|
111
|
+
source: string;
|
|
112
|
+
slug: string;
|
|
113
|
+
outcomeExternalMarketId: string;
|
|
114
|
+
stakeMusd: number;
|
|
115
|
+
} & {
|
|
116
|
+
agentTrace?: AgentTrace;
|
|
117
|
+
}, apiKey?: string): Promise<ApiResult>;
|
|
118
|
+
spotQuote(body: {
|
|
119
|
+
coinId: string;
|
|
120
|
+
side: string;
|
|
121
|
+
quantity: number;
|
|
122
|
+
} & {
|
|
123
|
+
agentTrace?: AgentTrace;
|
|
124
|
+
}, apiKey?: string): Promise<ApiResult>;
|
|
125
|
+
placeSpotOrder(body: TraceableBody<{
|
|
126
|
+
coinId: string;
|
|
127
|
+
side: string;
|
|
128
|
+
orderType: string;
|
|
129
|
+
quantity: number;
|
|
130
|
+
limitPrice?: number;
|
|
131
|
+
stopPrice?: number;
|
|
132
|
+
idempotencyKey: string;
|
|
133
|
+
}>, apiKey?: string): Promise<ApiResult>;
|
|
134
|
+
cancelSpotOrder(orderId: number, apiKey?: string, agentTrace?: AgentTrace): Promise<ApiResult>;
|
|
135
|
+
openFuturesPosition(body: TraceableBody<{
|
|
136
|
+
coinId: string;
|
|
137
|
+
side: string;
|
|
138
|
+
leverage: number;
|
|
139
|
+
marginMusd: number;
|
|
140
|
+
idempotencyKey: string;
|
|
141
|
+
stopLossPrice?: number | null;
|
|
142
|
+
takeProfitPrice?: number | null;
|
|
143
|
+
}>, apiKey?: string): Promise<ApiResult>;
|
|
144
|
+
setFuturesSlTp(body: TraceableBody<{
|
|
145
|
+
positionId: number;
|
|
146
|
+
stopLossPrice?: number | null;
|
|
147
|
+
takeProfitPrice?: number | null;
|
|
148
|
+
}>, apiKey?: string): Promise<ApiResult>;
|
|
149
|
+
closeFuturesPosition(body: TraceableBody<{
|
|
150
|
+
positionId: number;
|
|
151
|
+
fraction?: number;
|
|
152
|
+
idempotencyKey: string;
|
|
153
|
+
}>, apiKey?: string): Promise<ApiResult>;
|
|
154
|
+
openPmPosition(body: TraceableBody<{
|
|
155
|
+
source: string;
|
|
156
|
+
slug: string;
|
|
157
|
+
outcomeExternalMarketId: string;
|
|
158
|
+
stakeMusd: number;
|
|
159
|
+
idempotencyKey: string;
|
|
160
|
+
}>, apiKey?: string): Promise<ApiResult>;
|
|
161
|
+
}
|
|
162
|
+
export {};
|
package/dist/http.d.ts
ADDED
package/dist/index.d.ts
ADDED
package/dist/tools.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const SERVER_VERSION: string;
|