diagram-to-iac 1.4.0__py3-none-any.whl → 1.6.0__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.
@@ -0,0 +1,56 @@
1
+ # DemonstratorAgent specific configuration
2
+ # Inherits common settings from src/diagram_to_iac/config.yaml
3
+ # Only agent-specific overrides and unique settings are defined here
4
+
5
+ # Agent-specific routing tokens
6
+ routing_keys:
7
+ analyze: "ROUTE_TO_ANALYZE"
8
+ demonstrate: "ROUTE_TO_DEMONSTRATE"
9
+ collect_inputs: "ROUTE_TO_COLLECT_INPUTS"
10
+ retry: "ROUTE_TO_RETRY"
11
+ create_issue: "ROUTE_TO_CREATE_ISSUE"
12
+ end: "ROUTE_TO_END"
13
+
14
+ prompts:
15
+ planner_prompt: |
16
+ User request: "{user_input}"
17
+
18
+ This is a dry-run demonstration request for error: {error_type}
19
+ Error message: {error_message}
20
+
21
+ Analyze this request and determine the appropriate action:
22
+ 1. If need to analyze the error for user guidance, respond with "{route_analyze}"
23
+ 2. If need to demonstrate the issue to user, respond with "{route_demonstrate}"
24
+ 3. If need to collect user inputs for fixing, respond with "{route_collect_inputs}"
25
+ 4. If need to retry with new information, respond with "{route_retry}"
26
+ 5. If need to create GitHub issue, respond with "{route_create_issue}"
27
+ 6. If demonstration is complete, respond with "{route_end}"
28
+
29
+ Important: Focus on being helpful and educational in demonstrating the error and potential fixes.
30
+
31
+ # Error analysis patterns
32
+ error_patterns:
33
+ terraform_auth:
34
+ keywords: ["missing_terraform_token", "auth", "tfe_token"]
35
+ fixable: true
36
+ required_inputs: ["TFE_TOKEN", "TF_WORKSPACE"]
37
+
38
+ api_auth:
39
+ keywords: ["api key", "401", "unauthorized"]
40
+ fixable: true
41
+ required_inputs: ["OPENAI_API_KEY", "ANTHROPIC_API_KEY", "GITHUB_TOKEN"]
42
+
43
+ terraform_init:
44
+ keywords: ["terraform init", "backend"]
45
+ fixable: true
46
+ required_inputs: ["Backend configuration", "Access credentials"]
47
+
48
+ network_error:
49
+ keywords: ["network", "connection", "timeout"]
50
+ fixable: true
51
+ required_inputs: ["Network connectivity", "Proxy settings"]
52
+
53
+ permission_error:
54
+ keywords: ["permission", "forbidden", "access denied"]
55
+ fixable: false
56
+ manual_steps: "Check permissions and access rights"
@@ -0,0 +1,91 @@
1
+ # GitAgent specific configuration
2
+ # Inherits common settings from src/diagram_to_iac/config.yaml
3
+ # Only agent-specific overrides and unique settings are defined here
4
+
5
+ agent_name: "GitAgent"
6
+ description: "Git operations and GitHub issue management agent"
7
+
8
+ # Agent-specific routing tokens (others inherit from central config)
9
+ routing_keys:
10
+ git_clone: "ROUTE_TO_GIT_CLONE"
11
+ github_cli: "ROUTE_TO_GITHUB_ISSUE" # Fixed: was github_cli, now points to correct token
12
+ shell_exec: "ROUTE_TO_SHELL" # Fixed: was shell_exec, now points to correct token
13
+ end: "ROUTE_TO_END"
14
+
15
+ # Legacy routing support (to be removed in future)
16
+ routing:
17
+ route_to_clone: "clone_repo"
18
+ route_to_issue: "open_issue"
19
+ route_to_shell: "shell_exec"
20
+ ROUTE_TO_GIT_CLONE: "clone_repo"
21
+ ROUTE_TO_GITHUB_ISSUE: "open_issue"
22
+ ROUTE_TO_SHELL: "shell_exec"
23
+ route_to_end: "__end__"
24
+ ROUTE_TO_END: "__end__"
25
+
26
+ # Prompts Configuration
27
+ prompts:
28
+ planner_prompt: |
29
+ User input: "{user_input}"
30
+
31
+ You are a GitAgent specialized in Git operations and GitHub issue management.
32
+
33
+ Your role:
34
+ - Handle git repository operations (clone, branch management)
35
+ - Create GitHub issues for problems and errors
36
+ - Execute shell commands when needed for git operations
37
+
38
+ Available routing tokens:
39
+ - {route_git_clone}: For cloning repositories
40
+ - {route_github_cli}: For creating GitHub issues
41
+ - {route_shell_exec}: For shell command execution
42
+ - {route_end}: When task is complete
43
+
44
+ Routing Guidelines:
45
+ 1. If the query starts with "clone" and does NOT mention "issue", respond with "{route_git_clone}"
46
+ 2. If the query starts with "open issue" OR contains "create issue" OR contains "R2D deployment error", respond with "{route_github_cli}"
47
+ 3. If the query needs shell commands (like "ls", "cat", "mkdir"), respond with "{route_shell_exec}"
48
+ 4. If no action needed, respond with "{route_end}"
49
+
50
+ CRITICAL: Always emit exactly ONE routing token. Do not include explanations or additional text.
51
+ CRITICAL: ANY query that starts with "open issue" MUST route to {route_github_cli}.
52
+ CRITICAL: Issue creation requests should NEVER go to {route_end} or {route_shell_exec}.
53
+
54
+ # Planner Prompt Configuration (Legacy - keeping for compatibility)
55
+ planner_prompt: |
56
+ You are a GitAgent specialized in Git operations and GitHub issue management.
57
+
58
+ Your role:
59
+ - Handle git repository operations (clone, branch management)
60
+ - Create GitHub issues for problems and errors
61
+ - Execute shell commands when needed for git operations
62
+
63
+ Available routing tokens:
64
+ - ROUTE_TO_GIT_CLONE: For cloning repositories
65
+ - ROUTE_TO_GITHUB_ISSUE: For creating GitHub issues
66
+ - ROUTE_TO_SHELL: For shell command execution
67
+ - ROUTE_TO_END: When task is complete
68
+
69
+ Routing Guidelines:
70
+ 1. If the query starts with "clone" and does NOT mention "issue", use ROUTE_TO_GIT_CLONE
71
+ 2. If the query starts with "open issue" OR contains "create issue" OR contains "R2D deployment error", use ROUTE_TO_GITHUB_ISSUE
72
+ 3. If the query needs shell commands (like "ls", "cat", "mkdir"), use ROUTE_TO_SHELL
73
+ 4. If no action needed, use ROUTE_TO_END
74
+
75
+ CRITICAL: Always emit exactly ONE routing token. Do not include explanations or additional text.
76
+ CRITICAL: ANY query that starts with "open issue" MUST route to ROUTE_TO_GITHUB_ISSUE.
77
+ CRITICAL: Issue creation requests should NEVER go to ROUTE_TO_END or ROUTE_TO_SHELL.
78
+
79
+ Query: {query}
80
+
81
+ Routing decision:
82
+
83
+ # Error Handling
84
+ error_handling:
85
+ retry_attempts: 2
86
+ timeout_seconds: 30
87
+
88
+ # GitHub Issue Templates
89
+ github_issue:
90
+ default_labels: ["automation", "r2d-workflow"]
91
+ title_prefix: "R2D Workflow Error"
@@ -0,0 +1,6 @@
1
+ # HelloAgent specific configuration
2
+ # Inherits common settings from src/diagram_to_iac/config.yaml
3
+ # Only agent-specific overrides are defined here
4
+
5
+ ai:
6
+ default_temperature: 0.0 # HelloAgent uses 0.0 instead of common 0.1
@@ -0,0 +1,43 @@
1
+ # PolicyAgent specific configuration
2
+ # Inherits common settings from src/diagram_to_iac/config.yaml
3
+ # Only agent-specific overrides and unique settings are defined here
4
+
5
+ # Agent-specific routing tokens
6
+ routing_keys:
7
+ policy_scan: "ROUTE_TO_POLICY_SCAN"
8
+ policy_evaluate: "ROUTE_TO_POLICY_EVALUATE"
9
+ policy_block: "ROUTE_TO_POLICY_BLOCK"
10
+ policy_report: "ROUTE_TO_POLICY_REPORT"
11
+ end: "ROUTE_TO_END"
12
+
13
+ # Policy enforcement settings (unique to PolicyAgent)
14
+ policy:
15
+ # Security scanning with tfsec
16
+ tfsec:
17
+ enabled: true
18
+ timeout_seconds: 120
19
+ output_format: "json"
20
+ # Block apply on these severity levels
21
+ block_on_severity: ["CRITICAL", "HIGH"]
22
+ # Create artifacts for these severity levels
23
+ artifact_on_severity: ["CRITICAL", "HIGH", "MEDIUM"]
24
+
25
+ # Working directory for policy scans
26
+ working_directory: "/workspace"
27
+
28
+ # Artifact settings
29
+ artifacts:
30
+ # Directory to store policy findings
31
+ output_dir: "/workspace/.policy_findings"
32
+ # JSON artifact filename pattern
33
+ json_filename: "policy_findings_{timestamp}.json"
34
+ # Summary report filename pattern
35
+ summary_filename: "policy_summary_{timestamp}.txt"
36
+
37
+ # Override memory settings for PolicyAgent
38
+ memory:
39
+ max_history: 50
40
+
41
+ logging:
42
+ level: "INFO"
43
+ format: "%(asctime)s - %(name)s - %(levelname)s - %(threadName)s - %(message)s"
@@ -0,0 +1,55 @@
1
+ # SupervisorAgent specific configuration
2
+ # Inherits common settings from src/diagram_to_iac/config.yaml
3
+ # Only agent-specific overrides and unique settings are defined here
4
+
5
+ # Agent-specific routing tokens
6
+ routing_keys:
7
+ clone: "ROUTE_TO_CLONE"
8
+ stack_detect: "ROUTE_TO_STACK_DETECT"
9
+ terraform: "ROUTE_TO_TERRAFORM"
10
+ issue: "ROUTE_TO_ISSUE"
11
+ end: "ROUTE_TO_END"
12
+
13
+ # R2D workflow settings (unique to SupervisorAgent)
14
+ workflow:
15
+ timeout_seconds: 600
16
+ working_directory: "/workspace"
17
+ auto_branch_naming: true
18
+ enhanced_terraform: true
19
+
20
+ # Infrastructure detection patterns (unique to SupervisorAgent)
21
+ stack_patterns:
22
+ terraform: "*.tf"
23
+ ansible: "*.yml"
24
+ powershell: "*.ps1"
25
+ shell: "*.sh"
26
+
27
+ # Routing map for LangGraph nodes (unique to SupervisorAgent)
28
+ routing_map:
29
+ clone_repo_node: "clone_repo_node"
30
+ stack_detect_node: "stack_detect_node"
31
+ terraform_workflow_node: "terraform_workflow_node"
32
+ issue_create_node: "issue_create_node"
33
+
34
+ # Prompt templates
35
+ prompts:
36
+ planner_prompt: |
37
+ User input: "{user_input}"
38
+
39
+ Analyze this R2D (Repo-to-Deployment) request and determine the appropriate action:
40
+
41
+ **COMPLETE R2D WORKFLOW PATTERNS:**
42
+ - If the input contains a repository URL (http/https .git URLs), this is a complete R2D workflow request
43
+ - If requesting "Execute R2D workflow", "Deploy repository", "Process repository", this is a complete workflow
44
+ - For complete workflows, ALWAYS start with "{route_clone}" regardless of other keywords
45
+
46
+ **INDIVIDUAL ACTION PATTERNS:**
47
+ 1. If requesting to clone a repository (keywords: 'clone', 'download', 'git clone'), respond with "{route_clone}"
48
+ 2. If requesting stack detection (keywords: 'detect', 'scan', 'find files', 'infrastructure'), respond with "{route_stack_detect}"
49
+ 3. If requesting Terraform operations (keywords: 'terraform', 'plan', 'apply', 'init'), respond with "{route_terraform}"
50
+ 4. If requesting GitHub issue creation (keywords: 'issue', 'error', 'problem'), respond with "{route_issue}"
51
+ 5. If the request is complete or no action needed, respond with "{route_end}"
52
+
53
+ **IMPORTANT:**
54
+ - Repository URLs (.git, github.com, gitlab.com) = Complete R2D workflow = Start with "{route_clone}"
55
+ - Any mention of "R2D workflow", "execute workflow", "deploy repo" = Complete workflow = Start with "{route_clone}"
@@ -0,0 +1,25 @@
1
+ # TerraformAgent specific configuration
2
+ # Inherits common settings from src/diagram_to_iac/config.yaml
3
+ # Only agent-specific overrides and unique settings are defined here
4
+
5
+ # Agent-specific routing tokens
6
+ routing_keys:
7
+ terraform_init: "ROUTE_TO_TF_INIT"
8
+ terraform_plan: "ROUTE_TO_TF_PLAN"
9
+ terraform_apply: "ROUTE_TO_TF_APPLY"
10
+ open_issue: "ROUTE_TO_OPEN_ISSUE"
11
+ shell_exec: "ROUTE_TO_SHELL_EXEC"
12
+ end: "ROUTE_TO_END"
13
+
14
+ # Terraform-specific settings
15
+ terraform:
16
+ working_directory: "/workspace"
17
+ allowed_commands:
18
+ - "terraform"
19
+ - "init"
20
+ - "plan"
21
+ - "apply"
22
+ - "destroy"
23
+ - "validate"
24
+ - "fmt"
25
+ - "version"
@@ -0,0 +1,253 @@
1
+ # src/diagram_to_iac/config.yaml
2
+ # Central application configuration for diagram-to-iac
3
+ # This file contains common settings shared across agents and tools
4
+ # Individual agent/tool configs can override these values
5
+
6
+ # System settings
7
+ system:
8
+ workspace_base: "/workspace"
9
+ log_level: "INFO"
10
+
11
+ # Network timeouts
12
+ network:
13
+ api_timeout: 10 # Used in api_utils.py for API calls
14
+ shell_timeout: 30 # Used in shell tools
15
+ terraform_timeout: 300 # Used in terraform tools
16
+ github_timeout: 15 # Used in GitHub API calls
17
+ git_timeout: 300 # Used in git operations
18
+
19
+ # AI/LLM settings (common defaults)
20
+ ai:
21
+ default_model: "gpt-4o-mini"
22
+ default_temperature: 0.1 # Most agents use 0.1
23
+ max_tokens: 1000 # Common across agents
24
+
25
+ # Provider selection strategy for intelligent fallback
26
+ provider_selection:
27
+ strategy: "auto" # Options: "auto", "prefer_cost", "prefer_performance", "manual"
28
+ preferred_order: # Provider preference order when strategy is "auto"
29
+ - "openai" # Primary choice - good balance of cost/performance
30
+ - "anthropic" # Secondary - good for reasoning tasks
31
+ - "google" # Tertiary - good for multimodal tasks
32
+ - "grok" # Experimental - not implemented yet
33
+
34
+ # Strategy-specific configurations
35
+ cost_optimization:
36
+ prefer_models:
37
+ - "gpt-4o-mini" # Most cost-effective
38
+ - "gpt-3.5-turbo" # Good performance/cost ratio
39
+ - "claude-3-haiku" # Fast and cheap
40
+ - "gemini-pro" # Google's cost-effective option
41
+
42
+ performance_optimization:
43
+ prefer_models:
44
+ - "gpt-4o" # Best OpenAI performance
45
+ - "claude-3-sonnet" # Best Anthropic reasoning
46
+ - "gpt-4-turbo" # High performance OpenAI
47
+ - "gemini-1.5-pro" # Best Google model
48
+
49
+ # Fallback behavior when all providers fail
50
+ fallback:
51
+ enabled: true
52
+ retry_attempts: 2
53
+ retry_delay_seconds: 1
54
+ default_to_offline: false # If true, gracefully degrade to offline mode
55
+
56
+ # Common memory settings
57
+ memory:
58
+ type: "persistent"
59
+ max_history: 100
60
+
61
+ # Common error handling
62
+ error_handling:
63
+ max_retries: 3
64
+ retry_delay_seconds: 5
65
+ auto_fix_enabled: true
66
+ create_github_issues: true
67
+
68
+ # Common logging
69
+ logging:
70
+ level: "INFO"
71
+ format: "%(asctime)s - %(name)s - %(levelname)s - %(threadName)s - %(message)s"
72
+
73
+ # Route tokens (commonly used across agents)
74
+ routing:
75
+ tokens:
76
+ # Hello agent operations
77
+ addition: "ROUTE_TO_ADDITION"
78
+ multiplication: "ROUTE_TO_MULTIPLICATION"
79
+
80
+ # Git operations
81
+ git_clone: "ROUTE_TO_GIT_CLONE"
82
+ github_cli: "ROUTE_TO_GITHUB_CLI"
83
+ github_issue: "ROUTE_TO_GITHUB_ISSUE"
84
+ shell_exec: "ROUTE_TO_SHELL_EXEC"
85
+ shell: "ROUTE_TO_SHELL"
86
+ create_pr: "ROUTE_TO_CREATE_PR"
87
+
88
+ # Terraform operations
89
+ terraform_init: "ROUTE_TO_TF_INIT"
90
+ terraform_plan: "ROUTE_TO_TF_PLAN"
91
+ terraform_apply: "ROUTE_TO_TF_APPLY"
92
+
93
+ # Supervisor operations
94
+ clone: "ROUTE_TO_CLONE"
95
+ stack_detect: "ROUTE_TO_STACK_DETECT"
96
+ terraform: "ROUTE_TO_TERRAFORM"
97
+ issue: "ROUTE_TO_ISSUE"
98
+
99
+ # Demonstrator operations
100
+ analyze: "ROUTE_TO_ANALYZE"
101
+ demonstrate: "ROUTE_TO_DEMONSTRATE"
102
+ collect_inputs: "ROUTE_TO_COLLECT_INPUTS"
103
+ retry: "ROUTE_TO_RETRY"
104
+
105
+ # Policy operations
106
+ policy_scan: "ROUTE_TO_POLICY_SCAN"
107
+ policy_evaluate: "ROUTE_TO_POLICY_EVALUATE"
108
+ policy_block: "ROUTE_TO_POLICY_BLOCK"
109
+ policy_report: "ROUTE_TO_POLICY_REPORT"
110
+
111
+ # End states
112
+ create_issue: "ROUTE_TO_CREATE_ISSUE"
113
+ open_issue: "ROUTE_TO_OPEN_ISSUE"
114
+ end: "ROUTE_TO_END"
115
+
116
+ # Tool settings (common defaults)
117
+ tools:
118
+ shell:
119
+ allowed_binaries:
120
+ - "terraform"
121
+ - "git"
122
+ - "bash"
123
+ - "sh"
124
+ - "curl"
125
+ - "wget"
126
+ - "jq"
127
+ - "gh"
128
+ - "tfsec"
129
+ - "ls"
130
+ - "find"
131
+ - "wc"
132
+ max_output_size: 8192
133
+ allow_relative_paths: true
134
+ restrict_to_workspace: true
135
+
136
+ git:
137
+ default_clone_depth: 1
138
+ sanitize_repo_names: true
139
+ store_operations_in_memory: true
140
+ remote_name: "origin"
141
+
142
+ terraform:
143
+ allowed_binaries:
144
+ - "terraform"
145
+ - "git"
146
+ - "bash"
147
+ - "sh"
148
+ default_plan_file: "plan.tfplan"
149
+ default_auto_approve: true
150
+ restrict_to_workspace: true
151
+ store_operations_in_memory: true
152
+
153
+ policy:
154
+ tfsec_enabled: true
155
+ block_on_severity: ["CRITICAL", "HIGH"]
156
+ artifact_on_severity: ["CRITICAL", "HIGH", "MEDIUM"]
157
+
158
+ # Agent-specific configurations
159
+ agents:
160
+ policy_agent:
161
+ # Policy enforcement settings
162
+ policy:
163
+ tfsec:
164
+ enabled: true
165
+ timeout_seconds: 120
166
+ output_format: "json"
167
+ block_on_severity: ["CRITICAL", "HIGH"]
168
+ artifact_on_severity: ["CRITICAL", "HIGH", "MEDIUM"]
169
+ working_directory: "/workspace"
170
+ artifacts:
171
+ output_dir: "/workspace/.policy_findings"
172
+ json_filename: "policy_findings_{timestamp}.json"
173
+ summary_filename: "policy_summary_{timestamp}.txt"
174
+
175
+ # Agent-specific routing tokens
176
+ routing_keys:
177
+ policy_scan: "ROUTE_TO_POLICY_SCAN"
178
+ policy_evaluate: "ROUTE_TO_POLICY_EVALUATE"
179
+ policy_block: "ROUTE_TO_POLICY_BLOCK"
180
+ policy_report: "ROUTE_TO_POLICY_REPORT"
181
+ end: "ROUTE_TO_END"
182
+
183
+ # Memory settings
184
+ memory:
185
+ max_history: 50
186
+
187
+ policy:
188
+ tfsec_enabled: true
189
+ block_on_severity:
190
+ - "CRITICAL"
191
+ - "HIGH"
192
+ artifact_on_severity:
193
+ - "CRITICAL"
194
+ - "HIGH"
195
+ - "MEDIUM"
196
+
197
+ # GitHub settings
198
+ github:
199
+ default_assignees: ["team-infra"]
200
+ copilot_assignee: "CopilotUser"
201
+
202
+ # GitHub credentials and repository settings (for tests and development)
203
+ username: "amartyamandal" # GitHub username used in tests and development
204
+ default_repo: "amartyamandal/diagram-to-iac" # Default repository for development
205
+
206
+ # Test configuration
207
+ test:
208
+ # Repository settings for integration tests
209
+ github:
210
+ # Real, accessible test repository that the CI GitHub token has access to
211
+ test_repo_url: "https://github.com/amartyamandal/test_iac_agent_private.git"
212
+ test_repo_owner: "amartyamandal"
213
+ test_repo_name: "test_iac_agent_private"
214
+ # Alternative test repositories for different scenarios
215
+ public_test_repo_url: "https://github.com/amartyamandal/test_iac_agent_public.git"
216
+
217
+ # Test configuration flags
218
+ settings:
219
+ skip_integration_tests_without_token: true
220
+ use_real_github_api: true # Set to true in CI for real integration tests
221
+ mock_network_calls: true # Mock network calls by default for unit tests
222
+
223
+ # Secret management
224
+ security:
225
+ required_secrets:
226
+ - "REPO_API_KEY"
227
+ optional_secrets:
228
+ - "TF_API_KEY"
229
+ - "OPENAI_API_KEY"
230
+ - "GOOGLE_API_KEY"
231
+ - "ANTHROPIC_API_KEY"
232
+ - "GROK_API_KEY"
233
+ - "DOCKERHUB_API_KEY"
234
+ - "DOCKERHUB_USERNAME"
235
+ - "PYPI_API_KEY"
236
+ secret_mappings:
237
+ REPO_API_KEY: "GITHUB_TOKEN"
238
+ TF_API_KEY: "TFE_TOKEN"
239
+
240
+ # Environment variable overrides configuration
241
+ environment_overrides:
242
+ allowed_overrides:
243
+ - "network.api_timeout"
244
+ - "network.shell_timeout"
245
+ - "network.terraform_timeout"
246
+ - "network.github_timeout"
247
+ - "network.git_timeout"
248
+ - "ai.default_model"
249
+ - "ai.default_temperature"
250
+ - "ai.max_tokens"
251
+ - "system.workspace_base"
252
+ - "system.log_level"
253
+ - "logging.level"
@@ -1,4 +1,5 @@
1
1
  import json
