camel-ai 0.2.79a0__py3-none-any.whl → 0.2.79a1__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 camel-ai might be problematic. Click here for more details.

@@ -72,8 +72,16 @@ class SGLangModel(BaseModelBackend):
72
72
  (default: :obj:`None`)
73
73
  max_retries (int, optional): Maximum number of retries for API calls.
74
74
  (default: :obj:`3`)
75
+ client (Optional[Any], optional): A custom synchronous
76
+ OpenAI-compatible client instance. If provided, this client will
77
+ be used instead of creating a new one. Note: When using custom
78
+ clients with SGLang, server auto-start features will be disabled.
79
+ (default: :obj:`None`)
80
+ async_client (Optional[Any], optional): A custom asynchronous
81
+ OpenAI-compatible client instance. If provided, this client will
82
+ be used instead of creating a new one. (default: :obj:`None`)
75
83
  **kwargs (Any): Additional arguments to pass to the client
76
- initialization.
84
+ initialization. Ignored if custom clients are provided.
77
85
 
78
86
  Reference: https://sgl-project.github.io/backend/openai_api_completions.
79
87
  html
@@ -88,6 +96,8 @@ class SGLangModel(BaseModelBackend):
88
96
  token_counter: Optional[BaseTokenCounter] = None,
89
97
  timeout: Optional[float] = None,
90
98
  max_retries: int = 3,
99
+ client: Optional[Any] = None,
100
+ async_client: Optional[Any] = None,
91
101
  **kwargs: Any,
92
102
  ) -> None:
93
103
  if model_config_dict is None:
@@ -111,9 +121,10 @@ class SGLangModel(BaseModelBackend):
111
121
  max_retries,
112
122
  )
113
123
 
114
- self._client = None
115
-
116
- if self._url:
124
+ # Use custom clients if provided, otherwise create new ones
125
+ if client is not None:
126
+ self._client = client
127
+ elif self._url:
117
128
  # Initialize the client if an existing URL is provided
118
129
  self._client = OpenAI(
119
130
  timeout=self._timeout,
@@ -122,6 +133,12 @@ class SGLangModel(BaseModelBackend):
122
133
  base_url=self._url,
123
134
  **kwargs,
124
135
  )
136
+ else:
137
+ self._client = None
138
+
139
+ if async_client is not None:
140
+ self._async_client = async_client
141
+ elif self._url:
125
142
  self._async_client = AsyncOpenAI(
126
143
  timeout=self._timeout,
127
144
  max_retries=self._max_retries,
@@ -129,6 +146,8 @@ class SGLangModel(BaseModelBackend):
129
146
  base_url=self._url,
130
147
  **kwargs,
131
148
  )
149
+ else:
150
+ self._async_client = None
132
151
 
133
152
  def _start_server(self) -> None:
134
153
  try:
@@ -159,13 +178,24 @@ class SGLangModel(BaseModelBackend):
159
178
  )
160
179
  self._inactivity_thread.start()
161
180
  self.last_run_time = time.time()
162
- # Initialize the client after the server starts
163
- self._client = OpenAI(
164
- timeout=self._timeout,
165
- max_retries=self._max_retries,
166
- api_key="Set-but-ignored", # required but ignored
167
- base_url=self._url,
168
- )
181
+ # Initialize client after server starts if not already set
182
+ if self._client is None:
183
+ self._client = OpenAI(
184
+ timeout=self._timeout,
185
+ max_retries=self._max_retries,
186
+ api_key="Set-but-ignored", # required but ignored
187
+ base_url=self._url,
188
+ )
189
+ if (
190
+ not hasattr(self, '_async_client')
191
+ or self._async_client is None
192
+ ):
193
+ self._async_client = AsyncOpenAI(
194
+ timeout=self._timeout,
195
+ max_retries=self._max_retries,
196
+ api_key="Set-but-ignored", # required but ignored
197
+ base_url=self._url,
198
+ )
169
199
  except Exception as e:
170
200
  raise RuntimeError(f"Failed to start SGLang server: {e}") from e
171
201
 
@@ -14,10 +14,12 @@
14
14
 
15
15
  from .role_playing_worker import RolePlayingWorker
16
16
  from .single_agent_worker import SingleAgentWorker
17
+ from .workflow_memory_manager import WorkflowSelectionMethod
17
18
  from .workforce import Workforce
18
19
 
