tactus 0.35.1__py3-none-any.whl → 0.37.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 +1 -1
- tactus/adapters/channels/base.py +20 -2
- tactus/adapters/channels/broker.py +1 -0
- tactus/adapters/channels/host.py +3 -1
- tactus/adapters/channels/ipc.py +18 -3
- tactus/adapters/channels/sse.py +13 -5
- tactus/adapters/control_loop.py +44 -30
- tactus/adapters/mcp_manager.py +24 -7
- tactus/backends/http_backend.py +2 -2
- tactus/backends/pytorch_backend.py +2 -2
- tactus/broker/client.py +3 -3
- tactus/broker/server.py +17 -5
- tactus/core/dsl_stubs.py +3 -3
- tactus/core/execution_context.py +32 -27
- tactus/core/lua_sandbox.py +42 -34
- tactus/core/message_history_manager.py +51 -28
- tactus/core/output_validator.py +65 -51
- tactus/core/registry.py +29 -29
- tactus/core/runtime.py +69 -61
- tactus/dspy/broker_lm.py +13 -7
- tactus/dspy/config.py +7 -4
- tactus/ide/server.py +63 -33
- tactus/primitives/host.py +19 -16
- tactus/primitives/message_history.py +11 -14
- tactus/primitives/model.py +1 -1
- tactus/primitives/procedure.py +11 -8
- tactus/primitives/session.py +9 -9
- tactus/primitives/state.py +2 -2
- tactus/primitives/tool_handle.py +27 -24
- tactus/sandbox/container_runner.py +11 -6
- tactus/testing/context.py +6 -6
- tactus/testing/evaluation_runner.py +5 -5
- tactus/testing/mock_hitl.py +2 -2
- tactus/testing/models.py +2 -0
- tactus/testing/steps/builtin.py +2 -2
- tactus/testing/test_runner.py +6 -4
- tactus/utils/asyncio_helpers.py +2 -1
- tactus/utils/safe_libraries.py +2 -2
- {tactus-0.35.1.dist-info → tactus-0.37.0.dist-info}/METADATA +11 -5
- {tactus-0.35.1.dist-info → tactus-0.37.0.dist-info}/RECORD +43 -43
- {tactus-0.35.1.dist-info → tactus-0.37.0.dist-info}/WHEEL +0 -0
- {tactus-0.35.1.dist-info → tactus-0.37.0.dist-info}/entry_points.txt +0 -0
- {tactus-0.35.1.dist-info → tactus-0.37.0.dist-info}/licenses/LICENSE +0 -0
tactus/core/registry.py
CHANGED
|
@@ -6,7 +6,7 @@ procedure declarations from .tac files.
|
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
8
|
import logging
|
|
9
|
-
from typing import Any
|
|
9
|
+
from typing import Any, Dict, Optional, Union
|
|
10
10
|
|
|
11
11
|
from pydantic import BaseModel, Field, ValidationError, ConfigDict
|
|
12
12
|
|
|
@@ -19,7 +19,7 @@ class OutputFieldDeclaration(BaseModel):
|
|
|
19
19
|
name: str
|
|
20
20
|
field_type: str = Field(alias="type") # string, number, boolean, array, object
|
|
21
21
|
required: bool = False
|
|
22
|
-
description: str
|
|
22
|
+
description: Optional[str] = None
|
|
23
23
|
|
|
24
24
|
model_config = ConfigDict(populate_by_name=True)
|
|
25
25
|
|
|
@@ -31,7 +31,7 @@ class MessageHistoryConfiguration(BaseModel):
|
|
|
31
31
|
"""
|
|
32
32
|
|
|
33
33
|
source: str = "own" # "own", "shared", or another agent's name
|
|
34
|
-
filter: Any
|
|
34
|
+
filter: Optional[Any] = None # Lua function reference or filter name
|
|
35
35
|
|
|
36
36
|
|
|
37
37
|
class AgentOutputSchema(BaseModel):
|
|
@@ -44,21 +44,21 @@ class AgentDeclaration(BaseModel):
|
|
|
44
44
|
"""Agent declaration from DSL."""
|
|
45
45
|
|
|
46
46
|
name: str
|
|
47
|
-
provider: str
|
|
48
|
-
model: str
|
|
49
|
-
system_prompt: str
|
|
50
|
-
initial_message: str
|
|
47
|
+
provider: Optional[str] = None
|
|
48
|
+
model: Union[str, Dict[str, Any]] = "gpt-4o"
|
|
49
|
+
system_prompt: Union[str, Any] # String with {markers} or Lua function
|
|
50
|
+
initial_message: Optional[str] = None
|
|
51
51
|
tools: list[Any] = Field(default_factory=list) # Tool/toolset references and expressions
|
|
52
52
|
inline_tools: list[dict[str, Any]] = Field(default_factory=list) # Inline tool definitions
|
|
53
|
-
output: AgentOutputSchema
|
|
54
|
-
message_history: MessageHistoryConfiguration
|
|
53
|
+
output: Optional[AgentOutputSchema] = None # Aligned with pydantic-ai
|
|
54
|
+
message_history: Optional[MessageHistoryConfiguration] = None
|
|
55
55
|
max_turns: int = 50
|
|
56
56
|
disable_streaming: bool = (
|
|
57
57
|
False # Disable streaming for models that don't support tools in streaming mode
|
|
58
58
|
)
|
|
59
|
-
temperature: float
|
|
60
|
-
max_tokens: int
|
|
61
|
-
model_type: str
|
|
59
|
+
temperature: Optional[float] = None
|
|
60
|
+
max_tokens: Optional[int] = None
|
|
61
|
+
model_type: Optional[str] = None # e.g., "chat", "responses" for reasoning models
|
|
62
62
|
|
|
63
63
|
model_config = ConfigDict(extra="allow")
|
|
64
64
|
|
|
@@ -69,9 +69,9 @@ class HITLDeclaration(BaseModel):
|
|
|
69
69
|
name: str
|
|
70
70
|
hitl_type: str = Field(alias="type") # approval, input, review
|
|
71
71
|
message: str
|
|
72
|
-
timeout: int
|
|
72
|
+
timeout: Optional[int] = None
|
|
73
73
|
default: Any = None
|
|
74
|
-
options: list[dict[str, Any]]
|
|
74
|
+
options: Optional[list[dict[str, Any]]] = None
|
|
75
75
|
|
|
76
76
|
model_config = ConfigDict(populate_by_name=True)
|
|
77
77
|
|
|
@@ -81,9 +81,9 @@ class ScenarioDeclaration(BaseModel):
|
|
|
81
81
|
|
|
82
82
|
name: str
|
|
83
83
|
given: dict[str, Any] = Field(default_factory=dict)
|
|
84
|
-
when: str
|
|
85
|
-
then_output:
|
|
86
|
-
then_state:
|
|
84
|
+
when: Optional[str] = None # defaults to "procedure_completes"
|
|
85
|
+
then_output: Optional[Dict[str, Any]] = None
|
|
86
|
+
then_state: Optional[Dict[str, Any]] = None
|
|
87
87
|
mocks: dict[str, Any] = Field(default_factory=dict) # tool_name -> response
|
|
88
88
|
|
|
89
89
|
|
|
@@ -134,7 +134,7 @@ class ProcedureRegistry(BaseModel):
|
|
|
134
134
|
model_config = {"arbitrary_types_allowed": True}
|
|
135
135
|
|
|
136
136
|
# Metadata
|
|
137
|
-
description: str
|
|
137
|
+
description: Optional[str] = None
|
|
138
138
|
|
|
139
139
|
# Declarations
|
|
140
140
|
input_schema: dict[str, Any] = Field(default_factory=dict)
|
|
@@ -154,26 +154,26 @@ class ProcedureRegistry(BaseModel):
|
|
|
154
154
|
message_history_config: dict[str, Any] = Field(default_factory=dict)
|
|
155
155
|
|
|
156
156
|
# Gherkin BDD Testing
|
|
157
|
-
gherkin_specifications: str
|
|
157
|
+
gherkin_specifications: Optional[str] = None # Raw Gherkin text
|
|
158
158
|
specs_from_references: list[str] = Field(default_factory=list) # External spec file paths
|
|
159
159
|
custom_steps: dict[str, Any] = Field(default_factory=dict) # step_text -> lua_function
|
|
160
160
|
evaluation_config: dict[str, Any] = Field(default_factory=dict) # runs, parallel, etc.
|
|
161
161
|
|
|
162
162
|
# Pydantic Evals Integration
|
|
163
|
-
pydantic_evaluations:
|
|
163
|
+
pydantic_evaluations: Optional[Dict[str, Any]] = None # Pydantic Evals configuration
|
|
164
164
|
|
|
165
165
|
# Prompts
|
|
166
166
|
prompts: dict[str, str] = Field(default_factory=dict)
|
|
167
|
-
return_prompt: str
|
|
168
|
-
error_prompt: str
|
|
169
|
-
status_prompt: str
|
|
167
|
+
return_prompt: Optional[str] = None
|
|
168
|
+
error_prompt: Optional[str] = None
|
|
169
|
+
status_prompt: Optional[str] = None
|
|
170
170
|
|
|
171
171
|
# Execution settings
|
|
172
172
|
async_enabled: bool = False
|
|
173
173
|
max_depth: int = 5
|
|
174
174
|
max_turns: int = 50
|
|
175
|
-
default_provider: str
|
|
176
|
-
default_model: str
|
|
175
|
+
default_provider: Optional[str] = None
|
|
176
|
+
default_model: Optional[str] = None
|
|
177
177
|
|
|
178
178
|
# Named procedures (for in-file sub-procedures)
|
|
179
179
|
named_procedures: dict[str, dict[str, Any]] = Field(default_factory=dict)
|
|
@@ -193,8 +193,8 @@ class ValidationMessage(BaseModel):
|
|
|
193
193
|
|
|
194
194
|
level: str # "error" or "warning"
|
|
195
195
|
message: str
|
|
196
|
-
location: tuple[int, int]
|
|
197
|
-
declaration: str
|
|
196
|
+
location: Optional[tuple[int, int]] = None
|
|
197
|
+
declaration: Optional[str] = None
|
|
198
198
|
|
|
199
199
|
|
|
200
200
|
class ValidationResult(BaseModel):
|
|
@@ -203,7 +203,7 @@ class ValidationResult(BaseModel):
|
|
|
203
203
|
valid: bool
|
|
204
204
|
errors: list[ValidationMessage] = Field(default_factory=list)
|
|
205
205
|
warnings: list[ValidationMessage] = Field(default_factory=list)
|
|
206
|
-
registry: ProcedureRegistry
|
|
206
|
+
registry: Optional["ProcedureRegistry"] = None
|
|
207
207
|
|
|
208
208
|
|
|
209
209
|
class RegistryBuilder:
|
|
@@ -229,7 +229,7 @@ class RegistryBuilder:
|
|
|
229
229
|
self,
|
|
230
230
|
name: str,
|
|
231
231
|
config: dict,
|
|
232
|
-
output_schema: dict
|
|
232
|
+
output_schema: Optional[dict] = None,
|
|
233
233
|
) -> None:
|
|
234
234
|
"""Register an agent declaration."""
|
|
235
235
|
agent_config = dict(config)
|
tactus/core/runtime.py
CHANGED
|
@@ -13,7 +13,7 @@ import io
|
|
|
13
13
|
import logging
|
|
14
14
|
import time
|
|
15
15
|
import uuid
|
|
16
|
-
from typing import Any
|
|
16
|
+
from typing import Any, Dict, List, Optional
|
|
17
17
|
|
|
18
18
|
from tactus.core.registry import ProcedureRegistry, RegistryBuilder
|
|
19
19
|
from tactus.core.dsl_stubs import create_dsl_stubs, lua_table_to_dict
|
|
@@ -68,19 +68,19 @@ class TactusRuntime:
|
|
|
68
68
|
def __init__(
|
|
69
69
|
self,
|
|
70
70
|
procedure_id: str,
|
|
71
|
-
storage_backend: StorageBackend
|
|
72
|
-
hitl_handler: HITLHandler
|
|
73
|
-
chat_recorder: ChatRecorder
|
|
71
|
+
storage_backend: Optional[StorageBackend] = None,
|
|
72
|
+
hitl_handler: Optional[HITLHandler] = None,
|
|
73
|
+
chat_recorder: Optional[ChatRecorder] = None,
|
|
74
74
|
mcp_server=None,
|
|
75
|
-
mcp_servers:
|
|
76
|
-
openai_api_key: str
|
|
75
|
+
mcp_servers: Optional[Dict[str, Any]] = None,
|
|
76
|
+
openai_api_key: Optional[str] = None,
|
|
77
77
|
log_handler=None,
|
|
78
|
-
tool_primitive: ToolPrimitive
|
|
78
|
+
tool_primitive: Optional[ToolPrimitive] = None,
|
|
79
79
|
recursion_depth: int = 0,
|
|
80
|
-
tool_paths:
|
|
81
|
-
external_config:
|
|
82
|
-
run_id: str
|
|
83
|
-
source_file_path: str
|
|
80
|
+
tool_paths: Optional[List[str]] = None,
|
|
81
|
+
external_config: Optional[Dict[str, Any]] = None,
|
|
82
|
+
run_id: Optional[str] = None,
|
|
83
|
+
source_file_path: Optional[str] = None,
|
|
84
84
|
):
|
|
85
85
|
"""
|
|
86
86
|
Initialize the Tactus runtime.
|
|
@@ -144,31 +144,31 @@ class TactusRuntime:
|
|
|
144
144
|
self.source_file_path = source_file_path
|
|
145
145
|
|
|
146
146
|
# Will be initialized during setup
|
|
147
|
-
self.config:
|
|
148
|
-
self.registry: ProcedureRegistry
|
|
149
|
-
self.lua_sandbox: LuaSandbox
|
|
150
|
-
self.output_validator: OutputValidator
|
|
151
|
-
self.template_resolver: TemplateResolver
|
|
152
|
-
self.message_history_manager: MessageHistoryManager
|
|
147
|
+
self.config: Optional[Dict[str, Any]] = None # Legacy YAML support
|
|
148
|
+
self.registry: Optional[ProcedureRegistry] = None # New DSL registry
|
|
149
|
+
self.lua_sandbox: Optional[LuaSandbox] = None
|
|
150
|
+
self.output_validator: Optional[OutputValidator] = None
|
|
151
|
+
self.template_resolver: Optional[TemplateResolver] = None
|
|
152
|
+
self.message_history_manager: Optional[MessageHistoryManager] = None
|
|
153
153
|
|
|
154
154
|
# Execution context
|
|
155
|
-
self.execution_context: BaseExecutionContext
|
|
155
|
+
self.execution_context: Optional[BaseExecutionContext] = None
|
|
156
156
|
|
|
157
157
|
# Primitives (shared across all agents)
|
|
158
|
-
self.state_primitive: StatePrimitive
|
|
159
|
-
self.iterations_primitive: IterationsPrimitive
|
|
160
|
-
self.stop_primitive: StopPrimitive
|
|
161
|
-
self.tool_primitive: ToolPrimitive
|
|
162
|
-
self.human_primitive: HumanPrimitive
|
|
163
|
-
self.step_primitive: StepPrimitive
|
|
164
|
-
self.checkpoint_primitive: CheckpointPrimitive
|
|
165
|
-
self.log_primitive: LogPrimitive
|
|
166
|
-
self.json_primitive: JsonPrimitive
|
|
167
|
-
self.retry_primitive: RetryPrimitive
|
|
168
|
-
self.file_primitive: FilePrimitive
|
|
169
|
-
self.procedure_primitive: ProcedurePrimitive
|
|
170
|
-
self.system_primitive: SystemPrimitive
|
|
171
|
-
self.host_primitive: HostPrimitive
|
|
158
|
+
self.state_primitive: Optional[StatePrimitive] = None
|
|
159
|
+
self.iterations_primitive: Optional[IterationsPrimitive] = None
|
|
160
|
+
self.stop_primitive: Optional[StopPrimitive] = None
|
|
161
|
+
self.tool_primitive: Optional[ToolPrimitive] = None
|
|
162
|
+
self.human_primitive: Optional[HumanPrimitive] = None
|
|
163
|
+
self.step_primitive: Optional[StepPrimitive] = None
|
|
164
|
+
self.checkpoint_primitive: Optional[CheckpointPrimitive] = None
|
|
165
|
+
self.log_primitive: Optional[LogPrimitive] = None
|
|
166
|
+
self.json_primitive: Optional[JsonPrimitive] = None
|
|
167
|
+
self.retry_primitive: Optional[RetryPrimitive] = None
|
|
168
|
+
self.file_primitive: Optional[FilePrimitive] = None
|
|
169
|
+
self.procedure_primitive: Optional[ProcedurePrimitive] = None
|
|
170
|
+
self.system_primitive: Optional[SystemPrimitive] = None
|
|
171
|
+
self.host_primitive: Optional[HostPrimitive] = None
|
|
172
172
|
|
|
173
173
|
# Agent primitives (one per agent)
|
|
174
174
|
self.agents: dict[str, Any] = {}
|
|
@@ -181,17 +181,17 @@ class TactusRuntime:
|
|
|
181
181
|
|
|
182
182
|
# User dependencies (HTTP clients, DB connections, etc.)
|
|
183
183
|
self.user_dependencies: dict[str, Any] = {}
|
|
184
|
-
self.dependency_manager: Any
|
|
184
|
+
self.dependency_manager: Optional[Any] = None # ResourceManager for cleanup
|
|
185
185
|
|
|
186
186
|
# Mock manager for testing
|
|
187
|
-
self.mock_manager: Any
|
|
188
|
-
self.external_agent_mocks:
|
|
187
|
+
self.mock_manager: Optional[Any] = None # MockManager instance
|
|
188
|
+
self.external_agent_mocks: Optional[Dict[str, List[Dict[str, Any]]]] = None
|
|
189
189
|
self.mock_all_agents: bool = False
|
|
190
190
|
|
|
191
191
|
logger.info("TactusRuntime initialized for procedure %s", procedure_id)
|
|
192
192
|
|
|
193
193
|
async def execute(
|
|
194
|
-
self, source: str, context:
|
|
194
|
+
self, source: str, context: Optional[Dict[str, Any]] = None, format: str = "yaml"
|
|
195
195
|
) -> dict[str, Any]:
|
|
196
196
|
"""
|
|
197
197
|
Execute a workflow (Lua DSL or legacy YAML format).
|
|
@@ -221,17 +221,7 @@ class TactusRuntime:
|
|
|
221
221
|
logger.info("Step 0: Setting up Lua sandbox")
|
|
222
222
|
strict_determinism = self.external_config.get("strict_determinism", False)
|
|
223
223
|
|
|
224
|
-
|
|
225
|
-
# This ensures require() works correctly even when running from different directories
|
|
226
|
-
sandbox_base_path = None
|
|
227
|
-
if self.source_file_path:
|
|
228
|
-
from pathlib import Path
|
|
229
|
-
|
|
230
|
-
sandbox_base_path = str(Path(self.source_file_path).parent.resolve())
|
|
231
|
-
logger.debug(
|
|
232
|
-
"Using source file directory as sandbox base_path: %s",
|
|
233
|
-
sandbox_base_path,
|
|
234
|
-
)
|
|
224
|
+
sandbox_base_path = self._resolve_sandbox_base_path()
|
|
235
225
|
|
|
236
226
|
self.lua_sandbox = LuaSandbox(
|
|
237
227
|
execution_context=None,
|
|
@@ -242,13 +232,7 @@ class TactusRuntime:
|
|
|
242
232
|
# 0.5. Create execution context EARLY so it's available during DSL parsing
|
|
243
233
|
# This is critical for immediate agent creation during parsing
|
|
244
234
|
logger.info("Step 0.5: Creating execution context (early)")
|
|
245
|
-
self.execution_context =
|
|
246
|
-
procedure_id=self.procedure_id,
|
|
247
|
-
storage_backend=self.storage_backend,
|
|
248
|
-
hitl_handler=self.hitl_handler,
|
|
249
|
-
strict_determinism=strict_determinism,
|
|
250
|
-
log_handler=self.log_handler,
|
|
251
|
-
)
|
|
235
|
+
self.execution_context = self._create_execution_context(strict_determinism)
|
|
252
236
|
|
|
253
237
|
# Set run_id if provided
|
|
254
238
|
if self.run_id:
|
|
@@ -788,9 +772,33 @@ class TactusRuntime:
|
|
|
788
772
|
except Exception as e:
|
|
789
773
|
logger.warning("Error cleaning up dependencies: %s", e)
|
|
790
774
|
|
|
775
|
+
def _resolve_sandbox_base_path(self) -> Optional[str]:
|
|
776
|
+
# Compute base_path for sandbox from source file path if available.
|
|
777
|
+
# This ensures require() works correctly even when running from different directories.
|
|
778
|
+
if not self.source_file_path:
|
|
779
|
+
return None
|
|
780
|
+
|
|
781
|
+
from pathlib import Path
|
|
782
|
+
|
|
783
|
+
sandbox_base_path = str(Path(self.source_file_path).parent.resolve())
|
|
784
|
+
logger.debug(
|
|
785
|
+
"Using source file directory as sandbox base_path: %s",
|
|
786
|
+
sandbox_base_path,
|
|
787
|
+
)
|
|
788
|
+
return sandbox_base_path
|
|
789
|
+
|
|
790
|
+
def _create_execution_context(self, strict_determinism: bool) -> BaseExecutionContext:
|
|
791
|
+
return BaseExecutionContext(
|
|
792
|
+
procedure_id=self.procedure_id,
|
|
793
|
+
storage_backend=self.storage_backend,
|
|
794
|
+
hitl_handler=self.hitl_handler,
|
|
795
|
+
strict_determinism=strict_determinism,
|
|
796
|
+
log_handler=self.log_handler,
|
|
797
|
+
)
|
|
798
|
+
|
|
791
799
|
async def _initialize_primitives(
|
|
792
800
|
self,
|
|
793
|
-
placeholder_tool: ToolPrimitive
|
|
801
|
+
placeholder_tool: Optional[ToolPrimitive] = None,
|
|
794
802
|
):
|
|
795
803
|
"""Initialize all primitive objects.
|
|
796
804
|
|
|
@@ -828,7 +836,7 @@ class TactusRuntime:
|
|
|
828
836
|
|
|
829
837
|
logger.debug("All primitives initialized")
|
|
830
838
|
|
|
831
|
-
def resolve_toolset(self, name: str) -> Any
|
|
839
|
+
def resolve_toolset(self, name: str) -> Optional[Any]:
|
|
832
840
|
"""
|
|
833
841
|
Resolve a toolset by name from runtime's registered toolsets.
|
|
834
842
|
|
|
@@ -1039,7 +1047,7 @@ class TactusRuntime:
|
|
|
1039
1047
|
for name, toolset in self.toolset_registry.items():
|
|
1040
1048
|
logger.debug(f" - {name}: {type(toolset)} -> {toolset}")
|
|
1041
1049
|
|
|
1042
|
-
async def _resolve_tool_source(self, tool_name: str, source: str) -> Any
|
|
1050
|
+
async def _resolve_tool_source(self, tool_name: str, source: str) -> Optional[Any]:
|
|
1043
1051
|
"""
|
|
1044
1052
|
Resolve a tool from an external source.
|
|
1045
1053
|
|
|
@@ -1434,7 +1442,7 @@ class TactusRuntime:
|
|
|
1434
1442
|
|
|
1435
1443
|
async def _create_toolset_from_config(
|
|
1436
1444
|
self, name: str, definition: dict[str, Any]
|
|
1437
|
-
) -> Any
|
|
1445
|
+
) -> Optional[Any]:
|
|
1438
1446
|
"""
|
|
1439
1447
|
Create toolset from YAML config definition.
|
|
1440
1448
|
|
|
@@ -2186,7 +2194,7 @@ class TactusRuntime:
|
|
|
2186
2194
|
if is_required:
|
|
2187
2195
|
fields[field_name] = (field_type, ...) # Required field
|
|
2188
2196
|
else:
|
|
2189
|
-
fields[field_name] = (field_type
|
|
2197
|
+
fields[field_name] = (Optional[field_type], None) # Optional field
|
|
2190
2198
|
|
|
2191
2199
|
return create_model(model_name, **fields)
|
|
2192
2200
|
|
|
@@ -2644,7 +2652,7 @@ class TactusRuntime:
|
|
|
2644
2652
|
in_body = False
|
|
2645
2653
|
brace_depth = 0
|
|
2646
2654
|
function_depth = 0 # Track function...end blocks
|
|
2647
|
-
long_string_eq: str
|
|
2655
|
+
long_string_eq: Optional[str] = None
|
|
2648
2656
|
|
|
2649
2657
|
decl_start = re.compile(
|
|
2650
2658
|
r"^\s*(?:"
|
|
@@ -2863,7 +2871,7 @@ class TactusRuntime:
|
|
|
2863
2871
|
return False
|
|
2864
2872
|
|
|
2865
2873
|
def _parse_declarations(
|
|
2866
|
-
self, source: str, tool_primitive: ToolPrimitive
|
|
2874
|
+
self, source: str, tool_primitive: Optional[ToolPrimitive] = None
|
|
2867
2875
|
) -> ProcedureRegistry:
|
|
2868
2876
|
"""
|
|
2869
2877
|
Execute .tac to collect declarations.
|
tactus/dspy/broker_lm.py
CHANGED
|
@@ -11,7 +11,7 @@ while still supporting streaming via DSPy's `streamify()` mechanism.
|
|
|
11
11
|
from __future__ import annotations
|
|
12
12
|
|
|
13
13
|
import logging
|
|
14
|
-
from typing import Any
|
|
14
|
+
from typing import Any, Dict, List, Optional
|
|
15
15
|
|
|
16
16
|
import dspy
|
|
17
17
|
import litellm
|
|
@@ -42,10 +42,10 @@ class BrokeredLM(dspy.BaseLM):
|
|
|
42
42
|
model: str,
|
|
43
43
|
*,
|
|
44
44
|
model_type: str = "chat",
|
|
45
|
-
temperature: float
|
|
46
|
-
max_tokens: int
|
|
47
|
-
cache: bool
|
|
48
|
-
socket_path: str
|
|
45
|
+
temperature: Optional[float] = None,
|
|
46
|
+
max_tokens: Optional[int] = None,
|
|
47
|
+
cache: Optional[bool] = None,
|
|
48
|
+
socket_path: Optional[str] = None,
|
|
49
49
|
**kwargs: Any,
|
|
50
50
|
):
|
|
51
51
|
if model_type != "chat":
|
|
@@ -70,12 +70,18 @@ class BrokeredLM(dspy.BaseLM):
|
|
|
70
70
|
self._client = env_client
|
|
71
71
|
|
|
72
72
|
def forward(
|
|
73
|
-
self,
|
|
73
|
+
self,
|
|
74
|
+
prompt: Optional[str] = None,
|
|
75
|
+
messages: Optional[List[Dict[str, Any]]] = None,
|
|
76
|
+
**kwargs: Any,
|
|
74
77
|
):
|
|
75
78
|
return syncify(self.aforward)(prompt=prompt, messages=messages, **kwargs)
|
|
76
79
|
|
|
77
80
|
async def aforward(
|
|
78
|
-
self,
|
|
81
|
+
self,
|
|
82
|
+
prompt: Optional[str] = None,
|
|
83
|
+
messages: Optional[List[Dict[str, Any]]] = None,
|
|
84
|
+
**kwargs: Any,
|
|
79
85
|
):
|
|
80
86
|
provider, model_id = _split_provider_model(self.model)
|
|
81
87
|
|
tactus/dspy/config.py
CHANGED
|
@@ -103,10 +103,13 @@ def configure_lm(
|
|
|
103
103
|
|
|
104
104
|
logger = logging.getLogger(__name__)
|
|
105
105
|
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
106
|
+
try:
|
|
107
|
+
adapter = ChatAdapter(use_native_function_calling=True)
|
|
108
|
+
except TypeError:
|
|
109
|
+
adapter = ChatAdapter()
|
|
110
|
+
|
|
111
|
+
use_native = getattr(adapter, "use_native_function_calling", None)
|
|
112
|
+
logger.info(f"[ADAPTER] Created ChatAdapter with use_native_function_calling={use_native}")
|
|
110
113
|
|
|
111
114
|
# Set as global default with adapter
|
|
112
115
|
dspy.configure(lm=lm, adapter=adapter)
|