2
+ import os
2
3
  from pathlib import Path
3
4
  from typing import Dict, Optional
4
5
 
@@ -7,8 +8,18 @@ class IssueTracker:
7
8
 
8
9
  def __init__(self, file_path: Optional[str] = None):
9
10
  if file_path is None:
10
- base_dir = Path(__file__).resolve().parents[3]
11
- file_path = base_dir / "data" / "db" / "issue_tracker.json"
11
+ # Check environment variable first
12
+ if os.environ.get('ISSUE_TRACKER_FILE'):
13
+ file_path = os.environ['ISSUE_TRACKER_FILE']
14
+ else:
15
+ # Check for workspace-based path first (for containers)
16
+ workspace_base = os.environ.get('WORKSPACE_BASE', '/workspace')
17
+ if os.path.exists(workspace_base):
18
+ base_dir = Path(workspace_base)
19
+ else:
20
+ # Fallback to package-relative path
21
+ base_dir = Path(__file__).resolve().parents[3]
22
+ file_path = base_dir / "data" / "db" / "issue_tracker.json"
12
23
  self.file_path = Path(file_path)
13
24
  self._table: Dict[str, Dict[str, int]] = {}
14
25
  self._load()
@@ -87,12 +87,15 @@ class EnhancedMemory(Memory):
87
87
 
88
88
  # Default path for the persistent agent state JSON file. Allows override via
89
89
  # `AGENT_STATE_FILE` environment variable for testing.
90
- _DEFAULT_AGENT_STATE_PATH = (
91
- Path(__file__).resolve().parents[3]
92
- / "state"
93
- / ".agent_state"
94
- / "agent_state.json"
95
- )
90
+ def _get_default_agent_state_path():
91
+ """Get the default agent state path, checking workspace first."""
92
+ workspace_base = os.environ.get('WORKSPACE_BASE', '/workspace')
93
+ if os.path.exists(workspace_base):
94
+ return Path(workspace_base) / "data" / "state" / "agent_state.json"
95
+ else:
96
+ return Path(__file__).resolve().parents[3] / "state" / ".agent_state" / "agent_state.json"
97
+
98
+ _DEFAULT_AGENT_STATE_PATH = _get_default_agent_state_path()
96
99
  AGENT_STATE_PATH = Path(os.environ.get("AGENT_STATE_FILE", _DEFAULT_AGENT_STATE_PATH))
97
100
 
98
101