Gate Telegram market context for Leo research (#18)
This commit is contained in:
parent
bfc28e084b
commit
533295d38c
3 changed files with 48 additions and 3 deletions
|
|
@ -60,6 +60,7 @@ from http_chat_proxy import (
|
||||||
extract_paid_work_order_id,
|
extract_paid_work_order_id,
|
||||||
extract_smart_research_goal,
|
extract_smart_research_goal,
|
||||||
post_chat_proxy,
|
post_chat_proxy,
|
||||||
|
should_attach_structured_market_context,
|
||||||
smart_research_command_names,
|
smart_research_command_names,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -1208,9 +1209,12 @@ async def handle_tagged(update: Update, context: ContextTypes.DEFAULT_TYPE):
|
||||||
if AGENT_HTTP_RESEARCH_PROXY_URL and smart_research_goal:
|
if AGENT_HTTP_RESEARCH_PROXY_URL and smart_research_goal:
|
||||||
payment_gate = _smart_research_payment_gate(msg.chat_id)
|
payment_gate = _smart_research_payment_gate(msg.chat_id)
|
||||||
proxy_research_goal = smart_research_goal
|
proxy_research_goal = smart_research_goal
|
||||||
market_context, market_data_audit, market_duration, market_tokens = await _market_context_for_message(
|
if should_attach_structured_market_context(smart_research_goal):
|
||||||
smart_research_goal
|
market_context, market_data_audit, market_duration, market_tokens = await _market_context_for_message(
|
||||||
)
|
smart_research_goal
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
market_context, market_data_audit, market_duration, market_tokens = "", {}, 0, []
|
||||||
if market_context:
|
if market_context:
|
||||||
logger.info(
|
logger.info(
|
||||||
"%s smart research added structured market context for %s in %dms",
|
"%s smart research added structured market context for %s in %dms",
|
||||||
|
|
|
||||||
|
|
@ -50,6 +50,22 @@ _PAID_WORK_ORDER_ID_RE = re.compile(
|
||||||
r"\b((?:sponsored_work_orders|payment_receipts):[a-f0-9]{16,64})\b",
|
r"\b((?:sponsored_work_orders|payment_receipts):[a-f0-9]{16,64})\b",
|
||||||
re.IGNORECASE,
|
re.IGNORECASE,
|
||||||
)
|
)
|
||||||
|
_MARKET_CONTEXT_RE = re.compile(
|
||||||
|
r"\b("
|
||||||
|
r"volume|fdv|fully\s+diluted|market\s+cap|mcap|liquidity|price|chart|"
|
||||||
|
r"token|coin|pair|pool|dex|dexscreener|birdeye|jupiter|"
|
||||||
|
r"buy|sell|should\s+i|yes\s+or\s+no"
|
||||||
|
r")\b",
|
||||||
|
re.IGNORECASE,
|
||||||
|
)
|
||||||
|
_SOCIAL_DISCUSSION_RE = re.compile(
|
||||||
|
r"\b(twitter|x\.com|x\/twitter|tweet|tweets|social)\b.*"
|
||||||
|
r"\b(current|latest|recent|discussion|discussions|trend|trends|narrative|sentiment|fault|blame|position|stance)\b"
|
||||||
|
r"|"
|
||||||
|
r"\b(current|latest|recent|discussion|discussions|trend|trends|narrative|sentiment|fault|blame|position|stance)\b.*"
|
||||||
|
r"\b(twitter|x\.com|x\/twitter|tweet|tweets|social)\b",
|
||||||
|
re.IGNORECASE,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def smart_research_command_names(
|
def smart_research_command_names(
|
||||||
|
|
@ -158,6 +174,16 @@ def extract_paid_work_order_id(message: str) -> str | None:
|
||||||
return match.group(1)
|
return match.group(1)
|
||||||
|
|
||||||
|
|
||||||
|
def should_attach_structured_market_context(message: str) -> bool:
|
||||||
|
"""Return true only for explicit market-data questions, not social narrative research."""
|
||||||
|
text = message.strip()
|
||||||
|
if not text:
|
||||||
|
return False
|
||||||
|
if _SOCIAL_DISCUSSION_RE.search(text):
|
||||||
|
return False
|
||||||
|
return bool(_MARKET_CONTEXT_RE.search(text))
|
||||||
|
|
||||||
|
|
||||||
def build_smart_research_proxy_payload(
|
def build_smart_research_proxy_payload(
|
||||||
*,
|
*,
|
||||||
research_goal: str,
|
research_goal: str,
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ from http_chat_proxy import ( # noqa: E402
|
||||||
extract_paid_work_order_id,
|
extract_paid_work_order_id,
|
||||||
extract_chat_proxy_reply,
|
extract_chat_proxy_reply,
|
||||||
extract_smart_research_goal,
|
extract_smart_research_goal,
|
||||||
|
should_attach_structured_market_context,
|
||||||
smart_research_command_names,
|
smart_research_command_names,
|
||||||
)
|
)
|
||||||
from market_data import extract_market_data_tokens, format_price_context # noqa: E402
|
from market_data import extract_market_data_tokens, format_price_context # noqa: E402
|
||||||
|
|
@ -238,6 +239,20 @@ def test_market_data_token_extraction_maps_natural_market_question():
|
||||||
assert extract_market_data_tokens(message) == ["OMFG", "AVICI", "UMBRA"]
|
assert extract_market_data_tokens(message) == ["OMFG", "AVICI", "UMBRA"]
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
("message", "expected"),
|
||||||
|
[
|
||||||
|
("what is the volume and fdv of omnipair avici umbra? should i buy them yes or no", True),
|
||||||
|
("show me price and liquidity for AVICI", True),
|
||||||
|
("what are the current discussions about MetaDAO Ranger Finance on Twitter?", False),
|
||||||
|
("who was at fault for Ranger according to Twitter?", False),
|
||||||
|
("how much revenue does MetaDAO make today?", False),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
def test_should_attach_structured_market_context_only_for_market_data_intent(message, expected):
|
||||||
|
assert should_attach_structured_market_context(message) is expected
|
||||||
|
|
||||||
|
|
||||||
def test_market_data_context_formats_dexscreener_fdv_volume_liquidity():
|
def test_market_data_context_formats_dexscreener_fdv_volume_liquidity():
|
||||||
context = format_price_context(
|
context = format_price_context(
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue