yamlgraph 0.3.9__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 (185) hide show
  1. examples/__init__.py +1 -0
  2. examples/codegen/__init__.py +5 -0
  3. examples/codegen/models/__init__.py +13 -0
  4. examples/codegen/models/schemas.py +76 -0
  5. examples/codegen/tests/__init__.py +1 -0
  6. examples/codegen/tests/test_ai_helpers.py +235 -0
  7. examples/codegen/tests/test_ast_analysis.py +174 -0
  8. examples/codegen/tests/test_code_analysis.py +134 -0
  9. examples/codegen/tests/test_code_context.py +301 -0
  10. examples/codegen/tests/test_code_nav.py +89 -0
  11. examples/codegen/tests/test_dependency_tools.py +119 -0
  12. examples/codegen/tests/test_example_tools.py +185 -0
  13. examples/codegen/tests/test_git_tools.py +112 -0
  14. examples/codegen/tests/test_impl_agent_schemas.py +193 -0
  15. examples/codegen/tests/test_impl_agent_v4_graph.py +94 -0
  16. examples/codegen/tests/test_jedi_analysis.py +226 -0
  17. examples/codegen/tests/test_meta_tools.py +250 -0
  18. examples/codegen/tests/test_plan_discovery_prompt.py +98 -0
  19. examples/codegen/tests/test_syntax_tools.py +85 -0
  20. examples/codegen/tests/test_synthesize_prompt.py +94 -0
  21. examples/codegen/tests/test_template_tools.py +244 -0
  22. examples/codegen/tools/__init__.py +80 -0
  23. examples/codegen/tools/ai_helpers.py +420 -0
  24. examples/codegen/tools/ast_analysis.py +92 -0
  25. examples/codegen/tools/code_context.py +180 -0
  26. examples/codegen/tools/code_nav.py +52 -0
  27. examples/codegen/tools/dependency_tools.py +120 -0
  28. examples/codegen/tools/example_tools.py +188 -0
  29. examples/codegen/tools/git_tools.py +151 -0
  30. examples/codegen/tools/impl_executor.py +614 -0
  31. examples/codegen/tools/jedi_analysis.py +311 -0
  32. examples/codegen/tools/meta_tools.py +202 -0
  33. examples/codegen/tools/syntax_tools.py +26 -0
  34. examples/codegen/tools/template_tools.py +356 -0
  35. examples/fastapi_interview.py +167 -0
  36. examples/npc/api/__init__.py +1 -0
  37. examples/npc/api/app.py +100 -0
  38. examples/npc/api/routes/__init__.py +5 -0
  39. examples/npc/api/routes/encounter.py +182 -0
  40. examples/npc/api/session.py +330 -0
  41. examples/npc/demo.py +387 -0
  42. examples/npc/nodes/__init__.py +5 -0
  43. examples/npc/nodes/image_node.py +92 -0
  44. examples/npc/run_encounter.py +230 -0
  45. examples/shared/__init__.py +0 -0
  46. examples/shared/replicate_tool.py +238 -0
  47. examples/storyboard/__init__.py +1 -0
  48. examples/storyboard/generate_videos.py +335 -0
  49. examples/storyboard/nodes/__init__.py +12 -0
  50. examples/storyboard/nodes/animated_character_node.py +248 -0
  51. examples/storyboard/nodes/animated_image_node.py +138 -0
  52. examples/storyboard/nodes/character_node.py +162 -0
  53. examples/storyboard/nodes/image_node.py +118 -0
  54. examples/storyboard/nodes/replicate_tool.py +49 -0
  55. examples/storyboard/retry_images.py +118 -0
  56. scripts/demo_async_executor.py +212 -0
  57. scripts/demo_interview_e2e.py +200 -0
  58. scripts/demo_streaming.py +140 -0
  59. scripts/run_interview_demo.py +94 -0
  60. scripts/test_interrupt_fix.py +26 -0
  61. tests/__init__.py +1 -0
  62. tests/conftest.py +178 -0
  63. tests/integration/__init__.py +1 -0
  64. tests/integration/test_animated_storyboard.py +63 -0
  65. tests/integration/test_cli_commands.py +242 -0
  66. tests/integration/test_colocated_prompts.py +139 -0
  67. tests/integration/test_map_demo.py +50 -0
  68. tests/integration/test_memory_demo.py +283 -0
  69. tests/integration/test_npc_api/__init__.py +1 -0
  70. tests/integration/test_npc_api/test_routes.py +357 -0
  71. tests/integration/test_npc_api/test_session.py +216 -0
  72. tests/integration/test_pipeline_flow.py +105 -0
  73. tests/integration/test_providers.py +163 -0
  74. tests/integration/test_resume.py +75 -0
  75. tests/integration/test_subgraph_integration.py +295 -0
  76. tests/integration/test_subgraph_interrupt.py +106 -0
  77. tests/unit/__init__.py +1 -0
  78. tests/unit/test_agent_nodes.py +355 -0
  79. tests/unit/test_async_executor.py +346 -0
  80. tests/unit/test_checkpointer.py +212 -0
  81. tests/unit/test_checkpointer_factory.py +212 -0
  82. tests/unit/test_cli.py +121 -0
  83. tests/unit/test_cli_package.py +81 -0
  84. tests/unit/test_compile_graph_map.py +132 -0
  85. tests/unit/test_conditions_routing.py +253 -0
  86. tests/unit/test_config.py +93 -0
  87. tests/unit/test_conversation_memory.py +276 -0
  88. tests/unit/test_database.py +145 -0
  89. tests/unit/test_deprecation.py +104 -0
  90. tests/unit/test_executor.py +172 -0
  91. tests/unit/test_executor_async.py +179 -0
  92. tests/unit/test_export.py +149 -0
  93. tests/unit/test_expressions.py +178 -0
  94. tests/unit/test_feature_brainstorm.py +194 -0
  95. tests/unit/test_format_prompt.py +145 -0
  96. tests/unit/test_generic_report.py +200 -0
  97. tests/unit/test_graph_commands.py +327 -0
  98. tests/unit/test_graph_linter.py +627 -0
  99. tests/unit/test_graph_loader.py +357 -0
  100. tests/unit/test_graph_schema.py +193 -0
  101. tests/unit/test_inline_schema.py +151 -0
  102. tests/unit/test_interrupt_node.py +182 -0
  103. tests/unit/test_issues.py +164 -0
  104. tests/unit/test_jinja2_prompts.py +85 -0
  105. tests/unit/test_json_extract.py +134 -0
  106. tests/unit/test_langsmith.py +600 -0
  107. tests/unit/test_langsmith_tools.py +204 -0
  108. tests/unit/test_llm_factory.py +109 -0
  109. tests/unit/test_llm_factory_async.py +118 -0
  110. tests/unit/test_loops.py +403 -0
  111. tests/unit/test_map_node.py +144 -0
  112. tests/unit/test_no_backward_compat.py +56 -0
  113. tests/unit/test_node_factory.py +348 -0
  114. tests/unit/test_passthrough_node.py +126 -0
  115. tests/unit/test_prompts.py +324 -0
  116. tests/unit/test_python_nodes.py +198 -0
  117. tests/unit/test_reliability.py +298 -0
  118. tests/unit/test_result_export.py +234 -0
  119. tests/unit/test_router.py +296 -0
  120. tests/unit/test_sanitize.py +99 -0
  121. tests/unit/test_schema_loader.py +295 -0
  122. tests/unit/test_shell_tools.py +229 -0
  123. tests/unit/test_state_builder.py +331 -0
  124. tests/unit/test_state_builder_map.py +104 -0
  125. tests/unit/test_state_config.py +197 -0
  126. tests/unit/test_streaming.py +307 -0
  127. tests/unit/test_subgraph.py +596 -0
  128. tests/unit/test_template.py +190 -0
  129. tests/unit/test_tool_call_integration.py +164 -0
  130. tests/unit/test_tool_call_node.py +178 -0
  131. tests/unit/test_tool_nodes.py +129 -0
  132. tests/unit/test_websearch.py +234 -0
  133. yamlgraph/__init__.py +35 -0
  134. yamlgraph/builder.py +110 -0
  135. yamlgraph/cli/__init__.py +159 -0
  136. yamlgraph/cli/__main__.py +6 -0
  137. yamlgraph/cli/commands.py +231 -0
  138. yamlgraph/cli/deprecation.py +92 -0
  139. yamlgraph/cli/graph_commands.py +541 -0
  140. yamlgraph/cli/validators.py +37 -0
  141. yamlgraph/config.py +67 -0
  142. yamlgraph/constants.py +70 -0
  143. yamlgraph/error_handlers.py +227 -0
  144. yamlgraph/executor.py +290 -0
  145. yamlgraph/executor_async.py +288 -0
  146. yamlgraph/graph_loader.py +451 -0
  147. yamlgraph/map_compiler.py +150 -0
  148. yamlgraph/models/__init__.py +36 -0
  149. yamlgraph/models/graph_schema.py +181 -0
  150. yamlgraph/models/schemas.py +124 -0
  151. yamlgraph/models/state_builder.py +236 -0
  152. yamlgraph/node_factory.py +768 -0
  153. yamlgraph/routing.py +87 -0
  154. yamlgraph/schema_loader.py +240 -0
  155. yamlgraph/storage/__init__.py +20 -0
  156. yamlgraph/storage/checkpointer.py +72 -0
  157. yamlgraph/storage/checkpointer_factory.py +123 -0
  158. yamlgraph/storage/database.py +320 -0
  159. yamlgraph/storage/export.py +269 -0
  160. yamlgraph/tools/__init__.py +1 -0
  161. yamlgraph/tools/agent.py +320 -0
  162. yamlgraph/tools/graph_linter.py +388 -0
  163. yamlgraph/tools/langsmith_tools.py +125 -0
  164. yamlgraph/tools/nodes.py +126 -0
  165. yamlgraph/tools/python_tool.py +179 -0
  166. yamlgraph/tools/shell.py +205 -0
  167. yamlgraph/tools/websearch.py +242 -0
  168. yamlgraph/utils/__init__.py +48 -0
  169. yamlgraph/utils/conditions.py +157 -0
  170. yamlgraph/utils/expressions.py +245 -0
  171. yamlgraph/utils/json_extract.py +104 -0
  172. yamlgraph/utils/langsmith.py +416 -0
  173. yamlgraph/utils/llm_factory.py +118 -0
  174. yamlgraph/utils/llm_factory_async.py +105 -0
  175. yamlgraph/utils/logging.py +104 -0
  176. yamlgraph/utils/prompts.py +171 -0
  177. yamlgraph/utils/sanitize.py +98 -0
  178. yamlgraph/utils/template.py +102 -0
  179. yamlgraph/utils/validators.py +181 -0
  180. yamlgraph-0.3.9.dist-info/METADATA +1105 -0
  181. yamlgraph-0.3.9.dist-info/RECORD +185 -0
  182. yamlgraph-0.3.9.dist-info/WHEEL +5 -0
  183. yamlgraph-0.3.9.dist-info/entry_points.txt +2 -0
  184. yamlgraph-0.3.9.dist-info/licenses/LICENSE +33 -0
  185. yamlgraph-0.3.9.dist-info/top_level.txt +4 -0
