feat(core,cli): implement session-linked tool output storage and cleanup (#18416)

This commit is contained in:
Abhi
2026-02-06 01:36:42 -05:00
committed by GitHub
parent 8ec176e005
commit 30354892b3
12 changed files with 442 additions and 386 deletions
+27 -3
View File
@@ -1121,7 +1121,7 @@ describe('fileUtils', () => {
const expectedOutputFile = path.join(
tempRootDir,
'tool_output',
'tool-outputs',
'shell_123.txt',
);
expect(result.outputFile).toBe(expectedOutputFile);
@@ -1149,7 +1149,7 @@ describe('fileUtils', () => {
// ../../dangerous/tool -> ______dangerous_tool
const expectedOutputFile = path.join(
tempRootDir,
'tool_output',
'tool-outputs',
'______dangerous_tool_1.txt',
);
expect(result.outputFile).toBe(expectedOutputFile);
@@ -1170,12 +1170,36 @@ describe('fileUtils', () => {
// ../../etc/passwd -> ______etc_passwd
const expectedOutputFile = path.join(
tempRootDir,
'tool_output',
'tool-outputs',
'shell_______etc_passwd.txt',
);
expect(result.outputFile).toBe(expectedOutputFile);
});
it('should sanitize sessionId in filename/path', async () => {
const content = 'content';
const toolName = 'shell';
const id = '1';
const sessionId = '../../etc/passwd';
const result = await saveTruncatedToolOutput(
content,
toolName,
id,
tempRootDir,
sessionId,
);
// ../../etc/passwd -> ______etc_passwd
const expectedOutputFile = path.join(
tempRootDir,
'tool-outputs',
'session-______etc_passwd',
'shell_1.txt',
);
expect(result.outputFile).toBe(expectedOutputFile);
});
it('should format multi-line output correctly', () => {
const lines = Array.from({ length: 50 }, (_, i) => `line ${i}`);
const content = lines.join('\n');
+8 -2
View File
@@ -623,18 +623,24 @@ ${processedLines.join('\n')}`;
/**
* Saves tool output to a temporary file for later retrieval.
*/
export const TOOL_OUTPUT_DIR = 'tool_output';
export const TOOL_OUTPUTS_DIR = 'tool-outputs';
export async function saveTruncatedToolOutput(
content: string,
toolName: string,
id: string | number, // Accept string (callId) or number (truncationId)
projectTempDir: string,
sessionId?: string,
): Promise<{ outputFile: string; totalLines: number }> {
const safeToolName = sanitizeFilenamePart(toolName).toLowerCase();
const safeId = sanitizeFilenamePart(id.toString()).toLowerCase();
const fileName = `${safeToolName}_${safeId}.txt`;
const toolOutputDir = path.join(projectTempDir, TOOL_OUTPUT_DIR);
let toolOutputDir = path.join(projectTempDir, TOOL_OUTPUTS_DIR);
if (sessionId) {
const safeSessionId = sanitizeFilenamePart(sessionId);
toolOutputDir = path.join(toolOutputDir, `session-${safeSessionId}`);
}
const outputFile = path.join(toolOutputDir, fileName);
await fsPromises.mkdir(toolOutputDir, { recursive: true });