EnzGamers commited on
Commit
25ff730
·
verified ·
1 Parent(s): 4b5e535

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +11 -17
app.py CHANGED
@@ -56,21 +56,19 @@ app = FastAPI()
56
 
57
  # --- Tool Execution Functions ---
58
  def execute_browse_tool(url: str) -> str:
59
- """Visits a URL, extracts text content, and returns it."""
60
  try:
61
  headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'}
62
  response = requests.get(url, headers=headers, timeout=10)
63
  response.raise_for_status()
64
  soup = BeautifulSoup(response.content, 'html.parser')
65
- # Remove script and style elements
66
  for script in soup(["script", "style"]):
67
  script.decompose()
68
  text = soup.get_text(separator='\n', strip=True)
69
- return f"Content from {url}:\n\n{text[:4000]}" # Limit context size
70
  except Exception as e:
71
  return f"Error browsing {url}: {str(e)}"
72
 
73
- # --- Pydantic Models --- (Same as before)
74
  class ContentPart(BaseModel): type: str; text: str
75
  class ChatMessage(BaseModel): role: str; content: Union[str, List[ContentPart]]
76
  class ChatCompletionRequest(BaseModel):
@@ -97,30 +95,27 @@ async def create_chat_completion(request: ChatCompletionRequest):
97
 
98
  if not user_prompt: return {"error": "Prompt not found."}
99
 
100
- # --- AGENT LOGIC ---
101
- # STEP 1: Ask the model to think and decide on a tool
102
  initial_messages = [{'role': 'system', 'content': SYSTEM_PROMPT}, {'role': 'user', 'content': user_prompt}]
103
  inputs = tokenizer.apply_chat_template(initial_messages, add_generation_prompt=True, return_tensors="pt").to(DEVICE)
104
- outputs = model.generate(inputs.input_ids, attention_mask=inputs.attention_mask, max_new_tokens=150, eos_token_id=tokenizer.eos_token_id)
105
- thought_process = tokenizer.decode(outputs[0][len(inputs.input_ids[0]):], skip_special_tokens=True)
 
 
106
 
107
  tool_call = None
108
  try:
109
- # Check if the model's output is a JSON for a tool call
110
  json_part = thought_process[thought_process.find('{'):thought_process.rfind('}')+1]
111
  if json_part:
112
  tool_call = json.loads(json_part)
113
  except json.JSONDecodeError:
114
  tool_call = None
115
 
116
- # STEP 2: Execute the tool if requested
117
  if tool_call and 'tool' in tool_call:
118
  tool_context = ""
119
  if tool_call['tool'] == 'browse' and 'url' in tool_call:
120
  print(f"--- AGENT: Browsing URL: {tool_call['url']} ---")
121
  tool_context = execute_browse_tool(tool_call['url'])
122
 
123
- # STEP 3: Call the model AGAIN with the new context
124
  final_messages = [
125
  {'role': 'system', 'content': SYSTEM_PROMPT},
126
  {'role': 'user', 'content': user_prompt},
@@ -128,21 +123,20 @@ async def create_chat_completion(request: ChatCompletionRequest):
128
  {'role': 'system', 'content': "Now, provide the final, complete answer to the user based on this information."}
129
  ]
130
  else:
131
- # If no tool is needed, just use the original thought process
132
  final_messages = [
133
  {'role': 'system', 'content': SYSTEM_PROMPT},
134
  {'role': 'user', 'content': user_prompt},
135
- {'role': 'assistant', 'content': thought_process} # The model decided to answer directly
136
  ]
137
 
138
- # --- FINAL RESPONSE GENERATION (Streaming) ---
139
  final_inputs = tokenizer.apply_chat_template(final_messages, add_generation_prompt=False, return_tensors="pt").to(DEVICE)
140
- final_outputs = model.generate(final_inputs.input_ids, attention_mask=final_inputs.attention_mask, max_new_tokens=1024, do_sample=True, temperature=0.1, top_k=50, top_p=0.95, eos_token_id=tokenizer.eos_token_id)
141
- response_text = tokenizer.decode(final_outputs[0][len(final_inputs.input_ids[0]):], skip_special_tokens=True)
 
 
142
 
143
  async def stream_generator():
