@spfunctions/cli 1.1.8 → 1.2.1
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/dist/commands/agent.js +31 -9
- package/dist/commands/setup.d.ts +1 -0
- package/dist/commands/setup.js +18 -0
- package/dist/commands/trade.js +2 -3
- package/dist/index.js +2 -1
- package/dist/kalshi.d.ts +1 -1
- package/package.json +1 -1
package/dist/commands/agent.js
CHANGED
|
@@ -717,8 +717,18 @@ async function agentCommand(thesisId, opts) {
|
|
|
717
717
|
}
|
|
718
718
|
}
|
|
719
719
|
cachedPositions = positions;
|
|
720
|
+
const formatted = positions.map((p) => ({
|
|
721
|
+
ticker: p.ticker,
|
|
722
|
+
side: p.side,
|
|
723
|
+
quantity: p.quantity,
|
|
724
|
+
avg_price: `${p.average_price_paid}¢`,
|
|
725
|
+
current_price: `${p.current_value}¢`,
|
|
726
|
+
unrealized_pnl: `$${(p.unrealized_pnl / 100).toFixed(2)}`,
|
|
727
|
+
total_cost: `$${(p.total_cost / 100).toFixed(2)}`,
|
|
728
|
+
realized_pnl: `$${(p.realized_pnl / 100).toFixed(2)}`,
|
|
729
|
+
}));
|
|
720
730
|
return {
|
|
721
|
-
content: [{ type: 'text', text: JSON.stringify(
|
|
731
|
+
content: [{ type: 'text', text: JSON.stringify(formatted, null, 2) }],
|
|
722
732
|
details: {},
|
|
723
733
|
};
|
|
724
734
|
},
|
|
@@ -1090,8 +1100,8 @@ async function agentCommand(thesisId, opts) {
|
|
|
1090
1100
|
}),
|
|
1091
1101
|
execute: async (_toolCallId, params) => {
|
|
1092
1102
|
const { createOrder } = await import('../kalshi.js');
|
|
1093
|
-
const
|
|
1094
|
-
const maxCost = ((
|
|
1103
|
+
const priceCents = params.price_cents ? Math.round(Number(params.price_cents)) : undefined;
|
|
1104
|
+
const maxCost = ((priceCents || 99) * params.count / 100).toFixed(2);
|
|
1095
1105
|
// Show preview
|
|
1096
1106
|
const preview = [
|
|
1097
1107
|
C.zinc200(bold('ORDER PREVIEW')),
|
|
@@ -1100,7 +1110,7 @@ async function agentCommand(thesisId, opts) {
|
|
|
1100
1110
|
` Action: ${params.action.toUpperCase()}`,
|
|
1101
1111
|
` Quantity: ${params.count}`,
|
|
1102
1112
|
` Type: ${params.type}`,
|
|
1103
|
-
|
|
1113
|
+
priceCents ? ` Price: ${priceCents}\u00A2` : '',
|
|
1104
1114
|
` Max cost: $${maxCost}`,
|
|
1105
1115
|
].filter(Boolean).join('\n');
|
|
1106
1116
|
addSystemText(preview);
|
|
@@ -1118,7 +1128,7 @@ async function agentCommand(thesisId, opts) {
|
|
|
1118
1128
|
action: params.action,
|
|
1119
1129
|
type: params.type,
|
|
1120
1130
|
count: params.count,
|
|
1121
|
-
...(
|
|
1131
|
+
...(priceCents ? { yes_price: priceCents } : {}),
|
|
1122
1132
|
});
|
|
1123
1133
|
const order = result.order || result;
|
|
1124
1134
|
return {
|
|
@@ -1195,6 +1205,7 @@ Short-term markets (weekly/monthly contracts) settle into hard data that calibra
|
|
|
1195
1205
|
- If a causal tree node probability seriously contradicts the market price, point it out.
|
|
1196
1206
|
- Use Chinese if the user writes in Chinese, English if they write in English.
|
|
1197
1207
|
- For any question about prices, positions, or P&L, ALWAYS call a tool to get fresh data first. Never answer price-related questions using the cached data in this system prompt.
|
|
1208
|
+
- Prices are in cents (e.g. 35¢). P&L, cost, and balance are in dollars (e.g. $90.66). Tool outputs are pre-formatted with units — do not re-convert.
|
|
1198
1209
|
- Align tables. Be precise with numbers to the cent.
|
|
1199
1210
|
|
|
1200
1211
|
## Strategy rules
|
|
@@ -1206,6 +1217,10 @@ When the conversation produces a concrete trade idea (specific contract, directi
|
|
|
1206
1217
|
- After creating, confirm the strategy details and mention that sf runtime --dangerous can execute it.
|
|
1207
1218
|
- If the user says "change the stop loss on T150 to 30", use update_strategy.
|
|
1208
1219
|
|
|
1220
|
+
## Trading status
|
|
1221
|
+
|
|
1222
|
+
${config.tradingEnabled ? 'Trading is ENABLED. You have place_order and cancel_order tools.' : 'Trading is DISABLED. You cannot place or cancel orders. Tell the user to run `sf setup --enable-trading` to unlock trading.'}
|
|
1223
|
+
|
|
1209
1224
|
## Current thesis state
|
|
1210
1225
|
|
|
1211
1226
|
Thesis: ${ctx.thesis || ctx.rawThesis || 'N/A'}
|
|
@@ -1751,7 +1766,7 @@ Output a structured summary. Be concise but preserve every important detail —
|
|
|
1751
1766
|
const result = await createOrder({
|
|
1752
1767
|
ticker, side: 'yes', action: 'buy', type: 'limit',
|
|
1753
1768
|
count: parseInt(qtyStr),
|
|
1754
|
-
yes_price:
|
|
1769
|
+
yes_price: parseInt(priceStr),
|
|
1755
1770
|
});
|
|
1756
1771
|
addSystemText(C.emerald('\u2713 Order placed: ' + ((result.order || result).order_id || 'OK')));
|
|
1757
1772
|
}
|
|
@@ -1783,7 +1798,7 @@ Output a structured summary. Be concise but preserve every important detail —
|
|
|
1783
1798
|
const result = await createOrder({
|
|
1784
1799
|
ticker, side: 'yes', action: 'sell', type: 'limit',
|
|
1785
1800
|
count: parseInt(qtyStr),
|
|
1786
|
-
yes_price:
|
|
1801
|
+
yes_price: parseInt(priceStr),
|
|
1787
1802
|
});
|
|
1788
1803
|
addSystemText(C.emerald('\u2713 Order placed: ' + ((result.order || result).order_id || 'OK')));
|
|
1789
1804
|
}
|
|
@@ -2137,7 +2152,14 @@ async function runPlainTextAgent(params) {
|
|
|
2137
2152
|
pos.unrealized_pnl = Math.round((livePrice - pos.average_price_paid) * pos.quantity);
|
|
2138
2153
|
}
|
|
2139
2154
|
}
|
|
2140
|
-
|
|
2155
|
+
const formatted = positions.map((p) => ({
|
|
2156
|
+
ticker: p.ticker, side: p.side, quantity: p.quantity,
|
|
2157
|
+
avg_price: `${p.average_price_paid}¢`, current_price: `${p.current_value}¢`,
|
|
2158
|
+
unrealized_pnl: `$${(p.unrealized_pnl / 100).toFixed(2)}`,
|
|
2159
|
+
total_cost: `$${(p.total_cost / 100).toFixed(2)}`,
|
|
2160
|
+
realized_pnl: `$${(p.realized_pnl / 100).toFixed(2)}`,
|
|
2161
|
+
}));
|
|
2162
|
+
return { content: [{ type: 'text', text: JSON.stringify(formatted, null, 2) }], details: {} };
|
|
2141
2163
|
},
|
|
2142
2164
|
},
|
|
2143
2165
|
{
|
|
@@ -2309,7 +2331,7 @@ ${edgesSummary}
|
|
|
2309
2331
|
|
|
2310
2332
|
${ctx.lastEvaluation?.summary ? `Latest evaluation: ${ctx.lastEvaluation.summary.slice(0, 300)}` : ''}
|
|
2311
2333
|
|
|
2312
|
-
Rules: Be concise. Use tools when needed. Don't ask "anything else?".`;
|
|
2334
|
+
Rules: Be concise. Use tools when needed. Don't ask "anything else?". Prices are in cents (e.g. 35¢). P&L, cost, and balance are in dollars (e.g. $90.66). Tool outputs are pre-formatted with units — do not re-convert.`;
|
|
2313
2335
|
// ── Create agent ──────────────────────────────────────────────────────────
|
|
2314
2336
|
const agent = new Agent({
|
|
2315
2337
|
initialState: { systemPrompt, model, tools, thinkingLevel: 'off' },
|
package/dist/commands/setup.d.ts
CHANGED
package/dist/commands/setup.js
CHANGED
|
@@ -147,6 +147,24 @@ async function setupCommand(opts) {
|
|
|
147
147
|
ok(`保存到 ${(0, config_js_1.getConfigPath)()}`);
|
|
148
148
|
return;
|
|
149
149
|
}
|
|
150
|
+
// ── sf setup --kalshi (reconfigure Kalshi credentials) ──────────────────
|
|
151
|
+
if (opts.kalshi) {
|
|
152
|
+
const existing = (0, config_js_1.loadFileConfig)();
|
|
153
|
+
blank();
|
|
154
|
+
console.log(` ${bold('重新配置 Kalshi 凭证')}`);
|
|
155
|
+
blank();
|
|
156
|
+
info('去 https://kalshi.com/account/api-keys 生成新的 API key。');
|
|
157
|
+
info('如果需要交易功能,确保勾选 read+write 权限。');
|
|
158
|
+
blank();
|
|
159
|
+
await promptForKalshi(existing);
|
|
160
|
+
(0, config_js_1.saveConfig)(existing);
|
|
161
|
+
if (existing.kalshiKeyId) {
|
|
162
|
+
process.env.KALSHI_API_KEY_ID = existing.kalshiKeyId;
|
|
163
|
+
process.env.KALSHI_PRIVATE_KEY_PATH = existing.kalshiPrivateKeyPath;
|
|
164
|
+
}
|
|
165
|
+
blank();
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
150
168
|
// ── sf setup --enable-trading / --disable-trading ────────────────────────
|
|
151
169
|
if (opts.enableTrading) {
|
|
152
170
|
const existing = (0, config_js_1.loadFileConfig)();
|
package/dist/commands/trade.js
CHANGED
|
@@ -26,7 +26,6 @@ async function executeOrder(ticker, qty, action, opts) {
|
|
|
26
26
|
if (priceCents !== undefined && (priceCents < 1 || priceCents > 99)) {
|
|
27
27
|
throw new Error('Price must be 1-99 cents.');
|
|
28
28
|
}
|
|
29
|
-
const priceDollars = priceCents ? (priceCents / 100).toFixed(2) : undefined;
|
|
30
29
|
const maxCost = ((priceCents || 99) * quantity / 100).toFixed(2);
|
|
31
30
|
console.log();
|
|
32
31
|
console.log(` ${utils_js_1.c.bold}${utils_js_1.c.cyan}${action.toUpperCase()} Order${utils_js_1.c.reset}`);
|
|
@@ -35,7 +34,7 @@ async function executeOrder(ticker, qty, action, opts) {
|
|
|
35
34
|
console.log(` Side: ${side === 'yes' ? utils_js_1.c.green + 'YES' + utils_js_1.c.reset : utils_js_1.c.red + 'NO' + utils_js_1.c.reset}`);
|
|
36
35
|
console.log(` Quantity: ${quantity}`);
|
|
37
36
|
console.log(` Type: ${orderType}`);
|
|
38
|
-
if (
|
|
37
|
+
if (priceCents)
|
|
39
38
|
console.log(` Price: ${priceCents}¢`);
|
|
40
39
|
console.log(` Max cost: $${maxCost}`);
|
|
41
40
|
console.log();
|
|
@@ -53,7 +52,7 @@ async function executeOrder(ticker, qty, action, opts) {
|
|
|
53
52
|
action,
|
|
54
53
|
type: orderType,
|
|
55
54
|
count: quantity,
|
|
56
|
-
...(
|
|
55
|
+
...(priceCents ? { yes_price: priceCents } : {}),
|
|
57
56
|
});
|
|
58
57
|
const order = result.order || result;
|
|
59
58
|
console.log();
|
package/dist/index.js
CHANGED
|
@@ -87,8 +87,9 @@ program
|
|
|
87
87
|
.option('--key <key>', 'Set SF API key (non-interactive, for CI)')
|
|
88
88
|
.option('--enable-trading', 'Enable trading (sf buy/sell/cancel)')
|
|
89
89
|
.option('--disable-trading', 'Disable trading')
|
|
90
|
+
.option('--kalshi', 'Reconfigure Kalshi API credentials')
|
|
90
91
|
.action(async (opts) => {
|
|
91
|
-
await run(() => (0, setup_js_1.setupCommand)({ check: opts.check, reset: opts.reset, key: opts.key, enableTrading: opts.enableTrading, disableTrading: opts.disableTrading }));
|
|
92
|
+
await run(() => (0, setup_js_1.setupCommand)({ check: opts.check, reset: opts.reset, key: opts.key, enableTrading: opts.enableTrading, disableTrading: opts.disableTrading, kalshi: opts.kalshi }));
|
|
92
93
|
});
|
|
93
94
|
// ── sf list ──────────────────────────────────────────────────────────────────
|
|
94
95
|
program
|
package/dist/kalshi.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@spfunctions/cli",
|
|
3
|
-
"version": "1.1
|
|
3
|
+
"version": "1.2.1",
|
|
4
4
|
"description": "Prediction market intelligence CLI. Causal thesis model, 24/7 Kalshi/Polymarket scan, live orderbook, edge detection. Interactive agent mode with tool calling.",
|
|
5
5
|
"bin": {
|
|
6
6
|
"sf": "./dist/index.js"
|