
    -Ojl                        d Z ddlZddlZddlZddlZddlZddlZddlmZm	Z	 ej                  j                  ej                  j                  e            Zej                  j                  de       ej                  j                  dej                  j                  e             ddlmZmZmZmZ ddlmZ dZdZdZd	Zdd
Zd Zd Zd Zedk(  r e        yy)a[  Paper of the day: pick the single most relevant unfeatured paper from the
research feed, read the FULL paper (not the abstract), and produce a deep-dive
podcast episode ending with what it means for the Lakota language work.

Selection and summarization both run on the local model; the paper PDF comes
from arXiv. featured.json prevents repeats.
    N)datetimetimezone)
tts_to_mp3rebuild_rss
llm_scriptEPISODES)RESEARCH_STATEMENTz)http://localhost:8000/v1/chat/completionszgemma4-26b-a4bz(https://edgexpert-83b2.tail6663b0.ts.netu}  You are writing a spoken deep-dive podcast script (one host,
5 to 8 minutes) about ONE research paper, for a listener who builds
community-sovereign language AI for Lakota (OCR of legacy texts, RAG grounded in
community-approved books, per-stage evaluation, community-governed data).

Cover, in plain spoken prose with no markdown and no URLs:
1. The problem the paper tackles and why it exists.
2. How their approach works — mechanics, not buzzwords.
3. The concrete findings, with the actual numbers.
4. Honest limitations.
5. Close with the most useful segment: what this means for the Lakota pipeline —
   what to adopt, what to test, what to ignore, and why.

CRITICAL: never attempt to pronounce Lakota or other Indigenous-language words;
describe them or spell them letter by letter, naming diacritics.

PAPER TITLE: {title}
WHY IT WAS FLAGGED: {why}
PAPER TEXT (truncated):
{text}
c                 ~   t         ||d| dgd}t        j                  j                  t        t        j                  |      j                         ddi      }t        j                  j                  |d      5 }t        j                  |      d	   d
   d   d   j                         cd d d        S # 1 sw Y   y xY w)Nuser)rolecontent)modeltemperature
max_tokensmessageszContent-Typezapplication/json)dataheadersi,  timeoutchoicesr   messager   )LLMurllibrequestRequestLLM_URLjsondumpsencodeurlopenloadstrip)promptr   r   bodyreqrs         1/home/mgrim/research-feed/podcast/paper_of_day.pyllmr(   -   s    J"(V<=?D
..
 
 tzz$/?/F/F/H*8:L)M ! OC			S		1 HQyy|I&q))4Y?EEGH H Hs   :/B33B<c                 H   dj                  d t        |       D              }t        dt         d| dd      }t	        j
                  t        j                  d|t        j                        j                  d	            }| t        |d
            |j                  dd      fS )zFAsk the local model to choose the one paper most relevant to the work.
c              3   D   K   | ]  \  }}d | d|d    d|d      yw)[z] titleu    — whyN ).0ics      r'   	<genexpr>zpick_paper.<locals>.<genexpr>8   s/     _A!A3b7E!E(<_s    zRESEARCH STATEMENT:
z


PAPERS:
z

Which ONE paper is most worth a deep-dive for this researcher today? Reply ONLY with JSON: {"index": <int>, "reason": "<one sentence>"}x   )r   z\{.*\}r   indexreason )join	enumerater(   r	   r   loadsresearchSgroupintget)
candidateslistingrawds       r'   
pick_paperrE   6   s    ii_S]I^__G
%&8%9wi PS S C 	

299YRTT288;<Ac!G*o&h(;;;    c           	      d   | j                  dd      }|j                  dd      t        j                  dd|j                  dd            |j                  dd      g}t        j                  j                  t        d      }|D ]  }	 t        j                  j                  |d	d
i      }t        j                  j                  |d      5 }|j                         }ddd       |j                  |j                  dd      dd       rTddd j                         v r?t        j                  dd|j                  dd            }t        j                  dd|      }nxt!        |d      j#                         	 t%        j&                  d|dgddd      j(                  }	 t        j                  j-                  |      rt        j.                  |       	 t1        |      dkD  sb|dd t1        |      dkD  rd|d d z   z   c S dz   c S  y# 1 sw Y   0xY w# t        $ r Y w xY w# t$        j*                  $ r: Y t        j                  j-                  |      st        j.                  |       w xY w# t        j                  j-                  |      rt        j.                  |       w w xY w)!zarXiv abs URL -> full text, or None if the paper has no fetchable body
    (some arXiv entries are abstract-only). Tries versioned PDF, unversioned
    PDF, then the HTML rendering.zhttp://zhttps://z/abs/z/pdf/zv\d+$r7   z/html/z
