10xscale-agentflow-cli 0.2.8__tar.gz → 0.2.9__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/10xscale_agentflow_cli.egg-info/PKG-INFO +1 -1
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/PKG-INFO +1 -1
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow.json +2 -1
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/core/middleware/request_limits.py +1 -2
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/loader.py +36 -1
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/routers/checkpointer/router.py +45 -3
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/routers/checkpointer/services/checkpointer_service.py +2 -1
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/routers/graph/schemas/graph_schemas.py +29 -3
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/routers/graph/services/graph_service.py +20 -4
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/routers/store/router.py +12 -1
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/routers/store/services/store_service.py +2 -1
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/pyproject.toml +1 -1
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/10xscale_agentflow_cli.egg-info/SOURCES.txt +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/10xscale_agentflow_cli.egg-info/dependency_links.txt +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/10xscale_agentflow_cli.egg-info/entry_points.txt +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/10xscale_agentflow_cli.egg-info/not-zip-safe +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/10xscale_agentflow_cli.egg-info/requires.txt +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/10xscale_agentflow_cli.egg-info/top_level.txt +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/ActionPlan.md +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/MANIFEST.in +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/README.md +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/__init__.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/cli/__init__.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/cli/commands/__init__.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/cli/commands/api.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/cli/commands/build.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/cli/commands/init.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/cli/commands/version.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/cli/constants.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/cli/core/__init__.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/cli/core/config.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/cli/core/output.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/cli/core/validation.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/cli/exceptions.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/cli/logger.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/cli/main.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/cli/templates/__init__.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/cli/templates/defaults.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/__init__.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/__init__.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/core/__init__.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/core/auth/__init__.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/core/auth/auth_backend.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/core/auth/authorization.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/core/auth/base_auth.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/core/auth/jwt_auth.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/core/auth/permissions.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/core/config/__init__.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/core/config/graph_config.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/core/config/sentry_config.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/core/config/settings.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/core/config/setup_logs.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/core/config/setup_middleware.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/core/config/worker_middleware.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/core/exceptions/__init__.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/core/exceptions/general_exception.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/core/exceptions/handle_errors.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/core/exceptions/resources_exceptions.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/core/exceptions/user_exception.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/core/middleware/__init__.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/core/middleware/security_headers.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/core/utils/__init__.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/core/utils/log_sanitizer.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/main.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/routers/__init__.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/routers/a2a.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/routers/a2ui.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/routers/checkpointer/__init__.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/routers/checkpointer/schemas/__init__.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/routers/checkpointer/schemas/checkpointer_schemas.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/routers/checkpointer/services/__init__.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/routers/graph/__init__.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/routers/graph/router.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/routers/graph/schemas/__init__.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/routers/graph/services/__init__.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/routers/ping/__init__.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/routers/ping/router.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/routers/setup_router.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/routers/store/__init__.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/routers/store/schemas/__init__.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/routers/store/schemas/store_schemas.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/routers/store/services/__init__.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/tasks/__init__.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/tasks/user_tasks.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/utils/__init__.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/utils/callable_helper.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/utils/parse_output.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/utils/response_helper.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/utils/schemas/__init__.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/utils/schemas/output_schemas.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/utils/schemas/user_schemas.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/utils/snowflake_id_generator.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/utils/swagger_helper.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/utils/thread_name_generator.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/worker.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/graph/__init__.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/graph/react.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/graph/thread_name_generator.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/plan.md +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/scripts/generate_docs.py +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/setup.cfg +0 -0
- {10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/tests/test_utils_parse_and_callable.py +0 -0
|
@@ -56,8 +56,7 @@ class RequestSizeLimitMiddleware(BaseHTTPMiddleware):
|
|
|
56
56
|
"error": {
|
|
57
57
|
"code": "REQUEST_TOO_LARGE",
|
|
58
58
|
"message": (
|
|
59
|
-
f"Request body too large. "
|
|
60
|
-
f"Maximum size is {self.max_size_mb:.1f}MB"
|
|
59
|
+
f"Request body too large. Maximum size is {self.max_size_mb:.1f}MB"
|
|
61
60
|
),
|
|
62
61
|
"max_size_bytes": self.max_size,
|
|
63
62
|
"max_size_mb": self.max_size_mb,
|
{10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/loader.py
RENAMED
|
@@ -22,6 +22,9 @@ logger = logging.getLogger("agentflow-cli.loader")
|
|
|
22
22
|
|
|
23
23
|
|
|
24
24
|
async def load_graph(path: str) -> CompiledGraph | None:
|
|
25
|
+
if ":" not in path:
|
|
26
|
+
raise ValueError(f"Invalid graph path format '{path}'. Expected 'module:attribute'.")
|
|
27
|
+
|
|
25
28
|
module_name_importable, function_name = path.split(":")
|
|
26
29
|
|
|
27
30
|
try:
|
|
@@ -44,6 +47,12 @@ async def load_graph(path: str) -> CompiledGraph | None:
|
|
|
44
47
|
else:
|
|
45
48
|
raise TypeError("Loaded object is not a CompiledGraph.")
|
|
46
49
|
|
|
50
|
+
except ModuleNotFoundError as e:
|
|
51
|
+
logger.error(f"Module not found when loading graph from {path}: {e}")
|
|
52
|
+
raise ModuleNotFoundError(f"Module not found for graph path '{path}': {e}")
|
|
53
|
+
except AttributeError as e:
|
|
54
|
+
logger.error(f"Attribute not found when loading graph from {path}: {e}")
|
|
55
|
+
raise AttributeError(f"Attribute not found for graph path '{path}': {e}")
|
|
47
56
|
except Exception as e:
|
|
48
57
|
logger.error(f"Error loading graph from {path}: {e}")
|
|
49
58
|
raise Exception(f"Failed to load graph from {path}: {e}")
|
|
@@ -55,6 +64,9 @@ def load_checkpointer(path: str | None) -> BaseCheckpointer | None:
|
|
|
55
64
|
if not path:
|
|
56
65
|
return None
|
|
57
66
|
|
|
67
|
+
if ":" not in path:
|
|
68
|
+
raise ValueError(f"Invalid checkpointer path format '{path}'. Expected 'module:attribute'.")
|
|
69
|
+
|
|
58
70
|
module_name_importable, function_name = path.split(":")
|
|
59
71
|
|
|
60
72
|
try:
|
|
@@ -69,6 +81,12 @@ def load_checkpointer(path: str | None) -> BaseCheckpointer | None:
|
|
|
69
81
|
logger.info(f"Successfully loaded BaseCheckpointer '{function_name}' from {path}.")
|
|
70
82
|
else:
|
|
71
83
|
raise TypeError("Loaded object is not a BaseCheckpointer.")
|
|
84
|
+
except ModuleNotFoundError as e:
|
|
85
|
+
logger.error(f"Module not found when loading BaseCheckpointer from {path}: {e}")
|
|
86
|
+
raise ModuleNotFoundError(f"Module not found for checkpointer path '{path}': {e}")
|
|
87
|
+
except AttributeError as e:
|
|
88
|
+
logger.error(f"Attribute not found when loading BaseCheckpointer from {path}: {e}")
|
|
89
|
+
raise AttributeError(f"Attribute not found for checkpointer path '{path}': {e}")
|
|
72
90
|
except Exception as e:
|
|
73
91
|
logger.error(f"Error loading BaseCheckpointer from {path}: {e}")
|
|
74
92
|
raise Exception(f"Failed to load BaseCheckpointer from {path}: {e}")
|
|
@@ -80,6 +98,9 @@ def load_store(path: str | None) -> BaseStore | None:
|
|
|
80
98
|
if not path:
|
|
81
99
|
return None
|
|
82
100
|
|
|
101
|
+
if ":" not in path:
|
|
102
|
+
raise ValueError(f"Invalid store path format '{path}'. Expected 'module:attribute'.")
|
|
103
|
+
|
|
83
104
|
module_name_importable, function_name = path.split(":")
|
|
84
105
|
|
|
85
106
|
try:
|
|
@@ -94,6 +115,12 @@ def load_store(path: str | None) -> BaseStore | None:
|
|
|
94
115
|
logger.info(f"Successfully loaded graph '{function_name}' from {path}.")
|
|
95
116
|
else:
|
|
96
117
|
raise TypeError("Loaded object is not a BaseStore.")
|
|
118
|
+
except ModuleNotFoundError as e:
|
|
119
|
+
logger.error(f"Module not found when loading BaseStore from {path}: {e}")
|
|
120
|
+
raise ModuleNotFoundError(f"Module not found for store path '{path}': {e}")
|
|
121
|
+
except AttributeError as e:
|
|
122
|
+
logger.error(f"Attribute not found when loading BaseStore from {path}: {e}")
|
|
123
|
+
raise AttributeError(f"Attribute not found for store path '{path}': {e}")
|
|
97
124
|
except Exception as e:
|
|
98
125
|
logger.error(f"Error loading BaseStore from {path}: {e}")
|
|
99
126
|
raise Exception(f"Failed to load BaseStore from {path}: {e}")
|
|
@@ -134,13 +161,15 @@ def load_auth(path: str | None) -> BaseAuth | None:
|
|
|
134
161
|
if not path:
|
|
135
162
|
return None
|
|
136
163
|
|
|
164
|
+
if ":" not in path:
|
|
165
|
+
raise ValueError(f"Invalid auth path format '{path}'. Expected 'module:attribute'.")
|
|
166
|
+
|
|
137
167
|
module_name_importable, function_name = path.split(":")
|
|
138
168
|
|
|
139
169
|
try:
|
|
140
170
|
module = importlib.import_module(module_name_importable)
|
|
141
171
|
entry_point_obj = getattr(module, function_name)
|
|
142
172
|
|
|
143
|
-
# If it's a class, instantiate it; if it's an instance, use as is
|
|
144
173
|
if inspect.isclass(entry_point_obj) and issubclass(entry_point_obj, BaseAuth):
|
|
145
174
|
auth = entry_point_obj()
|
|
146
175
|
elif isinstance(entry_point_obj, BaseAuth):
|
|
@@ -149,6 +178,12 @@ def load_auth(path: str | None) -> BaseAuth | None:
|
|
|
149
178
|
raise TypeError("Loaded object is not a subclass or instance of BaseAuth.")
|
|
150
179
|
|
|
151
180
|
logger.info(f"Successfully loaded BaseAuth '{function_name}' from {path}.")
|
|
181
|
+
except ModuleNotFoundError as e:
|
|
182
|
+
logger.error(f"Module not found when loading BaseAuth from {path}: {e}")
|
|
183
|
+
raise ModuleNotFoundError(f"Module not found for auth path '{path}': {e}")
|
|
184
|
+
except AttributeError as e:
|
|
185
|
+
logger.error(f"Attribute not found when loading BaseAuth from {path}: {e}")
|
|
186
|
+
raise AttributeError(f"Attribute not found for auth path '{path}': {e}")
|
|
152
187
|
except Exception as e:
|
|
153
188
|
logger.error(f"Error loading BaseAuth from {path}: {e}")
|
|
154
189
|
raise Exception(f"Failed to load BaseAuth from {path}: {e}")
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
from typing import Any
|
|
4
4
|
|
|
5
5
|
from agentflow.state import Message
|
|
6
|
-
from fastapi import APIRouter, Depends, Request, status
|
|
6
|
+
from fastapi import APIRouter, Depends, HTTPException, Request, status
|
|
7
7
|
from injectq.integrations import InjectAPI
|
|
8
8
|
|
|
9
9
|
from agentflow_cli.src.app.core.auth.permissions import RequirePermission
|
|
@@ -26,6 +26,26 @@ from .services.checkpointer_service import CheckpointerService
|
|
|
26
26
|
router = APIRouter(tags=["checkpointer"])
|
|
27
27
|
|
|
28
28
|
|
|
29
|
+
def validate_thread_id(thread_id: int | str) -> None:
|
|
30
|
+
if isinstance(thread_id, str):
|
|
31
|
+
if not thread_id.strip():
|
|
32
|
+
raise HTTPException(
|
|
33
|
+
status_code=422,
|
|
34
|
+
detail="thread_id cannot be empty or whitespace"
|
|
35
|
+
)
|
|
36
|
+
elif isinstance(thread_id, int):
|
|
37
|
+
if thread_id < 1:
|
|
38
|
+
raise HTTPException(
|
|
39
|
+
status_code=422,
|
|
40
|
+
detail="thread_id must be a non-negative integer"
|
|
41
|
+
)
|
|
42
|
+
else:
|
|
43
|
+
raise HTTPException(
|
|
44
|
+
status_code=422,
|
|
45
|
+
detail="thread_id must be a string or integer"
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
|
|
29
49
|
@router.get(
|
|
30
50
|
"/v1/threads/{thread_id}/state",
|
|
31
51
|
status_code=status.HTTP_200_OK,
|
|
@@ -48,6 +68,8 @@ async def get_state(
|
|
|
48
68
|
Returns:
|
|
49
69
|
State response with state data or error
|
|
50
70
|
"""
|
|
71
|
+
validate_thread_id(thread_id)
|
|
72
|
+
|
|
51
73
|
config = {"thread_id": thread_id}
|
|
52
74
|
|
|
53
75
|
result = await service.get_state(
|
|
@@ -86,11 +108,11 @@ async def put_state(
|
|
|
86
108
|
Returns:
|
|
87
109
|
Success response or error
|
|
88
110
|
"""
|
|
111
|
+
validate_thread_id(thread_id)
|
|
89
112
|
config = {"thread_id": thread_id}
|
|
90
113
|
if payload.config:
|
|
91
114
|
config.update(payload.config)
|
|
92
115
|
|
|
93
|
-
# State is provided as dict; service will handle merging/reconstruction
|
|
94
116
|
res = await service.put_state(
|
|
95
117
|
config,
|
|
96
118
|
user,
|
|
@@ -127,6 +149,7 @@ async def clear_state(
|
|
|
127
149
|
Returns:
|
|
128
150
|
Success response or error
|
|
129
151
|
"""
|
|
152
|
+
validate_thread_id(thread_id)
|
|
130
153
|
config = {"thread_id": thread_id}
|
|
131
154
|
|
|
132
155
|
res = await service.clear_state(
|
|
@@ -168,7 +191,10 @@ async def put_messages(
|
|
|
168
191
|
Returns:
|
|
169
192
|
Success response or error
|
|
170
193
|
"""
|
|
171
|
-
|
|
194
|
+
validate_thread_id(thread_id)
|
|
195
|
+
if not payload.messages:
|
|
196
|
+
raise HTTPException(status_code=422, detail="messages must not be empty")
|
|
197
|
+
|
|
172
198
|
config = {"thread_id": thread_id}
|
|
173
199
|
if payload.config:
|
|
174
200
|
config.update(payload.config)
|
|
@@ -213,6 +239,10 @@ async def get_message(
|
|
|
213
239
|
Returns:
|
|
214
240
|
Message response with message data or error
|
|
215
241
|
"""
|
|
242
|
+
validate_thread_id(thread_id)
|
|
243
|
+
if not message_id or (isinstance(message_id, str) and not str(message_id).strip()):
|
|
244
|
+
raise HTTPException(status_code=422, detail="message_id is required and cannot be empty")
|
|
245
|
+
|
|
216
246
|
config = {"thread_id": thread_id}
|
|
217
247
|
|
|
218
248
|
result = await service.get_message(
|
|
@@ -255,6 +285,12 @@ async def list_messages(
|
|
|
255
285
|
Returns:
|
|
256
286
|
Messages list response with messages data or error
|
|
257
287
|
"""
|
|
288
|
+
validate_thread_id(thread_id)
|
|
289
|
+
if offset is not None and offset < 0:
|
|
290
|
+
raise HTTPException(status_code=422, detail="offset must be >= 0")
|
|
291
|
+
if limit is not None and limit <= 0:
|
|
292
|
+
raise HTTPException(status_code=422, detail="limit must be > 0")
|
|
293
|
+
|
|
258
294
|
config = {"thread_id": thread_id}
|
|
259
295
|
|
|
260
296
|
result = await service.get_messages(
|
|
@@ -297,6 +333,10 @@ async def delete_message(
|
|
|
297
333
|
Returns:
|
|
298
334
|
Success response or error
|
|
299
335
|
"""
|
|
336
|
+
validate_thread_id(thread_id)
|
|
337
|
+
if not message_id or (isinstance(message_id, str) and not str(message_id).strip()):
|
|
338
|
+
raise HTTPException(status_code=422, detail="message_id is required and cannot be empty")
|
|
339
|
+
|
|
300
340
|
config = {"thread_id": thread_id}
|
|
301
341
|
if payload.config:
|
|
302
342
|
config.update(payload.config)
|
|
@@ -340,6 +380,7 @@ async def get_thread(
|
|
|
340
380
|
Returns:
|
|
341
381
|
Thread response with thread data or error
|
|
342
382
|
"""
|
|
383
|
+
validate_thread_id(thread_id)
|
|
343
384
|
result = await service.get_thread(
|
|
344
385
|
{"thread_id": thread_id},
|
|
345
386
|
user,
|
|
@@ -415,6 +456,7 @@ async def delete_thread(
|
|
|
415
456
|
Returns:
|
|
416
457
|
Success response or error
|
|
417
458
|
"""
|
|
459
|
+
validate_thread_id(thread_id)
|
|
418
460
|
config = {"thread_id": thread_id}
|
|
419
461
|
if payload.config:
|
|
420
462
|
config.update(payload.config)
|
|
@@ -2,6 +2,7 @@ from typing import Any
|
|
|
2
2
|
|
|
3
3
|
from agentflow.checkpointer import BaseCheckpointer
|
|
4
4
|
from agentflow.state import AgentState, Message
|
|
5
|
+
from fastapi import HTTPException
|
|
5
6
|
from injectq import inject, singleton
|
|
6
7
|
|
|
7
8
|
from agentflow_cli.src.app.core import logger
|
|
@@ -26,7 +27,7 @@ class CheckpointerService:
|
|
|
26
27
|
|
|
27
28
|
def _config(self, config: dict[str, Any] | None, user: dict) -> dict[str, Any]:
|
|
28
29
|
if not self.checkpointer:
|
|
29
|
-
raise
|
|
30
|
+
raise HTTPException(status_code=503, detail="Checkpointer service is not available")
|
|
30
31
|
|
|
31
32
|
cfg: dict[str, Any] = dict(config or {})
|
|
32
33
|
cfg["user"] = user
|
|
@@ -2,7 +2,7 @@ from typing import Any
|
|
|
2
2
|
|
|
3
3
|
from agentflow.state import Message
|
|
4
4
|
from agentflow.utils import ResponseGranularity
|
|
5
|
-
from pydantic import BaseModel, Field
|
|
5
|
+
from pydantic import BaseModel, Field, field_validator
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
class GraphInputSchema(BaseModel):
|
|
@@ -23,8 +23,18 @@ class GraphInputSchema(BaseModel):
|
|
|
23
23
|
)
|
|
24
24
|
recursion_limit: int = Field(
|
|
25
25
|
default=25,
|
|
26
|
+
ge=1,
|
|
27
|
+
le=100,
|
|
26
28
|
description="Maximum recursion limit for graph execution",
|
|
27
29
|
)
|
|
30
|
+
|
|
31
|
+
@field_validator("messages")
|
|
32
|
+
@classmethod
|
|
33
|
+
def messages_must_not_be_empty(cls, v: list[Message]) -> list[Message]:
|
|
34
|
+
if not v:
|
|
35
|
+
raise ValueError("messages must contain at least one message")
|
|
36
|
+
return v
|
|
37
|
+
|
|
28
38
|
response_granularity: ResponseGranularity = Field(
|
|
29
39
|
default=ResponseGranularity.LOW,
|
|
30
40
|
description="Granularity of the response (full, partial, low)",
|
|
@@ -111,7 +121,15 @@ class GraphSchema(BaseModel):
|
|
|
111
121
|
class GraphStopSchema(BaseModel):
|
|
112
122
|
"""Schema for stopping graph execution."""
|
|
113
123
|
|
|
114
|
-
thread_id: str = Field(..., description="Thread ID to stop execution for")
|
|
124
|
+
thread_id: str = Field(..., min_length=1, description="Thread ID to stop execution for")
|
|
125
|
+
|
|
126
|
+
@field_validator("thread_id")
|
|
127
|
+
@classmethod
|
|
128
|
+
def thread_id_not_blank(cls, v: str) -> str:
|
|
129
|
+
if not v.strip():
|
|
130
|
+
raise ValueError("thread_id cannot be empty or whitespace")
|
|
131
|
+
return v.strip()
|
|
132
|
+
|
|
115
133
|
config: dict[str, Any] | None = Field(
|
|
116
134
|
default=None, description="Optional configuration for the stop operation"
|
|
117
135
|
)
|
|
@@ -137,7 +155,15 @@ class GraphSetupSchema(BaseModel):
|
|
|
137
155
|
class FixGraphRequestSchema(BaseModel):
|
|
138
156
|
"""Schema for fixing graph state by removing messages with empty tool call content."""
|
|
139
157
|
|
|
140
|
-
thread_id: str = Field(..., description="Thread ID to fix the graph state for")
|
|
158
|
+
thread_id: str = Field(..., min_length=1, description="Thread ID to fix the graph state for")
|
|
159
|
+
|
|
160
|
+
@field_validator("thread_id")
|
|
161
|
+
@classmethod
|
|
162
|
+
def thread_id_not_blank(cls, v: str) -> str:
|
|
163
|
+
if not v.strip():
|
|
164
|
+
raise ValueError("thread_id cannot be empty or whitespace")
|
|
165
|
+
return v.strip()
|
|
166
|
+
|
|
141
167
|
config: dict[str, Any] | None = Field(
|
|
142
168
|
default=None, description="Optional configuration for the fix operation"
|
|
143
169
|
)
|
|
@@ -154,6 +154,9 @@ class GraphService:
|
|
|
154
154
|
logger.info(f"Graph stop completed for thread {thread_id}: {result}")
|
|
155
155
|
return result
|
|
156
156
|
|
|
157
|
+
except ValueError as e:
|
|
158
|
+
logger.warning(f"Graph stop input validation failed for thread {thread_id}: {e}")
|
|
159
|
+
raise HTTPException(status_code=422, detail=str(e))
|
|
157
160
|
except Exception as e:
|
|
158
161
|
logger.error(f"Graph stop failed for thread {thread_id}: {e}")
|
|
159
162
|
raise HTTPException(
|
|
@@ -166,8 +169,8 @@ class GraphService:
|
|
|
166
169
|
):
|
|
167
170
|
is_new_thread = False
|
|
168
171
|
config = graph_input.config or {}
|
|
169
|
-
if "thread_id"
|
|
170
|
-
thread_id = config["thread_id"]
|
|
172
|
+
if config.get("thread_id") and str(config["thread_id"]).strip():
|
|
173
|
+
thread_id = str(config["thread_id"]).strip()
|
|
171
174
|
else:
|
|
172
175
|
thread_id = await InjectQ.get_instance().atry_get("generated_id") or str(uuid4())
|
|
173
176
|
is_new_thread = True
|
|
@@ -258,6 +261,9 @@ class GraphService:
|
|
|
258
261
|
meta=meta,
|
|
259
262
|
)
|
|
260
263
|
|
|
264
|
+
except ValueError as e:
|
|
265
|
+
logger.warning(f"Graph input validation failed: {e}")
|
|
266
|
+
raise HTTPException(status_code=422, detail=str(e))
|
|
261
267
|
except Exception as e:
|
|
262
268
|
logger.error(f"Graph execution failed: {e}")
|
|
263
269
|
raise HTTPException(status_code=500, detail=f"Graph execution failed: {e!s}")
|
|
@@ -334,6 +340,9 @@ class GraphService:
|
|
|
334
340
|
+ "\n"
|
|
335
341
|
)
|
|
336
342
|
|
|
343
|
+
except ValueError as e:
|
|
344
|
+
logger.warning(f"Graph stream input validation failed: {e}")
|
|
345
|
+
raise HTTPException(status_code=422, detail=str(e))
|
|
337
346
|
except Exception as e:
|
|
338
347
|
logger.error(f"Graph streaming failed: {e}")
|
|
339
348
|
raise HTTPException(status_code=500, detail=f"Graph streaming failed: {e!s}")
|
|
@@ -341,9 +350,11 @@ class GraphService:
|
|
|
341
350
|
async def graph_details(self) -> GraphSchema:
|
|
342
351
|
try:
|
|
343
352
|
logger.info("Getting graph details")
|
|
344
|
-
# Fetch and return graph details
|
|
345
353
|
res = self._graph.generate_graph()
|
|
346
354
|
return GraphSchema(**res)
|
|
355
|
+
except ValueError as e:
|
|
356
|
+
logger.warning(f"Graph details validation failed: {e}")
|
|
357
|
+
raise HTTPException(status_code=422, detail=str(e))
|
|
347
358
|
except Exception as e:
|
|
348
359
|
logger.error(f"Failed to get graph details: {e}")
|
|
349
360
|
raise HTTPException(status_code=500, detail=f"Failed to get graph details: {e!s}")
|
|
@@ -351,9 +362,11 @@ class GraphService:
|
|
|
351
362
|
async def get_state_schema(self) -> dict:
|
|
352
363
|
try:
|
|
353
364
|
logger.info("Getting state schema")
|
|
354
|
-
# Fetch and return state schema
|
|
355
365
|
res: BaseModel = self._graph._state
|
|
356
366
|
return res.model_json_schema()
|
|
367
|
+
except ValueError as e:
|
|
368
|
+
logger.warning(f"State schema validation failed: {e}")
|
|
369
|
+
raise HTTPException(status_code=422, detail=str(e))
|
|
357
370
|
except Exception as e:
|
|
358
371
|
logger.error(f"Failed to get state schema: {e}")
|
|
359
372
|
raise HTTPException(status_code=500, detail=f"Failed to get state schema: {e!s}")
|
|
@@ -451,6 +464,9 @@ class GraphService:
|
|
|
451
464
|
"removed_count": removed_count,
|
|
452
465
|
"state": state.model_dump_json(serialize_as_any=True),
|
|
453
466
|
}
|
|
467
|
+
except ValueError as e:
|
|
468
|
+
logger.warning(f"Fix graph input validation failed: {e}")
|
|
469
|
+
raise HTTPException(status_code=422, detail=str(e))
|
|
454
470
|
except Exception as e:
|
|
455
471
|
logger.error(f"Fix graph operation failed: {e}")
|
|
456
472
|
raise HTTPException(status_code=500, detail=f"Fix graph operation failed: {e!s}")
|
|
@@ -4,7 +4,7 @@ from __future__ import annotations
|
|
|
4
4
|
|
|
5
5
|
from typing import Any
|
|
6
6
|
|
|
7
|
-
from fastapi import APIRouter, Body, Depends, Request, status
|
|
7
|
+
from fastapi import APIRouter, Body, Depends, HTTPException, Request, status
|
|
8
8
|
from injectq.integrations import InjectAPI
|
|
9
9
|
|
|
10
10
|
from agentflow_cli.src.app.core.auth.permissions import RequirePermission
|
|
@@ -64,6 +64,8 @@ async def search_memories(
|
|
|
64
64
|
user: dict[str, Any] = Depends(RequirePermission("store", "read")),
|
|
65
65
|
):
|
|
66
66
|
"""Search stored memories."""
|
|
67
|
+
if not payload.query or (isinstance(payload.query, str) and not payload.query.strip()):
|
|
68
|
+
raise HTTPException(status_code=422, detail="query is required and cannot be empty")
|
|
67
69
|
|
|
68
70
|
result = await service.search_memories(payload, user)
|
|
69
71
|
return success_response(result, request)
|
|
@@ -87,6 +89,8 @@ async def get_memory(
|
|
|
87
89
|
user: dict[str, Any] = Depends(RequirePermission("store", "read")),
|
|
88
90
|
):
|
|
89
91
|
"""Get a memory by ID."""
|
|
92
|
+
if not memory_id or not memory_id.strip():
|
|
93
|
+
raise HTTPException(status_code=422, detail="memory_id is required and cannot be empty")
|
|
90
94
|
|
|
91
95
|
cfg = payload.config if payload else {}
|
|
92
96
|
opts = payload.options if payload else None
|
|
@@ -112,6 +116,9 @@ async def list_memories(
|
|
|
112
116
|
):
|
|
113
117
|
"""List stored memories."""
|
|
114
118
|
|
|
119
|
+
if payload and payload.limit is not None and payload.limit <= 0:
|
|
120
|
+
raise HTTPException(status_code=422, detail="limit must be > 0")
|
|
121
|
+
|
|
115
122
|
if payload is None:
|
|
116
123
|
payload = ListMemoriesSchema()
|
|
117
124
|
cfg = payload.config or {}
|
|
@@ -135,6 +142,8 @@ async def update_memory(
|
|
|
135
142
|
user: dict[str, Any] = Depends(RequirePermission("store", "write")),
|
|
136
143
|
):
|
|
137
144
|
"""Update a stored memory."""
|
|
145
|
+
if not memory_id or not memory_id.strip():
|
|
146
|
+
raise HTTPException(status_code=422, detail="memory_id is required and cannot be empty")
|
|
138
147
|
|
|
139
148
|
result = await service.update_memory(memory_id, payload, user)
|
|
140
149
|
return success_response(result, request, message="Memory updated successfully")
|
|
@@ -158,6 +167,8 @@ async def delete_memory(
|
|
|
158
167
|
user: dict[str, Any] = Depends(RequirePermission("store", "delete")),
|
|
159
168
|
):
|
|
160
169
|
"""Delete a stored memory."""
|
|
170
|
+
if not memory_id or not memory_id.strip():
|
|
171
|
+
raise HTTPException(status_code=422, detail="memory_id is required and cannot be empty")
|
|
161
172
|
|
|
162
173
|
config_payload = payload.config if payload else {}
|
|
163
174
|
options_payload = payload.options if payload else None
|
|
@@ -4,6 +4,7 @@ from typing import Any
|
|
|
4
4
|
|
|
5
5
|
from agentflow.state import Message
|
|
6
6
|
from agentflow.store import BaseStore
|
|
7
|
+
from fastapi import HTTPException
|
|
7
8
|
from injectq import inject, singleton
|
|
8
9
|
|
|
9
10
|
from agentflow_cli.src.app.core import logger
|
|
@@ -30,7 +31,7 @@ class StoreService:
|
|
|
30
31
|
|
|
31
32
|
def _get_store(self) -> BaseStore:
|
|
32
33
|
if not self.store:
|
|
33
|
-
raise
|
|
34
|
+
raise HTTPException(status_code=503, detail="Store service is not available")
|
|
34
35
|
return self.store
|
|
35
36
|
|
|
36
37
|
def _config(self, config: dict[str, Any] | None, user: dict[str, Any]) -> dict[str, Any]:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/cli/commands/__init__.py
RENAMED
|
File without changes
|
{10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/cli/commands/api.py
RENAMED
|
File without changes
|
{10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/cli/commands/build.py
RENAMED
|
File without changes
|
{10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/cli/commands/init.py
RENAMED
|
File without changes
|
{10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/cli/commands/version.py
RENAMED
|
File without changes
|
{10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/cli/constants.py
RENAMED
|
File without changes
|
{10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/cli/core/__init__.py
RENAMED
|
File without changes
|
{10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/cli/core/config.py
RENAMED
|
File without changes
|
{10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/cli/core/output.py
RENAMED
|
File without changes
|
{10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/cli/core/validation.py
RENAMED
|
File without changes
|
{10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/cli/exceptions.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/__init__.py
RENAMED
|
File without changes
|
{10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/core/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/routers/a2a.py
RENAMED
|
File without changes
|
{10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/routers/a2ui.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/agentflow_cli/src/app/worker.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/graph/thread_name_generator.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{10xscale_agentflow_cli-0.2.8 → 10xscale_agentflow_cli-0.2.9}/tests/test_utils_parse_and_callable.py
RENAMED
|
File without changes
|