ulysses/src
nickorlabs c39d8db12a
fix(agent): make context-budget hard_max configurable via agent_input_token_hard_max setting (#1273)
Completes the reviewer requirement from PR #1190 review that was carried
over but not implemented in #1230:

> "The hard max is a function-local constant. For this setting, the ceiling
>  should be configurable or at least represented as a named setting/default
>  with tests."
                                                                — review on #1190

#1230 shipped the adaptive auto-derivation but left `DEFAULT_HARD_MAX = 200_000`
as a hardcoded module constant in src/context_budget.py. Admins on premium
APIs with large context windows (kimi-k2 / minimax-m3 at 1M, etc.) can use
their full window today only by setting `agent_input_token_budget`
explicitly — which then takes them off the adaptive auto-path entirely.

## What this PR changes

- src/settings.py: register `agent_input_token_hard_max` in
  DEFAULT_SETTINGS, default 200_000 (matches `DEFAULT_HARD_MAX`). Inline
  comment documents the no-op semantics in the explicit branch.

- src/agent_loop.py: read the setting at the call site and pass it as the
  `hard_max` kwarg of `compute_input_token_budget`. Defensive parsing —
  missing / non-int / zero values fall back to `DEFAULT_HARD_MAX`, so a
  misconfig cannot silently zero the budget.

- src/tool_implementations.py: three friendly aliases for `manage_settings`:
  - "hard max" -> agent_input_token_hard_max
  - "token budget cap" -> agent_input_token_hard_max
  - "input budget cap" -> agent_input_token_hard_max
  Plus the existing "token budget" -> agent_input_token_budget keeps a
  matching shorter alias "input budget".

- tests/test_context_budget.py: 6 new tests on top of the existing 6:
  - hard_max raises the auto ceiling (1M ctx + raised cap -> 85% of ctx)
  - hard_max lowers the auto ceiling (128K ctx + 50K cap -> 50K)
  - hard_max has no effect on the explicit branch
  - DEFAULT_SETTINGS contains the new key
  - manage_settings aliases are registered
  - the live get_setting path returns the override value, and malformed
    values fall back per the agent_loop defensive parsing

12 passed in 0.04s. No changes to the pure helper signature or semantics;
#1230's behavior is the default when the new setting is unset.

## How it lets users drop the explicit override

Before this PR, on a 1M-context model:
  agent_input_token_budget = 900_000  (explicit)  -> 900K  [user override]
  agent_input_token_budget = <unset>  (auto)      -> 200K  [HARD_MAX]

After this PR, same model:
  agent_input_token_budget = <unset>
  agent_input_token_hard_max = 900_000
                                      -> min(1M * 0.85, 900K) = 850K  [auto, no override needed]

The explicit-override path keeps working unchanged for users who prefer it.
2026-06-03 01:36:57 +09:00
..
search fix: research query misclassifies 'whatsapp'/'however' as questions (#1247) 2026-06-03 01:10:06 +09:00
action_intents.py Route calendar action requests to tools 2026-06-01 14:32:41 +09:00
agent_loop.py fix(agent): make context-budget hard_max configurable via agent_input_token_hard_max setting (#1273) 2026-06-03 01:36:57 +09:00
agent_runs.py Handle incomplete detached agent streams 2026-06-01 16:54:11 +09:00
agent_tools.py Add SSRF-guarded web fetch agent tool 2026-06-01 16:57:28 +09:00
ai_interaction.py feat(ai): add OpenRouter and Ollama Cloud providers (#231) 2026-06-01 14:26:10 +09:00
api_key_manager.py API keys: skip undecryptable entries on load 2026-06-02 20:28:26 +09:00
app_helpers.py Odysseus v1.0 2026-05-31 23:58:26 +09:00
app_initializer.py Odysseus v1.0 2026-05-31 23:58:26 +09:00
assistant_log.py Odysseus v1.0 2026-05-31 23:58:26 +09:00
auth_helpers.py Attribute API-token sessions to the token owner (effective_user) (#871) 2026-06-02 11:39:01 +09:00
bg_jobs.py chore: use explicit utf-8 for shell job files (#820) 2026-06-02 11:12:13 +09:00
bg_monitor.py Odysseus v1.0 2026-05-31 23:58:26 +09:00
builtin_actions.py Scope memory consolidation by owner group 2026-06-02 12:40:28 +09:00
builtin_mcp.py Add native Windows compatibility layer 2026-06-01 15:09:47 +09:00
caldav_sync.py Fix duplicate CalDAV sync UIDs 2026-06-01 02:17:43 +00:00
chat_handler.py Use LM Studio-reported vision capability for image passthrough (#1130) 2026-06-02 23:01:04 +09:00
chat_helpers.py Use LM Studio-reported vision capability for image passthrough (#1130) 2026-06-02 23:01:04 +09:00
chat_processor.py Odysseus v1.0 2026-05-31 23:58:26 +09:00
chroma_client.py fix: ChromaDB unreachable blocks app startup for 30-60s (#326) (#476) 2026-06-01 22:22:41 +09:00
cleanup_service.py Odysseus v1.0 2026-05-31 23:58:26 +09:00
config.py Add native Windows compatibility layer 2026-06-01 15:09:47 +09:00
constants.py Align SearXNG fallback URL 2026-06-01 10:50:07 +09:00
context_budget.py feat: adapt agent_input_token_budget to the model context window (#1170) (#1230) 2026-06-03 00:13:53 +09:00
context_compactor.py Preserve system messages during context compaction 2026-06-01 23:10:58 +09:00
database.py Odysseus v1.0 2026-05-31 23:58:26 +09:00
deep_research.py Research: report empty search provider results clearly 2026-06-02 20:34:25 +09:00
document_actions.py Odysseus v1.0 2026-05-31 23:58:26 +09:00
document_processor.py Documents: strip PDF marker without corrupting text 2026-06-02 20:35:27 +09:00
email_thread_parser.py Email: recognize forwarded message dividers 2026-06-02 20:32:56 +09:00
embeddings.py Add native Windows compatibility layer 2026-06-01 15:09:47 +09:00
endpoint_resolver.py Background tasks: respect active session model fallback 2026-06-02 20:57:42 +09:00
event_bus.py Odysseus v1.0 2026-05-31 23:58:26 +09:00
exceptions.py Odysseus v1.0 2026-05-31 23:58:26 +09:00
goal_based_extractor.py Odysseus v1.0 2026-05-31 23:58:26 +09:00
integrations.py Secure by default uplift (#511) 2026-06-01 22:30:07 +09:00
llm_core.py fix: merging consecutive user messages corrupts multimodal (image) content (#1277) 2026-06-03 01:21:57 +09:00
markitdown_runtime.py Add optional markitdown extraction for Office/EPUB documents (#766) 2026-06-02 11:28:52 +09:00
mcp_manager.py fix(mcp): invalidate tool prompt cache on connect/disconnect/error (#1235) 2026-06-03 00:49:29 +09:00
memory.py Fix AttributeError on bullet lines in extract_memory_from_chat (#873) 2026-06-02 11:46:06 +09:00
memory_vector.py Odysseus v1.0 2026-05-31 23:58:26 +09:00
model_context.py Models: prefer longest known context match 2026-06-02 20:33:09 +09:00
model_discovery.py Discover LM Studio via host/port scanning and native-API fingerprint (#1126) 2026-06-02 23:04:58 +09:00
pdf_form_doc.py Harden PDF document markers against cross-owner upload access (#445) 2026-06-01 22:38:14 +09:00
pdf_forms.py Odysseus v1.0 2026-05-31 23:58:26 +09:00
pdf_runtime.py Show a clear message when PyMuPDF is missing 2026-06-01 18:27:17 +09:00
personal_docs.py Docs: respect path boundary when clearing exclusions 2026-06-02 20:35:44 +09:00
preset_manager.py Presets: fill missing built-in defaults on load 2026-06-02 20:32:08 +09:00
prompt_security.py Odysseus v1.0 2026-05-31 23:58:26 +09:00
rag_manager.py Odysseus v1.0 2026-05-31 23:58:26 +09:00
rag_singleton.py Re-enable VectorRAG init with lazy retry 2026-06-01 14:32:13 +09:00
rag_vector.py fix(rag): use a stable hash for document IDs so dedup survives restarts (#1098) 2026-06-02 22:42:23 +09:00
rate_limiter.py Odysseus v1.0 2026-05-31 23:58:26 +09:00
readiness.py feat: add /api/ready readiness probe (DB, data dir, local-first) (#1200) 2026-06-02 23:33:22 +09:00
request_models.py Odysseus v1.0 2026-05-31 23:58:26 +09:00
research_handler.py Surface deep research probe errors (#1086) 2026-06-02 22:51:25 +09:00
research_utils.py fix: deep research discards valid sources mentioning cookies/copyright (#481) 2026-06-01 22:26:37 +09:00
secret_storage.py Add native Windows compatibility layer 2026-06-01 15:09:47 +09:00
session_actions.py Odysseus v1.0 2026-05-31 23:58:26 +09:00
settings.py fix(agent): make context-budget hard_max configurable via agent_input_token_hard_max setting (#1273) 2026-06-03 01:36:57 +09:00
settings_scrub.py Deep-scrub secrets from public settings 2026-06-01 23:11:50 +09:00
task_endpoint.py Odysseus v1.0 2026-05-31 23:58:26 +09:00
task_scheduler.py fix: calendar check-in digest drops events 7-8 days out (#1249) 2026-06-03 01:03:58 +09:00
teacher_escalation.py Treat Venice as a tool-capable SOTA cloud provider (#1173) 2026-06-02 23:03:46 +09:00
text_helpers.py Text: strip dangling think blocks after visible text 2026-06-02 20:36:37 +09:00
tool_execution.py fix(tools): strict path confinement with sensitive-subpath deny list (#1072) 2026-06-02 23:13:30 +09:00
tool_implementations.py fix(agent): make context-budget hard_max configurable via agent_input_token_hard_max setting (#1273) 2026-06-03 01:36:57 +09:00
tool_index.py Polish email and cookbook flows 2026-06-02 22:42:07 +09:00
tool_parsing.py fix(agent): map native google_search and surface empty rounds 2026-06-02 12:57:45 +09:00
tool_schemas.py Polish email and cookbook flows 2026-06-02 22:42:07 +09:00
tool_security.py Tools: restrict app_api and serve_preset to admins 2026-06-02 20:29:47 +09:00
topic_analyzer.py Topics: hydrate session history before analysis 2026-06-02 20:44:27 +09:00
upload_handler.py fix: uploaded files with no extension become permanently unresolvable (#1275) 2026-06-03 01:16:30 +09:00
url_safety.py fix: SSRF hardening for the custom embedding endpoint URL (#132) (#1206) 2026-06-02 23:46:33 +09:00
visual_report.py Fix visual report chapter navigation (#505) 2026-06-01 22:26:13 +09:00
webhook_manager.py Webhook: block IPv6 SSRF bypasses 2026-06-02 20:28:12 +09:00
youtube_handler.py YouTube: enforce comment fetch timeout while waiting 2026-06-02 20:44:24 +09:00