ó
    ±"³j£e  ã                  ó²  • % S r SSKJr  SSKrSSKrSSKJr  SSKJr  SSK	J
r
Jr  SSKJr  SSKJrJr  SS	KJrJrJr  SS
KJrJr  SSKJrJr  SSKJr  SSKJrJr  SSK J!r!J"r"J#r#J$r$J%r%J&r&J'r'J(r(  SSK)J*r*J+r+J,r,J-r-J.r.  SSK/J0r0J1r1  SSK2J3r3  SSK4J5r5  SSK6J7r7  \*r8\.Rr                  r:Sr; " S S\5      r<\" \<5      r=Sr>\R~                  " S5      r@S,S jrAS-S jrBSrCSrD    S.S jrE\0" \E5      RŒ                  rG\GR�                  rIS \JS!'   \GR–                  rL\S/S" j5       rMS0S# jrNS1S$ jrOS1S% jrP\
" S&S'9 " S( S)\5\   5      5       rQ\
 " S* S+\7\   5      5       rRg)2u*  Tool search toolset and strategy types.

`ToolSearchToolset` wraps another toolset to support discovery of tools marked with
`defer_loading=True`. It settles the one question that doesn't depend on which model
serves the request â€” is this tool *searchable*? â€” and leaves the rest to
[`Model.prepare_request`][pydantic_ai.models.Model.prepare_request], which can't be
decided here because the model isn't known yet (think `FallbackModel`).

The two questions a deferred tool raises are kept apart:

* **Hidden until revealed** â€” true of every deferred tool. Carried by the authored
  `defer_loading` value, which stays set for the whole run, with current visibility
  travelling separately on `ModelRequestParameters.revealed_tool_names`.
* **Member of the searchable corpus** â€” carried by `with_native='tool_search'`, and set
  only on deferred tools no on-demand capability gates. A capability-gated tool becomes
  available by loading its capability, never by querying for it.

`Model.prepare_request` then decides, per model, how each hidden tool reaches the wire:

* Where the provider can declare a tool but withhold its schema, hidden tools stay in
  `tools` behind the provider's deferral flag (Anthropic `defer_loading`, OpenAI
  Responses `defer_loading`) and a reveal unlocks them in place, leaving `tools`
  byte-identical across the reveal.
* Otherwise hidden tools are kept off the wire entirely and arrive when they're revealed
  â€” as a full declaration on providers with a mid-conversation reveal item, or simply as
  a new `tools` entry where there's no such item.

`search_tools`, the local discovery function, carries `unless_native='tool_search'`
and is dropped by the adapter when the builtin is supported. When the capability commits
to a named-native strategy with no local equivalent (`'bm25'`/`'regex'`) the toolset is
constructed with `enable_fallback=False` and `search_tools` is not emitted at all â€” that
way `_resolve_request_tools` raises on providers that can't honor the builtin, and
the wire stays clean (just the native tool) on those that can.
é    )ÚannotationsN)ÚSequence)Údeepcopy)Ú	dataclassÚreplace)Úcache)Ú	AnnotatedÚAny)ÚFieldÚTypeAdapterÚValidationError)Ú	TypedDictÚassert_neveré   )Ú
AgentDepsTÚ
RunContext©Ú_NO_MATCHES_MESSAGE)Ú
ModelRetryÚ	UserError)ÚModelMessageÚModelRequestÚModelResponseÚNativeToolSearchReturnPartÚToolAvailabilityDeltaPartÚToolReturnPartÚToolSearchReturnPartÚpost_compaction_window)ÚTOOL_SEARCH_FUNCTION_TOOL_NAMEÚToolSearchFuncÚToolSearchMatchÚToolSearchReturnContentÚToolSearchTool)ÚToolÚToolDefinitioné   )Úis_gated_by_deferred_capability)ÚToolsetTool)ÚWrapperToolsetÚdiscovered_toolsc                  ó$   • \ rS rSr% SrS\S'   Srg)Ú_LegacyDiscoveryMetadataéP   a@  Pre-typed-content metadata sideband shape.