19
20
  __all__ = [
20
21
  "Workforce",
21
22
  "SingleAgentWorker",
22
23
  "RolePlayingWorker",
24
+ "WorkflowSelectionMethod",
23
25
  ]
@@ -119,11 +119,13 @@ class RolePlayingWorker(Worker):
119
119
  `TaskState.FAILED`.
120
120
  """
121
121
  dependency_tasks_info = self._get_dep_tasks_info(dependencies)
122
- prompt = ROLEPLAY_PROCESS_TASK_PROMPT.format(
123
- content=task.content,
124
- parent_task_content=task.parent.content if task.parent else "",
125
- dependency_tasks_info=dependency_tasks_info,
126
- additional_info=task.additional_info,
122
+ prompt = str(
123
+ ROLEPLAY_PROCESS_TASK_PROMPT.format(
124
+ content=task.content,
125
+ parent_task_content=task.parent.content if task.parent else "",
126
+ dependency_tasks_info=dependency_tasks_info,
127
+ additional_info=task.additional_info,
128
+ )
127
129
  )
128
130
  role_play_session = RolePlaying(
129
131
  assistant_role_name=self.assistant_role_name,
@@ -183,12 +185,14 @@ class RolePlayingWorker(Worker):
183
185
  input_msg = assistant_response.msg
184
186
 
185
187
  chat_history_str = "\n".join(chat_history)
186
- prompt = ROLEPLAY_SUMMARIZE_PROMPT.format(
187
- user_role=self.user_role_name,
188
- assistant_role=self.assistant_role_name,
189
- content=task.content,
190
- chat_history=chat_history_str,
191
- additional_info=task.additional_info,
188
+ prompt = str(
189
+ ROLEPLAY_SUMMARIZE_PROMPT.format(
190
+ user_role=self.user_role_name,
191
+ assistant_role=self.assistant_role_name,
192
+ content=task.content,
193
+ chat_history=chat_history_str,
194
+ additional_info=task.additional_info,
195
+ )
192
196
  )
193
197
  if self.use_structured_output_handler and self.structured_handler:
194
198
  # Use structured output handler for prompt-based extraction
@@ -15,12 +15,8 @@ from __future__ import annotations
15
15
 
16
16
  import asyncio
17
17
  import datetime
18
- import glob
19
- import os
20
- import re
21
18
  import time
22
19
  from collections import deque
23
- from pathlib import Path
24
20
  from typing import Any, Dict, List, Optional
25
21
 
26
22
  from colorama import Fore
@@ -34,8 +30,11 @@ from camel.societies.workforce.structured_output_handler import (
34
30
  )
35
31
  from camel.societies.workforce.utils import TaskResult
36
32
  from camel.societies.workforce.worker import Worker
33
+ from camel.societies.workforce.workflow_memory_manager import (
34
+ WorkflowMemoryManager,
35
+ )
37
36
  from camel.tasks.task import Task, TaskState, is_task_result_insufficient
38
- from camel.utils.context_utils import ContextUtility, WorkflowSummary
37
+ from camel.utils.context_utils import ContextUtility
39
38
 
40
39
  logger = get_logger(__name__)
41
40
 
@@ -254,6 +253,9 @@ class SingleAgentWorker(Worker):
254
253
  # from all task processing
255
254
  self._conversation_accumulator: Optional[ChatAgent] = None
256
255
 
256
+ # workflow memory manager for handling workflow operations
257
+ self._workflow_manager: Optional[WorkflowMemoryManager] = None
258
+
257
259
  # note: context utility is set on the worker agent during save/load
258
260
  # operations to avoid creating session folders during initialization
259
261
 
@@ -316,6 +318,21 @@ class SingleAgentWorker(Worker):
316
318
  )
317
319
  return self._conversation_accumulator
318
320
 
321
+ def _get_workflow_manager(self) -> WorkflowMemoryManager:
322
+ r"""Get or create the workflow memory manager."""
323
+ if self._workflow_manager is None:
324
+ context_util = (
325
+ self._shared_context_utility
326
+ if self._shared_context_utility is not None
327
+ else None
328
+ )
329
+ self._workflow_manager = WorkflowMemoryManager(
330
+ worker=self.worker,
331
+ description=self.description,
332
+ context_utility=context_util,
333
+ )
334
+ return self._workflow_manager
335
+
319
336
  async def _process_task(
320
337
  self, task: Task, dependencies: List[Task]
321
338
  ) -> TaskState:
@@ -342,11 +359,15 @@ class SingleAgentWorker(Worker):
342
359
 
343
360
  try:
344
361
  dependency_tasks_info = self._get_dep_tasks_info(dependencies)
345
- prompt = PROCESS_TASK_PROMPT.format(
346
- content=task.content,
347
- parent_task_content=task.parent.content if task.parent else "",
348
- dependency_tasks_info=dependency_tasks_info,
349
- additional_info=task.additional_info,
362
+ prompt = str(
363
+ PROCESS_TASK_PROMPT.format(
364
+ content=task.content,
365
+ parent_task_content=task.parent.content
366
+ if task.parent
367
+ else "",
368
+ dependency_tasks_info=dependency_tasks_info,
369
+ additional_info=task.additional_info,
370
+ )
350
371
  )
351
372
 
352
373
  if self.use_structured_output_handler and self.structured_handler:
@@ -590,6 +611,8 @@ class SingleAgentWorker(Worker):
590
611
  is based on either the worker's explicit role_name or the generated
591
612
  task_title from the summary.
592
613
 
614
+ Delegates to WorkflowMemoryManager for all workflow operations.
615
+
593
616
  Returns:
594
617
  Dict[str, Any]: Result dictionary with keys:
595
618
  - status (str): "success" or "error"
@@ -609,67 +632,24 @@ class SingleAgentWorker(Worker):
609
632
  DeprecationWarning,
610
633
  stacklevel=2,
611
634
  )
612
- try:
613
- # validate requirements
614
- validation_error = self._validate_workflow_save_requirements()
615
- if validation_error:
616
- return validation_error
617
-
618
- # setup context utility and agent
619
- context_util = self._get_context_utility()
620
- self.worker.set_context_utility(context_util)
621
-
622
- # prepare workflow summarization components
623
- structured_prompt = self._prepare_workflow_prompt()
624
- agent_to_summarize = self._select_agent_for_summarization(
625
- context_util
626
- )
627
635
 
628
- # check if we should use role_name or let summarize extract
629
- # task_title
630
- role_name = getattr(self.worker, 'role_name', 'assistant')
631
- use_role_name_for_filename = role_name.lower() not in {
632
- 'assistant',
633
- 'agent',
634
- 'user',
635
- 'system',
636
- }
637
-
638
- # generate and save workflow summary
639
- # if role_name is explicit, use it for filename
640
- # if role_name is generic, pass none to let summarize use
641
- # task_title
642
- filename = (
643
- self._generate_workflow_filename()
644
- if use_role_name_for_filename
645
- else None
646
- )
636
+ manager = self._get_workflow_manager()
637
+ result = manager.save_workflow(
638
+ conversation_accumulator=self._conversation_accumulator
639
+ )
647
640
 
648
- result = agent_to_summarize.summarize(
649
- filename=filename,
650
- summary_prompt=structured_prompt,
651
- response_format=WorkflowSummary,
641
+ # clean up accumulator after successful save
642
+ if (
643
+ result.get("status") == "success"
644
+ and self._conversation_accumulator is not None
645
+ ):
646
+ logger.info(
647
+ "Cleaning up conversation accumulator after workflow "
648
+ "summarization"
652
649
  )
650
+ self._conversation_accumulator = None
653
651
 
654
- # add worker metadata and cleanup
655
- result["worker_description"] = self.description
656
- if self._conversation_accumulator is not None:
657
- logger.info(
658
- "Cleaning up conversation accumulator after workflow "
659
- "summarization"
660
- )
661
- self._conversation_accumulator = None
662
-
663
- return result
664
-
665
- except Exception as e:
666
- return {
667
- "status": "error",
668
- "summary": "",
669
- "file_path": None,
670
- "worker_description": self.description,
671
- "message": f"Failed to save workflow memories: {e!s}",
672
- }
652
+ return result
673
653
 
674
654
  async def save_workflow_memories_async(self) -> Dict[str, Any]:
675
655
  r"""Asynchronously save the worker's current workflow memories using
