fix backup and file limit
frdel committed
Feb 6, 2026 at 14:11 UTC
65607a36fcd460c775f59dfca01adb09d7f9e9cf
7 files changed
+31
-16
python/api/backup_create.py
+1
-1
@@ -17,7 +17,7 @@ class BackupCreate(ApiHandler):
17
# Get input parameters
18
include_patterns = input.get("include_patterns", [])
19
exclude_patterns = input.get("exclude_patterns", [])
20
- include_hidden = input.get("include_hidden", False)
20
+ include_hidden = input.get("include_hidden", True)
21
backup_name = input.get("backup_name", "agent-zero-backup")
22
23
# Support legacy string patterns format for backward compatibility
python/api/backup_inspect.py
+1
-1
@@ -37,7 +37,7 @@ class BackupInspect(ApiHandler):
37
"backup_name": metadata.get("backup_name", ""),
38
"total_files": metadata.get("total_files", len(metadata.get("files", []))),
39
"backup_size": metadata.get("backup_size", 0),
40
- "include_hidden": metadata.get("include_hidden", False),
40
+ "include_hidden": metadata.get("include_hidden", True),
41
"files_in_archive": metadata.get("files_in_archive", []),
42
"checksums": {} # Will be added if needed
43
}
python/api/backup_preview_grouped.py
+1
-1
@@ -17,7 +17,7 @@ class BackupPreviewGrouped(ApiHandler):
17
# Get input parameters
18
include_patterns = input.get("include_patterns", [])
19
exclude_patterns = input.get("exclude_patterns", [])
20
- include_hidden = input.get("include_hidden", False)
20
+ include_hidden = input.get("include_hidden", True)
21
max_depth = input.get("max_depth", 3)
22
search_filter = input.get("search_filter", "")
23
python/api/backup_test.py
+1
-1
@@ -16,7 +16,7 @@ class BackupTest(ApiHandler):
16
# Get input parameters
17
include_patterns = input.get("include_patterns", [])
18
exclude_patterns = input.get("exclude_patterns", [])
19
- include_hidden = input.get("include_hidden", False)
19
+ include_hidden = input.get("include_hidden", True)
20
max_files = input.get("max_files", 1000)
21
22
# Support legacy string patterns format for backward compatibility
python/helpers/backup.py
+6
-6
@@ -43,7 +43,7 @@ class BackupService:
43
44
return {
45
"backup_name": f"agent-zero-backup-{timestamp[:10]}",
46
- "include_hidden": False,
46
+ "include_hidden": True,
47
"include_patterns": include_patterns,
48
"exclude_patterns": exclude_patterns,
49
"backup_config": {
@@ -64,8 +64,8 @@ class BackupService:
64
# All persistent user data is now centralized in /usr for easier backup and restore
65
{agent_root}/usr/**
66
67
-# Explicitly include .env
68
-{agent_root}/usr/.env
67
+# Root folder
68
+/root/**
69
"""
70
71
def _get_agent_zero_version(self) -> str:
@@ -247,7 +247,7 @@ class BackupService:
247
"""Test backup patterns and return list of matched files"""
248
include_patterns = metadata.get("include_patterns", [])
249
exclude_patterns = metadata.get("exclude_patterns", [])
250
- include_hidden = metadata.get("include_hidden", False)
250
+ include_hidden = metadata.get("include_hidden", True)
251
252
# Convert to patterns string for pathspec
253
patterns_string = self._patterns_to_string(include_patterns, exclude_patterns)
@@ -332,7 +332,7 @@ class BackupService:
332
self,
333
include_patterns: List[str],
334
exclude_patterns: List[str],
335
- include_hidden: bool = False,
335
+ include_hidden: bool = True,
336
backup_name: str = "agent-zero-backup"
337
) -> str:
338
"""Create backup archive and return path to created file"""
@@ -807,7 +807,7 @@ class BackupService:
807
# Use user-edited patterns for what to clean
808
user_include_patterns = user_metadata.get("include_patterns", [])
809
user_exclude_patterns = user_metadata.get("exclude_patterns", [])
810
- include_hidden = user_metadata.get("include_hidden", False)
810
+ include_hidden = user_metadata.get("include_hidden", True)
811
812
if not user_include_patterns:
813
return []
run_ui.py
+11
-1
@@ -10,6 +10,7 @@ import threading
10
import uvicorn
11
from flask import Flask, request, Response, session, redirect, url_for, render_template_string
12
from werkzeug.wrappers.response import Response as BaseResponse
13
+from werkzeug.wrappers.request import Request as WerkzeugRequest
14
15
import initialize
16
from python.helpers import files, git, mcp_server, fasta2a_server, settings as settings_helper
@@ -43,12 +44,21 @@ if hasattr(time, 'tzset'):
44
# initialize the internal Flask server
45
webapp = Flask("app", static_folder=get_abs_path("./webui"), static_url_path="/")
46
webapp.secret_key = os.getenv("FLASK_SECRET_KEY") or secrets.token_hex(32)
47
+
48
+UPLOAD_LIMIT_BYTES = 5 * 1024 * 1024 * 1024
49
+
50
+# Werkzeug's default max_form_memory_size is 500_000 bytes which can trigger 413 for multipart requests
51
+# with larger non-file fields. Raise it to match our intended upload limit.
52
+WerkzeugRequest.max_form_memory_size = UPLOAD_LIMIT_BYTES
53
+
54
webapp.config.update(
55
JSON_SORT_KEYS=False,
56
SESSION_COOKIE_NAME="session_" + runtime.get_runtime_id(), # bind the session cookie name to runtime id to prevent session collision on same host
57
SESSION_COOKIE_SAMESITE="Strict",
58
SESSION_PERMANENT=True,
51
- PERMANENT_SESSION_LIFETIME=timedelta(days=1)
59
+ PERMANENT_SESSION_LIFETIME=timedelta(days=1),
60
+ MAX_CONTENT_LENGTH=int(os.getenv("FLASK_MAX_CONTENT_LENGTH", str(UPLOAD_LIMIT_BYTES))),
61
+ MAX_FORM_MEMORY_SIZE=int(os.getenv("FLASK_MAX_FORM_MEMORY_SIZE", str(UPLOAD_LIMIT_BYTES))),
62
)
63
64
lock = threading.RLock()
webui/components/settings/backup/backup-store.js
+10
-5
@@ -114,7 +114,7 @@ const model = {
114
115
return {
116
backup_name: `agent-zero-backup-${timestamp.slice(0, 10)}`,
117
- include_hidden: false,
117
+ include_hidden: true,
118
include_patterns: include_patterns,
119
exclude_patterns: exclude_patterns,
120
backup_config: {
@@ -130,7 +130,7 @@ const model = {
130
// Fallback patterns (will be overridden by backend on first use)
131
return {
132
backup_name: `agent-zero-backup-${timestamp.slice(0, 10)}`,
133
- include_hidden: false,
133
+ include_hidden: true,
134
include_patterns: [
135
// These will be replaced with resolved absolute paths by backend
136
"# Loading default patterns from backend..."
@@ -245,7 +245,7 @@ const model = {
245
// Get grouped preview for better UX
246
const response = await sendJsonData("backup_preview_grouped", {
247
patterns: patternsString,
248
- include_hidden: metadata.include_hidden || false,
248
+ include_hidden: metadata.include_hidden ?? true,
249
max_depth: 3,
250
search_filter: this.fileSearchFilter
251
});
@@ -391,6 +391,7 @@ const model = {
391
392
try {
393
this.loading = true;
394
+ this.loadingMessage = 'Creating backup...';
395
this.error = '';
396
this.clearFileOperations();
397
this.addFileOperation('Starting backup creation...');
@@ -404,7 +405,7 @@ const model = {
405
body: JSON.stringify({
406
include_patterns: metadata.include_patterns,
407
exclude_patterns: metadata.exclude_patterns,
407
- include_hidden: metadata.include_hidden || false,
408
+ include_hidden: metadata.include_hidden ?? true,
409
backup_name: metadata.backup_name
410
})
411
});
@@ -500,6 +501,7 @@ const model = {
501
try {
502
this.loading = true;
503
this.loadingMessage = 'Performing dry run...';
504
+ this.error = '';
505
this.clearFileOperations();
506
this.addFileOperation('Starting backup dry run...');
507
@@ -508,7 +510,7 @@ const model = {
510
511
const response = await sendJsonData("backup_test", {
512
patterns: patternsString,
511
- include_hidden: metadata.include_hidden || false,
513
+ include_hidden: metadata.include_hidden ?? true,
514
max_files: 10000
515
});
516
@@ -540,6 +542,8 @@ const model = {
542
try {
543
this.loading = true;
544
this.loadingMessage = 'Performing restore dry run...';
545
+ this.error = '';
546
+ this.restoreResult = null;
547
this.clearFileOperations();
548
this.addFileOperation('Starting restore dry run...');
549
@@ -692,6 +696,7 @@ const model = {
696
this.loading = true;
697
this.loadingMessage = 'Restoring files...';
698
this.error = '';
699
+ this.restoreResult = null;
700
this.clearFileOperations();
701
this.addFileOperation('Starting file restoration...');
702