pybotchi 3.4.0__tar.gz → 3.4.2__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 (46) hide show
  1. {pybotchi-3.4.0 → pybotchi-3.4.2}/PKG-INFO +18 -17
  2. {pybotchi-3.4.0 → pybotchi-3.4.2}/README.md +17 -16
  3. {pybotchi-3.4.0 → pybotchi-3.4.2}/pybotchi/action.pyi +8 -0
  4. {pybotchi-3.4.0 → pybotchi-3.4.2}/pybotchi/common.py +4 -2
  5. {pybotchi-3.4.0 → pybotchi-3.4.2}/pybotchi/context.pyi +1 -0
  6. {pybotchi-3.4.0 → pybotchi-3.4.2}/pybotchi/grpc/action.pyi +1 -0
  7. {pybotchi-3.4.0 → pybotchi-3.4.2}/pybotchi/grpc/cli.py +7 -6
  8. {pybotchi-3.4.0 → pybotchi-3.4.2}/pybotchi/grpc/context.pyi +3 -0
  9. {pybotchi-3.4.0 → pybotchi-3.4.2}/pybotchi/grpc/exception.pyi +1 -0
  10. {pybotchi-3.4.0 → pybotchi-3.4.2}/pybotchi/grpc/pybotchi_pb2.pyi +2 -0
  11. {pybotchi-3.4.0 → pybotchi-3.4.2}/pybotchi/grpc/pybotchi_pb2_grpc.pyi +1 -0
  12. {pybotchi-3.4.0 → pybotchi-3.4.2}/pybotchi/mcp/action.py +7 -1
  13. {pybotchi-3.4.0 → pybotchi-3.4.2}/pybotchi/mcp/action.pyi +1 -0
  14. {pybotchi-3.4.0 → pybotchi-3.4.2}/pybotchi/mcp/common.py +0 -5
  15. {pybotchi-3.4.0 → pybotchi-3.4.2}/pybotchi/mcp/common.pyi +0 -3
  16. {pybotchi-3.4.0 → pybotchi-3.4.2}/pyproject.toml +1 -1
  17. {pybotchi-3.4.0 → pybotchi-3.4.2}/LICENSE +0 -0
  18. {pybotchi-3.4.0 → pybotchi-3.4.2}/pybotchi/__init__.py +0 -0
  19. {pybotchi-3.4.0 → pybotchi-3.4.2}/pybotchi/__init__.pyi +0 -0
  20. {pybotchi-3.4.0 → pybotchi-3.4.2}/pybotchi/action.py +0 -0
  21. {pybotchi-3.4.0 → pybotchi-3.4.2}/pybotchi/common.pyi +0 -0
  22. {pybotchi-3.4.0 → pybotchi-3.4.2}/pybotchi/context.py +0 -0
  23. {pybotchi-3.4.0 → pybotchi-3.4.2}/pybotchi/grpc/__init__.py +0 -0
  24. {pybotchi-3.4.0 → pybotchi-3.4.2}/pybotchi/grpc/__init__.pyi +0 -0
  25. {pybotchi-3.4.0 → pybotchi-3.4.2}/pybotchi/grpc/action.py +0 -0
  26. {pybotchi-3.4.0 → pybotchi-3.4.2}/pybotchi/grpc/cli.pyi +0 -0
  27. {pybotchi-3.4.0 → pybotchi-3.4.2}/pybotchi/grpc/common.py +0 -0
  28. {pybotchi-3.4.0 → pybotchi-3.4.2}/pybotchi/grpc/common.pyi +0 -0
  29. {pybotchi-3.4.0 → pybotchi-3.4.2}/pybotchi/grpc/context.py +0 -0
  30. {pybotchi-3.4.0 → pybotchi-3.4.2}/pybotchi/grpc/exception.py +0 -0
  31. {pybotchi-3.4.0 → pybotchi-3.4.2}/pybotchi/grpc/handler.py +0 -0
  32. {pybotchi-3.4.0 → pybotchi-3.4.2}/pybotchi/grpc/handler.pyi +0 -0
  33. {pybotchi-3.4.0 → pybotchi-3.4.2}/pybotchi/grpc/pybotchi.proto +0 -0
  34. {pybotchi-3.4.0 → pybotchi-3.4.2}/pybotchi/grpc/pybotchi_pb2.py +0 -0
  35. {pybotchi-3.4.0 → pybotchi-3.4.2}/pybotchi/grpc/pybotchi_pb2_grpc.py +0 -0
  36. {pybotchi-3.4.0 → pybotchi-3.4.2}/pybotchi/grpc/utils.py +0 -0
  37. {pybotchi-3.4.0 → pybotchi-3.4.2}/pybotchi/grpc/utils.pyi +0 -0
  38. {pybotchi-3.4.0 → pybotchi-3.4.2}/pybotchi/llm.py +0 -0
  39. {pybotchi-3.4.0 → pybotchi-3.4.2}/pybotchi/llm.pyi +0 -0
  40. {pybotchi-3.4.0 → pybotchi-3.4.2}/pybotchi/mcp/__init__.py +0 -0
  41. {pybotchi-3.4.0 → pybotchi-3.4.2}/pybotchi/mcp/__init__.pyi +0 -0
  42. {pybotchi-3.4.0 → pybotchi-3.4.2}/pybotchi/mcp/context.py +0 -0
  43. {pybotchi-3.4.0 → pybotchi-3.4.2}/pybotchi/mcp/context.pyi +0 -0
  44. {pybotchi-3.4.0 → pybotchi-3.4.2}/pybotchi/py.typed +0 -0
  45. {pybotchi-3.4.0 → pybotchi-3.4.2}/pybotchi/utils.py +0 -0
  46. {pybotchi-3.4.0 → pybotchi-3.4.2}/pybotchi/utils.pyi +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pybotchi
