Komalpreet Kaur commited on
Commit
bbc2fa9
·
0 Parent(s):

feat: Establish initial FastAPI project with core configuration, API endpoints, and a basic Langgraph orchestrator.

Browse files
.env.example ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ OPENAI_API_KEY=your_openai_api_key_here
2
+ REDIS_HOST=localhost
3
+ REDIS_PORT=6379
4
+ CHROMA_DB_PATH=./chroma_db
5
+ NEO4J_URI=bolt://localhost:7687
6
+ NEO4J_USER=neo4j
7
+ NEO4J_PASSWORD=password
.gitignore ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ __pycache__/
2
+ *.py[cod]
3
+ *$py.class
4
+ .env
5
+ .venv
6
+ env/
7
+ venv/
8
+ ENV/
9
+ env.bak/
10
+ venv.bak/
11
+ .idea/
12
+ .vscode/
13
+ *.swp
14
+ *.swo
15
+ chroma_db/
app/api/endpoints.py ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import APIRouter, HTTPException
2
+ from pydantic import BaseModel
3
+ from typing import List, Optional
4
+
5
+ router = APIRouter()
6
+
7
+ class QueryRequest(BaseModel):
8
+ text: str
9
+ user_id: str = "default_user"
10
+
11
+ class QueryResponse(BaseModel):
12
+ response: str
13
+ sources: List[str] = []
14
+
15
+ @router.post("/query", response_model=QueryResponse)
16
+ async def process_query(request: QueryRequest):
17
+ # This will eventually call the cognitive orchestrator
18
+ # For now, it's a placeholder for Phase 1 verification
19
+ return QueryResponse(
20
+ response=f"Brain received: {request.text}. Phase 1: Foundation is active.",
21
+ sources=["Phase 1: Foundation"]
22
+ )
app/core/config.py ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pydantic_settings import BaseSettings, SettingsConfigDict
2
+ from functools import lru_cache
3
+ import os
4
+ from pathlib import Path
5
+ from dotenv import load_dotenv
6
+
7
+ # Load .env file if it exists
8
+ env_path = Path(__file__).parent.parent.parent / ".env"
9
+ load_dotenv(dotenv_path=env_path)
10
+
11
+ class Settings(BaseSettings):
12
+ PROJECT_NAME: str = "Soma"
13
+ VERSION: str = "0.1.0"
14
+ API_V1_STR: str = "/api/v1"
15
+
16
+ OPENAI_API_KEY: str = os.getenv("OPENAI_API_KEY", "")
17
+
18
+ # Working Memory (Redis)
19
+ REDIS_HOST: str = os.getenv("REDIS_HOST", "localhost")
20
+ REDIS_PORT: int = int(os.getenv("REDIS_PORT", 6379))
21
+
22
+ # Episodic Memory (ChromaDB)
23
+ CHROMA_DB_PATH: str = os.getenv("CHROMA_DB_PATH", "./chroma_db")
24
+
25
+ # Semantic Memory (Neo4j)
26
+ NEO4J_URI: str = os.getenv("NEO4J_URI", "bolt://localhost:7687")
27
+ NEO4J_USER: str = os.getenv("NEO4J_USER", "neo4j")
28
+ NEO4J_PASSWORD: str = os.getenv("NEO4J_PASSWORD", "password")
29
+
30
+ model_config = SettingsConfigDict(case_sensitive=True)
31
+
32
+ @lru_cache()
33
+ def get_settings():
34
+ return Settings()
35
+
36
+ settings = get_settings()
app/main.py ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from fastapi import FastAPI
2
+ from fastapi.middleware.cors import CORSMiddleware
3
+ from app.core.config import settings
4
+ from app.api.endpoints import router as api_router
5
+
6
+ app = FastAPI(
7
+ title=settings.PROJECT_NAME,
8
+ version=settings.VERSION,
9
+ openapi_url=f"{settings.API_V1_STR}/openapi.json"
10
+ )
11
+
12
+ # Set up CORS
13
+ app.add_middleware(
14
+ CORSMiddleware,
15
+ allow_origins=["*"],
16
+ allow_credentials=True,
17
+ allow_methods=["*"],
18
+ allow_headers=["*"],
19
+ )
20
+
21
+ # Include the API router
22
+ app.include_router(api_router, prefix=settings.API_V1_STR)
23
+
24
+ @app.get("/")
25
+ async def root():
26
+ return {"message": f"Welcome to {settings.PROJECT_NAME} API"}
27
+
28
+ if __name__ == "__main__":
29
+ import uvicorn
30
+ uvicorn.run("app.main:app", host="0.0.0.0", port=8000, reload=True)
app/services/orchestrator.py ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from langgraph.graph import StateGraph, END
2
+ from typing import TypedDict, Annotated, List
3
+ import operator
4
+
5
+ class AgentState(TypedDict):
6
+ input: str
7
+ chat_history: List[dict]
8
+ context: List[str]
9
+ response: str
10
+
11
+ def call_model(state: AgentState):
12
+ # Simplified logic for Phase 1
13
+ # Will be expanded with memory layers in later phases
14
+ return {"response": f"Orchestrator processed: {state['input']}"}
15
+
16
+ def create_graph():
17
+ workflow = StateGraph(AgentState)
18
+
19
+ # Add nodes
20
+ workflow.add_node("call_model", call_model)
21
+
22
+ # Set entry point
23
+ workflow.set_entry_point("call_model")
24
+
25
+ # Add edges
26
+ workflow.add_edge("call_model", END)
27
+
28
+ return workflow.compile()
29
+
30
+ orchestrator = create_graph()
requirements.txt ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ fastapi
2
+ uvicorn
3
+ langgraph
4
+ langchain
5
+ langchain-openai
6
+ python-dotenv
7
+ pydantic
8
+ redis
9
+ chromadb
10
+ neo4j
11
+ python-multipart
12
+ aiosqlite
13
+ pydantic-settings
tests/test_phase1.py ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import requests
2
+ import json
3
+
4
+ url = "http://localhost:8000/api/v1/query"
5
+ payload = {
6
+ "text": "Hello Soma!",
7
+ "user_id": "test_user"
8
+ }
9
+ headers = {
10
+ "Content-Type": "application/json"
11
+ }
12
+
13
+ try:
14
+ response = requests.post(url, data=json.dumps(payload), headers=headers)
15
+ print(f"Status Code: {response.status_code}")
16
+ print(f"Response Body: {response.json()}")
17
+ except Exception as e:
18
+ print(f"Error: {e}")