flock-core 0.4.0b26__py3-none-any.whl → 0.4.0b27__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.
Potentially problematic release.
This version of flock-core might be problematic. Click here for more details.
- flock/core/context/context.py +10 -1
- flock/core/execution/temporal_executor.py +129 -20
- flock/core/flock.py +46 -2
- flock/core/flock_agent.py +145 -142
- flock/core/flock_factory.py +3 -0
- flock/workflow/agent_execution_activity.py +228 -0
- flock/workflow/flock_workflow.py +195 -28
- flock/workflow/temporal_config.py +96 -0
- flock/workflow/temporal_setup.py +23 -26
- {flock_core-0.4.0b26.dist-info → flock_core-0.4.0b27.dist-info}/METADATA +31 -5
- {flock_core-0.4.0b26.dist-info → flock_core-0.4.0b27.dist-info}/RECORD +14 -12
- {flock_core-0.4.0b26.dist-info → flock_core-0.4.0b27.dist-info}/WHEEL +0 -0
- {flock_core-0.4.0b26.dist-info → flock_core-0.4.0b27.dist-info}/entry_points.txt +0 -0
- {flock_core-0.4.0b26.dist-info → flock_core-0.4.0b27.dist-info}/licenses/LICENSE +0 -0
flock/workflow/flock_workflow.py
CHANGED
|
@@ -1,12 +1,22 @@
|
|
|
1
1
|
from datetime import timedelta
|
|
2
|
+
from typing import Any
|
|
2
3
|
|
|
3
4
|
from temporalio import workflow
|
|
4
5
|
|
|
5
|
-
from
|
|
6
|
-
|
|
7
|
-
from flock.
|
|
8
|
-
|
|
9
|
-
|
|
6
|
+
# Import activities from the new file
|
|
7
|
+
with workflow.unsafe.imports_passed_through():
|
|
8
|
+
from flock.core.context.context import AgentDefinition, FlockContext
|
|
9
|
+
from flock.core.context.context_vars import FLOCK_CURRENT_AGENT
|
|
10
|
+
from flock.core.flock_router import HandOffRequest
|
|
11
|
+
from flock.core.logging.logging import get_logger
|
|
12
|
+
from flock.workflow.agent_execution_activity import (
|
|
13
|
+
determine_next_agent,
|
|
14
|
+
execute_single_agent,
|
|
15
|
+
)
|
|
16
|
+
from flock.workflow.temporal_config import (
|
|
17
|
+
TemporalActivityConfig,
|
|
18
|
+
TemporalRetryPolicyConfig,
|
|
19
|
+
)
|
|
10
20
|
|
|
11
21
|
|
|
12
22
|
logger = get_logger("workflow")
|
|
@@ -14,45 +24,202 @@ logger = get_logger("workflow")
|
|
|
14
24
|
|
|
15
25
|
@workflow.defn
|
|
16
26
|
class FlockWorkflow:
|
|
17
|
-
|
|
18
|
-
self.context = None
|
|
27
|
+
# No need for __init__ storing context anymore if passed to run
|
|
19
28
|
|
|
20
29
|
@workflow.run
|
|
21
|
-
async def run(self,
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
30
|
+
async def run(self, workflow_args: dict[str, Any]) -> dict:
|
|
31
|
+
# --- Workflow Initialization ---
|
|
32
|
+
# Arguments are packed into a single dictionary
|
|
33
|
+
context_dict = workflow_args["context_dict"]
|
|
34
|
+
default_retry_config_dict = workflow_args["default_retry_config_dict"]
|
|
35
|
+
|
|
36
|
+
# Deserialize context and default retry config
|
|
37
|
+
context = FlockContext.from_dict(context_dict)
|
|
38
|
+
default_retry_config = TemporalRetryPolicyConfig.model_validate(
|
|
39
|
+
default_retry_config_dict
|
|
40
|
+
)
|
|
41
|
+
|
|
42
|
+
context.workflow_id = workflow.info().workflow_id
|
|
43
|
+
context.workflow_timestamp = workflow.info().start_time.strftime(
|
|
44
|
+
"%Y-%m-%d %H:%M:%S"
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
current_agent_name = context.get_variable(FLOCK_CURRENT_AGENT)
|
|
48
|
+
final_result = None
|
|
49
|
+
previous_agent_name = (
|
|
50
|
+
None # Keep track of the agent that called the current one
|
|
51
|
+
)
|
|
52
|
+
|
|
53
|
+
logger.info(
|
|
54
|
+
"Starting workflow execution",
|
|
55
|
+
workflow_id=context.workflow_id,
|
|
56
|
+
start_time=context.workflow_timestamp,
|
|
57
|
+
initial_agent=current_agent_name,
|
|
58
|
+
)
|
|
25
59
|
|
|
26
60
|
try:
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
61
|
+
while current_agent_name:
|
|
62
|
+
logger.info(
|
|
63
|
+
"Executing agent activity", agent=current_agent_name
|
|
64
|
+
)
|
|
31
65
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
66
|
+
# --- Determine Activity Settings ---
|
|
67
|
+
agent_def: AgentDefinition | None = (
|
|
68
|
+
context.get_agent_definition(current_agent_name)
|
|
69
|
+
)
|
|
70
|
+
agent_activity_config: TemporalActivityConfig | None = None
|
|
71
|
+
final_retry_config = (
|
|
72
|
+
default_retry_config # Start with the workflow default
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
if agent_def and agent_def.agent_data.get(
|
|
76
|
+
"temporal_activity_config"
|
|
77
|
+
):
|
|
78
|
+
try:
|
|
79
|
+
agent_activity_config = (
|
|
80
|
+
TemporalActivityConfig.model_validate(
|
|
81
|
+
agent_def.agent_data["temporal_activity_config"]
|
|
82
|
+
)
|
|
83
|
+
)
|
|
84
|
+
logger.debug(
|
|
85
|
+
f"Loaded agent-specific temporal config for {current_agent_name}"
|
|
86
|
+
)
|
|
87
|
+
except Exception as e:
|
|
88
|
+
logger.warn(
|
|
89
|
+
f"Failed to validate agent temporal config for {current_agent_name}: {e}. Using defaults."
|
|
90
|
+
)
|
|
91
|
+
|
|
92
|
+
# Layering logic: Agent config overrides workflow default config
|
|
93
|
+
activity_task_queue = (
|
|
94
|
+
workflow.info().task_queue
|
|
95
|
+
) # Default to workflow task queue
|
|
96
|
+
activity_timeout = timedelta(
|
|
97
|
+
minutes=5
|
|
98
|
+
) # Fallback default timeout
|
|
99
|
+
|
|
100
|
+
if agent_activity_config:
|
|
101
|
+
activity_task_queue = (
|
|
102
|
+
agent_activity_config.task_queue or activity_task_queue
|
|
103
|
+
)
|
|
104
|
+
activity_timeout = (
|
|
105
|
+
agent_activity_config.start_to_close_timeout
|
|
106
|
+
or activity_timeout
|
|
107
|
+
)
|
|
108
|
+
if agent_activity_config.retry_policy:
|
|
109
|
+
final_retry_config = agent_activity_config.retry_policy
|
|
110
|
+
|
|
111
|
+
# Convert config to actual Temporal object
|
|
112
|
+
final_retry_policy = final_retry_config.to_temporalio_policy()
|
|
113
|
+
|
|
114
|
+
logger.debug(
|
|
115
|
+
f"Final activity settings for {current_agent_name}: "
|
|
116
|
+
f"queue='{activity_task_queue}', timeout={activity_timeout}, "
|
|
117
|
+
f"retries={final_retry_policy.maximum_attempts}"
|
|
118
|
+
)
|
|
37
119
|
|
|
38
|
-
|
|
120
|
+
# --- Execute the current agent activity ---
|
|
121
|
+
agent_result = await workflow.execute_activity(
|
|
122
|
+
execute_single_agent,
|
|
123
|
+
args=[current_agent_name, context],
|
|
124
|
+
task_queue=activity_task_queue, # Use determined task queue
|
|
125
|
+
start_to_close_timeout=activity_timeout, # Use determined timeout
|
|
126
|
+
retry_policy=final_retry_policy, # Use determined retry policy
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
# Record the execution in the context history
|
|
130
|
+
# Note: The 'called_from' is the agent *before* this one
|
|
131
|
+
context.record(
|
|
132
|
+
agent_name=current_agent_name,
|
|
133
|
+
data=agent_result,
|
|
134
|
+
timestamp=workflow.now().isoformat(), # Use deterministic workflow time
|
|
135
|
+
hand_off=None, # Will be updated if handoff occurs
|
|
136
|
+
called_from=previous_agent_name, # Pass the correct previous agent
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
final_result = agent_result # Store the result of the last successful agent
|
|
140
|
+
|
|
141
|
+
logger.info(
|
|
142
|
+
"Determining next agent activity",
|
|
143
|
+
current_agent=current_agent_name,
|
|
144
|
+
)
|
|
145
|
+
# --- Determine the next agent activity (using workflow defaults for now) ---
|
|
146
|
+
# We could apply similar config logic to determine_next_agent if needed
|
|
147
|
+
handoff_data_dict = await workflow.execute_activity(
|
|
148
|
+
determine_next_agent,
|
|
149
|
+
args=[current_agent_name, agent_result, context],
|
|
150
|
+
# Using sensible defaults, but could be configured via workflow_config?
|
|
151
|
+
start_to_close_timeout=timedelta(minutes=1),
|
|
152
|
+
retry_policy=default_retry_config.to_temporalio_policy(), # Use default retry
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
# Update previous agent name for the next loop iteration
|
|
156
|
+
previous_agent_name = current_agent_name
|
|
157
|
+
|
|
158
|
+
if handoff_data_dict:
|
|
159
|
+
logger.debug(
|
|
160
|
+
"Handoff data received", data=handoff_data_dict
|
|
161
|
+
)
|
|
162
|
+
# Deserialize handoff data back into Pydantic model for easier access
|
|
163
|
+
handoff_request = HandOffRequest.model_validate(
|
|
164
|
+
handoff_data_dict
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
# Update context based on handoff overrides
|
|
168
|
+
if handoff_request.override_context:
|
|
169
|
+
context.state.update(handoff_request.override_context)
|
|
170
|
+
logger.info("Context updated based on handoff override")
|
|
171
|
+
|
|
172
|
+
# Update the last record's handoff information
|
|
173
|
+
if context.history:
|
|
174
|
+
context.history[-1].hand_off = handoff_data_dict
|
|
175
|
+
|
|
176
|
+
# Set the next agent
|
|
177
|
+
current_agent_name = handoff_request.next_agent
|
|
178
|
+
if current_agent_name:
|
|
179
|
+
context.set_variable(
|
|
180
|
+
FLOCK_CURRENT_AGENT, current_agent_name
|
|
181
|
+
)
|
|
182
|
+
logger.info("Next agent set", agent=current_agent_name)
|
|
183
|
+
else:
|
|
184
|
+
logger.info(
|
|
185
|
+
"Handoff requested termination (no next agent)"
|
|
186
|
+
)
|
|
187
|
+
break # Exit loop if router explicitly returned no next agent
|
|
188
|
+
|
|
189
|
+
else:
|
|
190
|
+
# No handoff data returned (no router or router returned None)
|
|
191
|
+
logger.info("No handoff occurred, workflow terminating.")
|
|
192
|
+
current_agent_name = None # End the loop
|
|
193
|
+
|
|
194
|
+
# --- Workflow Completion ---
|
|
195
|
+
logger.success(
|
|
196
|
+
"Workflow completed successfully",
|
|
197
|
+
final_agent=previous_agent_name,
|
|
198
|
+
)
|
|
199
|
+
context.set_variable(
|
|
39
200
|
"flock.result",
|
|
40
201
|
{
|
|
41
|
-
"result": result
|
|
202
|
+
"result": final_result, # Return the last agent's result
|
|
42
203
|
"success": True,
|
|
43
204
|
},
|
|
44
205
|
)
|
|
45
|
-
|
|
46
|
-
logger.success("Workflow completed successfully")
|
|
47
|
-
return result
|
|
206
|
+
return final_result # Return the actual result of the last agent
|
|
48
207
|
|
|
49
208
|
except Exception as e:
|
|
209
|
+
# Catch exceptions from activities (e.g., after retries fail)
|
|
210
|
+
# or workflow logic errors
|
|
50
211
|
logger.exception("Workflow execution failed", error=str(e))
|
|
51
|
-
|
|
212
|
+
context.set_variable(
|
|
52
213
|
"flock.result",
|
|
53
214
|
{
|
|
54
|
-
"result": f"
|
|
215
|
+
"result": f"Workflow failed: {e}",
|
|
55
216
|
"success": False,
|
|
56
217
|
},
|
|
57
218
|
)
|
|
58
|
-
|
|
219
|
+
# It's often better to let Temporal record the failure status
|
|
220
|
+
# by re-raising the exception rather than returning a custom error dict.
|
|
221
|
+
# However, returning the context might be useful for debugging.
|
|
222
|
+
# Consider re-raising: raise
|
|
223
|
+
return context.model_dump(
|
|
224
|
+
mode="json"
|
|
225
|
+
) # Return context state on failure
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
# src/flock/config/temporal_config.py
|
|
2
|
+
|
|
3
|
+
"""Pydantic models for configuring Temporal execution settings."""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from datetime import timedelta
|
|
8
|
+
from typing import TYPE_CHECKING
|
|
9
|
+
|
|
10
|
+
# Conditionally import for type hinting only
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from temporalio.common import RetryPolicy
|
|
13
|
+
|
|
14
|
+
# Note: Importing temporalio types directly into config models can complicate serialization
|
|
15
|
+
# if these models are meant to be purely data containers (e.g., for YAML/JSON).
|
|
16
|
+
# We define the structure and provide a helper method to convert to the actual Temporal object.
|
|
17
|
+
# Be careful if using workflow/activity decorators directly on methods within these config models.
|
|
18
|
+
from pydantic import BaseModel, Field
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class TemporalRetryPolicyConfig(BaseModel):
|
|
22
|
+
"""Configuration parameters for Temporal Retry Policies."""
|
|
23
|
+
|
|
24
|
+
initial_interval: timedelta = Field(
|
|
25
|
+
default=timedelta(seconds=1),
|
|
26
|
+
description="Initial delay before the first retry.",
|
|
27
|
+
)
|
|
28
|
+
backoff_coefficient: float = Field(
|
|
29
|
+
default=2.0, description="Multiplier for the delay between retries."
|
|
30
|
+
)
|
|
31
|
+
maximum_interval: timedelta | None = Field(
|
|
32
|
+
default=timedelta(seconds=100),
|
|
33
|
+
description="Maximum delay between retries.",
|
|
34
|
+
)
|
|
35
|
+
maximum_attempts: int = Field(
|
|
36
|
+
default=3,
|
|
37
|
+
description="Maximum number of retry attempts (0 means no retries after first failure).",
|
|
38
|
+
)
|
|
39
|
+
non_retryable_error_types: list[str] = Field(
|
|
40
|
+
default_factory=list,
|
|
41
|
+
description="List of error type names (strings) that should not be retried.",
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
# Helper to convert to actual Temporalio object when needed (e.g., in workflow/executor)
|
|
45
|
+
def to_temporalio_policy(self) -> RetryPolicy:
|
|
46
|
+
# Import locally to avoid making temporalio a hard dependency of the config module itself
|
|
47
|
+
# The type hint RetryPolicy is now available due to TYPE_CHECKING block
|
|
48
|
+
from temporalio.common import RetryPolicy
|
|
49
|
+
|
|
50
|
+
return RetryPolicy(
|
|
51
|
+
initial_interval=self.initial_interval,
|
|
52
|
+
backoff_coefficient=self.backoff_coefficient,
|
|
53
|
+
maximum_interval=self.maximum_interval,
|
|
54
|
+
maximum_attempts=self.maximum_attempts,
|
|
55
|
+
non_retryable_error_types=self.non_retryable_error_types,
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
|
|
59
|
+
class TemporalWorkflowConfig(BaseModel):
|
|
60
|
+
"""Configuration specific to Temporal Workflow Execution for a Flock."""
|
|
61
|
+
|
|
62
|
+
task_queue: str = Field(
|
|
63
|
+
default="flock-queue",
|
|
64
|
+
description="Default task queue for the workflow execution.",
|
|
65
|
+
)
|
|
66
|
+
workflow_execution_timeout: timedelta | None = Field(
|
|
67
|
+
default=None, # Default to no timeout (Temporal server default)
|
|
68
|
+
description="Total time limit for the workflow execution.",
|
|
69
|
+
)
|
|
70
|
+
workflow_run_timeout: timedelta | None = Field(
|
|
71
|
+
default=None, # Default to no timeout (Temporal server default)
|
|
72
|
+
description="Time limit for a single workflow run attempt.",
|
|
73
|
+
)
|
|
74
|
+
# Default retry policy for activities if not specified per-agent
|
|
75
|
+
default_activity_retry_policy: TemporalRetryPolicyConfig = Field(
|
|
76
|
+
default_factory=TemporalRetryPolicyConfig,
|
|
77
|
+
description="Default retry policy applied to activities if not overridden by the agent.",
|
|
78
|
+
)
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
class TemporalActivityConfig(BaseModel):
|
|
82
|
+
"""Configuration specific to Temporal Activity Execution (per Agent)."""
|
|
83
|
+
|
|
84
|
+
task_queue: str | None = Field(
|
|
85
|
+
default=None,
|
|
86
|
+
description="Specific task queue for this agent's activity execution (overrides workflow default).",
|
|
87
|
+
)
|
|
88
|
+
start_to_close_timeout: timedelta | None = Field(
|
|
89
|
+
default=timedelta(minutes=5), # Default to 5 minutes
|
|
90
|
+
description="Time limit for a single activity attempt.",
|
|
91
|
+
)
|
|
92
|
+
retry_policy: TemporalRetryPolicyConfig | None = Field(
|
|
93
|
+
default=None,
|
|
94
|
+
description="Specific retry policy for this activity (overrides workflow default).",
|
|
95
|
+
)
|
|
96
|
+
# Other timeouts like schedule_to_start, heartbeat_timeout could be added here if needed
|
flock/workflow/temporal_setup.py
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import asyncio
|
|
2
|
-
import traceback
|
|
3
1
|
import uuid
|
|
4
2
|
|
|
5
3
|
from temporalio.client import Client
|
|
@@ -7,34 +5,33 @@ from temporalio.worker import Worker
|
|
|
7
5
|
|
|
8
6
|
|
|
9
7
|
async def create_temporal_client() -> Client:
|
|
8
|
+
# Consider making the address configurable
|
|
10
9
|
client = await Client.connect("localhost:7233")
|
|
11
10
|
return client
|
|
12
11
|
|
|
13
12
|
|
|
14
|
-
async def setup_worker(
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
traceback.print_exc()
|
|
37
|
-
raise
|
|
13
|
+
async def setup_worker(
|
|
14
|
+
client: Client, task_queue: str, workflow: type, activities: list
|
|
15
|
+
) -> Worker:
|
|
16
|
+
"""Creates and configures a worker instance, but does not run it.
|
|
17
|
+
|
|
18
|
+
Args:
|
|
19
|
+
client: The Temporal client to associate with the worker.
|
|
20
|
+
task_queue: The task queue the worker should listen on.
|
|
21
|
+
workflow: The workflow class definition.
|
|
22
|
+
activities: A list of activity functions.
|
|
23
|
+
|
|
24
|
+
Returns:
|
|
25
|
+
A configured Worker instance.
|
|
26
|
+
"""
|
|
27
|
+
# Creates and configures the worker instance
|
|
28
|
+
worker = Worker(
|
|
29
|
+
client,
|
|
30
|
+
task_queue=task_queue,
|
|
31
|
+
workflows=[workflow],
|
|
32
|
+
activities=activities,
|
|
33
|
+
)
|
|
34
|
+
return worker # Return the configured worker instance
|
|
38
35
|
|
|
39
36
|
|
|
40
37
|
async def run_worker(client: Client, task_queue: str, workflows, activities):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: flock-core
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.0b27
|
|
4
4
|
Summary: Declarative LLM Orchestration at Scale
|
|
5
5
|
Author-email: Andre Ratzenberger <andre.ratzenberger@whiteduck.de>
|
|
6
6
|
License-File: LICENSE
|
|
@@ -216,13 +216,39 @@ if __name__ == "__main__":
|
|
|
216
216
|
|
|
217
217
|
## 🐤 New in Flock 0.4.0 `Magpie` 🐤
|
|
218
218
|
|
|
219
|
-
|
|
219
|
+
Version 0.4.0 brings significant enhancements focused on usability, deployment, and robustness:
|
|
220
220
|
|
|
221
|
-
### Web UI - Test Flock Agents in the Browser
|
|
222
221
|
|
|
223
|
-
###
|
|
222
|
+
### 🚀 REST API - Deploy Flock Agents as REST API Endpoints
|
|
224
223
|
|
|
225
|
-
|
|
224
|
+
Easily deploy your Flock agents as scalable REST API endpoints. Interact with your agent workflows via standard HTTP requests.
|
|
225
|
+
|
|
226
|
+
### 🖥️ Web UI - Test Flock Agents in the Browser
|
|
227
|
+
|
|
228
|
+
Test and interact with your Flock agents directly in your browser through an integrated web interface.
|
|
229
|
+
|
|
230
|
+
### ⌨️ CLI Tool - Manage Flock Agents via the Command Line
|
|
231
|
+
|
|
232
|
+
Manage Flock configurations, run agents, and inspect results directly from your command line.
|
|
233
|
+
|
|
234
|
+
### 💾 Enhanced Serialization - Share, Deploy, and Run Flock Agents by human readable yaml files
|
|
235
|
+
|
|
236
|
+
Define and share entire Flock configurations, including agents and components, using human-readable YAML files. Load flocks directly from these files for easy deployment and versioning.
|
|
237
|
+
|
|
238
|
+
### ⏱️ Robust Temporal Integration
|
|
239
|
+
|
|
240
|
+
Flock 0.4.0 introduces first-class support for Temporal.io, enabling you to build truly production-grade, reliable, and scalable agent workflows. Move beyond simple local execution and leverage Temporal's power for:
|
|
241
|
+
|
|
242
|
+
* **Fault Tolerance:** Workflows automatically resume from the last successful step after failures.
|
|
243
|
+
* **Retries:** Configure automatic retries for activities (like LLM calls or tool usage) with exponential backoff.
|
|
244
|
+
* **Scalability:** Distribute workflow and activity execution across multiple worker processes using Task Queues.
|
|
245
|
+
* **Observability:** Gain deep insights into workflow execution history via the Temporal UI.
|
|
246
|
+
|
|
247
|
+
Flock makes this easy with:
|
|
248
|
+
|
|
249
|
+
* **Declarative Configuration:** Define Temporal timeouts, retry policies, and task queues directly within your `Flock` and `FlockAgent` configurations (YAML or Python).
|
|
250
|
+
* **Correct Patterns:** Uses Temporal's recommended granular activity execution for better control and visibility.
|
|
251
|
+
* **Clear Worker Separation:** Provides guidance and flags for running dedicated Temporal workers, separating development convenience from production best practices.
|
|
226
252
|
|
|
227
253
|
### ✨ Utility: @flockclass Hydrator
|
|
228
254
|
|
|
@@ -19,10 +19,10 @@ flock/cli/view_results.py,sha256=dOzK0O1FHSIDERnx48y-2Xke9BkOHS7pcOhs64AyIg0,781
|
|
|
19
19
|
flock/cli/yaml_editor.py,sha256=K3N0bh61G1TSDAZDnurqW9e_-hO6CtSQKXQqlDhCjVo,12527
|
|
20
20
|
flock/cli/assets/release_notes.md,sha256=bqnk50jxM3w5uY44Dc7MkdT8XmRREFxrVBAG9XCOSSU,4896
|
|
21
21
|
flock/core/__init__.py,sha256=p7lmQULRu9ejIAELfanZiyMhW0CougIPvyFHW2nqBFQ,847
|
|
22
|
-
flock/core/flock.py,sha256=
|
|
23
|
-
flock/core/flock_agent.py,sha256=
|
|
22
|
+
flock/core/flock.py,sha256=_T_KAFePtEGDzfiFGV1HCdz7VHzj_U0cCquhAQ4xMAM,28199
|
|
23
|
+
flock/core/flock_agent.py,sha256=oOMPw9fmZCAdqJXZsLTbjc4tdIq6gn5_nX3GvPgm61Q,38969
|
|
24
24
|
flock/core/flock_evaluator.py,sha256=dOXZeDOGZcAmJ9ahqq_2bdGUU1VOXY4skmwTVpAjiVw,1685
|
|
25
|
-
flock/core/flock_factory.py,sha256=
|
|
25
|
+
flock/core/flock_factory.py,sha256=_4zsjkEmJnCR7IvJ3SUHnDbX6c7Tt3E4P5ohxwKvE6w,3173
|
|
26
26
|
flock/core/flock_module.py,sha256=96aFVYAgwpKN53xGbivQDUpikOYGFCxK5mqhclOcxY0,3003
|
|
27
27
|
flock/core/flock_registry.py,sha256=Qcu9juUFNyDAOEsqVxauwVlWdfgKZrSzc8yT8JMiK-c,24246
|
|
28
28
|
flock/core/flock_router.py,sha256=1OAXDsdaIIFApEfo6SRfFEDoTuGt3Si7n2MXiySEfis,2644
|
|
@@ -35,14 +35,14 @@ flock/core/api/runner.py,sha256=PjKQyMNawHm_N-X2uTUWBKAKBe7AEzNmRIGwQI6tUWw,1156
|
|
|
35
35
|
flock/core/api/ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
36
36
|
flock/core/api/ui/routes.py,sha256=nS-wWO94mshE5ozWfOQZ-HOvtes_1qxDVcqpMZtU5JQ,8885
|
|
37
37
|
flock/core/api/ui/utils.py,sha256=V7PqYHNK519hFJ8jvvwf7bGpbBXCRz_HQG3BDCCqlNA,4802
|
|
38
|
-
flock/core/context/context.py,sha256=
|
|
38
|
+
flock/core/context/context.py,sha256=GFqMwYXLheqECGvWcxar7sQ2-GuY3RVynZ7kjwd65R0,6875
|
|
39
39
|
flock/core/context/context_manager.py,sha256=FANSWa6DEhdhtZ7t_9Gza0v80UdpoDOhHbfVOccmjkA,1181
|
|
40
40
|
flock/core/context/context_vars.py,sha256=ASPA29hpENWub4mgRoG62FtTVakCHQZfn6IhJQKe3C8,347
|
|
41
41
|
flock/core/evaluation/utils.py,sha256=ZJkIMC9YT-HA2SPCZ4_bQ98isW1i6nbltVEYbjze-b0,12827
|
|
42
42
|
flock/core/execution/batch_executor.py,sha256=nvsFOVaH4c4uPw_gwZ5jCIULpK59EL1kmcoPTja5kko,13745
|
|
43
43
|
flock/core/execution/evaluation_executor.py,sha256=D9EO0sU-2qWj3vomjmUUi-DOtHNJNFRf30kGDHuzREE,17702
|
|
44
44
|
flock/core/execution/local_executor.py,sha256=rnIQvaJOs6zZORUcR3vvyS6LPREDJTjaygl_Db0M8ao,952
|
|
45
|
-
flock/core/execution/temporal_executor.py,sha256=
|
|
45
|
+
flock/core/execution/temporal_executor.py,sha256=dHcb0xuzPFWU_wbwTgI7glLNyyppei93Txs2sapjhaw,6283
|
|
46
46
|
flock/core/interpreter/python_interpreter.py,sha256=RaUMZuufsKBNQ4FAeSaOgUuxzs8VYu5TgUUs-xwaxxM,26376
|
|
47
47
|
flock/core/logging/__init__.py,sha256=Q8hp9-1ilPIUIV0jLgJ3_cP7COrea32cVwL7dicPnlM,82
|
|
48
48
|
flock/core/logging/logging.py,sha256=JcgABQ8QJU1hhzhfF93eqnE0jhyXGZ2oObZst68sKR8,15409
|
|
@@ -440,10 +440,12 @@ flock/themes/zenwritten-light.toml,sha256=G1iEheCPfBNsMTGaVpEVpDzYBHA_T-MV27rolU
|
|
|
440
440
|
flock/workflow/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
441
441
|
flock/workflow/activities.py,sha256=Rcgcepa-RzaEjKo2aNuI14O_sX8ij0RrqeyPa0oSw8M,9910
|
|
442
442
|
flock/workflow/agent_activities.py,sha256=NhBZscflEf2IMfSRa_pBM_TRP7uVEF_O0ROvWZ33eDc,963
|
|
443
|
-
flock/workflow/
|
|
444
|
-
flock/workflow/
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
flock_core-0.4.
|
|
448
|
-
flock_core-0.4.
|
|
449
|
-
flock_core-0.4.
|
|
443
|
+
flock/workflow/agent_execution_activity.py,sha256=Gy6FtuVAjf0NiUXmC3syS2eJpNQF4R3pmwMq47NYW3U,9462
|
|
444
|
+
flock/workflow/flock_workflow.py,sha256=iSUF_soFvWar0ffpkzE4irkDZRx0p4HnwmEBi_Ne2sY,9666
|
|
445
|
+
flock/workflow/temporal_config.py,sha256=3_8O7SDEjMsSMXsWJBfnb6XTp0TFaz39uyzSlMTSF_I,3988
|
|
446
|
+
flock/workflow/temporal_setup.py,sha256=YIHnSBntzOchHfMSh8hoLeNXrz3B1UbR14YrR6soM7A,1606
|
|
447
|
+
flock_core-0.4.0b27.dist-info/METADATA,sha256=N3xUdEq5nlLB7BVjw8gnEaGMsRKJDX5K7w5ogfS5RCw,14825
|
|
448
|
+
flock_core-0.4.0b27.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
449
|
+
flock_core-0.4.0b27.dist-info/entry_points.txt,sha256=rWaS5KSpkTmWySURGFZk6PhbJ87TmvcFQDi2uzjlagQ,37
|
|
450
|
+
flock_core-0.4.0b27.dist-info/licenses/LICENSE,sha256=iYEqWy0wjULzM9GAERaybP4LBiPeu7Z1NEliLUdJKSc,1072
|
|
451
|
+
flock_core-0.4.0b27.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|