Skip to content

main

main

FastAPI application — Alkiviades streaming SSE chat endpoint with authentication.

get_sql_session_mgr

get_sql_session_mgr() -> SQLSessionManager

Get or create the module-level SQLSessionManager (lazy init).

Returns the singleton SQLSessionManager instance. Initializes on first call if not already set — this covers both the lifespan path and the test fixture path where lifespan may not be triggered.

lifespan async

lifespan(app: FastAPI)

Application lifespan — init DB, bootstrap admin, migrate legacy sessions on startup.

login async

login(
    body: LoginRequest, response: Response, request: Request
) -> dict

Authenticate user with email/password, return JWT access token and set refresh cookie.

Validates credentials against the SQLite users table, creates a JWT access token (15-minute expiry) and an httpOnly refresh cookie (7 days). Returns a 401 "Invalid credentials" for wrong email, wrong password, or nonexistent user. Rate-limited at 5 requests per 60 seconds per IP.

Parameters:

Name Type Description Default
body LoginRequest

LoginRequest with email and password fields.

required
response Response

FastAPI Response object used to set the refresh cookie.

required
request Request

FastAPI Request object for rate limiting by client IP.

required

Returns:

Type Description
dict

Dict with access_token, token_type, is_admin flag, and role.

Raises:

Type Description
HTTPException

401 if credentials are invalid.

refresh async

refresh(request: Request, response: Response) -> dict

Issue a new access token using a valid refresh token from the httpOnly cookie.

Validates the refresh token from the request cookie: checks it exists, hasn't been revoked, and hasn't expired. Rotates the token — revokes the old one and issues a new refresh cookie. Rate-limited at 5 requests per 60 seconds per IP.

Parameters:

Name Type Description Default
request Request

FastAPI Request with the httpOnly refresh_token cookie.

required
response Response

FastAPI Response for setting the new refresh cookie.

required

Returns:

Type Description
dict

Dict with a fresh access_token and token_type.

Raises:

Type Description
HTTPException

401 if cookie is missing, token is invalid, revoked, or expired.

logout async

logout(request: Request, response: Response) -> dict

Revoke refresh token and clear cookie.

Idempotent — returns 200 even without a valid auth token. If a refresh_token cookie is present, marks it as revoked in the database and clears the cookie from the response.

Parameters:

Name Type Description Default
request Request

FastAPI Request with the optional refresh_token cookie.

required
response Response

FastAPI Response for clearing the refresh cookie.

required

Returns:

Type Description
dict

Dict with status 'ok'.

auth_me async

auth_me(user: dict = Depends(get_current_user)) -> dict

Return current user profile including role.

Requires a valid JWT access token in the Authorization header.

Parameters:

Name Type Description Default
user dict

Decoded JWT payload injected by get_current_user dependency.

Depends(get_current_user)

Returns:

Type Description
dict

Dict with id, email, role, and is_admin fields.

Raises:

Type Description
HTTPException

404 if the user no longer exists in the database.

health async

health() -> dict[str, str]

Public health check endpoint.

Returns:

Type Description
dict[str, str]

Dict with status 'ok'.

health_debug async

health_debug(user: dict = Depends(require_admin)) -> dict

System diagnostics endpoint — admin only.

Returns Python version, API key status, knowledge base size, embedding configuration, and environment variables (with secrets redacted).

Parameters:

Name Type Description Default
user dict

Decoded JWT payload — must have admin role.

Depends(require_admin)

Returns:

Type Description
dict

Dict with system diagnostic information.

admin_logs async

admin_logs(
    limit: int = 100, user: dict = Depends(require_admin)
) -> dict

Return the last N lines of the application log file.

Admin only. Reads from the rotating file log.

Parameters:

Name Type Description Default
limit int

Maximum number of log lines to return (default 100).

100
user dict

Decoded JWT payload — must have admin role.

Depends(require_admin)

Returns:

Type Description
dict

Dict with a 'lines' key containing the log lines as a list of strings.

admin_logs_stream async

