acra-cli 0.1.1__py3-none-any.whl

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.
Files changed (169) hide show
  1. acra/__init__.py +7 -0
  2. acra/__main__.py +4 -0
  3. acra/agents/__init__.py +0 -0
  4. acra/agents/__pycache__/__init__.cpython-312.pyc +0 -0
  5. acra/agents/__pycache__/llm.cpython-312.pyc +0 -0
  6. acra/agents/__pycache__/llm_utils.cpython-312.pyc +0 -0
  7. acra/agents/coder/__init__.py +0 -0
  8. acra/agents/coder/__pycache__/__init__.cpython-312.pyc +0 -0
  9. acra/agents/coder/__pycache__/coder_agent.cpython-312.pyc +0 -0
  10. acra/agents/coder/__pycache__/coder_chain.cpython-312.pyc +0 -0
  11. acra/agents/coder/coder_agent.py +235 -0
  12. acra/agents/coder/coder_chain.py +204 -0
  13. acra/agents/critic/__init__.py +0 -0
  14. acra/agents/critic/__pycache__/__init__.cpython-312.pyc +0 -0
  15. acra/agents/critic/__pycache__/critic_agent.cpython-312.pyc +0 -0
  16. acra/agents/critic/__pycache__/critic_chain.cpython-312.pyc +0 -0
  17. acra/agents/critic/critic_agent.py +199 -0
  18. acra/agents/critic/critic_chain.py +268 -0
  19. acra/agents/executor/__init__.py +0 -0
  20. acra/agents/executor/__pycache__/__init__.cpython-312.pyc +0 -0
  21. acra/agents/executor/__pycache__/docker_runner.cpython-312.pyc +0 -0
  22. acra/agents/executor/__pycache__/executor_agent.cpython-312.pyc +0 -0
  23. acra/agents/executor/__pycache__/sandbox_runner.cpython-312.pyc +0 -0
  24. acra/agents/executor/docker_runner.py +114 -0
  25. acra/agents/executor/executor_agent.py +142 -0
  26. acra/agents/executor/sandbox_runner.py +144 -0
  27. acra/agents/human/__init__.py +0 -0
  28. acra/agents/human/__pycache__/__init__.cpython-312.pyc +0 -0
  29. acra/agents/human/__pycache__/human_node.cpython-312.pyc +0 -0
  30. acra/agents/human/human_node.py +37 -0
  31. acra/agents/llm.py +263 -0
  32. acra/agents/llm_utils.py +161 -0
  33. acra/agents/memory/__init__.py +0 -0
  34. acra/agents/memory/__pycache__/__init__.cpython-312.pyc +0 -0
  35. acra/agents/memory/__pycache__/memory_agent.cpython-312.pyc +0 -0
  36. acra/agents/memory/__pycache__/memory_manager.cpython-312.pyc +0 -0
  37. acra/agents/memory/__pycache__/retrieval.cpython-312.pyc +0 -0
  38. acra/agents/memory/memory_agent.py +239 -0
  39. acra/agents/memory/memory_manager.py +273 -0
  40. acra/agents/memory/retrieval.py +355 -0
  41. acra/agents/planner/__init__.py +0 -0
  42. acra/agents/planner/__pycache__/__init__.cpython-312.pyc +0 -0
  43. acra/agents/planner/__pycache__/planner_agent.cpython-312.pyc +0 -0
  44. acra/agents/planner/__pycache__/planner_chain.cpython-312.pyc +0 -0
  45. acra/agents/planner/planner_agent.py +97 -0
  46. acra/agents/planner/planner_chain.py +160 -0
  47. acra/agents/researcher/__init__.py +1 -0
  48. acra/agents/researcher/__pycache__/__init__.cpython-312.pyc +0 -0
  49. acra/agents/researcher/__pycache__/researcher_agent.cpython-312.pyc +0 -0
  50. acra/agents/researcher/__pycache__/researcher_chain.cpython-312.pyc +0 -0
  51. acra/agents/researcher/researcher_agent.py +231 -0
  52. acra/agents/researcher/researcher_chain.py +193 -0
  53. acra/brain/__init__.py +6 -0
  54. acra/brain/model_registry.py +19 -0
  55. acra/brain/provider_manager.py +21 -0
  56. acra/cli.py +52 -0
  57. acra/commands/__init__.py +29 -0
  58. acra/commands/ask.py +49 -0
  59. acra/commands/brain.py +58 -0
  60. acra/commands/config.py +25 -0
  61. acra/commands/context.py +30 -0
  62. acra/commands/graph.py +18 -0
  63. acra/commands/keys.py +40 -0
  64. acra/commands/logs.py +13 -0
  65. acra/commands/memory.py +27 -0
  66. acra/commands/plugin.py +18 -0
  67. acra/commands/research.py +65 -0
  68. acra/commands/serve.py +13 -0
  69. acra/commands/session.py +20 -0
  70. acra/commands/utils.py +12 -0
  71. acra/config/__init__.py +36 -0
  72. acra/config/__pycache__/__init__.cpython-312.pyc +0 -0
  73. acra/config/__pycache__/defaults.cpython-312.pyc +0 -0
  74. acra/config/__pycache__/profile_manager.cpython-312.pyc +0 -0
  75. acra/config/defaults.py +88 -0
  76. acra/config/profile_manager.py +87 -0
  77. acra/execution/__init__.py +1 -0
  78. acra/execution/logs/__init__.py +1 -0
  79. acra/execution/logs/error_logs/__init__.py +1 -0
  80. acra/execution/logs/execution_logs/__init__.py +1 -0
  81. acra/execution/sandbox/__init__.py +1 -0
  82. acra/execution/sandbox/docker_executor.py +209 -0
  83. acra/execution/sandbox/isolated_runner.py +148 -0
  84. acra/execution/sandbox/sandbox_manager.py +178 -0
  85. acra/graph/__init__.py +0 -0
  86. acra/graph/checkpoint.py +85 -0
  87. acra/graph/conditional_edges.py +103 -0
  88. acra/graph/edges.py +85 -0
  89. acra/graph/graph_visualizer.py +175 -0
  90. acra/graph/nodes.py +68 -0
  91. acra/graph/router.py +69 -0
  92. acra/graph/state.py +93 -0
  93. acra/graph/workflow.py +117 -0
  94. acra/memory/__init__.py +1 -0
  95. acra/memory/checkpoints/__init__.py +1 -0
  96. acra/memory/checkpoints/data/__init__.py +1 -0
  97. acra/memory/checkpoints/postgres_checkpoint.py +247 -0
  98. acra/memory/checkpoints/sqlite_checkpoint.py +309 -0
  99. acra/memory/chroma_db/__init__.py +1 -0
  100. acra/memory/conversation_memory/__init__.py +1 -0
  101. acra/memory/conversation_memory/long_term.py +229 -0
  102. acra/memory/conversation_memory/short_term.py +158 -0
  103. acra/memory/storage/__init__.py +1 -0
  104. acra/memory/vector_store/__init__.py +0 -0
  105. acra/memory/vector_store/chroma_store.py +260 -0
  106. acra/memory/vector_store/embeddings.py +43 -0
  107. acra/observability/__init__.py +1 -0
  108. acra/observability/langsmith_tracing.py +91 -0
  109. acra/observability/metrics.py +189 -0
  110. acra/observability/monitoring.py +162 -0
  111. acra/observability/token_tracking.py +131 -0
  112. acra/prompts/__init__.py +1 -0
  113. acra/schemas/__init__.py +0 -0
  114. acra/schemas/__pycache__/__init__.cpython-312.pyc +0 -0
  115. acra/schemas/__pycache__/coder_schema.cpython-312.pyc +0 -0
  116. acra/schemas/__pycache__/critic_schema.cpython-312.pyc +0 -0
  117. acra/schemas/__pycache__/execution_schema.cpython-312.pyc +0 -0
  118. acra/schemas/__pycache__/planner_schema.cpython-312.pyc +0 -0
  119. acra/schemas/__pycache__/researcher_schema.cpython-312.pyc +0 -0
  120. acra/schemas/__pycache__/shared_schema.cpython-312.pyc +0 -0
  121. acra/schemas/coder_schema.py +257 -0
  122. acra/schemas/critic_schema.py +177 -0
  123. acra/schemas/execution_schema.py +74 -0
  124. acra/schemas/planner_schema.py +129 -0
  125. acra/schemas/researcher_schema.py +220 -0
  126. acra/schemas/shared_schema.py +329 -0
  127. acra/tools/__init__.py +1 -0
  128. acra/tools/code_tools/__init__.py +1 -0
  129. acra/tools/code_tools/file_reader.py +156 -0
  130. acra/tools/code_tools/file_writer.py +108 -0
  131. acra/tools/code_tools/python_repl.py +72 -0
  132. acra/tools/code_tools/terminal_runner.py +98 -0
  133. acra/tools/github_tools/__init__.py +1 -0
  134. acra/tools/github_tools/commit_generator.py +91 -0
  135. acra/tools/github_tools/github_search.py +113 -0
  136. acra/tools/github_tools/repo_analyzer.py +138 -0
  137. acra/tools/integration_test_helper.py +370 -0
  138. acra/tools/validation_tools/__init__.py +1 -0
  139. acra/tools/validation_tools/dependency_checker.py +101 -0
  140. acra/tools/validation_tools/environment_config_validator.py +353 -0
  141. acra/tools/validation_tools/http_validator.py +336 -0
  142. acra/tools/validation_tools/response_validator.py +407 -0
  143. acra/tools/validation_tools/security_checker.py +93 -0
  144. acra/tools/validation_tools/syntax_checker.py +75 -0
  145. acra/tools/validation_tools/web_framework_validator.py +382 -0
  146. acra/tools/web_tools/__init__.py +1 -0
  147. acra/tools/web_tools/arxiv_search.py +110 -0
  148. acra/tools/web_tools/serpapi_search.py +106 -0
  149. acra/tools/web_tools/tavily_search.py +96 -0
  150. acra/ui/__init__.py +8 -0
  151. acra/ui/__pycache__/__init__.cpython-312.pyc +0 -0
  152. acra/ui/__pycache__/banner.cpython-312.pyc +0 -0
  153. acra/ui/__pycache__/components.cpython-312.pyc +0 -0
  154. acra/ui/__pycache__/shell.cpython-312.pyc +0 -0
  155. acra/ui/__pycache__/theme.cpython-312.pyc +0 -0
  156. acra/ui/banner.py +40 -0
  157. acra/ui/components.py +32 -0
  158. acra/ui/shell.py +91 -0
  159. acra/ui/theme.py +28 -0
  160. acra/utils/__init__.py +21 -0
  161. acra/utils/context_manager.py +20 -0
  162. acra/utils/keyring_manager.py +83 -0
  163. acra/utils/output_formatter.py +18 -0
  164. acra/utils/session_manager.py +59 -0
  165. acra_cli-0.1.1.dist-info/METADATA +616 -0
  166. acra_cli-0.1.1.dist-info/RECORD +169 -0
  167. acra_cli-0.1.1.dist-info/WHEEL +5 -0
  168. acra_cli-0.1.1.dist-info/licenses/LICENSE +661 -0
  169. acra_cli-0.1.1.dist-info/top_level.txt +1 -0
