flock-core 0.3.14__py3-none-any.whl → 0.3.16__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.

@@ -1,9 +1,10 @@
1
1
  import uuid
2
- from dataclasses import asdict, dataclass, field
2
+ from dataclasses import asdict
3
3
  from datetime import datetime
4
4
  from typing import Any, Literal
5
5
 
6
6
  from opentelemetry import trace
7
+ from pydantic import BaseModel, Field
7
8
 
8
9
  from flock.core.context.context_vars import FLOCK_LAST_AGENT, FLOCK_LAST_RESULT
9
10
  from flock.core.logging.logging import get_logger
@@ -13,34 +14,31 @@ logger = get_logger("context")
13
14
  tracer = trace.get_tracer(__name__)
14
15
 
15
16
 
16
- @dataclass
17
- class AgentRunRecord:
18
- id: str = field(default="")
19
- agent: str = field(default="")
20
- data: dict[str, Any] = field(default_factory=dict)
21
- timestamp: str = field(default="")
22
- hand_off: dict = field(default_factory=dict)
23
- called_from: str = field(default="")
17
+ class AgentRunRecord(BaseModel):
18
+ id: str = Field(default="")
19
+ agent: str = Field(default="")
20
+ data: dict[str, Any] = Field(default_factory=dict)
21
+ timestamp: str = Field(default="")
22
+ hand_off: dict | None = Field(default_factory=dict)
23
+ called_from: str = Field(default="")
24
24
 
25
25
 
26
- @dataclass
27
- class AgentDefinition:
28
- agent_type: str = field(default="")
29
- agent_name: str = field(default="")
30
- agent_data: dict = field(default_factory=dict)
31
- serializer: Literal["json", "cloudpickle", "msgpack"] = field(
26
+ class AgentDefinition(BaseModel):
27
+ agent_type: str = Field(default="")
28
+ agent_name: str = Field(default="")
29
+ agent_data: dict = Field(default_factory=dict)
30
+ serializer: Literal["json", "cloudpickle", "msgpack"] = Field(
32
31
  default="cloudpickle"
33
32
  )
34
33
 
35
34
 
36
- @dataclass
37
- class FlockContext(Serializable):
38
- state: dict[str, Any] = field(default_factory=dict)
39
- history: list[AgentRunRecord] = field(default_factory=list)
40
- agent_definitions: dict[str, AgentDefinition] = field(default_factory=dict)
41
- run_id: str = field(default="")
42
- workflow_id: str = field(default="")
43
- workflow_timestamp: str = field(default="")
35
+ class FlockContext(Serializable, BaseModel):
36
+ state: dict[str, Any] = Field(default_factory=dict)
37
+ history: list[AgentRunRecord] = Field(default_factory=list)
38
+ agent_definitions: dict[str, AgentDefinition] = Field(default_factory=dict)
39
+ run_id: str = Field(default="")
40
+ workflow_id: str = Field(default="")
41
+ workflow_timestamp: str = Field(default="")
44
42
 
45
43
  def record(
46
44
  self,
flock/core/flock_agent.py CHANGED
@@ -11,6 +11,7 @@ import cloudpickle
11
11
  from opentelemetry import trace
12
12
  from pydantic import BaseModel, Field
13
13
 
14
+ from flock.core.context.context import FlockContext
14
15
  from flock.core.flock_evaluator import FlockEvaluator
15
16
  from flock.core.flock_module import FlockModule
16
17
  from flock.core.flock_router import FlockRouter
@@ -73,6 +74,11 @@ class FlockAgent(BaseModel, ABC, DSPyIntegrationMixin):
73
74
  description="FlockModules attached to this agent",
74
75
  )
75
76
 
77
+ context: FlockContext | None = Field(
78
+ default=None,
79
+ description="Context associated with flock",
80
+ )
81
+
76
82
  def add_module(self, module: FlockModule) -> None:
77
83
  """Add a module to this agent."""
78
84
  self.modules[module.name] = module
@@ -95,6 +101,13 @@ class FlockAgent(BaseModel, ABC, DSPyIntegrationMixin):
95
101
  with tracer.start_as_current_span("agent.initialize") as span:
96
102
  span.set_attribute("agent.name", self.name)
97
103
  span.set_attribute("inputs", str(inputs))
104
+ if not self.context:
105
+ self.context = FlockContext()
106
+
107
+ if self.name not in self.context.agent_definitions:
108
+ self.context.add_agent_definition(
109
+ type(self), self.name, self.to_dict()
110
+ )
98
111
 
99
112
  try:
100
113
  for module in self.get_enabled_modules():
@@ -102,7 +115,7 @@ class FlockAgent(BaseModel, ABC, DSPyIntegrationMixin):
102
115
  f"agent.initialize - module {module.name}",
103
116
  agent=self.name,
104
117
  )
