chat session context scoping, fix sandboxed pi config mounts, dedupe zai/opencode providers

- Add context/contextId fields to session types, storage, and index
- Filter sessions by context (project, workspace, or default chat)
- Pass context through websocket, REST API, and frontend hooks
- Mount ~/.pi/agent into sandboxed containers for auth + writable sessions
- Remove PI_CODING_AGENT_DIR override so container pi uses ~/.pi/agent
- Deduplicate zai/opencode models (same service, show as opencode)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-26 22:35:02 +00:00
co-authored by Claude Opus 4.6
parent 1cbf9553ec
commit 13cfeac384
15 changed files with 111 additions and 24 deletions
+4 -4
View File
@@ -242,7 +242,7 @@ function createEventHandler(sessionId: string, model: string, cwd: string, stora
async function handleChat(
ws: ServerWebSocket<WSData>,
msg: { prompt: string; sessionId?: string; model?: string; cwd?: string; cwdRoot?: string; sandboxed?: boolean; groupSlug?: string; attachmentIds?: string[]; thinking?: string }
msg: { prompt: string; sessionId?: string; model?: string; cwd?: string; cwdRoot?: string; sandboxed?: boolean; groupSlug?: string; attachmentIds?: string[]; thinking?: string; context?: string; contextId?: string }
): Promise<void> {
const { email, username, userId } = ws.data;
const sessionId = msg.sessionId || randomUUID();
@@ -276,13 +276,13 @@ async function handleChat(
? resolveSandboxedCwd(email, msg.cwdRoot, msg.cwd)
: resolveHostCwd(msg.cwdRoot, msg.cwd);
const groupSlug = msg.groupSlug || null;
const session = sessionManager.getOrCreate(sessionId, email, cwd, model, groupSlug);
const session = sessionManager.getOrCreate(sessionId, email, cwd, model, groupSlug, msg.context, msg.contextId);
session.sandboxed = sandboxed;
session.userId = userId;
sessionManager.attachWs(sessionId, ws);
wsToSessionMap.set(ws as any, sessionId);
sendToClient(ws, { type: 'session:init', sessionId, model, cwd });
sendToClient(ws, { type: 'session:init', sessionId, model, cwd, context: session.meta.context, contextId: session.meta.contextId });
if (!session.piProcess) {
try {
const onEvent = createEventHandler(sessionId, model, cwd, homeDir);
@@ -353,7 +353,7 @@ async function handleResume(
sessionManager.attachWs(sessionId, ws);
wsToSessionMap.set(ws as any, sessionId);
sendToClient(ws, { type: 'session:init', sessionId, model: session.model, cwd: session.cwd });
sendToClient(ws, { type: 'session:init', sessionId, model: session.model, cwd: session.cwd, context: session.meta.context, contextId: session.meta.contextId });
// Spawn fresh Pi process if needed
if (!session.piProcess) {