1Branch0Tags
GL
glucryptoRefresh package-lock for opentool 0.19.5
01acdef14 hours ago17Commits
typescript
import type { ToolProfile } from "opentool"; import { backtestDecisionRequestSchema, resolveBacktestMode } from "opentool/backtest"; import { store } from "opentool/store"; import { requestOverrideSchema, resolveProfileAssets, resolveRuntimeConfig, resolveScheduleConfig, NEWS_BOT_TEMPLATE_CONFIG, } from "../src/config"; import { buildBacktestDecisionSeries, runSimpleNewsBot, runSimpleNewsBotBacktest, } from "../src/news-bot"; const config = resolveRuntimeConfig(); export const schema = requestOverrideSchema.or(backtestDecisionRequestSchema.partial()); type BacktestAwareToolProfile = ToolProfile & { backtest?: { mode: "decisions"; }; }; export const profile: BacktestAwareToolProfile = { description: "News-driven strategy bot with optional Hyperliquid execution and replay support.", category: "strategy", backtest: { mode: "decisions", }, schedule: resolveScheduleConfig(config), assets: resolveProfileAssets(config), templatePreview: { subtitle: "News signal strategy with execution-aware replay.", description: `Reads a configured event or proposition signal from the gateway-backed news system. Maps validated news outcomes to buy / close decisions. Can submit standardized Hyperliquid orders when execution is enabled. Supports hourly replay and decision-series backtests for event-driven strategy validation.`, }, templateConfig: NEWS_BOT_TEMPLATE_CONFIG, }; export async function POST(req: Request) { const payload = await req.json().catch(() => null); const mode = payload && typeof payload === "object" && !Array.isArray(payload) ? (payload as { mode?: unknown }).mode : null; const normalizedMode = resolveBacktestMode(mode); if (normalizedMode === "backtest_decisions") { try { const parsed = backtestDecisionRequestSchema.safeParse(payload); if (!parsed.success) { return new Response( JSON.stringify({ ok: false, error: parsed.error.issues[0]?.message ?? "invalid backtest request payload", }), { status: 400, headers: { "content-type": "application/json" }, }, ); } const runtimeConfig = resolveRuntimeConfig(); const decisionSeries = await buildBacktestDecisionSeries({ config: runtimeConfig, request: parsed.data, }); return Response.json({ ok: true, mode: normalizedMode, backtest: decisionSeries, }); } catch (error) { const message = error instanceof Error ? error.message : "unknown"; return new Response(JSON.stringify({ ok: false, error: message }), { status: 400, headers: { "content-type": "application/json" }, }); } } const parsed = requestOverrideSchema.safeParse(payload ?? {}); if (!parsed.success) { return new Response( JSON.stringify({ ok: false, error: parsed.error.issues[0]?.message ?? "invalid request payload", }), { status: 400, headers: { "content-type": "application/json" }, }, ); } try { const runtimeConfig = resolveRuntimeConfig(parsed.data); const result = parsed.data.backtest ? await runSimpleNewsBotBacktest(runtimeConfig, parsed.data.backtest) : await runSimpleNewsBot(runtimeConfig, parsed.data.asOf ?? null); await store({ source: "news-bot", ref: `news-bot-${Date.now()}`, status: "info", action: parsed.data.backtest ? "news_signal_backtest" : "news_signal", metadata: result, }); return Response.json(result); } catch (error) { const message = error instanceof Error ? error.message : "unknown"; await store({ source: "news-bot", ref: `news-bot-${Date.now()}`, status: "failed", action: parsed.data.backtest ? "news_signal_backtest" : "news_signal", metadata: { ok: false, error: message }, }); return new Response(JSON.stringify({ ok: false, error: message }), { status: 400, headers: { "content-type": "application/json" }, }); } }