feat: off the record mode (OTR)
Adds a third input mode toggle alongside Note and Agent. When active: - Textarea gets a subtle purple tint with dashed border - OTR button highlights purple - Placeholder reads "Off the record — not logged or distilled…" - off_record=True is sent to /chat; session_logger is skipped - In-memory session context is preserved within the session Switching to Note or Agent mode deactivates OTR, and vice versa. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -23,6 +23,7 @@ class ChatRequest(BaseModel):
|
||||
include_long: bool = True
|
||||
include_mid: bool = True
|
||||
include_short: bool = True
|
||||
off_record: bool = False # skip session log (in-memory context preserved)
|
||||
user: str = "scott"
|
||||
persona: str = "inara"
|
||||
|
||||
@@ -92,7 +93,8 @@ async def _stream_chat(req: ChatRequest):
|
||||
response_text, actual_backend = task.result()
|
||||
history.append({"role": "assistant", "content": response_text})
|
||||
save_session(session_id, history)
|
||||
log_turn(session_id, req.message, response_text)
|
||||
if not req.off_record:
|
||||
log_turn(session_id, req.message, response_text)
|
||||
|
||||
requested = req.model or settings.primary_backend
|
||||
payload = {
|
||||
|
||||
@@ -80,11 +80,35 @@
|
||||
|
||||
agentModeBtnEl.addEventListener('click', () => {
|
||||
agentMode = !agentMode;
|
||||
if (agentMode) { otr_mode = false; update_otr_ui(); }
|
||||
localStorage.setItem('agentMode', agentMode);
|
||||
updateAgentModeUI();
|
||||
inputEl.focus();
|
||||
});
|
||||
|
||||
// ── Off the record mode ──────────────────────────────────────
|
||||
let otr_mode = false;
|
||||
const otr_btn_el = document.getElementById('otr-btn');
|
||||
|
||||
function update_otr_ui() {
|
||||
otr_btn_el.classList.toggle('active', otr_mode);
|
||||
inputEl.classList.toggle('otr-mode', otr_mode);
|
||||
updateInputPlaceholder();
|
||||
}
|
||||
|
||||
otr_btn_el.addEventListener('click', () => {
|
||||
otr_mode = !otr_mode;
|
||||
if (otr_mode) {
|
||||
agentMode = false;
|
||||
noteMode = false;
|
||||
localStorage.setItem('agentMode', false);
|
||||
updateAgentModeUI();
|
||||
updateInputMode();
|
||||
}
|
||||
update_otr_ui();
|
||||
inputEl.focus();
|
||||
});
|
||||
|
||||
// ── Note mode ────────────────────────────────────────────────
|
||||
let noteMode = false;
|
||||
let notePublic = false;
|
||||
@@ -124,6 +148,8 @@
|
||||
inputEl.placeholder = ctrlEnterMode
|
||||
? `Task for ${personaLabel}… (Gemini tool loop — Ctrl+Enter to run)`
|
||||
: `Task for ${personaLabel}… (Gemini tool loop)`;
|
||||
} else if (otr_mode) {
|
||||
inputEl.placeholder = `Off the record — not logged or distilled…`;
|
||||
} else {
|
||||
inputEl.placeholder = ctrlEnterMode
|
||||
? `Message ${personaLabel}… (Ctrl+Enter to send)`
|
||||
@@ -133,6 +159,7 @@
|
||||
|
||||
noteBtnEl.addEventListener('click', () => {
|
||||
noteMode = !noteMode;
|
||||
if (noteMode) { otr_mode = false; update_otr_ui(); }
|
||||
updateInputMode();
|
||||
inputEl.focus();
|
||||
});
|
||||
@@ -690,6 +717,7 @@
|
||||
include_long: memLong,
|
||||
include_mid: memMid,
|
||||
include_short: memShort,
|
||||
off_record: otr_mode,
|
||||
user: CORTEX_USER,
|
||||
persona: CORTEX_PERSONA,
|
||||
}),
|
||||
|
||||
@@ -131,6 +131,7 @@
|
||||
<!-- Note mode controls -->
|
||||
<button id="note-type-btn">private</button>
|
||||
<button id="note-btn">Note</button>
|
||||
<button id="otr-btn" title="Off the record — not logged or distilled into memory">OTR</button>
|
||||
<button id="agent-mode-btn" title="Agent mode — Gemini tool loop + Claude response">Agent</button>
|
||||
<button id="send">Send</button>
|
||||
<button id="stop">Stop</button>
|
||||
|
||||
@@ -571,6 +571,27 @@
|
||||
#note-btn.active { border-color: rgba(180, 130, 40, 0.6); color: #c9a84c; }
|
||||
#note-btn.active.public { border-color: rgba(40, 170, 150, 0.6); color: #4abfb0; }
|
||||
|
||||
/* OTR button */
|
||||
#otr-btn {
|
||||
background: var(--bg);
|
||||
border: 1px solid var(--border);
|
||||
color: var(--muted);
|
||||
border-radius: 8px;
|
||||
padding: 8px 0;
|
||||
cursor: pointer;
|
||||
font-size: 0.85rem;
|
||||
text-align: center;
|
||||
transition: border-color 0.15s, color 0.15s;
|
||||
}
|
||||
#otr-btn:hover { border-color: var(--muted); color: var(--text); }
|
||||
#otr-btn.active { border-color: rgba(120, 80, 160, 0.6); color: #a87fd4; }
|
||||
|
||||
/* OTR textarea styling */
|
||||
#input.otr-mode {
|
||||
border-color: rgba(120, 80, 160, 0.4);
|
||||
background: rgba(120, 80, 160, 0.04);
|
||||
}
|
||||
|
||||
/* Send button */
|
||||
#send {
|
||||
background: var(--user-bg);
|
||||
|
||||
Reference in New Issue
Block a user