gbakidz commited on
Commit
43b236c
·
verified ·
1 Parent(s): e5eec40

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +116 -31
app.py CHANGED
@@ -7,14 +7,19 @@ from bs4 import BeautifulSoup
7
 
8
  app = FastAPI()
9
 
10
- MODEL_NAME = "microsoft/phi-2"
11
 
12
- print("Loading Phi-2...")
13
 
14
  torch.set_num_threads(2)
15
 
16
  tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)
17
- model = AutoModelForCausalLM.from_pretrained(MODEL_NAME)
 
 
 
 
 
18
  model.to("cpu")
19
 
20
  print("Model loaded!")
@@ -22,51 +27,131 @@ print("Model loaded!")
22
  # -------- REQUEST SCHEMA --------
23
  class RequestData(BaseModel):
24
  prompt: str
25
- use_search: bool = False
 
26
 
27
 
28
- # -------- WEB SEARCH FUNCTION --------
29
- def search_web(query):
30
  url = f"https://duckduckgo.com/html/?q={query}"
31
  headers = {"User-Agent": "Mozilla/5.0"}
32
 
33
- response = requests.get(url, headers=headers)
34
- soup = BeautifulSoup(response.text, "html.parser")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
35
 
36
- results = []
37
- for a in soup.select("a.result__a"):
38
- results.append(a.get_text())
39
 
40
- return " ".join(results[:5])
 
 
41
 
 
 
 
 
 
42
 
43
- # -------- GENERATE FUNCTION --------
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
  def generate_text(prompt):
45
- formatted = f"Instruct: {prompt}\nOutput:"
46
 
47
- inputs = tokenizer(formatted, return_tensors="pt")
 
 
 
 
 
 
48
 
49
- outputs = model.generate(
50
- inputs["input_ids"],
51
- max_new_tokens=60,
52
- temperature=0.7
53
- )
54
 
55
- result = tokenizer.decode(outputs[0], skip_special_tokens=True)
56
- return result.split("Output:")[-1].strip()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
57
 
58
 
59
  # -------- API ENDPOINT --------
60
  @app.post("/generate")
61
  def generate(data: RequestData):
62
- prompt = data.prompt
63
-
64
- if data.use_search:
65
- web_data = search_web(prompt)
66
- prompt = f"{prompt}\n\nWeb Info: {web_data}"
67
 
68
- response = generate_text(prompt)
 
 
 
 
69
 
70
- return {
71
- "response": response
72
- }
 
7
 
8
  app = FastAPI()
9
 
10
+ MODEL_NAME = "microsoft/phi-1_5"
11
 
12
+ print("Loading model...")
13
 
14
  torch.set_num_threads(2)
15
 
16
  tokenizer = AutoTokenizer.from_pretrained(MODEL_NAME)
17
+ model = AutoModelForCausalLM.from_pretrained(
18
+ MODEL_NAME,
19
+ torch_dtype=torch.float32,
20
+ low_cpu_mem_usage=True
21
+ )
22
+
23
  model.to("cpu")
24
 
25
  print("Model loaded!")
 
27
  # -------- REQUEST SCHEMA --------
28
  class RequestData(BaseModel):
29
  prompt: str
30
+ history: list = []
31
+ use_search: bool = True
32
 
33
 
34
+ # -------- TOOL 1: SEARCH --------
35
+ def search_links(query):
36
  url = f"https://duckduckgo.com/html/?q={query}"
37
  headers = {"User-Agent": "Mozilla/5.0"}
38
 
39
+ try:
40
+ res = requests.get(url, headers=headers, timeout=10)
41
+ soup = BeautifulSoup(res.text, "html.parser")
42
+
43
+ links = []
44
+ for a in soup.select("a.result__a"):
45
+ href = a.get("href")
46
+ if href:
47
+ links.append(href)
48
+
49
+ return links[:3]
50
+ except:
51
+ return []
52
+
53
+
54
+ # -------- TOOL 2: OPEN PAGE --------
55
+ def extract_page_text(url):
56
+ try:
57
+ res = requests.get(url, timeout=10, headers={"User-Agent": "Mozilla/5.0"})
58
+ soup = BeautifulSoup(res.text, "html.parser")
59
+
60
+ for tag in soup(["script", "style"]):
61
+ tag.decompose()
62
+
63
+ text = soup.get_text(separator=" ")
64
+ return text[:2000]
65
+
66
+ except:
67
+ return ""
68
 
 
 
 
69
 
70
+ # -------- TOOL 3: BROWSE --------
71
+ def browse_web(query):
72
+ links = search_links(query)
73
 
74
+ contents = []
75
+ for link in links:
76
+ page = extract_page_text(link)
77
+ if page:
78
+ contents.append(page)
79
 
80
+ return "\n\n".join(contents[:3])
81
+
82
+
83
+ # -------- MEMORY BUILDER --------
84
+ def build_prompt(prompt, history):
85
+ convo = ""
86
+
87
+ for user, bot in history:
88
+ convo += f"User: {user}\nAssistant: {bot}\n"
89
+
90
+ convo += f"User: {prompt}\nAssistant:"
91
+ return convo
92
+
93
+
94
+ # -------- GENERATION --------
95
  def generate_text(prompt):
96
+ inputs = tokenizer(prompt, return_tensors="pt", truncation=True, max_length=512)
97
 
98
+ with torch.no_grad():
99
+ outputs = model.generate(
100
+ inputs["input_ids"],
101
+ max_new_tokens=120,
102
+ temperature=0.7,
103
+ do_sample=True
104
+ )
105
 
106
+ return tokenizer.decode(outputs[0], skip_special_tokens=True)
 
 
 
 
107
 
108
+
109
+ # -------- AGENT LOOP --------
110
+ def agent(prompt, history, use_search=True):
111
+
112
+ # Step 1: Build conversation
113
+ base_prompt = build_prompt(prompt, history)
114
+
115
+ # Step 2: Decide if search is needed
116
+ decision_prompt = f"""
117
+ You are an AI agent.
118
+
119
+ User question:
120
+ {prompt}
121
+
122
+ Should you search the web? Answer YES or NO.
123
+ """
124
+
125
+ decision = generate_text(decision_prompt).lower()
126
+
127
+ if use_search and "yes" in decision:
128
+ web_data = browse_web(prompt)
129
+
130
+ final_prompt = f"""
131
+ You are an AI assistant with access to web data.
132
+
133
+ Conversation:
134
+ {base_prompt}
135
+
136
+ Web Data:
137
+ {web_data}
138
+
139
+ Answer clearly and accurately:
140
+ """
141
+ else:
142
+ final_prompt = base_prompt
143
+
144
+ return generate_text(final_prompt)
145
 
146
 
147
  # -------- API ENDPOINT --------
148
  @app.post("/generate")
149
  def generate(data: RequestData):
 
 
 
 
 
150
 
151
+ response = agent(
152
+ prompt=data.prompt,
153
+ history=data.history,
154
+ use_search=data.use_search
155
+ )
156
 
157
+ return {"response": response}