@spfunctions/cli 0.1.6 → 0.1.7
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 +42 -22
- package/package.json +1 -1
package/dist/commands/agent.js
CHANGED
|
@@ -197,16 +197,19 @@ function renderEdges(context, piTui) {
|
|
|
197
197
|
const positions = context._positions || [];
|
|
198
198
|
const lines = [];
|
|
199
199
|
for (const e of edges) {
|
|
200
|
-
|
|
201
|
-
const
|
|
202
|
-
const
|
|
203
|
-
const
|
|
204
|
-
const
|
|
205
|
-
const
|
|
200
|
+
// Context API field names: market, marketId, thesisPrice, edge, orderbook.spread, orderbook.liquidityScore
|
|
201
|
+
const name = (e.market || e.marketId || '').slice(0, 18).padEnd(18);
|
|
202
|
+
const marketStr = typeof e.marketPrice === 'number' ? `${e.marketPrice}\u00A2` : '?';
|
|
203
|
+
const thesisStr = typeof e.thesisPrice === 'number' ? `${e.thesisPrice}\u00A2` : '?';
|
|
204
|
+
const edgeVal = typeof e.edge === 'number' ? (e.edge > 0 ? `+${e.edge}` : `${e.edge}`) : '?';
|
|
205
|
+
const ob = e.orderbook || {};
|
|
206
|
+
const spreadStr = typeof ob.spread === 'number' ? `${ob.spread}\u00A2` : '?';
|
|
207
|
+
const liq = ob.liquidityScore || 'low';
|
|
206
208
|
const liqBars = liq === 'high' ? '\u25A0\u25A0\u25A0' : liq === 'medium' ? '\u25A0\u25A0 ' : '\u25A0 ';
|
|
207
209
|
const liqColor = liq === 'high' ? C.emerald : liq === 'medium' ? C.amber : C.red;
|
|
208
|
-
// Check if we have a position on this edge
|
|
209
|
-
const pos = positions.find((p) => p.ticker === e.
|
|
210
|
+
// Check if we have a position on this edge (match by marketId prefix in ticker)
|
|
211
|
+
const pos = positions.find((p) => p.ticker === e.marketId ||
|
|
212
|
+
(e.marketId && p.ticker?.includes(e.marketId)));
|
|
210
213
|
let posStr = C.zinc600('\u2014');
|
|
211
214
|
if (pos) {
|
|
212
215
|
const side = pos.side?.toUpperCase() || 'YES';
|
|
@@ -215,7 +218,7 @@ function renderEdges(context, piTui) {
|
|
|
215
218
|
: '';
|
|
216
219
|
posStr = C.emerald(`${side} (${pos.quantity}@${pos.average_price_paid}\u00A2 ${pnl})`);
|
|
217
220
|
}
|
|
218
|
-
lines.push(` ${C.zinc200(name)} ${C.zinc400(
|
|
221
|
+
lines.push(` ${C.zinc200(name)} ${C.zinc400(marketStr)} \u2192 ${C.zinc400(thesisStr)} edge ${edgeVal.includes('+') ? C.emerald(edgeVal) : C.red(edgeVal)} spread ${C.zinc600(spreadStr)} ${liqColor(liqBars)} ${liqColor(liq.padEnd(4))} ${posStr}`);
|
|
219
222
|
}
|
|
220
223
|
return lines.join('\n');
|
|
221
224
|
}
|
|
@@ -283,7 +286,7 @@ async function agentCommand(thesisId, opts) {
|
|
|
283
286
|
// ── Fetch initial context ──────────────────────────────────────────────────
|
|
284
287
|
let latestContext = await sfClient.getContext(resolvedThesisId);
|
|
285
288
|
// ── Model setup ────────────────────────────────────────────────────────────
|
|
286
|
-
const rawModelName = opts?.model || 'anthropic/claude-sonnet-4
|
|
289
|
+
const rawModelName = opts?.model || 'anthropic/claude-sonnet-4.6';
|
|
287
290
|
let currentModelName = rawModelName.replace(/^openrouter\//, '');
|
|
288
291
|
function resolveModel(name) {
|
|
289
292
|
try {
|
|
@@ -564,6 +567,23 @@ Do NOT make up data. Always call tools to get current state.`;
|
|
|
564
567
|
let currentLoader = null;
|
|
565
568
|
const toolStartTimes = new Map();
|
|
566
569
|
const toolLines = new Map();
|
|
570
|
+
// Throttle renders during streaming to prevent flicker (max ~15fps)
|
|
571
|
+
let renderTimer = null;
|
|
572
|
+
function throttledRender() {
|
|
573
|
+
if (renderTimer)
|
|
574
|
+
return;
|
|
575
|
+
renderTimer = setTimeout(() => {
|
|
576
|
+
renderTimer = null;
|
|
577
|
+
tui.requestRender();
|
|
578
|
+
}, 66);
|
|
579
|
+
}
|
|
580
|
+
function flushRender() {
|
|
581
|
+
if (renderTimer) {
|
|
582
|
+
clearTimeout(renderTimer);
|
|
583
|
+
renderTimer = null;
|
|
584
|
+
}
|
|
585
|
+
tui.requestRender();
|
|
586
|
+
}
|
|
567
587
|
agent.subscribe((event) => {
|
|
568
588
|
if (event.type === 'message_start') {
|
|
569
589
|
// Show loader while waiting for first text
|
|
@@ -590,30 +610,30 @@ Do NOT make up data. Always call tools to get current state.`;
|
|
|
590
610
|
if (currentAssistantMd) {
|
|
591
611
|
currentAssistantMd.setText(currentAssistantText);
|
|
592
612
|
}
|
|
593
|
-
|
|
613
|
+
// Throttled render to prevent flicker during fast token streaming
|
|
614
|
+
throttledRender();
|
|
594
615
|
}
|
|
595
616
|
}
|
|
596
|
-
if (event.type === '
|
|
617
|
+
if (event.type === 'message_end') {
|
|
597
618
|
// Clean up loader if still present (no text was generated)
|
|
598
619
|
if (currentLoader) {
|
|
599
620
|
currentLoader.stop();
|
|
600
621
|
chatContainer.removeChild(currentLoader);
|
|
601
622
|
currentLoader = null;
|
|
602
623
|
}
|
|
603
|
-
//
|
|
624
|
+
// Final render of the complete message
|
|
625
|
+
if (currentAssistantMd && currentAssistantText) {
|
|
626
|
+
currentAssistantMd.setText(currentAssistantText);
|
|
627
|
+
}
|
|
604
628
|
addSpacer();
|
|
605
629
|
currentAssistantMd = null;
|
|
606
630
|
currentAssistantText = '';
|
|
631
|
+
flushRender();
|
|
632
|
+
}
|
|
633
|
+
if (event.type === 'agent_end') {
|
|
634
|
+
// Agent turn fully complete — safe to accept new input
|
|
607
635
|
isProcessing = false;
|
|
608
|
-
|
|
609
|
-
// Update token/cost tracking from event if available
|
|
610
|
-
if (event.usage) {
|
|
611
|
-
totalTokens += (event.usage.inputTokens || 0) + (event.usage.outputTokens || 0);
|
|
612
|
-
totalCost += event.usage.totalCost || 0;
|
|
613
|
-
footerBar.tokens = totalTokens;
|
|
614
|
-
footerBar.cost = totalCost;
|
|
615
|
-
footerBar.update();
|
|
616
|
-
}
|
|
636
|
+
flushRender();
|
|
617
637
|
}
|
|
618
638
|
if (event.type === 'tool_execution_start') {
|
|
619
639
|
const toolLine = new MutableLine(C.zinc600(` \u26A1 ${event.toolName}...`));
|