3
- Version: 3.4.0
3
+ Version: 3.4.2
4
4
  Summary: A deterministic, intent-based AI agent builder.
5
5
  License-File: LICENSE
6
6
  Author: Alexie (Boyong) Madolid
@@ -129,11 +129,16 @@ LLM.add(base=ChatOpenAI(
129
129
  ```python
130
130
  from pybotchi import Action, ActionReturn
131
131
 
132
+ from pydantic import Field
133
+
132
134
  class Translation(Action):
133
- """Translate to specified language."""
135
+ """Translate to specific language."""
136
+
137
+ message: str = Field(description="The text content to be translated.")
138
+ language: str = Field(description="The ISO code or name of the target language.")
134
139
 
135
140
  async def pre(self, context):
136
- message = await context.llm.ainvoke(context.prompts)
141
+ message = await context.llm.ainvoke(f"Reply only with translation of `{self.message}` to {self.language}.")
137
142
  await context.add_response(self, message.text)
138
143
  return ActionReturn.GO
139
144
  ```
@@ -181,22 +186,20 @@ async def test():
181
186
  context = Context(
182
187
  prompts=[
183
188
  {"role": "system", "content": "You're an AI that can solve math problems and translate requests."},
184
- {"role": "user", "content": "4 x 4 and explain in Filipino"}
189
+ {"role": "user", "content": "4 x 4 then explain in Filipino"},
185
190
  ],
186
191
  )
187
192
  await context.start(MultiAgent)
188
- print(context.prompts[-1]["content"])
193
+ print(f"MathProblem: {context.prompts[-3]['content']}")
194
+ print(f"Translate: {context.prompts[-1]['content']}")
189
195
 
190
196
  asyncio.run(test())
191
197
  ```
192
198
 
193
199
  **Result:**
194
200
  ```
195
- Ang sagot sa 4 x 4 ay 16.
196
-
197
- Paliwanag: Kapag sinabi nating 4 x 4, ibig sabihin ay apat na grupo ng apat. Kung bibilangin natin ito, makakakuha tayo ng kabuuang labing-anim (16).
198
-
199
- Ibig sabihin, 4 + 4 + 4 + 4 = 16.
201
+ MathProblem: Four multiplied by four is sixteen. Imagine you have four groups, and each group has four candies. If you count all the candies together, you will have sixteen candies. That's what 4 x 4 means!
202
+ Translate: Ang apat na pinarami sa apat ay labing-anim. Ipagpalagay mong may apat na grupo, at bawat grupo ay may apat na kendi. Kung bibilangin mo lahat ng kendi, magkakaroon ka ng labing-anim na kendi. Iyan ang ibig sabihin ng 4 x 4!
200
203
  ```
201
204
 
202
205
  ### Visualize Your Graph
@@ -210,7 +213,7 @@ async def print_mermaid_graph():
210
213
  multi_agent_graph = await graph(MultiAgent)
211
214
  print(multi_agent_graph.flowchart())
212
215
 
213
- run(print_mermaid_graph())
216
+ asyncio.run(print_mermaid_graph())
214
217
  ```
215
218
  **Result:**
216
219
  ```
@@ -393,14 +396,12 @@ pybotchi-grpc server.py
393
396
  **Result**
394
397
  ```bash
395
398
  #-------------------------------------------------------#
396
- # Agent ID: agent_b6c9ada82c7444818356a6338e975c09
397
- # Agent Path: server.py
399
+ # Agent ID: agent_8b3c5685c84b4602966d1b3252916aa7
398
400
  # Agent Path: server.py
399
401
  # Starting None worker(s) on 0.0.0.0:50051
400
402
  #-------------------------------------------------------#
401
- # Agent Path: server.py
403
+ # Agent Process: Process-1 [173012]
402
404
  # Agent Handler: PyBotchiGRPC
403
- # gRPC server running on 0.0.0.0:50051
404
405
  #-------------------------------------------------------#
405
406
  ```
406
407
  gRPC client print graph:
@@ -409,9 +410,9 @@ python3 client.py
409
410
  ```
410
411
  ```bash
411
412
  flowchart TD
413
+ grpc.agent_8b3c5685c84b4602966d1b3252916aa7.MathProblem[MathProblem]
412
414
  __main__.MultiAgent[MultiAgent]
413
- grpc.agent_b6c9ada82c7444818356a6338e975c09.MathProblem[MathProblem]
414
- __main__.MultiAgent --**GRPC** : remote--> grpc.agent_b6c9ada82c7444818356a6338e975c09.MathProblem
415
+ __main__.MultiAgent --"`**GRPC** : remote`"--> grpc.agent_8b3c5685c84b4602966d1b3252916aa7.MathProblem
415
416
  style __main__.MultiAgent fill:#4CAF50,color:#000000
416
417
  ```
417
418
  ![gRPC MultiAgent Graph](docs/mermaid2.png)
@@ -103,11 +103,16 @@ LLM.add(base=ChatOpenAI(
103
103
  ```python
104
104
  from pybotchi import Action, ActionReturn
105
105
 
106
+ from pydantic import Field
107
+
106
108
  class Translation(Action):
107
- """Translate to specified language."""
109
+ """Translate to specific language."""
110
+
111
+ message: str = Field(description="The text content to be translated.")
112
+ language: str = Field(description="The ISO code or name of the target language.")
108
113
 
109
114
  async def pre(self, context):
110
- message = await context.llm.ainvoke(context.prompts)
115
+ message = await context.llm.ainvoke(f"Reply only with translation of `{self.message}` to {self.language}.")
111
116
  await context.add_response(self, message.text)
112
117
  return ActionReturn.GO
113
118
  ```
@@ -155,22 +160,20 @@ async def test():
155
160
  context = Context(
156
161
  prompts=[
157
162
  {"role": "system", "content": "You're an AI that can solve math problems and translate requests."},
158
- {"role": "user", "content": "4 x 4 and explain in Filipino"}
163
+ {"role": "user", "content": "4 x 4 then explain in Filipino"},
159
164
  ],
160
165
  )
161
166
  await context.start(MultiAgent)
162
- print(context.prompts[-1]["content"])
167
+ print(f"MathProblem: {context.prompts[-3]['content']}")
168
+ print(f"Translate: {context.prompts[-1]['content']}")
163
169
 
164
170
  asyncio.run(test())
165
171
  ```
166
172
 
167
173
  **Result:**
168
174
  ```
169
- Ang sagot sa 4 x 4 ay 16.
170
-
171
- Paliwanag: Kapag sinabi nating 4 x 4, ibig sabihin ay apat na grupo ng apat. Kung bibilangin natin ito, makakakuha tayo ng kabuuang labing-anim (16).
172
-
173
- Ibig sabihin, 4 + 4 + 4 + 4 = 16.
175
+ MathProblem: Four multiplied by four is sixteen. Imagine you have four groups, and each group has four candies. If you count all the candies together, you will have sixteen candies. That's what 4 x 4 means!
176
+ Translate: Ang apat na pinarami sa apat ay labing-anim. Ipagpalagay mong may apat na grupo, at bawat grupo ay may apat na kendi. Kung bibilangin mo lahat ng kendi, magkakaroon ka ng labing-anim na kendi. Iyan ang ibig sabihin ng 4 x 4!
174
177
  ```
175
178
 
176
179
  ### Visualize Your Graph
@@ -184,7 +187,7 @@ async def print_mermaid_graph():
184
187
  multi_agent_graph = await graph(MultiAgent)
185
188
  print(multi_agent_graph.flowchart())
186
189
 
187
- run(print_mermaid_graph())
190
+ asyncio.run(print_mermaid_graph())
188
191
  ```
189
192
  **Result:**
190
193
  ```
@@ -367,14 +370,12 @@ pybotchi-grpc server.py
367
370
  **Result**
368
371
  ```bash
369
372
  #-------------------------------------------------------#
370
- # Agent ID: agent_b6c9ada82c7444818356a6338e975c09
371
- # Agent Path: server.py
373
+ # Agent ID: agent_8b3c5685c84b4602966d1b3252916aa7
372
374
  # Agent Path: server.py
373
375
  # Starting None worker(s) on 0.0.0.0:50051
374
376
  #-------------------------------------------------------#
375
- # Agent Path: server.py
377
+ # Agent Process: Process-1 [173012]
376
378
  # Agent Handler: PyBotchiGRPC
377
- # gRPC server running on 0.0.0.0:50051
378
379
  #-------------------------------------------------------#
379
380
  ```
380
381
  gRPC client print graph:
@@ -383,9 +384,9 @@ python3 client.py
383
384
  ```
384
385
  ```bash
385
386
  flowchart TD
387
+ grpc.agent_8b3c5685c84b4602966d1b3252916aa7.MathProblem[MathProblem]
386
388
  __main__.MultiAgent[MultiAgent]
387
- grpc.agent_b6c9ada82c7444818356a6338e975c09.MathProblem[MathProblem]
388
- __main__.MultiAgent --**GRPC** : remote--> grpc.agent_b6c9ada82c7444818356a6338e975c09.MathProblem
389
+ __main__.MultiAgent --"`**GRPC** : remote`"--> grpc.agent_8b3c5685c84b4602966d1b3252916aa7.MathProblem
389
390
  style __main__.MultiAgent fill:#4CAF50,color:#000000
390
391
  ```
391
392
  ![gRPC MultiAgent Graph](docs/mermaid2.png)
@@ -38,10 +38,18 @@ class Action(BaseModel, Generic[TContext]):
38
38
  __display_name__: str
39
39
  __groups__: Groups | set[str] | None
40
40
  __to_commit__: bool
41
+ _usage: list[UsageData]
42
+ _actions: list[Action | ActionEntry]
43
+ _parent: Action | None
44
+ _children: list['Action']
41
45
  @classmethod
42
46
  def __pydantic_init_subclass__(cls, **kwargs: Any) -> None: ...
43
47
  @classmethod
44
48
  def __init_child_actions__(cls) -> None: ...
49
+ @property
50
+ def _tool_call(self) -> ToolCall: ...
51
+ @classmethod
52
+ async def _as_tool(cls, context: TContext) -> dict[str, Any] | type[BaseModel]: ...
45
53
  async def pre(self, context: TContext) -> ActionReturn: ...
46
54
  async def fallback(self, context: TContext, content: str) -> ActionReturn: ...
47
55
  async def on_child_init_error(self, context: TContext, next_actions: list['Action'], child_cls: type[Action], child_args: dict[str, Any], exception: Exception) -> str | None: ...
@@ -110,11 +110,13 @@ class Graph(BaseModel):
110
110
 
111
111
  if concurrent:
112
112
  connection = (
113
- f"ed{con}@--**{base}** : {alias}<br>*[concurrent]*-->" if alias else f"ed{con}@--*[concurrent]*-->"
113
+ f'ed{con}@--"`**{base}** : {alias}<br>*[concurrent]*`"-->'
114
+ if alias
115
+ else f'ed{con}@--"`*[concurrent]*`"-->'
114
116
  )
115
117
  con += 1
116
118
  else:
117
- connection = f"--**{base}** : {alias}-->" if alias else "-->"
119
+ connection = f'--"`**{base}** : {alias}`"-->' if alias else "-->"
118
120
  content += f"{source} {connection} {target}\n"
119
121
 
120
122
  constraints = (
@@ -22,6 +22,7 @@ class Context(BaseModel, Generic[TLLM]):
22
22
  streaming: bool
23
23
  max_self_loop: int | None
24
24
  parent: Self | None
25
+ _action_call: dict[str, int]
25
26
  @cached_property
26
27
  def llm(self) -> TLLM: ...
27
28
  @cached_property
@@ -36,6 +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
40
  __to_commit__: bool
40
41
  async def execute(self, context: TContext, parent: Action | None = None, append: bool = True) -> ActionReturn: ...
41
42
  async def get_child_actions(self, context: TContext) -> ChildActions: ...
@@ -4,7 +4,7 @@ from asyncio import run
4
4
  from importlib.resources import files
5
5
  from importlib.util import module_from_spec, spec_from_file_location
6
6
  from inspect import getmembers, isclass
7
- from multiprocessing import Process, cpu_count
7
+ from multiprocessing import Process, cpu_count, current_process
8
8
  from os import getenv
9
9
  from pathlib import Path
10
10
  from signal import SIGINT, SIGTERM, signal
@@ -96,10 +96,12 @@ async def serve(
96
96
  server.add_insecure_port(address)
97
97
  await server.start()
98
98
 
99
- echo(f"# Agent Path: {path}")
100
- echo(f"# Agent Handler: {grpc_handler.__name__}")
101
- echo(f"# gRPC server running on {address}")
102
- echo("#-------------------------------------------------------#")
99
+ process = current_process()
100
+ echo(
101
+ f"# Agent Process: {process.name} [{process.pid}]\n"
102
+ f"# Agent Handler: {grpc_handler.__name__}\n"
103
+ "#-------------------------------------------------------#"
104
+ )
103
105
  await server.wait_for_termination()
104
106
 
105
107
 
@@ -191,7 +193,6 @@ def main(
191
193
  else:
192
194
  _certificate_chain = None
193
195
 
194
- echo(f"# Agent Path: {path}")
195
196
  echo(f"# Starting {workers} worker(s) on {host}:{port}")
196
197
  echo("#-------------------------------------------------------#")
197
198
 
@@ -3,6 +3,7 @@ from ..context import Action as Action, ChatRole as ChatRole, Context as Context
3
3
  from ..utils import uuid as uuid
4
4
  from .common import GRPCIntegration as GRPCIntegration
5
5
  from .pybotchi_pb2 import Event as Event
6
+ from asyncio import Queue
6
7
  from typing import Any, Generic, TypeVar
7
8
 
8
9
  TContext = TypeVar('TContext', bound='GRPCContext')
@@ -11,6 +12,8 @@ class GRPCContext(Context[TLLM], Generic[TLLM]):
11
12
  integrations: dict[str, GRPCIntegration]
12
13
  source_id: str | None
13
14
  context_id: str
15
+ _response_queue: Queue[Event] | None
16
+ _request_queues: dict[str, Queue]
14
17
  def grpc_dump(self) -> dict[str, Any]: ...
15
18
  def grpc_sharing_dump(self) -> dict[str, Any]: ...
16
19
  async def grpc_send_up(self, source_id: str | None, name: str, data: dict[str, Any]) -> None: ...
@@ -7,3 +7,4 @@ class GRPCRemoteError(Exception):
7
7
  message: Incomplete
8
8
  tracebacks: Incomplete
9
9
  def __init__(self, cls: str, alias: str, type: str, message: str, tracebacks: list[str]) -> None: ...
10
+ def __str__(self) -> str: ...
@@ -1,3 +1,5 @@
1
1
  from _typeshed import Incomplete
2
2
 
3
+ _sym_db: Incomplete
3
4
  DESCRIPTOR: Incomplete
5
+ _globals: Incomplete
@@ -2,6 +2,7 @@ from _typeshed import Incomplete
2
2
 
3
3
  GRPC_GENERATED_VERSION: str
4
4
  GRPC_VERSION: Incomplete
5
+ _version_not_supported: bool
5
6
 
6
7
  class PyBotchiGRPCStub:
7
8
  connect: Incomplete
@@ -402,7 +402,13 @@ async def multi_mcp_clients(
402
402
  )
403
403
  else:
404
404
  async_client = await stack.enter_async_context(
405
- AsyncClient(**overrided_config["async_client_args"], follow_redirects=True)
405
+ AsyncClient(
406
+ base_url=overrided_config["url"],
407
+ headers=overrided_config["headers"],
408
+ timeout=overrided_config["timeout"],
409
+ **overrided_config["async_client_args"],
410
+ follow_redirects=True,
411
+ )
406
412
  )
407
413
 
408
414
  streams = await stack.enter_async_context(
@@ -38,6 +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
42
  __to_commit__: bool
42
43
  async def execute(self, context: TContext, parent: Action | None = None, append: bool = True) -> ActionReturn: ...
43
44
  async def get_child_actions(self, context: TContext) -> ChildActions: ...
@@ -35,18 +35,13 @@ class AsyncClientArgs(TypedDict, total=False):
35
35
  | bytes
36
36
  | None
37
37
  )
38
- headers: (
39
- Mapping[str, str] | Mapping[bytes, bytes] | Sequence[tuple[str, str]] | Sequence[tuple[bytes, bytes]] | None
40
- )
41
38
  cookies: dict[str, str] | list[tuple[str, str]] | None
42
39
  verify: str | bool
43
40
  cert: CertTypes | None
44
41
  http1: bool
45
42
  http2: bool
46
43
  proxy: str | None
47
- timeout: float | None | tuple[float | None, float | None, float | None, float | None] | None
48
44
  max_redirects: int
49
- base_url: str
50
45
  trust_env: bool
51
46
  default_encoding: str
52
47
 
@@ -14,16 +14,13 @@ class MCPMode(StrEnum):
14
14
  class AsyncClientArgs(TypedDict, total=False):
15
15
  auth: tuple[str | bytes, str | bytes] | None
16
16
  params: Mapping[str, PrimitiveData | Sequence[PrimitiveData]] | list[tuple[str, PrimitiveData]] | tuple[tuple[str, PrimitiveData], ...] | str | bytes | None
17
- headers: Mapping[str, str] | Mapping[bytes, bytes] | Sequence[tuple[str, str]] | Sequence[tuple[bytes, bytes]] | None
18
17
  cookies: dict[str, str] | list[tuple[str, str]] | None
19
18
  verify: str | bool
20
19
  cert: CertTypes | None
21
20
  http1: bool
22
21
  http2: bool
23
22
  proxy: str | None
24
- timeout: float | None | tuple[float | None, float | None, float | None, float | None] | None
25
23
  max_redirects: int
26
- base_url: str
27
24
  trust_env: bool
28
25
  default_encoding: str
29
26
 
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "pybotchi"
3
- version = "3.4.0"
3
+ version = "3.4.2"
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"
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