algomath-extract 1.0.0
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.
- package/README.md +260 -0
- package/bin/algo-extract.js +143 -0
- package/bin/algo-generate.js +102 -0
- package/bin/algo-help.js +136 -0
- package/bin/algo-list.js +56 -0
- package/bin/algo-run.js +141 -0
- package/bin/algo-status.js +88 -0
- package/bin/algo-verify.js +189 -0
- package/bin/install.js +349 -0
- package/package.json +57 -0
- package/requirements.txt +20 -0
- package/src/__pycache__/intent.cpython-313.pyc +0 -0
- package/src/cli/__pycache__/commands.cpython-313.pyc +0 -0
- package/src/cli/cli_entry.py +106 -0
- package/src/cli/commands.py +339 -0
- package/src/execution/__init__.py +74 -0
- package/src/execution/__pycache__/__init__.cpython-313.pyc +0 -0
- package/src/execution/__pycache__/display.cpython-313.pyc +0 -0
- package/src/execution/__pycache__/errors.cpython-313.pyc +0 -0
- package/src/execution/__pycache__/executor.cpython-313.pyc +0 -0
- package/src/execution/__pycache__/sandbox.cpython-313.pyc +0 -0
- package/src/execution/display.py +261 -0
- package/src/execution/errors.py +158 -0
- package/src/execution/executor.py +253 -0
- package/src/execution/sandbox.py +333 -0
- package/src/extraction/__init__.py +102 -0
- package/src/extraction/__pycache__/__init__.cpython-313.pyc +0 -0
- package/src/extraction/__pycache__/boundaries.cpython-313.pyc +0 -0
- package/src/extraction/__pycache__/errors.cpython-313.pyc +0 -0
- package/src/extraction/__pycache__/llm_extraction.cpython-313.pyc +0 -0
- package/src/extraction/__pycache__/notation.cpython-313.pyc +0 -0
- package/src/extraction/__pycache__/parser.cpython-313.pyc +0 -0
- package/src/extraction/__pycache__/pdf_processor.cpython-313.pyc +0 -0
- package/src/extraction/__pycache__/prompts.cpython-313.pyc +0 -0
- package/src/extraction/__pycache__/review.cpython-313.pyc +0 -0
- package/src/extraction/__pycache__/schema.cpython-313.pyc +0 -0
- package/src/extraction/__pycache__/validation.cpython-313.pyc +0 -0
- package/src/extraction/boundaries.py +281 -0
- package/src/extraction/errors.py +156 -0
- package/src/extraction/llm_extraction.py +225 -0
- package/src/extraction/notation.py +240 -0
- package/src/extraction/parser.py +402 -0
- package/src/extraction/pdf_processor.py +281 -0
- package/src/extraction/prompts.py +90 -0
- package/src/extraction/review.py +298 -0
- package/src/extraction/schema.py +173 -0
- package/src/extraction/validation.py +202 -0
- package/src/generation/__init__.py +79 -0
- package/src/generation/__pycache__/__init__.cpython-313.pyc +0 -0
- package/src/generation/__pycache__/code_generator.cpython-313.pyc +0 -0
- package/src/generation/__pycache__/errors.cpython-313.pyc +0 -0
- package/src/generation/__pycache__/hybrid.cpython-313.pyc +0 -0
- package/src/generation/__pycache__/llm_generator.cpython-313.pyc +0 -0
- package/src/generation/__pycache__/persistence.cpython-313.pyc +0 -0
- package/src/generation/__pycache__/prompts.cpython-313.pyc +0 -0
- package/src/generation/__pycache__/review.cpython-313.pyc +0 -0
- package/src/generation/__pycache__/templates.cpython-313.pyc +0 -0
- package/src/generation/__pycache__/types.cpython-313.pyc +0 -0
- package/src/generation/__pycache__/validation.cpython-313.pyc +0 -0
- package/src/generation/code_generator.py +375 -0
- package/src/generation/errors.py +84 -0
- package/src/generation/hybrid.py +210 -0
- package/src/generation/llm_generator.py +223 -0
- package/src/generation/persistence.py +221 -0
- package/src/generation/prompts.py +202 -0
- package/src/generation/review.py +254 -0
- package/src/generation/templates.py +208 -0
- package/src/generation/types.py +196 -0
- package/src/generation/validation.py +278 -0
- package/src/intent.py +323 -0
- package/src/verification/__init__.py +63 -0
- package/src/verification/__pycache__/__init__.cpython-313.pyc +0 -0
- package/src/verification/__pycache__/checker.cpython-313.pyc +0 -0
- package/src/verification/__pycache__/comparison.cpython-313.pyc +0 -0
- package/src/verification/__pycache__/explainer.cpython-313.pyc +0 -0
- package/src/verification/__pycache__/static_analysis.cpython-313.pyc +0 -0
- package/src/verification/checker.py +220 -0
- package/src/verification/comparison.py +492 -0
- package/src/verification/explainer.py +414 -0
- package/src/verification/static_analysis.py +540 -0
- package/src/workflows/__init__.py +21 -0
- package/src/workflows/__pycache__/__init__.cpython-313.pyc +0 -0
- package/src/workflows/__pycache__/extract.cpython-313.pyc +0 -0
- package/src/workflows/__pycache__/generate.cpython-313.pyc +0 -0
- package/src/workflows/__pycache__/run.cpython-313.pyc +0 -0
- package/src/workflows/__pycache__/verify.cpython-313.pyc +0 -0
- package/src/workflows/extract.py +181 -0
- package/src/workflows/generate.py +155 -0
- package/src/workflows/run.py +187 -0
- package/src/workflows/verify.py +334 -0
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
"""Sandboxed subprocess execution module for AlgoMath.
|
|
2
|
+
|
|
3
|
+
Per D-01 through D-06: Provides safe, isolated code execution with resource
|
|
4
|
+
limits, timeout protection, output capture, and file system restrictions.
|
|
5
|
+
|
|
6
|
+
This module implements a subprocess-based sandbox that:
|
|
7
|
+
- Runs code in a separate Python process for isolation
|
|
8
|
+
- Applies CPU and memory limits to prevent resource abuse
|
|
9
|
+
- Captures stdout/stderr and returns execution results
|
|
10
|
+
- Restricts dangerous imports (os, sys, subprocess, etc.)
|
|
11
|
+
- Uses temporary directories that auto-clean after execution
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
import subprocess
|
|
15
|
+
import tempfile
|
|
16
|
+
import os
|
|
17
|
+
import sys
|
|
18
|
+
import signal
|
|
19
|
+
import json
|
|
20
|
+
import time
|
|
21
|
+
from pathlib import Path
|
|
22
|
+
from dataclasses import dataclass, field
|
|
23
|
+
from enum import Enum
|
|
24
|
+
from typing import Optional, Any, Dict, List
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class ExecutionStatus(Enum):
|
|
28
|
+
"""Enumeration of possible execution statuses."""
|
|
29
|
+
SUCCESS = "success"
|
|
30
|
+
TIMEOUT = "timeout"
|
|
31
|
+
MEMORY_ERROR = "memory_error"
|
|
32
|
+
RUNTIME_ERROR = "runtime_error"
|
|
33
|
+
SYNTAX_ERROR = "syntax_error"
|
|
34
|
+
IMPORT_ERROR = "import_error"
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@dataclass
|
|
38
|
+
class ExecutionResult:
|
|
39
|
+
"""Result of code execution.
|
|
40
|
+
|
|
41
|
+
Attributes:
|
|
42
|
+
status: Execution status (success, timeout, error, etc.)
|
|
43
|
+
stdout: Captured standard output
|
|
44
|
+
stderr: Captured standard error
|
|
45
|
+
runtime_seconds: Execution time in seconds
|
|
46
|
+
return_value: Serialized return value if code defines main()
|
|
47
|
+
error_type: Type of error if execution failed
|
|
48
|
+
error_message: Human-readable error message
|
|
49
|
+
"""
|
|
50
|
+
status: ExecutionStatus
|
|
51
|
+
stdout: str = ""
|
|
52
|
+
stderr: str = ""
|
|
53
|
+
runtime_seconds: float = 0.0
|
|
54
|
+
return_value: Any = None
|
|
55
|
+
error_type: Optional[str] = None
|
|
56
|
+
error_message: Optional[str] = None
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
# Modules that are blocked for security
|
|
60
|
+
# Note: 'sys' is removed from blocklist since wrapper needs it,
|
|
61
|
+
# but dangerous sys functions like sys.exit are blocked separately
|
|
62
|
+
BLOCKED_MODULES = [
|
|
63
|
+
'os', 'subprocess', 'socket', 'urllib', 'http', 'ftplib',
|
|
64
|
+
'smtplib', 'ssl', 'ctypes', 'mmap', 'resource', 'pty', 'tty',
|
|
65
|
+
'multiprocessing', 'concurrent.futures.process'
|
|
66
|
+
]
|
|
67
|
+
|
|
68
|
+
# Functions/methods that are dangerous even within allowed modules
|
|
69
|
+
BLOCKED_CALLS = [
|
|
70
|
+
('sys', 'exit'), # sys.exit() would terminate process
|
|
71
|
+
]
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
def _create_import_restrictor_code() -> str:
|
|
75
|
+
"""Create Python code that restricts dangerous imports.
|
|
76
|
+
|
|
77
|
+
Per D-28: Import restrictions block os, sys, subprocess, network modules.
|
|
78
|
+
This code overrides __import__ to check against a blocklist.
|
|
79
|
+
"""
|
|
80
|
+
blocked = json.dumps(BLOCKED_MODULES)
|
|
81
|
+
return f'''
|
|
82
|
+
import builtins
|
|
83
|
+
import json
|
|
84
|
+
|
|
85
|
+
__BLOCKED_MODULES = set(json.loads({repr(blocked)}))
|
|
86
|
+
_original_import = builtins.__import__
|
|
87
|
+
|
|
88
|
+
def _restricted_import(name, globals=None, locals=None, fromlist=(), level=0):
|
|
89
|
+
"""Import hook that blocks dangerous modules."""
|
|
90
|
+
# Check if the module or any of its parents is blocked
|
|
91
|
+
module_parts = name.split('.')
|
|
92
|
+
for i in range(len(module_parts)):
|
|
93
|
+
partial_name = '.'.join(module_parts[:i+1])
|
|
94
|
+
if partial_name in __BLOCKED_MODULES:
|
|
95
|
+
raise ImportError(
|
|
96
|
+
f"Import of '{{name}}' is not allowed. "
|
|
97
|
+
f"Module '{{partial_name}}' is restricted for security."
|
|
98
|
+
)
|
|
99
|
+
return _original_import(name, globals, locals, fromlist, level)
|
|
100
|
+
|
|
101
|
+
builtins.__import__ = _restricted_import
|
|
102
|
+
'''
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def _create_return_capture_wrapper(code: str) -> str:
|
|
106
|
+
"""Wrap code to capture return values from main() function.
|
|
107
|
+
|
|
108
|
+
Per D-30: Capture function return values for algorithms that return data.
|
|
109
|
+
"""
|
|
110
|
+
return f'''
|
|
111
|
+
import json
|
|
112
|
+
|
|
113
|
+
__algo_return_value = None
|
|
114
|
+
|
|
115
|
+
def _capture_main_result():
|
|
116
|
+
"""Check if main() was defined and capture its return value."""
|
|
117
|
+
global __algo_return_value
|
|
118
|
+
if 'main' in globals() and callable(globals()['main']):
|
|
119
|
+
__algo_return_value = main()
|
|
120
|
+
|
|
121
|
+
# User code starts here
|
|
122
|
+
{code}
|
|
123
|
+
|
|
124
|
+
# After code runs, try to capture main() result
|
|
125
|
+
_capture_main_result()
|
|
126
|
+
|
|
127
|
+
# Print return value for parent process to capture
|
|
128
|
+
if __algo_return_value is not None:
|
|
129
|
+
try:
|
|
130
|
+
# Try to serialize; if not JSON serializable, use repr
|
|
131
|
+
json.dumps(__algo_return_value)
|
|
132
|
+
print("__ALGO_RETURN__" + json.dumps(__algo_return_value))
|
|
133
|
+
except (TypeError, ValueError):
|
|
134
|
+
print("__ALGO_RETURN__" + repr(__algo_return_value))
|
|
135
|
+
'''
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
class SandboxExecutor:
|
|
139
|
+
"""Executor that runs Python code in a sandboxed subprocess.
|
|
140
|
+
|
|
141
|
+
Per D-01, D-02: Uses subprocess-based isolation with resource limits.
|
|
142
|
+
Per D-05: Default 30-second timeout.
|
|
143
|
+
Per D-09, D-10, D-11: Uses tempfile.TemporaryDirectory for isolation and cleanup.
|
|
144
|
+
|
|
145
|
+
Attributes:
|
|
146
|
+
timeout: Maximum execution time in seconds (default: 30)
|
|
147
|
+
max_memory_mb: Maximum memory in MB (default: 512)
|
|
148
|
+
allowed_imports: Optional list of allowed imports (None = use blocklist)
|
|
149
|
+
"""
|
|
150
|
+
|
|
151
|
+
def __init__(
|
|
152
|
+
self,
|
|
153
|
+
timeout: int = 30,
|
|
154
|
+
max_memory_mb: int = 512,
|
|
155
|
+
allowed_imports: Optional[List[str]] = None
|
|
156
|
+
):
|
|
157
|
+
"""Initialize sandbox executor.
|
|
158
|
+
|
|
159
|
+
Args:
|
|
160
|
+
timeout: Maximum execution time in seconds
|
|
161
|
+
max_memory_mb: Maximum memory allowed in megabytes
|
|
162
|
+
allowed_imports: Optional whitelist of allowed imports
|
|
163
|
+
"""
|
|
164
|
+
self.timeout = timeout
|
|
165
|
+
self.max_memory_mb = max_memory_mb
|
|
166
|
+
self.allowed_imports = allowed_imports
|
|
167
|
+
|
|
168
|
+
def _set_resource_limits(self):
|
|
169
|
+
"""Set resource limits for the child process.
|
|
170
|
+
|
|
171
|
+
Per D-02: Apply CPU and memory limits to subprocess.
|
|
172
|
+
Note: This only works on Unix-like systems.
|
|
173
|
+
"""
|
|
174
|
+
try:
|
|
175
|
+
import resource as res
|
|
176
|
+
|
|
177
|
+
# Set memory limit (soft limit, hard limit = unlimited)
|
|
178
|
+
max_bytes = self.max_memory_mb * 1024 * 1024
|
|
179
|
+
res.setrlimit(res.RLIMIT_AS, (max_bytes, res.RLIM_INFINITY))
|
|
180
|
+
|
|
181
|
+
# Set CPU time limit
|
|
182
|
+
res.setrlimit(res.RLIMIT_CPU, (self.timeout, self.timeout + 5))
|
|
183
|
+
except (ImportError, ValueError, OSError):
|
|
184
|
+
# resource module not available on Windows or failed
|
|
185
|
+
pass
|
|
186
|
+
|
|
187
|
+
def execute(
|
|
188
|
+
self,
|
|
189
|
+
code: str,
|
|
190
|
+
working_dir: Optional[Path] = None
|
|
191
|
+
) -> ExecutionResult:
|
|
192
|
+
"""Execute Python code in a sandboxed subprocess.
|
|
193
|
+
|
|
194
|
+
Args:
|
|
195
|
+
code: Python code to execute
|
|
196
|
+
working_dir: Optional working directory (uses temp dir if None)
|
|
197
|
+
|
|
198
|
+
Returns:
|
|
199
|
+
ExecutionResult with status, output, and metadata
|
|
200
|
+
"""
|
|
201
|
+
start_time = time.time()
|
|
202
|
+
|
|
203
|
+
# Create temporary directory for execution
|
|
204
|
+
# Per D-09, D-10: Auto-cleanup via TemporaryDirectory
|
|
205
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
206
|
+
code_file = Path(tmpdir) / "script.py"
|
|
207
|
+
|
|
208
|
+
# Prepare code with import restrictions and return value capture
|
|
209
|
+
full_code = _create_import_restrictor_code() + "\n"
|
|
210
|
+
full_code += _create_return_capture_wrapper(code)
|
|
211
|
+
|
|
212
|
+
# Write code to file
|
|
213
|
+
code_file.write_text(full_code, encoding='utf-8')
|
|
214
|
+
|
|
215
|
+
# Per D-11: Working directory isolation via cwd
|
|
216
|
+
cwd = working_dir if working_dir else Path(tmpdir)
|
|
217
|
+
|
|
218
|
+
try:
|
|
219
|
+
# Per D-01: Run in subprocess for isolation
|
|
220
|
+
# Per D-05, D-06: Apply timeout for hard termination
|
|
221
|
+
result = subprocess.run(
|
|
222
|
+
[sys.executable, str(code_file)],
|
|
223
|
+
capture_output=True,
|
|
224
|
+
text=True,
|
|
225
|
+
timeout=self.timeout,
|
|
226
|
+
cwd=str(cwd),
|
|
227
|
+
preexec_fn=self._set_resource_limits if os.name != 'nt' else None,
|
|
228
|
+
# Kill process group on timeout for complete cleanup
|
|
229
|
+
start_new_session=True
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
runtime = time.time() - start_time
|
|
233
|
+
|
|
234
|
+
# Parse return value from output
|
|
235
|
+
return_value = None
|
|
236
|
+
stdout_lines = result.stdout.split('\n')
|
|
237
|
+
filtered_stdout = []
|
|
238
|
+
for line in stdout_lines:
|
|
239
|
+
if line.startswith('__ALGO_RETURN__'):
|
|
240
|
+
json_str = line[len('__ALGO_RETURN__'):]
|
|
241
|
+
try:
|
|
242
|
+
return_value = json.loads(json_str)
|
|
243
|
+
except json.JSONDecodeError:
|
|
244
|
+
# Fall back to repr
|
|
245
|
+
return_value = json_str
|
|
246
|
+
else:
|
|
247
|
+
filtered_stdout.append(line)
|
|
248
|
+
|
|
249
|
+
stdout = '\n'.join(filtered_stdout).rstrip()
|
|
250
|
+
|
|
251
|
+
# Determine status based on return code
|
|
252
|
+
if result.returncode == 0:
|
|
253
|
+
status = ExecutionStatus.SUCCESS
|
|
254
|
+
else:
|
|
255
|
+
status = ExecutionStatus.RUNTIME_ERROR
|
|
256
|
+
|
|
257
|
+
return ExecutionResult(
|
|
258
|
+
status=status,
|
|
259
|
+
stdout=stdout,
|
|
260
|
+
stderr=result.stderr.rstrip(),
|
|
261
|
+
runtime_seconds=runtime,
|
|
262
|
+
return_value=return_value
|
|
263
|
+
)
|
|
264
|
+
|
|
265
|
+
except subprocess.TimeoutExpired as e:
|
|
266
|
+
# Per D-05, D-06, D-07: Timeout handling with clear status
|
|
267
|
+
runtime = time.time() - start_time
|
|
268
|
+
return ExecutionResult(
|
|
269
|
+
status=ExecutionStatus.TIMEOUT,
|
|
270
|
+
stdout=e.stdout.decode('utf-8', errors='replace') if e.stdout else "",
|
|
271
|
+
stderr=e.stderr.decode('utf-8', errors='replace') if e.stderr else "",
|
|
272
|
+
runtime_seconds=runtime,
|
|
273
|
+
error_type="TimeoutExpired",
|
|
274
|
+
error_message=f"Execution timed out after {self.timeout} seconds. Check for infinite loops."
|
|
275
|
+
)
|
|
276
|
+
|
|
277
|
+
except MemoryError:
|
|
278
|
+
# Per D-17, D-18: Memory error handling
|
|
279
|
+
runtime = time.time() - start_time
|
|
280
|
+
return ExecutionResult(
|
|
281
|
+
status=ExecutionStatus.MEMORY_ERROR,
|
|
282
|
+
runtime_seconds=runtime,
|
|
283
|
+
error_type="MemoryError",
|
|
284
|
+
error_message=f"Algorithm used too much memory (limit: {self.max_memory_mb}MB)"
|
|
285
|
+
)
|
|
286
|
+
|
|
287
|
+
except Exception as e:
|
|
288
|
+
# Per D-17: Error categorization
|
|
289
|
+
runtime = time.time() - start_time
|
|
290
|
+
error_type = type(e).__name__
|
|
291
|
+
|
|
292
|
+
# Check for syntax error indicators
|
|
293
|
+
if "SyntaxError" in str(e) or "syntax error" in str(e).lower():
|
|
294
|
+
status = ExecutionStatus.SYNTAX_ERROR
|
|
295
|
+
error_message = f"Generated code has a syntax issue: {e}"
|
|
296
|
+
elif "ImportError" in error_type or "ModuleNotFound" in error_type:
|
|
297
|
+
status = ExecutionStatus.IMPORT_ERROR
|
|
298
|
+
error_message = str(e)
|
|
299
|
+
else:
|
|
300
|
+
status = ExecutionStatus.RUNTIME_ERROR
|
|
301
|
+
error_message = f"Runtime error: {e}"
|
|
302
|
+
|
|
303
|
+
return ExecutionResult(
|
|
304
|
+
status=status,
|
|
305
|
+
runtime_seconds=runtime,
|
|
306
|
+
error_type=error_type,
|
|
307
|
+
error_message=error_message
|
|
308
|
+
)
|
|
309
|
+
|
|
310
|
+
|
|
311
|
+
# Convenience function for simple use cases
|
|
312
|
+
def execute_sandboxed(
|
|
313
|
+
code: str,
|
|
314
|
+
timeout: int = 30,
|
|
315
|
+
max_memory_mb: int = 512,
|
|
316
|
+
working_dir: Optional[Path] = None
|
|
317
|
+
) -> ExecutionResult:
|
|
318
|
+
"""Execute code with default sandbox settings.
|
|
319
|
+
|
|
320
|
+
Args:
|
|
321
|
+
code: Python code to execute
|
|
322
|
+
timeout: Maximum execution time in seconds
|
|
323
|
+
max_memory_mb: Maximum memory in megabytes
|
|
324
|
+
working_dir: Optional working directory
|
|
325
|
+
|
|
326
|
+
Returns:
|
|
327
|
+
ExecutionResult with status and output
|
|
328
|
+
"""
|
|
329
|
+
executor = SandboxExecutor(
|
|
330
|
+
timeout=timeout,
|
|
331
|
+
max_memory_mb=max_memory_mb
|
|
332
|
+
)
|
|
333
|
+
return executor.execute(code, working_dir=working_dir)
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
"""AlgoMath Extraction Module.
|
|
2
|
+
|
|
3
|
+
Provides functionality for extracting structured algorithms from
|
|
4
|
+
mathematical text descriptions.
|
|
5
|
+
|
|
6
|
+
Usage:
|
|
7
|
+
from src.extraction import HybridExtractor, Algorithm
|
|
8
|
+
|
|
9
|
+
extractor = HybridExtractor()
|
|
10
|
+
result = extractor.extract(text)
|
|
11
|
+
|
|
12
|
+
if result.success:
|
|
13
|
+
print(f"Extracted: {result.algorithm.name}")
|
|
14
|
+
for step in result.algorithm.steps:
|
|
15
|
+
print(f" {step.id}. {step.description}")
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
# Core types
|
|
19
|
+
from .schema import (
|
|
20
|
+
Algorithm,
|
|
21
|
+
Step,
|
|
22
|
+
StepType,
|
|
23
|
+
algorithm_to_json,
|
|
24
|
+
algorithm_from_json,
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
# Parsing
|
|
28
|
+
from .parser import (
|
|
29
|
+
RuleBasedParser,
|
|
30
|
+
parse_algorithm,
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
# LLM Extraction
|
|
34
|
+
from .llm_extraction import (
|
|
35
|
+
HybridExtractor,
|
|
36
|
+
extract_algorithm_llm,
|
|
37
|
+
ExtractionResult,
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
# Review
|
|
41
|
+
from .review import (
|
|
42
|
+
ReviewInterface,
|
|
43
|
+
validate_step_edit,
|
|
44
|
+
apply_edits,
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
# Errors
|
|
48
|
+
from .errors import (
|
|
49
|
+
ExtractionError,
|
|
50
|
+
ParseError,
|
|
51
|
+
AmbiguityError,
|
|
52
|
+
IncompleteError,
|
|
53
|
+
categorize_error,
|
|
54
|
+
format_errors_for_user,
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
# Validation
|
|
58
|
+
from .validation import (
|
|
59
|
+
validate_algorithm,
|
|
60
|
+
check_step_connectivity,
|
|
61
|
+
check_variable_flow,
|
|
62
|
+
ValidationResult,
|
|
63
|
+
)
|
|
64
|
+
|
|
65
|
+
__version__ = "0.1.0"
|
|
66
|
+
|
|
67
|
+
__all__ = [
|
|
68
|
+
# Core types
|
|
69
|
+
"Algorithm",
|
|
70
|
+
"Step",
|
|
71
|
+
"StepType",
|
|
72
|
+
"algorithm_to_json",
|
|
73
|
+
"algorithm_from_json",
|
|
74
|
+
|
|
75
|
+
# Parsing
|
|
76
|
+
"RuleBasedParser",
|
|
77
|
+
"parse_algorithm",
|
|
78
|
+
|
|
79
|
+
# LLM Extraction
|
|
80
|
+
"HybridExtractor",
|
|
81
|
+
"extract_algorithm_llm",
|
|
82
|
+
"ExtractionResult",
|
|
83
|
+
|
|
84
|
+
# Review
|
|
85
|
+
"ReviewInterface",
|
|
86
|
+
"validate_step_edit",
|
|
87
|
+
"apply_edits",
|
|
88
|
+
|
|
89
|
+
# Errors
|
|
90
|
+
"ExtractionError",
|
|
91
|
+
"ParseError",
|
|
92
|
+
"AmbiguityError",
|
|
93
|
+
"IncompleteError",
|
|
94
|
+
"categorize_error",
|
|
95
|
+
"format_errors_for_user",
|
|
96
|
+
|
|
97
|
+
# Validation
|
|
98
|
+
"validate_algorithm",
|
|
99
|
+
"check_step_connectivity",
|
|
100
|
+
"check_variable_flow",
|
|
101
|
+
"ValidationResult",
|
|
102
|
+
]
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|