fix(agent): isolate conversation workspaces
Generic Container CI/CD / test-build-publish (push) Successful in 2m2s
Agent CI/CD v2 / build-test-publish-and-deploy (push) Successful in 2m2s

This commit is contained in:
2026-08-25 13:18:39 +08:00
parent 004c9bb72d
commit ce04704af2
18 changed files with 621 additions and 48 deletions
+42 -5
View File
@@ -2,11 +2,14 @@ import {
createOpencode,
type OpencodeClient,
} from "@opencode-ai/sdk/v2";
import { randomUUID } from "node:crypto";
import { existsSync, readFileSync } from "node:fs";
import { chmod, mkdir, rmdir } from "node:fs/promises";
import { resolve } from "node:path";
import { config } from "../config.js";
import { logger } from "../logger.js";
import { ensureDirectory } from "../utils/fileStore.js";
import {
cleanupExpiredToolOutputs,
resolveOpencodeToolOutputDirectory,
@@ -126,12 +129,46 @@ export class OpencodeRuntimeAdapter {
}
}
async createSession(title?: string) {
async createSession(
title?: string,
options: {
conversationWorkspace?: boolean;
workspaceRoot?: string;
} = {},
) {
const client = await this.ensureClient();
const response = await client.session.create({
title,
});
return requireData(response.data, "session.create");
if (!options.conversationWorkspace) {
const response = await client.session.create({ title });
return requireData(response.data, "session.create");
}
const workspaceRoot = resolve(
options.workspaceRoot ?? config.RESULT_REF_IMPORT_DIR,
);
const directory = resolve(workspaceRoot, `conversation-${randomUUID()}`);
await ensureDirectory(workspaceRoot);
await chmod(workspaceRoot, 0o700);
await mkdir(directory, { mode: 0o700 });
try {
const response = await client.session.create({
directory,
title,
permission: [
{ permission: "read", pattern: `${directory}/**`, action: "allow" },
{ permission: "edit", pattern: `${directory}/**`, action: "ask" },
],
});
return requireData(response.data, "session.create");
} catch (error) {
await rmdir(directory).catch(() => undefined);
throw error;
}
}
async getSession(sessionId: string) {
const client = await this.ensureClient();
const response = await client.session.get({ sessionID: sessionId });
return requireData(response.data, "session.get");
}
async sendPrompt(sessionId: string, text: string) {