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.
Files changed (160) hide show
  1. tactus/__init__.py +49 -0
  2. tactus/adapters/__init__.py +9 -0
  3. tactus/adapters/broker_log.py +76 -0
  4. tactus/adapters/cli_hitl.py +189 -0
  5. tactus/adapters/cli_log.py +223 -0
  6. tactus/adapters/cost_collector_log.py +56 -0
  7. tactus/adapters/file_storage.py +367 -0
  8. tactus/adapters/http_callback_log.py +109 -0
  9. tactus/adapters/ide_log.py +71 -0
  10. tactus/adapters/lua_tools.py +336 -0
  11. tactus/adapters/mcp.py +289 -0
  12. tactus/adapters/mcp_manager.py +196 -0
  13. tactus/adapters/memory.py +53 -0
  14. tactus/adapters/plugins.py +419 -0
  15. tactus/backends/http_backend.py +58 -0
  16. tactus/backends/model_backend.py +35 -0
  17. tactus/backends/pytorch_backend.py +110 -0
  18. tactus/broker/__init__.py +12 -0
  19. tactus/broker/client.py +247 -0
  20. tactus/broker/protocol.py +183 -0
  21. tactus/broker/server.py +1123 -0
  22. tactus/broker/stdio.py +12 -0
  23. tactus/cli/__init__.py +7 -0
  24. tactus/cli/app.py +2245 -0
  25. tactus/cli/commands/__init__.py +0 -0
  26. tactus/core/__init__.py +32 -0
  27. tactus/core/config_manager.py +790 -0
  28. tactus/core/dependencies/__init__.py +14 -0
  29. tactus/core/dependencies/registry.py +180 -0
  30. tactus/core/dsl_stubs.py +2117 -0
  31. tactus/core/exceptions.py +66 -0
  32. tactus/core/execution_context.py +480 -0
  33. tactus/core/lua_sandbox.py +508 -0
  34. tactus/core/message_history_manager.py +236 -0
  35. tactus/core/mocking.py +286 -0
  36. tactus/core/output_validator.py +291 -0
  37. tactus/core/registry.py +499 -0
  38. tactus/core/runtime.py +2907 -0
  39. tactus/core/template_resolver.py +142 -0
  40. tactus/core/yaml_parser.py +301 -0
  41. tactus/docker/Dockerfile +61 -0
  42. tactus/docker/entrypoint.sh +69 -0
  43. tactus/dspy/__init__.py +39 -0
  44. tactus/dspy/agent.py +1144 -0
  45. tactus/dspy/broker_lm.py +181 -0
  46. tactus/dspy/config.py +212 -0
  47. tactus/dspy/history.py +196 -0
  48. tactus/dspy/module.py +405 -0
  49. tactus/dspy/prediction.py +318 -0
  50. tactus/dspy/signature.py +185 -0
  51. tactus/formatting/__init__.py +7 -0
  52. tactus/formatting/formatter.py +437 -0
  53. tactus/ide/__init__.py +9 -0
  54. tactus/ide/coding_assistant.py +343 -0
  55. tactus/ide/server.py +2223 -0
  56. tactus/primitives/__init__.py +49 -0
  57. tactus/primitives/control.py +168 -0
  58. tactus/primitives/file.py +229 -0
  59. tactus/primitives/handles.py +378 -0
  60. tactus/primitives/host.py +94 -0
  61. tactus/primitives/human.py +342 -0
  62. tactus/primitives/json.py +189 -0
  63. tactus/primitives/log.py +187 -0
  64. tactus/primitives/message_history.py +157 -0
  65. tactus/primitives/model.py +163 -0
  66. tactus/primitives/procedure.py +564 -0
  67. tactus/primitives/procedure_callable.py +318 -0
  68. tactus/primitives/retry.py +155 -0
  69. tactus/primitives/session.py +152 -0
  70. tactus/primitives/state.py +182 -0
  71. tactus/primitives/step.py +209 -0
  72. tactus/primitives/system.py +93 -0
  73. tactus/primitives/tool.py +375 -0
  74. tactus/primitives/tool_handle.py +279 -0
  75. tactus/primitives/toolset.py +229 -0
  76. tactus/protocols/__init__.py +38 -0
  77. tactus/protocols/chat_recorder.py +81 -0
  78. tactus/protocols/config.py +97 -0
  79. tactus/protocols/cost.py +31 -0
  80. tactus/protocols/hitl.py +71 -0
  81. tactus/protocols/log_handler.py +27 -0
  82. tactus/protocols/models.py +355 -0
  83. tactus/protocols/result.py +33 -0
  84. tactus/protocols/storage.py +90 -0
  85. tactus/providers/__init__.py +13 -0
  86. tactus/providers/base.py +92 -0
  87. tactus/providers/bedrock.py +117 -0
  88. tactus/providers/google.py +105 -0
  89. tactus/providers/openai.py +98 -0
  90. tactus/sandbox/__init__.py +63 -0
  91. tactus/sandbox/config.py +171 -0
  92. tactus/sandbox/container_runner.py +1099 -0
  93. tactus/sandbox/docker_manager.py +433 -0
  94. tactus/sandbox/entrypoint.py +227 -0
  95. tactus/sandbox/protocol.py +213 -0
  96. tactus/stdlib/__init__.py +10 -0
  97. tactus/stdlib/io/__init__.py +13 -0
  98. tactus/stdlib/io/csv.py +88 -0
  99. tactus/stdlib/io/excel.py +136 -0
  100. tactus/stdlib/io/file.py +90 -0
  101. tactus/stdlib/io/fs.py +154 -0
  102. tactus/stdlib/io/hdf5.py +121 -0
  103. tactus/stdlib/io/json.py +109 -0
  104. tactus/stdlib/io/parquet.py +83 -0
  105. tactus/stdlib/io/tsv.py +88 -0
  106. tactus/stdlib/loader.py +274 -0
  107. tactus/stdlib/tac/tactus/tools/done.tac +33 -0
  108. tactus/stdlib/tac/tactus/tools/log.tac +50 -0
  109. tactus/testing/README.md +273 -0
  110. tactus/testing/__init__.py +61 -0
  111. tactus/testing/behave_integration.py +380 -0
  112. tactus/testing/context.py +486 -0
  113. tactus/testing/eval_models.py +114 -0
  114. tactus/testing/evaluation_runner.py +222 -0
  115. tactus/testing/evaluators.py +634 -0
  116. tactus/testing/events.py +94 -0
  117. tactus/testing/gherkin_parser.py +134 -0
  118. tactus/testing/mock_agent.py +315 -0
  119. tactus/testing/mock_dependencies.py +234 -0
  120. tactus/testing/mock_hitl.py +171 -0
  121. tactus/testing/mock_registry.py +168 -0
  122. tactus/testing/mock_tools.py +133 -0
  123. tactus/testing/models.py +115 -0
  124. tactus/testing/pydantic_eval_runner.py +508 -0
  125. tactus/testing/steps/__init__.py +13 -0
  126. tactus/testing/steps/builtin.py +902 -0
  127. tactus/testing/steps/custom.py +69 -0
  128. tactus/testing/steps/registry.py +68 -0
  129. tactus/testing/test_runner.py +489 -0
  130. tactus/tracing/__init__.py +5 -0
  131. tactus/tracing/trace_manager.py +417 -0
  132. tactus/utils/__init__.py +1 -0
  133. tactus/utils/cost_calculator.py +72 -0
  134. tactus/utils/model_pricing.py +132 -0
  135. tactus/utils/safe_file_library.py +502 -0
  136. tactus/utils/safe_libraries.py +234 -0
  137. tactus/validation/LuaLexerBase.py +66 -0
  138. tactus/validation/LuaParserBase.py +23 -0
  139. tactus/validation/README.md +224 -0
  140. tactus/validation/__init__.py +7 -0
  141. tactus/validation/error_listener.py +21 -0
  142. tactus/validation/generated/LuaLexer.interp +231 -0
  143. tactus/validation/generated/LuaLexer.py +5548 -0
  144. tactus/validation/generated/LuaLexer.tokens +124 -0
  145. tactus/validation/generated/LuaLexerBase.py +66 -0
  146. tactus/validation/generated/LuaParser.interp +173 -0
  147. tactus/validation/generated/LuaParser.py +6439 -0
  148. tactus/validation/generated/LuaParser.tokens +124 -0
  149. tactus/validation/generated/LuaParserBase.py +23 -0
  150. tactus/validation/generated/LuaParserVisitor.py +118 -0
  151. tactus/validation/generated/__init__.py +7 -0
  152. tactus/validation/grammar/LuaLexer.g4 +123 -0
  153. tactus/validation/grammar/LuaParser.g4 +178 -0
  154. tactus/validation/semantic_visitor.py +817 -0
  155. tactus/validation/validator.py +157 -0
  156. tactus-0.31.0.dist-info/METADATA +1809 -0
  157. tactus-0.31.0.dist-info/RECORD +160 -0
  158. tactus-0.31.0.dist-info/WHEEL +4 -0
  159. tactus-0.31.0.dist-info/entry_points.txt +2 -0
  160. 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
+ )