Spaces:
Running
Running
Clean rewrite text, remove junk phrases, better prompt"
Browse files- app_entry.py +41 -17
app_entry.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
| 1 |
-
"""Wrapper: kill old renderers FIRST,
|
| 2 |
from ai_runtime_patch_fast import *
|
| 3 |
from ai_runtime_patch_fast import app, f5, f6, rt, PATCH_INJECT, _scrape, _domain, clean, _bg, _bg_home, _bg_shorts
|
| 4 |
from patch_extra import EXTRA_FIX
|
|
@@ -25,7 +25,6 @@ def _homepage_fast():
|
|
| 25 |
return JSONResponse(_bg_home['d'])
|
| 26 |
threading.Thread(target=_bg,daemon=True).start()
|
| 27 |
return JSONResponse([])
|
| 28 |
-
|
| 29 |
@app.get('/api/shorts')
|
| 30 |
def _shorts_fast(refresh:int=Query(default=0)):
|
| 31 |
if _bg_shorts['d']:
|
|
@@ -41,6 +40,15 @@ def _extract_title(text):
|
|
| 41 |
first=re.sub(r'^[#*\-•\d\.\)\s]+','',lines[0]).strip()
|
| 42 |
if 10<=len(first)<=120:return first
|
| 43 |
return lines[0][:100] if lines else 'Bài viết AI'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 44 |
def _source_image(sources, details):
|
| 45 |
for s in (details or []):
|
| 46 |
if s.get('url'):
|
|
@@ -70,8 +78,10 @@ async def _tp(request:Request):
|
|
| 70 |
try:text=await asyncio.wait_for(f5.base.qwen_generate(f'Viết bài tiếng Việt VỀ: "{topic}"\nNGUỒN:\n{sb[:18000]}\nCHỈ viết về "{topic}". 5-8 đoạn. Cuối có nguồn.',image_url=img,max_tokens=1700),timeout=35)
|
| 71 |
except:pass
|
| 72 |
if not text or len(text)<300:text=f"{topic}: tổng hợp\n\n"+'\n'.join([f"• {d['title']}: {d.get('content','')[:300]}" for d in (det or [])[:6]])+"\n\nNguồn: "+', '.join(sorted({d.get('via','') for d in (det or []) if d.get('via')}))
|
|
|
|
| 73 |
post=f5.base.make_post(topic,text,img,'','topic_focused',sources=[s for s in src if s.get('url')]);post['images']=[img];post['source_details']=det
|
| 74 |
ps=f5.base._load_ai_wall();ps.insert(0,post);f5.base._save_ai_wall(ps);return JSONResponse({'post':post})
|
|
|
|
| 75 |
@app.post('/api/rewrite_share')
|
| 76 |
@app.post('/api/url_wall')
|
| 77 |
async def _rw(request:Request):
|
|
@@ -81,14 +91,28 @@ async def _rw(request:Request):
|
|
| 81 |
if len(raw)<50:raw=ctx[:14000]
|
| 82 |
if len(raw)<50:return JSONResponse({'error':'Không đọc được bài'},status_code=422)
|
| 83 |
img=_ensure_img(img)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 84 |
text=None
|
| 85 |
-
try:text=await asyncio.wait_for(f5.base.qwen_generate(
|
| 86 |
except:pass
|
| 87 |
if not text or len(text)<80:text=f"{title}\n\n{raw[:1200]}\n\nNguồn: {_domain(url)}"
|
|
|
|
| 88 |
ai_title=_extract_title(text);lines=text.strip().split('\n')
|
| 89 |
body_text='\n'.join(lines[1:]).strip() if lines and lines[0].strip()==ai_title else text
|
|
|
|
| 90 |
post=f5.base.make_post(ai_title,body_text,img,url,'rewrite',sources=[{'title':title,'url':url,'via':_domain(url)}])
|
| 91 |
ps=f5.base._load_ai_wall();ps.insert(0,post);f5.base._save_ai_wall(ps);return JSONResponse({'post':post})
|
|
|
|
| 92 |
@app.post('/api/topic/rewrite')
|
| 93 |
async def _tr(request:Request):
|
| 94 |
b=await request.json();pid=str(b.get('post_id','')).strip()
|
|
@@ -103,43 +127,43 @@ async def _tr(request:Request):
|
|
| 103 |
if not best_img and uimg and len(uimg)>20:best_img=uimg
|
| 104 |
ac='\n---\n'.join(parts) if parts else (p.get('text') or '')
|
| 105 |
img=_ensure_img(best_img or p.get('img',''))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 106 |
text=None
|
| 107 |
-
try:text=await asyncio.wait_for(f5.base.qwen_generate(
|
| 108 |
except:pass
|
| 109 |
if not text or len(text)<100:text=f"Tóm tắt: {p.get('title','')}\n\n{ac[:1500]}\n\nNguồn: VNEWS AI"
|
|
|
|
| 110 |
ai_title=_extract_title(text);lines=text.strip().split('\n')
|
| 111 |
body_text='\n'.join(lines[1:]).strip() if lines and lines[0].strip()==ai_title else text
|
|
|
|
| 112 |
np=f5.base.make_post(ai_title,body_text,img,'','rewrite_topic',sources=p.get('sources',[]));np['images']=[img]
|
| 113 |
all_p=f5.base._load_ai_wall();all_p.insert(0,np);f5.base._save_ai_wall(all_p);return JSONResponse({'post':np})
|
| 114 |
|
| 115 |
-
# === CRITICAL: Script that runs BEFORE all old injects to prevent slide destruction ===
|
| 116 |
PRE_KILL_SCRIPT = r'''
|
| 117 |
<script>
|
| 118 |
-
// PRE-KILL: Override destructive functions BEFORE old inject code defines and calls them
|
| 119 |
Object.defineProperty(window,'renderTopicWallE',{get:function(){return function(){}},set:function(){},configurable:true});
|
| 120 |
Object.defineProperty(window,'renderAIShortHome',{get:function(){return function(){}},set:function(){},configurable:true});
|
| 121 |
Object.defineProperty(window,'renderAIShorts7',{get:function(){return function(){}},set:function(){},configurable:true});
|
| 122 |
</script>
|
| 123 |
'''
|
| 124 |
|
| 125 |
-
HIGHLIGHT_FIX = r'''
|
| 126 |
-
<style>
|
| 127 |
-
.vp-wrap{aspect-ratio:1/1!important;width:100%!important;max-height:100vh!important;background:#000!important;position:relative!important}
|
| 128 |
-
.vp-wrap video,.vp-wrap iframe{width:100%!important;height:100%!important;object-fit:contain!important}
|
| 129 |
-
.vp-wrap .vp-ratio-btn{display:none!important}
|
| 130 |
-
</style>
|
| 131 |
-
'''
|
| 132 |
-
|
| 133 |
@app.get('/')
|
| 134 |
async def _index_final():
|
| 135 |
html=f5.f4.f3.f2.f1._load_index_html()
|
| 136 |
-
# PRE-KILL goes FIRST before any old inject can run
|
| 137 |
body=PRE_KILL_SCRIPT
|
| 138 |
body+=getattr(rt.old,'PATCH_INJECT','')+f5.f4.f3.f2.f1.FINAL_INJECT+f5.f4.f3.FINAL3_INJECT+f5.f4.FINAL4_INJECT+f5.FINAL5_INJECT
|
| 139 |
body+=getattr(f6,'FINAL6_INJECT','')
|
| 140 |
body+=getattr(f6,'FINAL6_FAST_HOME_INJECT','')
|
| 141 |
-
# NO FINAL6E_INJECT
|
| 142 |
body+=PATCH_INJECT
|
| 143 |
body+=EXTRA_FIX
|
| 144 |
-
body+=HIGHLIGHT_FIX
|
| 145 |
return HTMLResponse(html.replace('</body>',body+'\n</body>') if '</body>' in html else html+body)
|
|
|
|
| 1 |
+
"""Wrapper: kill old renderers FIRST, highlight TikTok feed, clean rewrite, single wall."""
|
| 2 |
from ai_runtime_patch_fast import *
|
| 3 |
from ai_runtime_patch_fast import app, f5, f6, rt, PATCH_INJECT, _scrape, _domain, clean, _bg, _bg_home, _bg_shorts
|
| 4 |
from patch_extra import EXTRA_FIX
|
|
|
|
| 25 |
return JSONResponse(_bg_home['d'])
|
| 26 |
threading.Thread(target=_bg,daemon=True).start()
|
| 27 |
return JSONResponse([])
|
|
|
|
| 28 |
@app.get('/api/shorts')
|
| 29 |
def _shorts_fast(refresh:int=Query(default=0)):
|
| 30 |
if _bg_shorts['d']:
|
|
|
|
| 40 |
first=re.sub(r'^[#*\-•\d\.\)\s]+','',lines[0]).strip()
|
| 41 |
if 10<=len(first)<=120:return first
|
| 42 |
return lines[0][:100] if lines else 'Bài viết AI'
|
| 43 |
+
|
| 44 |
+
def _clean_rewrite_text(text):
|
| 45 |
+
"""Remove junk phrases from AI rewrite output."""
|
| 46 |
+
if not text:return text
|
| 47 |
+
junk=['xem trên vnews','xem trên VNEWS','Xem trên VNEWS','📖 Xem trên VNEWS','đọc trên vnews','Đọc trên VNEWS','📖 Đọc trên','Mở nguồn gốc','mở nguồn gốc']
|
| 48 |
+
for j in junk:text=text.replace(j,'')
|
| 49 |
+
text=re.sub(r'\n{3,}','\n\n',text)
|
| 50 |
+
return text.strip()
|
| 51 |
+
|
| 52 |
def _source_image(sources, details):
|
| 53 |
for s in (details or []):
|
| 54 |
if s.get('url'):
|
|
|
|
| 78 |
try:text=await asyncio.wait_for(f5.base.qwen_generate(f'Viết bài tiếng Việt VỀ: "{topic}"\nNGUỒN:\n{sb[:18000]}\nCHỈ viết về "{topic}". 5-8 đoạn. Cuối có nguồn.',image_url=img,max_tokens=1700),timeout=35)
|
| 79 |
except:pass
|
| 80 |
if not text or len(text)<300:text=f"{topic}: tổng hợp\n\n"+'\n'.join([f"• {d['title']}: {d.get('content','')[:300]}" for d in (det or [])[:6]])+"\n\nNguồn: "+', '.join(sorted({d.get('via','') for d in (det or []) if d.get('via')}))
|
| 81 |
+
text=_clean_rewrite_text(text)
|
| 82 |
post=f5.base.make_post(topic,text,img,'','topic_focused',sources=[s for s in src if s.get('url')]);post['images']=[img];post['source_details']=det
|
| 83 |
ps=f5.base._load_ai_wall();ps.insert(0,post);f5.base._save_ai_wall(ps);return JSONResponse({'post':post})
|
| 84 |
+
|
| 85 |
@app.post('/api/rewrite_share')
|
| 86 |
@app.post('/api/url_wall')
|
| 87 |
async def _rw(request:Request):
|
|
|
|
| 91 |
if len(raw)<50:raw=ctx[:14000]
|
| 92 |
if len(raw)<50:return JSONResponse({'error':'Không đọc được bài'},status_code=422)
|
| 93 |
img=_ensure_img(img)
|
| 94 |
+
prompt=f"""Tóm tắt bài viết thành bản tin ngắn gọn. Dòng đầu tiên phải là tiêu đề mới hấp dẫn.
|
| 95 |
+
|
| 96 |
+
Tiêu đề gốc (tham khảo): {title}
|
| 97 |
+
Nội dung bài:
|
| 98 |
+
{raw[:14000]}
|
| 99 |
+
|
| 100 |
+
Yêu cầu:
|
| 101 |
+
- Dòng 1: Tiêu đề MỚI ngắn gọn, hấp dẫn (không copy tiêu đề gốc).
|
| 102 |
+
- Tiếp: 4-6 ý chính tóm tắt nội dung.
|
| 103 |
+
- Cuối: ghi nguồn.
|
| 104 |
+
- KHÔNG viết "xem trên VNEWS", "đọc trên VNEWS", "mở nguồn gốc" hay bất kỳ cụm điều hướng nào."""
|
| 105 |
text=None
|
| 106 |
+
try:text=await asyncio.wait_for(f5.base.qwen_generate(prompt,image_url=img,max_tokens=1000),timeout=30)
|
| 107 |
except:pass
|
| 108 |
if not text or len(text)<80:text=f"{title}\n\n{raw[:1200]}\n\nNguồn: {_domain(url)}"
|
| 109 |
+
text=_clean_rewrite_text(text)
|
| 110 |
ai_title=_extract_title(text);lines=text.strip().split('\n')
|
| 111 |
body_text='\n'.join(lines[1:]).strip() if lines and lines[0].strip()==ai_title else text
|
| 112 |
+
body_text=_clean_rewrite_text(body_text)
|
| 113 |
post=f5.base.make_post(ai_title,body_text,img,url,'rewrite',sources=[{'title':title,'url':url,'via':_domain(url)}])
|
| 114 |
ps=f5.base._load_ai_wall();ps.insert(0,post);f5.base._save_ai_wall(ps);return JSONResponse({'post':post})
|
| 115 |
+
|
| 116 |
@app.post('/api/topic/rewrite')
|
| 117 |
async def _tr(request:Request):
|
| 118 |
b=await request.json();pid=str(b.get('post_id','')).strip()
|
|
|
|
| 127 |
if not best_img and uimg and len(uimg)>20:best_img=uimg
|
| 128 |
ac='\n---\n'.join(parts) if parts else (p.get('text') or '')
|
| 129 |
img=_ensure_img(best_img or p.get('img',''))
|
| 130 |
+
prompt=f"""Viết lại thành bản tóm tắt mới. Dòng đầu là tiêu đề mới hấp dẫn.
|
| 131 |
+
|
| 132 |
+
Chủ đề gốc: {p.get('title','')}
|
| 133 |
+
Nguồn:
|
| 134 |
+
{ac[:16000]}
|
| 135 |
+
|
| 136 |
+
Yêu cầu:
|
| 137 |
+
- Dòng 1: Tiêu đề MỚI.
|
| 138 |
+
- Tiếp: 4-6 ý chính.
|
| 139 |
+
- Cuối: nguồn tham khảo.
|
| 140 |
+
- KHÔNG viết "xem trên VNEWS" hay bất kỳ cụm điều hướng nào."""
|
| 141 |
text=None
|
| 142 |
+
try:text=await asyncio.wait_for(f5.base.qwen_generate(prompt,image_url=img,max_tokens=1200),timeout=35)
|
| 143 |
except:pass
|
| 144 |
if not text or len(text)<100:text=f"Tóm tắt: {p.get('title','')}\n\n{ac[:1500]}\n\nNguồn: VNEWS AI"
|
| 145 |
+
text=_clean_rewrite_text(text)
|
| 146 |
ai_title=_extract_title(text);lines=text.strip().split('\n')
|
| 147 |
body_text='\n'.join(lines[1:]).strip() if lines and lines[0].strip()==ai_title else text
|
| 148 |
+
body_text=_clean_rewrite_text(body_text)
|
| 149 |
np=f5.base.make_post(ai_title,body_text,img,'','rewrite_topic',sources=p.get('sources',[]));np['images']=[img]
|
| 150 |
all_p=f5.base._load_ai_wall();all_p.insert(0,np);f5.base._save_ai_wall(all_p);return JSONResponse({'post':np})
|
| 151 |
|
|
|
|
| 152 |
PRE_KILL_SCRIPT = r'''
|
| 153 |
<script>
|
|
|
|
| 154 |
Object.defineProperty(window,'renderTopicWallE',{get:function(){return function(){}},set:function(){},configurable:true});
|
| 155 |
Object.defineProperty(window,'renderAIShortHome',{get:function(){return function(){}},set:function(){},configurable:true});
|
| 156 |
Object.defineProperty(window,'renderAIShorts7',{get:function(){return function(){}},set:function(){},configurable:true});
|
| 157 |
</script>
|
| 158 |
'''
|
| 159 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 160 |
@app.get('/')
|
| 161 |
async def _index_final():
|
| 162 |
html=f5.f4.f3.f2.f1._load_index_html()
|
|
|
|
| 163 |
body=PRE_KILL_SCRIPT
|
| 164 |
body+=getattr(rt.old,'PATCH_INJECT','')+f5.f4.f3.f2.f1.FINAL_INJECT+f5.f4.f3.FINAL3_INJECT+f5.f4.FINAL4_INJECT+f5.FINAL5_INJECT
|
| 165 |
body+=getattr(f6,'FINAL6_INJECT','')
|
| 166 |
body+=getattr(f6,'FINAL6_FAST_HOME_INJECT','')
|
|
|
|
| 167 |
body+=PATCH_INJECT
|
| 168 |
body+=EXTRA_FIX
|
|
|
|
| 169 |
return HTMLResponse(html.replace('</body>',body+'\n</body>') if '</body>' in html else html+body)
|