tactus 0.31.0__py3-none-any.whl → 0.34.1__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 (101) hide show
  1. tactus/__init__.py +1 -1
  2. tactus/adapters/__init__.py +18 -1
  3. tactus/adapters/broker_log.py +127 -34
  4. tactus/adapters/channels/__init__.py +153 -0
  5. tactus/adapters/channels/base.py +174 -0
  6. tactus/adapters/channels/broker.py +179 -0
  7. tactus/adapters/channels/cli.py +448 -0
  8. tactus/adapters/channels/host.py +225 -0
  9. tactus/adapters/channels/ipc.py +297 -0
  10. tactus/adapters/channels/sse.py +305 -0
  11. tactus/adapters/cli_hitl.py +223 -1
  12. tactus/adapters/control_loop.py +879 -0
  13. tactus/adapters/file_storage.py +35 -2
  14. tactus/adapters/ide_log.py +7 -1
  15. tactus/backends/http_backend.py +0 -1
  16. tactus/broker/client.py +31 -1
  17. tactus/broker/server.py +416 -92
  18. tactus/cli/app.py +270 -7
  19. tactus/cli/control.py +393 -0
  20. tactus/core/config_manager.py +33 -6
  21. tactus/core/dsl_stubs.py +102 -18
  22. tactus/core/execution_context.py +265 -8
  23. tactus/core/lua_sandbox.py +8 -9
  24. tactus/core/registry.py +19 -2
  25. tactus/core/runtime.py +235 -27
  26. tactus/docker/Dockerfile.pypi +49 -0
  27. tactus/docs/__init__.py +33 -0
  28. tactus/docs/extractor.py +326 -0
  29. tactus/docs/html_renderer.py +72 -0
  30. tactus/docs/models.py +121 -0
  31. tactus/docs/templates/base.html +204 -0
  32. tactus/docs/templates/index.html +58 -0
  33. tactus/docs/templates/module.html +96 -0
  34. tactus/dspy/agent.py +403 -22
  35. tactus/dspy/broker_lm.py +57 -6
  36. tactus/dspy/config.py +14 -3
  37. tactus/dspy/history.py +2 -1
  38. tactus/dspy/module.py +136 -11
  39. tactus/dspy/signature.py +0 -1
  40. tactus/ide/config_server.py +536 -0
  41. tactus/ide/server.py +345 -21
  42. tactus/primitives/human.py +619 -47
  43. tactus/primitives/system.py +0 -1
  44. tactus/protocols/__init__.py +25 -0
  45. tactus/protocols/control.py +427 -0
  46. tactus/protocols/notification.py +207 -0
  47. tactus/sandbox/container_runner.py +79 -11
  48. tactus/sandbox/docker_manager.py +23 -0
  49. tactus/sandbox/entrypoint.py +26 -0
  50. tactus/sandbox/protocol.py +3 -0
  51. tactus/stdlib/README.md +77 -0
  52. tactus/stdlib/__init__.py +27 -1
  53. tactus/stdlib/classify/__init__.py +165 -0
  54. tactus/stdlib/classify/classify.spec.tac +195 -0
  55. tactus/stdlib/classify/classify.tac +257 -0
  56. tactus/stdlib/classify/fuzzy.py +282 -0
  57. tactus/stdlib/classify/llm.py +319 -0
  58. tactus/stdlib/classify/primitive.py +287 -0
  59. tactus/stdlib/core/__init__.py +57 -0
  60. tactus/stdlib/core/base.py +320 -0
  61. tactus/stdlib/core/confidence.py +211 -0
  62. tactus/stdlib/core/models.py +161 -0
  63. tactus/stdlib/core/retry.py +171 -0
  64. tactus/stdlib/core/validation.py +274 -0
  65. tactus/stdlib/extract/__init__.py +125 -0
  66. tactus/stdlib/extract/llm.py +330 -0
  67. tactus/stdlib/extract/primitive.py +256 -0
  68. tactus/stdlib/tac/tactus/classify/base.tac +51 -0
  69. tactus/stdlib/tac/tactus/classify/fuzzy.tac +87 -0
  70. tactus/stdlib/tac/tactus/classify/index.md +77 -0
  71. tactus/stdlib/tac/tactus/classify/init.tac +29 -0
  72. tactus/stdlib/tac/tactus/classify/llm.tac +150 -0
  73. tactus/stdlib/tac/tactus/classify.spec.tac +191 -0
  74. tactus/stdlib/tac/tactus/extract/base.tac +138 -0
  75. tactus/stdlib/tac/tactus/extract/index.md +96 -0
  76. tactus/stdlib/tac/tactus/extract/init.tac +27 -0
  77. tactus/stdlib/tac/tactus/extract/llm.tac +201 -0
  78. tactus/stdlib/tac/tactus/extract.spec.tac +153 -0
  79. tactus/stdlib/tac/tactus/generate/base.tac +142 -0
  80. tactus/stdlib/tac/tactus/generate/index.md +195 -0
  81. tactus/stdlib/tac/tactus/generate/init.tac +28 -0
  82. tactus/stdlib/tac/tactus/generate/llm.tac +169 -0
  83. tactus/stdlib/tac/tactus/generate.spec.tac +210 -0
  84. tactus/testing/behave_integration.py +171 -7
  85. tactus/testing/context.py +0 -1
  86. tactus/testing/evaluation_runner.py +0 -1
  87. tactus/testing/gherkin_parser.py +0 -1
  88. tactus/testing/mock_hitl.py +0 -1
  89. tactus/testing/mock_tools.py +0 -1
  90. tactus/testing/models.py +0 -1
  91. tactus/testing/steps/builtin.py +0 -1
  92. tactus/testing/steps/custom.py +81 -22
  93. tactus/testing/steps/registry.py +0 -1
  94. tactus/testing/test_runner.py +7 -1
  95. tactus/validation/semantic_visitor.py +11 -5
  96. tactus/validation/validator.py +0 -1
  97. {tactus-0.31.0.dist-info → tactus-0.34.1.dist-info}/METADATA +16 -2
  98. {tactus-0.31.0.dist-info → tactus-0.34.1.dist-info}/RECORD +101 -49
  99. {tactus-0.31.0.dist-info → tactus-0.34.1.dist-info}/WHEEL +0 -0
  100. {tactus-0.31.0.dist-info → tactus-0.34.1.dist-info}/entry_points.txt +0 -0
  101. {tactus-0.31.0.dist-info → tactus-0.34.1.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,204 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en" class="dark">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>{% block title %}Tactus Documentation{% endblock %}</title>
7
+ <style>
8
+ :root {
9
+ --bg: #0a0a0a;
10
+ --bg-secondary: #1a1a1a;
11
+ --border: #2a2a2a;
12
+ --text: #e4e4e7;
13
+ --text-secondary: #a1a1aa;
14
+ --accent: #3b82f6;
15
+ --accent-hover: #60a5fa;
16
+ --code-bg: #18181b;
17
+ }
18
+
19
+ * {
20
+ margin: 0;
21
+ padding: 0;
22
+ box-sizing: border-box;
23
+ }
24
+
25
+ body {
26
+ font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
27
+ background: var(--bg);
28
+ color: var(--text);
29
+ line-height: 1.6;
30
+ }
31
+
32
+ .container {
33
+ max-width: 1200px;
34
+ margin: 0 auto;
35
+ padding: 2rem;
36
+ }
37
+
38
+ header {
39
+ border-bottom: 1px solid var(--border);
40
+ padding-bottom: 2rem;
41
+ margin-bottom: 2rem;
42
+ }
43
+
44
+ h1, h2, h3, h4, h5, h6 {
45
+ margin-top: 1.5em;
46
+ margin-bottom: 0.5em;
47
+ font-weight: 600;
48
+ }
49
+
50
+ h1 { font-size: 2.5rem; margin-top: 0; }
51
+ h2 { font-size: 1.875rem; border-bottom: 1px solid var(--border); padding-bottom: 0.3em; }
52
+ h3 { font-size: 1.5rem; }
53
+ h4 { font-size: 1.25rem; }
54
+
55
+ a {
56
+ color: var(--accent);
57
+ text-decoration: none;
58
+ }
59
+
60
+ a:hover {
61
+ color: var(--accent-hover);
62
+ text-decoration: underline;
63
+ }
64
+
65
+ pre {
66
+ background: var(--code-bg);
67
+ border: 1px solid var(--border);
68
+ border-radius: 0.5rem;
69
+ padding: 1rem;
70
+ overflow-x: auto;
71
+ margin: 1rem 0;
72
+ }
73
+
74
+ code {
75
+ background: var(--code-bg);
76
+ padding: 0.2em 0.4em;
77
+ border-radius: 0.25rem;
78
+ font-family: "SF Mono", Monaco, Consolas, monospace;
79
+ font-size: 0.875em;
80
+ }
81
+
82
+ pre code {
83
+ background: none;
84
+ padding: 0;
85
+ }
86
+
87
+ .scenario {
88
+ background: var(--bg-secondary);
89
+ border: 1px solid var(--border);
90
+ border-radius: 0.5rem;
91
+ padding: 1.5rem;
92
+ margin: 1rem 0;
93
+ }
94
+
95
+ .scenario h3 {
96
+ margin-top: 0;
97
+ color: var(--accent);
98
+ }
99
+
100
+ .step {
101
+ padding: 0.5rem 0;
102
+ color: var(--text-secondary);
103
+ }
104
+
105
+ .step strong {
106
+ color: var(--accent);
107
+ }
108
+
109
+ .parameter {
110
+ background: var(--bg-secondary);
111
+ border-left: 3px solid var(--accent);
112
+ padding: 1rem;
113
+ margin: 1rem 0;
114
+ }
115
+
116
+ .parameter-name {
117
+ font-family: "SF Mono", Monaco, Consolas, monospace;
118
+ color: var(--accent);
119
+ font-weight: 600;
120
+ }
121
+
122
+ .badge {
123
+ display: inline-block;
124
+ padding: 0.25rem 0.5rem;
125
+ border-radius: 0.25rem;
126
+ font-size: 0.75rem;
127
+ font-weight: 600;
128
+ margin-left: 0.5rem;
129
+ }
130
+
131
+ .badge-required {
132
+ background: #ef4444;
133
+ color: white;
134
+ }
135
+
136
+ .badge-optional {
137
+ background: #64748b;
138
+ color: white;
139
+ }
140
+
141
+ .nav-links {
142
+ margin-top: 2rem;
143
+ padding-top: 2rem;
144
+ border-top: 1px solid var(--border);
145
+ }
146
+
147
+ ul, ol {
148
+ margin-left: 1.5rem;
149
+ margin-bottom: 1rem;
150
+ }
151
+
152
+ blockquote {
153
+ border-left: 3px solid var(--accent);
154
+ padding-left: 1rem;
155
+ color: var(--text-secondary);
156
+ margin: 1rem 0;
157
+ }
158
+
159
+ table {
160
+ width: 100%;
161
+ border-collapse: collapse;
162
+ margin: 1rem 0;
163
+ }
164
+
165
+ th, td {
166
+ padding: 0.75rem;
167
+ text-align: left;
168
+ border-bottom: 1px solid var(--border);
169
+ }
170
+
171
+ th {
172
+ background: var(--bg-secondary);
173
+ font-weight: 600;
174
+ }
175
+
176
+ .overview {
177
+ background: var(--bg-secondary);
178
+ border-radius: 0.5rem;
179
+ padding: 1.5rem;
180
+ margin: 2rem 0;
181
+ }
182
+ </style>
183
+ </head>
184
+ <body>
185
+ <div class="container">
186
+ <header>
187
+ <h1>{% block header %}Tactus Documentation{% endblock %}</h1>
188
+ <div class="nav-links">
189
+ <a href="index.html">← Back to Index</a>
190
+ </div>
191
+ </header>
192
+
193
+ <main>
194
+ {% block content %}{% endblock %}
195
+ </main>
196
+
197
+ <footer class="nav-links">
198
+ <p style="color: var(--text-secondary);">
199
+ Generated with <a href="https://github.com/AnthusAI/Tactus">Tactus</a>
200
+ </p>
201
+ </footer>
202
+ </div>
203
+ </body>
204
+ </html>
@@ -0,0 +1,58 @@
1
+ {% extends "base.html" %}
2
+
3
+ {% block title %}Tactus Standard Library Documentation{% endblock %}
4
+
5
+ {% block header %}Tactus Standard Library{% endblock %}
6
+
7
+ {% block content %}
8
+ <div class="overview">
9
+ <p>
10
+ The Tactus standard library provides reusable primitives for building AI agents
11
+ and classification workflows. All modules are written in Tactus with BDD specifications
12
+ serving as tests, documentation, and contracts.
13
+ </p>
14
+ </div>
15
+
16
+ <h2>Available Modules</h2>
17
+
18
+ {% if tree.modules %}
19
+ <div style="display: grid; grid-template-columns: repeat(auto-fill, minmax(300px, 1fr)); gap: 1rem; margin-top: 2rem;">
20
+ {% for module in tree.modules %}
21
+ <div class="scenario">
22
+ <h3>
23
+ <a href="{{ module.name }}.html">{{ module.full_name }}</a>
24
+ </h3>
25
+ <p style="color: var(--text-secondary); margin-top: 0.5rem;">
26
+ {{ module.overview|truncate(150) if module.overview else "No description available" }}
27
+ </p>
28
+ <div style="margin-top: 1rem; font-size: 0.875rem; color: var(--text-secondary);">
29
+ {% if module.has_specs %}
30
+ <span>✓ {{ module.features|length }} feature(s)</span>
31
+ <span style="margin-left: 1rem;">{{ module.line_count }} lines</span>
32
+ {% else %}
33
+ <span>{{ module.line_count }} lines</span>
34
+ {% endif %}
35
+ </div>
36
+ </div>
37
+ {% endfor %}
38
+ </div>
39
+ {% else %}
40
+ <p style="color: var(--text-secondary);">No modules found.</p>
41
+ {% endif %}
42
+
43
+ <h2>Quick Start</h2>
44
+
45
+ <pre><code class="language-lua">-- Load a module
46
+ local classify = require("tactus.classify")
47
+
48
+ -- Use it
49
+ local classifier = classify.LLMClassifier:new {
50
+ classes = {"Yes", "No"},
51
+ prompt = "Is this a question?"
52
+ }
53
+
54
+ local result = classifier:classify("How are you?")
55
+ print(result.value) -- "Yes"
56
+ </code></pre>
57
+
58
+ {% endblock %}
@@ -0,0 +1,96 @@
1
+ {% extends "base.html" %}
2
+
3
+ {% block title %}{{ module.full_name }} - Tactus Documentation{% endblock %}
4
+
5
+ {% block header %}{{ module.full_name }}{% endblock %}
6
+
7
+ {% block content %}
8
+
9
+ {% if module.index_content %}
10
+ <div class="overview">
11
+ {{ module.index_content|markdown|safe }}
12
+ </div>
13
+ {% elif module.overview %}
14
+ <div class="overview">
15
+ {{ module.overview|markdown|safe }}
16
+ </div>
17
+ {% endif %}
18
+
19
+ {% if module.examples %}
20
+ <h2>Examples</h2>
21
+ {% for example in module.examples %}
22
+ {% if example.source == "doc_block" %}
23
+ <div class="scenario">
24
+ <h3>{{ example.title }}</h3>
25
+ {% if example.description %}
26
+ <p style="color: var(--text-secondary);">{{ example.description }}</p>
27
+ {% endif %}
28
+ <pre><code class="language-lua">{{ example.code }}</code></pre>
29
+ </div>
30
+ {% endif %}
31
+ {% endfor %}
32
+ {% endif %}
33
+
34
+ {% if module.parameters %}
35
+ <h2>Parameters</h2>
36
+ {% for param in module.parameters %}
37
+ <div class="parameter">
38
+ <div>
39
+ <span class="parameter-name">{{ param.name }}</span>
40
+ {% if param.type_hint %}
41
+ <code>{{ param.type_hint }}</code>
42
+ {% endif %}
43
+ {% if param.required %}
44
+ <span class="badge badge-required">required</span>
45
+ {% else %}
46
+ <span class="badge badge-optional">optional</span>
47
+ {% endif %}
48
+ </div>
49
+ <p style="margin-top: 0.5rem; color: var(--text-secondary);">
50
+ {{ param.description }}
51
+ </p>
52
+ {% if param.default %}
53
+ <p style="margin-top: 0.5rem; font-size: 0.875rem;">
54
+ <strong>Default:</strong> <code>{{ param.default }}</code>
55
+ </p>
56
+ {% endif %}
57
+ </div>
58
+ {% endfor %}
59
+ {% endif %}
60
+
61
+ {% if module.features %}
62
+ <h2>Specifications</h2>
63
+ {% for feature in module.features %}
64
+ <h3>{{ feature.name }}</h3>
65
+ {% if feature.description %}
66
+ <p style="color: var(--text-secondary); font-style: italic;">{{ feature.description }}</p>
67
+ {% endif %}
68
+
69
+ {% for scenario in feature.scenarios %}
70
+ <div class="scenario">
71
+ <h4>{{ scenario.name }}</h4>
72
+ {% for step in scenario.steps %}
73
+ <div class="step">
74
+ <strong>{{ step.keyword }}</strong> {{ step.text }}
75
+ </div>
76
+ {% endfor %}
77
+ </div>
78
+ {% endfor %}
79
+ {% endfor %}
80
+ {% endif %}
81
+
82
+ {% if module.doc_blocks|length > 1 %}
83
+ <h2>Additional Documentation</h2>
84
+ {% for doc_block in module.doc_blocks[1:] %}
85
+ <div style="margin: 2rem 0;">
86
+ {{ doc_block.content|markdown|safe }}
87
+ </div>
88
+ {% endfor %}
89
+ {% endif %}
90
+
91
+ <div style="margin-top: 3rem; padding-top: 2rem; border-top: 1px solid var(--border); color: var(--text-secondary); font-size: 0.875rem;">
92
+ <p><strong>Source:</strong> <code>{{ module.file_path }}</code></p>
93
+ <p style="margin-top: 0.5rem;"><strong>Lines:</strong> {{ module.line_count }}</p>
94
+ </div>
95
+
96
+ {% endblock %}