atomicguard 0.1.0__py3-none-any.whl → 1.2.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.
Files changed (37) hide show
  1. atomicguard/__init__.py +8 -3
  2. atomicguard/application/action_pair.py +7 -1
  3. atomicguard/application/agent.py +46 -6
  4. atomicguard/application/workflow.py +494 -11
  5. atomicguard/domain/__init__.py +4 -1
  6. atomicguard/domain/exceptions.py +19 -0
  7. atomicguard/domain/interfaces.py +137 -6
  8. atomicguard/domain/models.py +120 -6
  9. atomicguard/guards/__init__.py +16 -5
  10. atomicguard/guards/composite/__init__.py +11 -0
  11. atomicguard/guards/dynamic/__init__.py +13 -0
  12. atomicguard/guards/dynamic/test_runner.py +207 -0
  13. atomicguard/guards/interactive/__init__.py +11 -0
  14. atomicguard/guards/static/__init__.py +13 -0
  15. atomicguard/guards/static/imports.py +177 -0
  16. atomicguard/infrastructure/__init__.py +4 -1
  17. atomicguard/infrastructure/llm/__init__.py +3 -1
  18. atomicguard/infrastructure/llm/huggingface.py +180 -0
  19. atomicguard/infrastructure/llm/mock.py +32 -6
  20. atomicguard/infrastructure/llm/ollama.py +40 -17
  21. atomicguard/infrastructure/persistence/__init__.py +7 -1
  22. atomicguard/infrastructure/persistence/checkpoint.py +361 -0
  23. atomicguard/infrastructure/persistence/filesystem.py +69 -5
  24. atomicguard/infrastructure/persistence/memory.py +25 -3
  25. atomicguard/infrastructure/registry.py +126 -0
  26. atomicguard/schemas/__init__.py +142 -0
  27. {atomicguard-0.1.0.dist-info → atomicguard-1.2.0.dist-info}/METADATA +75 -13
  28. atomicguard-1.2.0.dist-info/RECORD +37 -0
  29. {atomicguard-0.1.0.dist-info → atomicguard-1.2.0.dist-info}/WHEEL +1 -1
  30. atomicguard-1.2.0.dist-info/entry_points.txt +4 -0
  31. atomicguard/guards/test_runner.py +0 -176
  32. atomicguard-0.1.0.dist-info/RECORD +0 -27
  33. /atomicguard/guards/{base.py → composite/base.py} +0 -0
  34. /atomicguard/guards/{human.py → interactive/human.py} +0 -0
  35. /atomicguard/guards/{syntax.py → static/syntax.py} +0 -0
  36. {atomicguard-0.1.0.dist-info → atomicguard-1.2.0.dist-info}/licenses/LICENSE +0 -0
  37. {atomicguard-0.1.0.dist-info → atomicguard-1.2.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,142 @@
1
+ """AtomicGuard JSON Schema definitions and validation utilities.
2
+
3
+ This module provides JSON Schema definitions for AtomicGuard configuration files,
4
+ aligned with the formal framework defined in the paper.
5
+
6
+ Schemas:
7
+ - workflow.schema.json: Workflow definition (action pairs, guards, preconditions)
8
+ - prompts.schema.json: Prompt templates for generators
9
+ - artifact.schema.json: Artifact storage format in DAG
10
+
11
+ Usage:
12
+ from atomicguard.schemas import validate_workflow, validate_prompts
13
+
14
+ # Validate a workflow configuration
15
+ with open("workflow.json") as f:
16
+ data = json.load(f)
17
+ validate_workflow(data) # Raises jsonschema.ValidationError if invalid
18
+ """
19
+
20
+ from __future__ import annotations
21
+
22
+ import json
23
+ from importlib.resources import files
24
+ from typing import TYPE_CHECKING, Any
25
+
26
+ if TYPE_CHECKING:
27
+ import types
28
+
29
+ try:
30
+ import jsonschema as _jsonschema
31
+
32
+ jsonschema: types.ModuleType | None = _jsonschema
33
+ except ImportError:
34
+ jsonschema = None
35
+
36
+
37
+ def _load_schema(name: str) -> dict[str, Any]:
38
+ """Load a JSON schema from the schemas package.
39
+
40
+ Args:
41
+ name: Schema filename (e.g., 'workflow.schema.json')
42
+
43
+ Returns:
44
+ Parsed JSON schema as a dictionary
45
+ """
46
+ schema_text = files("atomicguard.schemas").joinpath(name).read_text()
47
+ result: dict[str, Any] = json.loads(schema_text)
48
+ return result
49
+
50
+
51
+ def get_workflow_schema() -> dict[str, Any]:
52
+ """Get the workflow.json schema.
53
+
54
+ Returns:
55
+ JSON Schema for workflow configuration
56
+ """
57
+ return _load_schema("workflow.schema.json")
58
+
59
+
60
+ def get_prompts_schema() -> dict[str, Any]:
61
+ """Get the prompts.json schema.
62
+
63
+ Returns:
64
+ JSON Schema for prompt templates
65
+ """
66
+ return _load_schema("prompts.schema.json")
67
+
68
+
69
+ def get_artifact_schema() -> dict[str, Any]:
70
+ """Get the artifact.json schema.
71
+
72
+ Returns:
73
+ JSON Schema for artifact storage
74
+ """
75
+ return _load_schema("artifact.schema.json")
76
+
77
+
78
+ def validate_workflow(data: dict[str, Any]) -> None:
79
+ """Validate a workflow configuration against the schema.
80
+
81
+ Args:
82
+ data: Workflow configuration dictionary
83
+
84
+ Raises:
85
+ jsonschema.ValidationError: If validation fails
86
+ ImportError: If jsonschema is not installed
87
+ """
88
+ if jsonschema is None:
89
+ raise ImportError(
90
+ "jsonschema is required for validation. "
91
+ "Install it with: pip install jsonschema"
92
+ )
93
+ schema = get_workflow_schema()
94
+ jsonschema.validate(data, schema)
95
+
96
+
97
+ def validate_prompts(data: dict[str, Any]) -> None:
98
+ """Validate prompt templates against the schema.
99
+
100
+ Args:
101
+ data: Prompts configuration dictionary
102
+
103
+ Raises:
104
+ jsonschema.ValidationError: If validation fails
105
+ ImportError: If jsonschema is not installed
106
+ """
107
+ if jsonschema is None:
108
+ raise ImportError(
109
+ "jsonschema is required for validation. "
110
+ "Install it with: pip install jsonschema"
111
+ )
112
+ schema = get_prompts_schema()
113
+ jsonschema.validate(data, schema)
114
+
115
+
116
+ def validate_artifact(data: dict[str, Any]) -> None:
117
+ """Validate an artifact against the schema.
118
+
119
+ Args:
120
+ data: Artifact dictionary
121
+
122
+ Raises:
123
+ jsonschema.ValidationError: If validation fails
124
+ ImportError: If jsonschema is not installed
125
+ """
126
+ if jsonschema is None:
127
+ raise ImportError(
128
+ "jsonschema is required for validation. "
129
+ "Install it with: pip install jsonschema"
130
+ )
131
+ schema = get_artifact_schema()
132
+ jsonschema.validate(data, schema)
133
+
134
+
135
+ __all__ = [
136
+ "get_workflow_schema",
137
+ "get_prompts_schema",
138
+ "get_artifact_schema",
139
+ "validate_workflow",
140
+ "validate_prompts",
141
+ "validate_artifact",
142
+ ]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: atomicguard
3
- Version: 0.1.0
3
+ Version: 1.2.0
4
4
  Summary: A Dual-State Agent Framework for reliable LLM code generation with guard-validated loops
5
5
  Author-email: Matthew Thompson <thompsonson@gmail.com>
6
6
  Maintainer-email: Matthew Thompson <thompsonson@gmail.com>
@@ -26,17 +26,10 @@ Classifier: Typing :: Typed
26
26
  Requires-Python: >=3.12
27
27
  Description-Content-Type: text/markdown
28
28
  License-File: LICENSE
29
- Requires-Dist: click>=8.3.1
30
29
  Requires-Dist: matplotlib>=3.10.0
31
- Requires-Dist: openai>=2.12.0
32
- Requires-Dist: rich>=14.0.0
33
- Provides-Extra: dev
34
- Requires-Dist: mypy>=1.13.0; extra == "dev"
35
- Requires-Dist: pre-commit>=4.5.0; extra == "dev"
36
- Requires-Dist: ruff>=0.14.0; extra == "dev"
37
- Provides-Extra: test
38
- Requires-Dist: pytest>=8.0.0; extra == "test"
39
- Requires-Dist: pytest-cov>=6.0.0; extra == "test"
30
+ Requires-Dist: openhands-ai>=0.27.0
31
+ Requires-Dist: pydantic-ai>=1.0.0
32
+ Requires-Dist: pytestarch>=4.0.1
40
33
  Dynamic: license-file
41
34
 
42
35
  # AtomicGuard
@@ -100,6 +93,67 @@ print(artifact.content)
100
93
 
101
94
  See [examples/](examples/) for more detailed usage, including a [mock example](examples/basic_mock.py) that works without an LLM.
102
95
 
96
+ ## LLM Backends
97
+
98
+ AtomicGuard supports multiple LLM backends. Each generator implements `GeneratorInterface` and can be swapped in with no other code changes.
99
+
100
+ ### Ollama (local or cloud)
101
+
102
+ Uses the OpenAI-compatible API. Works with any Ollama-served model:
103
+
104
+ ```python
105
+ from atomicguard.infrastructure.llm import OllamaGenerator
106
+
107
+ # Local instance (default: http://localhost:11434/v1)
108
+ generator = OllamaGenerator(model="qwen2.5-coder:7b")
109
+ ```
110
+
111
+ ### HuggingFace Inference API
112
+
113
+ Connects to HuggingFace Inference Providers via `huggingface_hub`. Supports any model available through the HF Inference API, including third-party providers like Together AI.
114
+
115
+ ```bash
116
+ # Install the optional dependency
117
+ pip install huggingface_hub
118
+
119
+ # Set your API token
120
+ export HF_TOKEN="hf_your_token_here"
121
+ ```
122
+
123
+ ```python
124
+ from atomicguard.infrastructure.llm import HuggingFaceGenerator
125
+ from atomicguard.infrastructure.llm.huggingface import HuggingFaceGeneratorConfig
126
+
127
+ # Default: Qwen/Qwen2.5-Coder-32B-Instruct
128
+ generator = HuggingFaceGenerator()
129
+
130
+ # Custom model and provider
131
+ generator = HuggingFaceGenerator(HuggingFaceGeneratorConfig(
132
+ model="Qwen/Qwen2.5-Coder-32B-Instruct",
133
+ provider="together", # or "auto", "hf-inference"
134
+ temperature=0.7,
135
+ max_tokens=4096,
136
+ ))
137
+ ```
138
+
139
+ Drop-in replacement in any workflow:
140
+
141
+ ```python
142
+ from atomicguard import (
143
+ SyntaxGuard, TestGuard, CompositeGuard,
144
+ ActionPair, DualStateAgent, InMemoryArtifactDAG
145
+ )
146
+ from atomicguard.infrastructure.llm import HuggingFaceGenerator
147
+
148
+ generator = HuggingFaceGenerator()
149
+ guard = CompositeGuard([SyntaxGuard(), TestGuard("assert add(2, 3) == 5")])
150
+ action_pair = ActionPair(generator=generator, guard=guard)
151
+ agent = DualStateAgent(action_pair, InMemoryArtifactDAG(), rmax=3)
152
+
153
+ artifact = agent.execute("Write a function that adds two numbers")
154
+ print(artifact.content)
155
+ ```
156
+
103
157
  ## Benchmarks
104
158
 
105
159
  Run the simulation from the paper:
@@ -124,11 +178,19 @@ atomicguard/
124
178
 
125
179
  ## Citation
126
180
 
181
+ If you use this framework in your research, please cite the paper:
182
+
183
+ > Thompson, M. (2025). Managing the Stochastic: Foundations of Learning in Neuro-Symbolic Systems for Software Engineering. arXiv preprint arXiv:2512.20660.
184
+
127
185
  ```bibtex
128
- @article{thompson2025managing,
186
+ @misc{thompson2025managing,
129
187
  title={Managing the Stochastic: Foundations of Learning in Neuro-Symbolic Systems for Software Engineering},
130
188
  author={Thompson, Matthew},
131
- year={2025}
189
+ year={2025},
190
+ eprint={2512.20660},
191
+ archivePrefix={arXiv},
192
+ primaryClass={cs.LG},
193
+ url={https://arxiv.org/abs/2512.20660}
132
194
  }
133
195
  ```
134
196
 
@@ -0,0 +1,37 @@
1
+ atomicguard/__init__.py,sha256=vW_pYf3hdmq4rgIYWc0319HMUAB-JkeraoqEdFIe--U,3051
2
+ atomicguard/application/__init__.py,sha256=-myJt7VuC1tMjO424NhjY6iZZuUdHGnFCJKFapFCAhw,409
3
+ atomicguard/application/action_pair.py,sha256=JfQH88gTZCMl5qa5frqLJnhebn-KgO_oGAol6sD58ys,2214
4
+ atomicguard/application/agent.py,sha256=ND2_pnRGwcWM5MovM8dnratrMph2gz9UmwXEgTeA59s,5907
5
+ atomicguard/application/workflow.py,sha256=mfWz2pdBqQsGC5rBZ5S1x_jaNe2aLvqoG20TvWyAsnM,23309
6
+ atomicguard/domain/__init__.py,sha256=BRmYKYFU-kLG1wPpRrXKxZ2jb4QgMea83r0gbDX_Da0,1149
7
+ atomicguard/domain/exceptions.py,sha256=Zj1iz31AiksyWnyKR8KfnNLRGhZdetrYhCIwFOapBtY,1376
8
+ atomicguard/domain/interfaces.py,sha256=73vRiPzTLkVAiBc2srn-EUNFSQfleooQNx6r3odIQFM,6574
9
+ atomicguard/domain/models.py,sha256=sVuHzuP98pgHefTz1mk1bYptgoeAySekRyBG2zMz7TE,8496
10
+ atomicguard/domain/prompts.py,sha256=SMGcP0kYc9azCbGku5EG0JZZs83D80WkJO-DWiuFV58,2785
11
+ atomicguard/guards/__init__.py,sha256=OzpOjwmyHGpTQSDVSDeGEuXUJNOyiNpZxZVnTVMIOyg,956
12
+ atomicguard/guards/composite/__init__.py,sha256=AedlMBxFw4uTFExVWL6RJRR7vRwMOK3sgjhutkXz838,217
13
+ atomicguard/guards/composite/base.py,sha256=VGydlOD4gmXdiDHvWXF5jSppXcJAoJYSCyDj7Lrbng0,1213
14
+ atomicguard/guards/dynamic/__init__.py,sha256=pjBBeD_yYavvn-I7s5I3nTDOlZtPTq1Hqmim_RgW5cE,321
15
+ atomicguard/guards/dynamic/test_runner.py,sha256=d5cPb5cCM-UnfZjTYGOHn4XoS-N66nr5EBHqPoDGwNM,7196
16
+ atomicguard/guards/interactive/__init__.py,sha256=PlP5LNB4CMZ4fJ7Xr8gjjpn8VwLnB3zs5M2Em9xyVCc,226
17
+ atomicguard/guards/interactive/human.py,sha256=G8SstAEdcMpHR2b8ugyG9drk9aBjw4_pE6E4UrTtcUo,2960
18
+ atomicguard/guards/static/__init__.py,sha256=KANeEg_yhrKGzSmA0yf2SewOE9qkUwnJly4mWkBzsm4,305
19
+ atomicguard/guards/static/imports.py,sha256=nWS3FNNqle7YWU5_tgRgYMRAXwEcWlxee8Q4MdomN5w,6292
20
+ atomicguard/guards/static/syntax.py,sha256=mPVgGDY3pzwtXuulmmuEwYAQG7rNG0fgSGB1puYRI6Y,919
21
+ atomicguard/infrastructure/__init__.py,sha256=Y3Ot6sRgTind-8s5kCnNtRYJGN3uq84QmbAUESx8Pio,581
22
+ atomicguard/infrastructure/registry.py,sha256=XilDY2sUedwm5z1Xrp39HfQ9e3paixyJxL_hwGaVbqs,3662
23
+ atomicguard/infrastructure/llm/__init__.py,sha256=wQg_FCAHmwbDXWm0bF5WX-9v7sutAS7RabhHCGiZZzo,338
24
+ atomicguard/infrastructure/llm/huggingface.py,sha256=8VpkjuIzxAKOj3C6OBufS394AuDtbhreuPNv1rm-qJg,5756
25
+ atomicguard/infrastructure/llm/mock.py,sha256=883Y7e2Q1yWapvp3rXn03bHEvuRnFwDe0CZsTZziG_E,2639
26
+ atomicguard/infrastructure/llm/ollama.py,sha256=pLSZX_X5U1aPvIxCsF_wsQ_AHsTspqU3xkYHWLbgJQ0,4832
27
+ atomicguard/infrastructure/persistence/__init__.py,sha256=KS95wmO_qVF6It63_884lWDoa-IB0WvRma_nXS2uTq4,483
28
+ atomicguard/infrastructure/persistence/checkpoint.py,sha256=MS4qpJ_jcl6Ibw7h3KncWgDqz7CEIlFJdrpFcu2vEgs,13966
29
+ atomicguard/infrastructure/persistence/filesystem.py,sha256=4upoycWCOlWRoSlVm4Ux_Kj8r3hX3Nm8N80x-IfBSLw,11440
30
+ atomicguard/infrastructure/persistence/memory.py,sha256=JTnTwXSKYYDnQEYbjwAFVpklZVAlQlCDIt9zxcQjlz0,2042
31
+ atomicguard/schemas/__init__.py,sha256=9z3gWBHsq8FHD2qE_TPy31wkTa_qXPfVgJrNdIu8p4g,3735
32
+ atomicguard-1.2.0.dist-info/licenses/LICENSE,sha256=ROMMFVruZ18U24pKTNte9AK_YIqoMfXnMzoxqBNmKS4,1073
33
+ atomicguard-1.2.0.dist-info/METADATA,sha256=slCf2YR0p3mYoZR2XnP96NUdCiD-qr5tLgMGo-LU4jk,6831
34
+ atomicguard-1.2.0.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
35
+ atomicguard-1.2.0.dist-info/entry_points.txt,sha256=MMVrkEyWFFCMoNIlpSWRY9FJYlEMGmaauvzMxEjwzTI,226
36
+ atomicguard-1.2.0.dist-info/top_level.txt,sha256=J_6ENELjnacSYJ5N3FGwomp-sVeAJQohPkJBh6pu6iY,12
37
+ atomicguard-1.2.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.9.0)
2
+ Generator: setuptools (80.10.2)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -0,0 +1,4 @@
1
+ [atomicguard.generators]
2
+ HuggingFaceGenerator = atomicguard.infrastructure.llm:HuggingFaceGenerator
3
+ MockGenerator = atomicguard.infrastructure.llm:MockGenerator
4
+ OllamaGenerator = atomicguard.infrastructure.llm:OllamaGenerator
@@ -1,176 +0,0 @@
1
- """
2
- Test execution guards.
3
-
4
- Guards that validate artifacts by running tests against them.
5
- """
6
-
7
- import multiprocessing
8
- import sys
9
- import types
10
- from typing import Any
11
-
12
- from atomicguard.domain.interfaces import GuardInterface
13
- from atomicguard.domain.models import Artifact, GuardResult
14
-
15
-
16
- class TestGuard(GuardInterface):
17
- """
18
- Validates artifact via test execution in the same process.
19
-
20
- Simple guard that executes test code against artifact content.
21
- For isolation, use DynamicTestGuard instead.
22
- """
23
-
24
- def __init__(self, test_code: str | None = None):
25
- """
26
- Args:
27
- test_code: Static test code to run (if not using dependencies)
28
- """
29
- self._static_test_code = test_code
30
-
31
- def validate(self, artifact: Artifact, **deps: Any) -> GuardResult:
32
- """
33
- Execute test code against artifact.
34
-
35
- Args:
36
- artifact: The implementation artifact to test
37
- **deps: May include 'test' artifact with test code
38
-
39
- Returns:
40
- GuardResult with test outcome
41
- """
42
- test_artifact = deps.get("test")
43
- test_code = test_artifact.content if test_artifact else self._static_test_code
44
-
45
- if not test_code:
46
- return GuardResult(passed=False, feedback="No test code provided")
47
-
48
- namespace: dict[str, Any] = {}
49
- try:
50
- exec(artifact.content, namespace)
51
- exec(test_code, namespace)
52
- return GuardResult(passed=True)
53
- except AssertionError as e:
54
- return GuardResult(passed=False, feedback=f"Test failed: {e}")
55
- except Exception as e:
56
- return GuardResult(passed=False, feedback=f"{type(e).__name__}: {e}")
57
-
58
-
59
- class DynamicTestGuard(GuardInterface):
60
- """
61
- Runs test code against implementation in isolated subprocess.
62
-
63
- Expects 'test' dependency containing the test artifact.
64
- Executes tests and returns pass/fail with detailed feedback.
65
-
66
- Uses multiprocessing for isolation to prevent test code from
67
- affecting the parent process.
68
- """
69
-
70
- def __init__(self, timeout: float = 60.0):
71
- """
72
- Args:
73
- timeout: Maximum time in seconds to wait for test execution
74
- """
75
- self.timeout = timeout
76
-
77
- def validate(self, artifact: Artifact, **deps: Any) -> GuardResult:
78
- """
79
- Run tests in isolated subprocess.
80
-
81
- Args:
82
- artifact: The implementation artifact to test
83
- **deps: Must include 'test' artifact with test code
84
-
85
- Returns:
86
- GuardResult with test outcome
87
- """
88
- test_artifact = deps.get("test")
89
- if not test_artifact:
90
- return GuardResult(
91
- passed=False, feedback="No test artifact in dependencies"
92
- )
93
-
94
- q: multiprocessing.Queue = multiprocessing.Queue()
95
- p = multiprocessing.Process(
96
- target=self._run_tests, args=(artifact, test_artifact, q)
97
- )
98
- p.start()
99
- p.join(self.timeout)
100
-
101
- if p.is_alive():
102
- p.terminate()
103
- p.join()
104
- return GuardResult(
105
- passed=False,
106
- feedback=f"Timeout: Test execution exceeded {self.timeout}s",
107
- )
108
-
109
- if not q.empty():
110
- passed, msg = q.get()
111
- return GuardResult(passed=passed, feedback=msg)
112
- return GuardResult(passed=False, feedback="Test execution crashed")
113
-
114
- def _run_tests(
115
- self, impl_artifact: Artifact, test_artifact: Artifact, q: Any
116
- ) -> None:
117
- """
118
- Execute tests in subprocess.
119
-
120
- This method runs in a forked process for isolation.
121
- """
122
- try:
123
- impl_code = impl_artifact.content
124
- test_code = test_artifact.content
125
-
126
- if not impl_code:
127
- q.put((False, "No implementation code"))
128
- return
129
-
130
- if not test_code:
131
- q.put((False, "No test code"))
132
- return
133
-
134
- # Create mock 'implementation' module
135
- impl_module = types.ModuleType("implementation")
136
- exec(impl_code, impl_module.__dict__)
137
- sys.modules["implementation"] = impl_module
138
-
139
- # Execute test code (pytest already in sys.modules from parent)
140
- import pytest
141
-
142
- test_scope = {"__builtins__": __builtins__, "pytest": pytest}
143
- exec(test_code, test_scope)
144
-
145
- # Find and run test functions
146
- test_funcs = [
147
- v
148
- for k, v in test_scope.items()
149
- if k.startswith("test_") and callable(v)
150
- ]
151
-
152
- if not test_funcs:
153
- q.put((False, "No test functions found"))
154
- return
155
-
156
- failures = []
157
- for func in test_funcs:
158
- try:
159
- func()
160
- except AssertionError as e:
161
- failures.append(f"{func.__name__}: AssertionError - {e}")
162
- except Exception as e:
163
- failures.append(f"{func.__name__}: {type(e).__name__} - {e}")
164
-
165
- if failures:
166
- q.put((False, "Test failures:\n" + "\n".join(failures)))
167
- else:
168
- q.put((True, f"All {len(test_funcs)} tests passed"))
169
-
170
- except SyntaxError as e:
171
- q.put((False, f"Syntax error: {e}"))
172
- except Exception as e:
173
- q.put((False, f"Execution error: {e}"))
174
- finally:
175
- if "implementation" in sys.modules:
176
- del sys.modules["implementation"]
@@ -1,27 +0,0 @@
1
- atomicguard/__init__.py,sha256=kiNxqjbVSlSf6Z0U7wpus3o_eMTB7M5-Dj41qgcgUwI,2927
2
- atomicguard/application/__init__.py,sha256=-myJt7VuC1tMjO424NhjY6iZZuUdHGnFCJKFapFCAhw,409
3
- atomicguard/application/action_pair.py,sha256=pa9gw4cTb8HaZLT_VqjQaKVMGGllo0BcDf6YzqsJlnA,1959
4
- atomicguard/application/agent.py,sha256=uzwhrn43JkrK1xxuw8ETvjL4IAiVZ1_Jeik4tMY_2ZE,4254
5
- atomicguard/application/workflow.py,sha256=CPnLVaten4hN4fiC_gGMvN9-BCJIVVwYsQb3HtRTlJg,4902
6
- atomicguard/domain/__init__.py,sha256=z7CWqBs21XsZPLeuqLD1fNQVtl9VxIs3zkrK_1n4uD0,1061
7
- atomicguard/domain/exceptions.py,sha256=3L1acckIcf0XewBy8QJpzgCRBaKyYdossbIAikt1Xkw,770
8
- atomicguard/domain/interfaces.py,sha256=3kPXRof0a-4c225d1DgZ_66_5A6P8H1XZK-gTp9YkCI,2935
9
- atomicguard/domain/models.py,sha256=p9FqB9MdriV7djaGUkREGEgkcWyhGvpYmHYrLq2VX-w,4483
10
- atomicguard/domain/prompts.py,sha256=SMGcP0kYc9azCbGku5EG0JZZs83D80WkJO-DWiuFV58,2785
11
- atomicguard/guards/__init__.py,sha256=pd4H3sfnrN76vKBX3KrXWsoe27V5vNacSEUKW9uIbmM,548
12
- atomicguard/guards/base.py,sha256=VGydlOD4gmXdiDHvWXF5jSppXcJAoJYSCyDj7Lrbng0,1213
13
- atomicguard/guards/human.py,sha256=G8SstAEdcMpHR2b8ugyG9drk9aBjw4_pE6E4UrTtcUo,2960
14
- atomicguard/guards/syntax.py,sha256=mPVgGDY3pzwtXuulmmuEwYAQG7rNG0fgSGB1puYRI6Y,919
15
- atomicguard/guards/test_runner.py,sha256=dIFtyOXxu_dxKDlrsBl_G7kCR5oy5gLQESQtYGslKO4,5538
16
- atomicguard/infrastructure/__init__.py,sha256=98eYKEgEIzJ05Z5r82M7tB0S0QGD2PrfPR_8wapzfHA,465
17
- atomicguard/infrastructure/llm/__init__.py,sha256=lmr-cYVeaiAsMi_DWcoM7G1wEs6Y6GS02RZeOs4GI-U,234
18
- atomicguard/infrastructure/llm/mock.py,sha256=OVumDkWYe9xU8KQHdt79evpHzIJIRRxXIqeC9fgI-hQ,1840
19
- atomicguard/infrastructure/llm/ollama.py,sha256=jtE3SXfMSsYUDocuKXDH3H4NrR8cMwjvCpSFkn99Xlg,4019
20
- atomicguard/infrastructure/persistence/__init__.py,sha256=DdoD0V-uCetJDo_RJRPiCfjae3xAX5yofnQWbalBrJw,285
21
- atomicguard/infrastructure/persistence/filesystem.py,sha256=LpdExc9FAwB2Od8eM5zSEMx4hC4Lx2AaztJdba8_MD0,8638
22
- atomicguard/infrastructure/persistence/memory.py,sha256=gZo2hcpi5VOu60nscxPnyQBDg8P87MI9ZXBdaW0eebQ,1339
23
- atomicguard-0.1.0.dist-info/licenses/LICENSE,sha256=ROMMFVruZ18U24pKTNte9AK_YIqoMfXnMzoxqBNmKS4,1073
24
- atomicguard-0.1.0.dist-info/METADATA,sha256=yJlnBW1n_-4ORhWkIjTOykpD9vf6N9OHzO4mJIh39lc,4919
25
- atomicguard-0.1.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
26
- atomicguard-0.1.0.dist-info/top_level.txt,sha256=J_6ENELjnacSYJ5N3FGwomp-sVeAJQohPkJBh6pu6iY,12
27
- atomicguard-0.1.0.dist-info/RECORD,,
File without changes
File without changes
File without changes