Skip to content

Commit 83aeda3

Browse files
committed
Make timeouts configurable in semantic LLM operations
1 parent 8b035ca commit 83aeda3

File tree

25 files changed

+474
-22
lines changed

25 files changed

+474
-22
lines changed

src/fenic/_backends/local/semantic_operators/analyze_sentiment.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,7 @@ def __init__(
134134
model: LanguageModel,
135135
temperature: float,
136136
model_alias: Optional[ResolvedModelAlias] = None,
137+
request_timeout: Optional[float] = None,
137138
):
138139
super().__init__(
139140
input,
@@ -145,6 +146,7 @@ def __init__(
145146
temperature=temperature,
146147
response_format=SENTIMENT_ANALYSIS_FORMAT,
147148
model_profile=model_alias.profile if model_alias else None,
149+
request_timeout=request_timeout,
148150
),
149151
),
150152
EXAMPLES,

src/fenic/_backends/local/semantic_operators/base.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ def send_requests(
7878
response_format=self.inference_config.response_format,
7979
top_logprobs=self.inference_config.top_logprobs,
8080
model_profile=self.inference_config.model_profile,
81+
request_timeout=self.inference_config.request_timeout,
8182
)
8283

8384
completions = [

src/fenic/_backends/local/semantic_operators/classify.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ def __init__(
4343
temperature: float,
4444
examples: Optional[ClassifyExampleCollection] = None,
4545
model_alias: Optional[ResolvedModelAlias] = None,
46+
request_timeout: Optional[float] = None,
4647
):
4748
self.classes = classes
4849
self.valid_labels = {class_def.label for class_def in classes}
@@ -59,6 +60,7 @@ def __init__(
5960
temperature=temperature,
6061
response_format=ResolvedResponseFormat.from_pydantic_model(self.output_model, generate_struct_type=False),
6162
model_profile=model_alias.profile if model_alias else None,
63+
request_timeout=request_timeout,
6264
),
6365
),
6466
examples,

src/fenic/_backends/local/semantic_operators/extract.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ def __init__(
5050
max_output_tokens: int,
5151
temperature: float,
5252
model_alias: Optional[ResolvedModelAlias] = None,
53+
request_timeout: Optional[float] = None,
5354
):
5455
self.resolved_format = response_format
5556
super().__init__(
@@ -61,6 +62,7 @@ def __init__(
6162
temperature=temperature,
6263
response_format=response_format,
6364
model_profile=model_alias.profile if model_alias else None,
65+
request_timeout=request_timeout,
6466
),
6567
model=model,
6668
),

src/fenic/_backends/local/semantic_operators/map.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ def __init__(
5353
model_alias: Optional[ResolvedModelAlias] = None,
5454
response_format: Optional[ResolvedResponseFormat] = None,
5555
examples: Optional[MapExampleCollection] = None,
56+
request_timeout: Optional[float] = None,
5657
):
5758
super().__init__(
5859
input,
@@ -64,6 +65,7 @@ def __init__(
6465
response_format=response_format,
6566
temperature=temperature,
6667
model_profile=model_alias.profile if model_alias else None,
68+
request_timeout=request_timeout,
6769
),
6870
),
6971
jinja_template=jinja2.Template(jinja_template),

src/fenic/_backends/local/semantic_operators/parse_pdf.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ def __init__(
5050
describe_images: bool = False,
5151
model_alias: Optional[ResolvedModelAlias] = None,
5252
max_output_tokens: Optional[int] = None,
53+
request_timeout: Optional[float] = None,
5354
):
5455
self.page_separator = page_separator
5556
self.describe_images = describe_images
@@ -68,6 +69,7 @@ def __init__(
6869
max_output_tokens=max_output_tokens,
6970
temperature=1.0, # Use a higher temperature so gemini flash models can handle complex table formatting. For more info see the conversation here: https://discuss.ai.google.dev/t/gemini-2-0-flash-has-a-weird-bug/65119/26
7071
model_profile=model_alias.profile if model_alias else None,
72+
request_timeout=request_timeout,
7173
),
7274
),
7375
examples=None, # PDF parsing doesn't use examples

src/fenic/_backends/local/semantic_operators/predicate.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ def __init__(
4646
temperature: float,
4747
examples: Optional[PredicateExampleCollection] = None,
4848
model_alias: Optional[ResolvedModelAlias] = None,
49+
request_timeout: Optional[float] = None,
4950
):
5051
super().__init__(
5152
input,
@@ -56,6 +57,7 @@ def __init__(
5657
response_format=PREDICATE_FORMAT,
5758
temperature=temperature,
5859
model_profile=model_alias.profile if model_alias else None,
60+
request_timeout=request_timeout,
5961
),
6062
model=model,
6163
),

