Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 0 additions & 70 deletions lib/crewai/src/crewai/llm.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,14 @@
from collections import defaultdict
from collections.abc import Callable
from datetime import datetime
import io
import json
import logging
import os
import sys
import threading
from typing import (
TYPE_CHECKING,
Any,
Final,
Literal,
TextIO,
TypedDict,
cast,
)
Expand Down Expand Up @@ -102,72 +98,6 @@
litellm.suppress_debug_info = True


class FilteredStream(io.TextIOBase):
_lock = None

def __init__(self, original_stream: TextIO):
self._original_stream = original_stream
self._lock = threading.Lock()

def write(self, s: str) -> int:
if not self._lock:
self._lock = threading.Lock()

with self._lock:
lower_s = s.lower()

# Skip common noisy LiteLLM banners and any other lines that contain "litellm"
if (
"litellm.info:" in lower_s
or "Consider using a smaller input or implementing a text splitting strategy"
in lower_s
):
return 0

return self._original_stream.write(s)

def flush(self) -> None:
if self._lock:
with self._lock:
return self._original_stream.flush()
return None

def __getattr__(self, name: str) -> Any:
"""Delegate attribute access to the wrapped original stream.

This ensures compatibility with libraries (e.g., Rich) that rely on
attributes such as `encoding`, `isatty`, `buffer`, etc., which may not
be explicitly defined on this proxy class.
"""
return getattr(self._original_stream, name)

# Delegate common properties/methods explicitly so they aren't shadowed by
# the TextIOBase defaults (e.g., .encoding returns None by default, which
# confuses Rich). These explicit pass-throughs ensure the wrapped Console
# still sees a fully-featured stream.
@property
def encoding(self) -> str | Any: # type: ignore[override]
return getattr(self._original_stream, "encoding", "utf-8")

def isatty(self) -> bool:
return self._original_stream.isatty()

def fileno(self) -> int:
return self._original_stream.fileno()

def writable(self) -> bool:
return True


# Apply the filtered stream globally so that any subsequent writes containing the filtered
# keywords (e.g., "litellm") are hidden from terminal output. We guard against double
# wrapping to ensure idempotency in environments where this module might be reloaded.
if not isinstance(sys.stdout, FilteredStream):
sys.stdout = FilteredStream(sys.stdout)
if not isinstance(sys.stderr, FilteredStream):
sys.stderr = FilteredStream(sys.stderr)


MIN_CONTEXT: Final[int] = 1024
MAX_CONTEXT: Final[int] = 2097152 # Current max from gemini-1.5-pro
ANTHROPIC_PREFIXES: Final[tuple[str, str, str]] = ("anthropic/", "claude-", "claude/")
Expand Down
Loading