| import requests |
| from fastapi import FastAPI |
| from pydantic import BaseModel |
| from datetime import date |
| from ollama import Client |
| import os |
|
|
| app = FastAPI() |
| today_date = date.today() |
|
|
| JINA_PASS = os.environ.get("JINA_AUTH") |
| class PromptRequest(BaseModel): |
| prompt: str |
| temperature: float = 0.5 |
|
|
| TOOL_PROMPT = f"""You are an autonomous AI Agent with real-time internet access. |
| Current Date: {today_date} |
| |
| You have access to one tool: |
| - Search [query] : searches the internet and returns real-time results |
| |
| RULES: |
| - If the user query needs current/real-time/recent information, respond with ONLY: Search [your search query] |
| - If you can answer from your own knowledge, answer directly |
| - Do NOT mix search command with other text |
| - After getting search results, answer the user query using those results |
| |
| """ |
|
|
| def search_tool(query: str) -> str: |
| try: |
| r = requests.get( |
| "https://s.jina.ai/", |
| params={"q": query}, |
| headers={"Accept": "application/json", "Authorization":f"{JINA_PASS}"}, |
| timeout=120 |
| ) |
| data = r.json().get("data", [])[:5] |
| results = [] |
| for item in data: |
| title = item.get("title", "") |
| desc = item.get("description", "") or item.get("content", "")[:300] |
| url = item.get("url", "") |
| results.append(f"- {title}\n {desc}\n Source: {url}") |
| return "\n\n".join(results) if results else "No results found." |
| except Exception as e: |
| return f"Search failed: {str(e)}" |
|
|
| def run_llm(messages: list, temperature: float) -> str: |
| client = Client(host="http://localhost:11434") |
| response = client.chat( |
| model="qwen2.5-coder:7b", |
| messages=messages, |
| options={"temperature": temperature} |
| ) |
| return response["message"]["content"].strip() |
|
|
| @app.get("/") |
| def health(): |
| return {"ok": True} |
|
|
| @app.post("/qwen2.5-coder:7b") |
| async def generate_response(request: PromptRequest): |
| |
| messages = [ |
| {"role": "system", "content": TOOL_PROMPT}, |
| {"role": "user", "content": request.prompt} |
| ] |
| response = run_llm(messages, request.temperature) |
| print(f"[LLM RAW]: {response}") |
|
|
| |
| if response.strip().startswith("Search "): |
| query = response.strip().removeprefix("Search ").strip("[]").strip() |
| print(f"[SEARCH QUERY]: {query}") |
| search_results = search_tool(query) |
| print(f"[SEARCH RESULTS]: {search_results[:200]}...") |
|
|
| |
| messages.append({"role": "assistant", "content": response}) |
| messages.append({ |
| "role": "user", |
| "content": f"Search Results:\n{search_results}\n\nNow answer the original question: {request.prompt}" |
| }) |
| final_response = run_llm(messages, request.temperature) |
| print(f"[FINAL]: {final_response}") |
| return {"response": final_response, "searched": True, "query": query} |
|
|
| return {"response": response, "searched": False} |