acra/graph/workflow.py ADDED
@@ -0,0 +1,117 @@
1
+ from langgraph.graph import (
2
+ StateGraph,
3
+ START,
4
+ END
5
+ )
6
+ import time
7
+
8
+ from acra.graph.state import AgentState
9
+
10
+ from acra.graph.nodes import (
11
+ NODE_REGISTRY
12
+ )
13
+
14
+ from acra.graph.conditional_edges import (
15
+ register_conditional_edges
16
+ )
17
+
18
+ from acra.graph.checkpoint import GraphCheckpointManager
19
+ from acra.observability.metrics import metrics_tracker
20
+ from acra.observability.monitoring import system_monitor
21
+
22
+
23
+ class OmniAgentCallbacks:
24
+ """LangGraph callbacks for metrics and monitoring."""
25
+
26
+ raise_error = False
27
+ ignore_chain = False
28
+ ignore_agent = False
29
+ ignore_llm = False
30
+ ignore_chat_model = False
31
+
32
+ def on_chain_start(self, serialized, inputs, **kwargs):
33
+ try:
34
+ self._start = time.time()
35
+ agent = (serialized or {}).get("name", "unknown") if isinstance(serialized, dict) else "unknown"
36
+ system_monitor.info(agent, f"Agent started: {agent}")
37
+ metrics_tracker.record_agent_execution(agent)
38
+ except Exception:
39
+ return None
40
+
41
+ def on_chain_end(self, outputs, **kwargs):
42
+ try:
43
+ elapsed = time.time() - getattr(self, "_start", time.time())
44
+ system_monitor.info("workflow", f"Step completed in {elapsed:.2f}s")
45
+ except Exception:
46
+ return None
47
+
48
+ def on_chain_error(self, error, **kwargs):
49
+ try:
50
+ system_monitor.error("workflow", str(error))
51
+ except Exception:
52
+ return None
53
+
54
+ def on_chat_model_start(self, serialized, messages, **kwargs):
55
+ return None
56
+
57
+ def on_llm_end(self, response, **kwargs):
58
+ return None
59
+
60
+ def on_llm_error(self, error, **kwargs):
61
+ return None
62
+
63
+
64
+ # Initialize checkpoint manager
65
+ graph_checkpoint = GraphCheckpointManager()
66
+
67
+
68
+ # create workflow graph
69
+
70
+ def create_workflow():
71
+ """
72
+ Build OMNIAGENT workflow graph.
73
+ """
74
+
75
+ workflow = StateGraph(
76
+ AgentState
77
+ )
78
+
79
+ # register nodes
80
+
81
+ for (
82
+ node_name,
83
+ node_function
84
+ ) in NODE_REGISTRY.items():
85
+
86
+ workflow.add_node(
87
+ node_name,
88
+ node_function
89
+ )
90
+
91
+ # entry point
92
+
93
+ workflow.add_edge(
94
+ START,
95
+ "planner"
96
+ )
97
+
98
+ # conditional routing
99
+
100
+ workflow = (
101
+ register_conditional_edges(
102
+ workflow
103
+ )
104
+ )
105
+
106
+ # compile graph with checkpointer
107
+
108
+ graph = workflow.compile(
109
+ checkpointer=graph_checkpoint.checkpointer
110
+ )
111
+
112
+ return graph
113
+
114
+
115
+ # singleton workflow instance
116
+
117
+ omniagent_graph = create_workflow()
@@ -0,0 +1 @@
1
+ # Package acra/memory
@@ -0,0 +1 @@
1
+ # Package acra/memory/checkpoints
@@ -0,0 +1 @@
1
+ # Package acra/memory/checkpoints/data
@@ -0,0 +1,247 @@
1
+ import json
2
+ import os
3
+ from datetime import datetime
4
+ from typing import Any, Dict, Optional
5
+
6
+ import psycopg2
7
+ from psycopg2.extras import RealDictCursor
8
+
9
+
10
+ # postgres config
11
+
12
+ POSTGRES_HOST = os.getenv(
13
+ "POSTGRES_HOST",
14
+ "localhost"
15
+ )
16
+
17
+ POSTGRES_PORT = os.getenv(
18
+ "POSTGRES_PORT",
19
+ "5432"
20
+ )
21
+
22
+ POSTGRES_DB = os.getenv(
23
+ "POSTGRES_DB",
24
+ "omniagent"
25
+ )
26
+
27
+ POSTGRES_USER = os.getenv(
28
+ "POSTGRES_USER",
29
+ "postgres"
30
+ )
31
+
32
+ POSTGRES_PASSWORD = os.getenv(
33
+ "POSTGRES_PASSWORD",
34
+ "postgres"
35
+ )
36
+
37
+
38
+ # postgres checkpoint manager
39
+
40
+ class PostgresCheckpointManager:
41
+ """
42
+ PostgreSQL workflow checkpoint system.
43
+
44
+ Responsibilities:
45
+ - scalable workflow persistence
46
+ - distributed checkpoint storage
47
+ - production-grade recovery
48
+ """
49
+
50
+ def __init__(self):
51
+ self.connection = None
52
+
53
+
54
+ # create connection
55
+
56
+ def _create_connection(self):
57
+
58
+ return psycopg2.connect(
59
+
60
+ host=POSTGRES_HOST,
61
+
62
+ port=POSTGRES_PORT,
63
+
64
+ dbname=POSTGRES_DB,
65
+
66
+ user=POSTGRES_USER,
67
+
68
+ password=POSTGRES_PASSWORD
69
+ )
70
+
71
+
72
+ # initialize Db
73
+
74
+ def _ensure_connection(self):
75
+ if self.connection is None:
76
+ self.connection = self._create_connection()
77
+ self._initialize_database()
78
+
79
+ return self.connection
80
+
81
+
82
+ def _initialize_database(self) -> None:
83
+ """
84
+ Create checkpoint table.
85
+ """
86
+
87
+ cursor = self.connection.cursor()
88
+
89
+ cursor.execute(
90
+ """
91
+ CREATE TABLE IF NOT EXISTS checkpoints (
92
+
93
+ id SERIAL PRIMARY KEY,
94
+
95
+ checkpoint_id TEXT UNIQUE,
96
+
97
+ session_id TEXT,
98
+
99
+ workflow_status TEXT,
100
+
101
+ active_agent TEXT,
102
+
103
+ retry_count INTEGER,
104
+
105
+ state_data JSONB,
106
+
107
+ created_at TIMESTAMP
108
+ )
109
+ """
110
+ )
111
+
112
+ self.connection.commit()
113
+
114
+ cursor.close()
115
+
116
+
117
+ # save checkpoint
118
+
119
+ def save_checkpoint(
120
+ self,
121
+ checkpoint_id: str,
122
+ session_id: str,
123
+ workflow_status: str,
124
+ active_agent: str,
125
+ retry_count: int,
126
+ state_data: Dict[str, Any]
127
+ ) -> Dict:
128
+ """
129
+ Persist workflow checkpoint.
130
+ """
131
+
132
+ try:
133
+
134
+ connection = self._ensure_connection()
135
+ cursor = connection.cursor()
136
+
137
+ cursor.execute(
138
+ """
139
+ INSERT INTO checkpoints (
140
+
141
+ checkpoint_id,
142
+ session_id,
143
+ workflow_status,
144
+ active_agent,
145
+ retry_count,
146
+ state_data,
147
+ created_at
148
+
149
+ ) VALUES (%s, %s, %s, %s, %s, %s, %s)
150
+
151
+ ON CONFLICT (checkpoint_id)
152
+
153
+ DO UPDATE SET
154
+
155
+ workflow_status = EXCLUDED.workflow_status,
156
+ active_agent = EXCLUDED.active_agent,
157
+ retry_count = EXCLUDED.retry_count,
158
+ state_data = EXCLUDED.state_data
159
+ """,
160
+ (
161
+ checkpoint_id,
162
+ session_id,
163
+ workflow_status,
164
+ active_agent,
165
+ retry_count,
166
+ json.dumps(state_data),
167
+ datetime.utcnow()
168
+ )
169
+ )
170
+
171
+ self.connection.commit()
172
+
173
+ cursor.close()
174
+
175
+ return {
176
+
177
+ "success": True,
178
+
179
+ "checkpoint_id": checkpoint_id
180
+ }
181
+
182
+ except Exception as e:
183
+
184
+ return {
185
+
186
+ "success": False,
187
+
188
+ "error": str(e)
189
+ }
190
+
191
+
192
+ # load checkpoint
193
+
194
+ def load_checkpoint(
195
+ self,
196
+ checkpoint_id: str
197
+ ) -> Dict:
198
+ """
199
+ Retrieve workflow checkpoint.
200
+ """
201
+
202
+ try:
203
+
204
+ connection = self._ensure_connection()
205
+ cursor = connection.cursor(
206
+ cursor_factory=RealDictCursor
207
+ )
208
+
209
+ cursor.execute(
210
+ """
211
+ SELECT *
212
+ FROM checkpoints
213
+ WHERE checkpoint_id = %s
214
+ """,
215
+ (checkpoint_id,)
216
+ )
217
+
218
+ result = cursor.fetchone()
219
+
220
+ cursor.close()
221
+
222
+ if not result:
223
+
224
+ return {
225
+
226
+ "success": False,
227
+
228
+ "error": (
229
+ "Checkpoint not found."
230
+ )
231
+ }
232
+
233
+ return {
234
+
235
+ "success": True,
236
+
237
+ "checkpoint": dict(result)
238
+ }
239
+
240
+ except Exception as e:
241
+
242
+ return {
243
+
244
+ "success": False,
245
+
246
+ "error": str(e)
247
+ }
@@ -0,0 +1,309 @@
1
+ import json
2
+ import os
3
+ import sqlite3
4
+ import logging
5
+ from datetime import datetime
6
+ from typing import Any, Dict, List, Optional
7
+ from acra.config import SQLITE_DB_PATH
8
+
9
+
10
+ # sqlite checkpoint manager
11
+
12
+ class SQLiteCheckpointManager:
13
+ """
14
+ SQLite-based workflow checkpoint system.
15
+
16
+ Responsibilities:
17
+ - persist workflow state
18
+ - enable workflow recovery
19
+ - support resumable execution
20
+ - track autonomous execution history
21
+ """
22
+
23
+ def __init__(
24
+ self,
25
+ db_path: str = None
26
+ ):
27
+
28
+ if db_path is None:
29
+ db_path = str(SQLITE_DB_PATH)
30
+ self.db_path = db_path
31
+
32
+ self._initialize_database()
33
+
34
+
35
+ # initialize DB
36
+
37
+ def _initialize_database(self) -> None:
38
+ """
39
+ Create checkpoint table if missing.
40
+ """
41
+
42
+ connection = sqlite3.connect(
43
+ self.db_path
44
+ )
45
+
46
+ cursor = connection.cursor()
47
+
48
+ cursor.execute(
49
+ """
50
+ CREATE TABLE IF NOT EXISTS checkpoints (
51
+
52
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
53
+
54
+ checkpoint_id TEXT UNIQUE,
55
+
56
+ session_id TEXT,
57
+
58
+ workflow_status TEXT,
59
+
60
+ active_agent TEXT,
61
+
62
+ retry_count INTEGER,
63
+
64
+ state_data TEXT,
65
+
66
+ created_at TEXT
67
+ )
68
+ """
69
+ )
70
+
71
+ connection.commit()
72
+
73
+ connection.close()
74
+
75
+
76
+ # save checkpoint
77
+
78
+ def save_checkpoint(
79
+ self,
80
+ checkpoint_id: str,
81
+ session_id: str,
82
+ workflow_status: str,
83
+ active_agent: str,
84
+ retry_count: int,
85
+ state_data: Dict[str, Any]
86
+ ) -> Dict:
87
+ """
88
+ Persist workflow checkpoint.
89
+ """
90
+
91
+ try:
92
+
93
+ connection = sqlite3.connect(
94
+ self.db_path
95
+ )
96
+
97
+ cursor = connection.cursor()
98
+
99
+ cursor.execute(
100
+ """
101
+ INSERT OR REPLACE INTO checkpoints (
102
+
103
+ checkpoint_id,
104
+ session_id,
105
+ workflow_status,
106
+ active_agent,
107
+ retry_count,
108
+ state_data,
109
+ created_at
110
+
111
+ ) VALUES (?, ?, ?, ?, ?, ?, ?)
112
+ """,
113
+ (
114
+ checkpoint_id,
115
+ session_id,
116
+ workflow_status,
117
+ active_agent,
118
+ retry_count,
119
+ json.dumps(state_data),
120
+ datetime.utcnow().isoformat()
121
+ )
122
+ )
123
+
124
+ connection.commit()
125
+
126
+ connection.close()
127
+
128
+ return {
129
+
130
+ "success": True,
131
+
132
+ "checkpoint_id": checkpoint_id
133
+ }
134
+
135
+ except Exception as e:
136
+ logging.getLogger(__name__).error("SQLiteCheckpointManager.save_checkpoint failed: %s", e, exc_info=True)
137
+
138
+ return {
139
+
140
+ "success": False,
141
+
142
+ "error": str(e)
143
+ }
144
+
145
+
146
+ # load checkpoint
147
+
148
+ def load_checkpoint(
149
+ self,
150
+ checkpoint_id: str
151
+ ) -> Dict:
152
+ """
153
+ Retrieve checkpoint by ID.
154
+ """
155
+
156
+ try:
157
+
158
+ connection = sqlite3.connect(
159
+ self.db_path
160
+ )
161
+
162
+ cursor = connection.cursor()
163
+
164
+ cursor.execute(
165
+ """
166
+ SELECT *
167
+ FROM checkpoints
168
+ WHERE checkpoint_id = ?
169
+ """,
170
+ (checkpoint_id,)
171
+ )
172
+
173
+ row = cursor.fetchone()
174
+
175
+ connection.close()
176
+
177
+ if not row:
178
+
179
+ return {
180
+
181
+ "success": False,
182
+
183
+ "error": (
184
+ "Checkpoint not found."
185
+ )
186
+ }
187
+
188
+ return {
189
+
190
+ "success": True,
191
+
192
+ "checkpoint": {
193
+
194
+ "checkpoint_id": row[1],
195
+
196
+ "session_id": row[2],
197
+
198
+ "workflow_status": row[3],
199
+
200
+ "active_agent": row[4],
201
+
202
+ "retry_count": row[5],
203
+
204
+ "state_data": json.loads(
205
+ row[6]
206
+ ),
207
+
208
+ "created_at": row[7]
209
+ }
210
+ }
211
+
212
+ except Exception as e:
213
+ logging.getLogger(__name__).error("SQLiteCheckpointManager.load_checkpoint failed: %s", e, exc_info=True)
214
+
215
+ return {
216
+
217
+ "success": False,
218
+
219
+ "error": str(e)
220
+ }
221
+
222
+
223
+ # list checkpoints
224
+
225
+ def list_checkpoints(
226
+ self,
227
+ session_id: Optional[str] = None
228
+ ) -> Dict:
229
+ """
230
+ Retrieve stored checkpoints.
231
+ """
232
+
233
+ try:
234
+
235
+ connection = sqlite3.connect(
236
+ self.db_path
237
+ )
238
+
239
+ cursor = connection.cursor()
240
+
241
+ if session_id:
242
+
243
+ cursor.execute(
244
+ """
245
+ SELECT checkpoint_id,
246
+ workflow_status,
247
+ active_agent,
248
+ created_at
249
+ FROM checkpoints
250
+ WHERE session_id = ?
251
+ ORDER BY created_at DESC
252
+ """,
253
+ (session_id,)
254
+ )
255
+
256
+ else:
257
+
258
+ cursor.execute(
259
+ """
260
+ SELECT checkpoint_id,
261
+ workflow_status,
262
+ active_agent,
263
+ created_at
264
+ FROM checkpoints
265
+ ORDER BY created_at DESC
266
+ """
267
+ )
268
+
269
+ rows = cursor.fetchall()
270
+
271
+ connection.close()
272
+
273
+ checkpoints = []
274
+
275
+ for row in rows:
276
+
277
+ checkpoints.append({
278
+
279
+ "checkpoint_id": row[0],
280
+
281
+ "workflow_status": row[1],
282
+
283
+ "active_agent": row[2],
284
+
285
+ "created_at": row[3]
286
+ })
287
+
288
+ return {
289
+
290
+ "success": True,
291
+
292
+ "checkpoints": checkpoints
293
+ }
294
+
295
+ except Exception as e:
296
+
297
+ return {
298
+
299
+ "success": False,
300
+
301
+ "error": str(e)
302
+ }
303
+
304
+
305
+ # global checkpoint manager
306
+
307
+ sqlite_checkpoint_manager = (
308
+ SQLiteCheckpointManager()
309
+ )
@@ -0,0 +1 @@
1
+ # Package acra/memory/chroma_db
@@ -0,0 +1 @@
1
+ # Package acra/memory/conversation_memory