pybotchi 3.4.3__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.
- {pybotchi-3.4.3 → pybotchi-3.4.4}/PKG-INFO +3 -3
- {pybotchi-3.4.3 → pybotchi-3.4.4}/pybotchi/action.py +3 -3
- {pybotchi-3.4.3 → pybotchi-3.4.4}/pybotchi/action.pyi +3 -4
- {pybotchi-3.4.3 → pybotchi-3.4.4}/pybotchi/common.py +1 -1
- {pybotchi-3.4.3 → pybotchi-3.4.4}/pybotchi/common.pyi +1 -2
- {pybotchi-3.4.3 → pybotchi-3.4.4}/pybotchi/grpc/action.py +13 -13
- {pybotchi-3.4.3 → pybotchi-3.4.4}/pybotchi/grpc/action.pyi +13 -13
- {pybotchi-3.4.3 → pybotchi-3.4.4}/pybotchi/grpc/cli.py +2 -1
- {pybotchi-3.4.3 → pybotchi-3.4.4}/pybotchi/grpc/common.py +17 -17
- {pybotchi-3.4.3 → pybotchi-3.4.4}/pybotchi/grpc/common.pyi +17 -18
- {pybotchi-3.4.3 → pybotchi-3.4.4}/pybotchi/grpc/exception.py +5 -5
- {pybotchi-3.4.3 → pybotchi-3.4.4}/pybotchi/grpc/exception.pyi +5 -7
- {pybotchi-3.4.3 → pybotchi-3.4.4}/pybotchi/grpc/handler.py +9 -9
- {pybotchi-3.4.3 → pybotchi-3.4.4}/pybotchi/grpc/handler.pyi +9 -10
- pybotchi-3.4.4/pybotchi/grpc/pybotchi_pb2.pyi +165 -0
- {pybotchi-3.4.3 → pybotchi-3.4.4}/pybotchi/grpc/pybotchi_pb2_grpc.py +1 -1
- pybotchi-3.4.4/pybotchi/grpc/pybotchi_pb2_grpc.pyi +67 -0
- {pybotchi-3.4.3 → pybotchi-3.4.4}/pybotchi/mcp/action.py +13 -13
- {pybotchi-3.4.3 → pybotchi-3.4.4}/pybotchi/mcp/action.pyi +13 -13
- {pybotchi-3.4.3 → pybotchi-3.4.4}/pybotchi/mcp/common.py +15 -15
- {pybotchi-3.4.3 → pybotchi-3.4.4}/pybotchi/mcp/common.pyi +15 -16
- {pybotchi-3.4.3 → pybotchi-3.4.4}/pybotchi/utils.py +3 -3
- {pybotchi-3.4.3 → pybotchi-3.4.4}/pybotchi/utils.pyi +3 -3
- {pybotchi-3.4.3 → pybotchi-3.4.4}/pyproject.toml +3 -3
- pybotchi-3.4.3/pybotchi/grpc/pybotchi_pb2.pyi +0 -5
- pybotchi-3.4.3/pybotchi/grpc/pybotchi_pb2_grpc.pyi +0 -26
- {pybotchi-3.4.3 → pybotchi-3.4.4}/LICENSE +0 -0
- {pybotchi-3.4.3 → pybotchi-3.4.4}/README.md +0 -0
- {pybotchi-3.4.3 → pybotchi-3.4.4}/pybotchi/__init__.py +0 -0
- {pybotchi-3.4.3 → pybotchi-3.4.4}/pybotchi/__init__.pyi +0 -0
- {pybotchi-3.4.3 → pybotchi-3.4.4}/pybotchi/context.py +0 -0
- {pybotchi-3.4.3 → pybotchi-3.4.4}/pybotchi/context.pyi +0 -0
- {pybotchi-3.4.3 → pybotchi-3.4.4}/pybotchi/grpc/__init__.py +0 -0
- {pybotchi-3.4.3 → pybotchi-3.4.4}/pybotchi/grpc/__init__.pyi +0 -0
- {pybotchi-3.4.3 → pybotchi-3.4.4}/pybotchi/grpc/cli.pyi +0 -0
- {pybotchi-3.4.3 → pybotchi-3.4.4}/pybotchi/grpc/context.py +0 -0
- {pybotchi-3.4.3 → pybotchi-3.4.4}/pybotchi/grpc/context.pyi +0 -0
- {pybotchi-3.4.3 → pybotchi-3.4.4}/pybotchi/grpc/pybotchi.proto +0 -0
- {pybotchi-3.4.3 → pybotchi-3.4.4}/pybotchi/grpc/pybotchi_pb2.py +0 -0
- {pybotchi-3.4.3 → pybotchi-3.4.4}/pybotchi/grpc/utils.py +0 -0
- {pybotchi-3.4.3 → pybotchi-3.4.4}/pybotchi/grpc/utils.pyi +0 -0
- {pybotchi-3.4.3 → pybotchi-3.4.4}/pybotchi/llm.py +0 -0
- {pybotchi-3.4.3 → pybotchi-3.4.4}/pybotchi/llm.pyi +0 -0
- {pybotchi-3.4.3 → pybotchi-3.4.4}/pybotchi/mcp/__init__.py +0 -0
- {pybotchi-3.4.3 → pybotchi-3.4.4}/pybotchi/mcp/__init__.pyi +0 -0
- {pybotchi-3.4.3 → pybotchi-3.4.4}/pybotchi/mcp/context.py +0 -0
- {pybotchi-3.4.3 → pybotchi-3.4.4}/pybotchi/mcp/context.pyi +0 -0
- {pybotchi-3.4.3 → 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.
|
|
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.
|
|
19
|
-
Requires-Dist: grpcio-tools (>=1.
|
|
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)
|
|
@@ -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.
|
|
@@ -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
6
|
from typing import Any, Generic, Literal, TypeVar
|
|
8
7
|
|
|
9
|
-
DEFAULT_ACTION:
|
|
10
|
-
DEFAULT_TOOL_CALL_PROMPT:
|
|
11
|
-
DEFAULT_MAX_ITERATION_PROMPT:
|
|
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')
|
|
@@ -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:
|
|
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]
|
|
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
|
-
) ->
|
|
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:
|
|
15
|
+
DMT: DataModelSet
|
|
16
16
|
|
|
17
17
|
class GRPCClient:
|
|
18
|
-
stub:
|
|
19
|
-
name:
|
|
20
|
-
config:
|
|
21
|
-
manual_enable:
|
|
22
|
-
allowed_actions:
|
|
23
|
-
remote_action_class:
|
|
24
|
-
exclude_unset:
|
|
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]
|
|
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:
|
|
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) ->
|
|
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
|
-
"
|
|
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:
|
|
44
|
-
url:
|
|
45
|
-
groups:
|
|
46
|
-
secure:
|
|
47
|
-
root_certificates:
|
|
48
|
-
private_key:
|
|
49
|
-
certificate_chain:
|
|
50
|
-
options:
|
|
51
|
-
compression:
|
|
52
|
-
interceptors:
|
|
53
|
-
metadata:
|
|
54
|
-
allow_exec:
|
|
55
|
-
manual_enable:
|
|
56
|
-
allowed_actions:
|
|
57
|
-
remote_action_class:
|
|
58
|
-
exclude_unset:
|
|
59
|
-
require_integration:
|
|
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:
|
|
5
|
-
alias:
|
|
6
|
-
type:
|
|
7
|
-
message:
|
|
8
|
-
tracebacks:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
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:
|
|
19
|
-
module:
|
|
20
|
-
groups:
|
|
21
|
-
__has_validate_metadata__:
|
|
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:
|
|
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:
|
|
28
|
-
async def execute_connect(self, request_iterator:
|
|
29
|
-
async def connect(self, request_iterator:
|
|
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: ...
|
|
@@ -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]
|
|
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
|
-
) ->
|
|
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
|
|
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:
|
|
16
|
+
DMT: DataModelSet
|
|
17
17
|
|
|
18
18
|
class MCPClient:
|
|
19
|
-
session:
|
|
20
|
-
name:
|
|
21
|
-
config:
|
|
22
|
-
manual_enable:
|
|
23
|
-
allowed_tools:
|
|
24
|
-
tool_action_class:
|
|
25
|
-
exclude_unset:
|
|
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]
|
|
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:
|
|
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) ->
|
|
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:
|
|
45
|
-
mode:
|
|
46
|
-
url:
|
|
47
|
-
headers:
|
|
48
|
-
timeout:
|
|
49
|
-
sse_read_timeout:
|
|
50
|
-
terminate_on_close:
|
|
51
|
-
httpx_client_factory:
|
|
52
|
-
auth:
|
|
53
|
-
on_session_created:
|
|
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:
|
|
56
|
-
allowed_tools:
|
|
57
|
-
tool_action_class:
|
|
58
|
-
exclude_unset:
|
|
59
|
-
require_integration:
|
|
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:
|
|
7
|
-
CAMEL_CASE:
|
|
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.
|
|
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.
|
|
30
|
-
grpcio-tools = { version = ">=1.
|
|
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,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
|
|
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
|
|
File without changes
|
|
File without changes
|