fix: session_id wiped on every trim, breaking --resume
The history trimming logic cleared session_id = None whenever entries exceeded history_size. Since the history was always at capacity, every new message wiped the session_id immediately after storing it. This meant --resume was never passed to Claude Code, making every turn a fresh conversation. Fix: preserve session_id on trim. Claude Code's --resume loads the full conversation from its own session transcript on disk, so trimming our local tracking entries doesn't invalidate the session. Also adds debug logging for session_id capture/storage (temporary). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -120,6 +120,7 @@ impl ClaudeCodeProvider {
|
|||||||
.map_err(|e| format!("PTY task panicked: {e}"))??;
|
.map_err(|e| format!("PTY task panicked: {e}"))??;
|
||||||
|
|
||||||
let captured_session_id = sid_rx.await.ok();
|
let captured_session_id = sid_rx.await.ok();
|
||||||
|
slog!("[pty-debug] RECEIVED session_id: {:?}", captured_session_id);
|
||||||
let structured_messages: Vec<Message> = msg_rx.try_iter().collect();
|
let structured_messages: Vec<Message> = msg_rx.try_iter().collect();
|
||||||
|
|
||||||
Ok(ClaudeCodeResult {
|
Ok(ClaudeCodeResult {
|
||||||
@@ -346,6 +347,7 @@ fn process_json_event(
|
|||||||
// Capture session_id from the first event that carries it
|
// Capture session_id from the first event that carries it
|
||||||
if let Some(tx) = sid_tx.take() {
|
if let Some(tx) = sid_tx.take() {
|
||||||
if let Some(sid) = json.get("session_id").and_then(|s| s.as_str()) {
|
if let Some(sid) = json.get("session_id").and_then(|s| s.as_str()) {
|
||||||
|
slog!("[pty-debug] CAPTURED session_id: {}", sid);
|
||||||
let _ = tx.send(sid.to_string());
|
let _ = tx.send(sid.to_string());
|
||||||
} else {
|
} else {
|
||||||
*sid_tx = Some(tx);
|
*sid_tx = Some(tx);
|
||||||
|
|||||||
@@ -881,6 +881,7 @@ async fn handle_message(
|
|||||||
} else {
|
} else {
|
||||||
remaining
|
remaining
|
||||||
};
|
};
|
||||||
|
slog!("[matrix-bot] session_id from chat_stream: {:?}", session_id);
|
||||||
(reply, session_id)
|
(reply, session_id)
|
||||||
}
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@@ -903,6 +904,7 @@ async fn handle_message(
|
|||||||
let conv = guard.entry(room_id).or_default();
|
let conv = guard.entry(room_id).or_default();
|
||||||
|
|
||||||
// Store the session ID so the next turn uses --resume.
|
// Store the session ID so the next turn uses --resume.
|
||||||
|
slog!("[matrix-bot] storing session_id: {:?} (was: {:?})", new_session_id, conv.session_id);
|
||||||
if new_session_id.is_some() {
|
if new_session_id.is_some() {
|
||||||
conv.session_id = new_session_id;
|
conv.session_id = new_session_id;
|
||||||
}
|
}
|
||||||
@@ -919,13 +921,12 @@ async fn handle_message(
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Trim to the configured maximum, dropping the oldest entries first.
|
// Trim to the configured maximum, dropping the oldest entries first.
|
||||||
// When trimming occurs, clear the session ID so the next turn starts
|
// The session_id is preserved: Claude Code's --resume loads the full
|
||||||
// a fresh Claude Code session (the old session's context would be
|
// conversation from its own session transcript on disk, so trimming
|
||||||
// stale since we've dropped entries from our tracking).
|
// our local tracking doesn't affect the LLM's context.
|
||||||
if conv.entries.len() > ctx.history_size {
|
if conv.entries.len() > ctx.history_size {
|
||||||
let excess = conv.entries.len() - ctx.history_size;
|
let excess = conv.entries.len() - ctx.history_size;
|
||||||
conv.entries.drain(..excess);
|
conv.entries.drain(..excess);
|
||||||
conv.session_id = None;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Persist to disk so history survives server restarts.
|
// Persist to disk so history survives server restarts.
|
||||||
|
|||||||
Reference in New Issue
Block a user