144
  response_id = f"chatcmpl-{uuid.uuid4()}"
145
- # (Streaming logic is the same as before)
146
  for char in response_text:
147
  chunk = {"id": response_id, "object": "chat.completion.chunk", "created": int(time.time()), "model": MODEL_ID, "choices": [{"index": 0, "delta": {"content": char}, "finish_reason": None}]}
148
  yield f"data: {json.dumps(chunk)}\n\n"
 
56
 
57
  # --- Tool Execution Functions ---
58
  def execute_browse_tool(url: str) -> str:
 
59
  try:
60
  headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'}
61
  response = requests.get(url, headers=headers, timeout=10)
62
  response.raise_for_status()
63
  soup = BeautifulSoup(response.content, 'html.parser')
 
64
  for script in soup(["script", "style"]):
65
  script.decompose()
66
  text = soup.get_text(separator='\n', strip=True)
67
+ return f"Content from {url}:\n\n{text[:4000]}"
68
  except Exception as e:
69
  return f"Error browsing {url}: {str(e)}"
70
 
71
+ # --- Pydantic Models ---
72
  class ContentPart(BaseModel): type: str; text: str
73
  class ChatMessage(BaseModel): role: str; content: Union[str, List[ContentPart]]
74
  class ChatCompletionRequest(BaseModel):
 
95
 
96
  if not user_prompt: return {"error": "Prompt not found."}
97
 
 
 
98
  initial_messages = [{'role': 'system', 'content': SYSTEM_PROMPT}, {'role': 'user', 'content': user_prompt}]
99
  inputs = tokenizer.apply_chat_template(initial_messages, add_generation_prompt=True, return_tensors="pt").to(DEVICE)
100
+
101
+ # CORRECTION ICI : On utilise **inputs pour décompresser le dictionnaire
102
+ outputs = model.generate(**inputs, max_new_tokens=150, eos_token_id=tokenizer.eos_token_id)
103
+ thought_process = tokenizer.decode(outputs[0][len(inputs['input_ids'][0]):], skip_special_tokens=True)
104
 
105
  tool_call = None
106
  try:
 
107
  json_part = thought_process[thought_process.find('{'):thought_process.rfind('}')+1]
108
  if json_part:
109
  tool_call = json.loads(json_part)
110
  except json.JSONDecodeError:
111
  tool_call = None
112
 
 
113
  if tool_call and 'tool' in tool_call:
114
  tool_context = ""
115
  if tool_call['tool'] == 'browse' and 'url' in tool_call:
116
  print(f"--- AGENT: Browsing URL: {tool_call['url']} ---")
117
  tool_context = execute_browse_tool(tool_call['url'])
118
 
 
119
  final_messages = [
120
  {'role': 'system', 'content': SYSTEM_PROMPT},
121
  {'role': 'user', 'content': user_prompt},
 
123
  {'role': 'system', 'content': "Now, provide the final, complete answer to the user based on this information."}
124
  ]
125
  else:
 
126
  final_messages = [
127
  {'role': 'system', 'content': SYSTEM_PROMPT},
128
  {'role': 'user', 'content': user_prompt},
129
+ {'role': 'assistant', 'content': thought_process}
130
  ]
131
 
 
132
  final_inputs = tokenizer.apply_chat_template(final_messages, add_generation_prompt=False, return_tensors="pt").to(DEVICE)
133
+
134
+ # DEUXIÈME CORRECTION ICI : On utilise également **final_inputs
135
+ final_outputs = model.generate(**final_inputs, max_new_tokens=1024, do_sample=True, temperature=0.1, top_k=50, top_p=0.95, eos_token_id=tokenizer.eos_token_id)
136
+ response_text = tokenizer.decode(final_outputs[0][len(final_inputs['input_ids'][0]):], skip_special_tokens=True)
137
 
138
  async def stream_generator():
139
  response_id = f"chatcmpl-{uuid.uuid4()}"
 
140
  for char in response_text:
141
  chunk = {"id": response_id, "object": "chat.completion.chunk", "created": int(time.time()), "model": MODEL_ID, "choices": [{"index": 0, "delta": {"content": char}, "finish_reason": None}]}
142
  yield f"data: {json.dumps(chunk)}\n\n"