1
0

feat: add default thinking thread — Timmy always ponders (#75)

This commit is contained in:
Alexander Whitestone
2026-02-27 01:00:11 -05:00
committed by GitHub
parent a975a845c5
commit 849b5b1a8d
11 changed files with 1012 additions and 1 deletions

View File

@@ -0,0 +1,65 @@
"""Thinking routes — Timmy's inner thought stream.
GET /thinking — render the thought stream page
GET /thinking/api — JSON list of recent thoughts
GET /thinking/api/{id}/chain — follow a thought chain
"""
import logging
from pathlib import Path
from fastapi import APIRouter, Request
from fastapi.responses import HTMLResponse, JSONResponse
from fastapi.templating import Jinja2Templates
from timmy.thinking import thinking_engine
logger = logging.getLogger(__name__)
router = APIRouter(prefix="/thinking", tags=["thinking"])
templates = Jinja2Templates(directory=str(Path(__file__).parent.parent / "templates"))
@router.get("", response_class=HTMLResponse)
async def thinking_page(request: Request):
"""Render Timmy's thought stream page."""
thoughts = thinking_engine.get_recent_thoughts(limit=50)
return templates.TemplateResponse(
request,
"thinking.html",
{"thoughts": thoughts},
)
@router.get("/api", response_class=JSONResponse)
async def thinking_api(limit: int = 20):
"""Return recent thoughts as JSON."""
thoughts = thinking_engine.get_recent_thoughts(limit=limit)
return [
{
"id": t.id,
"content": t.content,
"seed_type": t.seed_type,
"parent_id": t.parent_id,
"created_at": t.created_at,
}
for t in thoughts
]
@router.get("/api/{thought_id}/chain", response_class=JSONResponse)
async def thought_chain_api(thought_id: str):
"""Follow a thought chain backward and return in chronological order."""
chain = thinking_engine.get_thought_chain(thought_id)
if not chain:
return JSONResponse({"error": "Thought not found"}, status_code=404)
return [
{
"id": t.id,
"content": t.content,
"seed_type": t.seed_type,
"parent_id": t.parent_id,
"created_at": t.created_at,
}
for t in chain
]