admin_logs_stream(
    request: Request, user: dict = Depends(require_admin)
) -> EventSourceResponse

SSE stream of new log entries.

Admin only. Polls the log file every 2 seconds for new content and pushes each new line as an SSE event. Automatically stops when the client disconnects.

Parameters:

Name Type Description Default
request Request

FastAPI Request for disconnect detection.

required
user dict

Decoded JWT payload — must have admin role.

Depends(require_admin)

Returns:

Type Description
EventSourceResponse

EventSourceResponse yielding 'log' events with new log lines.

admin_list_users async

admin_list_users(
    user: dict = Depends(require_admin),
) -> list[dict]

List all users with API key status.

Admin only. Returns all registered users ordered by creation date descending, with per-user key configuration status.

Parameters:

Name Type Description Default
user dict

Decoded JWT payload — must have admin role.

Depends(require_admin)

Returns:

Type Description
list[dict]

List of dicts with id, email, role, queries_remaining,

list[dict]

created_at, and keys status.

admin_create_user async

admin_create_user(
    body: dict, user: dict = Depends(require_admin)
) -> dict

Create a new user account.

Admin only. Creates a standard user with the given email and password. Password must be at least 8 characters. The email must be unique.

Parameters:

Name Type Description Default
body dict

Dict with 'email' and 'password' keys.

required
user dict

Decoded JWT payload — must have admin role.

Depends(require_admin)

Returns:

Type Description
dict

Dict with id, email, role, and created flag.

Raises:

Type Description
HTTPException

422 if email or password missing/invalid, 409 if email already exists.

admin_delete_user async

admin_delete_user(
    user_id: str, user: dict = Depends(require_admin)
) -> dict

Delete a user and all their associated data.

Admin only. Removes the user's sessions, messages, refresh tokens, and the user record. Cannot delete admin accounts.

Parameters:

Name Type Description Default
user_id str

UUID of the user to delete.

required
user dict

Decoded JWT payload — must have admin role.

Depends(require_admin)

Returns:

Type Description
dict

Dict with deleted flag and user_id.

Raises:

Type Description
HTTPException

404 if user not found, 403 if target is admin.

admin_reset_user_keys async

admin_reset_user_keys(
    user_id: str, user: dict = Depends(require_admin)
) -> dict

Clear a user's personal API keys.

Admin only. Removes any user-configured API keys, causing the user to fall back to system keys on their next request.

Parameters:

Name Type Description Default
user_id str

UUID of the target user.

required
user dict

Decoded JWT payload — must have admin role.

Depends(require_admin)

Returns:

Type Description
dict

Dict with status and the user's new key status.

Raises:

Type Description
HTTPException

404 if user not found.

get_axes async

get_axes() -> dict

Get the current global axis values.

Returns the three political axes (ethical, alignment, social) that modulate all agent responses.

Returns:

Type Description
dict

Dict with ethical, alignment, and social float values.

set_axes async

set_axes(
    body: dict, user: dict = Depends(get_current_user)
) -> dict

Update the global axis values.

Accepts partial updates — only provided keys are modified. Values are clamped to the range [-1.0, 1.0].

Parameters:

Name Type Description Default
body dict

Dict with any of 'ethical', 'alignment', 'social' keys.

required
user dict

Decoded JWT payload (any authenticated user).

Depends(get_current_user)

Returns:

Type Description
dict

The updated axes dict with all three current values.

get_user_keys async

get_user_keys(
    user: dict = Depends(get_current_user),
) -> dict

Return the current user's API key status.

Values are redacted — only indicates whether each key is configured (user-provided or system fallback).

Parameters:

Name Type Description Default
user dict

Decoded JWT payload.

Depends(get_current_user)

Returns:

Type Description
dict

Dict with deepseek, tavily, and scrapingant key status entries.

set_user_keys async

set_user_keys(
    body: dict, user: dict = Depends(get_current_user)
) -> dict

Save personal API keys for the current user.

Partial update — only provided keys are stored. Supported keys: deepseek, tavily, scrapingant. Values are Fernet-encrypted at rest.

