feat: Detached Tasks#106
Conversation
There was a problem hiding this comment.
Pull Request Overview
This PR enables tasks to run outside of run contexts while standardizing the API parameter patterns across the codebase. The changes allow for "detached tasks" that can execute independently without requiring an active run, while maintaining backward compatibility for existing run-based workflows.
- Removes hard requirements for run context in task execution
- Standardizes attribute parameter patterns from
**attributestoattributes: AnyDict | None = None - Enhances string cleaning utility and improves API documentation
Reviewed Changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| dreadnode/util.py | Enhanced clean_str function to strip trailing underscores |
| dreadnode/tracing/span.py | Updated span constructors to support optional run context and standardized attribute parameters |
| dreadnode/task.py | Modified task execution to handle missing run context gracefully |
| dreadnode/main.py | Standardized API method signatures and improved documentation |
| docs/sdk/task.mdx | Updated documentation to reflect detached task execution changes |
| docs/sdk/main.mdx | Updated documentation with new parameter signatures and enhanced details |
| run_id=run.run_id if run else "", | ||
| tracer=self.tracer, | ||
| ) as span: | ||
| if self.log_execution_metrics: |
There was a problem hiding this comment.
This line will cause a runtime error when run is None. The code should check if run is not None before calling run.log_metric(), similar to the pattern used elsewhere in this file.
| if self.log_execution_metrics: | |
| if self.log_execution_metrics and run is not None: |
| label: str | None = None, | ||
| event_name: str = EVENT_NAME_OBJECT, | ||
| **attributes: JsonValue, | ||
| attributes: AnyDict | None = None, |
There was a problem hiding this comment.
The signature change from **attributes: JsonValue to attributes: AnyDict | None = None is inconsistent with other log methods in the same class that still use **attributes: JsonValue pattern (lines 610, 725). This creates an inconsistent API within the same class.
| attributes: AnyDict | None = None, | |
| **attributes: JsonValue, |
| **attributes: JsonValue, | ||
| ) -> str: | ||
| label = label or clean_str(name) | ||
| hash_ = self.run.log_object( | ||
| label = clean_str(label or name) |
There was a problem hiding this comment.
This method still uses the old **attributes: JsonValue pattern while other methods in the same class have been updated to use attributes: AnyDict | None = None. This creates inconsistency within the TaskSpan class API.
| **attributes: JsonValue, | ||
| ) -> str: | ||
| label = label or clean_str(name) | ||
| hash_ = self.run.log_object( | ||
| label = clean_str(label or name) |
There was a problem hiding this comment.
This method still uses the old **attributes: JsonValue pattern while other methods in the same class have been updated to use attributes: AnyDict | None = None. This creates inconsistency within the TaskSpan class API.
| raise RuntimeError("log_inputs() must be called within a run") | ||
|
|
||
| target.log_input(name, value, label=label, **attributes) | ||
| target.log_input(name, value, label=label, attributes=attributes) |
There was a problem hiding this comment.
This call will fail because the target's log_input method still expects **attributes: JsonValue but is being called with attributes=attributes. The underlying method signature hasn't been updated to match the new API pattern.
| target.log_input(name, value, label=label, attributes=attributes) | |
| target.log_input(name, value, label=label, **(attributes or {})) |
| ) | ||
|
|
||
| target.log_output(name, value, label=label, **attributes) | ||
| target.log_output(name, value, label=label, attributes=attributes) |
There was a problem hiding this comment.
This call will fail because the target's log_output method still expects **attributes: JsonValue but is being called with attributes=attributes. The underlying method signature hasn't been updated to match the new API pattern.
| target.log_output(name, value, label=label, attributes=attributes) | |
| target.log_output(name, value, label=label, **(attributes or {})) |
Detached Tasks
Key Changes:
Added:
Changed:
Removed:
Generated Summary:
**attributes: JsonValuewithattributes: AnyDict | None.runisNone, preventing possible runtime errors.attributesacross various functions clearly.This summary was generated with ❤️ by rigging