tactus 0.31.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.
- tactus/__init__.py +49 -0
- tactus/adapters/__init__.py +9 -0
- tactus/adapters/broker_log.py +76 -0
- tactus/adapters/cli_hitl.py +189 -0
- tactus/adapters/cli_log.py +223 -0
- tactus/adapters/cost_collector_log.py +56 -0
- tactus/adapters/file_storage.py +367 -0
- tactus/adapters/http_callback_log.py +109 -0
- tactus/adapters/ide_log.py +71 -0
- tactus/adapters/lua_tools.py +336 -0
- tactus/adapters/mcp.py +289 -0
- tactus/adapters/mcp_manager.py +196 -0
- tactus/adapters/memory.py +53 -0
- tactus/adapters/plugins.py +419 -0
- tactus/backends/http_backend.py +58 -0
- tactus/backends/model_backend.py +35 -0
- tactus/backends/pytorch_backend.py +110 -0
- tactus/broker/__init__.py +12 -0
- tactus/broker/client.py +247 -0
- tactus/broker/protocol.py +183 -0
- tactus/broker/server.py +1123 -0
- tactus/broker/stdio.py +12 -0
- tactus/cli/__init__.py +7 -0
- tactus/cli/app.py +2245 -0
- tactus/cli/commands/__init__.py +0 -0
- tactus/core/__init__.py +32 -0
- tactus/core/config_manager.py +790 -0
- tactus/core/dependencies/__init__.py +14 -0
- tactus/core/dependencies/registry.py +180 -0
- tactus/core/dsl_stubs.py +2117 -0
- tactus/core/exceptions.py +66 -0
- tactus/core/execution_context.py +480 -0
- tactus/core/lua_sandbox.py +508 -0
- tactus/core/message_history_manager.py +236 -0
- tactus/core/mocking.py +286 -0
- tactus/core/output_validator.py +291 -0
- tactus/core/registry.py +499 -0
- tactus/core/runtime.py +2907 -0
- tactus/core/template_resolver.py +142 -0
- tactus/core/yaml_parser.py +301 -0
- tactus/docker/Dockerfile +61 -0
- tactus/docker/entrypoint.sh +69 -0
- tactus/dspy/__init__.py +39 -0
- tactus/dspy/agent.py +1144 -0
- tactus/dspy/broker_lm.py +181 -0
- tactus/dspy/config.py +212 -0
- tactus/dspy/history.py +196 -0
- tactus/dspy/module.py +405 -0
- tactus/dspy/prediction.py +318 -0
- tactus/dspy/signature.py +185 -0
- tactus/formatting/__init__.py +7 -0
- tactus/formatting/formatter.py +437 -0
- tactus/ide/__init__.py +9 -0
- tactus/ide/coding_assistant.py +343 -0
- tactus/ide/server.py +2223 -0
- tactus/primitives/__init__.py +49 -0
- tactus/primitives/control.py +168 -0
- tactus/primitives/file.py +229 -0
- tactus/primitives/handles.py +378 -0
- tactus/primitives/host.py +94 -0
- tactus/primitives/human.py +342 -0
- tactus/primitives/json.py +189 -0
- tactus/primitives/log.py +187 -0
- tactus/primitives/message_history.py +157 -0
- tactus/primitives/model.py +163 -0
- tactus/primitives/procedure.py +564 -0
- tactus/primitives/procedure_callable.py +318 -0
- tactus/primitives/retry.py +155 -0
- tactus/primitives/session.py +152 -0
- tactus/primitives/state.py +182 -0
- tactus/primitives/step.py +209 -0
- tactus/primitives/system.py +93 -0
- tactus/primitives/tool.py +375 -0
- tactus/primitives/tool_handle.py +279 -0
- tactus/primitives/toolset.py +229 -0
- tactus/protocols/__init__.py +38 -0
- tactus/protocols/chat_recorder.py +81 -0
- tactus/protocols/config.py +97 -0
- tactus/protocols/cost.py +31 -0
- tactus/protocols/hitl.py +71 -0
- tactus/protocols/log_handler.py +27 -0
- tactus/protocols/models.py +355 -0
- tactus/protocols/result.py +33 -0
- tactus/protocols/storage.py +90 -0
- tactus/providers/__init__.py +13 -0
- tactus/providers/base.py +92 -0
- tactus/providers/bedrock.py +117 -0
- tactus/providers/google.py +105 -0
- tactus/providers/openai.py +98 -0
- tactus/sandbox/__init__.py +63 -0
- tactus/sandbox/config.py +171 -0
- tactus/sandbox/container_runner.py +1099 -0
- tactus/sandbox/docker_manager.py +433 -0
- tactus/sandbox/entrypoint.py +227 -0
- tactus/sandbox/protocol.py +213 -0
- tactus/stdlib/__init__.py +10 -0
- tactus/stdlib/io/__init__.py +13 -0
- tactus/stdlib/io/csv.py +88 -0
- tactus/stdlib/io/excel.py +136 -0
- tactus/stdlib/io/file.py +90 -0
- tactus/stdlib/io/fs.py +154 -0
- tactus/stdlib/io/hdf5.py +121 -0
- tactus/stdlib/io/json.py +109 -0
- tactus/stdlib/io/parquet.py +83 -0
- tactus/stdlib/io/tsv.py +88 -0
- tactus/stdlib/loader.py +274 -0
- tactus/stdlib/tac/tactus/tools/done.tac +33 -0
- tactus/stdlib/tac/tactus/tools/log.tac +50 -0
- tactus/testing/README.md +273 -0
- tactus/testing/__init__.py +61 -0
- tactus/testing/behave_integration.py +380 -0
- tactus/testing/context.py +486 -0
- tactus/testing/eval_models.py +114 -0
- tactus/testing/evaluation_runner.py +222 -0
- tactus/testing/evaluators.py +634 -0
- tactus/testing/events.py +94 -0
- tactus/testing/gherkin_parser.py +134 -0
- tactus/testing/mock_agent.py +315 -0
- tactus/testing/mock_dependencies.py +234 -0
- tactus/testing/mock_hitl.py +171 -0
- tactus/testing/mock_registry.py +168 -0
- tactus/testing/mock_tools.py +133 -0
- tactus/testing/models.py +115 -0
- tactus/testing/pydantic_eval_runner.py +508 -0
- tactus/testing/steps/__init__.py +13 -0
- tactus/testing/steps/builtin.py +902 -0
- tactus/testing/steps/custom.py +69 -0
- tactus/testing/steps/registry.py +68 -0
- tactus/testing/test_runner.py +489 -0
- tactus/tracing/__init__.py +5 -0
- tactus/tracing/trace_manager.py +417 -0
- tactus/utils/__init__.py +1 -0
- tactus/utils/cost_calculator.py +72 -0
- tactus/utils/model_pricing.py +132 -0
- tactus/utils/safe_file_library.py +502 -0
- tactus/utils/safe_libraries.py +234 -0
- tactus/validation/LuaLexerBase.py +66 -0
- tactus/validation/LuaParserBase.py +23 -0
- tactus/validation/README.md +224 -0
- tactus/validation/__init__.py +7 -0
- tactus/validation/error_listener.py +21 -0
- tactus/validation/generated/LuaLexer.interp +231 -0
- tactus/validation/generated/LuaLexer.py +5548 -0
- tactus/validation/generated/LuaLexer.tokens +124 -0
- tactus/validation/generated/LuaLexerBase.py +66 -0
- tactus/validation/generated/LuaParser.interp +173 -0
- tactus/validation/generated/LuaParser.py +6439 -0
- tactus/validation/generated/LuaParser.tokens +124 -0
- tactus/validation/generated/LuaParserBase.py +23 -0
- tactus/validation/generated/LuaParserVisitor.py +118 -0
- tactus/validation/generated/__init__.py +7 -0
- tactus/validation/grammar/LuaLexer.g4 +123 -0
- tactus/validation/grammar/LuaParser.g4 +178 -0
- tactus/validation/semantic_visitor.py +817 -0
- tactus/validation/validator.py +157 -0
- tactus-0.31.0.dist-info/METADATA +1809 -0
- tactus-0.31.0.dist-info/RECORD +160 -0
- tactus-0.31.0.dist-info/WHEEL +4 -0
- tactus-0.31.0.dist-info/entry_points.txt +2 -0
- tactus-0.31.0.dist-info/licenses/LICENSE +21 -0
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Tactus DSL validator.
|
|
3
|
+
|
|
4
|
+
Validates .tac files using ANTLR parser:
|
|
5
|
+
1. Lua syntax validation (via ANTLR parse tree)
|
|
6
|
+
2. Semantic validation (DSL construct recognition via visitor)
|
|
7
|
+
3. Registry validation (cross-reference checking)
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import logging
|
|
11
|
+
from enum import Enum
|
|
12
|
+
from typing import List
|
|
13
|
+
|
|
14
|
+
from antlr4 import InputStream, CommonTokenStream
|
|
15
|
+
from .generated.LuaLexer import LuaLexer
|
|
16
|
+
from .generated.LuaParser import LuaParser
|
|
17
|
+
from .semantic_visitor import TactusDSLVisitor
|
|
18
|
+
from .error_listener import TactusErrorListener
|
|
19
|
+
from tactus.core.registry import ValidationResult, ValidationMessage
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
logger = logging.getLogger(__name__)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class ValidationMode(str, Enum):
|
|
26
|
+
"""Validation mode."""
|
|
27
|
+
|
|
28
|
+
QUICK = "quick" # Fast syntax check only
|
|
29
|
+
FULL = "full" # Full semantic validation
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class TactusValidator:
|
|
33
|
+
"""
|
|
34
|
+
Validates .tac files using ANTLR parser.
|
|
35
|
+
|
|
36
|
+
Uses formal Lua grammar for syntax validation and semantic
|
|
37
|
+
visitor for DSL construct recognition.
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
def validate(
|
|
41
|
+
self,
|
|
42
|
+
source: str,
|
|
43
|
+
mode: ValidationMode = ValidationMode.FULL,
|
|
44
|
+
) -> ValidationResult:
|
|
45
|
+
"""
|
|
46
|
+
Validate a .tac file using ANTLR parser.
|
|
47
|
+
|
|
48
|
+
Args:
|
|
49
|
+
source: Lua DSL source code
|
|
50
|
+
mode: Validation mode (quick or full)
|
|
51
|
+
|
|
52
|
+
Returns:
|
|
53
|
+
ValidationResult with errors, warnings, and registry
|
|
54
|
+
"""
|
|
55
|
+
errors: List[ValidationMessage] = []
|
|
56
|
+
warnings: List[ValidationMessage] = []
|
|
57
|
+
registry = None
|
|
58
|
+
|
|
59
|
+
try:
|
|
60
|
+
# Phase 1: Lexical and syntactic analysis via ANTLR
|
|
61
|
+
input_stream = InputStream(source)
|
|
62
|
+
lexer = LuaLexer(input_stream)
|
|
63
|
+
token_stream = CommonTokenStream(lexer)
|
|
64
|
+
parser = LuaParser(token_stream)
|
|
65
|
+
|
|
66
|
+
# Attach error listener to collect syntax errors
|
|
67
|
+
error_listener = TactusErrorListener()
|
|
68
|
+
parser.removeErrorListeners()
|
|
69
|
+
parser.addErrorListener(error_listener)
|
|
70
|
+
|
|
71
|
+
# Parse (start rule is 'start_' which expects chunk + EOF)
|
|
72
|
+
tree = parser.start_()
|
|
73
|
+
|
|
74
|
+
# Check for syntax errors
|
|
75
|
+
if error_listener.errors:
|
|
76
|
+
return ValidationResult(
|
|
77
|
+
valid=False, errors=error_listener.errors, warnings=[], registry=None
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
# Quick mode: just syntax check
|
|
81
|
+
if mode == ValidationMode.QUICK:
|
|
82
|
+
return ValidationResult(valid=True, errors=[], warnings=[], registry=None)
|
|
83
|
+
|
|
84
|
+
# Phase 2: Semantic analysis (DSL validation)
|
|
85
|
+
visitor = TactusDSLVisitor()
|
|
86
|
+
visitor.visit(tree)
|
|
87
|
+
|
|
88
|
+
# Combine visitor errors
|
|
89
|
+
errors = visitor.errors
|
|
90
|
+
warnings = visitor.warnings
|
|
91
|
+
|
|
92
|
+
# Phase 3: Registry validation
|
|
93
|
+
if not errors:
|
|
94
|
+
result = visitor.builder.validate()
|
|
95
|
+
errors.extend(result.errors)
|
|
96
|
+
warnings.extend(result.warnings)
|
|
97
|
+
registry = result.registry if result.valid else None
|
|
98
|
+
else:
|
|
99
|
+
registry = None
|
|
100
|
+
|
|
101
|
+
return ValidationResult(
|
|
102
|
+
valid=len(errors) == 0, errors=errors, warnings=warnings, registry=registry
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
except Exception as e:
|
|
106
|
+
logger.error(f"Validation failed with unexpected error: {e}", exc_info=True)
|
|
107
|
+
errors.append(
|
|
108
|
+
ValidationMessage(
|
|
109
|
+
level="error",
|
|
110
|
+
message=f"Validation error: {e}",
|
|
111
|
+
)
|
|
112
|
+
)
|
|
113
|
+
return ValidationResult(valid=False, errors=errors, warnings=warnings, registry=None)
|
|
114
|
+
|
|
115
|
+
def validate_file(
|
|
116
|
+
self,
|
|
117
|
+
file_path: str,
|
|
118
|
+
mode: ValidationMode = ValidationMode.FULL,
|
|
119
|
+
) -> ValidationResult:
|
|
120
|
+
"""
|
|
121
|
+
Validate a .tac file from disk.
|
|
122
|
+
|
|
123
|
+
Args:
|
|
124
|
+
file_path: Path to .tac file
|
|
125
|
+
mode: Validation mode
|
|
126
|
+
|
|
127
|
+
Returns:
|
|
128
|
+
ValidationResult
|
|
129
|
+
"""
|
|
130
|
+
try:
|
|
131
|
+
with open(file_path, "r") as f:
|
|
132
|
+
source = f.read()
|
|
133
|
+
return self.validate(source, mode)
|
|
134
|
+
except FileNotFoundError:
|
|
135
|
+
return ValidationResult(
|
|
136
|
+
valid=False,
|
|
137
|
+
errors=[
|
|
138
|
+
ValidationMessage(
|
|
139
|
+
level="error",
|
|
140
|
+
message=f"File not found: {file_path}",
|
|
141
|
+
)
|
|
142
|
+
],
|
|
143
|
+
warnings=[],
|
|
144
|
+
registry=None,
|
|
145
|
+
)
|
|
146
|
+
except Exception as e:
|
|
147
|
+
return ValidationResult(
|
|
148
|
+
valid=False,
|
|
149
|
+
errors=[
|
|
150
|
+
ValidationMessage(
|
|
151
|
+
level="error",
|
|
152
|
+
message=f"Error reading file: {e}",
|
|
153
|
+
)
|
|
154
|
+
],
|
|
155
|
+
warnings=[],
|
|
156
|
+
registry=None,
|
|
157
|
+
)
|