back to mistral
Browse files- components/LLMs/Bart.py +0 -50
- components/LLMs/LLama3.py +0 -43
- components/LLMs/TinyLLama.py +0 -34
- components/generators/daily_feed.py +6 -8
components/LLMs/Bart.py
DELETED
@@ -1,50 +0,0 @@
|
|
1 |
-
# components/LLMs/bart.py
|
2 |
-
|
3 |
-
import os
|
4 |
-
import requests
|
5 |
-
from typing import Optional
|
6 |
-
|
7 |
-
HF_TOKEN = os.environ.get("HF_TOKEN")
|
8 |
-
BART_URL = "https://c5dk65n3sd14gjo1.us-east-1.aws.endpoints.huggingface.cloud"
|
9 |
-
|
10 |
-
HEADERS = {
|
11 |
-
"Authorization": f"Bearer {HF_TOKEN}",
|
12 |
-
"Content-Type": "application/json"
|
13 |
-
}
|
14 |
-
|
15 |
-
|
16 |
-
def call_bart_summarizer(base_prompt: str, tail_prompt: str, max_length: int = 130) -> Optional[str]:
|
17 |
-
"""
|
18 |
-
Calls facebook/bart-large-cnn using HF Inference API with composed prompt.
|
19 |
-
|
20 |
-
Args:
|
21 |
-
base_prompt (str): Instruction or high-level instruction.
|
22 |
-
tail_prompt (str): News content or body.
|
23 |
-
max_length (int): Output summary length limit.
|
24 |
-
|
25 |
-
Returns:
|
26 |
-
str: Cleaned summary string, or None if error.
|
27 |
-
"""
|
28 |
-
full_input = f"{base_prompt.strip()}\n\n{tail_prompt.strip()}"
|
29 |
-
payload = {
|
30 |
-
"inputs": full_input,
|
31 |
-
"parameters": {
|
32 |
-
"max_length": max_length,
|
33 |
-
"do_sample": False
|
34 |
-
}
|
35 |
-
}
|
36 |
-
|
37 |
-
try:
|
38 |
-
response = requests.post(BART_URL, headers=HEADERS, json=payload, timeout=30)
|
39 |
-
response.raise_for_status()
|
40 |
-
result = response.json()
|
41 |
-
|
42 |
-
if isinstance(result, list) and result and "summary_text" in result[0]:
|
43 |
-
return result[0]["summary_text"].strip()
|
44 |
-
else:
|
45 |
-
print("⚠️ Unexpected BART response format:", result)
|
46 |
-
return None
|
47 |
-
|
48 |
-
except Exception as e:
|
49 |
-
print(f"⚠️ BART API call failed: {e}")
|
50 |
-
return None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
components/LLMs/LLama3.py
DELETED
@@ -1,43 +0,0 @@
|
|
1 |
-
import os
|
2 |
-
import requests
|
3 |
-
from typing import Optional
|
4 |
-
|
5 |
-
# 🔐 Environment Variables
|
6 |
-
LLAMA3_URL = "https://c5dk65n3sd14gjo1.us-east-1.aws.endpoints.huggingface.cloud"
|
7 |
-
HF_TOKEN = os.environ.get("HF_TOKEN")
|
8 |
-
|
9 |
-
# 📜 Headers
|
10 |
-
HEADERS = {
|
11 |
-
"Authorization": f"Bearer {HF_TOKEN}",
|
12 |
-
"Content-Type": "application/json"
|
13 |
-
}
|
14 |
-
|
15 |
-
# 🧠 Prompt builder and caller for LLaMA 3 8B (QCA)
|
16 |
-
def call_llama3_8b(base_prompt: str, tail_prompt: str) -> Optional[str]:
|
17 |
-
prompt = f"<s>[INST]{base_prompt}\n\n{tail_prompt}[/INST]</s>"
|
18 |
-
|
19 |
-
try:
|
20 |
-
response = requests.post(
|
21 |
-
LLAMA3_URL,
|
22 |
-
headers=HEADERS,
|
23 |
-
json={"inputs": prompt},
|
24 |
-
timeout=60
|
25 |
-
)
|
26 |
-
response.raise_for_status()
|
27 |
-
data = response.json()
|
28 |
-
|
29 |
-
# Parse generated output
|
30 |
-
if isinstance(data, list) and data:
|
31 |
-
raw_output = data[0].get("generated_text", "")
|
32 |
-
elif isinstance(data, dict):
|
33 |
-
raw_output = data.get("generated_text", "")
|
34 |
-
else:
|
35 |
-
return None
|
36 |
-
|
37 |
-
if "[/INST]</s>" in raw_output:
|
38 |
-
return raw_output.split("[/INST]</s>")[-1].strip()
|
39 |
-
return raw_output.strip()
|
40 |
-
|
41 |
-
except Exception as e:
|
42 |
-
print(f"⚠️ LLaMA 3.1 8B API call failed: {e}")
|
43 |
-
return None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
components/LLMs/TinyLLama.py
DELETED
@@ -1,34 +0,0 @@
|
|
1 |
-
import os
|
2 |
-
from transformers import pipeline
|
3 |
-
from typing import Optional
|
4 |
-
|
5 |
-
# Load model just once when module is imported
|
6 |
-
_tinyllama_pipeline = pipeline(
|
7 |
-
"text-generation",
|
8 |
-
model="TinyLlama/TinyLlama-1.1B-Chat-v1.0",
|
9 |
-
torch_dtype="auto",
|
10 |
-
device_map="auto"
|
11 |
-
)
|
12 |
-
|
13 |
-
def call_tinyllama(base_prompt: str, tail_prompt: str, max_new_tokens: int = 256) -> Optional[str]:
|
14 |
-
"""
|
15 |
-
Calls TinyLlama model with an instruction-tuned prompt.
|
16 |
-
|
17 |
-
Args:
|
18 |
-
base_prompt (str): Instruction or system prompt.
|
19 |
-
tail_prompt (str): User or content-specific prompt.
|
20 |
-
max_new_tokens (int): Max tokens to generate.
|
21 |
-
|
22 |
-
Returns:
|
23 |
-
str or None: The generated summary content.
|
24 |
-
"""
|
25 |
-
prompt = f"<s>[INST]{base_prompt}\n\n{tail_prompt}[/INST]</s>"
|
26 |
-
try:
|
27 |
-
result = _tinyllama_pipeline(prompt, max_new_tokens=max_new_tokens)
|
28 |
-
output = result[0]["generated_text"]
|
29 |
-
if "[/INST]" in output:
|
30 |
-
return output.split("[/INST]")[-1].strip()
|
31 |
-
return output.strip()
|
32 |
-
except Exception as e:
|
33 |
-
print(f"⚠️ TinyLlama error: {e}")
|
34 |
-
return None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
components/generators/daily_feed.py
CHANGED
@@ -9,9 +9,6 @@ from llama_index.core.query_engine import RetrieverQueryEngine
|
|
9 |
from llama_index.core.schema import Document
|
10 |
from llama_index.core.settings import Settings
|
11 |
from components.LLMs.Mistral import call_mistral
|
12 |
-
from components.LLMs.TinyLLama import call_tinyllama
|
13 |
-
from components.LLMs.Bart import call_bart_summarizer
|
14 |
-
from components.LLMs.LLama3 import call_llama3_8b
|
15 |
|
16 |
# ✅ Disable implicit LLM usage
|
17 |
Settings.llm = None
|
@@ -27,6 +24,7 @@ redis_client = redis.Redis.from_url(REDIS_URL, decode_responses=True)
|
|
27 |
TOPICS = ["India news", "World news", "Tech news", "Finance news", "Sports news"]
|
28 |
|
29 |
# 🧠 Base summarization prompt (used for all topics)
|
|
|
30 |
BASE_PROMPT = (
|
31 |
"You are Nuse’s official news summarizer — insightful, punchy, and always on point.\n"
|
32 |
"Your job is to scan the content below and extract the key news items. For each item, craft a crisp summary (15–20 words). Avoid using any emojis.\n"
|
@@ -35,7 +33,7 @@ BASE_PROMPT = (
|
|
35 |
"Example format:\n"
|
36 |
"- India stuns Australia in a last-ball thriller at the World Cup finals\n"
|
37 |
"- U.S. imposes sweeping tariffs on Chinese tech giants, rattling global markets\n"
|
38 |
-
"- Ceasefire breakthrough: Netanyahu (Prime minister of
|
39 |
"\n"
|
40 |
"If you are mentioning a person, include their designation in brackets. For example: Jeff Bezos (Amazon CEO), Narendra Modi (Prime minister of India).\n"
|
41 |
"If you're referencing a post like 'NATO Chief', also include the name of the person who holds the post.\n"
|
@@ -45,13 +43,12 @@ BASE_PROMPT = (
|
|
45 |
"Return only the summary block — no extra commentary, no prompt repetition."
|
46 |
)
|
47 |
|
48 |
-
# ✂️ Summarize top N documents
|
49 |
def summarize_topic(docs: List[str], topic: str) -> List[Dict]:
|
50 |
feed = []
|
51 |
for doc in docs[:5]:
|
52 |
tail_prompt = f"Topic: {topic}\n\n{doc.strip()}"
|
53 |
-
print(f"\n📤 Prompt tail for
|
54 |
-
summary_block =
|
55 |
|
56 |
if summary_block:
|
57 |
for line in summary_block.splitlines():
|
@@ -62,10 +59,11 @@ def summarize_topic(docs: List[str], topic: str) -> List[Dict]:
|
|
62 |
feed.append({
|
63 |
"summary": clean_summary,
|
64 |
"image_url": "https://source.unsplash.com/800x600/?news",
|
65 |
-
"article_link": "https://google.com/search?q=
|
66 |
})
|
67 |
return feed
|
68 |
|
|
|
69 |
# ⚡ Generate and cache daily feed
|
70 |
def generate_and_cache_daily_feed(documents: List[Document]):
|
71 |
index = VectorStoreIndex.from_documents(documents)
|
|
|
9 |
from llama_index.core.schema import Document
|
10 |
from llama_index.core.settings import Settings
|
11 |
from components.LLMs.Mistral import call_mistral
|
|
|
|
|
|
|
12 |
|
13 |
# ✅ Disable implicit LLM usage
|
14 |
Settings.llm = None
|
|
|
24 |
TOPICS = ["India news", "World news", "Tech news", "Finance news", "Sports news"]
|
25 |
|
26 |
# 🧠 Base summarization prompt (used for all topics)
|
27 |
+
# 🧠 Define the base summarization prompt
|
28 |
BASE_PROMPT = (
|
29 |
"You are Nuse’s official news summarizer — insightful, punchy, and always on point.\n"
|
30 |
"Your job is to scan the content below and extract the key news items. For each item, craft a crisp summary (15–20 words). Avoid using any emojis.\n"
|
|
|
33 |
"Example format:\n"
|
34 |
"- India stuns Australia in a last-ball thriller at the World Cup finals\n"
|
35 |
"- U.S. imposes sweeping tariffs on Chinese tech giants, rattling global markets\n"
|
36 |
+
"- Ceasefire breakthrough: Netanyahu (Prime minister of Israel) bows to pressure after week-long escalation\n"
|
37 |
"\n"
|
38 |
"If you are mentioning a person, include their designation in brackets. For example: Jeff Bezos (Amazon CEO), Narendra Modi (Prime minister of India).\n"
|
39 |
"If you're referencing a post like 'NATO Chief', also include the name of the person who holds the post.\n"
|
|
|
43 |
"Return only the summary block — no extra commentary, no prompt repetition."
|
44 |
)
|
45 |
|
|
|
46 |
def summarize_topic(docs: List[str], topic: str) -> List[Dict]:
|
47 |
feed = []
|
48 |
for doc in docs[:5]:
|
49 |
tail_prompt = f"Topic: {topic}\n\n{doc.strip()}"
|
50 |
+
print(f"\n📤 Prompt tail for LLaMA-3 8B:\n{tail_prompt[:300]}...\n")
|
51 |
+
summary_block = call_mistral(base_prompt=BASE_PROMPT, tail_prompt=tail_prompt)
|
52 |
|
53 |
if summary_block:
|
54 |
for line in summary_block.splitlines():
|
|
|
59 |
feed.append({
|
60 |
"summary": clean_summary,
|
61 |
"image_url": "https://source.unsplash.com/800x600/?news",
|
62 |
+
"article_link": f"https://google.com/search?q={topic.replace(' ', '+')}"
|
63 |
})
|
64 |
return feed
|
65 |
|
66 |
+
|
67 |
# ⚡ Generate and cache daily feed
|
68 |
def generate_and_cache_daily_feed(documents: List[Document]):
|
69 |
index = VectorStoreIndex.from_documents(documents)
|