105
- await module.initialize(self, inputs)
118
+ await module.initialize(self, inputs, self.context)
106
119
  except Exception as module_error:
107
120
  logger.error(
108
121
  "Error during initialize",
@@ -124,7 +137,7 @@ class FlockAgent(BaseModel, ABC, DSPyIntegrationMixin):
124
137
  )
125
138
  try:
126
139
  for module in self.get_enabled_modules():
127
- await module.terminate(self, inputs, inputs)
140
+ await module.terminate(self, inputs, inputs, self.context)
128
141
  except Exception as module_error:
129
142
  logger.error(
130
143
  "Error during terminate",
@@ -139,7 +152,7 @@ class FlockAgent(BaseModel, ABC, DSPyIntegrationMixin):
139
152
  span.set_attribute("inputs", str(inputs))
140
153
  try:
141
154
  for module in self.get_enabled_modules():
142
- await module.on_error(self, error, inputs)
155
+ await module.on_error(self, error, inputs, self.context)
143
156
  except Exception as module_error:
144
157
  logger.error(
145
158
  "Error during on_error",
@@ -154,13 +167,15 @@ class FlockAgent(BaseModel, ABC, DSPyIntegrationMixin):
154
167
  span.set_attribute("inputs", str(inputs))
155
168
 
156
169
  for module in self.get_enabled_modules():
157
- inputs = await module.pre_evaluate(self, inputs)
170
+ inputs = await module.pre_evaluate(self, inputs, self.context)
158
171
 
159
172
  try:
160
173
  result = await self.evaluator.evaluate(self, inputs, self.tools)
161
174
 
162
175
  for module in self.get_enabled_modules():
163
- result = await module.post_evaluate(self, inputs, result)
176
+ result = await module.post_evaluate(
177
+ self, inputs, result, self.context
178
+ )
164
179
 
165
180
  span.set_attribute("result", str(result))
166
181
 
@@ -34,6 +34,8 @@ class FlockFactory:
34
34
  temperature: float = 0.0,
35
35
  max_tokens: int = 4096,
36
36
  alert_latency_threshold_ms: int = 30000,
37
+ no_output: bool = False,
38
+ print_context: bool = False,
37
39
  ) -> FlockAgent:
38
40
  """Creates a default FlockAgent.
39
41
 
@@ -63,6 +65,8 @@ class FlockFactory:
63
65
  render_table=enable_rich_tables,
64
66
  theme=output_theme,
65
67
  wait_for_input=wait_for_input,
68
+ no_output=no_output,
69
+ print_context=print_context,
66
70
  )
67
71
  output_module = OutputModule("output", config=output_config)
68
72
 
@@ -5,6 +5,8 @@ from typing import Any, TypeVar
5
5
 
6
6
  from pydantic import BaseModel, Field, create_model
7
7
 
8
+ from flock.core.context.context import FlockContext
9
+
8
10
  T = TypeVar("T", bound="FlockModuleConfig")
9
11
 
10
12
 
@@ -50,30 +52,50 @@ class FlockModule(BaseModel, ABC):
50
52
  default_factory=FlockModuleConfig, description="Module configuration"
51
53
  )
52
54
 
53
- async def initialize(self, agent: Any, inputs: dict[str, Any]) -> None:
55
+ async def initialize(
56
+ self,
57
+ agent: Any,
58
+ inputs: dict[str, Any],
59
+ context: FlockContext | None = None,
60
+ ) -> None:
54
61
  """Called when the agent starts running."""
55
62
  pass
56
63
 
57
64
  async def pre_evaluate(
58
- self, agent: Any, inputs: dict[str, Any]
65
+ self,
66
+ agent: Any,
67
+ inputs: dict[str, Any],
68
+ context: FlockContext | None = None,
59
69
  ) -> dict[str, Any]:
60
70
  """Called before agent evaluation, can modify inputs."""
61
71
  return inputs
62
72
 
63
73
  async def post_evaluate(
64
- self, agent: Any, inputs: dict[str, Any], result: dict[str, Any]
74
+ self,
75
+ agent: Any,
76
+ inputs: dict[str, Any],
77
+ result: dict[str, Any],
78
+ context: FlockContext | None = None,
65
79
  ) -> dict[str, Any]:
66
80
  """Called after agent evaluation, can modify results."""
67
81
  return result
68
82
 
69
83
  async def terminate(
70
- self, agent: Any, inputs: dict[str, Any], result: dict[str, Any]
84
+ self,
85
+ agent: Any,
86
+ inputs: dict[str, Any],
87
+ result: dict[str, Any],
88
+ context: FlockContext | None = None,
71
89
  ) -> None:
72
90
  """Called when the agent finishes running."""
73
91
  pass
74
92
 
75
93
  async def on_error(
76
- self, agent: Any, error: Exception, inputs: dict[str, Any]
94
+ self,
95
+ agent: Any,
96
+ error: Exception,
97
+ inputs: dict[str, Any],
98
+ context: FlockContext | None = None,
77
99
  ) -> None:
78
100
  """Called when an error occurs during agent execution."""
79
101
  pass
@@ -43,6 +43,30 @@ def web_search_duckduckgo(
43
43
  raise
44
44
 
45
45
 
46
+ @traced_and_logged
47
+ def web_search_bing(keywords: str):
48
+ try:
49
+ import httpx
50
+
51
+ subscription_key = os.environ["BING_SEARCH_V7_SUBSCRIPTION_KEY"]
52
+ endpoint = "https://api.bing.microsoft.com/v7.0/search"
53
+
54
+ # Query term(s) to search for.
55
+ query = keywords
56
+
57
+ # Construct a request
58
+ mkt = "en-US"
59
+ params = {"q": query, "mkt": mkt}
60
+ headers = {"Ocp-Apim-Subscription-Key": subscription_key}
61
+
62
+ response = httpx.get(endpoint, headers=headers, params=params)
63
+ response.raise_for_status()
64
+ search_results = response.json()
65
+ return search_results["webPages"]
66
+ except Exception:
67
+ raise
68
+
69
+
46
70
  def extract_links_from_markdown(markdown: str, url: str) -> list:
47
71
  # Regular expression to find all markdown links
48
72
  link_pattern = re.compile(r"\[([^\]]+)\]\(([^)]+)\)")
File without changes
File without changes
@@ -6,6 +6,7 @@ from typing import Any
6
6
  from pydantic import Field
7
7
 
8
8
  from flock.core import FlockModule, FlockModuleConfig
9
+ from flock.core.context.context import FlockContext
9
10
 
10
11
 
11
12
  class CallbackModuleConfig(FlockModuleConfig):
@@ -44,13 +45,21 @@ class CallbackModule(FlockModule):
44
45
  description="Callback module configuration",
45
46
  )
46
47
 
47
- async def pre_initialize(self, agent: Any, inputs: dict[str, Any]) -> None:
48
+ async def pre_initialize(
49
+ self,
50
+ agent: Any,
51
+ inputs: dict[str, Any],
52
+ context: FlockContext | None = None,
53
+ ) -> None:
48
54
  """Run initialize callback if configured."""
49
55
  if self.config.initialize_callback:
50
56
  await self.config.initialize_callback(agent, inputs)
51
57
 
52
58
  async def pre_evaluate(
53
- self, agent: Any, inputs: dict[str, Any]
59
+ self,
60
+ agent: Any,
61
+ inputs: dict[str, Any],
62
+ context: FlockContext | None = None,
54
63
  ) -> dict[str, Any]:
55
64
  """Run evaluate callback if configured."""
56
65
  if self.config.evaluate_callback:
@@ -58,29 +67,23 @@ class CallbackModule(FlockModule):
58
67
  return inputs
59
68
 
60
69
  async def pre_terminate(
61
- self, agent: Any, inputs: dict[str, Any], result: dict[str, Any]
70
+ self,
71
+ agent: Any,
72
+ inputs: dict[str, Any],
73
+ result: dict[str, Any],
74
+ context: FlockContext | None = None,
62
75
  ) -> None:
63
76
  """Run terminate callback if configured."""
64
77
  if self.config.terminate_callback:
65
78
  await self.config.terminate_callback(agent, inputs, result)
66
79
 
67
80
  async def on_error(
68
- self, agent: Any, error: Exception, inputs: dict[str, Any]
81
+ self,
82
+ agent: Any,
83
+ error: Exception,
84
+ inputs: dict[str, Any],
85
+ context: FlockContext | None = None,
69
86
  ) -> None:
70
87
  """Run error callback if configured."""
71
88
  if self.config.on_error_callback:
72
89
  await self.config.on_error_callback(agent, error, inputs)
73
-
74
- # Other hooks just pass through
75
- async def post_initialize(self, agent: Any, inputs: dict[str, Any]) -> None:
76
- pass
77
-
78
- async def post_evaluate(
79
- self, agent: Any, inputs: dict[str, Any], result: dict[str, Any]
80
- ) -> dict[str, Any]:
81
- return result
82
-
83
- async def post_terminate(
84
- self, agent: Any, inputs: dict[str, Any], result: dict[str, Any]
85
- ) -> None:
86
- pass
@@ -7,6 +7,7 @@ from pydantic import Field
7
7
  from tqdm import tqdm
8
8
 
9
9
  from flock.core import FlockAgent, FlockModule, FlockModuleConfig
10
+ from flock.core.context.context import FlockContext
10
11
  from flock.core.logging.logging import get_logger
11
12
  from flock.modules.memory.memory_parser import MemoryMappingParser
12
13
  from flock.modules.memory.memory_storage import FlockMemoryStore, MemoryEntry
@@ -77,7 +78,10 @@ class MemoryModule(FlockModule):
77
78
  )
78
79
 
79
80
  async def initialize(
80
- self, agent: FlockAgent, inputs: dict[str, Any]
81
+ self,
82
+ agent: FlockAgent,
83
+ inputs: dict[str, Any],
84
+ context: FlockContext | None = None,
81
85
  ) -> None:
82
86
  """Initialize memory store if needed."""
83
87
  if not self.memory_store:
@@ -92,44 +96,23 @@ class MemoryModule(FlockModule):
92
96
  logger.debug(f"Initialized memory module for agent {agent.name}")
93
97
 
94
98
  async def pre_evaluate(
95
- self, agent: FlockAgent, inputs: dict[str, Any]
99
+ self,
100
+ agent: FlockAgent,
101
+ inputs: dict[str, Any],
102
+ context: FlockContext | None = None,
96
103
  ) -> dict[str, Any]:
97
104
  """Check memory before evaluation."""
98
105
  if not self.memory_store:
99
106
  return inputs
100
107
 
101
- try:
102
- input_text = json.dumps(inputs)
103
- query_embedding = self.memory_store.compute_embedding(input_text)
104
- concepts = await self._extract_concepts(
105
- agent, input_text, self.config.number_of_concepts_to_extract
106
- )
107
-
108
- memory_results = []
109
- for op in self.memory_ops:
110
- if op["type"] == "semantic":
111
- semantic_results = self.memory_store.retrieve(
112
- query_embedding,
113
- concepts,
114
- similarity_threshold=self.config.similarity_threshold,
115
- )
116
- memory_results.extend(semantic_results)
117
- elif op["type"] == "exact":
118
- exact_results = self.memory_store.exact_match(inputs)
119
- memory_results.extend(exact_results)
120
-
121
- if memory_results:
122
- logger.debug(
123
- f"Found {len(memory_results)} relevant memories",
124
- agent=agent.name,
125
- )
126
- inputs["memory_results"] = memory_results
108
+ inputs = await self.search_memory(agent, inputs)
127
109
 
128
- return inputs
110
+ if "context" in inputs:
111
+ agent.input = (
112
+ agent.input + ", context: list | context with more information"
113
+ )
129
114
 
130
- except Exception as e:
131
- logger.warning(f"Memory retrieval failed: {e}", agent=agent.name)
132
- return inputs
115
+ return inputs
133
116
 
134
117
  def get_memory_filename(self, module_name: str) -> str:
135
118
  """Generate the full file path for the memory file."""
@@ -205,12 +188,18 @@ class MemoryModule(FlockModule):
205
188
  exact_results = self.memory_store.exact_match(query)
206
189
  memory_results.extend(exact_results)
207
190
 
191
+ context: list[dict[str, Any]] = []
208
192
  if memory_results:
193
+ for result in memory_results:
194
+ context.append(
195
+ {"content": result.content, "concepts": result.concepts}
196
+ )
197
+
209
198
  logger.debug(
210
199
  f"Found {len(memory_results)} relevant memories",
211
200
  agent=agent.name,
212
201
  )
213
- query["memory_results"] = memory_results
202
+ query["context"] = context
214
203
 
215
204
  return query
216
205
 
@@ -232,7 +221,11 @@ class MemoryModule(FlockModule):
232
221
  logger.warning(f"Memory storage failed: {e}", agent=agent.name)
233
222
 
234
223
  async def post_evaluate(
235
- self, agent: FlockAgent, inputs: dict[str, Any], result: dict[str, Any]
224
+ self,
225
+ agent: FlockAgent,
226
+ inputs: dict[str, Any],
227
+ result: dict[str, Any],
228
+ context: FlockContext | None = None,
236
229
  ) -> dict[str, Any]:
237
230
  """Store results in memory after evaluation."""
238
231
  if not self.memory_store:
@@ -247,7 +240,11 @@ class MemoryModule(FlockModule):
247
240
  return result
248
241
 
249
242
  async def terminate(
250
- self, agent: Any, inputs: dict[str, Any], result: dict[str, Any]
243
+ self,
244
+ agent: Any,
245
+ inputs: dict[str, Any],
246
+ result: dict[str, Any],
247
+ context: FlockContext | None = None,
251
248
  ) -> None:
252
249
  """Save memory store if configured."""
253
250
  if self.config.save_after_update and self.memory_store:
@@ -8,6 +8,7 @@ from typing import Any
8
8
  from pydantic import Field
9
9
 
10
10
  from flock.core import FlockAgent
11
+ from flock.core.context.context import FlockContext
11
12
  from flock.core.flock_module import FlockModule, FlockModuleConfig
12
13
  from flock.core.logging.formatters.themed_formatter import (
13
14
  ThemedAgentResultFormatter,
@@ -58,6 +59,10 @@ class OutputModuleConfig(FlockModuleConfig):
58
59
  default=False,
59
60
  description="Whether to suppress output",
60
61
  )
62
+ print_context: bool = Field(
63
+ default=False,
64
+ description="Whether to print the context",
65
+ )
61
66
 
62
67
 
63
68
  class OutputModule(FlockModule):
@@ -159,12 +164,18 @@ class OutputModule(FlockModule):
159
164
  json.dump(output_data, f, indent=2)
160
165
 
161
166
  async def post_evaluate(
162
- self, agent: FlockAgent, inputs: dict[str, Any], result: dict[str, Any]
167
+ self,
168
+ agent: FlockAgent,
169
+ inputs: dict[str, Any],
170
+ result: dict[str, Any],
171
+ context: FlockContext | None = None,
163
172
  ) -> dict[str, Any]:
164
173
  """Format and display the output."""
165
174
  logger.debug("Formatting and displaying output")
166
175
  if self.config.no_output:
167
176
  return result
177
+ if self.config.print_context:
178
+ result["context"] = context
168
179
  # Display the result using the formatter
169
180
  self._formatter.display_result(result, agent.name)
170
181
 
@@ -11,6 +11,7 @@ import numpy as np
11
11
  import psutil
12
12
  from pydantic import BaseModel, Field, validator
13
13
 
14
+ from flock.core.context.context import FlockContext
14
15
  from flock.core.flock_agent import FlockAgent
15
16
  from flock.core.flock_module import FlockModule, FlockModuleConfig
16
17
 
@@ -222,7 +223,11 @@ class MetricsModule(FlockModule):
222
223
  return stats
223
224
 
224
225
  async def terminate(
225
- self, agent: FlockAgent, inputs: dict[str, Any], result: dict[str, Any]
226
+ self,
227
+ agent: FlockAgent,
228
+ inputs: dict[str, Any],
229
+ result: dict[str, Any],
230
+ context: FlockContext | None = None,
226
231
  ) -> None:
227
232
  """Clean up and final metric recording."""
228
233
  if self.config.storage_type == "json":
@@ -331,7 +336,10 @@ class MetricsModule(FlockModule):
331
336
  return False
332
337
 
333
338
  async def initialize(
334
- self, agent: FlockAgent, inputs: dict[str, Any]
339
+ self,
340
+ agent: FlockAgent,
341
+ inputs: dict[str, Any],
342
+ context: FlockContext | None = None,
335
343
  ) -> None:
336
344
  """Initialize metrics collection."""
337
345
  self._start_time = time.time()
@@ -370,7 +378,10 @@ class MetricsModule(FlockModule):
370
378
  return token_count, total_cost
371
379
 
372
380
  async def pre_evaluate(
373
- self, agent: FlockAgent, inputs: dict[str, Any]
381
+ self,
382
+ agent: FlockAgent,
383
+ inputs: dict[str, Any],
384
+ context: FlockContext | None = None,
374
385
  ) -> dict[str, Any]:
375
386
  """Record pre-evaluation metrics."""
376
387
  if self.config.collect_token_usage:
@@ -408,7 +419,11 @@ class MetricsModule(FlockModule):
408
419
  return inputs
409
420
 
410
421
  async def post_evaluate(
411
- self, agent: FlockAgent, inputs: dict[str, Any], result: dict[str, Any]
422
+ self,
423
+ agent: FlockAgent,
424
+ inputs: dict[str, Any],
425
+ result: dict[str, Any],
426
+ context: FlockContext | None = None,
412
427
  ) -> dict[str, Any]:
413
428
  """Record post-evaluation metrics."""
414
429
  if self.config.collect_timing and self._start_time:
@@ -463,7 +478,11 @@ class MetricsModule(FlockModule):
463
478
  return result
464
479
 
465
480
  async def on_error(
466
- self, agent: FlockAgent, error: Exception, inputs: dict[str, Any]
481
+ self,
482
+ agent: FlockAgent,
483
+ error: Exception,
484
+ inputs: dict[str, Any],
485
+ context: FlockContext | None = None,
467
486
  ) -> None:
468
487
  """Record error metrics."""
469
488
  self._record_metric(
@@ -5,6 +5,7 @@ from pydantic import Field
5
5
  from zep_python.client import Zep
6
6
  from zep_python.types import Message as ZepMessage, SessionSearchResult
7
7
 
8
+ from flock.core.context.context import FlockContext
8
9
  from flock.core.flock_agent import FlockAgent
9
10
  from flock.core.flock_module import FlockModule, FlockModuleConfig
10
11
  from flock.core.logging.logging import get_logger
@@ -139,7 +140,11 @@ class ZepModule(FlockModule):
139
140
  return response.results
140
141
 
141
142
  async def post_evaluate(
142
- self, agent: FlockAgent, inputs: dict[str, Any], result: dict[str, Any]
143
+ self,
144
+ agent: FlockAgent,
145
+ inputs: dict[str, Any],
146
+ result: dict[str, Any],
147
+ context: FlockContext | None = None,
143
148
  ) -> dict[str, Any]:
144
149
  """Format and display the output."""
145
150
  if not self.config.enable_write:
@@ -152,7 +157,10 @@ class ZepModule(FlockModule):
152
157
  return result
153
158
 
154
159
  async def pre_evaluate(
155
- self, agent: FlockAgent, inputs: dict[str, Any]
160
+ self,
161
+ agent: FlockAgent,
162
+ inputs: dict[str, Any],
163
+ context: FlockContext | None = None,
156
164
  ) -> dict[str, Any]:
157
165
  """Format and display the output."""
158
166
  if not self.config.enable_read:
@@ -50,7 +50,7 @@ async def run_agent(context: FlockContext) -> dict:
50
50
  # Create a nested span for this iteration.
51
51
  with tracer.start_as_current_span("agent_iteration") as iter_span:
52
52
  iter_span.set_attribute("agent.name", agent.name)
53
-
53
+ agent.context = context
54
54
  # Resolve inputs for the agent.
55
55
  agent_inputs = resolve_inputs(
56
56
  agent.input, context, previous_agent_name
@@ -160,7 +160,7 @@ async def run_agent(context: FlockContext) -> dict:
160
160
  agent.name,
161
161
  result,
162
162
  timestamp=datetime.now().isoformat(),
163
- hand_off=handoff_data,
163
+ hand_off=handoff_data.model_dump(),
164
164
  called_from=previous_agent_name,
165
165
  )
166
166
  previous_agent_name = agent.name
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: flock-core
3
- Version: 0.3.14
3
+ Version: 0.3.16
4
4
  Summary: Declarative LLM Orchestration at Scale
5
5
  Author-email: Andre Ratzenberger <andre.ratzenberger@whiteduck.de>
6
6
  License-File: LICENSE
@@ -11,13 +11,13 @@ flock/cli/settings.py,sha256=DkeLUlrb7rGx3nZ04aADU9HXXu5mZTf_DBwT0xhzIv4,7
11
11
  flock/cli/assets/release_notes.md,sha256=-RuE-G9Sn8z1LWEdr9iqjuQN7N1K_JMaCzHYoyLR42U,4793
12
12
  flock/core/__init__.py,sha256=mPlvKc0SxC2qCvSlgYeP_7EyV8ptmdn24NO8mlQoCSo,559
13
13
  flock/core/flock.py,sha256=IURlcuNvdsnqKkvgXtX4v_pGWQ8Lfb60X--MT0zvxHo,19881
14
- flock/core/flock_agent.py,sha256=qG6j-aSxSTEcvv5tjMyw3RTCaBooIGF7IVhAUOrhPOo,11946
14
+ flock/core/flock_agent.py,sha256=QPyRSa1X_aAK2MSgqLNHBiL-_cnYHOSSnrFup2YTzss,12509
15
15
  flock/core/flock_api.py,sha256=2rHnmEdtT5KPZYwGesRT7LqwbrgKClODHT-O56u7pcQ,7140
16
16
  flock/core/flock_evaluator.py,sha256=j7riJj_KsWoBnKmLiGp-U0CRhxDyJbgEdLGN26tfKm8,1588
17
- flock/core/flock_factory.py,sha256=nh0tK5UzEPWP5EmFrRvhsAeaZEvaPG5e0tkYkHpTjy0,2606
18
- flock/core/flock_module.py,sha256=3DmxOc39gQS-tiJcgUCjMaLr8QDDJR4acV_M76Xcf6I,2602
17
+ flock/core/flock_factory.py,sha256=7nV0WAh197INdBckJ-NhnhSSZOSzZC1MlYfeZm2x8Xc,2750
18
+ flock/core/flock_module.py,sha256=96aFVYAgwpKN53xGbivQDUpikOYGFCxK5mqhclOcxY0,3003
19
19
  flock/core/flock_router.py,sha256=A5GaxcGvtiFlRLHBTW7okh5RDm3BdKam2uXvRHRaj7k,2187
20
- flock/core/context/context.py,sha256=AW0qKIAkgZucVroGsulrPVPc4WmWuqWIrVPHf2qaOLI,6380
20
+ flock/core/context/context.py,sha256=3sj5BrnY7OBG8Xk-uoT0yPKQjCzUU6a3VH26xuHo2KI,6407
21
21
  flock/core/context/context_manager.py,sha256=FANSWa6DEhdhtZ7t_9Gza0v80UdpoDOhHbfVOccmjkA,1181
22
22
  flock/core/context/context_vars.py,sha256=zYTMi9b6mNSSEHowEQUOTpEDurmAjaUcyBCgfKY6-cU,300
23
23
  flock/core/execution/local_executor.py,sha256=rnIQvaJOs6zZORUcR3vvyS6LPREDJTjaygl_Db0M8ao,952
@@ -40,7 +40,7 @@ flock/core/mixin/prompt_parser.py,sha256=eOqI-FK3y17gVqpc_y5GF-WmK1Jv8mFlkZxTcgw
40
40
  flock/core/registry/agent_registry.py,sha256=TUClh9e3eA6YzZC1CMTlsTPvQeqb9jYHewi-zPpcWM8,4987
41
41
  flock/core/serialization/secure_serializer.py,sha256=n5-zRvvXddgJv1FFHsaQ2wuYdL3WUSGPvG_LGaffEJo,6144
42
42
  flock/core/serialization/serializable.py,sha256=SymJ0YrjBx48mOBItYSqoRpKuzIc4vKWRS6ScTzre7s,2573
43
- flock/core/tools/basic_tools.py,sha256=idomjqvphTKIhuEkVS9CCJaigx_j_rv4jHqeDwp8sQY,5037
43
+ flock/core/tools/basic_tools.py,sha256=P1-RWkw57U2vSxPTCd5awlNg4MME4GkBLEB5HiiKmkw,5715
44
44
  flock/core/tools/llm_tools.py,sha256=Bdt4Dpur5dGpxd2KFEQyxjfZazvW1HCDKY6ydMj6UgQ,21811
45
45
  flock/core/tools/markdown_tools.py,sha256=W6fGM48yGHbifVlaOk1jOtVcybfRbRmf20VbDOZv8S4,6031
46
46
  flock/core/tools/dev_tools/github.py,sha256=a2OTPXS7kWOVA4zrZHynQDcsmEi4Pac5MfSjQOLePzA,5308
@@ -48,16 +48,18 @@ flock/core/util/cli_helper.py,sha256=QSpP10WRNcjXzVFwpTQA8lSBy7707Qlv7uCit1XjUms
48
48
  flock/core/util/hydrator.py,sha256=6qNwOwCZB7r6y25BZ--0PGofrAlfMaXbDKFQeP5NLts,11196
49
49
  flock/core/util/input_resolver.py,sha256=g9vDPdY4OH-G7qjas5ksGEHueokHGFPMoLOvC-ngeLo,5984
50
50
  flock/evaluators/declarative/declarative_evaluator.py,sha256=f8ldgZZp94zC4CoGzBufKvbvtckCGBe9EHTOoAZfZK0,1695
51
+ flock/evaluators/memory/azure_search_evaluator.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
51
52
  flock/evaluators/memory/memory_evaluator.py,sha256=SmerXyNaqm8DTV0yw-WqWkn9DXIf6x-nPG1eyTV6NY8,3452
52
53
  flock/evaluators/natural_language/natural_language_evaluator.py,sha256=6nVEeh8_uwv_h-d3FWlA0GbzDzRtdhvxCGKirHtyvOU,2012
53
54
  flock/evaluators/zep/zep_evaluator.py,sha256=9NOELl7JAuUcx_FQrxY6b-_vN3MjwDyW7ZppPIGeCFc,1954
54
- flock/modules/callback/callback_module.py,sha256=hCCw-HNYjK4aHnUQfvw26ZP1Q_jdlKb9kDh3BHzbCQA,2916
55
- flock/modules/memory/memory_module.py,sha256=z0MfMNpIsjL9NEXdfVofQ99z1ZaULQ1Fk3gp3SxEhd8,15246
55
+ flock/modules/azure-search/azure_search_module.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
56
+ flock/modules/callback/callback_module.py,sha256=volGGgHtY19qj1wHR6m5a_hmXSbV3Ca3uY6I76YmcfU,2833
57
+ flock/modules/memory/memory_module.py,sha256=dZ30eOFqIlAz0a5IKJMoXgJ-VyPEqApAOX0OQjhGA1I,14733
56
58
  flock/modules/memory/memory_parser.py,sha256=FLH7GL8XThvHiCMfX3eQH7Sz-f62fzhAUmO6_gaDI7U,4372
57
59
  flock/modules/memory/memory_storage.py,sha256=CNcLDMmvv0x7Z3YMKr6VveS_VCa7rKPw8l2d-XgqokA,27246
58
- flock/modules/output/output_module.py,sha256=ygk553PxKulmoGlRL0F_iP_FMiDteEtAcz9zUfYYTdI,7153
59
- flock/modules/performance/metrics_module.py,sha256=JsLIVs-2PZ_A8GyYLNVBsNXdSFyrVid3YGd0fu4HXyM,16404
60
- flock/modules/zep/zep_module.py,sha256=BIJ5K-hg2bLeJmGKoDcVY1rVN7_0yYETiSaVrO-gtMI,5830
60
+ flock/modules/output/output_module.py,sha256=MPs5QV5g5DZQGqR07dS0eBug_TGpkdjX5zTrcrDphq8,7467
61
+ flock/modules/performance/metrics_module.py,sha256=UD9OjY4-zAvauMD7YyDYqE1gyIhzpdr3JkBT8j9knxY,16790
62
+ flock/modules/zep/zep_module.py,sha256=x7JG6O6xnwwum0RETIqKYbA3xzdcvX2aUuns0Cl0c2Q,6014
61
63
  flock/platform/docker_tools.py,sha256=fpA7-6rJBjPOUBLdQP4ny2QPgJ_042nmqRn5GtKnoYw,1445
62
64
  flock/platform/jaeger_install.py,sha256=MyOMJQx4TQSMYvdUJxfiGSo3YCtsfkbNXcAcQ9bjETA,2898
63
65
  flock/routers/__init__.py,sha256=w9uL34Auuo26-q_EGlE8Z9iHsw6S8qutTAH_ZI7pn7M,39
@@ -405,12 +407,12 @@ flock/themes/zenburned.toml,sha256=UEmquBbcAO3Zj652XKUwCsNoC2iQSlIh-q5c6DH-7Kc,1
405
407
  flock/themes/zenwritten-dark.toml,sha256=To5l6520_3UqAGiEumpzGWsHhXxqu9ThrMildXKgIO0,1669
406
408
  flock/themes/zenwritten-light.toml,sha256=G1iEheCPfBNsMTGaVpEVpDzYBHA_T-MV27rolUYolmE,1666
407
409
  flock/workflow/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
408
- flock/workflow/activities.py,sha256=JDfcmn99k5UTN3QNm5hAdn_eRjWRYhWSIw1U0kMOAh4,9014
410
+ flock/workflow/activities.py,sha256=yah-lHjMW6_Ww1gt7hMXBis1cJRlcbHx0uLsMB9oNZ0,9066
409
411
  flock/workflow/agent_activities.py,sha256=NhBZscflEf2IMfSRa_pBM_TRP7uVEF_O0ROvWZ33eDc,963
410
412
  flock/workflow/temporal_setup.py,sha256=VWBgmBgfTBjwM5ruS_dVpA5AVxx6EZ7oFPGw4j3m0l0,1091
411
413
  flock/workflow/workflow.py,sha256=I9MryXW_bqYVTHx-nl2epbTqeRy27CAWHHA7ZZA0nAk,1696
412
- flock_core-0.3.14.dist-info/METADATA,sha256=-baOqTXylWNerDitHki7cJoYtHFFS9x3k8VWf1S6-SI,20502
413
- flock_core-0.3.14.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
414
- flock_core-0.3.14.dist-info/entry_points.txt,sha256=rWaS5KSpkTmWySURGFZk6PhbJ87TmvcFQDi2uzjlagQ,37
415
- flock_core-0.3.14.dist-info/licenses/LICENSE,sha256=iYEqWy0wjULzM9GAERaybP4LBiPeu7Z1NEliLUdJKSc,1072
416
- flock_core-0.3.14.dist-info/RECORD,,
414
+ flock_core-0.3.16.dist-info/METADATA,sha256=ufURDAvefWtPcOW36ewLIRKwXuqkdIaHCFD_LMlGWAk,20502
415
+ flock_core-0.3.16.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
416
+ flock_core-0.3.16.dist-info/entry_points.txt,sha256=rWaS5KSpkTmWySURGFZk6PhbJ87TmvcFQDi2uzjlagQ,37
417
+ flock_core-0.3.16.dist-info/licenses/LICENSE,sha256=iYEqWy0wjULzM9GAERaybP4LBiPeu7Z1NEliLUdJKSc,1072
418
+ flock_core-0.3.16.dist-info/RECORD,,