_paper.pdfz
User-AgentzMozilla/5.0)r   <   r   N   s   <html   z<[^>]+> zutf-8ignorez\s+wb	pdftotext-T)capture_outputtextchecki  i  i  z
[...]
i )replacer;   subospathr8   HEREr   r   r   r    read	Exception
startswithlowerdecodeopenwrite
subprocessrunstdoutCalledProcessErrorexistsremovelen)		arxiv_urlhttpstriespdf_pathurlr%   r&   r   txts	            r'   fetch_paper_textrl   A   sI    i4E]]7G,VVHb%--"AB]]7H-/E ww||D,/H Z	..((|]6S(TC''R'8  Avvx  >>%--:3B?@XQUVZWZQ[QaQaQcEc&&S$++gx*HIC&&c*C4 &&t,( nnk8S%ARV*.d<<BF 
 77>>(+IIh's8d?v;C5@P+FG"<YYVXYY+Z, '    		 00 77>>(+IIh'	 77>>(+IIh' ,sO   AHHH9&H(H	H	H%$H%(I5;I84I55I887J/c            	      B   t        j                  t        t        j                  j                  t        j                  j                  t              d                  } t        j                  j                  t        d      }t        j                  j                  |      r't        t        j                  t        |                  n	t               }| D cg c]  }|d   |vs| c}d d }|st        d       y d x}x}}t        d      D ]  }|s nt        |      \  }}t        d|d   d d	  d
|d d  dt        j                         t        |d         }|r nNt        dt        j                         |j!                  |d          |D 	cg c]  }	|	d   |d   k7  s|	 }}	d } |r|s5t        j"                  t%        |      t        |d             t        d       y t'        t(        j+                  |d   |d   |      dd      }
t-        j.                  t0        j2                        j5                  d      }t        j                  j                  t6        | d      }t9        |
|      }t        j"                  d|d   d d  | d|d    dt        |j;                  dd      d             |j!                  |d          t        j"                  t%        |      t        |d             t=        t>              }t        d| d| d       y c c}w c c}	w ) Nzhistory.jsonzfeatured.jsonid   u'   [paper] nothing unfeatured — skipping   z[paper] selected: r-   F   z (P   ))fileu7   [paper] no fetchable full text — skipping permanentlywz [paper] no fetchable paper todayr.   )r-   r.   rQ   i  g333333?)r   r   z%Y%m%dz_paper_of_the_day.mp3u   Paper of the day — rK   )r-   descriptionz.mp3z.jsonz[paper] episode ready (u   s) · feed has z items) r   r!   r]   rU   rV   r8   dirnamerW   rc   setprintrangerE   sysstderrrl   adddumpsortedr(   DEEP_DIVE_PROMPTformatr   nowr   utcstrftimer   r   rS   r   BASE_URL)history	feat_pathfeaturedhrA   paperrQ   r6   _r2   scriptstampmp3durns                  r'   mainr   c   s   iiRWW\\"''//$*?PQRGT?3I24''..2Ks499T)_-.QTQVH$@$x(?!@"EJ78  E D61X ":.v"5>#2#6"7r&"+aHszzZd,GcjjYU4[!!+FAqw%+/EaF
F 		&"DC$8901!((uW~5<.2 ) 4@DRUWF LL&//9E
'',,xE7*?!@
AC
VS
!CII/gs0C/DE!'%+793;;vw/57 LLtIIfXY 45HA	#C5s&
ABE A  Gs   L#LL"L__main__)iX  r   ) __doc__rU   r{   r   r;   urllib.requestr   r_   r   r   rV   rw   abspath__file__rW   insertmake_episoder   r   r   r   
build_feedr	   r   r   r   r   r(   rE   rl   r   __name__r/   rF   r'   <module>r      s    5 4 4 '	wwrwwx01 4  277??4( ) F F )
55 .H<D&CR zF rF   