mirror of
https://github.com/crewAIInc/crewAI.git
synced 2026-05-01 07:13:00 +00:00
Merge branch 'main' into fix/fingerprint-config-not-args
This commit is contained in:
@@ -4,6 +4,28 @@ description: "تحديثات المنتج والتحسينات وإصلاحات
|
|||||||
icon: "clock"
|
icon: "clock"
|
||||||
mode: "wide"
|
mode: "wide"
|
||||||
---
|
---
|
||||||
|
<Update label="2 أبريل 2026">
|
||||||
|
## v1.13.0a7
|
||||||
|
|
||||||
|
[عرض الإصدار على GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.13.0a7)
|
||||||
|
|
||||||
|
## ما الذي تغير
|
||||||
|
|
||||||
|
### الميزات
|
||||||
|
- إضافة امتداد A2UI مع دعم v0.8/v0.9، والمخططات، والوثائق
|
||||||
|
|
||||||
|
### إصلاحات الأخطاء
|
||||||
|
- إصلاح بادئات الرؤية متعددة الأنماط عن طريق إضافة GPT-5 وسلسلة o
|
||||||
|
|
||||||
|
### الوثائق
|
||||||
|
- تحديث سجل التغييرات والإصدار لـ v1.13.0a6
|
||||||
|
|
||||||
|
## المساهمون
|
||||||
|
|
||||||
|
@alex-clawd, @greysonlalonde, @joaomdmoura
|
||||||
|
|
||||||
|
</Update>
|
||||||
|
|
||||||
<Update label="1 أبريل 2026">
|
<Update label="1 أبريل 2026">
|
||||||
## v1.13.0a6
|
## v1.13.0a6
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,28 @@ description: "Product updates, improvements, and bug fixes for CrewAI"
|
|||||||
icon: "clock"
|
icon: "clock"
|
||||||
mode: "wide"
|
mode: "wide"
|
||||||
---
|
---
|
||||||
|
<Update label="Apr 02, 2026">
|
||||||
|
## v1.13.0a7
|
||||||
|
|
||||||
|
[View release on GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.13.0a7)
|
||||||
|
|
||||||
|
## What's Changed
|
||||||
|
|
||||||
|
### Features
|
||||||
|
- Add A2UI extension with v0.8/v0.9 support, schemas, and docs
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
- Fix multimodal vision prefixes by adding GPT-5 and o-series
|
||||||
|
|
||||||
|
### Documentation
|
||||||
|
- Update changelog and version for v1.13.0a6
|
||||||
|
|
||||||
|
## Contributors
|
||||||
|
|
||||||
|
@alex-clawd, @greysonlalonde, @joaomdmoura
|
||||||
|
|
||||||
|
</Update>
|
||||||
|
|
||||||
<Update label="Apr 01, 2026">
|
<Update label="Apr 01, 2026">
|
||||||
## v1.13.0a6
|
## v1.13.0a6
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,28 @@ description: "CrewAI의 제품 업데이트, 개선 사항 및 버그 수정"
|
|||||||
icon: "clock"
|
icon: "clock"
|
||||||
mode: "wide"
|
mode: "wide"
|
||||||
---
|
---
|
||||||
|
<Update label="2026년 4월 2일">
|
||||||
|
## v1.13.0a7
|
||||||
|
|
||||||
|
[GitHub 릴리스 보기](https://github.com/crewAIInc/crewAI/releases/tag/1.13.0a7)
|
||||||
|
|
||||||
|
## 변경 사항
|
||||||
|
|
||||||
|
### 기능
|
||||||
|
- v0.8/v0.9 지원, 스키마 및 문서가 포함된 A2UI 확장 추가
|
||||||
|
|
||||||
|
### 버그 수정
|
||||||
|
- GPT-5 및 o-series를 추가하여 다중 모드 비전 접두사 수정
|
||||||
|
|
||||||
|
### 문서
|
||||||
|
- v1.13.0a6에 대한 변경 로그 및 버전 업데이트
|
||||||
|
|
||||||
|
## 기여자
|
||||||
|
|
||||||
|
@alex-clawd, @greysonlalonde, @joaomdmoura
|
||||||
|
|
||||||
|
</Update>
|
||||||
|
|
||||||
<Update label="2026년 4월 1일">
|
<Update label="2026년 4월 1일">
|
||||||
## v1.13.0a6
|
## v1.13.0a6
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,28 @@ description: "Atualizações de produto, melhorias e correções do CrewAI"
|
|||||||
icon: "clock"
|
icon: "clock"
|
||||||
mode: "wide"
|
mode: "wide"
|
||||||
---
|
---
|
||||||
|
<Update label="02 abr 2026">
|
||||||
|
## v1.13.0a7
|
||||||
|
|
||||||
|
[Ver release no GitHub](https://github.com/crewAIInc/crewAI/releases/tag/1.13.0a7)
|
||||||
|
|
||||||
|
## O que Mudou
|
||||||
|
|
||||||
|
### Funcionalidades
|
||||||
|
- Adicionar a extensão A2UI com suporte a v0.8/v0.9, esquemas e documentação
|
||||||
|
|
||||||
|
### Correções de Bugs
|
||||||
|
- Corrigir prefixos de visão multimodal adicionando GPT-5 e o-series
|
||||||
|
|
||||||
|
### Documentação
|
||||||
|
- Atualizar changelog e versão para v1.13.0a6
|
||||||
|
|
||||||
|
## Contribuidores
|
||||||
|
|
||||||
|
@alex-clawd, @greysonlalonde, @joaomdmoura
|
||||||
|
|
||||||
|
</Update>
|
||||||
|
|
||||||
<Update label="01 abr 2026">
|
<Update label="01 abr 2026">
|
||||||
## v1.13.0a6
|
## v1.13.0a6
|
||||||
|
|
||||||
|
|||||||
@@ -152,4 +152,4 @@ __all__ = [
|
|||||||
"wrap_file_source",
|
"wrap_file_source",
|
||||||
]
|
]
|
||||||
|
|
||||||
__version__ = "1.13.0a6"
|
__version__ = "1.13.0a7"
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ dependencies = [
|
|||||||
"pytube~=15.0.0",
|
"pytube~=15.0.0",
|
||||||
"requests~=2.32.5",
|
"requests~=2.32.5",
|
||||||
"docker~=7.1.0",
|
"docker~=7.1.0",
|
||||||
"crewai==1.13.0a6",
|
"crewai==1.13.0a7",
|
||||||
"tiktoken~=0.8.0",
|
"tiktoken~=0.8.0",
|
||||||
"beautifulsoup4~=4.13.4",
|
"beautifulsoup4~=4.13.4",
|
||||||
"python-docx~=1.2.0",
|
"python-docx~=1.2.0",
|
||||||
|
|||||||
@@ -309,4 +309,4 @@ __all__ = [
|
|||||||
"ZapierActionTools",
|
"ZapierActionTools",
|
||||||
]
|
]
|
||||||
|
|
||||||
__version__ = "1.13.0a6"
|
__version__ = "1.13.0a7"
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ Repository = "https://github.com/crewAIInc/crewAI"
|
|||||||
|
|
||||||
[project.optional-dependencies]
|
[project.optional-dependencies]
|
||||||
tools = [
|
tools = [
|
||||||
"crewai-tools==1.13.0a6",
|
"crewai-tools==1.13.0a7",
|
||||||
]
|
]
|
||||||
embeddings = [
|
embeddings = [
|
||||||
"tiktoken~=0.8.0"
|
"tiktoken~=0.8.0"
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ from crewai.agent.core import Agent
|
|||||||
from crewai.agent.planning_config import PlanningConfig
|
from crewai.agent.planning_config import PlanningConfig
|
||||||
from crewai.crew import Crew
|
from crewai.crew import Crew
|
||||||
from crewai.crews.crew_output import CrewOutput
|
from crewai.crews.crew_output import CrewOutput
|
||||||
|
from crewai.execution_context import ExecutionContext
|
||||||
from crewai.flow.flow import Flow
|
from crewai.flow.flow import Flow
|
||||||
from crewai.knowledge.knowledge import Knowledge
|
from crewai.knowledge.knowledge import Knowledge
|
||||||
from crewai.llm import LLM
|
from crewai.llm import LLM
|
||||||
@@ -44,7 +45,7 @@ def _suppress_pydantic_deprecation_warnings() -> None:
|
|||||||
|
|
||||||
_suppress_pydantic_deprecation_warnings()
|
_suppress_pydantic_deprecation_warnings()
|
||||||
|
|
||||||
__version__ = "1.13.0a6"
|
__version__ = "1.13.0a7"
|
||||||
_telemetry_submitted = False
|
_telemetry_submitted = False
|
||||||
|
|
||||||
|
|
||||||
@@ -96,6 +97,10 @@ def __getattr__(name: str) -> Any:
|
|||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
from crewai.agents.agent_builder.base_agent import BaseAgent as _BaseAgent
|
||||||
|
from crewai.agents.agent_builder.base_agent_executor_mixin import (
|
||||||
|
CrewAgentExecutorMixin as _CrewAgentExecutorMixin,
|
||||||
|
)
|
||||||
from crewai.agents.tools_handler import ToolsHandler as _ToolsHandler
|
from crewai.agents.tools_handler import ToolsHandler as _ToolsHandler
|
||||||
from crewai.experimental.agent_executor import AgentExecutor as _AgentExecutor
|
from crewai.experimental.agent_executor import AgentExecutor as _AgentExecutor
|
||||||
from crewai.hooks.llm_hooks import LLMCallHookContext as _LLMCallHookContext
|
from crewai.hooks.llm_hooks import LLMCallHookContext as _LLMCallHookContext
|
||||||
@@ -105,25 +110,66 @@ try:
|
|||||||
SystemPromptResult as _SystemPromptResult,
|
SystemPromptResult as _SystemPromptResult,
|
||||||
)
|
)
|
||||||
|
|
||||||
_AgentExecutor.model_rebuild(
|
_base_namespace: dict[str, type] = {
|
||||||
force=True,
|
"Agent": Agent,
|
||||||
_types_namespace={
|
"Crew": Crew,
|
||||||
"Agent": Agent,
|
"BaseLLM": BaseLLM,
|
||||||
"ToolsHandler": _ToolsHandler,
|
"Task": Task,
|
||||||
"Crew": Crew,
|
"CrewAgentExecutorMixin": _CrewAgentExecutorMixin,
|
||||||
"BaseLLM": BaseLLM,
|
}
|
||||||
"Task": Task,
|
|
||||||
"StandardPromptResult": _StandardPromptResult,
|
try:
|
||||||
"SystemPromptResult": _SystemPromptResult,
|
from crewai.a2a.config import (
|
||||||
"LLMCallHookContext": _LLMCallHookContext,
|
A2AClientConfig as _A2AClientConfig,
|
||||||
"ToolResult": _ToolResult,
|
A2AConfig as _A2AConfig,
|
||||||
},
|
A2AServerConfig as _A2AServerConfig,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
_base_namespace.update(
|
||||||
|
{
|
||||||
|
"A2AConfig": _A2AConfig,
|
||||||
|
"A2AClientConfig": _A2AClientConfig,
|
||||||
|
"A2AServerConfig": _A2AServerConfig,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
_full_namespace = {
|
||||||
|
**_base_namespace,
|
||||||
|
"ToolsHandler": _ToolsHandler,
|
||||||
|
"StandardPromptResult": _StandardPromptResult,
|
||||||
|
"SystemPromptResult": _SystemPromptResult,
|
||||||
|
"LLMCallHookContext": _LLMCallHookContext,
|
||||||
|
"ToolResult": _ToolResult,
|
||||||
|
}
|
||||||
|
|
||||||
|
_resolve_namespace = {
|
||||||
|
**_full_namespace,
|
||||||
|
**sys.modules[_BaseAgent.__module__].__dict__,
|
||||||
|
}
|
||||||
|
|
||||||
|
for _mod_name in (
|
||||||
|
_BaseAgent.__module__,
|
||||||
|
Agent.__module__,
|
||||||
|
_AgentExecutor.__module__,
|
||||||
|
):
|
||||||
|
sys.modules[_mod_name].__dict__.update(_resolve_namespace)
|
||||||
|
|
||||||
|
_BaseAgent.model_rebuild(force=True, _types_namespace=_full_namespace)
|
||||||
|
_AgentExecutor.model_rebuild(force=True, _types_namespace=_full_namespace)
|
||||||
|
|
||||||
|
try:
|
||||||
|
Agent.model_rebuild(force=True, _types_namespace=_full_namespace)
|
||||||
|
except PydanticUserError:
|
||||||
|
pass
|
||||||
except (ImportError, PydanticUserError):
|
except (ImportError, PydanticUserError):
|
||||||
import logging as _logging
|
import logging as _logging
|
||||||
|
|
||||||
_logging.getLogger(__name__).warning(
|
_logging.getLogger(__name__).warning(
|
||||||
"AgentExecutor.model_rebuild() failed; forward refs may be unresolved.",
|
"model_rebuild() failed; forward refs may be unresolved.",
|
||||||
exc_info=True,
|
exc_info=True,
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -133,6 +179,7 @@ __all__ = [
|
|||||||
"BaseLLM",
|
"BaseLLM",
|
||||||
"Crew",
|
"Crew",
|
||||||
"CrewOutput",
|
"CrewOutput",
|
||||||
|
"ExecutionContext",
|
||||||
"Flow",
|
"Flow",
|
||||||
"Knowledge",
|
"Knowledge",
|
||||||
"LLMGuardrail",
|
"LLMGuardrail",
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ from pydantic import (
|
|||||||
BaseModel,
|
BaseModel,
|
||||||
ConfigDict,
|
ConfigDict,
|
||||||
Field,
|
Field,
|
||||||
|
InstanceOf,
|
||||||
PrivateAttr,
|
PrivateAttr,
|
||||||
model_validator,
|
model_validator,
|
||||||
)
|
)
|
||||||
@@ -267,6 +268,9 @@ class Agent(BaseAgent):
|
|||||||
Can be a single A2AConfig/A2AClientConfig/A2AServerConfig, or a list of any number of A2AConfig/A2AClientConfig with a single A2AServerConfig.
|
Can be a single A2AConfig/A2AClientConfig/A2AServerConfig, or a list of any number of A2AConfig/A2AClientConfig with a single A2AServerConfig.
|
||||||
""",
|
""",
|
||||||
)
|
)
|
||||||
|
agent_executor: InstanceOf[CrewAgentExecutor] | InstanceOf[AgentExecutor] | None = (
|
||||||
|
Field(default=None, description="An instance of the CrewAgentExecutor class.")
|
||||||
|
)
|
||||||
executor_class: type[CrewAgentExecutor] | type[AgentExecutor] = Field(
|
executor_class: type[CrewAgentExecutor] | type[AgentExecutor] = Field(
|
||||||
default=CrewAgentExecutor,
|
default=CrewAgentExecutor,
|
||||||
description="Class to use for the agent executor. Defaults to CrewAgentExecutor, can optionally use AgentExecutor.",
|
description="Class to use for the agent executor. Defaults to CrewAgentExecutor, can optionally use AgentExecutor.",
|
||||||
@@ -690,7 +694,9 @@ class Agent(BaseAgent):
|
|||||||
task_prompt,
|
task_prompt,
|
||||||
knowledge_config,
|
knowledge_config,
|
||||||
self.knowledge.query if self.knowledge else lambda *a, **k: None,
|
self.knowledge.query if self.knowledge else lambda *a, **k: None,
|
||||||
self.crew.query_knowledge if self.crew else lambda *a, **k: None,
|
self.crew.query_knowledge
|
||||||
|
if self.crew and not isinstance(self.crew, str)
|
||||||
|
else lambda *a, **k: None,
|
||||||
)
|
)
|
||||||
|
|
||||||
task_prompt = self._finalize_task_prompt(task_prompt, tools, task)
|
task_prompt = self._finalize_task_prompt(task_prompt, tools, task)
|
||||||
@@ -777,14 +783,18 @@ class Agent(BaseAgent):
|
|||||||
if not self.agent_executor:
|
if not self.agent_executor:
|
||||||
raise RuntimeError("Agent executor is not initialized.")
|
raise RuntimeError("Agent executor is not initialized.")
|
||||||
|
|
||||||
return self.agent_executor.invoke(
|
result = cast(
|
||||||
{
|
dict[str, Any],
|
||||||
"input": task_prompt,
|
self.agent_executor.invoke(
|
||||||
"tool_names": self.agent_executor.tools_names,
|
{
|
||||||
"tools": self.agent_executor.tools_description,
|
"input": task_prompt,
|
||||||
"ask_for_human_input": task.human_input,
|
"tool_names": self.agent_executor.tools_names,
|
||||||
}
|
"tools": self.agent_executor.tools_description,
|
||||||
)["output"]
|
"ask_for_human_input": task.human_input,
|
||||||
|
}
|
||||||
|
),
|
||||||
|
)
|
||||||
|
return result["output"]
|
||||||
|
|
||||||
async def aexecute_task(
|
async def aexecute_task(
|
||||||
self,
|
self,
|
||||||
@@ -955,19 +965,23 @@ class Agent(BaseAgent):
|
|||||||
if self.agent_executor is not None:
|
if self.agent_executor is not None:
|
||||||
self._update_executor_parameters(
|
self._update_executor_parameters(
|
||||||
task=task,
|
task=task,
|
||||||
tools=parsed_tools, # type: ignore[arg-type]
|
tools=parsed_tools,
|
||||||
raw_tools=raw_tools,
|
raw_tools=raw_tools,
|
||||||
prompt=prompt,
|
prompt=prompt,
|
||||||
stop_words=stop_words,
|
stop_words=stop_words,
|
||||||
rpm_limit_fn=rpm_limit_fn,
|
rpm_limit_fn=rpm_limit_fn,
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
if not isinstance(self.llm, BaseLLM):
|
||||||
|
raise RuntimeError(
|
||||||
|
"LLM must be resolved before creating agent executor."
|
||||||
|
)
|
||||||
self.agent_executor = self.executor_class(
|
self.agent_executor = self.executor_class(
|
||||||
llm=cast(BaseLLM, self.llm),
|
llm=self.llm,
|
||||||
task=task, # type: ignore[arg-type]
|
task=task, # type: ignore[arg-type]
|
||||||
i18n=self.i18n,
|
i18n=self.i18n,
|
||||||
agent=self,
|
agent=self,
|
||||||
crew=self.crew,
|
crew=self.crew, # type: ignore[arg-type]
|
||||||
tools=parsed_tools,
|
tools=parsed_tools,
|
||||||
prompt=prompt,
|
prompt=prompt,
|
||||||
original_tools=raw_tools,
|
original_tools=raw_tools,
|
||||||
@@ -991,7 +1005,7 @@ class Agent(BaseAgent):
|
|||||||
def _update_executor_parameters(
|
def _update_executor_parameters(
|
||||||
self,
|
self,
|
||||||
task: Task | None,
|
task: Task | None,
|
||||||
tools: list[BaseTool],
|
tools: list[CrewStructuredTool],
|
||||||
raw_tools: list[BaseTool],
|
raw_tools: list[BaseTool],
|
||||||
prompt: SystemPromptResult | StandardPromptResult,
|
prompt: SystemPromptResult | StandardPromptResult,
|
||||||
stop_words: list[str],
|
stop_words: list[str],
|
||||||
@@ -1007,11 +1021,17 @@ class Agent(BaseAgent):
|
|||||||
stop_words: Stop words list.
|
stop_words: Stop words list.
|
||||||
rpm_limit_fn: RPM limit callback function.
|
rpm_limit_fn: RPM limit callback function.
|
||||||
"""
|
"""
|
||||||
|
if self.agent_executor is None:
|
||||||
|
raise RuntimeError("Agent executor is not initialized.")
|
||||||
|
|
||||||
self.agent_executor.task = task
|
self.agent_executor.task = task
|
||||||
self.agent_executor.tools = tools
|
self.agent_executor.tools = tools
|
||||||
self.agent_executor.original_tools = raw_tools
|
self.agent_executor.original_tools = raw_tools
|
||||||
self.agent_executor.prompt = prompt
|
self.agent_executor.prompt = prompt
|
||||||
self.agent_executor.stop_words = stop_words
|
if isinstance(self.agent_executor, AgentExecutor):
|
||||||
|
self.agent_executor.stop_words = stop_words
|
||||||
|
else:
|
||||||
|
self.agent_executor.stop = stop_words
|
||||||
self.agent_executor.tools_names = get_tool_names(tools)
|
self.agent_executor.tools_names = get_tool_names(tools)
|
||||||
self.agent_executor.tools_description = render_text_description_and_args(tools)
|
self.agent_executor.tools_description = render_text_description_and_args(tools)
|
||||||
self.agent_executor.response_model = (
|
self.agent_executor.response_model = (
|
||||||
@@ -1787,21 +1807,3 @@ class Agent(BaseAgent):
|
|||||||
LiteAgentOutput: The result of the agent execution.
|
LiteAgentOutput: The result of the agent execution.
|
||||||
"""
|
"""
|
||||||
return await self.kickoff_async(messages, response_format, input_files)
|
return await self.kickoff_async(messages, response_format, input_files)
|
||||||
|
|
||||||
|
|
||||||
try:
|
|
||||||
from crewai.a2a.config import (
|
|
||||||
A2AClientConfig as _A2AClientConfig,
|
|
||||||
A2AConfig as _A2AConfig,
|
|
||||||
A2AServerConfig as _A2AServerConfig,
|
|
||||||
)
|
|
||||||
|
|
||||||
Agent.model_rebuild(
|
|
||||||
_types_namespace={
|
|
||||||
"A2AConfig": _A2AConfig,
|
|
||||||
"A2AClientConfig": _A2AClientConfig,
|
|
||||||
"A2AServerConfig": _A2AServerConfig,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
except ImportError:
|
|
||||||
pass
|
|
||||||
|
|||||||
@@ -137,7 +137,8 @@ def handle_knowledge_retrieval(
|
|||||||
Returns:
|
Returns:
|
||||||
The task prompt potentially augmented with knowledge context.
|
The task prompt potentially augmented with knowledge context.
|
||||||
"""
|
"""
|
||||||
if not (agent.knowledge or (agent.crew and agent.crew.knowledge)):
|
_crew = agent.crew if not isinstance(agent.crew, str) else None
|
||||||
|
if not (agent.knowledge or (_crew and _crew.knowledge)):
|
||||||
return task_prompt
|
return task_prompt
|
||||||
|
|
||||||
crewai_event_bus.emit(
|
crewai_event_bus.emit(
|
||||||
@@ -244,7 +245,7 @@ def apply_training_data(agent: Agent, task_prompt: str) -> str:
|
|||||||
Returns:
|
Returns:
|
||||||
The task prompt with training data applied.
|
The task prompt with training data applied.
|
||||||
"""
|
"""
|
||||||
if agent.crew and agent.crew._train:
|
if agent.crew and not isinstance(agent.crew, str) and agent.crew._train:
|
||||||
return agent._training_handler(task_prompt=task_prompt)
|
return agent._training_handler(task_prompt=task_prompt)
|
||||||
return agent._use_trained_data(task_prompt=task_prompt)
|
return agent._use_trained_data(task_prompt=task_prompt)
|
||||||
|
|
||||||
@@ -355,7 +356,8 @@ async def ahandle_knowledge_retrieval(
|
|||||||
Returns:
|
Returns:
|
||||||
The task prompt potentially augmented with knowledge context.
|
The task prompt potentially augmented with knowledge context.
|
||||||
"""
|
"""
|
||||||
if not (agent.knowledge or (agent.crew and agent.crew.knowledge)):
|
_crew = agent.crew if not isinstance(agent.crew, str) else None
|
||||||
|
if not (agent.knowledge or (_crew and _crew.knowledge)):
|
||||||
return task_prompt
|
return task_prompt
|
||||||
|
|
||||||
crewai_event_bus.emit(
|
crewai_event_bus.emit(
|
||||||
@@ -381,15 +383,16 @@ async def ahandle_knowledge_retrieval(
|
|||||||
if agent.agent_knowledge_context:
|
if agent.agent_knowledge_context:
|
||||||
task_prompt += agent.agent_knowledge_context
|
task_prompt += agent.agent_knowledge_context
|
||||||
|
|
||||||
knowledge_snippets = await agent.crew.aquery_knowledge(
|
if _crew:
|
||||||
[agent.knowledge_search_query], **knowledge_config
|
knowledge_snippets = await _crew.aquery_knowledge(
|
||||||
)
|
[agent.knowledge_search_query], **knowledge_config
|
||||||
if knowledge_snippets:
|
|
||||||
agent.crew_knowledge_context = extract_knowledge_context(
|
|
||||||
knowledge_snippets
|
|
||||||
)
|
)
|
||||||
if agent.crew_knowledge_context:
|
if knowledge_snippets:
|
||||||
task_prompt += agent.crew_knowledge_context
|
agent.crew_knowledge_context = extract_knowledge_context(
|
||||||
|
knowledge_snippets
|
||||||
|
)
|
||||||
|
if agent.crew_knowledge_context:
|
||||||
|
task_prompt += agent.crew_knowledge_context
|
||||||
|
|
||||||
crewai_event_bus.emit(
|
crewai_event_bus.emit(
|
||||||
agent,
|
agent,
|
||||||
|
|||||||
@@ -188,14 +188,14 @@ class OpenAIAgentAdapter(BaseAgentAdapter):
|
|||||||
self._openai_agent = OpenAIAgent(
|
self._openai_agent = OpenAIAgent(
|
||||||
name=self.role,
|
name=self.role,
|
||||||
instructions=instructions,
|
instructions=instructions,
|
||||||
model=self.llm,
|
model=str(self.llm),
|
||||||
**self._agent_config or {},
|
**self._agent_config or {},
|
||||||
)
|
)
|
||||||
|
|
||||||
if all_tools:
|
if all_tools:
|
||||||
self.configure_tools(all_tools)
|
self.configure_tools(all_tools)
|
||||||
|
|
||||||
self.agent_executor = Runner
|
self.agent_executor = Runner # type: ignore[assignment]
|
||||||
|
|
||||||
def configure_tools(self, tools: list[BaseTool] | None = None) -> None:
|
def configure_tools(self, tools: list[BaseTool] | None = None) -> None:
|
||||||
"""Configure tools for the OpenAI Assistant.
|
"""Configure tools for the OpenAI Assistant.
|
||||||
|
|||||||
@@ -5,21 +5,25 @@ from copy import copy as shallow_copy
|
|||||||
from hashlib import md5
|
from hashlib import md5
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import re
|
import re
|
||||||
from typing import Any, Final, Literal
|
from typing import TYPE_CHECKING, Annotated, Any, Final, Literal
|
||||||
import uuid
|
import uuid
|
||||||
|
|
||||||
from pydantic import (
|
from pydantic import (
|
||||||
UUID4,
|
UUID4,
|
||||||
BaseModel,
|
BaseModel,
|
||||||
|
BeforeValidator,
|
||||||
Field,
|
Field,
|
||||||
|
InstanceOf,
|
||||||
PrivateAttr,
|
PrivateAttr,
|
||||||
field_validator,
|
field_validator,
|
||||||
model_validator,
|
model_validator,
|
||||||
)
|
)
|
||||||
|
from pydantic.functional_serializers import PlainSerializer
|
||||||
from pydantic_core import PydanticCustomError
|
from pydantic_core import PydanticCustomError
|
||||||
from typing_extensions import Self
|
from typing_extensions import Self
|
||||||
|
|
||||||
from crewai.agent.internal.meta import AgentMeta
|
from crewai.agent.internal.meta import AgentMeta
|
||||||
|
from crewai.agents.agent_builder.base_agent_executor_mixin import CrewAgentExecutorMixin
|
||||||
from crewai.agents.agent_builder.utilities.base_token_process import TokenProcess
|
from crewai.agents.agent_builder.utilities.base_token_process import TokenProcess
|
||||||
from crewai.agents.cache.cache_handler import CacheHandler
|
from crewai.agents.cache.cache_handler import CacheHandler
|
||||||
from crewai.agents.tools_handler import ToolsHandler
|
from crewai.agents.tools_handler import ToolsHandler
|
||||||
@@ -27,6 +31,7 @@ from crewai.knowledge.knowledge import Knowledge
|
|||||||
from crewai.knowledge.knowledge_config import KnowledgeConfig
|
from crewai.knowledge.knowledge_config import KnowledgeConfig
|
||||||
from crewai.knowledge.source.base_knowledge_source import BaseKnowledgeSource
|
from crewai.knowledge.source.base_knowledge_source import BaseKnowledgeSource
|
||||||
from crewai.knowledge.storage.base_knowledge_storage import BaseKnowledgeStorage
|
from crewai.knowledge.storage.base_knowledge_storage import BaseKnowledgeStorage
|
||||||
|
from crewai.llms.base_llm import BaseLLM
|
||||||
from crewai.mcp.config import MCPServerConfig
|
from crewai.mcp.config import MCPServerConfig
|
||||||
from crewai.memory.memory_scope import MemoryScope, MemorySlice
|
from crewai.memory.memory_scope import MemoryScope, MemorySlice
|
||||||
from crewai.memory.unified_memory import Memory
|
from crewai.memory.unified_memory import Memory
|
||||||
@@ -42,6 +47,20 @@ from crewai.utilities.rpm_controller import RPMController
|
|||||||
from crewai.utilities.string_utils import interpolate_only
|
from crewai.utilities.string_utils import interpolate_only
|
||||||
|
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from crewai.crew import Crew
|
||||||
|
|
||||||
|
|
||||||
|
def _validate_crew_ref(value: Any) -> Any:
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
|
def _serialize_crew_ref(value: Any) -> str | None:
|
||||||
|
if value is None:
|
||||||
|
return None
|
||||||
|
return str(value.id) if hasattr(value, "id") else str(value)
|
||||||
|
|
||||||
|
|
||||||
_SLUG_RE: Final[re.Pattern[str]] = re.compile(
|
_SLUG_RE: Final[re.Pattern[str]] = re.compile(
|
||||||
r"^(?:crewai-amp:)?[a-zA-Z0-9][a-zA-Z0-9_-]*(?:#[\w-]+)?$"
|
r"^(?:crewai-amp:)?[a-zA-Z0-9][a-zA-Z0-9_-]*(?:#[\w-]+)?$"
|
||||||
)
|
)
|
||||||
@@ -122,7 +141,7 @@ class BaseAgent(BaseModel, ABC, metaclass=AgentMeta):
|
|||||||
__hash__ = object.__hash__
|
__hash__ = object.__hash__
|
||||||
_logger: Logger = PrivateAttr(default_factory=lambda: Logger(verbose=False))
|
_logger: Logger = PrivateAttr(default_factory=lambda: Logger(verbose=False))
|
||||||
_rpm_controller: RPMController | None = PrivateAttr(default=None)
|
_rpm_controller: RPMController | None = PrivateAttr(default=None)
|
||||||
_request_within_rpm_limit: Any = PrivateAttr(default=None)
|
_request_within_rpm_limit: SerializableCallable | None = PrivateAttr(default=None)
|
||||||
_original_role: str | None = PrivateAttr(default=None)
|
_original_role: str | None = PrivateAttr(default=None)
|
||||||
_original_goal: str | None = PrivateAttr(default=None)
|
_original_goal: str | None = PrivateAttr(default=None)
|
||||||
_original_backstory: str | None = PrivateAttr(default=None)
|
_original_backstory: str | None = PrivateAttr(default=None)
|
||||||
@@ -154,13 +173,19 @@ class BaseAgent(BaseModel, ABC, metaclass=AgentMeta):
|
|||||||
max_iter: int = Field(
|
max_iter: int = Field(
|
||||||
default=25, description="Maximum iterations for an agent to execute a task"
|
default=25, description="Maximum iterations for an agent to execute a task"
|
||||||
)
|
)
|
||||||
agent_executor: Any = Field(
|
agent_executor: InstanceOf[CrewAgentExecutorMixin] | None = Field(
|
||||||
default=None, description="An instance of the CrewAgentExecutor class."
|
default=None, description="An instance of the CrewAgentExecutor class."
|
||||||
)
|
)
|
||||||
llm: Any = Field(
|
llm: str | BaseLLM | None = Field(
|
||||||
default=None, description="Language model that will run the agent."
|
default=None, description="Language model that will run the agent."
|
||||||
)
|
)
|
||||||
crew: Any = Field(default=None, description="Crew to which the agent belongs.")
|
crew: Annotated[
|
||||||
|
Crew | str | None,
|
||||||
|
BeforeValidator(_validate_crew_ref),
|
||||||
|
PlainSerializer(
|
||||||
|
_serialize_crew_ref, return_type=str | None, when_used="always"
|
||||||
|
),
|
||||||
|
] = Field(default=None, description="Crew to which the agent belongs.")
|
||||||
i18n: I18N = Field(
|
i18n: I18N = Field(
|
||||||
default_factory=get_i18n, description="Internationalization settings."
|
default_factory=get_i18n, description="Internationalization settings."
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ description = "{{name}} using crewAI"
|
|||||||
authors = [{ name = "Your Name", email = "you@example.com" }]
|
authors = [{ name = "Your Name", email = "you@example.com" }]
|
||||||
requires-python = ">=3.10,<3.14"
|
requires-python = ">=3.10,<3.14"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crewai[tools]==1.13.0a6"
|
"crewai[tools]==1.13.0a7"
|
||||||
]
|
]
|
||||||
|
|
||||||
[project.scripts]
|
[project.scripts]
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ description = "{{name}} using crewAI"
|
|||||||
authors = [{ name = "Your Name", email = "you@example.com" }]
|
authors = [{ name = "Your Name", email = "you@example.com" }]
|
||||||
requires-python = ">=3.10,<3.14"
|
requires-python = ">=3.10,<3.14"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crewai[tools]==1.13.0a6"
|
"crewai[tools]==1.13.0a7"
|
||||||
]
|
]
|
||||||
|
|
||||||
[project.scripts]
|
[project.scripts]
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ description = "Power up your crews with {{folder_name}}"
|
|||||||
readme = "README.md"
|
readme = "README.md"
|
||||||
requires-python = ">=3.10,<3.14"
|
requires-python = ">=3.10,<3.14"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"crewai[tools]==1.13.0a6"
|
"crewai[tools]==1.13.0a7"
|
||||||
]
|
]
|
||||||
|
|
||||||
[tool.crewai]
|
[tool.crewai]
|
||||||
|
|||||||
@@ -266,7 +266,7 @@ class Crew(FlowTrackable, BaseModel):
|
|||||||
default=False,
|
default=False,
|
||||||
description="Plan the crew execution and add the plan to the crew.",
|
description="Plan the crew execution and add the plan to the crew.",
|
||||||
)
|
)
|
||||||
planning_llm: str | BaseLLM | Any | None = Field(
|
planning_llm: str | BaseLLM | None = Field(
|
||||||
default=None,
|
default=None,
|
||||||
description=(
|
description=(
|
||||||
"Language model that will run the AgentPlanner if planning is True."
|
"Language model that will run the AgentPlanner if planning is True."
|
||||||
@@ -287,7 +287,7 @@ class Crew(FlowTrackable, BaseModel):
|
|||||||
"knowledge object."
|
"knowledge object."
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
chat_llm: str | BaseLLM | Any | None = Field(
|
chat_llm: str | BaseLLM | None = Field(
|
||||||
default=None,
|
default=None,
|
||||||
description="LLM used to handle chatting with the crew.",
|
description="LLM used to handle chatting with the crew.",
|
||||||
)
|
)
|
||||||
@@ -1311,7 +1311,7 @@ class Crew(FlowTrackable, BaseModel):
|
|||||||
and hasattr(agent, "multimodal")
|
and hasattr(agent, "multimodal")
|
||||||
and getattr(agent, "multimodal", False)
|
and getattr(agent, "multimodal", False)
|
||||||
):
|
):
|
||||||
if not (agent.llm and agent.llm.supports_multimodal()):
|
if not (isinstance(agent.llm, BaseLLM) and agent.llm.supports_multimodal()):
|
||||||
tools = self._add_multimodal_tools(agent, tools)
|
tools = self._add_multimodal_tools(agent, tools)
|
||||||
|
|
||||||
if agent and (hasattr(agent, "apps") and getattr(agent, "apps", None)):
|
if agent and (hasattr(agent, "apps") and getattr(agent, "apps", None)):
|
||||||
@@ -1328,7 +1328,11 @@ class Crew(FlowTrackable, BaseModel):
|
|||||||
files = get_all_files(self.id, task.id)
|
files = get_all_files(self.id, task.id)
|
||||||
if files:
|
if files:
|
||||||
supported_types: list[str] = []
|
supported_types: list[str] = []
|
||||||
if agent and agent.llm and agent.llm.supports_multimodal():
|
if (
|
||||||
|
agent
|
||||||
|
and isinstance(agent.llm, BaseLLM)
|
||||||
|
and agent.llm.supports_multimodal()
|
||||||
|
):
|
||||||
provider = (
|
provider = (
|
||||||
getattr(agent.llm, "provider", None)
|
getattr(agent.llm, "provider", None)
|
||||||
or getattr(agent.llm, "model", None)
|
or getattr(agent.llm, "model", None)
|
||||||
@@ -1781,17 +1785,10 @@ class Crew(FlowTrackable, BaseModel):
|
|||||||
token_sum = self.manager_agent._token_process.get_summary()
|
token_sum = self.manager_agent._token_process.get_summary()
|
||||||
total_usage_metrics.add_usage_metrics(token_sum)
|
total_usage_metrics.add_usage_metrics(token_sum)
|
||||||
|
|
||||||
if (
|
if self.manager_agent:
|
||||||
self.manager_agent
|
|
||||||
and hasattr(self.manager_agent, "llm")
|
|
||||||
and hasattr(self.manager_agent.llm, "get_token_usage_summary")
|
|
||||||
):
|
|
||||||
if isinstance(self.manager_agent.llm, BaseLLM):
|
if isinstance(self.manager_agent.llm, BaseLLM):
|
||||||
llm_usage = self.manager_agent.llm.get_token_usage_summary()
|
llm_usage = self.manager_agent.llm.get_token_usage_summary()
|
||||||
else:
|
total_usage_metrics.add_usage_metrics(llm_usage)
|
||||||
llm_usage = self.manager_agent.llm._token_process.get_summary()
|
|
||||||
|
|
||||||
total_usage_metrics.add_usage_metrics(llm_usage)
|
|
||||||
|
|
||||||
self.usage_metrics = total_usage_metrics
|
self.usage_metrics = total_usage_metrics
|
||||||
return total_usage_metrics
|
return total_usage_metrics
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ from opentelemetry import baggage
|
|||||||
|
|
||||||
from crewai.agents.agent_builder.base_agent import BaseAgent
|
from crewai.agents.agent_builder.base_agent import BaseAgent
|
||||||
from crewai.crews.crew_output import CrewOutput
|
from crewai.crews.crew_output import CrewOutput
|
||||||
|
from crewai.llms.base_llm import BaseLLM
|
||||||
from crewai.rag.embeddings.types import EmbedderConfig
|
from crewai.rag.embeddings.types import EmbedderConfig
|
||||||
from crewai.skills.loader import activate_skill, discover_skills
|
from crewai.skills.loader import activate_skill, discover_skills
|
||||||
from crewai.skills.models import INSTRUCTIONS, Skill as SkillModel
|
from crewai.skills.models import INSTRUCTIONS, Skill as SkillModel
|
||||||
@@ -50,7 +51,7 @@ def enable_agent_streaming(agents: Iterable[BaseAgent]) -> None:
|
|||||||
agents: Iterable of agents to enable streaming on.
|
agents: Iterable of agents to enable streaming on.
|
||||||
"""
|
"""
|
||||||
for agent in agents:
|
for agent in agents:
|
||||||
if agent.llm is not None:
|
if isinstance(agent.llm, BaseLLM):
|
||||||
agent.llm.stream = True
|
agent.llm.stream = True
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -25,13 +25,25 @@ def _get_or_create_counter() -> Iterator[int]:
|
|||||||
return counter
|
return counter
|
||||||
|
|
||||||
|
|
||||||
|
_last_emitted: contextvars.ContextVar[int] = contextvars.ContextVar(
|
||||||
|
"_last_emitted", default=0
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def get_next_emission_sequence() -> int:
|
def get_next_emission_sequence() -> int:
|
||||||
"""Get the next emission sequence number.
|
"""Get the next emission sequence number.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
The next sequence number.
|
The next sequence number.
|
||||||
"""
|
"""
|
||||||
return next(_get_or_create_counter())
|
seq = next(_get_or_create_counter())
|
||||||
|
_last_emitted.set(seq)
|
||||||
|
return seq
|
||||||
|
|
||||||
|
|
||||||
|
def get_emission_sequence() -> int:
|
||||||
|
"""Get the current emission sequence value without incrementing."""
|
||||||
|
return _last_emitted.get()
|
||||||
|
|
||||||
|
|
||||||
def reset_emission_counter() -> None:
|
def reset_emission_counter() -> None:
|
||||||
@@ -41,6 +53,14 @@ def reset_emission_counter() -> None:
|
|||||||
"""
|
"""
|
||||||
counter: Iterator[int] = itertools.count(start=1)
|
counter: Iterator[int] = itertools.count(start=1)
|
||||||
_emission_counter.set(counter)
|
_emission_counter.set(counter)
|
||||||
|
_last_emitted.set(0)
|
||||||
|
|
||||||
|
|
||||||
|
def set_emission_counter(start: int) -> None:
|
||||||
|
"""Set the emission counter to resume from a given value."""
|
||||||
|
counter: Iterator[int] = itertools.count(start=start + 1)
|
||||||
|
_emission_counter.set(counter)
|
||||||
|
_last_emitted.set(start)
|
||||||
|
|
||||||
|
|
||||||
class BaseEvent(BaseModel):
|
class BaseEvent(BaseModel):
|
||||||
|
|||||||
80
lib/crewai/src/crewai/execution_context.py
Normal file
80
lib/crewai/src/crewai/execution_context.py
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
"""Checkpointable execution context for the crewAI runtime.
|
||||||
|
|
||||||
|
Captures the ContextVar state needed to resume execution from a checkpoint.
|
||||||
|
Used by the RootModel (step 5) to include execution context in snapshots.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from typing import Any
|
||||||
|
|
||||||
|
from pydantic import BaseModel, Field
|
||||||
|
|
||||||
|
from crewai.context import (
|
||||||
|
_current_task_id,
|
||||||
|
_platform_integration_token,
|
||||||
|
)
|
||||||
|
from crewai.events.base_events import (
|
||||||
|
get_emission_sequence,
|
||||||
|
set_emission_counter,
|
||||||
|
)
|
||||||
|
from crewai.events.event_context import (
|
||||||
|
_event_id_stack,
|
||||||
|
_last_event_id,
|
||||||
|
_triggering_event_id,
|
||||||
|
)
|
||||||
|
from crewai.flow.flow_context import (
|
||||||
|
current_flow_id,
|
||||||
|
current_flow_method_name,
|
||||||
|
current_flow_request_id,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class ExecutionContext(BaseModel):
|
||||||
|
"""Snapshot of ContextVar state required for checkpoint/resume."""
|
||||||
|
|
||||||
|
current_task_id: str | None = Field(default=None)
|
||||||
|
flow_request_id: str | None = Field(default=None)
|
||||||
|
flow_id: str | None = Field(default=None)
|
||||||
|
flow_method_name: str = Field(default="unknown")
|
||||||
|
|
||||||
|
event_id_stack: tuple[tuple[str, str], ...] = Field(default=())
|
||||||
|
last_event_id: str | None = Field(default=None)
|
||||||
|
triggering_event_id: str | None = Field(default=None)
|
||||||
|
emission_sequence: int = Field(default=0)
|
||||||
|
|
||||||
|
feedback_callback_info: dict[str, Any] | None = Field(default=None)
|
||||||
|
platform_token: str | None = Field(default=None)
|
||||||
|
|
||||||
|
|
||||||
|
def capture_execution_context(
|
||||||
|
feedback_callback_info: dict[str, Any] | None = None,
|
||||||
|
) -> ExecutionContext:
|
||||||
|
"""Read all checkpoint-required ContextVars into an ExecutionContext."""
|
||||||
|
return ExecutionContext(
|
||||||
|
current_task_id=_current_task_id.get(),
|
||||||
|
flow_request_id=current_flow_request_id.get(),
|
||||||
|
flow_id=current_flow_id.get(),
|
||||||
|
flow_method_name=current_flow_method_name.get(),
|
||||||
|
event_id_stack=_event_id_stack.get(),
|
||||||
|
last_event_id=_last_event_id.get(),
|
||||||
|
triggering_event_id=_triggering_event_id.get(),
|
||||||
|
emission_sequence=get_emission_sequence(),
|
||||||
|
feedback_callback_info=feedback_callback_info,
|
||||||
|
platform_token=_platform_integration_token.get(),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def apply_execution_context(ctx: ExecutionContext) -> None:
|
||||||
|
"""Write an ExecutionContext back into the ContextVars."""
|
||||||
|
_current_task_id.set(ctx.current_task_id)
|
||||||
|
current_flow_request_id.set(ctx.flow_request_id)
|
||||||
|
current_flow_id.set(ctx.flow_id)
|
||||||
|
current_flow_method_name.set(ctx.flow_method_name)
|
||||||
|
|
||||||
|
_event_id_stack.set(ctx.event_id_stack)
|
||||||
|
_last_event_id.set(ctx.last_event_id)
|
||||||
|
_triggering_event_id.set(ctx.triggering_event_id)
|
||||||
|
set_emission_counter(ctx.emission_sequence)
|
||||||
|
|
||||||
|
_platform_integration_token.set(ctx.platform_token)
|
||||||
@@ -41,6 +41,7 @@ from crewai.events.types.task_events import (
|
|||||||
TaskFailedEvent,
|
TaskFailedEvent,
|
||||||
TaskStartedEvent,
|
TaskStartedEvent,
|
||||||
)
|
)
|
||||||
|
from crewai.llms.base_llm import BaseLLM
|
||||||
from crewai.security import Fingerprint, SecurityConfig
|
from crewai.security import Fingerprint, SecurityConfig
|
||||||
from crewai.tasks.output_format import OutputFormat
|
from crewai.tasks.output_format import OutputFormat
|
||||||
from crewai.tasks.task_output import TaskOutput
|
from crewai.tasks.task_output import TaskOutput
|
||||||
@@ -316,6 +317,10 @@ class Task(BaseModel):
|
|||||||
if self.agent is None:
|
if self.agent is None:
|
||||||
raise ValueError("Agent is required to use LLMGuardrail")
|
raise ValueError("Agent is required to use LLMGuardrail")
|
||||||
|
|
||||||
|
if not isinstance(self.agent.llm, BaseLLM):
|
||||||
|
raise ValueError(
|
||||||
|
"Agent must have a BaseLLM instance to use LLMGuardrail"
|
||||||
|
)
|
||||||
self._guardrail = cast(
|
self._guardrail = cast(
|
||||||
GuardrailCallable,
|
GuardrailCallable,
|
||||||
LLMGuardrail(description=self.guardrail, llm=self.agent.llm),
|
LLMGuardrail(description=self.guardrail, llm=self.agent.llm),
|
||||||
@@ -339,6 +344,10 @@ class Task(BaseModel):
|
|||||||
)
|
)
|
||||||
from crewai.tasks.llm_guardrail import LLMGuardrail
|
from crewai.tasks.llm_guardrail import LLMGuardrail
|
||||||
|
|
||||||
|
if not isinstance(self.agent.llm, BaseLLM):
|
||||||
|
raise ValueError(
|
||||||
|
"Agent must have a BaseLLM instance to use LLMGuardrail"
|
||||||
|
)
|
||||||
guardrails.append(
|
guardrails.append(
|
||||||
cast(
|
cast(
|
||||||
GuardrailCallable,
|
GuardrailCallable,
|
||||||
@@ -359,6 +368,10 @@ class Task(BaseModel):
|
|||||||
)
|
)
|
||||||
from crewai.tasks.llm_guardrail import LLMGuardrail
|
from crewai.tasks.llm_guardrail import LLMGuardrail
|
||||||
|
|
||||||
|
if not isinstance(self.agent.llm, BaseLLM):
|
||||||
|
raise ValueError(
|
||||||
|
"Agent must have a BaseLLM instance to use LLMGuardrail"
|
||||||
|
)
|
||||||
guardrails.append(
|
guardrails.append(
|
||||||
cast(
|
cast(
|
||||||
GuardrailCallable,
|
GuardrailCallable,
|
||||||
@@ -646,7 +659,12 @@ class Task(BaseModel):
|
|||||||
await cb_result
|
await cb_result
|
||||||
|
|
||||||
crew = self.agent.crew # type: ignore[union-attr]
|
crew = self.agent.crew # type: ignore[union-attr]
|
||||||
if crew and crew.task_callback and crew.task_callback != self.callback:
|
if (
|
||||||
|
crew
|
||||||
|
and not isinstance(crew, str)
|
||||||
|
and crew.task_callback
|
||||||
|
and crew.task_callback != self.callback
|
||||||
|
):
|
||||||
cb_result = crew.task_callback(self.output)
|
cb_result = crew.task_callback(self.output)
|
||||||
if inspect.isawaitable(cb_result):
|
if inspect.isawaitable(cb_result):
|
||||||
await cb_result
|
await cb_result
|
||||||
@@ -761,7 +779,12 @@ class Task(BaseModel):
|
|||||||
asyncio.run(cb_result)
|
asyncio.run(cb_result)
|
||||||
|
|
||||||
crew = self.agent.crew # type: ignore[union-attr]
|
crew = self.agent.crew # type: ignore[union-attr]
|
||||||
if crew and crew.task_callback and crew.task_callback != self.callback:
|
if (
|
||||||
|
crew
|
||||||
|
and not isinstance(crew, str)
|
||||||
|
and crew.task_callback
|
||||||
|
and crew.task_callback != self.callback
|
||||||
|
):
|
||||||
cb_result = crew.task_callback(self.output)
|
cb_result = crew.task_callback(self.output)
|
||||||
if inspect.iscoroutine(cb_result):
|
if inspect.iscoroutine(cb_result):
|
||||||
asyncio.run(cb_result)
|
asyncio.run(cb_result)
|
||||||
@@ -812,11 +835,14 @@ class Task(BaseModel):
|
|||||||
if trigger_payload is not None:
|
if trigger_payload is not None:
|
||||||
description += f"\n\nTrigger Payload: {trigger_payload}"
|
description += f"\n\nTrigger Payload: {trigger_payload}"
|
||||||
|
|
||||||
if self.agent and self.agent.crew:
|
if self.agent and self.agent.crew and not isinstance(self.agent.crew, str):
|
||||||
files = get_all_files(self.agent.crew.id, self.id)
|
files = get_all_files(self.agent.crew.id, self.id)
|
||||||
if files:
|
if files:
|
||||||
supported_types: list[str] = []
|
supported_types: list[str] = []
|
||||||
if self.agent.llm and self.agent.llm.supports_multimodal():
|
if (
|
||||||
|
isinstance(self.agent.llm, BaseLLM)
|
||||||
|
and self.agent.llm.supports_multimodal()
|
||||||
|
):
|
||||||
provider: str = str(
|
provider: str = str(
|
||||||
getattr(self.agent.llm, "provider", None)
|
getattr(self.agent.llm, "provider", None)
|
||||||
or getattr(self.agent.llm, "model", "openai")
|
or getattr(self.agent.llm, "model", "openai")
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ from crewai.events.types.system_events import (
|
|||||||
SigTStpEvent,
|
SigTStpEvent,
|
||||||
SigTermEvent,
|
SigTermEvent,
|
||||||
)
|
)
|
||||||
|
from crewai.llms.base_llm import BaseLLM
|
||||||
from crewai.telemetry.constants import (
|
from crewai.telemetry.constants import (
|
||||||
CREWAI_TELEMETRY_BASE_URL,
|
CREWAI_TELEMETRY_BASE_URL,
|
||||||
CREWAI_TELEMETRY_SERVICE_NAME,
|
CREWAI_TELEMETRY_SERVICE_NAME,
|
||||||
@@ -323,7 +324,9 @@ class Telemetry:
|
|||||||
if getattr(agent, "function_calling_llm", None)
|
if getattr(agent, "function_calling_llm", None)
|
||||||
else ""
|
else ""
|
||||||
),
|
),
|
||||||
"llm": agent.llm.model,
|
"llm": agent.llm.model
|
||||||
|
if isinstance(agent.llm, BaseLLM)
|
||||||
|
else str(agent.llm),
|
||||||
"delegation_enabled?": agent.allow_delegation,
|
"delegation_enabled?": agent.allow_delegation,
|
||||||
"allow_code_execution?": getattr(
|
"allow_code_execution?": getattr(
|
||||||
agent, "allow_code_execution", False
|
agent, "allow_code_execution", False
|
||||||
@@ -427,7 +430,9 @@ class Telemetry:
|
|||||||
if getattr(agent, "function_calling_llm", None)
|
if getattr(agent, "function_calling_llm", None)
|
||||||
else ""
|
else ""
|
||||||
),
|
),
|
||||||
"llm": agent.llm.model,
|
"llm": agent.llm.model
|
||||||
|
if isinstance(agent.llm, BaseLLM)
|
||||||
|
else str(agent.llm),
|
||||||
"delegation_enabled?": agent.allow_delegation,
|
"delegation_enabled?": agent.allow_delegation,
|
||||||
"allow_code_execution?": getattr(
|
"allow_code_execution?": getattr(
|
||||||
agent, "allow_code_execution", False
|
agent, "allow_code_execution", False
|
||||||
@@ -840,7 +845,9 @@ class Telemetry:
|
|||||||
"max_iter": agent.max_iter,
|
"max_iter": agent.max_iter,
|
||||||
"max_rpm": agent.max_rpm,
|
"max_rpm": agent.max_rpm,
|
||||||
"i18n": agent.i18n.prompt_file,
|
"i18n": agent.i18n.prompt_file,
|
||||||
"llm": agent.llm.model,
|
"llm": agent.llm.model
|
||||||
|
if isinstance(agent.llm, BaseLLM)
|
||||||
|
else str(agent.llm),
|
||||||
"delegation_enabled?": agent.allow_delegation,
|
"delegation_enabled?": agent.allow_delegation,
|
||||||
"tools_names": [
|
"tools_names": [
|
||||||
sanitize_tool_name(tool.name)
|
sanitize_tool_name(tool.name)
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
"""CrewAI development tools."""
|
"""CrewAI development tools."""
|
||||||
|
|
||||||
__version__ = "1.13.0a6"
|
__version__ = "1.13.0a7"
|
||||||
|
|||||||
Reference in New Issue
Block a user