pybotchi 3.4.3__tar.gz → 3.5.0__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.5.0}/PKG-INFO +3 -3
- {pybotchi-3.4.3 → pybotchi-3.5.0}/pybotchi/action.py +3 -3
- {pybotchi-3.4.3 → pybotchi-3.5.0}/pybotchi/common.py +1 -1
- {pybotchi-3.4.3 → pybotchi-3.5.0}/pybotchi/grpc/action.py +13 -13
- {pybotchi-3.4.3 → pybotchi-3.5.0}/pybotchi/grpc/cli.py +1 -1
- {pybotchi-3.4.3 → pybotchi-3.5.0}/pybotchi/grpc/common.py +17 -17
- {pybotchi-3.4.3 → pybotchi-3.5.0}/pybotchi/grpc/exception.py +5 -5
- {pybotchi-3.4.3 → pybotchi-3.5.0}/pybotchi/grpc/handler.py +9 -9
- pybotchi-3.5.0/pybotchi/grpc/pybotchi_pb2.pyi +165 -0
- {pybotchi-3.4.3 → pybotchi-3.5.0}/pybotchi/grpc/pybotchi_pb2_grpc.py +1 -1
- {pybotchi-3.4.3 → pybotchi-3.5.0}/pybotchi/mcp/action.py +13 -13
- {pybotchi-3.4.3 → pybotchi-3.5.0}/pybotchi/mcp/common.py +15 -15
- {pybotchi-3.4.3 → pybotchi-3.5.0}/pybotchi/utils.py +3 -3
- {pybotchi-3.4.3 → pybotchi-3.5.0}/pyproject.toml +3 -3
- pybotchi-3.4.3/pybotchi/__init__.pyi +0 -6
- pybotchi-3.4.3/pybotchi/action.pyi +0 -81
- pybotchi-3.4.3/pybotchi/common.pyi +0 -86
- pybotchi-3.4.3/pybotchi/context.pyi +0 -45
- pybotchi-3.4.3/pybotchi/grpc/__init__.pyi +0 -5
- pybotchi-3.4.3/pybotchi/grpc/action.pyi +0 -65
- pybotchi-3.4.3/pybotchi/grpc/cli.pyi +0 -12
- pybotchi-3.4.3/pybotchi/grpc/common.pyi +0 -61
- pybotchi-3.4.3/pybotchi/grpc/context.pyi +0 -25
- pybotchi-3.4.3/pybotchi/grpc/exception.pyi +0 -10
- pybotchi-3.4.3/pybotchi/grpc/handler.pyi +0 -31
- 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/grpc/utils.pyi +0 -3
- pybotchi-3.4.3/pybotchi/llm.pyi +0 -22
- pybotchi-3.4.3/pybotchi/mcp/__init__.pyi +0 -5
- pybotchi-3.4.3/pybotchi/mcp/action.pyi +0 -66
- pybotchi-3.4.3/pybotchi/mcp/common.pyi +0 -61
- pybotchi-3.4.3/pybotchi/mcp/context.pyi +0 -9
- pybotchi-3.4.3/pybotchi/utils.pyi +0 -13
- {pybotchi-3.4.3 → pybotchi-3.5.0}/LICENSE +0 -0
- {pybotchi-3.4.3 → pybotchi-3.5.0}/README.md +0 -0
- {pybotchi-3.4.3 → pybotchi-3.5.0}/pybotchi/__init__.py +0 -0
- {pybotchi-3.4.3 → pybotchi-3.5.0}/pybotchi/context.py +0 -0
- {pybotchi-3.4.3 → pybotchi-3.5.0}/pybotchi/grpc/__init__.py +0 -0
- {pybotchi-3.4.3 → pybotchi-3.5.0}/pybotchi/grpc/context.py +0 -0
- {pybotchi-3.4.3 → pybotchi-3.5.0}/pybotchi/grpc/pybotchi.proto +0 -0
- {pybotchi-3.4.3 → pybotchi-3.5.0}/pybotchi/grpc/pybotchi_pb2.py +0 -0
- {pybotchi-3.4.3 → pybotchi-3.5.0}/pybotchi/grpc/utils.py +0 -0
- {pybotchi-3.4.3 → pybotchi-3.5.0}/pybotchi/llm.py +0 -0
- {pybotchi-3.4.3 → pybotchi-3.5.0}/pybotchi/mcp/__init__.py +0 -0
- {pybotchi-3.4.3 → pybotchi-3.5.0}/pybotchi/mcp/context.py +0 -0
- {pybotchi-3.4.3 → pybotchi-3.5.0}/pybotchi/py.typed +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: pybotchi
|
|
3
|
-
Version: 3.
|
|
3
|
+
Version: 3.5.0
|
|
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.
|
|
@@ -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,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] = {}
|
|
@@ -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."""
|
|
@@ -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,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()):
|
|
@@ -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: ...
|
|
@@ -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] = {}
|
|
@@ -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."""
|
|
@@ -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,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "pybotchi"
|
|
3
|
-
version = "3.
|
|
3
|
+
version = "3.5.0"
|
|
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,6 +0,0 @@
|
|
|
1
|
-
from .action import Action as Action, DEFAULT_ACTION as DEFAULT_ACTION, all_agents as all_agents, graph as graph
|
|
2
|
-
from .common import ActionReturn as ActionReturn, ChatRole as ChatRole, Groups as Groups, UsageMetadata as UsageMetadata
|
|
3
|
-
from .context import Context as Context
|
|
4
|
-
from .llm import LLM as LLM
|
|
5
|
-
|
|
6
|
-
__all__ = ['Action', 'DEFAULT_ACTION', 'all_agents', 'graph', 'ActionReturn', 'ChatRole', 'Groups', 'UsageMetadata', 'Context', 'LLM']
|