Earlier versions stashed discovered tool names on
`ToolReturnPart.metadata['discovered_tools']` instead of on the typed `content`.
Validating against this shape via Pydantic keeps the legacy reader honest about
what it accepts; new writes always go through the typed content.
ú	list[str]r*   © N©Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__Ú__annotations__Ú__static_attributes__r/   ó    Ú^/home/mande/repo/quber/.venv/lib/python3.13/site-packages/pydantic_ai/toolsets/_tool_search.pyr,   r,   P   s   ‡ ñð  Ör8   r,   é
   z	[a-z0-9]+c                óZ   • [        [        R                  U R                  5       5      5      $ )uú   Lowercase + extract alphanumeric tokens for keyword matching.

Used for both the query and the indexed terms (tool name + description) so
matching is case-insensitive and word-bounded â€” `me` matches `get_me` but not
the substring inside `comment`.
)ÚsetÚ_SEARCH_TOKEN_REÚfindallÚlower)Útexts    r9   Ú	_tokenizerA   c   s!   € ô Ô×'Ñ'¨¯
©
«Ó5Ó6Ð6r8   c                óv  • [        SR                  U5      5      nU(       d  / $ / nU Ha  n[        UR                   SUR                  =(       d    S 35      n[	        X6-  5      nUS:”  d  ME  UR                  XuR                  45        Mc     UR                  S SS9  U VV	s/ s H  u  p‰U	PM	     sn	n$ s  sn	nf )uS  Built-in keyword-overlap search algorithm exposed as a [`ToolSearchFunc`][pydantic_ai.capabilities.ToolSearchFunc].

Score each tool by how many query keywords appear in its name or description, then
return matching names ordered by descending score. Used both as the default
algorithm when `ToolSearch` was constructed without an explicit strategy AND as
the explicit `strategy='keywords'` choice â€” the difference is that the explicit
choice routes through the same dispatch path as a user-supplied callable, which
enables client-executed-native wire on supporting providers (cache benefit).
Ú Ú r   c                ó   • U S   $ )Nr   r/   ©Úitems    r9   Ú<lambda>Ú$keywords_search_fn.<locals>.<lambda>€   s   €   a¢r8   T©ÚkeyÚreverse)rA   ÚjoinÚnameÚdescriptionÚlenÚappendÚsort)
Ú_ctxÚqueriesÚtoolsÚtermsÚscoredÚtool_defÚ
tool_termsÚscoreÚ_rN   s
             r9   Úkeywords_search_fnr\   m   s§   € ô �c—h‘h˜wÓ'Ó(€EÞØˆ	Ø$&€FÛˆÜ (§-¡- °°(×2FÑ2F×2LÈ"Ð1MÐNÓOˆ
Ü�EÑ&Ó'ˆØ�1�9Ø�M‰M˜5§-¡-Ð0Ö1ñ	 ð
 ‡K�KÑ(°$€KÑ7Ù &Ô'¢‘W�Q‹D¡Ò'Ð'ùÓ's   Â#B5aD  Search first for a standalone deferred tool when current tools and catalog descriptions do not name the requested operation. A capability id used as an ordinary domain word does not request that capability. This cannot find capability-owned tools; load a listed capability by id instead. If no tools are found, do not retry.zðList of search queries to match against tool names and descriptions. Use specific words likely to appear in tool names or descriptions to narrow down relevant tools. Each query is independently tokenized; matches across queries are unioned.c                ó   • [         e)u  Source-of-truth signature for the `search_tools` function tool.

Used by [`Tool`][pydantic_ai.tools.Tool] to derive the JSON schema and validator
that go on the `ToolDefinition` we hand to the model. Wrapping the function in a
`Tool` (rather than hand-rolling a `TypedDict` + `TypeAdapter`) keeps schema
generation aligned with how every other tool in the framework is defined.

Parameter is `queries: list[str]` to match the cross-provider
[`ToolSearchArgs`][pydantic_ai.messages.ToolSearchArgs] shape â€” so the same typed
[`ToolSearchCallPart`][pydantic_ai.messages.ToolSearchCallPart] represents both
model-emitted local calls AND cross-provider-synthesized history (Anthropic native
`bm25`/`regex` and OpenAI Responses `tool_search_call`, both normalized to `queries`).
)ÚNotImplementedError)rT   s    r9   Ú_search_tools_signaturer_   ”   s
   € ô  Ðr8   údict[str, Any]Ú_SEARCH_TOOL_SCHEMAc                óp   • U [         :X  a  [        [        4$ [        [        5      nXS   S   S'   U[        4$ )ug  Reuse the default schema/validator or splice in a custom `queries` description.

Cached per-description: with the default description the call is a constant-time
lookup that returns the module-level schema and validator (`Tool(fn).function_schema`
is the source of truth for both). A custom description gets a per-description rebuild
whose result is memoized â€” the framework only pays schema-construction cost on the
first run with a given override.

The custom path splices `parameter_description` into the existing JSON schema rather
than rebuilding from a closure-bound signature: `from __future__ import annotations`
stringifies the type expression, so a closure-captured `parameter_description` would
be unresolvable when `Tool` re-evaluates the string at schema-derivation time. The
validator is unaffected by description, so we can safely reuse the default one.
Ú
propertiesrT   rO   )Ú_DEFAULT_PARAMETER_DESCRIPTIONra   Ú_SEARCH_TOOL_VALIDATORr   )Úparameter_descriptionÚschemas     r9   Ú_build_search_args_schemarh   ¬   sB   € ð  Ô >Ó>Ü"Ô$:Ð:Ð:äÔ)Ó*€FØ5Jˆ<Ñ˜Ñ# MÑ2ØÔ)Ð)Ð)r8   c                ó*   • [        [        U 5      5      $ )uq  Scan visible message history for previously-discovered tool names.

Every [`CompactionPart`][pydantic_ai.messages.CompactionPart] resets the derived
state at its exact position in a response. This is deliberately provider-agnostic:
over-counting can prevent rediscovery or claim a schema is visible when it is not,
while under-counting once only permitted a redundant, idempotent search. Now that
availability gates execution, an under-count also *refuses* the call â€” see
[`post_compaction_window`][pydantic_ai.messages.post_compaction_window] for when that
is wrong and what is tracked to fix it.

Trusts that any `ToolSearchReturnPart` / `NativeToolSearchReturnPart` in the
history has a validated `ToolSearchReturnContent`:
Pydantic's discriminator dispatch promotes from base parts on deserialization,
and direct construction goes through the typed-class `__init__` (which Pydantic
validates). No defensive isinstance walks needed.

Also reads the legacy `metadata['discovered_tools']` sideband (validated against
a TypedDict) so histories serialized before the typed-content migration continue
to surface previously-discovered tools.

Only the [`post_compaction_window`][pydantic_ai.messages.post_compaction_window] is scanned â€”
the one definition of the boundary â€” so locating it costs a cheap reverse
`isinstance` pass rather than parsing history the boundary would reset anyway.
)r<   Údiscovered_tool_names_in_order©Úmessagess    r9   Úparse_discovered_toolsrm   Ä   s   € ô2 Ô-¨hÓ7Ó8Ð8r8   c                ó*   • [        [        U 5      5      $ )a  Return discovered names in first-appearance order for byte-stable provider tool segments.

Scans only the [`post_compaction_window`][pydantic_ai.messages.post_compaction_window], so both the
reveal set and the wire ordering derive from what the model can actually see.
)Ú_discovered_tool_names_in_orderr   rk   s    r9   rj   rj   à   s   € ô +Ô+AÀ(Ó+KÓLÐLr8   c                óÀ  • 0 nU  GH¹  n[        U[        5      (       Ga  UR                   GH	  n[        U[        5      (       a0  UR	                  [
        R                  UR                  5      5        MI  [        U[        5      (       a7  UR	                  [
        R                  S UR                   5       5      5        M•  [        U[        5      (       d  M¬  UR                  [        :X  d  MÂ   [        R                  UR                  5      nUR	                  [
        R                  US   5      5        GM     GM7  [        U["        5      (       ab  UR                   HO  n[        U[$        5      (       d  M  UR	                  [
        R                  S UR                   5       5      5        MQ     GM®  ['        U5        GM¼     [)        U5      $ ! [          a     GM±  f = f)zAParse discovery evidence from an already-selected message window.c              3  ó*   #   • U  H	  oS    v •  M     g7f©rN   Nr/   ©Ú.0Úmatchs     r9   Ú	<genexpr>Ú2_discovered_tool_names_in_order.<locals>.<genexpr>ò   ó   é € Ð3eÒOdÀe¸&¶MÒOdùó   ‚r*   c              3  ó*   #   • U  H	  oS    v •  M     g7frr   r/   rs   s     r9   rv   rw      rx   ry   )Ú
isinstancer   Úpartsr   ÚupdateÚdictÚfromkeysÚtools_addedr   r*   r   Ú	tool_nameÚ_SEARCH_TOOLS_NAMEÚ_LEGACY_METADATA_TAÚvalidate_pythonÚmetadatar   r   r   r   Útuple)rl   Ú
discoveredÚmsgÚpartÚ	validateds        r9   ro   ro   é   sR  € à"$€JÜˆÜ�cœ<×(Ò(ØŸ	�	�Ü˜dÔ$=×>Ñ>Ø×%Ñ%¤d§m¡m°D×4DÑ4DÓ&EÖFÜ Ô&:×;Ñ;Ø×%Ñ%¤d§m¡mÑ3eÈt×OdÒOdÓ3eÓ&eÖfÜ ¤n×5Ó5¸$¿.¹.ÔL^Õ:^ð
!Ü$7×$GÑ$GÈÏÉÓ$V˜	ð ×%Ñ%¤d§m¡m°IÐ>PÑ4QÓ&R×Sô "ô ˜œ]×+Ñ+ØŸ	œ	�Ü˜dÔ$>×?Ó?Ø×%Ñ%¤d§m¡mÑ3eÈt×OdÒOdÓ3eÓ&eÖfô "ô ˜×ñ- ô. �ÓÐøô +ó !Û ð!ús   Ã.GÇ
GÇGT)Úkw_onlyc                  ó.   • \ rS rSr% SrS\S'   S\S'   Srg)	Ú_SearchTooli  u)  The local `search_tools` function, carrying the corpus it should search over.

The real `ToolDefinition`s flow through to user-supplied search functions so
callables can read whatever metadata they need (parameters schema, kind, etc.) â€” not
just the name/description pair we'd otherwise expose.
zlist[ToolDefinition]Úcorpusúset[str]Údiscovered_tool_namesr/   Nr0   r/   r8   r9   r�   r�     s   ‡ ñð !Ó à#Ó#òr8   r�   c                  óB  • \ rS rSr% SrSrS\S'    \rS\S'    Sr	S\S	'    Sr
S\S
'    SrS\S'    SrS\S'    SS jr      SS jr          SS jr\SS j5       r        SS jr      SS jr          S S jr\S!S j5       r\S"S j5       rSrg)#ÚToolSearchToolseti  uþ  A toolset that enables tool discovery for large toolsets.

Wraps another toolset and exposes a `search_tools` function that lets the model
discover tools with `defer_loading=True`. Tools with `defer_loading=True` are
not initially presented to the model â€” they become available after the model
discovers them via search.

When the model supports the framework-managed tool-search builtin, discovery is
handled by the provider and the deferred tools are sent to the API with
`defer_loading=True` on the wire.
Nz!ToolSearchFunc[AgentDepsT] | NoneÚ	search_fnÚintÚmax_resultsú
str | NoneÚtool_descriptionrf   TÚboolÚenable_fallbackz
int | NoneÚmax_retriesc           	   ƒ  ób  #   • U R                   R                  U5      I S h  v•N n0 n0 nUR                  5        H*  u  pVUR                  R                  (       a  XcU'   M&  XdU'   M,     U(       d  U$ [
        U;   a  [        S[
         S35      e[        U5      n0 nUR                  5        HK  u  pV[        XR                  5      (       a  XgU'   M%  XhU'   [        U[        UR                  [        S9S9Xu'   MM     U R                  (       a  U(       a  U R                  X5      U[
        '   U$  GN7f)NzTool name 'zC' is reserved for tool search. Rename your tool to avoid conflicts.)Úwith_native)rX   )ÚwrappedÚ	get_toolsÚitemsrX   Údefer_loadingr‚   r   r~   r'   r   Ú_TOOL_SEARCH_BUILTIN_IDr™   Ú_build_search_tool)	ÚselfÚctxÚ	all_toolsÚdeferredÚvisiblerN   ÚtoolÚresultÚ
searchables	            r9   rž   ÚToolSearchToolset.get_toolsN  s  é € ØŸ,™,×0Ñ0°Ó5×5ˆ	à79ˆØ68ˆØ#Ÿ/™/Ö+‰JˆDØ�}‰}×*×*Ø!%˜“à $˜“ñ	 ,ö ØÐä Ó*ÜØÔ0Ð1Ð1tÐuóð ô 6:¸'³]ˆð :<ˆ
Ø"Ÿ.™.Ö*‰JˆDÜ.¨s·M±M×BÑBØ#�t“à#'˜4Ñ Ü& t´g¸d¿m¹mÔYpÑ6qÑr�“ñ +ð. ××¦JØ)-×)@Ñ)@ÀÓ)QˆFÔ%Ñ&àˆòm 6ùs   ‚D/¡D,¢DD/c           
     ó¬  • U R                   =(       d    [        n[        U5      u  pEUR                  5        Vs/ s H  ofR                  PM     nnU R
                  c  [        OS n[        [        U R                  =(       d    [        USUS9n	[        U U	U R                  b  U R                  OUR                  UU[        UR                  5      S9$ s  snf )Nztool-search)rN   rO   Úparameters_json_schemaÚ	tool_kindÚunless_native)ÚtoolsetrX   rš   Úargs_validatorrŽ   r�   )rf   rd   rh   ÚvaluesrX   r“   r¡   r%   r‚   r—   Ú_DEFAULT_TOOL_DESCRIPTIONr�   rš   r<   r�   )
r£   r¤   rª   rf   rg   r±   r¨   rŽ   r¯   Úsearch_tool_defs
             r9   r¢   Ú$ToolSearchToolset._build_search_tool‡  sÈ   € ð
 !%× :Ñ :× \Ô>\ÐÜ!:Ð;PÓ!QÑˆð
 -7×,=Ñ,=Ô,?Ó@Ò,? D—-”-Ñ,?ˆÐ@ð 48·>±>Ñ3IÕ/ÈtˆÜ(Ü#Ø×-Ñ-×JÔ1JØ#)Ø#Ø'ñ
ˆô ØØ$Ø,0×,<Ñ,<Ñ,H˜×(Ò(ÈcÏoÉoØ)ØÜ"% c×&?Ñ&?Ó"@ñ
ð 	
ùò+ As   ¹Cc              ƒ  óÌ   #   • U[         :X  a/  [        U[        5      (       a  U R                  X#U5      I S h  v•N $ U R                  R                  XX45      I S h  v•N $  N( N7f©N)r‚   r{   r�   Ú_search_toolsr�   Ú	call_tool)r£   rN   Ú	tool_argsr¤   r¨   s        r9   r¹   ÚToolSearchToolset.call_tool°  sU   é € ð Ô%Ó%¬*°T¼;×*GÑ*GØ×+Ñ+¨I¸DÓA×AÐAØ—\‘\×+Ñ+¨D¸SÓG×GÐGñ BÙGùs!   ‚5A$·A ¸#A$ÁA"ÁA$Á"A$c                óÐ   • [        [        R                  U R                  5       5      5      nU(       a2  UR	                  [        R                  UR                  5       5      5        U$ r·   )r<   r=   r>   r?   r}   )rN   rO   Úsearch_termss      r9   Ú_search_termsÚToolSearchToolset._search_terms·  sJ   € äÔ+×3Ñ3°D·J±J³LÓAÓBˆÞØ×ÑÔ 0× 8Ñ 8¸×9JÑ9JÓ9LÓ MÔNØÐr8   c              ƒ  óÐ   #   • US   n[        S U 5       5      (       d  [        S5      eU R                  nUb  U R                  XTX#5      I Sh  v•N $ U R	                  XC5      $  N7f)zFRun the configured search strategy over all searchable deferred tools.rT   c              3  ó@   #   • U  H  oR                  5       v •  M     g 7fr·   )Ústrip)rt   Úqs     r9   rv   Ú2ToolSearchToolset._search_tools.<locals>.<genexpr>Ã  s   é € Ð.¢g —7‘7—9�9¢gùs   ‚ú3Please provide at least one non-empty search query.N)Úanyr   r“   Ú_run_search_fnÚ_run_keywords_search)r£   rº   r¤   Úsearch_toolrT   Úfns         r9   r¸   ÚToolSearchToolset._search_tools¾  si   é € ð ' yÑ1ˆÜÑ.¡gÓ.×.Ñ.ÜÐRÓSÐSà�^‰^ˆØ‰>Ø×,Ñ,¨R¸#ÓK×KÐKØ×(Ñ(¨Ó>Ð>ñ Lùs   ‚AA&ÁA$ÁA&c                ó<  • U R                  SR                  U5      S5      nU(       d  [        S5      e/ nUR                   Hu  nU R                  UR                  UR
                  5      n[        X6-  5      nUS:X  a  M>  UR                  UR                  UR                  ;  USUR                  045        Mw     U(       d  U R                  5       $ UR                  S SS9  USU R                    VV	s/ s H  u    p‰U	PM
     n
nn	U R                  U
5      $ s  sn	nf )	uŠ  Score each tool by how many query tokens appear in its name/description.

Tokenizes on alphanumeric runs for both the queries and the indexed terms, so the
top hit for "github profile" is `github_get_me` (two matches) without matching
substrings inside longer words like `comment` for the query `me`. Tokens from all
queries are unioned â€” the same token-overlap score applies across the set.
rC   NrÅ   r   rN   c                ó   • U S   U S   4$ )Nr   r&   r/   rF   s    r9   rH   Ú8ToolSearchToolset._run_keywords_search.<locals>.<lambda>é  s   € ¨d°1©g°t¸A±wÑ-?r8   TrJ   )r¾   rM   r   rŽ   rN   rO   rP   rQ   r�   Ú_empty_returnrR   r•   Ú_build_return)r£   rT   rÉ   rV   Úscored_matchesrX   rY   rZ   r[   ru   Úmatchess              r9   rÈ   Ú&ToolSearchToolset._run_keywords_searchË  s  € ð ×"Ñ" 3§8¡8¨GÓ#4°dÓ;ˆÞÜÐRÓSÐSàBDˆØ#×*Ô*ˆHØ×+Ñ+¨H¯M©M¸8×;OÑ;OÓPˆJÜ˜Ñ*Ó+ˆEØ˜‹zÙØ×!Ñ!Ø—‘ k×&GÑ&GÑGÈÐQWÐYa×YfÑYfÐPgÐhöñ +ö Ø×%Ñ%Ó'Ð'ð
 	×ÑÑ ?ÈÐÑNØ,:Ð;M¸T×=MÑ=MÑ,NÔOÒ,N™[˜Q “5Ñ,NˆÑOØ×!Ñ! 'Ó*Ð*ùó Ps   Ã5Dc              ƒ  óÌ  #   • UR                    Vs0 s H  oUR                  U_M     nnU" X2UR                   5      n[        R                  " U5      (       a
  UI Sh  v•N n/ n[	        U5      SU R
                    H6  n	UR                  U	5      =nc  M  UR                  SUR                  05        M8     U(       d  U R                  5       $ U R                  U5      $ s  snf  N…7f)zNInvoke a user-provided strategy, validating that the returned names are known.NrN   )
rŽ   rN   ÚinspectÚisawaitableÚlistr•   ÚgetrQ   rÏ   rÐ   )
r£   rÊ   rT   r¤   rÉ   rX   Útool_defs_by_namer©   rÒ   rN   s
             r9   rÇ   Ú ToolSearchToolset._run_search_fní  sÓ   é € ð FQ×EWÒEWÓXÒEW¸Ÿ]™]¨HÒ4ÑEWÐÐXá�C +×"4Ñ"4Ó5ˆÜ×Ò˜v×&Ñ&Ø!—\ˆFà)+ˆÜ˜“LÐ!3 4×#3Ñ#3Ó4ˆDØ-×1Ñ1°$Ó7Ð7�ÓDØ—‘ ¨¯©Ð6Ö7ñ 5ö Ø×%Ñ%Ó'Ð'Ø×!Ñ! 'Ó*Ð*ùò Yñ "ùs"   ‚C$‘C§5C$ÁC"Á3C$ÂAC$c                 ó   • / [         S.$ )u°  Shaped "no matches" return: empty discovered_tools list with a user-visible message.

Sending only the typed
[`ToolSearchReturnContent`][pydantic_ai.messages.ToolSearchReturnContent] is enough
â€” the JSON-serialized return value carries the message to the model, so it doesn't
retry searching with the same keywords; adapters that need the message on the wire
(Anthropic custom-callable empty-results path) read it from there too.
)r*   Úmessager   r/   r8   r9   rÏ   ÚToolSearchToolset._empty_return  s   € ð !#Ü*ñ
ð 	
r8   c                ó
   • SU 0$ )zgShaped matches return: typed [`ToolSearchReturnContent`][pydantic_ai.messages.ToolSearchReturnContent].r*   r/   )rÒ   s    r9   rÐ   ÚToolSearchToolset._build_return  s   € ð # GÐ,Ð,r8   r/   )r¤   úRunContext[AgentDepsT]Úreturnú"dict[str, ToolsetTool[AgentDepsT]])r¤   rà   rª   râ   rá   ú_SearchTool[AgentDepsT])
rN   Ústrrº   r`   r¤   rà   r¨   zToolsetTool[AgentDepsT]rá   r
   )rN   rä   rO   r–   rá   r�   )rº   r`   r¤   rà   rÉ   rã   rá   r"   )rT   úSequence[str]rÉ   rã   rá   r"   )
rÊ   zToolSearchFunc[AgentDepsT]rT   rå   r¤   rà   rÉ   rã   rá   r"   )rá   r"   )rÒ   zlist[ToolSearchMatch]rá   r"   )r1   r2   r3   r4   r5   r“   r6   Ú_MAX_SEARCH_RESULTSr•   r—   rf   r™   rš   rž   r¢   r¹   Ústaticmethodr¾   r¸   rÈ   rÇ   rÏ   rÐ   r7   r/   r8   r9   r’   r’     st  ‡ ñ
ð 48€IÐ0Ó7ðð +€K�Ó*ØHà#'Ð�jÓ'ØPà(,Ð˜:Ó,ØLà €O�TÓ ðQð #€K�Ó"ð	ô7ðr'
à#ð'
ð 7ð'
ð 
!ô	'
ðRHØðHØ$2ðHØ9OðHØWnðHà	ôHð óó ðð?Ø'ð?Ø.Dð?ØSjð?à	 ô?ð +Ø$ð +Ø3Jð +à	 ô +ðD+à&ð+ð ð+ð $ð	+ð
 -ð+ð 
!ô+ð. ó
ó ð
ð ó-ó ó-r8   r’   )r@   rä   rá   r�   )rS   zRunContext[Any]rT   rå   rU   zSequence[ToolDefinition]rá   r.   )rT   zGAnnotated[list[str], Field(description=_DEFAULT_PARAMETER_DESCRIPTION)]rá   r"   )rf   rä   rá   ztuple[dict[str, Any], Any])rl   úSequence[ModelMessage]rá   r�   )rl   rè   rá   ztuple[str, ...])Sr5   Ú
__future__r   rÕ   ÚreÚcollections.abcr   Úcopyr   Údataclassesr   r   Ú	functoolsr   Útypingr	   r
   Úpydanticr   r   r   Útyping_extensionsr   r   Ú_run_contextr   r   Ú_tool_searchr   Ú
exceptionsr   r   rl   r   r   r   r   r   r   r   r   Únative_tools._tool_searchr   r    r!   r"   r#   rU   r$   r%   Ú_capability_ownedr'   Úabstractr(   Úwrapperr)   r‚   Úkindr¡   Ú%_LEGACY_DISCOVERED_TOOLS_METADATA_KEYr,   rƒ   ræ   Úcompiler=   rA   r\   r³   rd   r_   Úfunction_schemaÚ_SEARCH_TOOL_FN_SCHEMAÚjson_schemara   r6   Ú	validatorre   rh   rm   rj   ro   r�   r’   r/   r8   r9   Ú<module>r      sx  ðò!õF #ã Û 	Ý $Ý ß *Ý ß !ç 8Ñ 8ß 5ç 1Ý .ß .÷	÷ 	ó 	÷õ ÷ )Ý >Ý !Ý #à3Ð Ø(×-Ñ-Ð à(:Ð %ô	 ˜yô 	 ñ "Ð":Ó;Ð ð Ð Ø—:’:˜lÓ+Ð ô7ô(ð0,ð ðRð ðØTðàôñ& Ð5Ó6×FÑFÐ Ø&<×&HÑ&HÐ �^Ó HØ/×9Ñ9Ð ð ó*ó ð*ô.9ô8Môñ: �4Ñô�+˜jÑ)ó ó ðð( ôz-˜ zÑ2ó z-ó ñz-r8   