meshagent-cli 0.0.33__py3-none-any.whl → 0.0.35__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.
Potentially problematic release.
This version of meshagent-cli might be problematic. Click here for more details.
- meshagent/cli/auth_async.py +1 -1
- meshagent/cli/chatbot.py +77 -19
- meshagent/cli/cli.py +126 -0
- meshagent/cli/cli_mcp.py +3 -2
- meshagent/cli/helper.py +6 -0
- meshagent/cli/messaging.py +12 -7
- meshagent/cli/storage.py +8 -2
- meshagent/cli/tty.py +2 -2
- meshagent/cli/version.py +1 -1
- meshagent/cli/voicebot.py +49 -16
- {meshagent_cli-0.0.33.dist-info → meshagent_cli-0.0.35.dist-info}/METADATA +9 -9
- {meshagent_cli-0.0.33.dist-info → meshagent_cli-0.0.35.dist-info}/RECORD +15 -15
- {meshagent_cli-0.0.33.dist-info → meshagent_cli-0.0.35.dist-info}/WHEEL +0 -0
- {meshagent_cli-0.0.33.dist-info → meshagent_cli-0.0.35.dist-info}/entry_points.txt +0 -0
- {meshagent_cli-0.0.33.dist-info → meshagent_cli-0.0.35.dist-info}/top_level.txt +0 -0
meshagent/cli/auth_async.py
CHANGED
|
@@ -58,7 +58,7 @@ async def _wait_for_code() -> str:
|
|
|
58
58
|
return web.Response(status=400)
|
|
59
59
|
|
|
60
60
|
app.add_routes([web.get("/callback", callback)])
|
|
61
|
-
runner = web.AppRunner(app)
|
|
61
|
+
runner = web.AppRunner(app, access_log=None)
|
|
62
62
|
await runner.setup()
|
|
63
63
|
site = web.TCPSite(runner, "localhost", REDIRECT_PORT)
|
|
64
64
|
await site.start()
|
meshagent/cli/chatbot.py
CHANGED
|
@@ -2,19 +2,15 @@
|
|
|
2
2
|
import typer
|
|
3
3
|
from rich import print
|
|
4
4
|
from typing import Annotated, Optional
|
|
5
|
-
import json
|
|
6
|
-
import aiohttp
|
|
7
5
|
from meshagent.tools import Toolkit
|
|
8
6
|
from meshagent.api import RoomClient, ParticipantToken, WebSocketClientProtocol, RoomException
|
|
9
7
|
from meshagent.api.helpers import meshagent_base_url, websocket_room_url
|
|
10
|
-
from meshagent.api.services import send_webhook
|
|
11
8
|
from meshagent.cli import async_typer
|
|
12
|
-
from meshagent.cli.helper import get_client,
|
|
13
|
-
from meshagent.cli.helper import set_active_project, get_active_project, resolve_project_id, resolve_api_key
|
|
9
|
+
from meshagent.cli.helper import get_client, resolve_project_id, resolve_api_key, resolve_token_jwt, resolve_room
|
|
14
10
|
from meshagent.agents.chat import ChatBot
|
|
15
11
|
from meshagent.openai import OpenAIResponsesAdapter
|
|
16
12
|
from meshagent.openai.tools.responses_adapter import LocalShellTool
|
|
17
|
-
|
|
13
|
+
from meshagent.api.services import ServiceHost
|
|
18
14
|
|
|
19
15
|
from meshagent.agents.chat import ChatBotThreadOpenAIImageGenerationTool
|
|
20
16
|
|
|
@@ -28,7 +24,7 @@ app = async_typer.AsyncTyper()
|
|
|
28
24
|
async def make_call(
|
|
29
25
|
*,
|
|
30
26
|
project_id: str = None,
|
|
31
|
-
room: Annotated[str, typer.Option()],
|
|
27
|
+
room: Annotated[Optional[str], typer.Option()] = None,
|
|
32
28
|
api_key_id: Annotated[Optional[str], typer.Option()] = None,
|
|
33
29
|
name: Annotated[str, typer.Option(..., help="Participant name")] = "cli",
|
|
34
30
|
role: str = "agent",
|
|
@@ -36,28 +32,23 @@ async def make_call(
|
|
|
36
32
|
rule: Annotated[List[str], typer.Option("--rule", "-r", help="a system rule")] = [],
|
|
37
33
|
toolkit: Annotated[List[str], typer.Option("--toolkit", "-t", help="the name or url of a required toolkit")] = [],
|
|
38
34
|
schema: Annotated[List[str], typer.Option("--schema", "-s", help="the name or url of a required schema")] = [],
|
|
35
|
+
token_path: Annotated[Optional[str], typer.Option()] = None,
|
|
39
36
|
image_generation: Annotated[Optional[str], typer.Option(..., help="Name of an image gen provider (openai)")] = None,
|
|
40
37
|
):
|
|
41
38
|
account_client = await get_client()
|
|
42
39
|
try:
|
|
43
40
|
project_id = await resolve_project_id(project_id=project_id)
|
|
44
41
|
api_key_id = await resolve_api_key(project_id, api_key_id)
|
|
45
|
-
|
|
46
|
-
key = (await account_client.decrypt_project_api_key(project_id=project_id, id=api_key_id))["token"]
|
|
47
|
-
|
|
48
|
-
token = ParticipantToken(
|
|
49
|
-
name=name,
|
|
50
|
-
project_id=project_id,
|
|
51
|
-
api_key_id=api_key_id
|
|
52
|
-
)
|
|
53
|
-
token.add_role_grant(role=role)
|
|
54
|
-
token.add_room_grant(room)
|
|
55
42
|
|
|
43
|
+
room = resolve_room(room)
|
|
44
|
+
jwt = await resolve_token_jwt(project_id=project_id, api_key_id=api_key_id, token_path=token_path, name=name, role=role, room=room)
|
|
56
45
|
|
|
57
46
|
print("[bold green]Connecting to room...[/bold green]")
|
|
58
47
|
async with RoomClient(
|
|
59
|
-
protocol=WebSocketClientProtocol(
|
|
60
|
-
|
|
48
|
+
protocol=WebSocketClientProtocol(
|
|
49
|
+
url=websocket_room_url(room_name=room, base_url=meshagent_base_url()),
|
|
50
|
+
token=jwt
|
|
51
|
+
)
|
|
61
52
|
) as client:
|
|
62
53
|
|
|
63
54
|
requirements = []
|
|
@@ -102,3 +93,70 @@ async def make_call(
|
|
|
102
93
|
|
|
103
94
|
finally:
|
|
104
95
|
await account_client.close()
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
@app.async_command("service")
|
|
100
|
+
async def service(
|
|
101
|
+
*,
|
|
102
|
+
room: Annotated[Optional[str], typer.Option()] = None,
|
|
103
|
+
|
|
104
|
+
agent_name: Annotated[str, typer.Option(..., help="Name of the agent to call")],
|
|
105
|
+
|
|
106
|
+
rule: Annotated[List[str], typer.Option("--rule", "-r", help="a system rule")] = [],
|
|
107
|
+
toolkit: Annotated[List[str], typer.Option("--toolkit", "-t", help="the name or url of a required toolkit")] = [],
|
|
108
|
+
schema: Annotated[List[str], typer.Option("--schema", "-s", help="the name or url of a required schema")] = [],
|
|
109
|
+
image_generation: Annotated[Optional[str], typer.Option(..., help="Name of an image gen provider (openai)")] = None,
|
|
110
|
+
|
|
111
|
+
host: Annotated[Optional[str], typer.Option()] = None,
|
|
112
|
+
port: Annotated[Optional[int], typer.Option()] = None,
|
|
113
|
+
path: Annotated[str, typer.Option()] = "/agent",
|
|
114
|
+
):
|
|
115
|
+
|
|
116
|
+
room = resolve_room(room)
|
|
117
|
+
|
|
118
|
+
print("[bold green]Connecting to room...[/bold green]")
|
|
119
|
+
|
|
120
|
+
requirements = []
|
|
121
|
+
|
|
122
|
+
toolkits = []
|
|
123
|
+
|
|
124
|
+
for t in toolkit:
|
|
125
|
+
requirements.append(RequiredToolkit(name=t))
|
|
126
|
+
|
|
127
|
+
for t in schema:
|
|
128
|
+
requirements.append(RequiredSchema(name=t))
|
|
129
|
+
|
|
130
|
+
class CustomChatbot(ChatBot):
|
|
131
|
+
|
|
132
|
+
async def get_thread_toolkits(self, *, thread_context, participant):
|
|
133
|
+
toolkits = await super().get_thread_toolkits(thread_context=thread_context, participant=participant)
|
|
134
|
+
|
|
135
|
+
thread_toolkit = Toolkit(name="thread_toolkit", tools=[])
|
|
136
|
+
if image_generation != None:
|
|
137
|
+
if image_generation == "openai":
|
|
138
|
+
print("adding openai image gen to thread")
|
|
139
|
+
thread_toolkit.tools.append(ChatBotThreadOpenAIImageGenerationTool(thread_context=thread_context, partial_images=3))
|
|
140
|
+
else:
|
|
141
|
+
raise Exception("image-generation must be openai")
|
|
142
|
+
toolkits.append(thread_toolkit)
|
|
143
|
+
return toolkits
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
service = ServiceHost(
|
|
147
|
+
host=host,
|
|
148
|
+
port=port
|
|
149
|
+
)
|
|
150
|
+
|
|
151
|
+
@service.path(path=path)
|
|
152
|
+
class CustomChatbot(ChatBot):
|
|
153
|
+
def __init__(self):
|
|
154
|
+
super().__init__(
|
|
155
|
+
llm_adapter=OpenAIResponsesAdapter(),
|
|
156
|
+
name=agent_name,
|
|
157
|
+
requires=requirements,
|
|
158
|
+
toolkits=toolkits,
|
|
159
|
+
rules=rule if len(rule) > 0 else None
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
await service.run()
|
meshagent/cli/cli.py
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import typer
|
|
2
2
|
import asyncio
|
|
3
|
+
from typing import Optional
|
|
3
4
|
|
|
4
5
|
from meshagent.cli import auth
|
|
5
6
|
from meshagent.cli import api_keys
|
|
@@ -41,6 +42,131 @@ app.add_typer(tty.app, name="tty")
|
|
|
41
42
|
def _run_async(coro):
|
|
42
43
|
asyncio.run(coro)
|
|
43
44
|
|
|
45
|
+
|
|
46
|
+
import os, sys
|
|
47
|
+
from pathlib import Path
|
|
48
|
+
import typer
|
|
49
|
+
from meshagent.cli.helper import get_client, set_active_project, get_active_project, resolve_project_id, resolve_api_key
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
def detect_shell() -> str:
|
|
53
|
+
"""
|
|
54
|
+
Best-effort detection of the *current* interactive shell.
|
|
55
|
+
|
|
56
|
+
Order of preference
|
|
57
|
+
1. Explicit --shell argument (handled by Typer)
|
|
58
|
+
2. Per-shell env vars set by the running shell
|
|
59
|
+
• BASH_VERSION / ZSH_VERSION / FISH_VERSION
|
|
60
|
+
3. $SHELL on POSIX (user’s login shell – still correct >90 % of the time)
|
|
61
|
+
4. Parent process on Windows (COMSPEC → cmd / powershell)
|
|
62
|
+
5. Safe default: 'bash'
|
|
63
|
+
"""
|
|
64
|
+
# Per-shell version variables (works even if login shell ≠ current shell)
|
|
65
|
+
for var, name in (
|
|
66
|
+
("ZSH_VERSION", "zsh"),
|
|
67
|
+
("BASH_VERSION", "bash"),
|
|
68
|
+
("FISH_VERSION", "fish"),
|
|
69
|
+
):
|
|
70
|
+
if var in os.environ:
|
|
71
|
+
return name
|
|
72
|
+
|
|
73
|
+
# POSIX fallback: login shell path
|
|
74
|
+
sh = os.environ.get("SHELL")
|
|
75
|
+
if sh:
|
|
76
|
+
return Path(sh).name.lower()
|
|
77
|
+
|
|
78
|
+
# Windows heuristics
|
|
79
|
+
if sys.platform == "win32":
|
|
80
|
+
comspec = Path(os.environ.get("COMSPEC", "")).name.lower()
|
|
81
|
+
if "powershell" in comspec:
|
|
82
|
+
return "powershell"
|
|
83
|
+
if "cmd" in comspec:
|
|
84
|
+
return "cmd"
|
|
85
|
+
return "powershell" # sensible default on modern Windows
|
|
86
|
+
|
|
87
|
+
# Last-ditch default
|
|
88
|
+
return "bash"
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
def _bash_like(name: str, value: str, unset: bool) -> str:
|
|
92
|
+
return f'unset {name}' if unset else f'export {name}="{value}"'
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
def _fish(name: str, value: str, unset: bool) -> str:
|
|
96
|
+
return f'set -e {name}' if unset else f'set -gx {name} "{value}"'
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
def _powershell(name: str, value: str, unset: bool) -> str:
|
|
100
|
+
return f'Remove-Item Env:{name}' if unset else f'$Env:{name}="{value}"'
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def _cmd(name: str, value: str, unset: bool) -> str:
|
|
104
|
+
return f'set {name}=' if unset else f'set {name}={value}'
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
SHELL_RENDERERS = {
|
|
108
|
+
"bash": _bash_like,
|
|
109
|
+
"zsh": _bash_like,
|
|
110
|
+
"fish": _fish,
|
|
111
|
+
"powershell": _powershell,
|
|
112
|
+
"cmd": _cmd,
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
@app.command(
|
|
117
|
+
"env",
|
|
118
|
+
help="Generate commands to set meshagent environment variables.",
|
|
119
|
+
)
|
|
120
|
+
def env(
|
|
121
|
+
shell: Optional[str] = typer.Option(None,
|
|
122
|
+
"--shell",
|
|
123
|
+
case_sensitive=False,
|
|
124
|
+
help="bash | zsh | fish | powershell | cmd",
|
|
125
|
+
),
|
|
126
|
+
unset: bool = typer.Option(
|
|
127
|
+
False, "--unset", help="Output commands to unset the variables."
|
|
128
|
+
),
|
|
129
|
+
):
|
|
130
|
+
"""Print shell-specific exports/unsets for Docker environment variables."""
|
|
131
|
+
|
|
132
|
+
async def command():
|
|
133
|
+
nonlocal shell, unset
|
|
134
|
+
shell = (shell or detect_shell()).lower()
|
|
135
|
+
if shell not in SHELL_RENDERERS:
|
|
136
|
+
typer.echo(f"Unsupported shell '{shell}'.", err=True)
|
|
137
|
+
raise typer.Exit(code=1)
|
|
138
|
+
|
|
139
|
+
client = await get_client()
|
|
140
|
+
try:
|
|
141
|
+
project_id = await resolve_project_id(project_id=None)
|
|
142
|
+
api_key_id = await resolve_api_key(project_id=project_id, api_key_id=None)
|
|
143
|
+
|
|
144
|
+
token = (await client.decrypt_project_api_key(project_id=project_id, id=api_key_id))["token"]
|
|
145
|
+
finally:
|
|
146
|
+
await client.close()
|
|
147
|
+
|
|
148
|
+
vars = {
|
|
149
|
+
"MESHAGENT_PROJECT_ID" : project_id,
|
|
150
|
+
"MESHAGENT_API_KEY" : api_key_id,
|
|
151
|
+
"MESHAGENT_SECRET" : token
|
|
152
|
+
}
|
|
153
|
+
if shell not in SHELL_RENDERERS:
|
|
154
|
+
typer.echo(f"Unsupported shell '{shell}'.", err=True)
|
|
155
|
+
raise typer.Exit(code=1)
|
|
156
|
+
|
|
157
|
+
render = SHELL_RENDERERS[shell]
|
|
158
|
+
|
|
159
|
+
for name, value in vars.items():
|
|
160
|
+
typer.echo(render(name, value, unset))
|
|
161
|
+
|
|
162
|
+
if not unset and shell in ("bash", "zsh"):
|
|
163
|
+
typer.echo(
|
|
164
|
+
'\n# Run this command to configure your current shell:\n'
|
|
165
|
+
f'# eval "$(meshagent env)"'
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
_run_async(command())
|
|
169
|
+
|
|
44
170
|
@app.command("setup")
|
|
45
171
|
def setup_command():
|
|
46
172
|
"""Perform initial login and project/api key activation."""
|
meshagent/cli/cli_mcp.py
CHANGED
|
@@ -10,8 +10,7 @@ from typing import Annotated, Optional, List
|
|
|
10
10
|
from meshagent.api.helpers import meshagent_base_url, websocket_room_url
|
|
11
11
|
from meshagent.api import RoomClient, ParticipantToken, WebSocketClientProtocol, RoomException
|
|
12
12
|
from meshagent.cli import async_typer
|
|
13
|
-
from meshagent.cli.helper import get_client,
|
|
14
|
-
from meshagent.cli.helper import set_active_project, get_active_project, resolve_project_id, resolve_api_key, resolve_token_jwt
|
|
13
|
+
from meshagent.cli.helper import get_client, resolve_project_id, resolve_api_key, resolve_token_jwt, resolve_room
|
|
15
14
|
|
|
16
15
|
from meshagent.tools.hosting import RemoteToolkit, RemoteToolkitServer
|
|
17
16
|
|
|
@@ -36,6 +35,7 @@ async def sse(*, project_id: str = None, room: Annotated[str, typer.Option()], t
|
|
|
36
35
|
project_id = await resolve_project_id(project_id=project_id)
|
|
37
36
|
api_key_id = await resolve_api_key(project_id, api_key_id)
|
|
38
37
|
|
|
38
|
+
room = resolve_room(room)
|
|
39
39
|
jwt = await resolve_token_jwt(project_id=project_id, api_key_id=api_key_id, token_path=token_path, name=name, role=role, room=room)
|
|
40
40
|
|
|
41
41
|
print("[bold green]Connecting to room...[/bold green]")
|
|
@@ -73,6 +73,7 @@ async def stdio(*, project_id: str = None, room: Annotated[str, typer.Option()],
|
|
|
73
73
|
project_id = await resolve_project_id(project_id=project_id)
|
|
74
74
|
api_key_id = await resolve_api_key(project_id, api_key_id)
|
|
75
75
|
|
|
76
|
+
room = resolve_room(room)
|
|
76
77
|
jwt = await resolve_token_jwt(project_id=project_id, api_key_id=api_key_id, token_path=token_path, name=name, role=role, room=room)
|
|
77
78
|
|
|
78
79
|
print("[bold green]Connecting to room...[/bold green]")
|
meshagent/cli/helper.py
CHANGED
|
@@ -92,6 +92,12 @@ def print_json_table(records: list, *cols):
|
|
|
92
92
|
Console().print(table)
|
|
93
93
|
|
|
94
94
|
|
|
95
|
+
def resolve_room(room_name: Optional[str] = None):
|
|
96
|
+
if room_name == None:
|
|
97
|
+
room_name = os.getenv("MESHAGENT_ROOM")
|
|
98
|
+
|
|
99
|
+
return room_name
|
|
100
|
+
|
|
95
101
|
async def resolve_project_id(project_id: Optional[str] = None):
|
|
96
102
|
if project_id == None:
|
|
97
103
|
project_id = await get_active_project()
|
meshagent/cli/messaging.py
CHANGED
|
@@ -6,16 +6,16 @@ import json
|
|
|
6
6
|
from meshagent.api import RoomClient, ParticipantToken, WebSocketClientProtocol
|
|
7
7
|
from meshagent.api.helpers import meshagent_base_url, websocket_room_url
|
|
8
8
|
from meshagent.cli import async_typer
|
|
9
|
-
from meshagent.cli.helper import get_client, resolve_project_id, resolve_api_key, resolve_token_jwt
|
|
9
|
+
from meshagent.cli.helper import get_client, resolve_project_id, resolve_api_key, resolve_token_jwt, resolve_room
|
|
10
10
|
|
|
11
11
|
app = async_typer.AsyncTyper()
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
@app.async_command("list")
|
|
14
|
+
@app.async_command("list-participants")
|
|
15
15
|
async def messaging_list_participants_command(
|
|
16
16
|
*,
|
|
17
17
|
project_id: str = None,
|
|
18
|
-
room: Annotated[str, typer.Option()],
|
|
18
|
+
room: Annotated[Optional[str], typer.Option()] = None,
|
|
19
19
|
token_path: Annotated[Optional[str], typer.Option()] = None,
|
|
20
20
|
api_key_id: Annotated[Optional[str], typer.Option()] = None,
|
|
21
21
|
name: Annotated[str, typer.Option()] = "cli",
|
|
@@ -29,7 +29,9 @@ async def messaging_list_participants_command(
|
|
|
29
29
|
# Resolve project_id if not provided
|
|
30
30
|
project_id = await resolve_project_id(project_id=project_id)
|
|
31
31
|
api_key_id = await resolve_api_key(project_id, api_key_id)
|
|
32
|
-
|
|
32
|
+
|
|
33
|
+
room = resolve_room(room)
|
|
34
|
+
|
|
33
35
|
jwt = await resolve_token_jwt(project_id=project_id, api_key_id=api_key_id, token_path=token_path, name=name, role=role, room=room)
|
|
34
36
|
|
|
35
37
|
print("[bold green]Connecting to room...[/bold green]")
|
|
@@ -65,7 +67,7 @@ async def messaging_list_participants_command(
|
|
|
65
67
|
async def messaging_send_command(
|
|
66
68
|
*,
|
|
67
69
|
project_id: str = None,
|
|
68
|
-
room: Annotated[str, typer.Option()],
|
|
70
|
+
room: Annotated[Optional[str], typer.Option()] = None,
|
|
69
71
|
token_path: Annotated[Optional[str], typer.Option()] = None,
|
|
70
72
|
api_key_id: Annotated[Optional[str], typer.Option()] = None,
|
|
71
73
|
name: Annotated[str, typer.Option()] = "cli",
|
|
@@ -81,7 +83,9 @@ async def messaging_send_command(
|
|
|
81
83
|
# Resolve project_id if not provided
|
|
82
84
|
project_id = await resolve_project_id(project_id=project_id)
|
|
83
85
|
api_key_id = await resolve_api_key(project_id, api_key_id)
|
|
84
|
-
|
|
86
|
+
|
|
87
|
+
room = resolve_room(room)
|
|
88
|
+
|
|
85
89
|
jwt = await resolve_token_jwt(project_id=project_id, api_key_id=api_key_id, token_path=token_path, name=name, role=role, room=room)
|
|
86
90
|
|
|
87
91
|
print("[bold green]Connecting to room...[/bold green]")
|
|
@@ -124,7 +128,7 @@ async def messaging_send_command(
|
|
|
124
128
|
async def messaging_broadcast_command(
|
|
125
129
|
*,
|
|
126
130
|
project_id: str = None,
|
|
127
|
-
room: Annotated[str, typer.Option()],
|
|
131
|
+
room: Annotated[Optional[str], typer.Option()] = None,
|
|
128
132
|
token_path: Annotated[Optional[str], typer.Option()] = None,
|
|
129
133
|
api_key_id: Annotated[Optional[str], typer.Option()] = None,
|
|
130
134
|
name: Annotated[str, typer.Option()] = "cli",
|
|
@@ -140,6 +144,7 @@ async def messaging_broadcast_command(
|
|
|
140
144
|
project_id = await resolve_project_id(project_id=project_id)
|
|
141
145
|
api_key_id = await resolve_api_key(project_id, api_key_id)
|
|
142
146
|
|
|
147
|
+
room = resolve_room(room)
|
|
143
148
|
jwt = await resolve_token_jwt(project_id=project_id, api_key_id=api_key_id, token_path=token_path, name=name, role=role, room=room)
|
|
144
149
|
|
|
145
150
|
print("[bold green]Connecting to room...[/bold green]")
|
meshagent/cli/storage.py
CHANGED
|
@@ -11,6 +11,7 @@ from meshagent.api.room_server_client import StorageClient
|
|
|
11
11
|
from meshagent.api.helpers import meshagent_base_url, websocket_room_url
|
|
12
12
|
from meshagent.cli import async_typer
|
|
13
13
|
from meshagent.cli.helper import get_client, resolve_project_id, resolve_api_key, resolve_token_jwt
|
|
14
|
+
from meshagent.cli.helper import get_client, resolve_project_id, resolve_api_key, resolve_token_jwt, resolve_room
|
|
14
15
|
|
|
15
16
|
app = async_typer.AsyncTyper()
|
|
16
17
|
|
|
@@ -63,7 +64,7 @@ async def storage_exists_command(
|
|
|
63
64
|
try:
|
|
64
65
|
project_id = await resolve_project_id(project_id=project_id)
|
|
65
66
|
api_key_id = await resolve_api_key(project_id, api_key_id)
|
|
66
|
-
|
|
67
|
+
room = resolve_room(room)
|
|
67
68
|
jwt = await resolve_token_jwt(project_id=project_id, api_key_id=api_key_id, token_path=token_path, name=name, role=role, room=room)
|
|
68
69
|
|
|
69
70
|
print("[bold green]Connecting to room...[/bold green]")
|
|
@@ -95,6 +96,8 @@ async def storage_cp_command(
|
|
|
95
96
|
source_path: str,
|
|
96
97
|
dest_path: str
|
|
97
98
|
):
|
|
99
|
+
room = resolve_room(room)
|
|
100
|
+
|
|
98
101
|
try:
|
|
99
102
|
"""
|
|
100
103
|
Copy files between local and remote storage. Supports globs on the source side.
|
|
@@ -310,8 +313,10 @@ async def storage_show_command(
|
|
|
310
313
|
"""
|
|
311
314
|
Print the contents of a file (local or remote) to the console.
|
|
312
315
|
"""
|
|
316
|
+
room = resolve_room(room)
|
|
317
|
+
|
|
313
318
|
scheme, subpath = parse_path(path)
|
|
314
|
-
|
|
319
|
+
|
|
315
320
|
# If we need a remote connection, set it up:
|
|
316
321
|
account_client = None
|
|
317
322
|
client = None
|
|
@@ -388,6 +393,7 @@ async def storage_rm_command(
|
|
|
388
393
|
- Supports wildcards on the source path (for files).
|
|
389
394
|
- Fails if trying to remove a directory/folder without --recursive/-r.
|
|
390
395
|
"""
|
|
396
|
+
room = resolve_room(room)
|
|
391
397
|
|
|
392
398
|
try:
|
|
393
399
|
# We'll mimic the "cp" approach, expanding wildcards for local/remote.
|
meshagent/cli/tty.py
CHANGED
|
@@ -2,6 +2,7 @@ import pathlib
|
|
|
2
2
|
import sys
|
|
3
3
|
import tty
|
|
4
4
|
import termios
|
|
5
|
+
from meshagent.api.helpers import websocket_room_url
|
|
5
6
|
from typing import Annotated, Optional
|
|
6
7
|
|
|
7
8
|
import asyncio
|
|
@@ -46,10 +47,9 @@ async def tty_command(
|
|
|
46
47
|
)
|
|
47
48
|
|
|
48
49
|
token.add_role_grant(role="user")
|
|
49
|
-
|
|
50
50
|
token.add_room_grant(room)
|
|
51
51
|
|
|
52
|
-
ws_url =
|
|
52
|
+
ws_url = websocket_room_url(room_name=room)+"/tty?token={token.to_jwt(token=key)}"
|
|
53
53
|
|
|
54
54
|
print(f"[bold green]Connecting to[/bold green] {room}")
|
|
55
55
|
|
meshagent/cli/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.0.
|
|
1
|
+
__version__ = "0.0.35"
|
meshagent/cli/voicebot.py
CHANGED
|
@@ -8,13 +8,12 @@ from meshagent.api import RoomClient, ParticipantToken, WebSocketClientProtocol,
|
|
|
8
8
|
from meshagent.api.helpers import meshagent_base_url, websocket_room_url
|
|
9
9
|
from meshagent.api.services import send_webhook
|
|
10
10
|
from meshagent.cli import async_typer
|
|
11
|
-
from meshagent.cli.helper import get_client,
|
|
12
|
-
from meshagent.cli.helper import set_active_project, get_active_project, resolve_project_id, resolve_api_key
|
|
11
|
+
from meshagent.cli.helper import get_client, resolve_project_id, resolve_api_key, resolve_token_jwt, resolve_room
|
|
13
12
|
from meshagent.openai import OpenAIResponsesAdapter
|
|
14
13
|
from typing import List
|
|
15
14
|
|
|
16
15
|
from meshagent.api import RequiredToolkit, RequiredSchema
|
|
17
|
-
|
|
16
|
+
from meshagent.api.services import ServiceHost
|
|
18
17
|
|
|
19
18
|
try:
|
|
20
19
|
|
|
@@ -34,7 +33,7 @@ app = async_typer.AsyncTyper()
|
|
|
34
33
|
async def make_call(
|
|
35
34
|
*,
|
|
36
35
|
project_id: str = None,
|
|
37
|
-
room: Annotated[str, typer.Option()],
|
|
36
|
+
room: Annotated[Optional[str], typer.Option()] = None,
|
|
38
37
|
api_key_id: Annotated[Optional[str], typer.Option()] = None,
|
|
39
38
|
name: Annotated[str, typer.Option(..., help="Participant name")] = "cli",
|
|
40
39
|
role: str = "agent",
|
|
@@ -44,27 +43,19 @@ async def make_call(
|
|
|
44
43
|
schema: Annotated[List[str], typer.Option("--schema", "-s", help="the name or url of a required schema")] = [],
|
|
45
44
|
auto_greet_message: Annotated[Optional[str], typer.Option()] = None,
|
|
46
45
|
auto_greet_prompt: Annotated[Optional[str], typer.Option()] = None,
|
|
46
|
+
token_path: Annotated[Optional[str], typer.Option()] = None,
|
|
47
47
|
):
|
|
48
48
|
account_client = await get_client()
|
|
49
49
|
try:
|
|
50
50
|
project_id = await resolve_project_id(project_id=project_id)
|
|
51
51
|
api_key_id = await resolve_api_key(project_id, api_key_id)
|
|
52
52
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
token = ParticipantToken(
|
|
56
|
-
name=name,
|
|
57
|
-
project_id=project_id,
|
|
58
|
-
api_key_id=api_key_id
|
|
59
|
-
)
|
|
60
|
-
token.add_role_grant(role=role)
|
|
61
|
-
token.add_room_grant(room)
|
|
62
|
-
|
|
53
|
+
room = resolve_room(room)
|
|
54
|
+
jwt = await resolve_token_jwt(project_id=project_id, api_key_id=api_key_id, token_path=token_path, name=name, role=role, room=room)
|
|
63
55
|
|
|
64
56
|
print("[bold green]Connecting to room...[/bold green]")
|
|
65
57
|
async with RoomClient(
|
|
66
|
-
protocol=WebSocketClientProtocol(url=websocket_room_url(room_name=room, base_url=meshagent_base_url()),
|
|
67
|
-
token=token.to_jwt(token=key))
|
|
58
|
+
protocol=WebSocketClientProtocol(url=websocket_room_url(room_name=room, base_url=meshagent_base_url()), token=jwt)
|
|
68
59
|
) as client:
|
|
69
60
|
|
|
70
61
|
requirements = []
|
|
@@ -92,3 +83,45 @@ async def make_call(
|
|
|
92
83
|
|
|
93
84
|
finally:
|
|
94
85
|
await account_client.close()
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
@app.async_command("service")
|
|
89
|
+
async def service(
|
|
90
|
+
*,
|
|
91
|
+
project_id: str = None,
|
|
92
|
+
agent_name: Annotated[str, typer.Option(..., help="Name of the agent to call")],
|
|
93
|
+
rule: Annotated[List[str], typer.Option("--rule", "-r", help="a system rule")] = [],
|
|
94
|
+
toolkit: Annotated[List[str], typer.Option("--toolkit", "-t", help="the name or url of a required toolkit")] = [],
|
|
95
|
+
schema: Annotated[List[str], typer.Option("--schema", "-s", help="the name or url of a required schema")] = [],
|
|
96
|
+
auto_greet_message: Annotated[Optional[str], typer.Option()] = None,
|
|
97
|
+
auto_greet_prompt: Annotated[Optional[str], typer.Option()] = None,
|
|
98
|
+
|
|
99
|
+
host: Annotated[Optional[str], typer.Option()] = None,
|
|
100
|
+
port: Annotated[Optional[int], typer.Option()] = None,
|
|
101
|
+
path: Annotated[str, typer.Option()] = "/agent",
|
|
102
|
+
):
|
|
103
|
+
requirements = []
|
|
104
|
+
|
|
105
|
+
for t in toolkit:
|
|
106
|
+
requirements.append(RequiredToolkit(name=t))
|
|
107
|
+
|
|
108
|
+
for t in schema:
|
|
109
|
+
requirements.append(RequiredSchema(name=t))
|
|
110
|
+
|
|
111
|
+
service = ServiceHost(
|
|
112
|
+
host=host,
|
|
113
|
+
port=port
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
@service.path(path=path)
|
|
117
|
+
class CustomVoiceBot(VoiceBot):
|
|
118
|
+
def __init__(self):
|
|
119
|
+
super().__init__(
|
|
120
|
+
auto_greet_message=auto_greet_message,
|
|
121
|
+
auto_greet_prompt=auto_greet_prompt,
|
|
122
|
+
name=agent_name,
|
|
123
|
+
requires=requirements,
|
|
124
|
+
rules=rule if len(rule) > 0 else None
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
await service.run()
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: meshagent-cli
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.35
|
|
4
4
|
Summary: CLI for Meshagent
|
|
5
5
|
License-Expression: Apache-2.0
|
|
6
6
|
Project-URL: Documentation, https://docs.meshagent.com
|
|
@@ -8,14 +8,14 @@ Project-URL: Website, https://www.meshagent.com
|
|
|
8
8
|
Project-URL: Source, https://www.meshagent.com
|
|
9
9
|
Requires-Python: >=3.12
|
|
10
10
|
Description-Content-Type: text/markdown
|
|
11
|
-
Requires-Dist: typer~=0.15
|
|
12
|
-
Requires-Dist: pydantic-yaml~=1.4
|
|
13
|
-
Requires-Dist: meshagent-api~=0.0.
|
|
14
|
-
Requires-Dist: meshagent-agents~=0.0.
|
|
15
|
-
Requires-Dist: meshagent-tools~=0.0.
|
|
16
|
-
Requires-Dist: meshagent-mcp~=0.0.
|
|
17
|
-
Requires-Dist: supabase~=2.15
|
|
18
|
-
Requires-Dist: fastmcp~=2.8
|
|
11
|
+
Requires-Dist: typer~=0.15
|
|
12
|
+
Requires-Dist: pydantic-yaml~=1.4
|
|
13
|
+
Requires-Dist: meshagent-api~=0.0.35
|
|
14
|
+
Requires-Dist: meshagent-agents~=0.0.35
|
|
15
|
+
Requires-Dist: meshagent-tools~=0.0.35
|
|
16
|
+
Requires-Dist: meshagent-mcp~=0.0.35
|
|
17
|
+
Requires-Dist: supabase~=2.15
|
|
18
|
+
Requires-Dist: fastmcp~=2.8
|
|
19
19
|
|
|
20
20
|
### Meshagent CLI
|
|
21
21
|
|
|
@@ -3,26 +3,26 @@ meshagent/cli/agent.py,sha256=0VjwJkwZ-G637Mps3OtxxWIfjWbrirJ4TTq2Idvjtug,10023
|
|
|
3
3
|
meshagent/cli/api_keys.py,sha256=VZynVFCBwxcwJ6dtxcoqKB91B0_QsUfJTim4vUXGvKc,4550
|
|
4
4
|
meshagent/cli/async_typer.py,sha256=GCeSefBDbpd-V4V8LrvHGUTBMth3HspVMfFa-HUZ0cg,898
|
|
5
5
|
meshagent/cli/auth.py,sha256=pZQwYTNWQOWTqpyDrkQLNKuidH-wn9GNE5yEJoxn3-g,767
|
|
6
|
-
meshagent/cli/auth_async.py,sha256=
|
|
6
|
+
meshagent/cli/auth_async.py,sha256=run_J11mRPJQ6BI_aAtV_3O3h52eAl1EOnHuotwhoqQ,4018
|
|
7
7
|
meshagent/cli/call.py,sha256=-6Bf5PCVcsuLMgDpG1g3GiY3S5rgs_-CWgWX4C6AXwg,4739
|
|
8
|
-
meshagent/cli/chatbot.py,sha256=
|
|
9
|
-
meshagent/cli/cli.py,sha256=
|
|
10
|
-
meshagent/cli/cli_mcp.py,sha256=
|
|
8
|
+
meshagent/cli/chatbot.py,sha256=_ZuEpWwj1tYpu4CxuoQ4OXAk4LEkD1Qfmt-bOsjkkBU,6437
|
|
9
|
+
meshagent/cli/cli.py,sha256=L3DaoAy03buBemBiltTSgcV9aq9I044pkg6zoZPKzYc,5937
|
|
10
|
+
meshagent/cli/cli_mcp.py,sha256=SG0r-cL3P7eu-fbwB-1WgjQPCmxKqQBh-X3kTKDli-E,9536
|
|
11
11
|
meshagent/cli/cli_secrets.py,sha256=U0kdzN3zt7JIqzdRLynAjxdvAsI0enesBd_m7TeXjnQ,13629
|
|
12
12
|
meshagent/cli/developer.py,sha256=5eoDr3kfi-IufA5d6OESqNr739Bdut_IFBtT3nq0xZU,3002
|
|
13
|
-
meshagent/cli/helper.py,sha256=
|
|
14
|
-
meshagent/cli/messaging.py,sha256=
|
|
13
|
+
meshagent/cli/helper.py,sha256=39_oznxO4sCi3namCJzYC0eWqeeGNlen1zlOuWF43os,4785
|
|
14
|
+
meshagent/cli/messaging.py,sha256=bHMecKtVwY8P11itXMIvaLxPv-Zm6SpgrXnLDppb4Gc,6282
|
|
15
15
|
meshagent/cli/participant_token.py,sha256=uCGmlUgNOfarYGkDZpzreXwnv9AJrM76tu5Lt690vYU,1456
|
|
16
16
|
meshagent/cli/projects.py,sha256=EQfbO9_GQKkjlFcaSHQfIxqIxsmFR3FbH5Fd17I5IPk,3305
|
|
17
17
|
meshagent/cli/services.py,sha256=pMAyLg0eEO33fhRiin5q0KbNVoTzQyT5wSDgvDqeRYM,11241
|
|
18
18
|
meshagent/cli/sessions.py,sha256=WWvuztYqRfthSq6ztwL_eQ_sz9JRc33jcN6p7YyM_Fs,782
|
|
19
|
-
meshagent/cli/storage.py,sha256=
|
|
20
|
-
meshagent/cli/tty.py,sha256=
|
|
21
|
-
meshagent/cli/version.py,sha256=
|
|
22
|
-
meshagent/cli/voicebot.py,sha256=
|
|
19
|
+
meshagent/cli/storage.py,sha256=Se_4xhxiihIovSR1ajlEWo_YZ12G7eUY_-lvifJ8pjo,33806
|
|
20
|
+
meshagent/cli/tty.py,sha256=DkgeYQckjil191HNoEGHmheniCi41XNUSMpYY1ilAic,4099
|
|
21
|
+
meshagent/cli/version.py,sha256=QmUV3Ydc9xA0pOuihDI_wM1kvEzVZrdkq2eiedTW2UA,23
|
|
22
|
+
meshagent/cli/voicebot.py,sha256=5vB0yzcKVvQ-nq2in51Xlf-rWbJB8Mjc8V44me6mUD4,4701
|
|
23
23
|
meshagent/cli/webhook.py,sha256=KBl8U1TcOX3z2uoyH4YMuUuw0vSVX7xpRxYvzxI5c-Y,2811
|
|
24
|
-
meshagent_cli-0.0.
|
|
25
|
-
meshagent_cli-0.0.
|
|
26
|
-
meshagent_cli-0.0.
|
|
27
|
-
meshagent_cli-0.0.
|
|
28
|
-
meshagent_cli-0.0.
|
|
24
|
+
meshagent_cli-0.0.35.dist-info/METADATA,sha256=5tcx5aulHPt6KgjOIdaih5sXkMGB1Dp7SiLPIg5H7o4,627
|
|
25
|
+
meshagent_cli-0.0.35.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
26
|
+
meshagent_cli-0.0.35.dist-info/entry_points.txt,sha256=WRcGGN4vMtvC5Pgl3uRFqsJiQXNoHuLLa-TCSY3gAhQ,52
|
|
27
|
+
meshagent_cli-0.0.35.dist-info/top_level.txt,sha256=GlcXnHtRP6m7zlG3Df04M35OsHtNXy_DY09oFwWrH74,10
|
|
28
|
+
meshagent_cli-0.0.35.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|