diff --git a/cortex/context_loader.py b/cortex/context_loader.py index df3c67d..f1a1a7f 100644 --- a/cortex/context_loader.py +++ b/cortex/context_loader.py @@ -20,6 +20,7 @@ def load_context( include_mid: bool = True, include_short: bool = True, role_append: str = "", + inject_datetime: bool = True, ) -> str: """ Build the system-prompt context block for a given tier and memory toggles. @@ -38,9 +39,10 @@ def load_context( inara_dir = persona_path() parts = [] - # ── 0. Current date and time (always — injected first so it's prominent) ── - now = datetime.now().astimezone() - parts.append(f"--- System ---\nCurrent date and time: {now.strftime('%A, %Y-%m-%d at %I:%M %p %Z')}") + # ── 0. Current date and time (per-role toggle — injected first so it's prominent) ── + if inject_datetime: + now = datetime.now().astimezone() + parts.append(f"--- System ---\nCurrent date and time: {now.strftime('%A, %Y-%m-%d at %I:%M %p %Z')}") # ── 1. Core identity (always) ────────────────────────────────── for filename in _CORE: diff --git a/cortex/model_registry.py b/cortex/model_registry.py index 0d52b05..04698ae 100644 --- a/cortex/model_registry.py +++ b/cortex/model_registry.py @@ -416,17 +416,25 @@ def get_best_local_model(username: str, role: str = "chat") -> dict | None: return None -def set_role_config(username: str, role: str, system_append: str, tools: list[str] | None) -> None: - """Save system_append and tools allow-list for a role. +def set_role_config( + username: str, + role: str, + system_append: str, + tools: list[str] | None, + inject_datetime: bool = True, +) -> None: + """Save system_append, tools allow-list, and inject_datetime flag for a role. tools=None clears the allow-list (role uses all accessible tools). - tools=[] would mean no tools at all — validate in the caller if that's undesired. + inject_datetime=False suppresses the current date/time from the system prompt + for this role — useful for pure processing roles (summarizer, classifier, etc.). """ data = _load(username) roles = data.setdefault("roles", {}) if role not in roles: roles[role] = {} roles[role]["system_append"] = system_append.strip() + roles[role]["inject_datetime"] = inject_datetime if tools is None: roles[role].pop("tools", None) else: @@ -436,17 +444,19 @@ def set_role_config(username: str, role: str, system_append: str, tools: list[st def get_role_config(username: str, role: str) -> dict: """ - Return supplemental config for a role: system_append and tools. + Return supplemental config for a role: system_append, tools, and inject_datetime. - Both keys are optional in the registry — missing means "use defaults": - system_append: str — appended to the system prompt for this role + All keys are optional in the registry — missing means "use defaults": + system_append: str — appended to the system prompt for this role tools: list[str] | None — explicit tool allow-list (None = no restriction) + inject_datetime: bool — whether to inject current date/time (default True) """ registry = _load(username) role_cfg = registry.get("roles", {}).get(role, {}) return { - "system_append": role_cfg.get("system_append", ""), - "tools": role_cfg.get("tools") or None, + "system_append": role_cfg.get("system_append", ""), + "tools": role_cfg.get("tools") or None, + "inject_datetime": role_cfg.get("inject_datetime", True), } diff --git a/cortex/routers/local_llm.py b/cortex/routers/local_llm.py index 7b168dd..e91a296 100644 --- a/cortex/routers/local_llm.py +++ b/cortex/routers/local_llm.py @@ -313,6 +313,14 @@ def _render(username: str, success: str = "", error: str = "") -> str: f'' f'' + f'
' + f'' + f'' + f'Disable for pure processing roles (summarizer, classifier, translator)' + f'
' f'
' f'' @@ -332,8 +340,9 @@ def _render(username: str, success: str = "", error: str = "") -> str: role_config_data_js = _json.dumps({ role: { - "system_append": roles.get(role, {}).get("system_append", ""), - "tools": roles.get(role, {}).get("tools") or None, + "system_append": roles.get(role, {}).get("system_append", ""), + "tools": roles.get(role, {}).get("tools") or None, + "inject_datetime": roles.get(role, {}).get("inject_datetime", True), } for role in app_settings.get_defined_roles() }) @@ -574,10 +583,11 @@ async def set_role(request: Request) -> JSONResponse: @router.post("/api/models/role-config") async def set_role_config(request: Request) -> JSONResponse: - """AJAX: save system_append and tool allow-list for a role. + """AJAX: save system_append, tool allow-list, and inject_datetime flag for a role. - Body: {"role": "coder", "system_append": "...", "tools": ["web_search", ...] | null} + Body: {"role": "coder", "system_append": "...", "tools": [...] | null, "inject_datetime": true} tools=null clears the allow-list (role uses all accessible tools). + inject_datetime=false suppresses the date/time header for pure processing roles. """ username = _get_user(request) if not username: @@ -587,18 +597,19 @@ async def set_role_config(request: Request) -> JSONResponse: except Exception: return JSONResponse({"error": "Invalid JSON"}, status_code=400) - role = body.get("role", "").strip() - system_append = body.get("system_append", "") - tools = body.get("tools") # list[str] or None + role = body.get("role", "").strip() + system_append = body.get("system_append", "") + tools = body.get("tools") # list[str] or None + inject_datetime = body.get("inject_datetime", True) if not role: return JSONResponse({"error": "role is required"}, status_code=400) if tools is not None and not isinstance(tools, list): return JSONResponse({"error": "tools must be a list or null"}, status_code=400) - reg.set_role_config(username, role, system_append, tools) - logger.info("role config saved: %s %s (tools=%s)", username, role, - len(tools) if tools is not None else "all") + reg.set_role_config(username, role, system_append, tools, inject_datetime=bool(inject_datetime)) + logger.info("role config saved: %s %s (tools=%s inject_datetime=%s)", + username, role, len(tools) if tools is not None else "all", inject_datetime) return JSONResponse({"ok": True}) diff --git a/cortex/routers/orchestrator.py b/cortex/routers/orchestrator.py index 87bdedc..0e5d315 100644 --- a/cortex/routers/orchestrator.py +++ b/cortex/routers/orchestrator.py @@ -203,6 +203,7 @@ async def _run_job(job_id: str, req: OrchestrateRequest, user: str) -> None: include_mid=req.include_mid, include_short=req.include_short, role_append=role_cfg.get("system_append", ""), + inject_datetime=role_cfg.get("inject_datetime", True), ) session_id = req.session_id or generate_session_id() diff --git a/cortex/static/local_llm.html b/cortex/static/local_llm.html index 1ff865a..52aa2a9 100644 --- a/cortex/static/local_llm.html +++ b/cortex/static/local_llm.html @@ -627,6 +627,9 @@ if (!panel) return; // Populate textarea panel.querySelector('.rcp-textarea').value = cfg.system_append || ''; + // Inject datetime checkbox (default true if not set) + const dtCb = panel.querySelector('.rcp-datetime-cb'); + if (dtCb) dtCb.checked = cfg.inject_datetime !== false; // Build tool checklist buildToolChecklist(role, cfg.tools || null); panel.classList.add('open'); @@ -665,7 +668,9 @@ const role = btn.dataset.role; const panel = document.getElementById(`rcp-${role}`); const ta = panel.querySelector('.rcp-textarea'); - const checks = [...panel.querySelectorAll('.rcp-check input[type=checkbox]')]; + const dtCb = panel.querySelector('.rcp-datetime-cb'); + const inject_datetime = dtCb ? dtCb.checked : true; + const checks = [...panel.querySelectorAll('.rcp-tools input[type=checkbox]')]; const allChecked = checks.every(c => c.checked); const someChecked = checks.some(c => c.checked); const tools = allChecked ? null : (someChecked ? checks.filter(c => c.checked).map(c => c.value) : []); @@ -675,7 +680,7 @@ const res = await fetch('/api/models/role-config', { method: 'POST', headers: {'Content-Type': 'application/json'}, - body: JSON.stringify({role, system_append: ta.value, tools}), + body: JSON.stringify({role, system_append: ta.value, tools, inject_datetime}), }); const data = await res.json(); if (data.ok) { @@ -683,6 +688,7 @@ if (!ROLE_CONFIG_DATA[role]) ROLE_CONFIG_DATA[role] = {}; ROLE_CONFIG_DATA[role].system_append = ta.value; ROLE_CONFIG_DATA[role].tools = tools; + ROLE_CONFIG_DATA[role].inject_datetime = inject_datetime; showToast(`${role} config saved`); closeRolePanel(role); } else {