Skip to content

Commit ade0fa2

Browse files
author
stlc-bot
committed
feat(search): add highlights to web search and bill page reads per 10 results (#1387)
Stainless-Generated-From: ab671f0
1 parent 7918ce8 commit ade0fa2

4 files changed

Lines changed: 68 additions & 6 deletions

File tree

‎src/context/dev/resources/web.py‎

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1025,6 +1025,7 @@ def search(
10251025
| Omit = omit,
10261026
exclude_domains: SequenceNotStr[str] | Omit = omit,
10271027
freshness: Literal["last_24_hours", "last_week", "last_month", "last_year"] | Omit = omit,
1028+
highlights_options: web_search_params.HighlightsOptions | Omit = omit,
10281029
include_domains: SequenceNotStr[str] | Omit = omit,
10291030
markdown_options: web_search_params.MarkdownOptions | Omit = omit,
10301031
num_results: int | Omit = omit,
@@ -1040,7 +1041,8 @@ def search(
10401041
timeout: float | httpx.Timeout | None | NotGiven = not_given,
10411042
) -> WebSearchResponse:
10421043
"""
1043-
Search the web and optionally return page content with each result.
1044+
Search the web and optionally return page content or relevant passages with each
1045+
result.
10441046
10451047
Args:
10461048
query: Search query. Accepts natural language as well as Google-style search operators
@@ -1054,6 +1056,9 @@ def search(
10541056
10551057
freshness: Restrict results to content published within this window.
10561058
1059+
highlights_options: Passages from each result page that are relevant to the query. Pages are read
1060+
with the `markdownOptions` settings.
1061+
10571062
include_domains: Allowlist — only return results from these domains. Example: ["arxiv.org",
10581063
"github.com"].
10591064
@@ -1086,6 +1091,7 @@ def search(
10861091
"country": country,
10871092
"exclude_domains": exclude_domains,
10881093
"freshness": freshness,
1094+
"highlights_options": highlights_options,
10891095
"include_domains": include_domains,
10901096
"markdown_options": markdown_options,
10911097
"num_results": num_results,
@@ -2425,6 +2431,7 @@ async def search(
24252431
| Omit = omit,
24262432
exclude_domains: SequenceNotStr[str] | Omit = omit,
24272433
freshness: Literal["last_24_hours", "last_week", "last_month", "last_year"] | Omit = omit,
2434+
highlights_options: web_search_params.HighlightsOptions | Omit = omit,
24282435
include_domains: SequenceNotStr[str] | Omit = omit,
24292436
markdown_options: web_search_params.MarkdownOptions | Omit = omit,
24302437
num_results: int | Omit = omit,
@@ -2440,7 +2447,8 @@ async def search(
24402447
timeout: float | httpx.Timeout | None | NotGiven = not_given,
24412448
) -> WebSearchResponse:
24422449
"""
2443-
Search the web and optionally return page content with each result.
2450+
Search the web and optionally return page content or relevant passages with each
2451+
result.
24442452
24452453
Args:
24462454
query: Search query. Accepts natural language as well as Google-style search operators
@@ -2454,6 +2462,9 @@ async def search(
24542462
24552463
freshness: Restrict results to content published within this window.
24562464
2465+
highlights_options: Passages from each result page that are relevant to the query. Pages are read
2466+
with the `markdownOptions` settings.
2467+
24572468
include_domains: Allowlist — only return results from these domains. Example: ["arxiv.org",
24582469
"github.com"].
24592470
@@ -2486,6 +2497,7 @@ async def search(
24862497
"country": country,
24872498
"exclude_domains": exclude_domains,
24882499
"freshness": freshness,
2500+
"highlights_options": highlights_options,
24892501
"include_domains": include_domains,
24902502
"markdown_options": markdown_options,
24912503
"num_results": num_results,

‎src/context/dev/types/web_search_params.py‎

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,14 @@
77
from .._types import SequenceNotStr
88
from .._utils import PropertyInfo
99

10-
__all__ = ["WebSearchParams", "MarkdownOptions", "MarkdownOptionsPdf", "MarkdownOptionsTimeoutOpts", "TimeoutOpts"]
10+
__all__ = [
11+
"WebSearchParams",
12+
"HighlightsOptions",
13+
"MarkdownOptions",
14+
"MarkdownOptionsPdf",
15+
"MarkdownOptionsTimeoutOpts",
16+
"TimeoutOpts",
17+
]
1118

1219

1320
class WebSearchParams(TypedDict, total=False):
@@ -273,6 +280,12 @@ class WebSearchParams(TypedDict, total=False):
273280
freshness: Literal["last_24_hours", "last_week", "last_month", "last_year"]
274281
"""Restrict results to content published within this window."""
275282

283+
highlights_options: Annotated[HighlightsOptions, PropertyInfo(alias="highlightsOptions")]
284+
"""Passages from each result page that are relevant to the query.
285+
286+
Pages are read with the `markdownOptions` settings.
287+
"""
288+
276289
include_domains: Annotated[SequenceNotStr[str], PropertyInfo(alias="includeDomains")]
277290
"""Allowlist — only return results from these domains.
278291
@@ -301,6 +314,19 @@ class WebSearchParams(TypedDict, total=False):
301314
"""
302315

303316

317+
class HighlightsOptions(TypedDict, total=False):
318+
"""Passages from each result page that are relevant to the query.
319+
320+
Pages are read with the `markdownOptions` settings.
321+
"""
322+
323+
enabled: bool
324+
"""Return relevant passages for each result. Adds 1 credit per 10 results."""
325+
326+
max_characters: Annotated[int, PropertyInfo(alias="maxCharacters")]
327+
"""Maximum combined length of passages per result."""
328+
329+
304330
class MarkdownOptionsPdf(TypedDict, total=False):
305331
"""PDF handling. Use start/end to bound text extraction and OCR to a page range."""
306332

@@ -335,7 +361,7 @@ class MarkdownOptions(TypedDict, total=False):
335361
"""Inline Markdown scraping for each result. Set `enabled: true` to activate."""
336362

337363
enabled: bool
338-
"""Scrape each result to Markdown. Off by default to keep search cheap and fast."""
364+
"""Scrape each result to Markdown. Adds 1 credit per 10 results."""
339365

340366
include_frames: Annotated[bool, PropertyInfo(alias="includeFrames")]
341367
"""Render iframe contents into the Markdown."""
@@ -349,7 +375,7 @@ class MarkdownOptions(TypedDict, total=False):
349375
max_age_ms: Annotated[int, PropertyInfo(alias="maxAgeMs")]
350376
"""Cache TTL in ms for scraped Markdown keyed by URL + options.
351377
352-
Default 1 day, max 30 days. Set to 0 to force a fresh scrape.
378+
Default 15 days, max 30 days. Set to 0 to force a fresh scrape.
353379
"""
354380

355381
pdf: MarkdownOptionsPdf

‎src/context/dev/types/web_search_response.py‎

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
from .._models import BaseModel
99

10-
__all__ = ["WebSearchResponse", "CacheMetadata", "Result", "ResultMarkdown", "KeyMetadata"]
10+
__all__ = ["WebSearchResponse", "CacheMetadata", "Result", "ResultHighlights", "ResultMarkdown", "KeyMetadata"]
1111

1212

1313
class CacheMetadata(BaseModel):
@@ -23,6 +23,19 @@ class CacheMetadata(BaseModel):
2323
"""
2424

2525

26+
class ResultHighlights(BaseModel):
27+
"""Highlights status and passages for this result."""
28+
29+
code: Literal["SUCCESS", "NOT_REQUESTED", "TIMEOUT", "CONTENT_TOO_LARGE", "WEBSITE_ACCESS_ERROR", "ERROR"]
30+
"""Per-result highlights outcome. Inspect this before reading `highlights`."""
31+
32+
highlights: Optional[List[str]] = None
33+
"""Passages relevant to the query, in page order.
34+
35+
Null unless highlightsOptions.enabled is true and the page was read.
36+
"""
37+
38+
2639
class ResultMarkdown(BaseModel):
2740
"""Markdown scrape status and content for this result."""
2841

@@ -49,6 +62,9 @@ class Result(BaseModel):
4962
Empty string when the search provider does not supply a snippet.
5063
"""
5164

65+
highlights: ResultHighlights
66+
"""Highlights status and passages for this result."""
67+
5268
markdown: ResultMarkdown
5369
"""Markdown scrape status and content for this result."""
5470

‎tests/api_resources/test_web.py‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,10 @@ def test_method_search_with_all_params(self, client: ContextDev) -> None:
430430
country="af",
431431
exclude_domains=["string"],
432432
freshness="last_24_hours",
433+
highlights_options={
434+
"enabled": True,
435+
"max_characters": 100,
436+
},
433437
include_domains=["string"],
434438
markdown_options={
435439
"enabled": True,
@@ -967,6 +971,10 @@ async def test_method_search_with_all_params(self, async_client: AsyncContextDev
967971
country="af",
968972
exclude_domains=["string"],
969973
freshness="last_24_hours",
974+
highlights_options={
975+
"enabled": True,
976+
"max_characters": 100,
977+
},
970978
include_domains=["string"],
971979
markdown_options={
972980
"enabled": True,

0 commit comments

Comments
 (0)