Commit ·
24cf535
1
Parent(s): 2fc33d9
Swap ChatOpenAI for crewai.LLM so newer crewai versions accept the llm
Browse filesNewer crewai versions strictly validate Agent(llm=...) and reject a
raw ChatOpenAI instance. Switching to crewai.LLM with the hosted_vllm
provider prefix + explicit base_url routes through litellm cleanly.
- crew/agents.py +27 -12
crew/agents.py
CHANGED
|
@@ -1,24 +1,39 @@
|
|
| 1 |
"""Agent factory functions for creating configured CrewAI Agent instances."""
|
| 2 |
|
| 3 |
-
from crewai import Agent
|
| 4 |
-
from langchain_openai import ChatOpenAI
|
| 5 |
|
| 6 |
from crew.config import LLMConfig
|
| 7 |
|
| 8 |
|
| 9 |
-
def create_llm(config: LLMConfig) ->
|
| 10 |
-
"""Create a shared LLM instance pointing to the vLLM endpoint.
|
| 11 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 12 |
base_url=config.base_url,
|
| 13 |
-
|
| 14 |
temperature=config.temperature,
|
| 15 |
max_tokens=config.max_tokens,
|
| 16 |
timeout=config.request_timeout,
|
| 17 |
-
api_key="not-needed",
|
| 18 |
)
|
| 19 |
|
| 20 |
|
| 21 |
-
def create_market_scanner(llm:
|
| 22 |
"""Create the Market Scanner agent.
|
| 23 |
|
| 24 |
Args:
|
|
@@ -40,7 +55,7 @@ def create_market_scanner(llm: ChatOpenAI, tools: list) -> Agent:
|
|
| 40 |
)
|
| 41 |
|
| 42 |
|
| 43 |
-
def create_fundamental_analyst(llm:
|
| 44 |
"""Create the Fundamental Analyst agent.
|
| 45 |
|
| 46 |
Args:
|
|
@@ -62,7 +77,7 @@ def create_fundamental_analyst(llm: ChatOpenAI, tools: list) -> Agent:
|
|
| 62 |
)
|
| 63 |
|
| 64 |
|
| 65 |
-
def create_technical_analyst(llm:
|
| 66 |
"""Create the Technical Analyst agent.
|
| 67 |
|
| 68 |
Args:
|
|
@@ -84,7 +99,7 @@ def create_technical_analyst(llm: ChatOpenAI, tools: list) -> Agent:
|
|
| 84 |
)
|
| 85 |
|
| 86 |
|
| 87 |
-
def create_risk_manager(llm:
|
| 88 |
"""Create the Risk Manager agent.
|
| 89 |
|
| 90 |
Args:
|
|
@@ -106,7 +121,7 @@ def create_risk_manager(llm: ChatOpenAI, tools: list) -> Agent:
|
|
| 106 |
)
|
| 107 |
|
| 108 |
|
| 109 |
-
def create_chief_strategist(llm:
|
| 110 |
"""Create the Chief Strategist agent (no tools, pure reasoning)."""
|
| 111 |
return Agent(
|
| 112 |
role="Chief Strategist",
|
|
|
|
| 1 |
"""Agent factory functions for creating configured CrewAI Agent instances."""
|
| 2 |
|
| 3 |
+
from crewai import Agent, LLM
|
|
|
|
| 4 |
|
| 5 |
from crew.config import LLMConfig
|
| 6 |
|
| 7 |
|
| 8 |
+
def create_llm(config: LLMConfig) -> LLM:
|
| 9 |
+
"""Create a shared crewai.LLM instance pointing to the vLLM endpoint.
|
| 10 |
+
|
| 11 |
+
Newer versions of crewai validate ``Agent(llm=...)`` strictly and only
|
| 12 |
+
accept a :class:`crewai.LLM` (or a plain model-name string). A raw
|
| 13 |
+
``langchain_openai.ChatOpenAI`` is rejected. crewai.LLM delegates to
|
| 14 |
+
litellm under the hood, and litellm needs an explicit provider prefix
|
| 15 |
+
for self-hosted OpenAI-compatible endpoints — hence the
|
| 16 |
+
``hosted_vllm/`` prefix on the model name.
|
| 17 |
+
|
| 18 |
+
``api_key`` is a required positional for the OpenAI provider flow even
|
| 19 |
+
when the upstream server (vLLM) does not enforce auth; any non-empty
|
| 20 |
+
value is accepted.
|
| 21 |
+
"""
|
| 22 |
+
model_name = config.model_name
|
| 23 |
+
if not model_name.startswith("hosted_vllm/"):
|
| 24 |
+
model_name = f"hosted_vllm/{model_name}"
|
| 25 |
+
|
| 26 |
+
return LLM(
|
| 27 |
+
model=model_name,
|
| 28 |
base_url=config.base_url,
|
| 29 |
+
api_key="not-needed",
|
| 30 |
temperature=config.temperature,
|
| 31 |
max_tokens=config.max_tokens,
|
| 32 |
timeout=config.request_timeout,
|
|
|
|
| 33 |
)
|
| 34 |
|
| 35 |
|
| 36 |
+
def create_market_scanner(llm: LLM, tools: list) -> Agent:
|
| 37 |
"""Create the Market Scanner agent.
|
| 38 |
|
| 39 |
Args:
|
|
|
|
| 55 |
)
|
| 56 |
|
| 57 |
|
| 58 |
+
def create_fundamental_analyst(llm: LLM, tools: list) -> Agent:
|
| 59 |
"""Create the Fundamental Analyst agent.
|
| 60 |
|
| 61 |
Args:
|
|
|
|
| 77 |
)
|
| 78 |
|
| 79 |
|
| 80 |
+
def create_technical_analyst(llm: LLM, tools: list) -> Agent:
|
| 81 |
"""Create the Technical Analyst agent.
|
| 82 |
|
| 83 |
Args:
|
|
|
|
| 99 |
)
|
| 100 |
|
| 101 |
|
| 102 |
+
def create_risk_manager(llm: LLM, tools: list) -> Agent:
|
| 103 |
"""Create the Risk Manager agent.
|
| 104 |
|
| 105 |
Args:
|
|
|
|
| 121 |
)
|
| 122 |
|
| 123 |
|
| 124 |
+
def create_chief_strategist(llm: LLM) -> Agent:
|
| 125 |
"""Create the Chief Strategist agent (no tools, pure reasoning)."""
|
| 126 |
return Agent(
|
| 127 |
role="Chief Strategist",
|