pybotchi 3.4.2__tar.gz → 3.4.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. {pybotchi-3.4.2 → pybotchi-3.4.4}/PKG-INFO +3 -3
  2. {pybotchi-3.4.2 → pybotchi-3.4.4}/pybotchi/action.py +7 -7
  3. {pybotchi-3.4.2 → pybotchi-3.4.4}/pybotchi/action.pyi +5 -6
  4. {pybotchi-3.4.2 → pybotchi-3.4.4}/pybotchi/common.py +1 -1
  5. {pybotchi-3.4.2 → pybotchi-3.4.4}/pybotchi/common.pyi +1 -2
  6. {pybotchi-3.4.2 → pybotchi-3.4.4}/pybotchi/grpc/action.py +13 -13
  7. {pybotchi-3.4.2 → pybotchi-3.4.4}/pybotchi/grpc/action.pyi +13 -13
  8. {pybotchi-3.4.2 → pybotchi-3.4.4}/pybotchi/grpc/cli.py +2 -1
  9. {pybotchi-3.4.2 → pybotchi-3.4.4}/pybotchi/grpc/common.py +17 -17
  10. {pybotchi-3.4.2 → pybotchi-3.4.4}/pybotchi/grpc/common.pyi +17 -18
  11. {pybotchi-3.4.2 → pybotchi-3.4.4}/pybotchi/grpc/exception.py +5 -5
  12. {pybotchi-3.4.2 → pybotchi-3.4.4}/pybotchi/grpc/exception.pyi +5 -7
  13. {pybotchi-3.4.2 → pybotchi-3.4.4}/pybotchi/grpc/handler.py +9 -9
  14. {pybotchi-3.4.2 → pybotchi-3.4.4}/pybotchi/grpc/handler.pyi +9 -10
  15. pybotchi-3.4.4/pybotchi/grpc/pybotchi_pb2.pyi +165 -0
  16. {pybotchi-3.4.2 → pybotchi-3.4.4}/pybotchi/grpc/pybotchi_pb2_grpc.py +1 -1
  17. pybotchi-3.4.4/pybotchi/grpc/pybotchi_pb2_grpc.pyi +67 -0
  18. {pybotchi-3.4.2 → pybotchi-3.4.4}/pybotchi/mcp/action.py +13 -13
  19. {pybotchi-3.4.2 → pybotchi-3.4.4}/pybotchi/mcp/action.pyi +13 -13
  20. {pybotchi-3.4.2 → pybotchi-3.4.4}/pybotchi/mcp/common.py +15 -15
  21. {pybotchi-3.4.2 → pybotchi-3.4.4}/pybotchi/mcp/common.pyi +15 -16
  22. {pybotchi-3.4.2 → pybotchi-3.4.4}/pybotchi/utils.py +3 -3
  23. {pybotchi-3.4.2 → pybotchi-3.4.4}/pybotchi/utils.pyi +3 -3
  24. {pybotchi-3.4.2 → pybotchi-3.4.4}/pyproject.toml +3 -3
  25. pybotchi-3.4.2/pybotchi/grpc/pybotchi_pb2.pyi +0 -5
  26. pybotchi-3.4.2/pybotchi/grpc/pybotchi_pb2_grpc.pyi +0 -26
  27. {pybotchi-3.4.2 → pybotchi-3.4.4}/LICENSE +0 -0
  28. {pybotchi-3.4.2 → pybotchi-3.4.4}/README.md +0 -0
  29. {pybotchi-3.4.2 → pybotchi-3.4.4}/pybotchi/__init__.py +0 -0
  30. {pybotchi-3.4.2 → pybotchi-3.4.4}/pybotchi/__init__.pyi +0 -0
  31. {pybotchi-3.4.2 → pybotchi-3.4.4}/pybotchi/context.py +0 -0
  32. {pybotchi-3.4.2 → pybotchi-3.4.4}/pybotchi/context.pyi +0 -0
  33. {pybotchi-3.4.2 → pybotchi-3.4.4}/pybotchi/grpc/__init__.py +0 -0
  34. {pybotchi-3.4.2 → pybotchi-3.4.4}/pybotchi/grpc/__init__.pyi +0 -0
  35. {pybotchi-3.4.2 → pybotchi-3.4.4}/pybotchi/grpc/cli.pyi +0 -0
  36. {pybotchi-3.4.2 → pybotchi-3.4.4}/pybotchi/grpc/context.py +0 -0
  37. {pybotchi-3.4.2 → pybotchi-3.4.4}/pybotchi/grpc/context.pyi +0 -0
  38. {pybotchi-3.4.2 → pybotchi-3.4.4}/pybotchi/grpc/pybotchi.proto +0 -0
  39. {pybotchi-3.4.2 → pybotchi-3.4.4}/pybotchi/grpc/pybotchi_pb2.py +0 -0
  40. {pybotchi-3.4.2 → pybotchi-3.4.4}/pybotchi/grpc/utils.py +0 -0
  41. {pybotchi-3.4.2 → pybotchi-3.4.4}/pybotchi/grpc/utils.pyi +0 -0
  42. {pybotchi-3.4.2 → pybotchi-3.4.4}/pybotchi/llm.py +0 -0
  43. {pybotchi-3.4.2 → pybotchi-3.4.4}/pybotchi/llm.pyi +0 -0
  44. {pybotchi-3.4.2 → pybotchi-3.4.4}/pybotchi/mcp/__init__.py +0 -0
  45. {pybotchi-3.4.2 → pybotchi-3.4.4}/pybotchi/mcp/__init__.pyi +0 -0
  46. {pybotchi-3.4.2 → pybotchi-3.4.4}/pybotchi/mcp/context.py +0 -0
  47. {pybotchi-3.4.2 → pybotchi-3.4.4}/pybotchi/mcp/context.pyi +0 -0
  48. {pybotchi-3.4.2 → pybotchi-3.4.4}/pybotchi/py.typed +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pybotchi
3
- Version: 3.4.2
3
+ Version: 3.4.4
4
4
  Summary: A deterministic, intent-based AI agent builder.
5
5
  License-File: LICENSE
6
6
  Author: Alexie (Boyong) Madolid
@@ -15,8 +15,8 @@ Provides-Extra: mcp
15
15
  Requires-Dist: aiofiles (>=25.1.0) ; extra == "grpc"
16
16
  Requires-Dist: click (>=8.3.1) ; extra == "grpc"
17
17
  Requires-Dist: datamodel-code-generator[ruff] (>=0.31.2) ; extra == "mcp" or extra == "grpc"
18
- Requires-Dist: grpcio (>=1.76.0) ; extra == "grpc"
19
- Requires-Dist: grpcio-tools (>=1.76.0) ; extra == "grpc"
18
+ Requires-Dist: grpcio (>=1.80.0) ; extra == "grpc"
19
+ Requires-Dist: grpcio-tools (>=1.80.0) ; extra == "grpc"
20
20
  Requires-Dist: langchain-core (>=0.3.15)
21
21
  Requires-Dist: mcp (>=1.15.0) ; extra == "mcp"
22
22
  Requires-Dist: orjson (>=3.9.11)
@@ -7,7 +7,7 @@ from collections import deque
7
7
  from collections.abc import Generator
8
8
  from inspect import getmembers
9
9
  from os import getenv
10
- from typing import Any, Generic, TYPE_CHECKING, TypeVar
10
+ from typing import Any, Generic, Literal, TYPE_CHECKING, TypeVar
11
11
 
12
12
  from pydantic import BaseModel, PrivateAttr
13
13
 
@@ -26,8 +26,8 @@ if TYPE_CHECKING:
26
26
  from .context import Context
27
27
 
28
28
 
29
- DEFAULT_ACTION = getenv("DEFAULT_ACTION", "DefaultAction")
30
- DEFAULT_TOOL_CALL_PROMPT = getenv(
29
+ DEFAULT_ACTION: str = getenv("DEFAULT_ACTION", "DefaultAction")
30
+ DEFAULT_TOOL_CALL_PROMPT: str = getenv(
31
31
  "DEFAULT_TOOL_CALL_PROMPT",
32
32
  """
33
33
  You are an AI assistant expert in function calling.
@@ -47,7 +47,7 @@ ${system}
47
47
  ${addons}
48
48
  """.strip(),
49
49
  )
50
- DEFAULT_MAX_ITERATION_PROMPT = getenv(
50
+ DEFAULT_MAX_ITERATION_PROMPT: str = getenv(
51
51
  "DEFAULT_MAX_ITERATION_PROMPT",
52
52
  """
53
53
  You are an AI assistant responsible for delivering the final response to the user.
@@ -503,13 +503,13 @@ class Action(BaseModel, Generic[TContext]):
503
503
 
504
504
  return ActionReturn.GO
505
505
 
506
- def serialize(self) -> ActionEntry:
506
+ def serialize(self, mode: str | Literal["python", "json"] = "python") -> ActionEntry:
507
507
  """Serialize Action."""
508
508
  return {
509
509
  "name": self.__class__.__name__,
510
- "args": self.model_dump(),
510
+ "args": self.model_dump(mode=mode),
511
511
  "usages": self._usage,
512
- "actions": [a.serialize() if isinstance(a, Action) else a for a in self._actions],
512
+ "actions": [a.serialize(mode) if isinstance(a, Action) else a for a in self._actions],
513
513
  }
514
514
 
515
515
  ####################################################################################################
@@ -1,14 +1,13 @@
1
1
  from .common import ActionEntry as ActionEntry, ActionReturn as ActionReturn, ConcurrentBreakPoint as ConcurrentBreakPoint, Graph as Graph, Groups as Groups, ToolCall as ToolCall, UsageData as UsageData
2
2
  from .context import Context as Context
3
3
  from .utils import apply_placeholders as apply_placeholders, unwrap_exceptions as unwrap_exceptions, uuid as uuid
4
- from _typeshed import Incomplete
5
4
  from collections.abc import Generator
6
5
  from pydantic import BaseModel
7
- from typing import Any, Generic, TypeVar
6
+ from typing import Any, Generic, Literal, TypeVar
8
7
 
9
- DEFAULT_ACTION: Incomplete
10
- DEFAULT_TOOL_CALL_PROMPT: Incomplete
11
- DEFAULT_MAX_ITERATION_PROMPT: Incomplete
8
+ DEFAULT_ACTION: str
9
+ DEFAULT_TOOL_CALL_PROMPT: str
10
+ DEFAULT_MAX_ITERATION_PROMPT: str
12
11
  TAction = TypeVar('TAction', bound='Action')
13
12
  TContext = TypeVar('TContext', bound='Context')
14
13
  T = TypeVar('T')
@@ -66,7 +65,7 @@ class Action(BaseModel, Generic[TContext]):
66
65
  async def execution(self, context: TContext) -> ActionReturn: ...
67
66
  async def concurrent_children_execution(self, context: TContext, next_actions: list[Action]) -> ActionReturn: ...
68
67
  async def sequential_children_execution(self, context: TContext, next_actions: list[Action]) -> ActionReturn: ...
69
- def serialize(self) -> ActionEntry: ...
68
+ def serialize(self, mode: str | Literal['python', 'json'] = 'python') -> ActionEntry: ...
70
69
  @classmethod
71
70
  def add_child(cls, action: type['Action'], name: str | None = None, override: bool = False, extended: bool = True) -> None: ...
72
71
  @classmethod
@@ -182,7 +182,7 @@ class ConcurrentBreakPoint(Exception): # noqa: N818
182
182
 
183
183
  def __init__(self, action_return: ActionReturn) -> None:
184
184
  """Initialize ConcurrentBreakPoint Exception."""
185
- self.action_return = action_return
185
+ self.action_return: ActionReturn = action_return
186
186
  super().__init__(action_return)
187
187
 
188
188
 
@@ -1,4 +1,3 @@
1
- from _typeshed import Incomplete
2
1
  from enum import StrEnum
3
2
  from functools import cached_property as cached_property
4
3
  from pydantic import BaseModel, ConfigDict, SkipValidation as SkipValidation
@@ -80,7 +79,7 @@ class Break(ActionReturn): ...
80
79
  class End(Break): ...
81
80
 
82
81
  class ConcurrentBreakPoint(Exception):
83
- action_return: Incomplete
82
+ action_return: ActionReturn
84
83
  def __init__(self, action_return: ActionReturn) -> None: ...
85
84
 
86
85
  UNSPECIFIED: str
@@ -1,14 +1,14 @@
1
1
  """Pybotchi GRPC Classes."""
2
2
 
3
3
  from asyncio import Queue
4
- from collections.abc import AsyncGenerator, Awaitable
4
+ from collections.abc import AsyncGenerator, AsyncIterator, Awaitable
5
5
  from contextlib import AsyncExitStack, asynccontextmanager
6
6
  from inspect import getmembers
7
7
  from itertools import islice
8
8
  from typing import Any, Generic
9
9
 
10
10
  from datamodel_code_generator import DataModelType, Formatter, PythonVersion
11
- from datamodel_code_generator.model import get_data_model_types
11
+ from datamodel_code_generator.model import DataModelSet, get_data_model_types
12
12
  from datamodel_code_generator.parser.jsonschema import (
13
13
  JsonSchemaParser,
14
14
  )
@@ -36,7 +36,7 @@ from ..action import Action, ChildActions
36
36
  from ..common import ActionReturn, Graph
37
37
  from ..utils import unwrap_exceptions
38
38
 
39
- DMT = get_data_model_types(
39
+ DMT: DataModelSet = get_data_model_types(
40
40
  DataModelType.PydanticV2BaseModel,
41
41
  target_python_version=PythonVersion.PY_313,
42
42
  )
@@ -56,13 +56,13 @@ class GRPCClient:
56
56
  exclude_unset: bool,
57
57
  ) -> None:
58
58
  """Build GRPC Client."""
59
- self.stub = stub
60
- self.name = name
61
- self.config = config
62
- self.manual_enable = manual_enable
63
- self.allowed_actions = allowed_actions
64
- self.remote_action_class = remote_action_class or GRPCRemoteAction
65
- self.exclude_unset = exclude_unset
59
+ self.stub: PyBotchiGRPCStub = stub
60
+ self.name: str = name
61
+ self.config: GRPCConfigLoaded = config
62
+ self.manual_enable: bool = manual_enable
63
+ self.allowed_actions: dict[str, bool] = allowed_actions
64
+ self.remote_action_class: type["GRPCRemoteAction"] = remote_action_class or GRPCRemoteAction
65
+ self.exclude_unset: bool = exclude_unset
66
66
 
67
67
  def build_action(self, agent_id: str, action_schema: ActionSchema) -> tuple[str, type["GRPCRemoteAction"]]:
68
68
  """Build GRPCToolAction."""
@@ -143,7 +143,7 @@ class GRPCClient:
143
143
  return actions
144
144
 
145
145
 
146
- class GRPCAction(Action[TContext], Generic[TContext]):
146
+ class GRPCAction(Action[TContext]):
147
147
  """GRPC Action."""
148
148
 
149
149
  __grpc_clients__: dict[str, GRPCClient]
@@ -178,7 +178,7 @@ class GRPCAction(Action[TContext], Generic[TContext]):
178
178
 
179
179
  async def execute(self, context: TContext, parent: Action | None = None, append: bool = True) -> ActionReturn:
180
180
  """Execute main process."""
181
- self._parent = parent
181
+ self._parent: Action | None = parent
182
182
  parent_context = context
183
183
  try:
184
184
  if parent and append:
@@ -441,7 +441,7 @@ async def multi_grpc_clients(
441
441
  integrations: dict[str, GRPCIntegration],
442
442
  connections: list[GRPCConnection],
443
443
  bypass: bool = False,
444
- ) -> AsyncGenerator[dict[str, GRPCClient], None]:
444
+ ) -> AsyncIterator[dict[str, GRPCClient]]:
445
445
  """Connect to multiple grpc clients."""
446
446
  async with AsyncExitStack() as stack:
447
447
  clients: dict[str, GRPCClient] = {}
@@ -6,27 +6,27 @@ from .context import TContext as TContext
6
6
  from .exception import GRPCRemoteError as GRPCRemoteError
7
7
  from .pybotchi_pb2 import ActionListRequest as ActionListRequest, ActionListResponse as ActionListResponse, ActionSchema as ActionSchema, Event as Event, TraverseGraph as TraverseGraph, TraverseRequest as TraverseRequest
8
8
  from .pybotchi_pb2_grpc import PyBotchiGRPCStub as PyBotchiGRPCStub
9
- from _typeshed import Incomplete
10
9
  from asyncio import Queue
11
- from collections.abc import AsyncGenerator
10
+ from collections.abc import AsyncGenerator, AsyncIterator
12
11
  from contextlib import asynccontextmanager
12
+ from datamodel_code_generator.model import DataModelSet as DataModelSet
13
13
  from typing import Any, Generic
14
14
 
15
- DMT: Incomplete
15
+ DMT: DataModelSet
16
16
 
17
17
  class GRPCClient:
18
- stub: Incomplete
19
- name: Incomplete
20
- config: Incomplete
21
- manual_enable: Incomplete
22
- allowed_actions: Incomplete
23
- remote_action_class: Incomplete
24
- exclude_unset: Incomplete
18
+ stub: PyBotchiGRPCStub
19
+ name: str
20
+ config: GRPCConfigLoaded
21
+ manual_enable: bool
22
+ allowed_actions: dict[str, bool]
23
+ remote_action_class: type['GRPCRemoteAction']
24
+ exclude_unset: bool
25
25
  def __init__(self, stub: PyBotchiGRPCStub, name: str, config: GRPCConfigLoaded, manual_enable: bool, allowed_actions: dict[str, bool], remote_action_class: type['GRPCRemoteAction'] | None, exclude_unset: bool) -> None: ...
26
26
  def build_action(self, agent_id: str, action_schema: ActionSchema) -> tuple[str, type['GRPCRemoteAction']]: ...
27
27
  async def patch_actions(self, actions: ChildActions, grpc_actions: ChildActions) -> ChildActions: ...
28
28
 
29
- class GRPCAction(Action[TContext], Generic[TContext]):
29
+ class GRPCAction(Action[TContext]):
30
30
  __grpc_clients__: dict[str, GRPCClient]
31
31
  __grpc_connections__: list[GRPCConnection]
32
32
  __grpc_tool_actions__: ChildActions
@@ -36,7 +36,7 @@ class GRPCAction(Action[TContext], Generic[TContext]):
36
36
  @classmethod
37
37
  def __init_child_actions__(cls) -> None: ...
38
38
  async def pre_grpc(self, context: TContext) -> ActionReturn: ...
39
- _parent: Incomplete
39
+ _parent: Action | None
40
40
  __to_commit__: bool
41
41
  async def execute(self, context: TContext, parent: Action | None = None, append: bool = True) -> ActionReturn: ...
42
42
  async def get_child_actions(self, context: TContext) -> ChildActions: ...
@@ -60,6 +60,6 @@ class GRPCRemoteAction(Action[TContext], Generic[TContext]):
60
60
  async def pre(self, context: TContext) -> ActionReturn: ...
61
61
 
62
62
  @asynccontextmanager
63
- async def multi_grpc_clients(integrations: dict[str, GRPCIntegration], connections: list[GRPCConnection], bypass: bool = False) -> AsyncGenerator[dict[str, GRPCClient], None]: ...
63
+ async def multi_grpc_clients(integrations: dict[str, GRPCIntegration], connections: list[GRPCConnection], bypass: bool = False) -> AsyncIterator[dict[str, GRPCClient]]: ...
64
64
  async def graph(action: type[Action], allowed_actions: dict[str, bool] | None = None, integrations: dict[str, GRPCIntegration] | None = None, bypass: bool = False) -> Graph: ...
65
65
  async def traverse(graph: Graph, action: type[Action], allowed_actions: dict[str, bool] | None, integrations: dict[str, GRPCIntegration], bypass: bool = False, module: str | None = None, alias: str | None = None) -> None: ...
@@ -234,7 +234,8 @@ def compile() -> None:
234
234
  f"--python_out={current_dir}",
235
235
  f"--pyi_out={current_dir}",
236
236
  f"--grpc_python_out={current_dir}",
237
- "pybotchi.proto", # must be relative to --proto_path
237
+ f"--mypy_grpc_out={current_dir}",
238
+ "pybotchi.proto",
238
239
  ]
239
240
  )
240
241
 
@@ -81,23 +81,23 @@ class GRPCConnection:
81
81
  require_integration: bool = True,
82
82
  ) -> None:
83
83
  """Build GRPC Connection."""
84
- self.name = name
85
- self.url = url
86
- self.groups = [] if groups is None else groups
87
- self.secure = secure
88
- self.root_certificates = root_certificates
89
- self.private_key = private_key
90
- self.certificate_chain = certificate_chain
91
- self.options = options
92
- self.compression = compression
93
- self.interceptors = interceptors
94
- self.metadata = metadata
95
- self.allow_exec = allow_exec
96
- self.manual_enable = manual_enable
97
- self.allowed_actions = {} if allowed_actions is None else allowed_actions
98
- self.remote_action_class = remote_action_class
99
- self.exclude_unset = exclude_unset
100
- self.require_integration = require_integration
84
+ self.name: str = name
85
+ self.url: str = url
86
+ self.groups: list[str] = [] if groups is None else groups
87
+ self.secure: bool = secure
88
+ self.root_certificates: str | bytes | None = root_certificates
89
+ self.private_key: str | bytes | None = private_key
90
+ self.certificate_chain: str | bytes | None = certificate_chain
91
+ self.options: list[tuple[str, Any]] | None = options
92
+ self.compression: GRPCCompression | None = compression
93
+ self.interceptors: Sequence[ClientInterceptor] | None = interceptors
94
+ self.metadata: dict[str, Any] | None = metadata
95
+ self.allow_exec: bool = allow_exec
96
+ self.manual_enable: bool = manual_enable
97
+ self.allowed_actions: dict[str, bool] = {} if allowed_actions is None else allowed_actions
98
+ self.remote_action_class: type["GRPCRemoteAction"] | None = remote_action_class
99
+ self.exclude_unset: bool = exclude_unset
100
+ self.require_integration: bool = require_integration
101
101
 
102
102
  async def get_config(self, override: GRPCConfig | None) -> GRPCConfigLoaded:
103
103
  """Generate config."""
@@ -1,6 +1,5 @@
1
1
  from .action import GRPCRemoteAction as GRPCRemoteAction
2
2
  from .utils import read_cert as read_cert
3
- from _typeshed import Incomplete
4
3
  from enum import StrEnum
5
4
  from grpc.aio import ClientInterceptor as ClientInterceptor
6
5
  from typing import Any, Sequence, TypedDict
@@ -40,22 +39,22 @@ class GRPCIntegration(TypedDict, total=False):
40
39
  exclude_unset: bool
41
40
 
42
41
  class GRPCConnection:
43
- name: Incomplete
44
- url: Incomplete
45
- groups: Incomplete
46
- secure: Incomplete
47
- root_certificates: Incomplete
48
- private_key: Incomplete
49
- certificate_chain: Incomplete
50
- options: Incomplete
51
- compression: Incomplete
52
- interceptors: Incomplete
53
- metadata: Incomplete
54
- allow_exec: Incomplete
55
- manual_enable: Incomplete
56
- allowed_actions: Incomplete
57
- remote_action_class: Incomplete
58
- exclude_unset: Incomplete
59
- require_integration: Incomplete
42
+ name: str
43
+ url: str
44
+ groups: list[str]
45
+ secure: bool
46
+ root_certificates: str | bytes | None
47
+ private_key: str | bytes | None
48
+ certificate_chain: str | bytes | None
49
+ options: list[tuple[str, Any]] | None
50
+ compression: GRPCCompression | None
51
+ interceptors: Sequence[ClientInterceptor] | None
52
+ metadata: dict[str, Any] | None
53
+ allow_exec: bool
54
+ manual_enable: bool
55
+ allowed_actions: dict[str, bool]
56
+ remote_action_class: type['GRPCRemoteAction'] | None
57
+ exclude_unset: bool
58
+ require_integration: bool
60
59
  def __init__(self, name: str, url: str = '', groups: list[str] | None = None, secure: bool = False, root_certificates: str | bytes | None = None, private_key: str | bytes | None = None, certificate_chain: str | bytes | None = None, options: list[tuple[str, Any]] | None = None, compression: GRPCCompression | None = None, interceptors: Sequence[ClientInterceptor] | None = None, metadata: dict[str, Any] | None = None, allow_exec: bool = False, manual_enable: bool = False, allowed_actions: dict[str, bool] | None = None, remote_action_class: type['GRPCRemoteAction'] | None = None, exclude_unset: bool = True, require_integration: bool = True) -> None: ...
61
60
  async def get_config(self, override: GRPCConfig | None) -> GRPCConfigLoaded: ...
@@ -6,11 +6,11 @@ class GRPCRemoteError(Exception):
6
6
 
7
7
  def __init__(self, cls: str, alias: str, type: str, message: str, tracebacks: list[str]) -> None:
8
8
  """Initialize Error."""
9
- self.cls = cls
10
- self.alias = alias
11
- self.type = type
12
- self.message = message
13
- self.tracebacks = tracebacks
9
+ self.cls: str = cls
10
+ self.alias: str = alias
11
+ self.type: str = type
12
+ self.message: str = message
13
+ self.tracebacks: list[str] = tracebacks
14
14
 
15
15
  super().__init__(cls, alias, type, message, tracebacks)
16
16
 
@@ -1,10 +1,8 @@
1
- from _typeshed import Incomplete
2
-
3
1
  class GRPCRemoteError(Exception):
4
- cls: Incomplete
5
- alias: Incomplete
6
- type: Incomplete
7
- message: Incomplete
8
- tracebacks: Incomplete
2
+ cls: str
3
+ alias: str
4
+ type: str
5
+ message: str
6
+ tracebacks: list[str]
9
7
  def __init__(self, cls: str, alias: str, type: str, message: str, tracebacks: list[str]) -> None: ...
10
8
  def __str__(self) -> str: ...
@@ -1,7 +1,7 @@
1
1
  """PyBotchi GRPC Handler."""
2
2
 
3
3
  from asyncio import Queue, create_task
4
- from collections.abc import AsyncGenerator, Awaitable
4
+ from collections.abc import AsyncGenerator, AsyncIterator, Awaitable
5
5
  from itertools import islice
6
6
  from sys import exc_info
7
7
  from traceback import format_exception
@@ -39,16 +39,16 @@ class PyBotchiGRPC(PyBotchiGRPCServicer, Generic[TContext]):
39
39
 
40
40
  def __init__(self, id: str, module: str, groups: dict[str, dict[str, type[Action]]]) -> None:
41
41
  """Initialize Handler."""
42
- self.id = id
43
- self.module = module
44
- self.groups = groups
45
- self.__has_validate_metadata__ = self.__class__.validate_metadata is not PyBotchiGRPC.validate_metadata
42
+ self.id: str = id
43
+ self.module: str = module
44
+ self.groups: dict[str, dict[str, type[Action]]] = groups
45
+ self.__has_validate_metadata__: bool = self.__class__.validate_metadata is not PyBotchiGRPC.validate_metadata
46
46
 
47
47
  async def validate_metadata(self, metadata: Metadata | None) -> None:
48
48
  """Validate invocation metadata."""
49
49
  pass
50
50
 
51
- async def consume(self, context: TContext, groups: list[str], events: AsyncGenerator[Event, None]) -> None:
51
+ async def consume(self, context: TContext, groups: list[str], events: AsyncIterator[Event]) -> None:
52
52
  """Consume event."""
53
53
  try:
54
54
  async for event in events:
@@ -133,7 +133,7 @@ class PyBotchiGRPC(PyBotchiGRPCServicer, Generic[TContext]):
133
133
  if isinstance(ret, Awaitable):
134
134
  await ret
135
135
 
136
- async def accept(self, events: AsyncGenerator[Event, None], context: ServicerContext) -> Queue[Event]:
136
+ async def accept(self, events: AsyncIterator[Event], context: ServicerContext) -> Queue[Event]:
137
137
  """Accept connect execution."""
138
138
  event = await anext(events)
139
139
  if event.name != "init" or not event.data:
@@ -156,7 +156,7 @@ class PyBotchiGRPC(PyBotchiGRPCServicer, Generic[TContext]):
156
156
  ##############################################################################################
157
157
 
158
158
  async def execute_connect(
159
- self, request_iterator: AsyncGenerator[Event, None], context: ServicerContext
159
+ self, request_iterator: AsyncIterator[Event], context: ServicerContext
160
160
  ) -> AsyncGenerator[Event, None]:
161
161
  """Execute `connect` method."""
162
162
  queue = await self.accept(request_iterator, context)
@@ -172,7 +172,7 @@ class PyBotchiGRPC(PyBotchiGRPCServicer, Generic[TContext]):
172
172
  ##############################################################################################
173
173
 
174
174
  async def connect(
175
- self, request_iterator: AsyncGenerator[Event, None], context: ServicerContext
175
+ self, request_iterator: AsyncIterator[Event], context: ServicerContext
176
176
  ) -> AsyncGenerator[Event, None]:
177
177
  """Consume `connect` method."""
178
178
  if self.__has_validate_metadata__ and self.validate_metadata(context.invocation_metadata()):
@@ -6,26 +6,25 @@ from .context import GRPCContext as GRPCContext, TContext as TContext
6
6
  from .exception import GRPCRemoteError as GRPCRemoteError
7
7
  from .pybotchi_pb2 import ActionListRequest as ActionListRequest, ActionListResponse as ActionListResponse, ActionSchema as ActionSchema, Edge as Edge, Event as Event, JSONSchema as JSONSchema, TraverseGraph as TraverseGraph, TraverseRequest as TraverseRequest
8
8
  from .pybotchi_pb2_grpc import PyBotchiGRPCServicer as PyBotchiGRPCServicer
9
- from _typeshed import Incomplete
10
9
  from asyncio import Queue
11
- from collections.abc import AsyncGenerator
10
+ from collections.abc import AsyncGenerator, AsyncIterator
12
11
  from grpc.aio import Metadata as Metadata, ServicerContext as ServicerContext
13
12
  from typing import Generic
14
13
 
15
14
  class PyBotchiGRPC(PyBotchiGRPCServicer, Generic[TContext]):
16
15
  __context_class__: type[TContext]
17
16
  __allow_exec__: bool
18
- id: Incomplete
19
- module: Incomplete
20
- groups: Incomplete
21
- __has_validate_metadata__: Incomplete
17
+ id: str
18
+ module: str
19
+ groups: dict[str, dict[str, type[Action]]]
20
+ __has_validate_metadata__: bool
22
21
  def __init__(self, id: str, module: str, groups: dict[str, dict[str, type[Action]]]) -> None: ...
23
22
  async def validate_metadata(self, metadata: Metadata | None) -> None: ...
24
- async def consume(self, context: TContext, groups: list[str], events: AsyncGenerator[Event, None]) -> None: ...
23
+ async def consume(self, context: TContext, groups: list[str], events: AsyncIterator[Event]) -> None: ...
25
24
  async def grpc_event_execute(self, context: TContext, groups: list[str], event: Event) -> None: ...
26
25
  async def grpc_event_update(self, context: TContext, groups: list[str], event: Event) -> None: ...
27
- async def accept(self, events: AsyncGenerator[Event, None], context: ServicerContext) -> Queue[Event]: ...
28
- async def execute_connect(self, request_iterator: AsyncGenerator[Event, None], context: ServicerContext) -> AsyncGenerator[Event, None]: ...
29
- async def connect(self, request_iterator: AsyncGenerator[Event, None], context: ServicerContext) -> AsyncGenerator[Event, None]: ...
26
+ async def accept(self, events: AsyncIterator[Event], context: ServicerContext) -> Queue[Event]: ...
27
+ async def execute_connect(self, request_iterator: AsyncIterator[Event], context: ServicerContext) -> AsyncGenerator[Event, None]: ...
28
+ async def connect(self, request_iterator: AsyncIterator[Event], context: ServicerContext) -> AsyncGenerator[Event, None]: ...
30
29
  async def action_list(self, request: ActionListRequest, context: ServicerContext) -> ActionListResponse: ...
31
30
  async def traverse(self, request: TraverseRequest, context: ServicerContext) -> TraverseGraph: ...
@@ -0,0 +1,165 @@
1
+ from google.protobuf import struct_pb2 as _struct_pb2
2
+ from google.protobuf.internal import containers as _containers
3
+ from google.protobuf import descriptor as _descriptor
4
+ from google.protobuf import message as _message
5
+ from collections.abc import Iterable as _Iterable, Mapping as _Mapping
6
+ from typing import ClassVar as _ClassVar, Optional as _Optional, Union as _Union
7
+
8
+ DESCRIPTOR: _descriptor.FileDescriptor
9
+
10
+ class Event(_message.Message):
11
+ __slots__ = ("name", "data")
12
+ NAME_FIELD_NUMBER: _ClassVar[int]
13
+ DATA_FIELD_NUMBER: _ClassVar[int]
14
+ name: str
15
+ data: _struct_pb2.Struct
16
+ def __init__(self, name: _Optional[str] = ..., data: _Optional[_Union[_struct_pb2.Struct, _Mapping]] = ...) -> None: ...
17
+
18
+ class ActionListRequest(_message.Message):
19
+ __slots__ = ("groups", "allowed_actions")
20
+ class AllowedActionsEntry(_message.Message):
21
+ __slots__ = ("key", "value")
22
+ KEY_FIELD_NUMBER: _ClassVar[int]
23
+ VALUE_FIELD_NUMBER: _ClassVar[int]
24
+ key: str
25
+ value: bool
26
+ def __init__(self, key: _Optional[str] = ..., value: bool = ...) -> None: ...
27
+ GROUPS_FIELD_NUMBER: _ClassVar[int]
28
+ ALLOWED_ACTIONS_FIELD_NUMBER: _ClassVar[int]
29
+ groups: _containers.RepeatedScalarFieldContainer[str]
30
+ allowed_actions: _containers.ScalarMap[str, bool]
31
+ def __init__(self, groups: _Optional[_Iterable[str]] = ..., allowed_actions: _Optional[_Mapping[str, bool]] = ...) -> None: ...
32
+
33
+ class ActionListResponse(_message.Message):
34
+ __slots__ = ("agent_id", "actions")
35
+ AGENT_ID_FIELD_NUMBER: _ClassVar[int]
36
+ ACTIONS_FIELD_NUMBER: _ClassVar[int]
37
+ agent_id: str
38
+ actions: _containers.RepeatedCompositeFieldContainer[ActionSchema]
39
+ def __init__(self, agent_id: _Optional[str] = ..., actions: _Optional[_Iterable[_Union[ActionSchema, _Mapping]]] = ...) -> None: ...
40
+
41
+ class ActionSchema(_message.Message):
42
+ __slots__ = ("concurrent", "group", "schema")
43
+ CONCURRENT_FIELD_NUMBER: _ClassVar[int]
44
+ GROUP_FIELD_NUMBER: _ClassVar[int]
45
+ SCHEMA_FIELD_NUMBER: _ClassVar[int]
46
+ concurrent: bool
47
+ group: str
48
+ schema: JSONSchema
49
+ def __init__(self, concurrent: bool = ..., group: _Optional[str] = ..., schema: _Optional[_Union[JSONSchema, _Mapping]] = ...) -> None: ...
50
+
51
+ class JSONSchema(_message.Message):
52
+ __slots__ = ("schema", "id", "title", "description", "type", "properties", "required", "additional_properties", "items", "min_items", "max_items", "min_length", "max_length", "pattern", "format", "minimum", "maximum", "multiple_of", "enum", "default_value", "definitions", "ref", "all_of", "any_of", "one_of")
53
+ class PropertiesEntry(_message.Message):
54
+ __slots__ = ("key", "value")
55
+ KEY_FIELD_NUMBER: _ClassVar[int]
56
+ VALUE_FIELD_NUMBER: _ClassVar[int]
57
+ key: str
58
+ value: JSONSchema
59
+ def __init__(self, key: _Optional[str] = ..., value: _Optional[_Union[JSONSchema, _Mapping]] = ...) -> None: ...
60
+ class DefinitionsEntry(_message.Message):
61
+ __slots__ = ("key", "value")
62
+ KEY_FIELD_NUMBER: _ClassVar[int]
63
+ VALUE_FIELD_NUMBER: _ClassVar[int]
64
+ key: str
65
+ value: JSONSchema
66
+ def __init__(self, key: _Optional[str] = ..., value: _Optional[_Union[JSONSchema, _Mapping]] = ...) -> None: ...
67
+ SCHEMA_FIELD_NUMBER: _ClassVar[int]
68
+ ID_FIELD_NUMBER: _ClassVar[int]
69
+ TITLE_FIELD_NUMBER: _ClassVar[int]
70
+ DESCRIPTION_FIELD_NUMBER: _ClassVar[int]
71
+ TYPE_FIELD_NUMBER: _ClassVar[int]
72
+ PROPERTIES_FIELD_NUMBER: _ClassVar[int]
73
+ REQUIRED_FIELD_NUMBER: _ClassVar[int]
74
+ ADDITIONAL_PROPERTIES_FIELD_NUMBER: _ClassVar[int]
75
+ ITEMS_FIELD_NUMBER: _ClassVar[int]
76
+ MIN_ITEMS_FIELD_NUMBER: _ClassVar[int]
77
+ MAX_ITEMS_FIELD_NUMBER: _ClassVar[int]
78
+ MIN_LENGTH_FIELD_NUMBER: _ClassVar[int]
79
+ MAX_LENGTH_FIELD_NUMBER: _ClassVar[int]
80
+ PATTERN_FIELD_NUMBER: _ClassVar[int]
81
+ FORMAT_FIELD_NUMBER: _ClassVar[int]
82
+ MINIMUM_FIELD_NUMBER: _ClassVar[int]
83
+ MAXIMUM_FIELD_NUMBER: _ClassVar[int]
84
+ MULTIPLE_OF_FIELD_NUMBER: _ClassVar[int]
85
+ ENUM_FIELD_NUMBER: _ClassVar[int]
86
+ DEFAULT_VALUE_FIELD_NUMBER: _ClassVar[int]
87
+ DEFINITIONS_FIELD_NUMBER: _ClassVar[int]
88
+ REF_FIELD_NUMBER: _ClassVar[int]
89
+ ALL_OF_FIELD_NUMBER: _ClassVar[int]
90
+ ANY_OF_FIELD_NUMBER: _ClassVar[int]
91
+ ONE_OF_FIELD_NUMBER: _ClassVar[int]
92
+ NOT_FIELD_NUMBER: _ClassVar[int]
93
+ schema: str
94
+ id: str
95
+ title: str
96
+ description: str
97
+ type: str
98
+ properties: _containers.MessageMap[str, JSONSchema]
99
+ required: _containers.RepeatedScalarFieldContainer[str]
100
+ additional_properties: bool
101
+ items: JSONSchema
102
+ min_items: int
103
+ max_items: int
104
+ min_length: int
105
+ max_length: int
106
+ pattern: str
107
+ format: str
108
+ minimum: float
109
+ maximum: float
110
+ multiple_of: float
111
+ enum: _containers.RepeatedScalarFieldContainer[str]
112
+ default_value: str
113
+ definitions: _containers.MessageMap[str, JSONSchema]
114
+ ref: str
115
+ all_of: _containers.RepeatedCompositeFieldContainer[JSONSchema]
116
+ any_of: _containers.RepeatedCompositeFieldContainer[JSONSchema]
117
+ one_of: _containers.RepeatedCompositeFieldContainer[JSONSchema]
118
+ def __init__(self, schema: _Optional[str] = ..., id: _Optional[str] = ..., title: _Optional[str] = ..., description: _Optional[str] = ..., type: _Optional[str] = ..., properties: _Optional[_Mapping[str, JSONSchema]] = ..., required: _Optional[_Iterable[str]] = ..., additional_properties: bool = ..., items: _Optional[_Union[JSONSchema, _Mapping]] = ..., min_items: _Optional[int] = ..., max_items: _Optional[int] = ..., min_length: _Optional[int] = ..., max_length: _Optional[int] = ..., pattern: _Optional[str] = ..., format: _Optional[str] = ..., minimum: _Optional[float] = ..., maximum: _Optional[float] = ..., multiple_of: _Optional[float] = ..., enum: _Optional[_Iterable[str]] = ..., default_value: _Optional[str] = ..., definitions: _Optional[_Mapping[str, JSONSchema]] = ..., ref: _Optional[str] = ..., all_of: _Optional[_Iterable[_Union[JSONSchema, _Mapping]]] = ..., any_of: _Optional[_Iterable[_Union[JSONSchema, _Mapping]]] = ..., one_of: _Optional[_Iterable[_Union[JSONSchema, _Mapping]]] = ..., **kwargs) -> None: ...
119
+
120
+ class TraverseRequest(_message.Message):
121
+ __slots__ = ("nodes", "alias", "groups", "name", "allowed_actions", "integrations", "bypass")
122
+ class AllowedActionsEntry(_message.Message):
123
+ __slots__ = ("key", "value")
124
+ KEY_FIELD_NUMBER: _ClassVar[int]
125
+ VALUE_FIELD_NUMBER: _ClassVar[int]
126
+ key: str
127
+ value: bool
128
+ def __init__(self, key: _Optional[str] = ..., value: bool = ...) -> None: ...
129
+ NODES_FIELD_NUMBER: _ClassVar[int]
130
+ ALIAS_FIELD_NUMBER: _ClassVar[int]
131
+ GROUPS_FIELD_NUMBER: _ClassVar[int]
132
+ NAME_FIELD_NUMBER: _ClassVar[int]
133
+ ALLOWED_ACTIONS_FIELD_NUMBER: _ClassVar[int]
134
+ INTEGRATIONS_FIELD_NUMBER: _ClassVar[int]
135
+ BYPASS_FIELD_NUMBER: _ClassVar[int]
136
+ nodes: _containers.RepeatedScalarFieldContainer[str]
137
+ alias: str
138
+ groups: _containers.RepeatedScalarFieldContainer[str]
139
+ name: str
140
+ allowed_actions: _containers.ScalarMap[str, bool]
141
+ integrations: _struct_pb2.Struct
142
+ bypass: bool
143
+ def __init__(self, nodes: _Optional[_Iterable[str]] = ..., alias: _Optional[str] = ..., groups: _Optional[_Iterable[str]] = ..., name: _Optional[str] = ..., allowed_actions: _Optional[_Mapping[str, bool]] = ..., integrations: _Optional[_Union[_struct_pb2.Struct, _Mapping]] = ..., bypass: bool = ...) -> None: ...
144
+
145
+ class TraverseGraph(_message.Message):
146
+ __slots__ = ("origin", "nodes", "edges")
147
+ ORIGIN_FIELD_NUMBER: _ClassVar[int]
148
+ NODES_FIELD_NUMBER: _ClassVar[int]
149
+ EDGES_FIELD_NUMBER: _ClassVar[int]
150
+ origin: str
151
+ nodes: _containers.RepeatedScalarFieldContainer[str]
152
+ edges: _containers.RepeatedCompositeFieldContainer[Edge]
153
+ def __init__(self, origin: _Optional[str] = ..., nodes: _Optional[_Iterable[str]] = ..., edges: _Optional[_Iterable[_Union[Edge, _Mapping]]] = ...) -> None: ...
154
+
155
+ class Edge(_message.Message):
156
+ __slots__ = ("source", "target", "concurrent", "name")
157
+ SOURCE_FIELD_NUMBER: _ClassVar[int]
158
+ TARGET_FIELD_NUMBER: _ClassVar[int]
159
+ CONCURRENT_FIELD_NUMBER: _ClassVar[int]
160
+ NAME_FIELD_NUMBER: _ClassVar[int]
161
+ source: str
162
+ target: str
163
+ concurrent: bool
164
+ name: str
165
+ def __init__(self, source: _Optional[str] = ..., target: _Optional[str] = ..., concurrent: bool = ..., name: _Optional[str] = ...) -> None: ...
@@ -5,7 +5,7 @@ import warnings
5
5
 
6
6
  from . import pybotchi_pb2 as pybotchi__pb2
7
7
 
8
- GRPC_GENERATED_VERSION = '1.76.0'
8
+ GRPC_GENERATED_VERSION = '1.80.0'
9
9
  GRPC_VERSION = grpc.__version__
10
10
  _version_not_supported = False
11
11
 
@@ -0,0 +1,67 @@
1
+ """
2
+ @generated by mypy-protobuf. Do not edit manually!
3
+ isort:skip_file
4
+ """
5
+
6
+ from collections import abc as _abc
7
+ from grpc import aio as _aio
8
+ import abc as _abc_1
9
+ import grpc as _grpc
10
+ import pybotchi_pb2 as _pybotchi_pb2
11
+ import sys
12
+ import typing as _typing
13
+
14
+ if sys.version_info >= (3, 11):
15
+ from typing import Self as _Self
16
+ else:
17
+ from typing_extensions import Self as _Self
18
+
19
+ _T = _typing.TypeVar("_T")
20
+
21
+ class _MaybeAsyncIterator(_abc.AsyncIterator[_T], _abc.Iterator[_T], metaclass=_abc_1.ABCMeta): ...
22
+
23
+ class _ServicerContext(_grpc.ServicerContext, _aio.ServicerContext): # type: ignore[misc, type-arg]
24
+ ...
25
+
26
+ GRPC_GENERATED_VERSION: str
27
+ GRPC_VERSION: str
28
+
29
+ class PyBotchiGRPCStub:
30
+ @_typing.overload
31
+ def __new__(cls, channel: _grpc.Channel) -> _Self: ...
32
+ @_typing.overload
33
+ def __new__(cls, channel: _aio.Channel) -> PyBotchiGRPCAsyncStub: ...
34
+ connect: _grpc.StreamStreamMultiCallable[_pybotchi_pb2.Event, _pybotchi_pb2.Event]
35
+ action_list: _grpc.UnaryUnaryMultiCallable[_pybotchi_pb2.ActionListRequest, _pybotchi_pb2.ActionListResponse]
36
+ traverse: _grpc.UnaryUnaryMultiCallable[_pybotchi_pb2.TraverseRequest, _pybotchi_pb2.TraverseGraph]
37
+
38
+ @_typing.type_check_only
39
+ class PyBotchiGRPCAsyncStub(PyBotchiGRPCStub):
40
+ def __init__(self, channel: _aio.Channel) -> None: ...
41
+ connect: _aio.StreamStreamMultiCallable[_pybotchi_pb2.Event, _pybotchi_pb2.Event] # type: ignore[assignment]
42
+ action_list: _aio.UnaryUnaryMultiCallable[_pybotchi_pb2.ActionListRequest, _pybotchi_pb2.ActionListResponse] # type: ignore[assignment]
43
+ traverse: _aio.UnaryUnaryMultiCallable[_pybotchi_pb2.TraverseRequest, _pybotchi_pb2.TraverseGraph] # type: ignore[assignment]
44
+
45
+ class PyBotchiGRPCServicer(metaclass=_abc_1.ABCMeta):
46
+ @_abc_1.abstractmethod
47
+ def connect(
48
+ self,
49
+ request_iterator: _MaybeAsyncIterator[_pybotchi_pb2.Event],
50
+ context: _ServicerContext,
51
+ ) -> _typing.Union[_abc.Iterator[_pybotchi_pb2.Event], _abc.AsyncIterator[_pybotchi_pb2.Event]]: ...
52
+
53
+ @_abc_1.abstractmethod
54
+ def action_list(
55
+ self,
56
+ request: _pybotchi_pb2.ActionListRequest,
57
+ context: _ServicerContext,
58
+ ) -> _typing.Union[_pybotchi_pb2.ActionListResponse, _abc.Awaitable[_pybotchi_pb2.ActionListResponse]]: ...
59
+
60
+ @_abc_1.abstractmethod
61
+ def traverse(
62
+ self,
63
+ request: _pybotchi_pb2.TraverseRequest,
64
+ context: _ServicerContext,
65
+ ) -> _typing.Union[_pybotchi_pb2.TraverseGraph, _abc.Awaitable[_pybotchi_pb2.TraverseGraph]]: ...
66
+
67
+ def add_PyBotchiGRPCServicer_to_server(servicer: PyBotchiGRPCServicer, server: _typing.Union[_grpc.Server, _aio.Server]) -> None: ...
@@ -1,6 +1,6 @@
1
1
  """Pybotchi MCP Classes."""
2
2
 
3
- from collections.abc import AsyncGenerator, Awaitable
3
+ from collections.abc import AsyncGenerator, AsyncIterator, Awaitable
4
4
  from contextlib import AsyncExitStack, asynccontextmanager, suppress
5
5
  from inspect import getdoc, getmembers
6
6
  from itertools import islice
@@ -8,7 +8,7 @@ from os import getenv
8
8
  from typing import Any, Callable, Generic, Literal
9
9
 
10
10
  from datamodel_code_generator import DataModelType, Formatter, PythonVersion
11
- from datamodel_code_generator.model import get_data_model_types
11
+ from datamodel_code_generator.model import DataModelSet, get_data_model_types
12
12
  from datamodel_code_generator.parser.base import title_to_class_name
13
13
  from datamodel_code_generator.parser.jsonschema import (
14
14
  JsonSchemaParser,
@@ -42,7 +42,7 @@ from ..action import Action, ChildActions
42
42
  from ..common import ActionReturn, ChatRole, Graph
43
43
  from ..utils import is_camel_case, unwrap_exceptions
44
44
 
45
- DMT = get_data_model_types(
45
+ DMT: DataModelSet = get_data_model_types(
46
46
  DataModelType.PydanticV2BaseModel,
47
47
  target_python_version=PythonVersion.PY_313,
48
48
  )
@@ -62,13 +62,13 @@ class MCPClient:
62
62
  exclude_unset: bool,
63
63
  ) -> None:
64
64
  """Build MCP Client."""
65
- self.session = session
66
- self.name = name
67
- self.config = config
68
- self.manual_enable = manual_enable
69
- self.allowed_tools = allowed_tools
70
- self.tool_action_class = tool_action_class or MCPToolAction
71
- self.exclude_unset = exclude_unset
65
+ self.session: ClientSession = session
66
+ self.name: str = name
67
+ self.config: MCPConfig = config
68
+ self.manual_enable: bool = manual_enable
69
+ self.allowed_tools: dict[str, bool] = allowed_tools
70
+ self.tool_action_class: type["MCPToolAction"] = tool_action_class or MCPToolAction
71
+ self.exclude_unset: bool = exclude_unset
72
72
 
73
73
  def build_tool(self, tool: Tool) -> tuple[str, type["MCPToolAction"]]:
74
74
  """Build MCPToolAction."""
@@ -142,7 +142,7 @@ class MCPClient:
142
142
  return actions
143
143
 
144
144
 
145
- class MCPAction(Action[TContext], Generic[TContext]):
145
+ class MCPAction(Action[TContext]):
146
146
  """MCP Action."""
147
147
 
148
148
  __mcp_servers__: dict[str, FastMCP] = {}
@@ -179,7 +179,7 @@ class MCPAction(Action[TContext], Generic[TContext]):
179
179
 
180
180
  async def execute(self, context: TContext, parent: Action | None = None, append: bool = True) -> ActionReturn:
181
181
  """Execute main process."""
182
- self._parent = parent
182
+ self._parent: Action | None = parent
183
183
  parent_context = context
184
184
  try:
185
185
  if parent and append:
@@ -367,7 +367,7 @@ async def multi_mcp_clients(
367
367
  integrations: dict[str, MCPIntegration],
368
368
  connections: list[MCPConnection],
369
369
  bypass: bool = False,
370
- ) -> AsyncGenerator[dict[str, MCPClient], None]:
370
+ ) -> AsyncIterator[dict[str, MCPClient]]:
371
371
  """Connect to multiple mcp clients."""
372
372
  async with AsyncExitStack() as stack:
373
373
  clients: dict[str, MCPClient] = {}
@@ -3,9 +3,9 @@ from ..common import ActionReturn as ActionReturn, ChatRole as ChatRole, Graph a
3
3
  from ..utils import is_camel_case as is_camel_case, unwrap_exceptions as unwrap_exceptions
4
4
  from .common import MCPConfig as MCPConfig, MCPConnection as MCPConnection, MCPIntegration as MCPIntegration, MCPMode as MCPMode
5
5
  from .context import TContext as TContext
6
- from _typeshed import Incomplete
7
- from collections.abc import AsyncGenerator, Awaitable
6
+ from collections.abc import AsyncGenerator, AsyncIterator, Awaitable
8
7
  from contextlib import AsyncExitStack, asynccontextmanager
8
+ from datamodel_code_generator.model import DataModelSet as DataModelSet
9
9
  from mcp import ClientSession, Tool as Tool
10
10
  from mcp.server.fastmcp import FastMCP
11
11
  from mcp.shared.session import ProgressFnT as ProgressFnT
@@ -13,21 +13,21 @@ from mcp.types import ContentBlock as ContentBlock
13
13
  from starlette.applications import AppType as AppType, Starlette
14
14
  from typing import Any, Callable, Generic, Literal
15
15
 
16
- DMT: Incomplete
16
+ DMT: DataModelSet
17
17
 
18
18
  class MCPClient:
19
- session: Incomplete
20
- name: Incomplete
21
- config: Incomplete
22
- manual_enable: Incomplete
23
- allowed_tools: Incomplete
24
- tool_action_class: Incomplete
25
- exclude_unset: Incomplete
19
+ session: ClientSession
20
+ name: str
21
+ config: MCPConfig
22
+ manual_enable: bool
23
+ allowed_tools: dict[str, bool]
24
+ tool_action_class: type['MCPToolAction']
25
+ exclude_unset: bool
26
26
  def __init__(self, session: ClientSession, name: str, config: MCPConfig, manual_enable: bool, allowed_tools: dict[str, bool], tool_action_class: type['MCPToolAction'] | None, exclude_unset: bool) -> None: ...
27
27
  def build_tool(self, tool: Tool) -> tuple[str, type['MCPToolAction']]: ...
28
28
  async def patch_tools(self, actions: ChildActions, mcp_actions: ChildActions) -> ChildActions: ...
29
29
 
30
- class MCPAction(Action[TContext], Generic[TContext]):
30
+ class MCPAction(Action[TContext]):
31
31
  __mcp_servers__: dict[str, FastMCP]
32
32
  __mcp_clients__: dict[str, MCPClient]
33
33
  __mcp_connections__: list[MCPConnection]
@@ -38,7 +38,7 @@ class MCPAction(Action[TContext], Generic[TContext]):
38
38
  @classmethod
39
39
  def __init_child_actions__(cls) -> None: ...
40
40
  async def pre_mcp(self, context: TContext) -> ActionReturn: ...
41
- _parent: Incomplete
41
+ _parent: Action | None
42
42
  __to_commit__: bool
43
43
  async def execute(self, context: TContext, parent: Action | None = None, append: bool = True) -> ActionReturn: ...
44
44
  async def get_child_actions(self, context: TContext) -> ChildActions: ...
@@ -55,7 +55,7 @@ class MCPToolAction(Action[TContext], Generic[TContext]):
55
55
  async def pre(self, context: TContext) -> ActionReturn: ...
56
56
 
57
57
  @asynccontextmanager
58
- async def multi_mcp_clients(integrations: dict[str, MCPIntegration], connections: list[MCPConnection], bypass: bool = False) -> AsyncGenerator[dict[str, MCPClient], None]: ...
58
+ async def multi_mcp_clients(integrations: dict[str, MCPIntegration], connections: list[MCPConnection], bypass: bool = False) -> AsyncIterator[dict[str, MCPClient]]: ...
59
59
  def initialize_mcp_groups() -> None: ...
60
60
  @asynccontextmanager
61
61
  async def mount_mcp_app(app: AppType, *groups: str, transport: Literal['sse', 'streamable-http'] | dict[str, str] = 'streamable-http') -> AsyncGenerator[AsyncExitStack, None]: ...
@@ -91,22 +91,22 @@ class MCPConnection:
91
91
  require_integration: bool = True,
92
92
  ) -> None:
93
93
  """Build MCP Connection."""
94
- self.name = name
95
- self.mode = mode
96
- self.url = url
97
- self.headers = headers
98
- self.timeout = timeout
99
- self.sse_read_timeout = sse_read_timeout
100
- self.terminate_on_close = terminate_on_close
101
- self.httpx_client_factory = httpx_client_factory
102
- self.auth = auth
103
- self.on_session_created = on_session_created
94
+ self.name: str = name
95
+ self.mode: MCPMode | Literal["SSE", "SHTTP"] = mode
96
+ self.url: str = url
97
+ self.headers: dict[str, str] | None = headers
98
+ self.timeout: float = timeout
99
+ self.sse_read_timeout: float = sse_read_timeout
100
+ self.terminate_on_close: bool = terminate_on_close
101
+ self.httpx_client_factory: McpHttpClientFactory = httpx_client_factory
102
+ self.auth: Auth | None = auth
103
+ self.on_session_created: Callable[[str], None] | None = on_session_created
104
104
  self.async_client_args: AsyncClientArgs = {} if async_client_args is None else async_client_args
105
- self.manual_enable = manual_enable
106
- self.allowed_tools = {} if allowed_tools is None else allowed_tools
107
- self.tool_action_class = tool_action_class
108
- self.exclude_unset = exclude_unset
109
- self.require_integration = require_integration
105
+ self.manual_enable: bool = manual_enable
106
+ self.allowed_tools: dict[str, bool] = {} if allowed_tools is None else allowed_tools
107
+ self.tool_action_class: type["MCPToolAction"] | None = tool_action_class
108
+ self.exclude_unset: bool = exclude_unset
109
+ self.require_integration: bool = require_integration
110
110
 
111
111
  def get_config(self, override: MCPConfig | None) -> MCPConfig:
112
112
  """Generate config."""
@@ -1,5 +1,4 @@
1
1
  from .action import MCPToolAction as MCPToolAction
2
- from _typeshed import Incomplete
3
2
  from collections.abc import Callable as Callable, Mapping, Sequence
4
3
  from enum import StrEnum
5
4
  from httpx import Auth as Auth
@@ -41,21 +40,21 @@ class MCPIntegration(TypedDict, total=False):
41
40
  exclude_unset: bool
42
41
 
43
42
  class MCPConnection:
44
- name: Incomplete
45
- mode: Incomplete
46
- url: Incomplete
47
- headers: Incomplete
48
- timeout: Incomplete
49
- sse_read_timeout: Incomplete
50
- terminate_on_close: Incomplete
51
- httpx_client_factory: Incomplete
52
- auth: Incomplete
53
- on_session_created: Incomplete
43
+ name: str
44
+ mode: MCPMode | Literal['SSE', 'SHTTP']
45
+ url: str
46
+ headers: dict[str, str] | None
47
+ timeout: float
48
+ sse_read_timeout: float
49
+ terminate_on_close: bool
50
+ httpx_client_factory: McpHttpClientFactory
51
+ auth: Auth | None
52
+ on_session_created: Callable[[str], None] | None
54
53
  async_client_args: AsyncClientArgs
55
- manual_enable: Incomplete
56
- allowed_tools: Incomplete
57
- tool_action_class: Incomplete
58
- exclude_unset: Incomplete
59
- require_integration: Incomplete
54
+ manual_enable: bool
55
+ allowed_tools: dict[str, bool]
56
+ tool_action_class: type['MCPToolAction'] | None
57
+ exclude_unset: bool
58
+ require_integration: bool
60
59
  def __init__(self, name: str, mode: MCPMode | Literal['SSE', 'SHTTP'], url: str = '', headers: dict[str, str] | None = None, timeout: float = 5.0, sse_read_timeout: float = 300.0, terminate_on_close: bool = True, httpx_client_factory: McpHttpClientFactory = ..., auth: Auth | None = None, on_session_created: Callable[[str], None] | None = None, async_client_args: AsyncClientArgs | None = None, manual_enable: bool = False, allowed_tools: dict[str, bool] | None = None, tool_action_class: type['MCPToolAction'] | None = None, exclude_unset: bool = True, require_integration: bool = True) -> None: ...
61
60
  def get_config(self, override: MCPConfig | None) -> MCPConfig: ...
@@ -4,14 +4,14 @@ from collections import deque
4
4
  from collections.abc import Generator
5
5
  from contextlib import suppress
6
6
  from importlib import import_module
7
- from re import compile
7
+ from re import Pattern, compile
8
8
  from typing import Any, Callable
9
9
  from uuid import UUID
10
10
 
11
11
  from orjson import loads
12
12
 
13
- PLACEHOLDERS = compile(r"(\${\s*([^:\s]+)\s*(?:\:\s*([\S\s]*?))?\s*})")
14
- CAMEL_CASE = compile(r"^[a-z]+(?:[A-Z][a-z0-9]*)*$")
13
+ PLACEHOLDERS: Pattern = compile(r"(\${\s*([^:\s]+)\s*(?:\:\s*([\S\s]*?))?\s*})")
14
+ CAMEL_CASE: Pattern = compile(r"^[a-z]+(?:[A-Z][a-z0-9]*)*$")
15
15
 
16
16
 
17
17
  def apply_placeholders(target: str, **placeholders: Any) -> str:
@@ -1,10 +1,10 @@
1
- from _typeshed import Incomplete
2
1
  from collections.abc import Generator
2
+ from re import Pattern
3
3
  from typing import Any, Callable
4
4
  from uuid import UUID
5
5
 
6
- PLACEHOLDERS: Incomplete
7
- CAMEL_CASE: Incomplete
6
+ PLACEHOLDERS: Pattern
7
+ CAMEL_CASE: Pattern
8
8
 
9
9
  def apply_placeholders(target: str, **placeholders: Any) -> str: ...
10
10
  def is_camel_case(data: str) -> bool: ...
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "pybotchi"
3
- version = "3.4.2"
3
+ version = "3.4.4"
4
4
  description = "A deterministic, intent-based AI agent builder."
5
5
  authors = ["Alexie (Boyong) Madolid <madolid.alexie@gmail.com>"]
6
6
  readme = "README.md"
@@ -26,8 +26,8 @@ mcp = { version = ">=1.15.0", optional = true }
26
26
 
27
27
  # GRPC optional
28
28
  click = { version = ">=8.3.1", optional = true }
29
- grpcio = { version = ">=1.76.0", optional = true }
30
- grpcio-tools = { version = ">=1.76.0", optional = true }
29
+ grpcio = { version = ">=1.80.0", optional = true }
30
+ grpcio-tools = { version = ">=1.80.0", optional = true }
31
31
  aiofiles = { version = ">=25.1.0", optional = true }
32
32
 
33
33
  [tool.poetry.group.dev.dependencies]
@@ -1,5 +0,0 @@
1
- from _typeshed import Incomplete
2
-
3
- _sym_db: Incomplete
4
- DESCRIPTOR: Incomplete
5
- _globals: Incomplete
@@ -1,26 +0,0 @@
1
- from _typeshed import Incomplete
2
-
3
- GRPC_GENERATED_VERSION: str
4
- GRPC_VERSION: Incomplete
5
- _version_not_supported: bool
6
-
7
- class PyBotchiGRPCStub:
8
- connect: Incomplete
9
- action_list: Incomplete
10
- traverse: Incomplete
11
- def __init__(self, channel) -> None: ...
12
-
13
- class PyBotchiGRPCServicer:
14
- def connect(self, request_iterator, context) -> None: ...
15
- def action_list(self, request, context) -> None: ...
16
- def traverse(self, request, context) -> None: ...
17
-
18
- def add_PyBotchiGRPCServicer_to_server(servicer, server) -> None: ...
19
-
20
- class PyBotchiGRPC:
21
- @staticmethod
22
- def connect(request_iterator, target, options=(), channel_credentials=None, call_credentials=None, insecure: bool = False, compression=None, wait_for_ready=None, timeout=None, metadata=None): ...
23
- @staticmethod
24
- def action_list(request, target, options=(), channel_credentials=None, call_credentials=None, insecure: bool = False, compression=None, wait_for_ready=None, timeout=None, metadata=None): ...
25
- @staticmethod
26
- def traverse(request, target, options=(), channel_credentials=None, call_credentials=None, insecure: bool = False, compression=None, wait_for_ready=None, timeout=None, metadata=None): ...
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes