meshagent-cli 0.7.0__py3-none-any.whl → 0.21.0__py3-none-any.whl
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.
- meshagent/cli/agent.py +15 -11
- meshagent/cli/api_keys.py +4 -4
- meshagent/cli/async_typer.py +52 -4
- meshagent/cli/call.py +12 -8
- meshagent/cli/chatbot.py +1007 -129
- meshagent/cli/cli.py +21 -20
- meshagent/cli/cli_mcp.py +92 -28
- meshagent/cli/cli_secrets.py +10 -10
- meshagent/cli/common_options.py +19 -4
- meshagent/cli/containers.py +164 -16
- meshagent/cli/database.py +997 -0
- meshagent/cli/developer.py +3 -3
- meshagent/cli/exec.py +22 -6
- meshagent/cli/helper.py +62 -11
- meshagent/cli/helpers.py +66 -9
- meshagent/cli/host.py +37 -0
- meshagent/cli/mailbot.py +1004 -40
- meshagent/cli/mailboxes.py +223 -0
- meshagent/cli/meeting_transcriber.py +10 -4
- meshagent/cli/messaging.py +7 -7
- meshagent/cli/multi.py +402 -0
- meshagent/cli/oauth2.py +44 -21
- meshagent/cli/participant_token.py +5 -3
- meshagent/cli/port.py +70 -0
- meshagent/cli/queue.py +2 -2
- meshagent/cli/room.py +20 -212
- meshagent/cli/rooms.py +214 -0
- meshagent/cli/services.py +32 -23
- meshagent/cli/sessions.py +5 -5
- meshagent/cli/storage.py +5 -5
- meshagent/cli/task_runner.py +770 -0
- meshagent/cli/version.py +1 -1
- meshagent/cli/voicebot.py +502 -76
- meshagent/cli/webhook.py +7 -7
- meshagent/cli/worker.py +1327 -0
- {meshagent_cli-0.7.0.dist-info → meshagent_cli-0.21.0.dist-info}/METADATA +13 -13
- meshagent_cli-0.21.0.dist-info/RECORD +44 -0
- meshagent_cli-0.7.0.dist-info/RECORD +0 -36
- {meshagent_cli-0.7.0.dist-info → meshagent_cli-0.21.0.dist-info}/WHEEL +0 -0
- {meshagent_cli-0.7.0.dist-info → meshagent_cli-0.21.0.dist-info}/entry_points.txt +0 -0
- {meshagent_cli-0.7.0.dist-info → meshagent_cli-0.21.0.dist-info}/top_level.txt +0 -0
meshagent/cli/agent.py
CHANGED
|
@@ -15,16 +15,16 @@ from meshagent.cli.helper import resolve_project_id
|
|
|
15
15
|
from meshagent.cli import async_typer
|
|
16
16
|
from meshagent.cli.helper import get_client, resolve_room
|
|
17
17
|
|
|
18
|
-
app = async_typer.AsyncTyper()
|
|
18
|
+
app = async_typer.AsyncTyper(help="Interact with agents and toolkits in a room")
|
|
19
19
|
|
|
20
20
|
|
|
21
|
-
@app.async_command("ask")
|
|
21
|
+
@app.async_command("ask", help="Send a request to an agent")
|
|
22
22
|
async def ask(
|
|
23
23
|
*,
|
|
24
|
-
project_id: ProjectIdOption
|
|
24
|
+
project_id: ProjectIdOption,
|
|
25
25
|
room: RoomOption,
|
|
26
|
-
agent: Annotated[str, typer.Option()],
|
|
27
|
-
input: Annotated[str, typer.Option()],
|
|
26
|
+
agent: Annotated[str, typer.Option(..., help="Agent name to ask")],
|
|
27
|
+
input: Annotated[str, typer.Option(..., help="JSON string with tool arguments")],
|
|
28
28
|
timeout: Annotated[
|
|
29
29
|
Optional[int],
|
|
30
30
|
typer.Option(
|
|
@@ -32,6 +32,8 @@ async def ask(
|
|
|
32
32
|
),
|
|
33
33
|
] = 30,
|
|
34
34
|
):
|
|
35
|
+
"""Wait for an agent to join, then send it an ask request."""
|
|
36
|
+
|
|
35
37
|
account_client = await get_client()
|
|
36
38
|
try:
|
|
37
39
|
project_id = await resolve_project_id(project_id=project_id)
|
|
@@ -76,10 +78,10 @@ async def ask(
|
|
|
76
78
|
await account_client.close()
|
|
77
79
|
|
|
78
80
|
|
|
79
|
-
@app.async_command("invoke-tool")
|
|
81
|
+
@app.async_command("invoke-tool", help="Invoke a specific tool from a toolkit")
|
|
80
82
|
async def invoke_tool(
|
|
81
83
|
*,
|
|
82
|
-
project_id: ProjectIdOption
|
|
84
|
+
project_id: ProjectIdOption,
|
|
83
85
|
room: RoomOption,
|
|
84
86
|
toolkit: Annotated[str, typer.Option(..., help="Toolkit name")],
|
|
85
87
|
tool: Annotated[str, typer.Option(..., help="Tool name")],
|
|
@@ -161,10 +163,10 @@ async def invoke_tool(
|
|
|
161
163
|
await account_client.close()
|
|
162
164
|
|
|
163
165
|
|
|
164
|
-
@app.async_command("list-agents")
|
|
166
|
+
@app.async_command("list-agents", help="List agents currently in the room")
|
|
165
167
|
async def list_agents_command(
|
|
166
168
|
*,
|
|
167
|
-
project_id: ProjectIdOption
|
|
169
|
+
project_id: ProjectIdOption,
|
|
168
170
|
room: RoomOption,
|
|
169
171
|
):
|
|
170
172
|
"""
|
|
@@ -205,10 +207,12 @@ async def list_agents_command(
|
|
|
205
207
|
await account_client.close()
|
|
206
208
|
|
|
207
209
|
|
|
208
|
-
@app.async_command(
|
|
210
|
+
@app.async_command(
|
|
211
|
+
"list-toolkits", help="List toolkits (and tools) available in the room"
|
|
212
|
+
)
|
|
209
213
|
async def list_toolkits_command(
|
|
210
214
|
*,
|
|
211
|
-
project_id: ProjectIdOption
|
|
215
|
+
project_id: ProjectIdOption,
|
|
212
216
|
room: RoomOption,
|
|
213
217
|
role: str = "user",
|
|
214
218
|
participant_id: Annotated[
|
meshagent/cli/api_keys.py
CHANGED
|
@@ -19,7 +19,7 @@ app = async_typer.AsyncTyper(help="Manage or activate api-keys for your project"
|
|
|
19
19
|
@app.async_command("list")
|
|
20
20
|
async def list(
|
|
21
21
|
*,
|
|
22
|
-
project_id: ProjectIdOption
|
|
22
|
+
project_id: ProjectIdOption,
|
|
23
23
|
o: OutputFormatOption = "table",
|
|
24
24
|
):
|
|
25
25
|
project_id = await resolve_project_id(project_id=project_id)
|
|
@@ -42,7 +42,7 @@ async def list(
|
|
|
42
42
|
@app.async_command("create")
|
|
43
43
|
async def create(
|
|
44
44
|
*,
|
|
45
|
-
project_id: ProjectIdOption
|
|
45
|
+
project_id: ProjectIdOption,
|
|
46
46
|
name: str,
|
|
47
47
|
description: Annotated[
|
|
48
48
|
str, typer.Option(..., help="a description for the api key")
|
|
@@ -85,7 +85,7 @@ async def create(
|
|
|
85
85
|
@app.async_command("activate")
|
|
86
86
|
async def activate(
|
|
87
87
|
*,
|
|
88
|
-
project_id: ProjectIdOption
|
|
88
|
+
project_id: ProjectIdOption,
|
|
89
89
|
key: str,
|
|
90
90
|
):
|
|
91
91
|
project_id = await resolve_project_id(project_id=project_id)
|
|
@@ -94,7 +94,7 @@ async def activate(
|
|
|
94
94
|
|
|
95
95
|
|
|
96
96
|
@app.async_command("delete")
|
|
97
|
-
async def delete(*, project_id: ProjectIdOption
|
|
97
|
+
async def delete(*, project_id: ProjectIdOption, id: str):
|
|
98
98
|
project_id = await resolve_project_id(project_id=project_id)
|
|
99
99
|
|
|
100
100
|
client = await get_client()
|
meshagent/cli/async_typer.py
CHANGED
|
@@ -2,20 +2,64 @@ from __future__ import annotations
|
|
|
2
2
|
|
|
3
3
|
import asyncio
|
|
4
4
|
import inspect
|
|
5
|
+
import threading
|
|
5
6
|
from functools import partial, wraps
|
|
6
|
-
from typing import Any, Callable
|
|
7
|
+
from typing import Any, Callable, TypeVar
|
|
7
8
|
|
|
8
9
|
from typer import Typer
|
|
9
10
|
|
|
11
|
+
T = TypeVar("T")
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def _run_coroutine_sync(
|
|
15
|
+
coro: "asyncio.Future[T] | asyncio.coroutines.Coroutine[Any, Any, T]",
|
|
16
|
+
) -> T:
|
|
17
|
+
"""
|
|
18
|
+
Run an awaitable from sync code.
|
|
19
|
+
|
|
20
|
+
- If we're not currently in an event loop, use asyncio.run().
|
|
21
|
+
- If we ARE in a running loop (e.g. inside an agent / notebook / ASGI app),
|
|
22
|
+
run asyncio.run() in a separate thread and block for the result.
|
|
23
|
+
|
|
24
|
+
This avoids: RuntimeError: asyncio.run() cannot be called from a running event loop
|
|
25
|
+
"""
|
|
26
|
+
try:
|
|
27
|
+
asyncio.get_running_loop()
|
|
28
|
+
in_running_loop = True
|
|
29
|
+
except RuntimeError:
|
|
30
|
+
in_running_loop = False
|
|
31
|
+
|
|
32
|
+
if not in_running_loop:
|
|
33
|
+
return asyncio.run(coro) # type: ignore[arg-type]
|
|
34
|
+
|
|
35
|
+
result: dict[str, Any] = {}
|
|
36
|
+
done = threading.Event()
|
|
37
|
+
|
|
38
|
+
def _worker() -> None:
|
|
39
|
+
try:
|
|
40
|
+
result["value"] = asyncio.run(coro) # type: ignore[arg-type]
|
|
41
|
+
except BaseException as e:
|
|
42
|
+
result["error"] = e
|
|
43
|
+
finally:
|
|
44
|
+
done.set()
|
|
45
|
+
|
|
46
|
+
t = threading.Thread(target=_worker, daemon=True)
|
|
47
|
+
t.start()
|
|
48
|
+
done.wait()
|
|
49
|
+
|
|
50
|
+
if "error" in result:
|
|
51
|
+
raise result["error"]
|
|
52
|
+
return result["value"] # type: ignore[return-value]
|
|
53
|
+
|
|
10
54
|
|
|
11
55
|
class AsyncTyper(Typer):
|
|
12
56
|
@staticmethod
|
|
13
|
-
def maybe_run_async(decorator: Callable, func: Callable) -> Any:
|
|
57
|
+
def maybe_run_async(decorator: Callable[..., Any], func: Callable[..., Any]) -> Any:
|
|
14
58
|
if inspect.iscoroutinefunction(func):
|
|
15
59
|
|
|
16
60
|
@wraps(func)
|
|
17
61
|
def runner(*args: Any, **kwargs: Any) -> Any:
|
|
18
|
-
return
|
|
62
|
+
return _run_coroutine_sync(func(*args, **kwargs))
|
|
19
63
|
|
|
20
64
|
decorator(runner)
|
|
21
65
|
else:
|
|
@@ -26,6 +70,10 @@ class AsyncTyper(Typer):
|
|
|
26
70
|
decorator = super().callback(*args, **kwargs)
|
|
27
71
|
return partial(self.maybe_run_async, decorator)
|
|
28
72
|
|
|
29
|
-
def
|
|
73
|
+
def command(self, *args: Any, **kwargs: Any) -> Any:
|
|
30
74
|
decorator = super().command(*args, **kwargs)
|
|
31
75
|
return partial(self.maybe_run_async, decorator)
|
|
76
|
+
|
|
77
|
+
# keep your existing name if you prefer
|
|
78
|
+
def async_command(self, *args: Any, **kwargs: Any) -> Any:
|
|
79
|
+
return self.command(*args, **kwargs)
|
meshagent/cli/call.py
CHANGED
|
@@ -24,7 +24,7 @@ import pathlib
|
|
|
24
24
|
from pydantic_yaml import parse_yaml_raw_as
|
|
25
25
|
from meshagent.api.participant_token import ParticipantTokenSpec
|
|
26
26
|
|
|
27
|
-
app = async_typer.AsyncTyper()
|
|
27
|
+
app = async_typer.AsyncTyper(help="Trigger agent/tool calls via URL")
|
|
28
28
|
|
|
29
29
|
PRIVATE_NETS = (
|
|
30
30
|
ipaddress.ip_network("10.0.0.0/8"),
|
|
@@ -68,13 +68,13 @@ def is_local_url(url: str) -> bool:
|
|
|
68
68
|
return True
|
|
69
69
|
|
|
70
70
|
|
|
71
|
-
@app.async_command("schema")
|
|
72
|
-
@app.async_command("toolkit")
|
|
73
|
-
@app.async_command("agent")
|
|
74
|
-
@app.async_command("tool")
|
|
71
|
+
@app.async_command("schema", help="Send a call request to a schema webhook URL")
|
|
72
|
+
@app.async_command("toolkit", help="Send a call request to a toolkit webhook URL")
|
|
73
|
+
@app.async_command("agent", help="Send a call request to an agent webhook URL")
|
|
74
|
+
@app.async_command("tool", help="Send a call request to a tool webhook URL")
|
|
75
75
|
async def make_call(
|
|
76
76
|
*,
|
|
77
|
-
project_id: ProjectIdOption
|
|
77
|
+
project_id: ProjectIdOption,
|
|
78
78
|
room: RoomOption,
|
|
79
79
|
role: str = "agent",
|
|
80
80
|
local: Optional[bool] = None,
|
|
@@ -103,6 +103,8 @@ async def make_call(
|
|
|
103
103
|
typer.Option("--key", help="an api key to sign the token with"),
|
|
104
104
|
] = None,
|
|
105
105
|
):
|
|
106
|
+
"""Send a `room.call` request to a URL or in-room agent."""
|
|
107
|
+
|
|
106
108
|
key = await resolve_key(project_id=project_id, key=key)
|
|
107
109
|
|
|
108
110
|
if permissions is not None:
|
|
@@ -136,7 +138,7 @@ async def make_call(
|
|
|
136
138
|
|
|
137
139
|
async def _make_call(
|
|
138
140
|
*,
|
|
139
|
-
project_id: ProjectIdOption
|
|
141
|
+
project_id: ProjectIdOption,
|
|
140
142
|
room: RoomOption,
|
|
141
143
|
role: str = "agent",
|
|
142
144
|
local: Optional[bool] = None,
|
|
@@ -198,7 +200,9 @@ async def _make_call(
|
|
|
198
200
|
"room_url": websocket_room_url(room_name=room),
|
|
199
201
|
"room_name": room,
|
|
200
202
|
"token": token.to_jwt(api_key=key),
|
|
201
|
-
"arguments": arguments
|
|
203
|
+
"arguments": json.loads(arguments)
|
|
204
|
+
if isinstance(arguments, str)
|
|
205
|
+
else arguments,
|
|
202
206
|
}
|
|
203
207
|
|
|
204
208
|
await send_webhook(
|