Skip to content

Commit

Permalink
docs: add verbose param (#283)
Browse files Browse the repository at this point in the history
  • Loading branch information
shreyashankar authored Jan 22, 2025
1 parent 5b86a58 commit 05c4357
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 3 deletions.
31 changes: 29 additions & 2 deletions docetl/operations/utils/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@

from litellm import ModelResponse, RateLimitError, completion, embedding
from rich import print as rprint
from rich.console import Console
from rich.console import Console, Group
from rich.panel import Panel
from rich.text import Text

from docetl.utils import completion_cost

Expand Down Expand Up @@ -378,7 +380,7 @@ def call_llm(
rate_limited_attempt = 0
while attempt <= max_retries:
try:
return timeout(timeout_seconds)(self._cached_call_llm)(
output = timeout(timeout_seconds)(self._cached_call_llm)(
key,
model,
op_type,
Expand All @@ -393,6 +395,31 @@ def call_llm(
initial_result=initial_result,
litellm_completion_kwargs=litellm_completion_kwargs,
)
# Log input and output if verbose
if verbose:
# Truncate messages to 500 chars
messages_str = str(messages)
truncated_messages = (
messages_str[:500] + "..."
if len(messages_str) > 500
else messages_str
)

# Log with nice formatting
self.runner.console.print(
Panel(
Group(
Text("Input:", style="bold cyan"),
Text(truncated_messages),
Text("\nOutput:", style="bold cyan"),
Text(str(output)),
),
title="[bold green]LLM Call Details[/bold green]",
border_style="green",
)
)

return output
except RateLimitError:
# TODO: this is a really hacky way to handle rate limits
# we should implement a more robust retry mechanism
Expand Down
6 changes: 5 additions & 1 deletion docetl/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,11 @@ def extract_jinja_variables(template_string: str) -> List[str]:

def completion_cost(response) -> float:
try:
return lcc(response)
return (
response._completion_cost
if hasattr(response, "_completion_cost")
else lcc(response)
)
except Exception:
return 0.0

Expand Down
1 change: 1 addition & 0 deletions docs/operators/map.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ This example demonstrates how the Map operation can transform long, unstructured
| `timeout` | Timeout for each LLM call in seconds | 120 |
| `litellm_completion_kwargs` | Additional parameters to pass to LiteLLM completion calls. | {} |
| `skip_on_error` | If true, skip the operation if the LLM returns an error. | False |
| `bypass_cache` | If true, bypass the cache for this operation. | False |

Note: If `drop_keys` is specified, `prompt` and `output` become optional parameters.

Expand Down
1 change: 1 addition & 0 deletions docs/operators/reduce.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ This Reduce operation processes customer feedback grouped by department:
| `timeout` | Timeout for each LLM call in seconds | 120 |
| `max_retries_per_timeout` | Maximum number of retries per timeout | 2 |
| `litellm_completion_kwargs` | Additional parameters to pass to LiteLLM completion calls. | {} |
| `bypass_cache` | If true, bypass the cache for this operation. | False |

## Advanced Features

Expand Down
1 change: 1 addition & 0 deletions docs/operators/resolve.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ After determining eligible pairs for comparison, the Resolve operation uses a Un
| `max_retries_per_timeout` | Maximum number of retries per timeout | 2 |
| `sample` | Number of samples to use for the operation | None |
| `litellm_completion_kwargs` | Additional parameters to pass to LiteLLM completion calls. | {} |
| `bypass_cache` | If true, bypass the cache for this operation. | False |

## Best Practices

Expand Down
26 changes: 26 additions & 0 deletions tests/basic/test_basic_map.py
Original file line number Diff line number Diff line change
Expand Up @@ -358,4 +358,30 @@ def test_map_operation_with_max_tokens(simple_map_config, map_sample_data, api_w
# Since we limited max_tokens to 10, each response should be relatively short
# The sentiment field should contain just the sentiment value without much extra text
assert all(len(result["sentiment"]) <= 20 for result in results)

def test_map_operation_with_verbose(simple_map_config, map_sample_data, api_wrapper):
# Add verbose configuration
map_config_with_verbose = {
**simple_map_config,
"verbose": True,
"bypass_cache": True
}

operation = MapOperation(api_wrapper, map_config_with_verbose, "gpt-4o-mini", 4)

# Execute the operation
results, cost = operation.execute(map_sample_data)

# Assert that we have results for all input items
assert len(results) == len(map_sample_data)

# Check that all results have a sentiment
assert all("sentiment" in result for result in results)

# Verify that all sentiments are valid
valid_sentiments = ["positive", "negative", "neutral"]
assert all(
any(vs in result["sentiment"] for vs in valid_sentiments) for result in results
)


0 comments on commit 05c4357

Please sign in to comment.