Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions cortex_on/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM python:3.10-slim
FROM python:3.11-slim-bullseye

WORKDIR /app

Expand All @@ -20,4 +20,4 @@ COPY . .

EXPOSE 8081

CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8081"]
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8081"]
8 changes: 4 additions & 4 deletions cortex_on/agents/orchestrator_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -307,8 +307,8 @@ async def web_surfer_task(ctx: RunContext[orchestrator_deps], task: str) -> str:

await _safe_websocket_send(ctx.deps.websocket, web_surfer_stream_output)

# Initialize WebSurfer agent
web_surfer_agent = WebSurfer(api_url="http://localhost:8000/api/v1/web/stream")
# Initialize WebSurfer agent - will use environment variable or Docker service name
web_surfer_agent = WebSurfer()

# Run WebSurfer with its own stream_output
success, message, messages = await web_surfer_agent.generate_reply(
Expand Down Expand Up @@ -484,7 +484,7 @@ async def planner_agent_update(ctx: RunContext[orchestrator_deps], completed_tas
logfire.error(error_msg, exc_info=True)

planner_stream_output.steps.append(f"Plan update failed: {str(e)}")
planner_stream_output.status_code = a500
planner_stream_output.status_code = 500
await _safe_websocket_send(ctx.deps.websocket, planner_stream_output)

return f"Failed to update the plan: {error_msg}"
Expand All @@ -511,4 +511,4 @@ async def _safe_websocket_send(websocket: Optional[WebSocket], message: Any) ->
return False
except Exception as e:
logfire.error(f"WebSocket send failed: {str(e)}")
return False
return False
10 changes: 8 additions & 2 deletions cortex_on/agents/web_surfer.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,13 @@
TIMEOUT = 9999999999999999999999999999999999999999999

class WebSurfer:
def __init__(self, api_url: str = "http://localhost:8000/api/v1/web/stream"):
def __init__(self, api_url: Optional[str] = None):
# Use environment variable or default to Docker service name, fallback to localhost
if api_url is None:
api_url = os.getenv(
"AGENTIC_BROWSER_URL",
"http://agentic_browser:8000/api/v1/web/stream"
)
self.api_url = api_url
self.name = "Web Surfer Agent"
self.description = "An agent that is a websurfer and a webscraper that can access any web-page to extract information or perform actions."
Expand Down Expand Up @@ -148,4 +154,4 @@ async def generate_reply(
timestamp=datetime.utcnow(),
)

return False, error_message, [error_response]
return False, error_message, [error_response]
34 changes: 30 additions & 4 deletions cortex_on/main.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# Standard library imports
import json
from typing import List, Optional

# Third-party imports
from fastapi import FastAPI, WebSocket
from fastapi import FastAPI, WebSocket, WebSocketDisconnect
import logfire

# Local application imports
from instructor import SystemInstructor
Expand All @@ -22,6 +24,30 @@ async def agent_chat(task: str) -> List:
@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
await websocket.accept()
while True:
data = await websocket.receive_text()
await generate_response(data, websocket)
try:
while True:
try:
data = await websocket.receive_text()
await generate_response(data, websocket)
except WebSocketDisconnect:
logfire.info("Client disconnected from WebSocket")
break
except Exception as e:
logfire.error(f"Error processing WebSocket message: {str(e)}")
# Try to send error to client if still connected
try:
if websocket.client_state.CONNECTED:
await websocket.send_text(json.dumps({"error": str(e)}))
except:
pass
break
except WebSocketDisconnect:
logfire.info("WebSocket connection closed by client")
except Exception as e:
logfire.error(f"WebSocket endpoint error: {str(e)}")
finally:
try:
if websocket.client_state.CONNECTED:
await websocket.close()
except:
pass
11 changes: 6 additions & 5 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
version: '3.8'

services:
cortex_on:
build:
Expand All @@ -9,8 +7,9 @@ services:
- ./cortex_on:/app
env_file:
- .env
ports:
- "8081:8081"
restart: always
network_mode: host

agentic_browser:
build:
Expand All @@ -20,8 +19,9 @@ services:
- ./ta-browser:/app
env_file:
- .env
ports:
- "8000:8000"
restart: always
network_mode: host

frontend:
build:
Expand All @@ -32,8 +32,9 @@ services:
- /app/node_modules
env_file:
- .env
ports:
- "3000:3000"
depends_on:
- cortex_on
- agentic_browser
restart: always
network_mode: host
19 changes: 11 additions & 8 deletions frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,20 @@ import {BrowserRouter, Route, Routes} from "react-router-dom";
import Home from "./pages/Home";
import {Layout} from "./pages/Layout";
import {Vault} from "./pages/Vault";
import {ConversationProvider} from "./contexts/ConversationContext";

function App() {
return (
<BrowserRouter>
<Routes>
<Route path="/" element={<Layout />}>
<Route index element={<Home />} />
<Route path="/vault" element={<Vault />} />
</Route>
</Routes>
</BrowserRouter>
<ConversationProvider>
<BrowserRouter>
<Routes>
<Route path="/" element={<Layout />}>
<Route index element={<Home />} />
<Route path="/vault" element={<Vault />} />
</Route>
</Routes>
</BrowserRouter>
</ConversationProvider>
);
}

Expand Down
24 changes: 17 additions & 7 deletions frontend/src/components/home/Chat.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,22 +3,32 @@ import {useState} from "react";
import {useSelector} from "react-redux";
import ChatList from "./ChatList";
import Landing from "./Landing";
import {ConversationList} from "./ConversationList";
import {useConversationContext} from "@/contexts/ConversationContext";

const Chat = () => {
const [isLoading, setIsLoading] = useState<boolean>(false);
const {isOpen, closeConversationList} = useConversationContext();

const messages = useSelector(
(state: RootState) => state.messagesState.messages
);

return (
<div className="flex justify-center items-center h-[92vh] overflow-auto scrollbar-thin">
{messages.length === 0 ? (
<Landing isLoading={isLoading} setIsLoading={setIsLoading} />
) : (
<ChatList isLoading={isLoading} setIsLoading={setIsLoading} />
)}
</div>
<>
<div className="flex justify-center items-center h-[92vh] overflow-auto scrollbar-thin">
{messages.length === 0 ? (
<Landing isLoading={isLoading} setIsLoading={setIsLoading} />
) : (
<ChatList isLoading={isLoading} setIsLoading={setIsLoading} />
)}
</div>
<ConversationList
isOpen={isOpen}
onClose={closeConversationList}
currentMessages={messages}
/>
</>
);
};

Expand Down
Loading