Compare commits

...

3 Commits

Author SHA1 Message Date
Devin AI
06c4974cb3 fix: exclude empty stop parameter from LLM completion params
This fixes issue #4149 where models like gpt-5.1 don't support the
stop parameter at all. Previously, an empty list was always passed
to the API, causing an error.

Changes:
- Only include stop in params when it has values (non-empty)
- Respect additional_drop_params to ensure retry logic works correctly
- Add tests to verify the fix

Co-Authored-By: João <joao@crewai.com>
2025-12-24 07:12:18 +00:00
Lucas Gomide
0c020991c4 docs: fix wrong trigger name in sample docs (#4147)
Some checks failed
Check Documentation Broken Links / Check broken links (push) Has been cancelled
Notify Downstream / notify-downstream (push) Has been cancelled
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
Build uv cache / build-cache (3.10) (push) Has been cancelled
Build uv cache / build-cache (3.11) (push) Has been cancelled
Build uv cache / build-cache (3.12) (push) Has been cancelled
Build uv cache / build-cache (3.13) (push) Has been cancelled
2025-12-23 08:41:51 -05:00
Heitor Carvalho
be70a04153 fix: correct error fetching for workos login polling (#4124)
Some checks failed
CodeQL Advanced / Analyze (actions) (push) Has been cancelled
CodeQL Advanced / Analyze (python) (push) Has been cancelled
Notify Downstream / notify-downstream (push) Has been cancelled
Mark stale issues and pull requests / stale (push) Has been cancelled
Build uv cache / build-cache (3.10) (push) Has been cancelled
Build uv cache / build-cache (3.11) (push) Has been cancelled
Build uv cache / build-cache (3.12) (push) Has been cancelled
Build uv cache / build-cache (3.13) (push) Has been cancelled
2025-12-19 20:00:26 -03:00
6 changed files with 78 additions and 12 deletions

View File

@@ -62,13 +62,13 @@ Test your Gmail trigger integration locally using the CrewAI CLI:
crewai triggers list
# Simulate a Gmail trigger with realistic payload
crewai triggers run gmail/new_email
crewai triggers run gmail/new_email_received
```
The `crewai triggers run` command will execute your crew with a complete Gmail payload, allowing you to test your parsing logic before deployment.
<Warning>
Use `crewai triggers run gmail/new_email` (not `crewai run`) to simulate trigger execution during development. After deployment, your crew will automatically receive the trigger payload.
Use `crewai triggers run gmail/new_email_received` (not `crewai run`) to simulate trigger execution during development. After deployment, your crew will automatically receive the trigger payload.
</Warning>
## Monitoring Executions
@@ -83,6 +83,6 @@ Track history and performance of triggered runs:
- Ensure Gmail is connected in Tools & Integrations
- Verify the Gmail Trigger is enabled on the Triggers tab
- Test locally with `crewai triggers run gmail/new_email` to see the exact payload structure
- Test locally with `crewai triggers run gmail/new_email_received` to see the exact payload structure
- Check the execution logs and confirm the payload is passed as `crewai_trigger_payload`
- Remember: use `crewai triggers run` (not `crewai run`) to simulate trigger execution

View File

@@ -62,13 +62,13 @@ CrewAI CLI를 사용하여 Gmail 트리거 통합을 로컬에서 테스트하
crewai triggers list
# 실제 payload로 Gmail 트리거 시뮬레이션
crewai triggers run gmail/new_email
crewai triggers run gmail/new_email_received
```
`crewai triggers run` 명령은 완전한 Gmail payload로 크루를 실행하여 배포 전에 파싱 로직을 테스트할 수 있게 해줍니다.
<Warning>
개발 중에는 `crewai triggers run gmail/new_email`을 사용하세요 (`crewai run`이 아님). 배포 후에는 크루가 자동으로 트리거 payload를 받습니다.
개발 중에는 `crewai triggers run gmail/new_email_received`을 사용하세요 (`crewai run`이 아님). 배포 후에는 크루가 자동으로 트리거 payload를 받습니다.
</Warning>
## Monitoring Executions
@@ -83,6 +83,6 @@ Track history and performance of triggered runs:
- Ensure Gmail is connected in Tools & Integrations
- Verify the Gmail Trigger is enabled on the Triggers tab
- `crewai triggers run gmail/new_email`로 로컬 테스트하여 정확한 payload 구조를 확인하세요
- `crewai triggers run gmail/new_email_received`로 로컬 테스트하여 정확한 payload 구조를 확인하세요
- Check the execution logs and confirm the payload is passed as `crewai_trigger_payload`
- 주의: 트리거 실행을 시뮬레이션하려면 `crewai triggers run`을 사용하세요 (`crewai run`이 아님)

View File

@@ -62,13 +62,13 @@ Teste sua integração de trigger do Gmail localmente usando a CLI da CrewAI:
crewai triggers list
# Simule um trigger do Gmail com payload realista
crewai triggers run gmail/new_email
crewai triggers run gmail/new_email_received
```
O comando `crewai triggers run` executará sua crew com um payload completo do Gmail, permitindo que você teste sua lógica de parsing antes do deployment.
<Warning>
Use `crewai triggers run gmail/new_email` (não `crewai run`) para simular execução de trigger durante o desenvolvimento. Após o deployment, sua crew receberá automaticamente o payload do trigger.
Use `crewai triggers run gmail/new_email_received` (não `crewai run`) para simular execução de trigger durante o desenvolvimento. Após o deployment, sua crew receberá automaticamente o payload do trigger.
</Warning>
## Monitoring Executions
@@ -83,6 +83,6 @@ Track history and performance of triggered runs:
- Ensure Gmail is connected in Tools & Integrations
- Verify the Gmail Trigger is enabled on the Triggers tab
- Teste localmente com `crewai triggers run gmail/new_email` para ver a estrutura exata do payload
- Teste localmente com `crewai triggers run gmail/new_email_received` para ver a estrutura exata do payload
- Check the execution logs and confirm the payload is passed as `crewai_trigger_payload`
- Lembre-se: use `crewai triggers run` (não `crewai run`) para simular execução de trigger

View File

@@ -149,7 +149,9 @@ class AuthenticationCommand:
return
if token_data["error"] not in ("authorization_pending", "slow_down"):
raise requests.HTTPError(token_data["error_description"])
raise requests.HTTPError(
token_data.get("error_description") or token_data.get("error")
)
time.sleep(device_code_data["interval"])
attempts += 1

View File

@@ -676,14 +676,13 @@ class LLM(BaseLLM):
formatted_messages = self._format_messages_for_provider(messages)
# --- 2) Prepare the parameters for the completion call
params = {
params: dict[str, Any] = {
"model": self.model,
"messages": formatted_messages,
"timeout": self.timeout,
"temperature": self.temperature,
"top_p": self.top_p,
"n": self.n,
"stop": self.stop,
"max_tokens": self.max_tokens or self.max_completion_tokens,
"presence_penalty": self.presence_penalty,
"frequency_penalty": self.frequency_penalty,
@@ -702,6 +701,12 @@ class LLM(BaseLLM):
**self.additional_params,
}
# Only include stop if it has values and is not in additional_drop_params
# Some models (e.g., gpt-5.1) don't support the stop parameter at all
drop_params = self.additional_params.get("additional_drop_params", [])
if self.stop and "stop" not in drop_params:
params["stop"] = self.stop
# Remove None values from params
return {k: v for k, v in params.items() if v is not None}

View File

@@ -877,3 +877,62 @@ def test_validate_model_in_constants():
LLM._validate_model_in_constants("anthropic.claude-future-v1:0", "bedrock")
is True
)
def test_prepare_completion_params_excludes_empty_stop():
"""Test that _prepare_completion_params excludes stop when it's empty.
This is a regression test for issue #4149 where models like gpt-5.1
don't support the stop parameter at all, and passing an empty list
would cause an error.
"""
llm = LLM(model="gpt-4o", is_litellm=True)
# By default, stop is initialized to an empty list
assert llm.stop == []
params = llm._prepare_completion_params("Hello")
# stop should not be in params when it's empty
assert "stop" not in params
def test_prepare_completion_params_includes_stop_when_provided():
"""Test that _prepare_completion_params includes stop when it has values."""
llm = LLM(model="gpt-4o", stop=["Observation:"], is_litellm=True)
assert llm.stop == ["Observation:"]
params = llm._prepare_completion_params("Hello")
# stop should be in params when it has values
assert "stop" in params
assert params["stop"] == ["Observation:"]
def test_prepare_completion_params_excludes_stop_when_in_drop_params():
"""Test that _prepare_completion_params excludes stop when it's in additional_drop_params.
This ensures the retry logic works correctly when a model doesn't support stop.
"""
llm = LLM(
model="gpt-4o",
stop=["Observation:"],
additional_drop_params=["stop"],
is_litellm=True,
)
assert llm.stop == ["Observation:"]
params = llm._prepare_completion_params("Hello")
# stop should not be in params when it's in additional_drop_params
assert "stop" not in params
def test_prepare_completion_params_excludes_stop_with_existing_drop_params():
"""Test that stop is excluded when additional_drop_params already has other params."""
llm = LLM(
model="gpt-4o",
stop=["Observation:"],
additional_drop_params=["another_param", "stop"],
is_litellm=True,
)
params = llm._prepare_completion_params("Hello")
# stop should not be in params
assert "stop" not in params