fix: prevent stale SDK session and tool-marker parroting after idle timeout (#184)
fix: prevent stale SDK session and tool-marker parroting after idle timeout
This commit is contained in:
1 parent
03d2636d7f
commit
a53c60531f
3 files changed
+18
-10
No files matched your search
@@ -1,5 +1,5 @@
|
||||
import { NextRequest } from 'next/server';
|
||||
import { deleteSession, getSession, updateSessionWorkingDirectory, updateSessionTitle, updateSessionMode, updateSessionModel, updateSessionProviderId, clearSessionMessages } from '@/lib/db';
|
||||
import { deleteSession, getSession, updateSessionWorkingDirectory, updateSessionTitle, updateSessionMode, updateSessionModel, updateSessionProviderId, clearSessionMessages, updateSdkSessionId } from '@/lib/db';
|
||||
|
||||
export async function GET(
|
||||
_request: NextRequest,
|
||||
@@ -46,6 +46,9 @@ export async function PATCH(
|
||||
if (body.provider_id !== undefined) {
|
||||
updateSessionProviderId(id, body.provider_id);
|
||||
}
|
||||
if (body.sdk_session_id !== undefined) {
|
||||
updateSdkSessionId(id, body.sdk_session_id);
|
||||
}
|
||||
if (body.clear_messages) {
|
||||
clearSessionMessages(id);
|
||||
}
|
||||
|
||||
@@ -235,9 +235,13 @@ function buildPromptWithHistory(
|
||||
): string {
|
||||
if (!history || history.length === 0) return prompt;
|
||||
|
||||
const lines: string[] = ['<conversation_history>'];
|
||||
const lines: string[] = [
|
||||
'<conversation_history>',
|
||||
'(This is a summary of earlier conversation turns for context. Tool calls shown here were already executed — do not repeat them or output their markers as text.)',
|
||||
];
|
||||
for (const msg of history) {
|
||||
// For assistant messages with tool blocks (JSON arrays), summarize
|
||||
// For assistant messages with tool blocks (JSON arrays), extract only the text portions.
|
||||
// Tool-use and tool-result blocks are omitted to avoid Claude parroting them as plain text.
|
||||
let content = msg.content;
|
||||
if (msg.role === 'assistant' && content.startsWith('[')) {
|
||||
try {
|
||||
@@ -245,14 +249,9 @@ function buildPromptWithHistory(
|
||||
const parts: string[] = [];
|
||||
for (const b of blocks) {
|
||||
if (b.type === 'text' && b.text) parts.push(b.text);
|
||||
else if (b.type === 'tool_use') parts.push(`[Used tool: ${b.name}]`);
|
||||
else if (b.type === 'tool_result') {
|
||||
const resultStr = typeof b.content === 'string' ? b.content : JSON.stringify(b.content);
|
||||
// Truncate long tool results
|
||||
parts.push(`[Tool result: ${resultStr.slice(0, 500)}${resultStr.length > 500 ? '...' : ''}]`);
|
||||
}
|
||||
// Skip tool_use and tool_result — they were already executed
|
||||
}
|
||||
content = parts.join('\n');
|
||||
content = parts.length > 0 ? parts.join('\n') : '(assistant used tools)';
|
||||
} catch {
|
||||
// Not JSON, use as-is
|
||||
}
|
||||
|
||||
@@ -405,6 +405,12 @@ async function runStream(stream: ActiveStream, params: StartStreamParams): Promi
|
||||
stream.toolResultsArray = [];
|
||||
stream.toolOutputAccumulated = '';
|
||||
emit(stream, 'completed');
|
||||
// Clear stale SDK session so next message starts fresh
|
||||
fetch(`/api/chat/sessions/${encodeURIComponent(stream.sessionId)}`, {
|
||||
method: 'PATCH',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ sdk_session_id: '' }),
|
||||
}).catch(() => {});
|
||||
scheduleGC(stream);
|
||||
} else if (stream.toolTimeoutInfo) {
|
||||
// Tool timeout — auto-retry
|
||||
|
||||
Reference in new issue
Block a user