feat: session source in session_meta and an Automated sidebar folder (#40)

Co-authored-by: Alice <alice@prismshadow.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Yaowei Zheng
2026-07-23 00:58:43 +08:00
committed by GitHub
parent e0bf1706b9
commit c380113e26
30 changed files with 1023 additions and 74 deletions
+24 -1
View File
@@ -182,13 +182,36 @@ export function ChatPage() {
};
}, [projectId, selectedAgentId]);
// The Session list is paged: a deep-linked Session (old bookmark, cross-page jump) may sit
// beyond the loaded pages. Look it up directly and insert it before the auto-select effect
// below concludes it doesn't exist; only a failed probe releases that redirect.
const [probeFailedId, setProbeFailedId] = useState<string | null>(null);
useEffect(() => {
if (draft || !routeSessionId || sessionsLoading) return;
if (sessions.some((s) => s.sessionId === routeSessionId)) return;
let cancelled = false;
api.getSession(routeSessionId).then(
(res) => {
if (!cancelled) addSession(res.session);
},
() => {
if (!cancelled) setProbeFailedId(routeSessionId);
},
);
return () => {
cancelled = true;
};
}, [draft, routeSessionId, sessionsLoading, sessions, addSession]);
// Auto-select the most recent Session when the route doesn't select one; if there are none at all, fall back to draft state (instead of auto-creating one).
useEffect(() => {
if (sessionsLoading || draft) return;
if (routeSessionId && sessions.some((s) => s.sessionId === routeSessionId)) return;
// A routed id missing from the paged list isn't gone until the direct lookup fails.
if (routeSessionId && probeFailedId !== routeSessionId) return;
const first = sessions[0];
navigate(first ? `/chat/${first.sessionId}` : `/chat/${DRAFT_SESSION_ID}`, { replace: true });
}, [sessionsLoading, draft, routeSessionId, sessions, navigate]);
}, [sessionsLoading, draft, routeSessionId, probeFailedId, sessions, navigate]);
// Sync task_state to the sidebar list badge.
useEffect(() => {
@@ -158,6 +158,8 @@ const summaryClass =
function SessionMetaBody({ p }: { p: Record<string, unknown> }) {
const rows: Array<[string, string]> = [
["session_id", String(p.session_id ?? "")],
// Session origin (subagent / schedule); user-created sessions have no source and show the empty dash.
["source", String(p.source ?? "")],
["model_id", String(p.model_id ?? "")],
["context_window", String(p.model_context_window ?? "")],
["thinking_level", String(p.thinking_level ?? "")],