forked from Likhithsai2580/ai-navigator
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.py
More file actions
170 lines (141 loc) · 5.67 KB
/
main.py
File metadata and controls
170 lines (141 loc) · 5.67 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
import asyncio
from fastapi import FastAPI, Depends, HTTPException, BackgroundTasks
from fastapi.responses import StreamingResponse
from sqlalchemy.orm import Session
from typing import Optional, List, Dict, Any
from pydantic import BaseModel, HttpUrl
from core.database.database import get_db, init_db
from core.database.models import LearnedInfo, APIRequest
from core.plugins.apis.ollama_client import OllamaClient
from core.plugins.selenium_manager import SeleniumManager
from navigator.orchestrator import Navigator
app = FastAPI(title="Ultimate AI - Web Navigator")
# Initialize components
ollama_client = OllamaClient()
selenium_manager = SeleniumManager(headless=False) # Set to True in production
navigator = Navigator(ollama_client, selenium_manager)
# Initialize the database on startup
@app.on_event("startup")
def startup_db_client():
init_db()
# Request and response models
class WebGoalRequest(BaseModel):
goal: str
context: Optional[str] = None
run_headless: Optional[bool] = False
class WebCaptureRequest(BaseModel):
url: HttpUrl
context: Optional[str] = None
class ApiSearchRequest(BaseModel):
query: str
class SemanticSearchRequest(BaseModel):
query: str
top_k: Optional[int] = 5
class CodeGenerationRequest(BaseModel):
task: str
language: Optional[str] = "python"
class GenerateResponse(BaseModel):
content: str
source: Optional[str] = None
class ApiListResponse(BaseModel):
apis: List[Dict[str, Any]]
@app.post("/navigate", response_model=Dict[str, str])
async def navigate_web(request: WebGoalRequest, background_tasks: BackgroundTasks):
"""
Start a web navigation session with the specified goal.
This endpoint demonstrates the multi-model orchestration:
1. Hermes-3 creates a plan
2. Granite-Code generates the execution code
3. As actions are taken, requests are captured
4. DeepSeek-R1 analyzes the API interactions
5. mxbai-embed stores and connects the semantic knowledge
"""
# Set headless mode if requested
if hasattr(navigator.selenium_manager, 'headless'):
navigator.selenium_manager.headless = request.run_headless
# Start the navigation in the background
background_tasks.add_task(
navigator.perform_web_goal,
request.goal
)
return {
"status": "Navigation started in background",
"goal": request.goal
}
@app.post("/plan", response_model=Dict[str, str])
async def get_plan(request: WebGoalRequest):
"""Get just the initial plan for a goal without executing it."""
plan = await navigator.handle_user_request(request.goal, request.context or "")
return {"plan": plan}
@app.post("/analyze-webpage", response_model=GenerateResponse)
async def analyze_webpage(request: WebCaptureRequest, db: Session = Depends(get_db)):
"""Analyze a webpage using the AI models."""
# Extract content from webpage
if not hasattr(selenium_manager, 'extract_page_content'):
# Create a simple method if it doesn't exist
selenium_manager.driver.get(str(request.url))
page_content = {
'title': selenium_manager.driver.title,
'content': selenium_manager.driver.page_source
}
else:
page_content = await selenium_manager.extract_page_content(str(request.url))
# Use our TaskPlanner (Hermes-3) to analyze the page
analysis = await navigator.planner.analyze_ui(
page_content.get('content', ''),
current_url=str(request.url)
)
# Store the learned information
learned_info = LearnedInfo(
topic=page_content.get('title', 'Webpage Analysis'),
content=analysis.get('full_analysis', ''),
source=str(request.url)
)
db.add(learned_info)
db.commit()
return GenerateResponse(
content=analysis.get('full_analysis', ''),
source=str(request.url)
)
@app.post("/apis/search", response_model=ApiListResponse)
async def search_apis(request: ApiSearchRequest):
"""Search for captured APIs matching a query."""
api_memories = await navigator.api_search(request.query)
# Format for response
results = []
for api in api_memories:
results.append({
"id": api.get("id", ""),
"text": api.get("text", ""),
"similarity": api.get("similarity_score", 0),
"metadata": api.get("metadata", {})
})
return ApiListResponse(apis=results)
@app.post("/generate/code", response_model=Dict[str, str])
async def generate_code(request: CodeGenerationRequest):
"""Generate code for a specific task using Granite-Code."""
code = await navigator.generate_code_for_task(request.task)
return {"code": code}
@app.get("/apis/recent", response_model=ApiListResponse)
async def get_recent_apis(limit: int = 10, db: Session = Depends(get_db)):
"""Get recently captured API requests."""
api_requests = db.query(APIRequest).order_by(APIRequest.timestamp.desc()).limit(limit).all()
# Format for response
results = []
for api in api_requests:
results.append({
"id": api.id,
"method": api.method,
"url": api.url,
"response_status": api.response_status_code,
"notes": api.notes
})
return ApiListResponse(apis=results)
@app.post("/memory/search", response_model=Dict[str, Any])
async def search_semantic_memory(request: SemanticSearchRequest):
"""Search the semantic memory using mxbai embeddings."""
results = await navigator.semantic_indexer.search_memory(request.query, top_k=request.top_k)
return {"results": results}
if __name__ == "__main__":
import uvicorn
uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)