Parameters:

Name Type Description Default
body dict

Dict with optional 'deepseek', 'tavily', 'scrapingant' string values.

required
user dict

Decoded JWT payload.

Depends(get_current_user)

Returns:

Type Description
dict

Dict with updated key status for all three providers.

clear_user_keys async

clear_user_keys(
    user: dict = Depends(get_current_user),
) -> dict

Remove all personal API keys, reverting to system keys.

Parameters:

Name Type Description Default
user dict

Decoded JWT payload.

Depends(get_current_user)

Returns:

Type Description
dict

Dict with updated key status showing system fallback for all providers.

list_sessions async

list_sessions(
    user: dict = Depends(get_current_user),
) -> list[dict]

List sessions for the authenticated user.

Parameters:

Name Type Description Default
user dict

Decoded JWT payload.

Depends(get_current_user)

Returns:

Type Description
list[dict]

List of session dicts with id, title, created_at, updated_at,

list[dict]

and turn_count for each session.

get_session async

get_session(
    session_id: str,
    user: dict = Depends(get_current_user),
    preview: bool = False,
) -> dict

Get session details with full conversation history.

Returns all turns by default. With ?preview=true, returns only the first 3 turns (for sidebar hover previews).

Parameters:

Name Type Description Default
session_id str

UUID of the session to load.

required
user dict

Decoded JWT payload.

Depends(get_current_user)
preview bool

If true, return only the first 3 turns.

False

Returns:

Type Description
dict

Session dict with id, title, axes, turns list, and timestamps.

Raises:

Type Description
HTTPException

404 if session not found or not owned by user.

delete_session_endpoint async

delete_session_endpoint(
    session_id: str, user: dict = Depends(get_current_user)
) -> dict

Delete a session and all its messages.

Parameters:

Name Type Description Default
session_id str

UUID of the session to delete.

required
user dict

Decoded JWT payload.

Depends(get_current_user)

Returns:

Type Description
dict

Dict with status 'deleted'.

Raises:

Type Description
HTTPException

404 if session not found or not owned by user.

rebuild_kb async

rebuild_kb(user: dict = Depends(require_admin)) -> dict

Rebuild the knowledge base from source files.

Admin only. Re-processes all files in processed/ and stratcom/, rebuilding chunk vectors and saving to the vector pickle file. Returns a diff of files added, removed, and changed.

Parameters:

Name Type Description Default
user dict

Decoded JWT payload — must have admin role.

Depends(require_admin)

Returns:

Type Description
dict

Dict with chunk count and diff dict (added, removed, changed lists).

chat async

chat(
    body: ChatRequest,
    user: dict = Depends(get_current_user),
) -> dict

Non-streaming chat endpoint — runs agent and returns complete response.

Fallback for clients that don't support SSE. Resolves all tool calls and streaming internally, then returns the full reply.

Parameters:

Name Type Description Default
body ChatRequest

ChatRequest with message, session_id, and optional axes override.

required
user dict

Decoded JWT payload.

Depends(get_current_user)

Returns:

Type Description
dict

Dict with reply, session_id, and sources list.

Raises:

Type Description
HTTPException

400 if no DeepSeek API key is configured.

chat_stream async

chat_stream(
    body: ChatRequest,
    request: Request,
    user: dict = Depends(get_current_user),
) -> EventSourceResponse

SSE streaming chat endpoint.

Streams the agent's response token by token alongside RAG source citations, tool call events, and tool results. Sends heartbeat events every 15 seconds to keep the connection alive. On completion, persists the conversation turn to SQLite.

Parameters:

Name Type Description Default
body ChatRequest

ChatRequest with message, session_id, and optional axes override.

required
request Request

FastAPI Request for disconnect detection.

required
user dict

Decoded JWT payload.

Depends(get_current_user)

Returns:

Type Description
EventSourceResponse

EventSourceResponse yielding token, source, tool_call,

EventSourceResponse

tool_result, done, error, and heartbeat events.

Raises:

Type Description
HTTPException

400 if no DeepSeek API key is configured.