Compare commits

..

4 Commits

5 changed files with 14 additions and 105 deletions

View File

@@ -873,22 +873,10 @@ class Crew(BaseModel):
tools = self._inject_delegation_tools(tools, self.manager_agent, self.agents)
return tools
def _get_context(self, task: Task, task_outputs: List[TaskOutput]) -> str:
"""Get context for task execution.
Determines whether to use the task's explicit context or aggregate outputs from previous tasks.
When task.context is an empty list, it will use the task_outputs instead.
Args:
task: The task to get context for
task_outputs: List of previous task outputs
Returns:
String containing the aggregated context
"""
def _get_context(self, task: Task, task_outputs: List[TaskOutput]):
context = (
aggregate_raw_outputs_from_tasks(task.context)
if task.context and len(task.context) > 0
if task.context
else aggregate_raw_outputs_from_task_outputs(task_outputs)
)
return context

View File

@@ -14,13 +14,13 @@ class Knowledge(BaseModel):
Knowledge is a collection of sources and setup for the vector store to save and query relevant context.
Args:
sources: List[BaseKnowledgeSource] = Field(default_factory=list)
storage: KnowledgeStorage = Field(default_factory=KnowledgeStorage)
storage: Optional[KnowledgeStorage] = Field(default=None)
embedder_config: Optional[Dict[str, Any]] = None
"""
sources: List[BaseKnowledgeSource] = Field(default_factory=list)
model_config = ConfigDict(arbitrary_types_allowed=True)
storage: KnowledgeStorage = Field(default_factory=KnowledgeStorage)
storage: Optional[KnowledgeStorage] = Field(default=None)
embedder_config: Optional[Dict[str, Any]] = None
collection_name: Optional[str] = None

View File

@@ -22,7 +22,7 @@ class BaseFileKnowledgeSource(BaseKnowledgeSource, ABC):
default_factory=list, description="The path to the file"
)
content: Dict[Path, str] = Field(init=False, default_factory=dict)
storage: KnowledgeStorage = Field(default_factory=KnowledgeStorage)
storage: Optional[KnowledgeStorage] = Field(default=None)
safe_file_paths: List[Path] = Field(default_factory=list)
@field_validator("file_path", "file_paths", mode="before")
@@ -62,7 +62,10 @@ class BaseFileKnowledgeSource(BaseKnowledgeSource, ABC):
def _save_documents(self):
"""Save the documents to the storage."""
self.storage.save(self.chunks)
if self.storage:
self.storage.save(self.chunks)
else:
raise ValueError("No storage found to save documents.")
def convert_to_path(self, path: Union[Path, str]) -> Path:
"""Convert a path to a Path object."""

View File

@@ -16,7 +16,7 @@ class BaseKnowledgeSource(BaseModel, ABC):
chunk_embeddings: List[np.ndarray] = Field(default_factory=list)
model_config = ConfigDict(arbitrary_types_allowed=True)
storage: KnowledgeStorage = Field(default_factory=KnowledgeStorage)
storage: Optional[KnowledgeStorage] = Field(default=None)
metadata: Dict[str, Any] = Field(default_factory=dict) # Currently unused
collection_name: Optional[str] = Field(default=None)
@@ -46,4 +46,7 @@ class BaseKnowledgeSource(BaseModel, ABC):
Save the documents to the storage.
This method should be called after the chunks and embeddings are generated.
"""
self.storage.save(self.chunks)
if self.storage:
self.storage.save(self.chunks)
else:
raise ValueError("No storage found to save documents.")

View File

@@ -1,85 +0,0 @@
"""Test that context=[] is respected and doesn't include previous task outputs."""
from unittest import mock
import pytest
from crewai import Agent, Crew, Process, Task
from crewai.tasks.task_output import OutputFormat, TaskOutput
from crewai.utilities.formatter import (
aggregate_raw_outputs_from_task_outputs,
aggregate_raw_outputs_from_tasks,
)
def test_context_empty_list():
"""Test that context=[] is respected and doesn't include previous task outputs.
This test verifies that when a task has context=[], the _get_context method
correctly uses task_outputs instead of an empty context list.
Returns:
None
Raises:
AssertionError: If the context handling doesn't work as expected
"""
researcher = Agent(
role='Researcher',
goal='Research thoroughly',
backstory='You are an expert researcher'
)
task_with_empty_context = Task(
description='Task with empty context',
expected_output='Output',
agent=researcher,
context=[] # Explicitly set context to empty list
)
task_outputs = [
TaskOutput(
description="Previous task output",
raw="Previous task result",
agent="Researcher",
json_dict=None,
output_format=OutputFormat.RAW,
pydantic=None,
summary="Previous task result",
)
]
crew = Crew(
agents=[researcher],
tasks=[task_with_empty_context],
process=Process.sequential,
verbose=False
)
with mock.patch('crewai.agent.Agent.execute_task') as mock_execute:
mock_execute.return_value = "Mocked execution result"
context = crew._get_context(task_with_empty_context, task_outputs)
# So it should return the aggregated task_outputs
expected_context = aggregate_raw_outputs_from_task_outputs(task_outputs)
assert context == expected_context
assert not (task_with_empty_context.context and len(task_with_empty_context.context) > 0)
other_task = Task(
description='Other task',
expected_output='Output',
agent=researcher
)
task_with_context = Task(
description='Task with context',
expected_output='Output',
agent=researcher,
context=[other_task] # Non-empty context
)
assert task_with_context.context and len(task_with_context.context) > 0