sensitive settings store/load, short guids in scheduler and vdb

frdel committed Jan 2, 2026 at 11:28 UTC ed0964a857b9aa4a3e6fe14461e7c4767f00fc9c
4 files changed +16 -25
agent.py
-1
@@ -8,7 +8,6 @@ from dataclasses import dataclass, field
8 from datetime import datetime, timezone
9 from typing import Any, Awaitable, Coroutine, Dict, Literal
10 from enum import Enum
11 -import uuid
11 import models
12
13 from python.helpers import (
python/helpers/settings.py
+12 -20
@@ -264,6 +264,13 @@ def convert_out(settings: Settings) -> SettingsOutput:
264 additional["knowledge_subdirs"] = _ensure_option_present(additional.get("knowledge_subdirs"), current.get("agent_knowledge_subdir"))
265 additional["stt_models"] = _ensure_option_present(additional.get("stt_models"), current.get("stt_model_size"))
266
267 + # masked api keys
268 + providers = get_providers("chat") + get_providers("embedding")
269 + for provider in providers:
270 + provider_name = provider["value"]
271 + api_key = settings["api_keys"].get(provider_name, models.get_api_key(provider_name))
272 + settings["api_keys"][provider_name] = API_KEY_PLACEHOLDER if api_key and api_key != "None" else ""
273 +
274 # load auth from dotenv
275 out["settings"]["auth_login"] = dotenv.get_dotenv_value(dotenv.KEY_AUTH_LOGIN) or ""
276 out["settings"]["auth_password"] = (
@@ -311,21 +318,7 @@ def _get_api_key_field(settings: Settings, provider: str, title: str) -> Setting
318 def convert_in(settings: Settings) -> Settings:
319 current = get_settings()
320
314 - # api keys
315 - if "api_keys" in settings and isinstance(settings["api_keys"], dict):
316 - for provider, value in settings["api_keys"].items():
317 - if value != API_KEY_PLACEHOLDER:
318 - current["api_keys"][provider] = value
319 -
320 - # all other fields
321 for key, value in settings.items():
322 - if key == "api_keys":
323 - continue
324 -
325 - # Skip saving if value is a placeholder
326 - if value == PASSWORD_PLACEHOLDER or value == API_KEY_PLACEHOLDER:
327 - continue
328 -
322 # Special handling for browser_http_headers and *_kwargs (stored as .env text)
323 if (key == "browser_http_headers" or key.endswith("_kwargs")) and isinstance(value, str):
324 current[key] = _env_to_dict(value)
@@ -436,17 +429,16 @@ def _remove_sensitive_settings(settings: Settings):
429
430 def _write_sensitive_settings(settings: Settings):
431 for key, val in settings["api_keys"].items():
439 - dotenv.save_dotenv_value(key.upper(), val)
432 + if val != API_KEY_PLACEHOLDER:
433 + dotenv.save_dotenv_value(key.upper(), val)
434
435 dotenv.save_dotenv_value(dotenv.KEY_AUTH_LOGIN, settings["auth_login"])
442 - if settings["auth_password"]:
436 + if settings["auth_password"] != PASSWORD_PLACEHOLDER:
437 dotenv.save_dotenv_value(dotenv.KEY_AUTH_PASSWORD, settings["auth_password"])
444 - if settings["rfc_password"]:
438 + if settings["rfc_password"] != PASSWORD_PLACEHOLDER:
439 dotenv.save_dotenv_value(dotenv.KEY_RFC_PASSWORD, settings["rfc_password"])
446 -
447 - if settings["root_password"]:
440 + if settings["root_password"] != PASSWORD_PLACEHOLDER:
441 dotenv.save_dotenv_value(dotenv.KEY_ROOT_PASSWORD, settings["root_password"])
449 - if settings["root_password"]:
442 set_root_password(settings["root_password"])
443
444 # Handle secrets separately - merge with existing preserving comments/order and support deletions
python/helpers/task_scheduler.py
+2 -2
@@ -22,7 +22,7 @@ from python.helpers.print_style import PrintStyle
22 from python.helpers.defer import DeferredTask
23 from python.helpers.files import get_abs_path, make_dirs, read_file, write_file
24 from python.helpers.localization import Localization
25 -from python.helpers import projects
25 +from python.helpers import projects, guids
26 import pytz
27 from typing import Annotated
28
@@ -118,7 +118,7 @@ class TaskPlan(BaseModel):
118
119
120 class BaseTask(BaseModel):
121 - uuid: str = Field(default_factory=lambda: str(uuid.uuid4()))
121 + uuid: str = Field(default_factory=lambda: guids.generate_id())
122 context_id: Optional[str] = Field(default=None)
123 state: TaskState = Field(default=TaskState.IDLE)
124 name: str = Field()
python/helpers/vector_db.py
+2 -2
@@ -1,5 +1,4 @@
1 from typing import Any, List, Sequence
2 -import uuid
2 from langchain_community.vectorstores import FAISS
3
4 # faiss needs to be patched for python 3.12 on arm #TODO remove once not needed
@@ -17,6 +16,7 @@ from langchain.embeddings import CacheBackedEmbeddings
16 from simpleeval import simple_eval
17
18 from agent import Agent
19 +from python.helpers import guids
20
21
22 class MyFaiss(FAISS):
@@ -99,7 +99,7 @@ class VectorDB:
99 return result
100
101 async def insert_documents(self, docs: list[Document]):
102 - ids = [str(uuid.uuid4()) for _ in range(len(docs))]
102 + ids = [guids.generate_id() for _ in range(len(docs))]
103
104 if ids:
105 for doc, id in zip(docs, ids):