@@ -679,6 +659,8 @@ class SingleAgentWorker(Worker):
679
659
  asummarize() for non-blocking LLM calls, enabling parallel
680
660
  summarization of multiple workers.
681
661
 
662
+ Delegates to WorkflowMemoryManager for all workflow operations.
663
+
682
664
  Returns:
683
665
  Dict[str, Any]: Result dictionary with keys:
684
666
  - status (str): "success" or "error"
@@ -686,322 +668,62 @@ class SingleAgentWorker(Worker):
686
668
  - file_path (str): Path to saved file
687
669
  - worker_description (str): Worker description used
688
670
  """
689
- try:
690
- # validate requirements
691
- validation_error = self._validate_workflow_save_requirements()
692
- if validation_error:
693
- return validation_error
694
-
695
- # setup context utility and agent
696
- context_util = self._get_context_utility()
697
- self.worker.set_context_utility(context_util)
698
-
699
- # prepare workflow summarization components
700
- structured_prompt = self._prepare_workflow_prompt()
701
- agent_to_summarize = self._select_agent_for_summarization(
702
- context_util
703
- )
704
-
705
- # check if we should use role_name or let summarize extract
706
- # task_title
707
- role_name = getattr(self.worker, 'role_name', 'assistant')
708
- use_role_name_for_filename = role_name.lower() not in {
709
- 'assistant',
710
- 'agent',
711
- 'user',
712
- 'system',
713
- }
714
-
715
- # generate and save workflow summary
716
- # if role_name is explicit, use it for filename
717
- # if role_name is generic, pass none to let summarize use
718
- # task_title
719
- filename = (
720
- self._generate_workflow_filename()
721
- if use_role_name_for_filename
722
- else None
723
- )
671
+ manager = self._get_workflow_manager()
672
+ result = await manager.save_workflow_async(
673
+ conversation_accumulator=self._conversation_accumulator
674
+ )
724
675
 
725
- # **KEY CHANGE**: Using asummarize() instead of summarize()
726
- result = await agent_to_summarize.asummarize(
727
- filename=filename,
728
- summary_prompt=structured_prompt,
729
- response_format=WorkflowSummary,
676
+ # clean up accumulator after successful save
677
+ if (
678
+ result.get("status") == "success"
679
+ and self._conversation_accumulator is not None
680
+ ):
681
+ logger.info(
682
+ "Cleaning up conversation accumulator after workflow "
683
+ "summarization"
730
684
  )
685
+ self._conversation_accumulator = None
731
686
 
732
- # add worker metadata and cleanup
733
- result["worker_description"] = self.description
734
- if self._conversation_accumulator is not None:
735
- logger.info(
736
- "Cleaning up conversation accumulator after workflow "
737
- "summarization"
738
- )
739
- self._conversation_accumulator = None
740
-
741
- return result
742
-
743
- except Exception as e:
744
- return {
745
- "status": "error",
746
- "summary": "",
747
- "file_path": None,
748
- "worker_description": self.description,
749
- "message": f"Failed to save workflow memories: {e!s}",
750
- }
687
+ return result
751
688
 
752
689
  def load_workflow_memories(
753
690
  self,
754
691
  pattern: Optional[str] = None,
755
- max_files_to_load: int = 3,
692
+ max_workflows: int = 3,
756
693
  session_id: Optional[str] = None,
694
+ use_smart_selection: bool = True,
757
695
  ) -> bool:
758
- r"""Load workflow memories matching worker description
759
- from saved files.
696
+ r"""Load workflow memories using intelligent agent-based selection.
760
697
 
761
- This method searches for workflow memory files that match the worker's
762
- description and loads them into the agent's memory using
763
- ContextUtility.
698
+ This method uses the worker agent to intelligently select the most
699
+ relevant workflows based on metadata (title, description, tags)
700
+ rather than simple filename pattern matching.
701
+
702
+ Delegates to WorkflowMemoryManager for all workflow operations.
764
703
 
765
704
  Args:
766
- pattern (Optional[str]): Custom search pattern for workflow
767
- memory files.
768
- If None, uses worker description to generate pattern.
769
- max_files_to_load (int): Maximum number of workflow files to load.
705
+ pattern (Optional[str]): Legacy parameter for backward
706
+ compatibility. When use_smart_selection=False, uses this
707
+ pattern for file matching. Ignored when smart selection
708
+ is enabled.
709
+ max_workflows (int): Maximum number of workflow files to load.
770
710
  (default: :obj:`3`)
771
711
  session_id (Optional[str]): Specific workforce session ID to load
772
712
  from. If None, searches across all sessions.
773
713
  (default: :obj:`None`)
714
+ use_smart_selection (bool): Whether to use agent-based intelligent
715
+ workflow selection. When True, uses metadata and LLM to select
716
+ most relevant workflows. When False, falls back to pattern
717
+ matching. (default: :obj:`True`)
774
718
 
775
719
  Returns:
776
720
  bool: True if workflow memories were successfully loaded, False
777
721
  otherwise.
778
722
  """
779
- try:
780
- # reset system message to original state before loading
781
- # this prevents duplicate workflow context on multiple calls
782
- if isinstance(self.worker, ChatAgent):
783
- self.worker.reset_to_original_system_message()
784
-
785
- # Find workflow memory files matching the pattern
786
- workflow_files = self._find_workflow_files(pattern, session_id)
787
- if not workflow_files:
788
- return False
789
-
790
- # Load the workflow memory files
791
- loaded_count = self._load_workflow_files(
792
- workflow_files, max_files_to_load
793
- )
794
-
795
- # Report results
796
- logger.info(
797
- f"Successfully loaded {loaded_count} workflow file(s) for "
798
- f"{self.description}"
799
- )
800
- return loaded_count > 0
801
-
802
- except Exception as e:
803
- logger.warning(
804
- f"Error loading workflow memories for {self.description}: "
805
- f"{e!s}"
806
- )
807
- return False
808
-
809
- def _find_workflow_files(
810
- self, pattern: Optional[str], session_id: Optional[str] = None
811
- ) -> List[str]:
812
- r"""Find and return sorted workflow files matching the pattern.
813
-
814
- Args:
815
- pattern (Optional[str]): Custom search pattern for workflow files.
816
- If None, uses worker description to generate pattern.
817
- session_id (Optional[str]): Specific session ID to search in.
818
- If None, searches across all sessions.
819
-
820
- Returns:
821
- List[str]: Sorted list of workflow file paths (empty if
822
- validation fails).
823
- """
824
- # Ensure we have a ChatAgent worker
825
- if not isinstance(self.worker, ChatAgent):
826
- logger.warning(
827
- f"Cannot load workflow: {self.description} worker is not "
828
- "a ChatAgent"
829
- )
830
- return []
831
-
832
- # generate filename-safe search pattern from worker role name
833
- if pattern is None:
834
- from camel.utils.context_utils import ContextUtility
835
-
836
- # get role_name (always available, defaults to "assistant")
837
- role_name = getattr(self.worker, 'role_name', 'assistant')
838
- clean_name = ContextUtility.sanitize_workflow_filename(role_name)
839
-
840
- # check if role_name is generic
841
- generic_names = {'assistant', 'agent', 'user', 'system'}
842
- if clean_name in generic_names:
843
- # for generic role names, search for all workflow files
844
- # since filename is based on task_title
845
- pattern = "*_workflow*.md"
846
- else:
847
- # for explicit role names, search for role-specific files
848
- pattern = f"{clean_name}_workflow*.md"
849
-
850
- # Get the base workforce_workflows directory
851
- camel_workdir = os.environ.get("CAMEL_WORKDIR")
852
- if camel_workdir:
853
- base_dir = os.path.join(camel_workdir, "workforce_workflows")
854
- else:
855
- base_dir = "workforce_workflows"
856
-
857
- # search for workflow files in specified or all session directories
858
- if session_id:
859
- search_path = str(Path(base_dir) / session_id / pattern)
860
- else:
861
- # search across all session directories using wildcard pattern
862
- search_path = str(Path(base_dir) / "*" / pattern)
863
- workflow_files = glob.glob(search_path)
864
-
865
- if not workflow_files:
866
- logger.info(f"No workflow files found for pattern: {pattern}")
867
- return []
868
-
869
- # prioritize most recent sessions by session timestamp in
870
- # directory name
871
- def extract_session_timestamp(filepath: str) -> str:
872
- match = re.search(r'session_(\d{8}_\d{6}_\d{6})', filepath)
873
- return match.group(1) if match else ""
874
-
875
- workflow_files.sort(key=extract_session_timestamp, reverse=True)
876
- return workflow_files
877
-
878
- def _load_workflow_files(
879
- self, workflow_files: List[str], max_files_to_load: int
880
- ) -> int:
881
- r"""Load workflow files and return count of successful loads.
882
-
883
- Args:
884
- workflow_files (List[str]): List of workflow file paths to load.
885
-
886
- Returns:
887
- int: Number of successfully loaded workflow files.
888
- """
889
- loaded_count = 0
890
- # limit loading to prevent context overflow
891
- for file_path in workflow_files[:max_files_to_load]:
892
- try:
893
- # extract file and session info from full path
894
- filename = os.path.basename(file_path).replace('.md', '')
895
- session_dir = os.path.dirname(file_path)
896
- session_id = os.path.basename(session_dir)
897
-
898
- # create context utility for the specific session
899
- # where file exists
900
- temp_utility = ContextUtility.get_workforce_shared(session_id)
901
-
902
- status = temp_utility.load_markdown_context_to_memory(
903
- self.worker, filename
904
- )
905
-
906
- if "Context appended" in status:
907
- loaded_count += 1
908
- logger.info(f"Loaded workflow: {filename}")
909
- else:
910
- logger.warning(
911
- f"Failed to load workflow {filename}: {status}"
912
- )
913
-
914
- except Exception as e:
915
- logger.warning(
916
- f"Failed to load workflow file {file_path}: {e!s}"
917
- )
918
- continue
919
-
920
- return loaded_count
921
-
922
- def _validate_workflow_save_requirements(self) -> Optional[Dict[str, Any]]:
923
- r"""Validate requirements for workflow saving.
924
-
925
- Returns:
926
- Optional[Dict[str, Any]]: Error result dict if validation fails,
927
- None if validation passes.
928
- """
929
- if not isinstance(self.worker, ChatAgent):
930
- return {
931
- "status": "error",
932
- "summary": "",
933
- "file_path": None,
934
- "worker_description": self.description,
935
- "message": (
936
- "Worker must be a ChatAgent instance to save workflow "
937
- "memories"
938
- ),
939
- }
940
- return None
941
-
942
- def _generate_workflow_filename(self) -> str:
943
- r"""Generate a filename for the workflow based on worker role name.
944
-
945
- Uses the worker's explicit role_name when available.
946
-
947
- Returns:
948
- str: Sanitized filename without timestamp and without .md
949
- extension. Format: {role_name}_workflow
950
- """
951
- from camel.utils.context_utils import ContextUtility
952
-
953
- # get role_name (always available, defaults to "assistant"/"Assistant")
954
- role_name = getattr(self.worker, 'role_name', 'assistant')
955
- clean_name = ContextUtility.sanitize_workflow_filename(role_name)
956
-
957
- return f"{clean_name}_workflow"
958
-
959
- def _prepare_workflow_prompt(self) -> str:
960
- r"""Prepare the structured prompt for workflow summarization.
961
-
962
- Returns:
963
- str: Structured prompt for workflow summary.
964
- """
965
- workflow_prompt = WorkflowSummary.get_instruction_prompt()
966
- return StructuredOutputHandler.generate_structured_prompt(
967
- base_prompt=workflow_prompt, schema=WorkflowSummary
723
+ manager = self._get_workflow_manager()
724
+ return manager.load_workflows(
725
+ pattern=pattern,
726
+ max_files_to_load=max_workflows,
727
+ session_id=session_id,
728
+ use_smart_selection=use_smart_selection,
968
729
  )
969
-
970
- def _select_agent_for_summarization(
971
- self, context_util: ContextUtility
972
- ) -> ChatAgent:
973
- r"""Select the best agent for workflow summarization.
974
-
975
- Args:
976
- context_util: Context utility to set on selected agent.
977
-
978
- Returns:
979
- ChatAgent: Agent to use for summarization.
980
- """
981
- agent_to_summarize = self.worker
982
-
983
- if self._conversation_accumulator is not None:
984
- accumulator_messages, _ = (
985
- self._conversation_accumulator.memory.get_context()
986
- )
987
- if accumulator_messages:
988
- self._conversation_accumulator.set_context_utility(
989
- context_util
990
- )
991
- agent_to_summarize = self._conversation_accumulator
992
- logger.info(
993
- f"Using conversation accumulator with "
994
- f"{len(accumulator_messages)} messages for workflow "
995
- f"summary"
996
- )
997
- else:
998
- logger.info(
999
- "Using original worker for workflow summary (no "
1000
- "accumulated conversations)"
1001
- )
1002
- else:
1003
- logger.info(
1004
- "Using original worker for workflow summary (no accumulator)"
1005
- )
1006
-
1007
- return agent_to_summarize