fix: suppress loguru noise in CLI, fix birdx text parser
- CLI now suppresses loguru INFO logs by default (use -v/--verbose to show) - Fixed birdx output parser to correctly extract author, url, date, text - birdx search now uses plain text output (--json returns empty arrays)
This commit is contained in:
parent
d891af5b7d
commit
e7cd04655e
2 changed files with 63 additions and 22 deletions
|
|
@ -17,15 +17,25 @@ import sys
|
|||
import asyncio
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
|
||||
from agent_eyes import __version__
|
||||
|
||||
|
||||
def _configure_logging(verbose: bool = False):
|
||||
"""Suppress loguru output unless --verbose is set."""
|
||||
from loguru import logger
|
||||
logger.remove() # Remove default stderr handler
|
||||
if verbose:
|
||||
logger.add(sys.stderr, level="INFO")
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(
|
||||
prog="agent-eyes",
|
||||
description="👁️ Give your AI Agent eyes to see the entire internet",
|
||||
)
|
||||
parser.add_argument("-v", "--verbose", action="store_true", help="Show debug logs")
|
||||
sub = parser.add_subparsers(dest="command", help="Available commands")
|
||||
|
||||
# ── read ──
|
||||
|
|
@ -66,6 +76,9 @@ def main():
|
|||
|
||||
args = parser.parse_args()
|
||||
|
||||
# Suppress loguru noise unless --verbose
|
||||
_configure_logging(getattr(args, "verbose", False))
|
||||
|
||||
if not args.command:
|
||||
parser.print_help()
|
||||
sys.exit(0)
|
||||
|
|
|
|||
|
|
@ -38,46 +38,74 @@ async def _search_birdx(query: str, limit: int) -> List[Dict[str, Any]]:
|
|||
"""Search Twitter via birdx CLI."""
|
||||
logger.info(f"birdx search: {query} (n={limit})")
|
||||
try:
|
||||
# birdx --json returns [] for search, so use plain text output
|
||||
result = subprocess.run(
|
||||
["birdx", "search", query, "-n", str(limit), "--json"],
|
||||
["birdx", "search", query, "-n", str(limit)],
|
||||
capture_output=True, text=True, timeout=30,
|
||||
)
|
||||
if result.returncode != 0:
|
||||
# birdx might not support --json, try plain output
|
||||
result = subprocess.run(
|
||||
["birdx", "search", query, "-n", str(limit)],
|
||||
capture_output=True, text=True, timeout=30,
|
||||
)
|
||||
return _parse_birdx_text(result.stdout)
|
||||
|
||||
data = json.loads(result.stdout)
|
||||
if isinstance(data, list):
|
||||
return data
|
||||
return data.get("tweets", data.get("results", []))
|
||||
except (subprocess.TimeoutExpired, json.JSONDecodeError, FileNotFoundError) as e:
|
||||
logger.error(f"birdx search failed: {result.stderr}")
|
||||
return []
|
||||
return _parse_birdx_text(result.stdout)
|
||||
except (subprocess.TimeoutExpired, FileNotFoundError) as e:
|
||||
logger.error(f"birdx search failed: {e}")
|
||||
return []
|
||||
|
||||
|
||||
def _parse_birdx_text(text: str) -> List[Dict[str, Any]]:
|
||||
"""Parse birdx plain text output into structured data."""
|
||||
"""Parse birdx plain text output into structured data.
|
||||
|
||||
Format:
|
||||
@handle (Display Name):
|
||||
Tweet text here
|
||||
possibly multiple lines
|
||||
date: Mon Feb 24 12:00:00 +0000 2026
|
||||
url: https://x.com/handle/status/123
|
||||
──────────────────────────────────────────────────
|
||||
"""
|
||||
results = []
|
||||
current = {}
|
||||
current: Dict[str, Any] = {}
|
||||
text_lines = []
|
||||
|
||||
for line in text.strip().split("\n"):
|
||||
line = line.strip()
|
||||
if not line:
|
||||
|
||||
# Separator between tweets
|
||||
if line.startswith("─"):
|
||||
if current:
|
||||
if text_lines:
|
||||
current["text"] = "\n".join(text_lines).strip()
|
||||
results.append(current)
|
||||
current = {}
|
||||
text_lines = []
|
||||
continue
|
||||
if line.startswith("@"):
|
||||
current["author"] = line.split()[0] if line else ""
|
||||
elif line.startswith("http"):
|
||||
current["url"] = line
|
||||
else:
|
||||
current["text"] = current.get("text", "") + " " + line
|
||||
|
||||
# Author line: @handle (Display Name):
|
||||
if line.startswith("@") and line.endswith(":") and "(" in line:
|
||||
handle = line.split()[0]
|
||||
current["author"] = handle
|
||||
continue
|
||||
|
||||
# Date line
|
||||
if line.startswith("date:"):
|
||||
current["date"] = line[5:].strip()
|
||||
continue
|
||||
|
||||
# URL line
|
||||
if line.startswith("url:"):
|
||||
current["url"] = line[4:].strip()
|
||||
continue
|
||||
|
||||
# Content line
|
||||
if current:
|
||||
text_lines.append(line)
|
||||
|
||||
# Last tweet
|
||||
if current:
|
||||
if text_lines:
|
||||
current["text"] = "\n".join(text_lines).strip()
|
||||
results.append(current)
|
||||
|
||||
return results
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue