Coverage for core/langgraph/tools/contract.py: 100%

26 statements  

« prev     ^ index     » next       coverage.py v7.16.0, created at 2026-10-04 15:34 +0000

1""" 

2Structural tool contract and execution value types. 

3 

4A tool is any object that satisfies the `Tool` protocol by member presence 

5alone — no base class, no registration requirement. `ToolResult` and 

6`ToolContext` are the frozen value types exchanged across one invocation. 

7""" 

8from __future__ import annotations 

9 

10from dataclasses import dataclass 

11from pathlib import Path 

12from typing import Any, Protocol, runtime_checkable 

13 

14 

15RESOLVED_TOOLS_KEY = "_resolved_tools" 

16"""Step carrier key holding an agent's resolved `list[Tool]`.""" 

17 

18 

19@runtime_checkable 

20class Tool(Protocol): 

21 """Structural interface every tool satisfies without inheriting it.""" 

22 

23 name: str 

24 

25 def definition(self) -> dict[str, Any]: 

26 """Model-facing definition in OpenAI native function-tool shape.""" 

27 ... 

28 

29 def instruction(self) -> str | None: 

30 """The tool's usage instruction text, or None when it has none.""" 

31 ... 

32 

33 def params(self) -> list[dict[str, Any]] | None: 

34 """Declared parameter descriptors, or None when there are none.""" 

35 ... 

36 

37 def execute(self, context: ToolContext) -> ToolResult: 

38 """Run one invocation: one context in, one result out.""" 

39 ... 

40 

41 

42@dataclass(frozen=True) 

43class ToolResult: 

44 """Outcome of one tool invocation.""" 

45 

46 ok: bool 

47 content: str 

48 error: str | None = None 

49 state_patch: dict[str, Any] | None = None 

50 

51 

52@dataclass(frozen=True) 

53class ToolContext: 

54 """Invocation inputs handed to `Tool.execute`.""" 

55 

56 args: dict[str, Any] 

57 state: dict[str, Any] 

58 root: Path | None = None 

59 step: dict[str, Any] | None = None 

60 invoker: Any | None = None