mirror of
https://github.com/agent0ai/agent-zero.git
synced 2026-08-22 06:45:03 +00:00
Project updates and deletion previously persisted every loaded chat, while matching chats were written twice through the existing activation helpers. Keep the established project lifecycle flow and remove the unconditional writes so only affected chats are saved once. Add focused regression coverage and document the persistence contract.
8.8 KiB
8.8 KiB
projects.py DOX
Purpose
- Own the
projects.pyhelper module. - This module owns project metadata, workspace creation, Git status, and project-scoped settings including per-project MCP server config.
- Keep this file-level DOX profile synchronized with
projects.pybecause this directory is intentionally flat.
Ownership
projects.pyowns the runtime implementation.projects.py.dox.mdowns durable notes about responsibilities, contracts, side effects, and verification for that implementation.- Classes:
FileStructureInjectionSettings(TypedDict)SubAgentSettings(TypedDict)BasicProjectData(TypedDict)GitStatusData(TypedDict)EditProjectData(BasicProjectData)- Top-level functions:
get_projects_parent_folder()get_project_folder(name: str)get_project_meta(name: str, *sub_dirs)validate_project_name(name: str | None) -> strdelete_project(name: str)create_project(name: str, data: BasicProjectData)clone_git_project(name: str, git_url: str, git_token: str, data: BasicProjectData): Clone a git repository as a new A0 project. Token is used only for cloning via http header.load_project_header(name: str)_default_file_structure_settings()_normalizeBasicData(data: BasicProjectData) -> BasicProjectData_normalizeEditData(data: EditProjectData) -> EditProjectData_edit_data_to_basic_data(data: EditProjectData)_basic_data_to_edit_data(data: BasicProjectData) -> EditProjectDataupdate_project(name: str, data: EditProjectData)load_basic_project_data(name: str) -> BasicProjectDataload_edit_project_data(name: str) -> EditProjectDatasave_project_header(name: str, data: BasicProjectData)load_project_extended_data(name: str) -> ProjectExtendedDatasave_project_extended_data(name: str, project_data: ProjectExtendedData)_project_extended_data_for_save(data: object) -> ProjectExtendedData_merge_project_extended_data(data: EditProjectData, extended_data: object) -> Noneload_project_mcp_servers(name: str) -> strsave_project_mcp_servers(name: str, mcp_servers: str)get_active_projects_list()_get_projects_list(parent_dir)reconcile_agent_profile(context: AgentContext, project_name: str | None) -> boolreconcile_agent_profiles(project_name: str | None, *, all_scopes: bool=...) -> Noneactivate_project(context_id: str, name: str, mark_dirty: bool=...)deactivate_project(context_id: str, mark_dirty: bool=...)reactivate_project_in_chats(name: str)deactivate_project_in_chats(name: str)build_system_prompt_vars(name: str)get_agents_md_chain(root: str, target: str) -> list[tuple[str, str]]build_agents_md_protocol(name: str, target: str | None=...) -> strget_additional_instructions_files(name: str)get_project_instruction_files(name: str, include_agents_md: bool=...) -> list[tuple[str, str]]get_project_agents_md_instruction_file(name: str) -> tuple[str, str] | None_format_project_instruction_files(instruction_files: list[tuple[str, str]]) -> str_normalize_include_agents_md(value: object) -> boolload_project_subagents(name: str) -> dict[str, SubAgentSettings]save_project_subagents(name: str, subagents_data: dict[str, SubAgentSettings])set_project_subagent_enabled(name: str, profile_id: str, enabled: bool) -> None_normalize_subagents(subagents_data: dict[str, SubAgentSettings], project_name: str=...) -> dict[str, SubAgentSettings]- Notable constants/configuration names:
PROJECTS_PARENT_DIR,PROJECT_META_DIR,PROJECT_INSTRUCTIONS_DIR,PROJECT_KNOWLEDGE_DIR,PROJECT_SKILLS_DIR,PROJECT_HEADER_FILE,PROJECT_MCP_SERVERS_FILE,PROJECT_AGENTS_MD_FILES,DEFAULT_MCP_SERVERS_CONFIG,CONTEXT_DATA_KEY_PROJECT.
Runtime Contracts
- Helper modules own reusable framework APIs and must preserve public callers unless all callers, tests, and docs are updated together.
- Update this file whenever public functions, classes, persistence behavior, path/security assumptions, side effects, or cross-module contracts change.
- Per-project MCP server configuration is persisted as
.a0proj/mcp_servers.json, exposed throughload_edit_project_data(...), and saved during project create/clone/update flows. - Additional project-edit payload sections are delegated through extensible
load_project_extended_data(...)andsave_project_extended_data(...); the project helper must stay storage-agnostic and plugin-specific config rules belong to the owning plugin. - Project extension data may add named top-level sections such as
llm, but it must not overwrite core project fields owned byEditProjectData. - Project extension save payloads exclude core project fields and transient inputs such as
git_token; plugins needing core metadata should load it by project name. - Project metadata setup creates and repairs
.a0proj/instructions,.a0proj/knowledge, and.a0proj/skillsso settings surfaces can open those folders consistently. - AGENTS.md discovery is a linear root-to-target chain walk with
AGENTS.override.mdprecedence; sibling directories are not scanned. - Active-project AGENTS.md protocol guidance excludes the exact project root AGENTS.md because
build_system_prompt_vars(...)already loads it into project instructions; prose for that protocol block lives inprompts/agent.protocol.projects.agents_md.md. - Project MCP config uses the same JSON string shape as global MCP settings: an object with
mcpServers. - Project MCP load/save paths validate project names as simple folder basenames before touching
.a0proj/mcp_servers.json. - Activating or deactivating a project preserves the active chat profile when it
is available in the destination scope; otherwise it replaces it with the
configured default profile, then
agent0, then the first available profile. - Per-project profile availability is persisted sparsely in
.a0proj/agents.json; entries matching the profile definition's scoped default are omitted. The helper retains the established tolerant load contract for read-only settings. Profile-scoped mutations re-read the file strictly, preserve unrelated entries, refuse malformed data, and write throughhelpers.files. General project edit payloads neither expose nor mutate profile availability; legacysubagentsinput is ignored. - Profile reconciliation treats
Noneas the Global scope. Callers must passall_scopes=Trueto check every loaded chat after a Global availability change. Each pass resolves the available profile catalog once per encountered scope; only chats whose active profile actually changes are persisted and marked dirty. Context creation uses the same reconciliation after resolving its scope, so a disabled configured profile cannot become invisibly active. - Project updates and deletion refresh only chats assigned to that project and persist each affected chat once; unrelated chats are never rewritten.
- Observed side-effect areas: filesystem reads, filesystem writes, filesystem deletion, plugin state, settings/state persistence, secret handling.
- Imported dependency areas include:
helpers,helpers.print_style,os,typing.
Key Concepts
- Important called helpers/classes observed in the source:
files.get_abs_path,files.delete_dir,deactivate_project_in_chats,files.create_dir_safe,create_project_meta_folders,_normalizeBasicData,save_project_header,save_project_mcp_servers,load_project_mcp_servers,save_project_extended_data,load_project_extended_data,_project_extended_data_for_save,_merge_project_extended_data,_PROJECT_CORE_EDIT_KEYS,_PROJECT_TRANSIENT_INPUT_KEYS,extension.extensible,files.basename,dirty_json.parse,FileStructureInjectionSettings,cast,_normalizeEditData,load_edit_project_data,_edit_data_to_basic_data,save_project_variables,save_project_secrets,save_project_subagents,reactivate_project_in_chats,load_basic_project_data. - Keep request/response, tool, or helper semantics documented here at the same time as source changes.
Work Guidance
- Preserve public helper APIs used by core code and plugins unless every caller is updated.
- Keep path, auth, secret, persistence, network, and subprocess behavior explicit and bounded.
- Prefer adding cohesive helper functions here only when behavior is reused across modules.
Verification
- Run targeted tests for changed helper behavior; run security regressions for auth, filesystem, WebSocket, tunnel, upload, or secret-handling helpers.
- Related tests observed by source search:
tests/test_model_config_project_presets.pytests/test_office_document_store.pytests/test_plugin_activation_ui.pytests/test_projects.pytests/test_skills_runtime.pytests/test_task_scheduler_timezone.pytests/test_time_travel.pytests/test_tool_action_contracts.py
Child DOX Index
No child DOX files.