Spaces:
Sleeping
Sleeping
File size: 6,206 Bytes
1397957 |
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 |
from typing import Optional, List, Dict, Any
from pydantic import BaseModel
from datetime import datetime
from ..core.storage import Storage, NotFoundError
from ..core.bus import Bus, SESSION_CREATED, SESSION_UPDATED, SESSION_DELETED, SessionPayload
from ..core.identifier import Identifier
from ..core.supabase import get_client, is_enabled as supabase_enabled
class SessionInfo(BaseModel):
id: str
user_id: Optional[str] = None
title: str
created_at: datetime
updated_at: datetime
provider_id: Optional[str] = None
model_id: Optional[str] = None
agent_id: Optional[str] = None
class SessionCreate(BaseModel):
title: Optional[str] = None
provider_id: Optional[str] = None
model_id: Optional[str] = None
agent_id: Optional[str] = None
class Session:
@staticmethod
async def create(data: Optional[SessionCreate] = None, user_id: Optional[str] = None) -> SessionInfo:
session_id = Identifier.generate("session")
now = datetime.utcnow()
info = SessionInfo(
id=session_id,
user_id=user_id,
title=data.title if data and data.title else f"Session {now.isoformat()}",
created_at=now,
updated_at=now,
provider_id=data.provider_id if data else None,
model_id=data.model_id if data else None,
agent_id=data.agent_id if data else "build",
)
if supabase_enabled() and user_id:
client = get_client()
client.table("opencode_sessions").insert({
"id": session_id,
"user_id": user_id,
"title": info.title,
"agent_id": info.agent_id,
"provider_id": info.provider_id,
"model_id": info.model_id,
}).execute()
else:
await Storage.write(["session", session_id], info)
await Bus.publish(SESSION_CREATED, SessionPayload(id=session_id, title=info.title))
return info
@staticmethod
async def get(session_id: str, user_id: Optional[str] = None) -> SessionInfo:
if supabase_enabled() and user_id:
client = get_client()
result = client.table("opencode_sessions").select("*").eq("id", session_id).eq("user_id", user_id).single().execute()
if not result.data:
raise NotFoundError(["session", session_id])
return SessionInfo(
id=result.data["id"],
user_id=result.data["user_id"],
title=result.data["title"],
created_at=result.data["created_at"],
updated_at=result.data["updated_at"],
provider_id=result.data.get("provider_id"),
model_id=result.data.get("model_id"),
agent_id=result.data.get("agent_id"),
)
data = await Storage.read(["session", session_id])
if not data:
raise NotFoundError(["session", session_id])
return SessionInfo(**data)
@staticmethod
async def update(session_id: str, updates: Dict[str, Any], user_id: Optional[str] = None) -> SessionInfo:
updates["updated_at"] = datetime.utcnow().isoformat()
if supabase_enabled() and user_id:
client = get_client()
result = client.table("opencode_sessions").update(updates).eq("id", session_id).eq("user_id", user_id).execute()
if not result.data:
raise NotFoundError(["session", session_id])
return await Session.get(session_id, user_id)
def updater(data: Dict[str, Any]):
data.update(updates)
data = await Storage.update(["session", session_id], updater)
info = SessionInfo(**data)
await Bus.publish(SESSION_UPDATED, SessionPayload(id=session_id, title=info.title))
return info
@staticmethod
async def delete(session_id: str, user_id: Optional[str] = None) -> bool:
if supabase_enabled() and user_id:
client = get_client()
client.table("opencode_sessions").delete().eq("id", session_id).eq("user_id", user_id).execute()
await Bus.publish(SESSION_DELETED, SessionPayload(id=session_id, title=""))
return True
info = await Session.get(session_id)
message_keys = await Storage.list(["message", session_id])
for key in message_keys:
await Storage.remove(key)
await Storage.remove(["session", session_id])
await Bus.publish(SESSION_DELETED, SessionPayload(id=session_id, title=info.title))
return True
@staticmethod
async def list(limit: Optional[int] = None, user_id: Optional[str] = None) -> List[SessionInfo]:
if supabase_enabled() and user_id:
client = get_client()
query = client.table("opencode_sessions").select("*").eq("user_id", user_id).order("updated_at", desc=True)
if limit:
query = query.limit(limit)
result = query.execute()
return [
SessionInfo(
id=row["id"],
user_id=row["user_id"],
title=row["title"],
created_at=row["created_at"],
updated_at=row["updated_at"],
provider_id=row.get("provider_id"),
model_id=row.get("model_id"),
agent_id=row.get("agent_id"),
)
for row in result.data
]
session_keys = await Storage.list(["session"])
sessions = []
for key in session_keys:
if limit and len(sessions) >= limit:
break
data = await Storage.read(key)
if data:
sessions.append(SessionInfo(**data))
sessions.sort(key=lambda s: s.updated_at, reverse=True)
return sessions
@staticmethod
async def touch(session_id: str, user_id: Optional[str] = None) -> None:
await Session.update(session_id, {}, user_id)
|