@@ -0,0 +1,244 @@
1
+ """Tests for template extraction tools."""
2
+
3
+ from pathlib import Path
4
+
5
+ from examples.codegen.tools.template_tools import (
6
+ extract_class_template,
7
+ extract_function_template,
8
+ extract_test_template,
9
+ )
10
+
11
+ # ============================================================================
12
+ # extract_function_template tests
13
+ # ============================================================================
14
+
15
+
16
+ class TestExtractFunctionTemplate:
17
+ """Tests for extract_function_template."""
18
+
19
+ def test_extracts_basic_function(self, tmp_path: Path):
20
+ """Extract template from a simple function."""
21
+ source = tmp_path / "example.py"
22
+ source.write_text('''
23
+ def greet(name: str) -> str:
24
+ """Say hello to someone."""
25
+ return f"Hello, {name}!"
26
+ ''')
27
+ result = extract_function_template(str(source), "greet")
28
+
29
+ assert "template" in result
30
+ template = result["template"]
31
+ assert "{function_name}" in template or "greet" in template
32
+ assert "str" in template # type hints preserved
33
+ assert "hello" in template.lower() or "{" in template
34
+
35
+ def test_extracts_function_with_error_handling(self, tmp_path: Path):
36
+ """Extract template preserves try/except structure."""
37
+ source = tmp_path / "example.py"
38
+ source.write_text('''
39
+ def process(file_path: str) -> dict:
40
+ """Process a file."""
41
+ try:
42
+ data = open(file_path).read()
43
+ return {"result": data}
44
+ except FileNotFoundError:
45
+ return {"error": "File not found"}
46
+ ''')
47
+ result = extract_function_template(str(source), "process")
48
+
49
+ assert "template" in result
50
+ template = result["template"]
51
+ assert "try" in template or "{try_block}" in template
52
+ assert "except" in template or "{except_block}" in template
53
+
54
+ def test_preserves_docstring_structure(self, tmp_path: Path):
55
+ """Docstring is preserved in template."""
56
+ source = tmp_path / "example.py"
57
+ source.write_text('''
58
+ def analyze(file_path: str, depth: int = 3) -> dict:
59
+ """Analyze something.
60
+
61
+ Args:
62
+ file_path: Path to the file
63
+ depth: How deep to analyze
64
+
65
+ Returns:
66
+ dict with analysis results
67
+ """
68
+ return {}
69
+ ''')
70
+ result = extract_function_template(str(source), "analyze")
71
+
72
+ assert "template" in result
73
+ template = result["template"]
74
+ assert "Args:" in template
75
+ assert "Returns:" in template
76
+
77
+ def test_handles_missing_function(self, tmp_path: Path):
78
+ """Returns error for missing function."""
79
+ source = tmp_path / "example.py"
80
+ source.write_text("def other(): pass")
81
+
82
+ result = extract_function_template(str(source), "missing")
83
+ assert "error" in result
84
+
85
+ def test_handles_missing_file(self):
86
+ """Returns error for missing file."""
87
+ result = extract_function_template("/nonexistent/file.py", "func")
88
+ assert "error" in result
89
+
90
+ def test_handles_syntax_error(self, tmp_path: Path):
91
+ """Returns error for invalid Python."""
92
+ source = tmp_path / "bad.py"
93
+ source.write_text("def broken(:")
94
+
95
+ result = extract_function_template(str(source), "broken")
96
+ assert "error" in result
97
+
98
+
99
+ # ============================================================================
100
+ # extract_class_template tests
101
+ # ============================================================================
102
+
103
+
104
+ class TestExtractClassTemplate:
105
+ """Tests for extract_class_template."""
106
+
107
+ def test_extracts_basic_class(self, tmp_path: Path):
108
+ """Extract template from a simple class."""
109
+ source = tmp_path / "example.py"
110
+ source.write_text('''
111
+ class Widget:
112
+ """A widget."""
113
+
114
+ def __init__(self, name: str):
115
+ self.name = name
116
+
117
+ def render(self) -> str:
118
+ return f"<{self.name}>"
119
+ ''')
120
+ result = extract_class_template(str(source), "Widget")
121
+
122
+ assert "template" in result
123
+ template = result["template"]
124
+ assert "class" in template
125
+ assert "__init__" in template
126
+ assert "render" in template
127
+
128
+ def test_extracts_class_with_inheritance(self, tmp_path: Path):
129
+ """Extract template preserves base classes."""
130
+ source = tmp_path / "example.py"
131
+ source.write_text('''
132
+ class MyError(ValueError, RuntimeError):
133
+ """Custom error."""
134
+ pass
135
+ ''')
136
+ result = extract_class_template(str(source), "MyError")
137
+
138
+ assert "template" in result
139
+ template = result["template"]
140
+ assert "ValueError" in template or "{bases}" in template
141
+
142
+ def test_extracts_class_variables(self, tmp_path: Path):
143
+ """Extract template includes class variables."""
144
+ source = tmp_path / "example.py"
145
+ source.write_text('''
146
+ class Config:
147
+ """Configuration."""
148
+
149
+ DEFAULT_TIMEOUT: int = 30
150
+ MAX_RETRIES: int = 3
151
+
152
+ def __init__(self):
153
+ self.value = None
154
+ ''')
155
+ result = extract_class_template(str(source), "Config")
156
+
157
+ assert "template" in result
158
+ template = result["template"]
159
+ # Should capture class variable pattern
160
+ assert "TIMEOUT" in template or "int" in template
161
+
162
+ def test_handles_missing_class(self, tmp_path: Path):
163
+ """Returns error for missing class."""
164
+ source = tmp_path / "example.py"
165
+ source.write_text("class Other: pass")
166
+
167
+ result = extract_class_template(str(source), "Missing")
168
+ assert "error" in result
169
+
170
+ def test_handles_missing_file(self):
171
+ """Returns error for missing file."""
172
+ result = extract_class_template("/nonexistent/file.py", "MyClass")
173
+ assert "error" in result
174
+
175
+
176
+ # ============================================================================
177
+ # extract_test_template tests
178
+ # ============================================================================
179
+
180
+
181
+ class TestExtractTestTemplate:
182
+ """Tests for extract_test_template."""
183
+
184
+ def test_extracts_pytest_patterns(self, tmp_path: Path):
185
+ """Extract test template from pytest file."""
186
+ test_file = tmp_path / "test_example.py"
187
+ test_file.write_text('''
188
+ import pytest
189
+ from mymodule import process
190
+
191
+ @pytest.fixture
192
+ def sample_data():
193
+ return {"key": "value"}
194
+
195
+ class TestProcess:
196
+ """Tests for process function."""
197
+
198
+ def test_basic(self, sample_data):
199
+ result = process(sample_data)
200
+ assert result["status"] == "ok"
201
+
202
+ def test_error_handling(self):
203
+ with pytest.raises(ValueError):
204
+ process(None)
205
+ ''')
206
+ result = extract_test_template(str(test_file), "mymodule")
207
+
208
+ assert "template" in result
209
+ template = result["template"]
210
+ assert "@pytest.fixture" in template or "fixture" in template.lower()
211
+ assert "class Test" in template or "{test_class}" in template
212
+
213
+ def test_extracts_mock_patterns(self, tmp_path: Path):
214
+ """Extract mock/patch patterns from tests."""
215
+ test_file = tmp_path / "test_example.py"
216
+ test_file.write_text("""
217
+ from unittest.mock import patch, MagicMock
218
+ from mymodule import fetch_data
219
+
220
+ def test_with_mock():
221
+ with patch("mymodule.requests.get") as mock_get:
222
+ mock_get.return_value.json.return_value = {}
223
+ result = fetch_data()
224
+ assert result == {}
225
+ """)
226
+ result = extract_test_template(str(test_file), "mymodule")
227
+
228
+ assert "template" in result
229
+ template = result["template"]
230
+ assert "patch" in template or "mock" in template.lower()
231
+
232
+ def test_handles_missing_file(self):
233
+ """Returns error for missing file."""
234
+ result = extract_test_template("/nonexistent/test.py", "module")
235
+ assert "error" in result
236
+
237
+ def test_handles_empty_test_file(self, tmp_path: Path):
238
+ """Returns minimal template for empty file."""
239
+ test_file = tmp_path / "test_empty.py"
240
+ test_file.write_text("# Empty test file")
241
+
242
+ result = extract_test_template(str(test_file), "module")
243
+ # Should return some default template structure
244
+ assert "template" in result or "error" in result
@@ -0,0 +1,80 @@
1
+ """Code analysis tools for impl-agent.
2
+
3
+ This subpackage provides static and semantic analysis capabilities:
4
+ - AST-based structure extraction
5
+ - Code context reading and search
6
+ - Code navigation and module discovery
7
+ - Jedi-based cross-file reference tracking (optional)
8
+ """
9
+
10
+ from examples.codegen.tools.ai_helpers import (
11
+ diff_preview,
12
+ find_similar_code,
13
+ summarize_module,
14
+ )
15
+ from examples.codegen.tools.ast_analysis import get_module_structure
16
+ from examples.codegen.tools.code_context import (
17
+ find_related_tests,
18
+ read_lines,
19
+ search_codebase,
20
+ search_in_file,
21
+ )
22
+ from examples.codegen.tools.code_nav import list_package_modules
23
+ from examples.codegen.tools.dependency_tools import get_dependents, get_imports
24
+ from examples.codegen.tools.example_tools import find_error_handling, find_example
25
+ from examples.codegen.tools.git_tools import git_blame, git_log
26
+ from examples.codegen.tools.jedi_analysis import (
27
+ JEDI_AVAILABLE,
28
+ find_references,
29
+ get_callees,
30
+ get_callers,
31
+ )
32
+ from examples.codegen.tools.meta_tools import (
33
+ extract_graph_template,
34
+ extract_prompt_template,
35
+ )
36
+ from examples.codegen.tools.syntax_tools import syntax_check
37
+ from examples.codegen.tools.template_tools import (
38
+ extract_class_template,
39
+ extract_function_template,
40
+ extract_test_template,
41
+ )
42
+
43
+ __all__ = [
44
+ # AST analysis
45
+ "get_module_structure",
46
+ # Code context
47
+ "read_lines",
48
+ "search_in_file",
49
+ "search_codebase",
50
+ "find_related_tests",
51
+ # Code navigation
52
+ "list_package_modules",
53
+ # Jedi analysis
54
+ "JEDI_AVAILABLE",
55
+ "find_references",
56
+ "get_callers",
57
+ "get_callees",
58
+ # Git analysis
59
+ "git_blame",
60
+ "git_log",
61
+ # Syntax validation
62
+ "syntax_check",
63
+ # Dependency analysis
64
+ "get_imports",
65
+ "get_dependents",
66
+ # AI helpers
67
+ "summarize_module",
68
+ "diff_preview",
69
+ "find_similar_code",
70
+ # Template extraction
71
+ "extract_function_template",
72
+ "extract_class_template",
73
+ "extract_test_template",
74
+ # Example discovery
75
+ "find_example",
76
+ "find_error_handling",
77
+ # Meta templates (YAMLGraph)
78
+ "extract_graph_template",
79
+ "extract_prompt_template",
80
+ ]