Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/app/api/chat/sessions/[id]/route.ts
Original file line number Diff line number Diff line change
@@ -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,
Expand Down Expand Up @@ -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);
}
Expand Down
17 changes: 8 additions & 9 deletions src/lib/claude-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,24 +235,23 @@ 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 {
const blocks = JSON.parse(content);
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
}
Expand Down
6 changes: 6 additions & 0 deletions src/lib/stream-session-manager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,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
Expand Down
Loading