src/fenic/_backends/local/semantic_operators/summarize.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ def __init__(
4545
temperature: float,
4646
model: LanguageModel,
4747
model_alias: Optional[ResolvedModelAlias] = None,
48+
request_timeout: Optional[float] = None,
4849
):
4950
self.format = format
5051

@@ -56,6 +57,7 @@ def __init__(
5657
max_output_tokens=self.get_max_tokens(),
5758
temperature=temperature,
5859
model_profile=model_alias.profile if model_alias else None,
60+
request_timeout=request_timeout,
5961
),
6062
model=model,
6163
),

src/fenic/_backends/local/transpiler/expr_converter.py

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,7 @@ def sem_map_fn(batch: pl.Series) -> pl.Series:
567567
temperature=logical.temperature,
568568
response_format=logical.response_format,
569569
model_alias=logical.model_alias,
570+
request_timeout=logical.request_timeout,
570571
).execute()
571572

572573
column_exprs = [self._convert_expr(expr) for expr in logical.exprs]
@@ -666,6 +667,7 @@ def sem_ext_fn(batch: pl.Series) -> pl.Series:
666667
max_output_tokens=logical.max_tokens,
667668
temperature=logical.temperature,
668669
model_alias=logical.model_alias,
670+
request_timeout=logical.request_timeout,
669671
).execute()
670672

671673
return self._convert_expr(logical.expr).map_batches(
@@ -686,6 +688,7 @@ def sem_pred_fn(batch: pl.Series) -> pl.Series:
686688
examples=logical.examples,
687689
temperature=logical.temperature,
688690
model_alias=logical.model_alias,
691+
request_timeout=logical.request_timeout,
689692
).execute()
690693

691694
column_exprs = [self._convert_expr(expr) for expr in logical.exprs]
@@ -708,6 +711,7 @@ def sem_classify_fn(batch: pl.Series) -> pl.Series:
708711
temperature=logical.temperature,
709712
examples=logical.examples,
710713
model_alias=logical.model_alias,
714+
request_timeout=logical.request_timeout,
711715
).execute()
712716

713717
return self._convert_expr(logical.expr).map_batches(
@@ -723,6 +727,7 @@ def sem_sentiment_fn(batch: pl.Series) -> pl.Series:
723727
model=self.session_state.get_language_model(logical.model_alias),
724728
temperature=logical.temperature,
725729
model_alias=logical.model_alias,
730+
request_timeout=logical.request_timeout,
726731
).execute()
727732

728733
return self._convert_expr(logical.expr).map_batches(
@@ -739,7 +744,7 @@ def sem_summarize_fn(batch: pl.Series) -> pl.Series:
739744
format=logical.format,
740745
temperature=logical.temperature,
741746
model=self.session_state.get_language_model(logical.model_alias),
742-
747+
request_timeout=logical.request_timeout,
743748
).execute()
744749

745750
return self._convert_expr(logical.expr).map_batches(
@@ -756,6 +761,7 @@ def parse_pdf_fn(batch: pl.Series) -> pl.Series:
756761
describe_images=logical.describe_images,
757762
model_alias=logical.model_alias,
758763
max_output_tokens=logical.max_output_tokens,
764+
request_timeout=logical.request_timeout,
759765
).execute()
760766

761767
return self._convert_expr(logical.expr).map_batches(

src/fenic/_inference/anthropic/anthropic_provider.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,9 @@
33
import logging
44

55
import anthropic
6+
import httpx
67

8+
from fenic._inference.request_utils import MAX_CLIENT_TIMEOUT
79
from fenic.core._inference.model_provider import ModelProviderClass
810

911
logger = logging.getLogger(__name__)
@@ -18,11 +20,11 @@ def name(self) -> str:
1820

1921
def create_client(self):
2022
"""Create an Anthropic sync client instance."""
21-
return anthropic.Client()
23+
return anthropic.Client(http_client=httpx.Client(timeout=MAX_CLIENT_TIMEOUT))
2224

2325
def create_aio_client(self):
2426
"""Create an Anthropic async client instance."""
25-
return anthropic.AsyncAnthropic()
27+
return anthropic.AsyncAnthropic(http_client=httpx.AsyncClient(timeout=MAX_CLIENT_TIMEOUT))
2628

2729
async def validate_api_key(self) -> None:
2830
"""Validate Anthropic API key by making a minimal completion request."""

0 commit comments

Comments
 (0)