fix: improve AI coach chat context, 128k window, and output limits
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -9,7 +9,13 @@ from typing import Any, Optional
|
||||
|
||||
import httpx
|
||||
|
||||
from hub_ai.config import FUND_HISTORY_DAYS, hub_agent_timeout, hub_flask_timeout, trading_day_reset_hour
|
||||
from hub_ai.config import (
|
||||
CHAT_CONTEXT_MAX_CHARS,
|
||||
FUND_HISTORY_DAYS,
|
||||
hub_agent_timeout,
|
||||
hub_flask_timeout,
|
||||
trading_day_reset_hour,
|
||||
)
|
||||
from hub_ai.fund_history import format_fund_history_text, get_fund_history, record_fund_snapshot
|
||||
from hub_trades_lib import current_trading_day, summarize_trades
|
||||
|
||||
@@ -706,15 +712,71 @@ def format_chat_position_overview(payload: dict) -> str:
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
def format_chat_context_for_chat(payload: dict, max_chars: int = 5200) -> str:
|
||||
def format_chat_context_slim(payload: dict) -> str:
|
||||
"""聊天专用:不含 180 日资金曲线与昨日平仓明细,避免挤占对话上下文。"""
|
||||
totals = payload.get("totals") or {}
|
||||
day = totals.get("trading_day")
|
||||
lines = [
|
||||
f"【今日合计 {day}】平仓盈亏 {totals.get('total_pnl_u')}U | "
|
||||
f"笔数 {totals.get('closed_count')}(胜{totals.get('win_count')}/负{totals.get('loss_count')})| "
|
||||
f"实盘持仓 {totals.get('open_position_count', 0)} 仓 | 浮盈亏 {totals.get('float_pnl_u')}U",
|
||||
"【说明】持仓=交易所实盘;趋势/关键位/监控单=本地计划,不等于已开仓。",
|
||||
]
|
||||
for ac in payload.get("accounts") or []:
|
||||
if ac.get("status") == "未监控":
|
||||
lines.append(f"- {ac.get('name')}:未监控")
|
||||
continue
|
||||
st = ac.get("trade_stats") or {}
|
||||
open_n = int(ac.get("open_position_count") or _account_open_position_count(ac))
|
||||
pos_txt = "空仓" if open_n <= 0 else f"{open_n}仓 浮盈亏{ac.get('float_pnl_u')}U"
|
||||
mc = _monitor_counts(ac)
|
||||
mon = []
|
||||
if mc["trends"]:
|
||||
mon.append(f"趋势{mc['trends']}")
|
||||
if mc["rolls"]:
|
||||
mon.append(f"加仓{mc['rolls']}")
|
||||
if mc["keys"]:
|
||||
mon.append(f"关键位{mc['keys']}")
|
||||
if mc["orders"]:
|
||||
mon.append(f"监控单{mc['orders']}")
|
||||
mon_txt = f";监控 {'/'.join(mon)}" if mon else ""
|
||||
lines.append(
|
||||
f"- {ac.get('name')}:{pos_txt} | 今日盈亏{st.get('total_pnl_u')}U "
|
||||
f"({st.get('closed_count')}笔) | 资金{_fmt_fund(ac.get('funding_usdt'))} "
|
||||
f"交易{_fmt_fund(ac.get('trading_usdt'))}{mon_txt}"
|
||||
)
|
||||
trades = ac.get("trades") or []
|
||||
if trades:
|
||||
for t in trades[:4]:
|
||||
lines.append(f" · {_format_trade_line(t)}")
|
||||
if len(trades) > 4:
|
||||
lines.append(f" · …共{len(trades)}笔今日平仓")
|
||||
positions = ac.get("positions") or []
|
||||
for p in positions[:4]:
|
||||
if not isinstance(p, dict):
|
||||
continue
|
||||
sym = p.get("symbol") or "?"
|
||||
side = p.get("side") or "?"
|
||||
upnl = _position_float_pnl(p)
|
||||
lines.append(f" · 持仓 {sym} {side} 浮盈亏{upnl:.4f}U")
|
||||
return "\n".join(lines)
|
||||
|
||||
|
||||
def format_chat_context_for_chat(
|
||||
payload: dict,
|
||||
max_chars: int = CHAT_CONTEXT_MAX_CHARS,
|
||||
) -> str:
|
||||
overview = format_chat_position_overview(payload)
|
||||
body = format_context_text(payload)
|
||||
body = str(payload.get("text") or "").strip() or format_context_text(payload)
|
||||
text = overview + "\n\n" + body
|
||||
if len(text) <= max_chars:
|
||||
return text
|
||||
budget = max(800, max_chars - len(overview) - 4)
|
||||
return overview + "\n\n" + body[:budget].rstrip() + "..."
|
||||
budget = max(2000, max_chars - len(overview) - 4)
|
||||
return overview + "\n\n" + body[:budget].rstrip() + "…"
|
||||
|
||||
|
||||
def format_chat_context_brief(payload: dict, max_chars: int = 4500) -> str:
|
||||
def format_chat_context_brief(
|
||||
payload: dict,
|
||||
max_chars: int = CHAT_CONTEXT_MAX_CHARS,
|
||||
) -> str:
|
||||
return format_chat_context_for_chat(payload, max_chars=max_chars)
|
||||
|
||||
Reference in New Issue
Block a user