emrg: persist and pass back DeepSeek thinking-mode reasoning - #937

Merged
argszero merged 1 commit into
masterfrom
feature/deepseek-reasoning-passback
Aug 22, 2026
Merged

emrg: persist and pass back DeepSeek thinking-mode reasoning#937
argszero merged 1 commit into
masterfrom
feature/deepseek-reasoning-passback

Conversation

@argszero

Copy link
Copy Markdown
Owner

Fixes DeepSeek thinking-mode 400 error: "The reasoning_content in the thinking mode must be passed back to the API" (LLM stream error in round N).

Root cause (verified against source + logs):

  1. llm.py correctly accumulates reasoning_content into full_reasoning during streaming;
  2. but the three append_message calls in daemon.py persisted assistant messages with only content + tool_calls (reasoning went only to llm.jsonl);
  3. on the next request, session.get_messages_for_llm() rebuilt assistant messages without reasoning;
  4. DeepSeek thinking mode requires assistant messages (especially tool-call rounds) to pass back the previously returned reasoning_content verbatim — missing it triggers the 400 inside tool loops.

Fix (4 changes):

  • daemon.py ×3 main-loop append_message sites: persist reasoning when not None (old records untouched);
  • daemon.py main-loop in-memory messages: reasoning_content added to the assistant message appended for the next round — closes the within-tool-loop path (round N error);
  • daemon.py memory-reflection + task-handler tool loops: pass back reasoning_content from llm.chat responses (same bug class);
  • session.pyget_messages_for_llm: maps persisted reasoningreasoning_content; records without the field are skipped naturally (old histories unaffected).

Compatibility: folded placeholder assistant messages (no tool_calls) are not required by DeepSeek to carry reasoning; history size grows slightly (API hard requirement) — a reasoning-window fold can be a follow-up.

Verification: pytest 1010 passed + 1 skipped (1011 collected, +3 new regression tests); import/help OK; Agent.md count synced to 1011.

@argszeroargszero left a comment

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle 2026-08-22T19:26:07. Fix is correct and complete:

  • Root cause verified: reasoning_content accumulated in llm.py streaming but dropped on session persistence and message reassembly, so subsequent rounds lack the verbatim reasoning DeepSeek thinking mode requires (400 error).
  • daemon.py covers all four message-building paths (final answer, in-loop tool_calls round, _reflect, _consolidate_session_memories) — reasoning persisted as 'reasoning' and re-injected as 'reasoning_content'.
  • session.py get_messages_for_llm() maps persisted reasoning → reasoning_content; old records without the field are skipped naturally (no regression).
  • Tests cover plain pass-back, tool-call rounds, and legacy-record compatibility.
  • CI green (test + test-windows, run 32566754537).

@argszeroargszero left a comment

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle 47. Re-verified: head unchanged (8858728), diff covers all four assistant-message paths (final answer / tool-call round / _reflect / task-handler) with reasoning persisted + re-injected as reasoning_content, session.py maps persisted reasoning back with natural skip for legacy records. 3 regression tests added; local pytest 1010 passed + 1 skipped; CI green (test + test-windows, run 32566754537).

@argszeroargszero left a comment

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle 48. Re-verified: head unchanged (8858728), CI green (test + test-windows, run 32566754537), fix covers all assistant-message paths + session mapping + legacy compat. 3rd consecutive ✅ — merging.

@argszero
argszero merged commit e6c066b into masterAug 22, 2026
2 checks passed
argszero added a commit that referenced this pull request Aug 22, 2026
#936#937) (#939)
* emrg: revert DeepSeek thinking-mode reasoning pass-back (rant 2026-08-22T21:12:46)
* emrg: revert tool result sliding window (#936) (rant 2026-08-22T21:23:18)
@argszero
argszero deleted the feature/deepseek-reasoning-passback branch August 23, 2026 02:26
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@argszero
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

emrg: persist and pass back DeepSeek thinking-mode reasoning - #937

Merged
argszero merged 1 commit into
masterfrom
feature/deepseek-reasoning-passback
Aug 22, 2026
Merged

emrg: persist and pass back DeepSeek thinking-mode reasoning#937
argszero merged 1 commit into
masterfrom
feature/deepseek-reasoning-passback

Conversation

@argszero

Copy link
Copy Markdown
Owner

Fixes DeepSeek thinking-mode 400 error: "The reasoning_content in the thinking mode must be passed back to the API" (LLM stream error in round N).

Root cause (verified against source + logs):

  1. llm.py correctly accumulates reasoning_content into full_reasoning during streaming;
  2. but the three append_message calls in daemon.py persisted assistant messages with only content + tool_calls (reasoning went only to llm.jsonl);
  3. on the next request, session.get_messages_for_llm() rebuilt assistant messages without reasoning;
  4. DeepSeek thinking mode requires assistant messages (especially tool-call rounds) to pass back the previously returned reasoning_content verbatim — missing it triggers the 400 inside tool loops.

Fix (4 changes):

  • daemon.py ×3 main-loop append_message sites: persist reasoning when not None (old records untouched);
  • daemon.py main-loop in-memory messages: reasoning_content added to the assistant message appended for the next round — closes the within-tool-loop path (round N error);
  • daemon.py memory-reflection + task-handler tool loops: pass back reasoning_content from llm.chat responses (same bug class);
  • session.pyget_messages_for_llm: maps persisted reasoningreasoning_content; records without the field are skipped naturally (old histories unaffected).

Compatibility: folded placeholder assistant messages (no tool_calls) are not required by DeepSeek to carry reasoning; history size grows slightly (API hard requirement) — a reasoning-window fold can be a follow-up.

Verification: pytest 1010 passed + 1 skipped (1011 collected, +3 new regression tests); import/help OK; Agent.md count synced to 1011.

@argszeroargszero left a comment

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle 2026-08-22T19:26:07. Fix is correct and complete:

  • Root cause verified: reasoning_content accumulated in llm.py streaming but dropped on session persistence and message reassembly, so subsequent rounds lack the verbatim reasoning DeepSeek thinking mode requires (400 error).
  • daemon.py covers all four message-building paths (final answer, in-loop tool_calls round, _reflect, _consolidate_session_memories) — reasoning persisted as 'reasoning' and re-injected as 'reasoning_content'.
  • session.py get_messages_for_llm() maps persisted reasoning → reasoning_content; old records without the field are skipped naturally (no regression).
  • Tests cover plain pass-back, tool-call rounds, and legacy-record compatibility.
  • CI green (test + test-windows, run 32566754537).

@argszeroargszero left a comment

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle 47. Re-verified: head unchanged (8858728), diff covers all four assistant-message paths (final answer / tool-call round / _reflect / task-handler) with reasoning persisted + re-injected as reasoning_content, session.py maps persisted reasoning back with natural skip for legacy records. 3 regression tests added; local pytest 1010 passed + 1 skipped; CI green (test + test-windows, run 32566754537).

@argszeroargszero left a comment

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle 48. Re-verified: head unchanged (8858728), CI green (test + test-windows, run 32566754537), fix covers all assistant-message paths + session mapping + legacy compat. 3rd consecutive ✅ — merging.

@argszero
argszero merged commit e6c066b into masterAug 22, 2026
2 checks passed
argszero added a commit that referenced this pull request Aug 22, 2026
#936#937) (#939)
* emrg: revert DeepSeek thinking-mode reasoning pass-back (rant 2026-08-22T21:12:46)
* emrg: revert tool result sliding window (#936) (rant 2026-08-22T21:23:18)
@argszero
argszero deleted the feature/deepseek-reasoning-passback branch August 23, 2026 02:26
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@argszero
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

emrg: persist and pass back DeepSeek thinking-mode reasoning - #937

Merged
argszero merged 1 commit into
masterfrom
feature/deepseek-reasoning-passback
Aug 22, 2026
Merged

emrg: persist and pass back DeepSeek thinking-mode reasoning#937
argszero merged 1 commit into
masterfrom
feature/deepseek-reasoning-passback

Conversation

@argszero

Copy link
Copy Markdown
Owner

Fixes DeepSeek thinking-mode 400 error: "The reasoning_content in the thinking mode must be passed back to the API" (LLM stream error in round N).

Root cause (verified against source + logs):

  1. llm.py correctly accumulates reasoning_content into full_reasoning during streaming;
  2. but the three append_message calls in daemon.py persisted assistant messages with only content + tool_calls (reasoning went only to llm.jsonl);
  3. on the next request, session.get_messages_for_llm() rebuilt assistant messages without reasoning;
  4. DeepSeek thinking mode requires assistant messages (especially tool-call rounds) to pass back the previously returned reasoning_content verbatim — missing it triggers the 400 inside tool loops.

Fix (4 changes):

  • daemon.py ×3 main-loop append_message sites: persist reasoning when not None (old records untouched);
  • daemon.py main-loop in-memory messages: reasoning_content added to the assistant message appended for the next round — closes the within-tool-loop path (round N error);
  • daemon.py memory-reflection + task-handler tool loops: pass back reasoning_content from llm.chat responses (same bug class);
  • session.pyget_messages_for_llm: maps persisted reasoningreasoning_content; records without the field are skipped naturally (old histories unaffected).

Compatibility: folded placeholder assistant messages (no tool_calls) are not required by DeepSeek to carry reasoning; history size grows slightly (API hard requirement) — a reasoning-window fold can be a follow-up.

Verification: pytest 1010 passed + 1 skipped (1011 collected, +3 new regression tests); import/help OK; Agent.md count synced to 1011.

@argszeroargszero left a comment

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle 2026-08-22T19:26:07. Fix is correct and complete:

  • Root cause verified: reasoning_content accumulated in llm.py streaming but dropped on session persistence and message reassembly, so subsequent rounds lack the verbatim reasoning DeepSeek thinking mode requires (400 error).
  • daemon.py covers all four message-building paths (final answer, in-loop tool_calls round, _reflect, _consolidate_session_memories) — reasoning persisted as 'reasoning' and re-injected as 'reasoning_content'.
  • session.py get_messages_for_llm() maps persisted reasoning → reasoning_content; old records without the field are skipped naturally (no regression).
  • Tests cover plain pass-back, tool-call rounds, and legacy-record compatibility.
  • CI green (test + test-windows, run 32566754537).

@argszeroargszero left a comment

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle 47. Re-verified: head unchanged (8858728), diff covers all four assistant-message paths (final answer / tool-call round / _reflect / task-handler) with reasoning persisted + re-injected as reasoning_content, session.py maps persisted reasoning back with natural skip for legacy records. 3 regression tests added; local pytest 1010 passed + 1 skipped; CI green (test + test-windows, run 32566754537).

@argszeroargszero left a comment

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle 48. Re-verified: head unchanged (8858728), CI green (test + test-windows, run 32566754537), fix covers all assistant-message paths + session mapping + legacy compat. 3rd consecutive ✅ — merging.

@argszero
argszero merged commit e6c066b into masterAug 22, 2026
2 checks passed
argszero added a commit that referenced this pull request Aug 22, 2026
#936#937) (#939)
* emrg: revert DeepSeek thinking-mode reasoning pass-back (rant 2026-08-22T21:12:46)
* emrg: revert tool result sliding window (#936) (rant 2026-08-22T21:23:18)
@argszero
argszero deleted the feature/deepseek-reasoning-passback branch August 23, 2026 02:26
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@argszero
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

emrg: persist and pass back DeepSeek thinking-mode reasoning - #937

Merged
argszero merged 1 commit into
masterfrom
feature/deepseek-reasoning-passback
Aug 22, 2026
Merged

emrg: persist and pass back DeepSeek thinking-mode reasoning#937
argszero merged 1 commit into
masterfrom
feature/deepseek-reasoning-passback

Conversation

@argszero

Copy link
Copy Markdown
Owner

Fixes DeepSeek thinking-mode 400 error: "The reasoning_content in the thinking mode must be passed back to the API" (LLM stream error in round N).

Root cause (verified against source + logs):

  1. llm.py correctly accumulates reasoning_content into full_reasoning during streaming;
  2. but the three append_message calls in daemon.py persisted assistant messages with only content + tool_calls (reasoning went only to llm.jsonl);
  3. on the next request, session.get_messages_for_llm() rebuilt assistant messages without reasoning;
  4. DeepSeek thinking mode requires assistant messages (especially tool-call rounds) to pass back the previously returned reasoning_content verbatim — missing it triggers the 400 inside tool loops.

Fix (4 changes):

  • daemon.py ×3 main-loop append_message sites: persist reasoning when not None (old records untouched);
  • daemon.py main-loop in-memory messages: reasoning_content added to the assistant message appended for the next round — closes the within-tool-loop path (round N error);
  • daemon.py memory-reflection + task-handler tool loops: pass back reasoning_content from llm.chat responses (same bug class);
  • session.pyget_messages_for_llm: maps persisted reasoningreasoning_content; records without the field are skipped naturally (old histories unaffected).

Compatibility: folded placeholder assistant messages (no tool_calls) are not required by DeepSeek to carry reasoning; history size grows slightly (API hard requirement) — a reasoning-window fold can be a follow-up.

Verification: pytest 1010 passed + 1 skipped (1011 collected, +3 new regression tests); import/help OK; Agent.md count synced to 1011.

@argszeroargszero left a comment

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle 2026-08-22T19:26:07. Fix is correct and complete:

  • Root cause verified: reasoning_content accumulated in llm.py streaming but dropped on session persistence and message reassembly, so subsequent rounds lack the verbatim reasoning DeepSeek thinking mode requires (400 error).
  • daemon.py covers all four message-building paths (final answer, in-loop tool_calls round, _reflect, _consolidate_session_memories) — reasoning persisted as 'reasoning' and re-injected as 'reasoning_content'.
  • session.py get_messages_for_llm() maps persisted reasoning → reasoning_content; old records without the field are skipped naturally (no regression).
  • Tests cover plain pass-back, tool-call rounds, and legacy-record compatibility.
  • CI green (test + test-windows, run 32566754537).

@argszeroargszero left a comment

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle 47. Re-verified: head unchanged (8858728), diff covers all four assistant-message paths (final answer / tool-call round / _reflect / task-handler) with reasoning persisted + re-injected as reasoning_content, session.py maps persisted reasoning back with natural skip for legacy records. 3 regression tests added; local pytest 1010 passed + 1 skipped; CI green (test + test-windows, run 32566754537).

@argszeroargszero left a comment

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle 48. Re-verified: head unchanged (8858728), CI green (test + test-windows, run 32566754537), fix covers all assistant-message paths + session mapping + legacy compat. 3rd consecutive ✅ — merging.

@argszero
argszero merged commit e6c066b into masterAug 22, 2026
2 checks passed
argszero added a commit that referenced this pull request Aug 22, 2026
#936#937) (#939)
* emrg: revert DeepSeek thinking-mode reasoning pass-back (rant 2026-08-22T21:12:46)
* emrg: revert tool result sliding window (#936) (rant 2026-08-22T21:23:18)
@argszero
argszero deleted the feature/deepseek-reasoning-passback branch August 23, 2026 02:26
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@argszero
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

emrg: persist and pass back DeepSeek thinking-mode reasoning - #937

Merged
argszero merged 1 commit into
masterfrom
feature/deepseek-reasoning-passback
Aug 22, 2026
Merged

emrg: persist and pass back DeepSeek thinking-mode reasoning#937
argszero merged 1 commit into
masterfrom
feature/deepseek-reasoning-passback

Conversation

@argszero

Copy link
Copy Markdown
Owner

Fixes DeepSeek thinking-mode 400 error: "The reasoning_content in the thinking mode must be passed back to the API" (LLM stream error in round N).

Root cause (verified against source + logs):

  1. llm.py correctly accumulates reasoning_content into full_reasoning during streaming;
  2. but the three append_message calls in daemon.py persisted assistant messages with only content + tool_calls (reasoning went only to llm.jsonl);
  3. on the next request, session.get_messages_for_llm() rebuilt assistant messages without reasoning;
  4. DeepSeek thinking mode requires assistant messages (especially tool-call rounds) to pass back the previously returned reasoning_content verbatim — missing it triggers the 400 inside tool loops.

Fix (4 changes):

  • daemon.py ×3 main-loop append_message sites: persist reasoning when not None (old records untouched);
  • daemon.py main-loop in-memory messages: reasoning_content added to the assistant message appended for the next round — closes the within-tool-loop path (round N error);
  • daemon.py memory-reflection + task-handler tool loops: pass back reasoning_content from llm.chat responses (same bug class);
  • session.pyget_messages_for_llm: maps persisted reasoningreasoning_content; records without the field are skipped naturally (old histories unaffected).

Compatibility: folded placeholder assistant messages (no tool_calls) are not required by DeepSeek to carry reasoning; history size grows slightly (API hard requirement) — a reasoning-window fold can be a follow-up.

Verification: pytest 1010 passed + 1 skipped (1011 collected, +3 new regression tests); import/help OK; Agent.md count synced to 1011.

@argszeroargszero left a comment

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle 2026-08-22T19:26:07. Fix is correct and complete:

  • Root cause verified: reasoning_content accumulated in llm.py streaming but dropped on session persistence and message reassembly, so subsequent rounds lack the verbatim reasoning DeepSeek thinking mode requires (400 error).
  • daemon.py covers all four message-building paths (final answer, in-loop tool_calls round, _reflect, _consolidate_session_memories) — reasoning persisted as 'reasoning' and re-injected as 'reasoning_content'.
  • session.py get_messages_for_llm() maps persisted reasoning → reasoning_content; old records without the field are skipped naturally (no regression).
  • Tests cover plain pass-back, tool-call rounds, and legacy-record compatibility.
  • CI green (test + test-windows, run 32566754537).

@argszeroargszero left a comment

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle 47. Re-verified: head unchanged (8858728), diff covers all four assistant-message paths (final answer / tool-call round / _reflect / task-handler) with reasoning persisted + re-injected as reasoning_content, session.py maps persisted reasoning back with natural skip for legacy records. 3 regression tests added; local pytest 1010 passed + 1 skipped; CI green (test + test-windows, run 32566754537).

@argszeroargszero left a comment

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle 48. Re-verified: head unchanged (8858728), CI green (test + test-windows, run 32566754537), fix covers all assistant-message paths + session mapping + legacy compat. 3rd consecutive ✅ — merging.

@argszero
argszero merged commit e6c066b into masterAug 22, 2026
2 checks passed
argszero added a commit that referenced this pull request Aug 22, 2026
#936#937) (#939)
* emrg: revert DeepSeek thinking-mode reasoning pass-back (rant 2026-08-22T21:12:46)
* emrg: revert tool result sliding window (#936) (rant 2026-08-22T21:23:18)
@argszero
argszero deleted the feature/deepseek-reasoning-passback branch August 23, 2026 02:26
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@argszero
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

emrg: persist and pass back DeepSeek thinking-mode reasoning - #937

Merged
argszero merged 1 commit into
masterfrom
feature/deepseek-reasoning-passback
Aug 22, 2026
Merged

emrg: persist and pass back DeepSeek thinking-mode reasoning#937
argszero merged 1 commit into
masterfrom
feature/deepseek-reasoning-passback

Conversation

@argszero

Copy link
Copy Markdown
Owner

Fixes DeepSeek thinking-mode 400 error: "The reasoning_content in the thinking mode must be passed back to the API" (LLM stream error in round N).

Root cause (verified against source + logs):

  1. llm.py correctly accumulates reasoning_content into full_reasoning during streaming;
  2. but the three append_message calls in daemon.py persisted assistant messages with only content + tool_calls (reasoning went only to llm.jsonl);
  3. on the next request, session.get_messages_for_llm() rebuilt assistant messages without reasoning;
  4. DeepSeek thinking mode requires assistant messages (especially tool-call rounds) to pass back the previously returned reasoning_content verbatim — missing it triggers the 400 inside tool loops.

Fix (4 changes):

  • daemon.py ×3 main-loop append_message sites: persist reasoning when not None (old records untouched);
  • daemon.py main-loop in-memory messages: reasoning_content added to the assistant message appended for the next round — closes the within-tool-loop path (round N error);
  • daemon.py memory-reflection + task-handler tool loops: pass back reasoning_content from llm.chat responses (same bug class);
  • session.pyget_messages_for_llm: maps persisted reasoningreasoning_content; records without the field are skipped naturally (old histories unaffected).

Compatibility: folded placeholder assistant messages (no tool_calls) are not required by DeepSeek to carry reasoning; history size grows slightly (API hard requirement) — a reasoning-window fold can be a follow-up.

Verification: pytest 1010 passed + 1 skipped (1011 collected, +3 new regression tests); import/help OK; Agent.md count synced to 1011.

@argszeroargszero left a comment

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle 2026-08-22T19:26:07. Fix is correct and complete:

  • Root cause verified: reasoning_content accumulated in llm.py streaming but dropped on session persistence and message reassembly, so subsequent rounds lack the verbatim reasoning DeepSeek thinking mode requires (400 error).
  • daemon.py covers all four message-building paths (final answer, in-loop tool_calls round, _reflect, _consolidate_session_memories) — reasoning persisted as 'reasoning' and re-injected as 'reasoning_content'.
  • session.py get_messages_for_llm() maps persisted reasoning → reasoning_content; old records without the field are skipped naturally (no regression).
  • Tests cover plain pass-back, tool-call rounds, and legacy-record compatibility.
  • CI green (test + test-windows, run 32566754537).

@argszeroargszero left a comment

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle 47. Re-verified: head unchanged (8858728), diff covers all four assistant-message paths (final answer / tool-call round / _reflect / task-handler) with reasoning persisted + re-injected as reasoning_content, session.py maps persisted reasoning back with natural skip for legacy records. 3 regression tests added; local pytest 1010 passed + 1 skipped; CI green (test + test-windows, run 32566754537).

@argszeroargszero left a comment

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle 48. Re-verified: head unchanged (8858728), CI green (test + test-windows, run 32566754537), fix covers all assistant-message paths + session mapping + legacy compat. 3rd consecutive ✅ — merging.

@argszero
argszero merged commit e6c066b into masterAug 22, 2026
2 checks passed
argszero added a commit that referenced this pull request Aug 22, 2026
#936#937) (#939)
* emrg: revert DeepSeek thinking-mode reasoning pass-back (rant 2026-08-22T21:12:46)
* emrg: revert tool result sliding window (#936) (rant 2026-08-22T21:23:18)
@argszero
argszero deleted the feature/deepseek-reasoning-passback branch August 23, 2026 02:26
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@argszero
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

emrg: persist and pass back DeepSeek thinking-mode reasoning - #937

Merged
argszero merged 1 commit into
masterfrom
feature/deepseek-reasoning-passback
Aug 22, 2026
Merged

emrg: persist and pass back DeepSeek thinking-mode reasoning#937
argszero merged 1 commit into
masterfrom
feature/deepseek-reasoning-passback

Conversation

@argszero

Copy link
Copy Markdown
Owner

Fixes DeepSeek thinking-mode 400 error: "The reasoning_content in the thinking mode must be passed back to the API" (LLM stream error in round N).

Root cause (verified against source + logs):

  1. llm.py correctly accumulates reasoning_content into full_reasoning during streaming;
  2. but the three append_message calls in daemon.py persisted assistant messages with only content + tool_calls (reasoning went only to llm.jsonl);
  3. on the next request, session.get_messages_for_llm() rebuilt assistant messages without reasoning;
  4. DeepSeek thinking mode requires assistant messages (especially tool-call rounds) to pass back the previously returned reasoning_content verbatim — missing it triggers the 400 inside tool loops.

Fix (4 changes):

  • daemon.py ×3 main-loop append_message sites: persist reasoning when not None (old records untouched);
  • daemon.py main-loop in-memory messages: reasoning_content added to the assistant message appended for the next round — closes the within-tool-loop path (round N error);
  • daemon.py memory-reflection + task-handler tool loops: pass back reasoning_content from llm.chat responses (same bug class);
  • session.pyget_messages_for_llm: maps persisted reasoningreasoning_content; records without the field are skipped naturally (old histories unaffected).

Compatibility: folded placeholder assistant messages (no tool_calls) are not required by DeepSeek to carry reasoning; history size grows slightly (API hard requirement) — a reasoning-window fold can be a follow-up.

Verification: pytest 1010 passed + 1 skipped (1011 collected, +3 new regression tests); import/help OK; Agent.md count synced to 1011.

@argszeroargszero left a comment

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle 2026-08-22T19:26:07. Fix is correct and complete:

  • Root cause verified: reasoning_content accumulated in llm.py streaming but dropped on session persistence and message reassembly, so subsequent rounds lack the verbatim reasoning DeepSeek thinking mode requires (400 error).
  • daemon.py covers all four message-building paths (final answer, in-loop tool_calls round, _reflect, _consolidate_session_memories) — reasoning persisted as 'reasoning' and re-injected as 'reasoning_content'.
  • session.py get_messages_for_llm() maps persisted reasoning → reasoning_content; old records without the field are skipped naturally (no regression).
  • Tests cover plain pass-back, tool-call rounds, and legacy-record compatibility.
  • CI green (test + test-windows, run 32566754537).

@argszeroargszero left a comment

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle 47. Re-verified: head unchanged (8858728), diff covers all four assistant-message paths (final answer / tool-call round / _reflect / task-handler) with reasoning persisted + re-injected as reasoning_content, session.py maps persisted reasoning back with natural skip for legacy records. 3 regression tests added; local pytest 1010 passed + 1 skipped; CI green (test + test-windows, run 32566754537).

@argszeroargszero left a comment

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle 48. Re-verified: head unchanged (8858728), CI green (test + test-windows, run 32566754537), fix covers all assistant-message paths + session mapping + legacy compat. 3rd consecutive ✅ — merging.

@argszero
argszero merged commit e6c066b into masterAug 22, 2026
2 checks passed
argszero added a commit that referenced this pull request Aug 22, 2026
#936#937) (#939)
* emrg: revert DeepSeek thinking-mode reasoning pass-back (rant 2026-08-22T21:12:46)
* emrg: revert tool result sliding window (#936) (rant 2026-08-22T21:23:18)
@argszero
argszero deleted the feature/deepseek-reasoning-passback branch August 23, 2026 02:26
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@argszero
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

emrg: persist and pass back DeepSeek thinking-mode reasoning - #937

Merged
argszero merged 1 commit into
masterfrom
feature/deepseek-reasoning-passback
Aug 22, 2026
Merged

emrg: persist and pass back DeepSeek thinking-mode reasoning#937
argszero merged 1 commit into
masterfrom
feature/deepseek-reasoning-passback

Conversation

@argszero

Copy link
Copy Markdown
Owner

Fixes DeepSeek thinking-mode 400 error: "The reasoning_content in the thinking mode must be passed back to the API" (LLM stream error in round N).

Root cause (verified against source + logs):

  1. llm.py correctly accumulates reasoning_content into full_reasoning during streaming;
  2. but the three append_message calls in daemon.py persisted assistant messages with only content + tool_calls (reasoning went only to llm.jsonl);
  3. on the next request, session.get_messages_for_llm() rebuilt assistant messages without reasoning;
  4. DeepSeek thinking mode requires assistant messages (especially tool-call rounds) to pass back the previously returned reasoning_content verbatim — missing it triggers the 400 inside tool loops.

Fix (4 changes):

  • daemon.py ×3 main-loop append_message sites: persist reasoning when not None (old records untouched);
  • daemon.py main-loop in-memory messages: reasoning_content added to the assistant message appended for the next round — closes the within-tool-loop path (round N error);
  • daemon.py memory-reflection + task-handler tool loops: pass back reasoning_content from llm.chat responses (same bug class);
  • session.pyget_messages_for_llm: maps persisted reasoningreasoning_content; records without the field are skipped naturally (old histories unaffected).

Compatibility: folded placeholder assistant messages (no tool_calls) are not required by DeepSeek to carry reasoning; history size grows slightly (API hard requirement) — a reasoning-window fold can be a follow-up.

Verification: pytest 1010 passed + 1 skipped (1011 collected, +3 new regression tests); import/help OK; Agent.md count synced to 1011.

@argszeroargszero left a comment

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle 2026-08-22T19:26:07. Fix is correct and complete:

  • Root cause verified: reasoning_content accumulated in llm.py streaming but dropped on session persistence and message reassembly, so subsequent rounds lack the verbatim reasoning DeepSeek thinking mode requires (400 error).
  • daemon.py covers all four message-building paths (final answer, in-loop tool_calls round, _reflect, _consolidate_session_memories) — reasoning persisted as 'reasoning' and re-injected as 'reasoning_content'.
  • session.py get_messages_for_llm() maps persisted reasoning → reasoning_content; old records without the field are skipped naturally (no regression).
  • Tests cover plain pass-back, tool-call rounds, and legacy-record compatibility.
  • CI green (test + test-windows, run 32566754537).

@argszeroargszero left a comment

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle 47. Re-verified: head unchanged (8858728), diff covers all four assistant-message paths (final answer / tool-call round / _reflect / task-handler) with reasoning persisted + re-injected as reasoning_content, session.py maps persisted reasoning back with natural skip for legacy records. 3 regression tests added; local pytest 1010 passed + 1 skipped; CI green (test + test-windows, run 32566754537).

@argszeroargszero left a comment

Copy link
Copy Markdown
OwnerAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ LGTM — cycle 48. Re-verified: head unchanged (8858728), CI green (test + test-windows, run 32566754537), fix covers all assistant-message paths + session mapping + legacy compat. 3rd consecutive ✅ — merging.

@argszero
argszero merged commit e6c066b into masterAug 22, 2026
2 checks passed
argszero added a commit that referenced this pull request Aug 22, 2026
#936#937) (#939)
* emrg: revert DeepSeek thinking-mode reasoning pass-back (rant 2026-08-22T21:12:46)
* emrg: revert tool result sliding window (#936) (rant 2026-08-22T21:23:18)
@argszero
argszero deleted the feature/deepseek-reasoning-passback branch August 23, 2026 02:26
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@argszero