meshagent-cli 0.0.17__tar.gz → 0.0.18__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.

Potentially problematic release.


This version of meshagent-cli might be problematic. Click here for more details.

Files changed (32) hide show
  1. {meshagent_cli-0.0.17 → meshagent_cli-0.0.18}/PKG-INFO +4 -4
  2. {meshagent_cli-0.0.17 → meshagent_cli-0.0.18}/meshagent/cli/agent.py +15 -35
  3. {meshagent_cli-0.0.17 → meshagent_cli-0.0.18}/meshagent/cli/api_keys.py +2 -3
  4. {meshagent_cli-0.0.17 → meshagent_cli-0.0.18}/meshagent/cli/auth.py +1 -4
  5. {meshagent_cli-0.0.17 → meshagent_cli-0.0.18}/meshagent/cli/cli_mcp.py +18 -32
  6. {meshagent_cli-0.0.17 → meshagent_cli-0.0.18}/meshagent/cli/helper.py +49 -8
  7. {meshagent_cli-0.0.17 → meshagent_cli-0.0.18}/meshagent/cli/messaging.py +14 -40
  8. {meshagent_cli-0.0.17 → meshagent_cli-0.0.18}/meshagent/cli/participant_token.py +14 -7
  9. {meshagent_cli-0.0.17 → meshagent_cli-0.0.18}/meshagent/cli/storage.py +33 -71
  10. meshagent_cli-0.0.18/meshagent/cli/version.py +1 -0
  11. {meshagent_cli-0.0.17 → meshagent_cli-0.0.18}/meshagent/cli/webhook.py +3 -2
  12. {meshagent_cli-0.0.17 → meshagent_cli-0.0.18}/meshagent_cli.egg-info/PKG-INFO +4 -4
  13. meshagent_cli-0.0.18/meshagent_cli.egg-info/requires.txt +5 -0
  14. {meshagent_cli-0.0.17 → meshagent_cli-0.0.18}/pyproject.toml +3 -3
  15. meshagent_cli-0.0.17/meshagent/cli/version.py +0 -1
  16. meshagent_cli-0.0.17/meshagent_cli.egg-info/requires.txt +0 -5
  17. {meshagent_cli-0.0.17 → meshagent_cli-0.0.18}/README.md +0 -0
  18. {meshagent_cli-0.0.17 → meshagent_cli-0.0.18}/meshagent/cli/__init__.py +0 -0
  19. {meshagent_cli-0.0.17 → meshagent_cli-0.0.18}/meshagent/cli/async_typer.py +0 -0
  20. {meshagent_cli-0.0.17 → meshagent_cli-0.0.18}/meshagent/cli/auth_async.py +0 -0
  21. {meshagent_cli-0.0.17 → meshagent_cli-0.0.18}/meshagent/cli/call.py +5 -5
  22. {meshagent_cli-0.0.17 → meshagent_cli-0.0.18}/meshagent/cli/cli.py +0 -0
  23. {meshagent_cli-0.0.17 → meshagent_cli-0.0.18}/meshagent/cli/cli_secrets.py +2 -2
  24. {meshagent_cli-0.0.17 → meshagent_cli-0.0.18}/meshagent/cli/developer.py +3 -3
  25. {meshagent_cli-0.0.17 → meshagent_cli-0.0.18}/meshagent/cli/projects.py +2 -2
  26. {meshagent_cli-0.0.17 → meshagent_cli-0.0.18}/meshagent/cli/services.py +2 -2
  27. {meshagent_cli-0.0.17 → meshagent_cli-0.0.18}/meshagent/cli/sessions.py +0 -0
  28. {meshagent_cli-0.0.17 → meshagent_cli-0.0.18}/meshagent_cli.egg-info/SOURCES.txt +0 -0
  29. {meshagent_cli-0.0.17 → meshagent_cli-0.0.18}/meshagent_cli.egg-info/dependency_links.txt +0 -0
  30. {meshagent_cli-0.0.17 → meshagent_cli-0.0.18}/meshagent_cli.egg-info/entry_points.txt +0 -0
  31. {meshagent_cli-0.0.17 → meshagent_cli-0.0.18}/meshagent_cli.egg-info/top_level.txt +0 -0
  32. {meshagent_cli-0.0.17 → meshagent_cli-0.0.18}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: meshagent-cli
3
- Version: 0.0.17
3
+ Version: 0.0.18
4
4
  Summary: CLI for Meshagent
5
5
  License-Expression: LicenseRef-Proprietary
6
6
  Project-URL: Documentation, https://meshagent.com
@@ -10,9 +10,9 @@ Requires-Python: >=3.9.0
10
10
  Description-Content-Type: text/markdown
11
11
  Requires-Dist: typer~=0.15.3
12
12
  Requires-Dist: pydantic-yaml~=1.4.0
13
- Requires-Dist: meshagent-api~=0.0.17
14
- Requires-Dist: meshagent-agents~=0.0.17
15
- Requires-Dist: meshagent-tools~=0.0.17
13
+ Requires-Dist: meshagent-api~=0.0.18
14
+ Requires-Dist: meshagent-agents~=0.0.18
15
+ Requires-Dist: meshagent-tools~=0.0.18
16
16
 
17
17
  ### Meshagent CLI
18
18
 
@@ -1,15 +1,15 @@
1
- from meshagent.cli import async_typer
2
1
  import typer
3
- from meshagent.cli.helper import get_client, print_json_table, set_active_project, resolve_project_id
4
2
  from rich import print
5
- from meshagent.api import RoomClient, ParticipantToken, WebSocketClientProtocol, RoomException
6
- from meshagent.cli.helper import set_active_project, get_active_project, resolve_project_id, resolve_api_key
7
3
  from typing import Annotated, Optional
8
- from meshagent.api.helpers import meshagent_base_url, websocket_room_url
9
4
  import json
10
5
  import asyncio
11
- import aiohttp
6
+
7
+ from meshagent.api.helpers import meshagent_base_url, websocket_room_url
12
8
  from meshagent.api.services import send_webhook
9
+ from meshagent.api import RoomClient, ParticipantToken, WebSocketClientProtocol, RoomException
10
+ from meshagent.cli.helper import set_active_project, get_active_project, resolve_project_id, resolve_api_key
11
+ from meshagent.cli import async_typer
12
+ from meshagent.cli.helper import get_client, print_json_table, set_active_project, resolve_project_id, resolve_token_jwt
13
13
 
14
14
  app = async_typer.AsyncTyper()
15
15
 
@@ -71,6 +71,7 @@ async def invoke_tool(
71
71
  *,
72
72
  project_id: str = None,
73
73
  room: Annotated[str, typer.Option()],
74
+ token_path: Annotated[Optional[str], typer.Option()] = None,
74
75
  api_key_id: Annotated[Optional[str], typer.Option()] = None,
75
76
  name: Annotated[str, typer.Option(..., help="Participant name")] = "cli",
76
77
  role: str = "user",
@@ -90,20 +91,13 @@ async def invoke_tool(
90
91
  try:
91
92
  project_id = await resolve_project_id(project_id=project_id)
92
93
  api_key_id = await resolve_api_key(project_id, api_key_id)
93
- key = (await account_client.decrypt_project_api_key(project_id=project_id, id=api_key_id))["token"]
94
94
 
95
- token = ParticipantToken(
96
- name=name,
97
- project_id=project_id,
98
- api_key_id=api_key_id
99
- )
100
- token.add_role_grant(role=role)
101
- token.add_room_grant(room)
95
+ 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)
102
96
 
103
97
  print("[bold green]Connecting to room...[/bold green]")
104
98
  async with RoomClient(
105
99
  protocol=WebSocketClientProtocol(url=websocket_room_url(room_name=room, base_url=meshagent_base_url()),
106
- token=token.to_jwt(token=key))
100
+ token=jwt)
107
101
  ) as client:
108
102
 
109
103
  found = timeout == 0
@@ -150,6 +144,7 @@ async def list_agents_command(
150
144
  *,
151
145
  project_id: str = None,
152
146
  room: Annotated[str, typer.Option()],
147
+ token_path: Annotated[Optional[str], typer.Option()] = None,
153
148
  api_key_id: Annotated[Optional[str], typer.Option()] = None,
154
149
  name: Annotated[str, typer.Option(..., help="Participant name")] = "cli",
155
150
  role: str = "user"
@@ -161,20 +156,12 @@ async def list_agents_command(
161
156
  try:
162
157
  project_id = await resolve_project_id(project_id=project_id)
163
158
  api_key_id = await resolve_api_key(project_id, api_key_id)
164
- key = (await account_client.decrypt_project_api_key(project_id=project_id, id=api_key_id))["token"]
165
-
166
- token = ParticipantToken(
167
- name=name,
168
- project_id=project_id,
169
- api_key_id=api_key_id
170
- )
171
- token.add_role_grant(role=role)
172
- token.add_room_grant(room)
159
+ 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)
173
160
 
174
161
  print("[bold green]Connecting to room...[/bold green]")
175
162
  async with RoomClient(
176
163
  protocol=WebSocketClientProtocol(url=websocket_room_url(room_name=room, base_url=meshagent_base_url()),
177
- token=token.to_jwt(token=key))
164
+ token=jwt)
178
165
  ) as client:
179
166
  print("[bold green]Fetching list of agents...[/bold green]")
180
167
  agents = await client.agents.list_agents()
@@ -200,6 +187,7 @@ async def list_toolkits_command(
200
187
  *,
201
188
  project_id: str = None,
202
189
  room: Annotated[str, typer.Option()],
190
+ token_path: Annotated[Optional[str], typer.Option()] = None,
203
191
  api_key_id: Annotated[Optional[str], typer.Option()] = None,
204
192
  name: Annotated[str, typer.Option(..., help="Participant name")] = "cli",
205
193
  role: str = "user",
@@ -212,20 +200,12 @@ async def list_toolkits_command(
212
200
  try:
213
201
  project_id = await resolve_project_id(project_id=project_id)
214
202
  api_key_id = await resolve_api_key(project_id, api_key_id)
215
- key = (await account_client.decrypt_project_api_key(project_id=project_id, id=api_key_id))["token"]
216
-
217
- token = ParticipantToken(
218
- name=name,
219
- project_id=project_id,
220
- api_key_id=api_key_id
221
- )
222
- token.add_role_grant(role=role)
223
- token.add_room_grant(room)
203
+ 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)
224
204
 
225
205
  print("[bold green]Connecting to room...[/bold green]")
226
206
  async with RoomClient(
227
207
  protocol=WebSocketClientProtocol(url=websocket_room_url(room_name=room, base_url=meshagent_base_url()),
228
- token=token.to_jwt(token=key))
208
+ token=jwt)
229
209
  ) as client:
230
210
  print("[bold green]Fetching list of toolkits...[/bold green]")
231
211
  toolkits = await client.agents.list_toolkits(participant_id=participant_id)
@@ -1,8 +1,7 @@
1
- from meshagent.cli import async_typer
2
1
  import typer
3
- from meshagent.cli.helper import get_client, print_json_table
4
2
  from rich import print
5
- from typing import Optional
3
+ from meshagent.cli import async_typer
4
+ from meshagent.cli.helper import get_client, print_json_table
6
5
  from meshagent.cli.helper import set_active_project, get_active_project, resolve_project_id, set_active_api_key, resolve_api_key
7
6
 
8
7
  app = async_typer.AsyncTyper()
@@ -1,11 +1,8 @@
1
1
  import typer
2
- from meshagent.api.accounts_client import AccountsClient
3
-
4
- import os
5
- from .helper import set_active_project, get_active_project
6
2
 
7
3
  from meshagent.cli import async_typer
8
4
  from meshagent.cli import auth_async
5
+ from meshagent.cli.helper import set_active_project, get_active_project
9
6
 
10
7
  app = async_typer.AsyncTyper()
11
8
 
@@ -3,43 +3,38 @@ from mcp.client.session import ClientSession
3
3
  from mcp.client.sse import sse_client
4
4
  from mcp.client.stdio import stdio_client, StdioServerParameters
5
5
 
6
- from meshagent.mcp import MCPToolkit
7
-
8
- from meshagent.cli import async_typer
9
6
  import typer
10
- from meshagent.cli.helper import get_client, print_json_table, set_active_project, resolve_project_id
11
7
  from rich import print
12
- from meshagent.api import RoomClient, ParticipantToken, WebSocketClientProtocol, RoomException
13
- from meshagent.cli.helper import set_active_project, get_active_project, resolve_project_id, resolve_api_key
14
8
  from typing import Annotated, Optional
15
- from meshagent.api.helpers import meshagent_base_url, websocket_room_url
16
9
 
10
+ from meshagent.api.helpers import meshagent_base_url, websocket_room_url
11
+ from meshagent.api import RoomClient, ParticipantToken, WebSocketClientProtocol, RoomException
17
12
  from meshagent.api.services import send_webhook
13
+ from meshagent.cli import async_typer
14
+ from meshagent.cli.helper import get_client, print_json_table, set_active_project, resolve_project_id
15
+ from meshagent.cli.helper import set_active_project, get_active_project, resolve_project_id, resolve_api_key, resolve_token_jwt
16
+
18
17
  from meshagent.tools.hosting import RemoteToolkit
18
+
19
+ from meshagent.mcp import MCPToolkit
20
+ from pathlib import Path
21
+
22
+
19
23
  import shlex
20
24
 
21
25
  app = async_typer.AsyncTyper()
22
26
 
23
27
  @app.async_command("sse")
24
- async def sse(*, project_id: str = None, room: Annotated[str, typer.Option()], api_key_id: Annotated[Optional[str], typer.Option()] = None, name: Annotated[str, typer.Option(..., help="Participant name")] = "cli", role: str = "tool", url: Annotated[str, typer.Option()]):
28
+ async def sse(*, project_id: str = None, room: Annotated[str, typer.Option()], token_path: Annotated[Optional[str], typer.Option()] = None, api_key_id: Annotated[Optional[str], typer.Option()] = None, name: Annotated[str, typer.Option(..., help="Participant name")] = "cli", role: str = "tool", url: Annotated[str, typer.Option()]):
25
29
  account_client = await get_client()
26
30
  try:
27
31
  project_id = await resolve_project_id(project_id=project_id)
28
32
  api_key_id = await resolve_api_key(project_id, api_key_id)
29
33
 
30
- key = (await account_client.decrypt_project_api_key(project_id=project_id, id=api_key_id))["token"]
31
-
32
- token = ParticipantToken(
33
- name=name,
34
- project_id=project_id,
35
- api_key_id=api_key_id
36
- )
37
-
38
- token.add_role_grant(role=role)
39
- token.add_room_grant(room)
40
-
34
+ 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)
35
+
41
36
  print("[bold green]Connecting to room...[/bold green]")
42
- async with RoomClient(protocol=WebSocketClientProtocol(url=websocket_room_url(room_name=room, base_url=meshagent_base_url()), token=token.to_jwt(token=key))) as client:
37
+ async with RoomClient(protocol=WebSocketClientProtocol(url=websocket_room_url(room_name=room, base_url=meshagent_base_url()), token=jwt)) as client:
43
38
 
44
39
  async with sse_client(url) as (read_stream, write_stream):
45
40
 
@@ -66,25 +61,16 @@ async def sse(*, project_id: str = None, room: Annotated[str, typer.Option()], a
66
61
 
67
62
 
68
63
  @app.async_command("stdio")
69
- async def stdio(*, project_id: str = None, room: Annotated[str, typer.Option()], api_key_id: Annotated[Optional[str], typer.Option()] = None, name: Annotated[str, typer.Option(..., help="Participant name")] = "cli", role: str = "tool", command: Annotated[str, typer.Option()], args: Annotated[str, typer.Option()]):
64
+ async def stdio(*, project_id: str = None, room: Annotated[str, typer.Option()], token_path: Annotated[Optional[str], typer.Option()] = None, api_key_id: Annotated[Optional[str], typer.Option()] = None, name: Annotated[str, typer.Option(..., help="Participant name")] = "cli", role: str = "tool", command: Annotated[str, typer.Option()], args: Annotated[str, typer.Option()]):
70
65
  account_client = await get_client()
71
66
  try:
72
67
  project_id = await resolve_project_id(project_id=project_id)
73
68
  api_key_id = await resolve_api_key(project_id, api_key_id)
74
69
 
75
- key = (await account_client.decrypt_project_api_key(project_id=project_id, id=api_key_id))["token"]
76
-
77
- token = ParticipantToken(
78
- name=name,
79
- project_id=project_id,
80
- api_key_id=api_key_id
81
- )
82
-
83
- token.add_role_grant(role=role)
84
- token.add_room_grant(room)
70
+ 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)
85
71
 
86
72
  print("[bold green]Connecting to room...[/bold green]")
87
- async with RoomClient(protocol=WebSocketClientProtocol(url=websocket_room_url(room_name=room, base_url=meshagent_base_url()), token=token.to_jwt(token=key))) as client:
73
+ async with RoomClient(protocol=WebSocketClientProtocol(url=websocket_room_url(room_name=room, base_url=meshagent_base_url()), token=jwt)) as client:
88
74
 
89
75
  async with stdio_client(StdioServerParameters(
90
76
  command=command, # Executable
@@ -1,17 +1,18 @@
1
- from meshagent.cli import async_typer
2
1
  import typer
3
- from meshagent.api.helpers import meshagent_base_url
4
- from meshagent.api.accounts_client import AccountsClient
5
-
6
2
  from rich.console import Console
7
3
  from rich.table import Table
8
-
9
4
  from pydantic import BaseModel
10
-
11
- from meshagent.cli import auth_async
12
5
  from pathlib import Path
13
6
  from typing import Optional
14
7
 
8
+ from meshagent.cli import auth_async
9
+ from meshagent.cli import async_typer
10
+ from meshagent.api.helpers import meshagent_base_url
11
+ from meshagent.api.accounts_client import AccountsClient
12
+ from meshagent.api.participant_token import ParticipantToken
13
+
14
+ import os
15
+
15
16
  SETTINGS_FILE = Path.home() / ".meshagent" / "project.json"
16
17
 
17
18
  def _ensure_cache_dir():
@@ -110,4 +111,44 @@ async def resolve_api_key(project_id: str, api_key_id: Optional[str] = None):
110
111
  raise typer.Exit(code=1)
111
112
 
112
113
  return api_key_id
113
-
114
+
115
+
116
+ async def resolve_token_jwt(*, project_id: str, api_key_id: Optional[str] = None, token_path: Optional[str] = None, name: Optional[str] = None, role: Optional[str] = None, room: Optional[str]= None) -> str:
117
+ jwt = None
118
+
119
+ if api_key_id == None:
120
+
121
+ if token_path != None:
122
+
123
+ if token_path == None:
124
+
125
+ token_path = os.getenv("MESHAGENT_TOKEN_PATH", (Path.home() / ".meshagent" / "token").as_posix())
126
+
127
+ p = Path(token_path)
128
+ jwt = p.read_text().strip()
129
+
130
+ else:
131
+
132
+ jwt = os.getenv("MESHAGENT_TOKEN", None)
133
+
134
+ if jwt == None:
135
+
136
+ account_client = await get_client()
137
+ try:
138
+ key = (await account_client.decrypt_project_api_key(project_id=project_id, id=api_key_id))["token"]
139
+
140
+ token = ParticipantToken(
141
+ name=name,
142
+ project_id=project_id,
143
+ api_key_id=api_key_id
144
+ )
145
+
146
+ token.add_role_grant(role=role)
147
+ token.add_room_grant(room)
148
+
149
+ jwt = token.to_jwt(token=key)
150
+ finally:
151
+
152
+ await account_client.close()
153
+
154
+ return jwt
@@ -1,12 +1,13 @@
1
- from meshagent.cli import async_typer
2
1
  import typer
3
- from meshagent.cli.helper import get_client, resolve_project_id, resolve_api_key
4
2
  from rich import print
5
- from meshagent.api import RoomClient, ParticipantToken, WebSocketClientProtocol
6
- from meshagent.api.helpers import meshagent_base_url, websocket_room_url
7
3
  from typing import Annotated, Optional
8
4
  import json
9
5
 
6
+ from meshagent.api import RoomClient, ParticipantToken, WebSocketClientProtocol
7
+ from meshagent.api.helpers import meshagent_base_url, websocket_room_url
8
+ from meshagent.cli import async_typer
9
+ from meshagent.cli.helper import get_client, resolve_project_id, resolve_api_key, resolve_token_jwt
10
+
10
11
  app = async_typer.AsyncTyper()
11
12
 
12
13
 
@@ -15,6 +16,7 @@ async def messaging_list_participants_command(
15
16
  *,
16
17
  project_id: str = None,
17
18
  room: Annotated[str, typer.Option()],
19
+ token_path: Annotated[Optional[str], typer.Option()] = None,
18
20
  api_key_id: Annotated[Optional[str], typer.Option()] = None,
19
21
  name: Annotated[str, typer.Option()] = "cli",
20
22
  role: str = "user"
@@ -28,23 +30,13 @@ async def messaging_list_participants_command(
28
30
  project_id = await resolve_project_id(project_id=project_id)
29
31
  api_key_id = await resolve_api_key(project_id, api_key_id)
30
32
 
31
- # Decrypt the API key
32
- key = (await account_client.decrypt_project_api_key(project_id=project_id, id=api_key_id))["token"]
33
-
34
- # Build participant token
35
- token = ParticipantToken(
36
- name=name,
37
- project_id=project_id,
38
- api_key_id=api_key_id
39
- )
40
- token.add_role_grant(role=role)
41
- token.add_room_grant(room)
33
+ 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)
42
34
 
43
35
  print("[bold green]Connecting to room...[/bold green]")
44
36
  async with RoomClient(
45
37
  protocol=WebSocketClientProtocol(
46
38
  url=websocket_room_url(room_name=room, base_url=meshagent_base_url()),
47
- token=token.to_jwt(token=key)
39
+ token=jwt
48
40
  )
49
41
  ) as client:
50
42
 
@@ -74,6 +66,7 @@ async def messaging_send_command(
74
66
  *,
75
67
  project_id: str = None,
76
68
  room: Annotated[str, typer.Option()],
69
+ token_path: Annotated[Optional[str], typer.Option()] = None,
77
70
  api_key_id: Annotated[Optional[str], typer.Option()] = None,
78
71
  name: Annotated[str, typer.Option()] = "cli",
79
72
  role: str = "user",
@@ -89,23 +82,13 @@ async def messaging_send_command(
89
82
  project_id = await resolve_project_id(project_id=project_id)
90
83
  api_key_id = await resolve_api_key(project_id, api_key_id)
91
84
 
92
- # Decrypt the API key
93
- key = (await account_client.decrypt_project_api_key(project_id=project_id, id=api_key_id))["token"]
94
-
95
- # Build participant token
96
- token = ParticipantToken(
97
- name=name,
98
- project_id=project_id,
99
- api_key_id=api_key_id
100
- )
101
- token.add_role_grant(role=role)
102
- token.add_room_grant(room)
85
+ 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)
103
86
 
104
87
  print("[bold green]Connecting to room...[/bold green]")
105
88
  async with RoomClient(
106
89
  protocol=WebSocketClientProtocol(
107
90
  url=websocket_room_url(room_name=room, base_url=meshagent_base_url()),
108
- token=token.to_jwt(token=key)
91
+ token=jwt
109
92
  )
110
93
  ) as client:
111
94
  # Create and enable messaging
@@ -142,6 +125,7 @@ async def messaging_broadcast_command(
142
125
  *,
143
126
  project_id: str = None,
144
127
  room: Annotated[str, typer.Option()],
128
+ token_path: Annotated[Optional[str], typer.Option()] = None,
145
129
  api_key_id: Annotated[Optional[str], typer.Option()] = None,
146
130
  name: Annotated[str, typer.Option()] = "cli",
147
131
  role: str = "user",
@@ -156,23 +140,13 @@ async def messaging_broadcast_command(
156
140
  project_id = await resolve_project_id(project_id=project_id)
157
141
  api_key_id = await resolve_api_key(project_id, api_key_id)
158
142
 
159
- # Decrypt the API key
160
- key = (await account_client.decrypt_project_api_key(project_id=project_id, id=api_key_id))["token"]
161
-
162
- # Build participant token
163
- token = ParticipantToken(
164
- name=name,
165
- project_id=project_id,
166
- api_key_id=api_key_id
167
- )
168
- token.add_role_grant(role=role)
169
- token.add_room_grant(room)
143
+ 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)
170
144
 
171
145
  print("[bold green]Connecting to room...[/bold green]")
172
146
  async with RoomClient(
173
147
  protocol=WebSocketClientProtocol(
174
148
  url=websocket_room_url(room_name=room, base_url=meshagent_base_url()),
175
- token=token.to_jwt(token=key)
149
+ token=jwt
176
150
  )
177
151
  ) as client:
178
152
  # Create and enable messaging
@@ -1,19 +1,20 @@
1
- from meshagent.cli import async_typer
2
1
  import typer
3
- from meshagent.cli.helper import get_client, print_json_table, set_active_project, resolve_project_id
4
2
  from rich import print
5
- from meshagent.api import RoomClient, ParticipantToken
6
- from meshagent.cli.helper import set_active_project, get_active_project, resolve_project_id
7
3
  from typing import Annotated, Optional
8
-
4
+ from meshagent.api import RoomClient, ParticipantToken
5
+ from meshagent.cli.helper import set_active_project, get_active_project, resolve_project_id, resolve_api_key
6
+ from meshagent.cli import async_typer
7
+ from meshagent.cli.helper import get_client, print_json_table, set_active_project, resolve_project_id
8
+ import pathlib
9
9
 
10
10
  app = async_typer.AsyncTyper()
11
11
 
12
12
  @app.async_command("generate")
13
- async def generate(*, project_id: str = None, room: Annotated[str, typer.Option()], api_key_id: Annotated[Optional[str], typer.Option()] = None, name: Annotated[str, typer.Option()], role: str = "agent"):
13
+ async def generate(*, project_id: str = None, token_path: Annotated[str, typer.Option()], room: Annotated[str, typer.Option()], api_key_id: Annotated[Optional[str], typer.Option()] = None, name: Annotated[str, typer.Option()], role: str = "agent"):
14
14
  client = await get_client()
15
15
  try:
16
16
  project_id = await resolve_project_id(project_id=project_id)
17
+ api_key_id = await resolve_api_key(project_id=project_id, api_key_id=api_key_id)
17
18
 
18
19
  key = (await client.decrypt_project_api_key(project_id=project_id, id=api_key_id))["token"]
19
20
 
@@ -27,7 +28,13 @@ async def generate(*, project_id: str = None, room: Annotated[str, typer.Option(
27
28
 
28
29
  token.add_room_grant(room)
29
30
 
30
- print(token.to_jwt(token=key))
31
+ if token_path == None:
32
+
33
+ print(token.to_jwt(token=key))
34
+
35
+ else:
36
+
37
+ pathlib.Path(token_path).expanduser().resolve().write_text(token.to_jwt(token=key))
31
38
 
32
39
  finally:
33
40
  await client.close()
@@ -1,4 +1,3 @@
1
- from meshagent.cli import async_typer
2
1
  import typer
3
2
  from typing import Annotated, Optional
4
3
  from rich import print
@@ -6,17 +5,15 @@ import os
6
5
  import fnmatch
7
6
  import glob
8
7
  import shutil
8
+
9
9
  from meshagent.api import RoomClient, ParticipantToken, WebSocketClientProtocol
10
10
  from meshagent.api.room_server_client import StorageClient
11
-
12
11
  from meshagent.api.helpers import meshagent_base_url, websocket_room_url
13
-
14
- from meshagent.cli .helper import get_client, resolve_project_id, resolve_api_key
12
+ from meshagent.cli import async_typer
13
+ from meshagent.cli.helper import get_client, resolve_project_id, resolve_api_key, resolve_token_jwt
15
14
 
16
15
  app = async_typer.AsyncTyper()
17
16
 
18
-
19
-
20
17
  def parse_path(path: str):
21
18
  """
22
19
  Parse a path and return a tuple (scheme, subpath).
@@ -53,6 +50,7 @@ async def storage_exists_command(
53
50
  *,
54
51
  project_id: str = None,
55
52
  room: Annotated[str, typer.Option(..., help="Room name")],
53
+ token_path: Annotated[Optional[str], typer.Option()] = None,
56
54
  api_key_id: Annotated[Optional[str], typer.Option(..., help="API Key ID")] = None,
57
55
  name: Annotated[str, typer.Option(..., help="Participant name")] = "cli",
58
56
  role: str = "user",
@@ -65,22 +63,14 @@ async def storage_exists_command(
65
63
  try:
66
64
  project_id = await resolve_project_id(project_id=project_id)
67
65
  api_key_id = await resolve_api_key(project_id, api_key_id)
68
-
69
- key = (await account_client.decrypt_project_api_key(project_id=project_id, id=api_key_id))["token"]
70
-
71
- token = ParticipantToken(
72
- name=name,
73
- project_id=project_id,
74
- api_key_id=api_key_id
75
- )
76
- token.add_role_grant(role=role)
77
- token.add_room_grant(room)
78
66
 
67
+ 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
+
79
69
  print("[bold green]Connecting to room...[/bold green]")
80
70
  async with RoomClient(
81
71
  protocol=WebSocketClientProtocol(
82
72
  url=websocket_room_url(room_name=room, base_url=meshagent_base_url()),
83
- token=token.to_jwt(token=key)
73
+ token=jwt
84
74
  )
85
75
  ) as client:
86
76
 
@@ -98,6 +88,7 @@ async def storage_cp_command(
98
88
  *,
99
89
  project_id: str = None,
100
90
  room: Annotated[str, typer.Option(..., help="Room name (if copying to/from remote)")],
91
+ token_path: Annotated[Optional[str], typer.Option()] = None,
101
92
  api_key_id: Annotated[str, typer.Option(..., help="API Key ID (if copying to/from remote)")],
102
93
  name: Annotated[str, typer.Option(..., help="Participant name (if copying to/from remote)")],
103
94
  role: str = "user",
@@ -124,30 +115,22 @@ async def storage_cp_command(
124
115
 
125
116
  # A helper to ensure we have a connected StorageClient if needed
126
117
  async def ensure_storage_client():
127
- nonlocal account_client, client, storage_client, api_key_id
118
+ nonlocal account_client, client, storage_client, api_key_id, project_id
128
119
 
129
120
  if storage_client is not None:
130
121
  return # Already connected
131
122
 
132
123
  account_client = await get_client()
133
- resolved_proj_id = await resolve_project_id(project_id=project_id)
124
+ project_id = await resolve_project_id(project_id=project_id)
134
125
  api_key_id = await resolve_api_key(project_id, api_key_id)
135
126
 
136
- key = (await account_client.decrypt_project_api_key(project_id=resolved_proj_id, id=api_key_id))["token"]
137
-
138
- token = ParticipantToken(
139
- name=name,
140
- project_id=resolved_proj_id,
141
- api_key_id=api_key_id
142
- )
143
- token.add_role_grant(role=role)
144
- token.add_room_grant(room)
127
+ 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)
145
128
 
146
129
  print("[bold green]Connecting to room...[/bold green]")
147
130
  client = RoomClient(
148
131
  protocol=WebSocketClientProtocol(
149
132
  url=websocket_room_url(room_name=room, base_url=meshagent_base_url()),
150
- token=token.to_jwt(token=key)
133
+ token=jwt
151
134
  )
152
135
  )
153
136
 
@@ -317,6 +300,7 @@ async def storage_show_command(
317
300
  *,
318
301
  project_id: Annotated[Optional[str], typer.Option(..., help="Project ID (if remote)")] = None,
319
302
  room: Annotated[Optional[str], typer.Option(..., help="Room name (if remote)")] = None,
303
+ token_path: Annotated[Optional[str], typer.Option()] = None,
320
304
  api_key_id: Annotated[Optional[str], typer.Option(..., help="API Key ID (if remote)")] = None,
321
305
  name: Annotated[Optional[str], typer.Option(..., help="Participant name (if remote)")] = None,
322
306
  role: str = "user",
@@ -334,35 +318,27 @@ async def storage_show_command(
334
318
  storage_client = None
335
319
 
336
320
  async def ensure_storage_client():
337
- nonlocal account_client, client, storage_client, api_key_id
321
+ nonlocal account_client, client, storage_client, api_key_id, project_id
338
322
 
339
323
  if storage_client is not None:
340
324
  return
341
325
 
342
- if not room or not api_key_id or not name:
326
+ if not room:
343
327
  raise typer.BadParameter(
344
- "To show a remote file, you must provide --room, --api-key-id, and --name."
328
+ "To show a remote file, you must provide --room"
345
329
  )
346
330
 
347
331
  account_client = await get_client()
348
- resolved_proj_id = await resolve_project_id(project_id=project_id)
332
+ project_id = await resolve_project_id(project_id=project_id)
349
333
  api_key_id = await resolve_api_key(project_id, api_key_id)
350
-
351
- key = (await account_client.decrypt_project_api_key(project_id=resolved_proj_id, id=api_key_id))["token"]
352
334
 
353
- token = ParticipantToken(
354
- name=name,
355
- project_id=resolved_proj_id,
356
- api_key_id=api_key_id
357
- )
358
- token.add_role_grant(role=role)
359
- token.add_room_grant(room)
335
+ 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)
360
336
 
361
337
  print("[bold green]Connecting to room...[/bold green]")
362
338
  client = RoomClient(
363
339
  protocol=WebSocketClientProtocol(
364
340
  url=websocket_room_url(room_name=room, base_url=meshagent_base_url()),
365
- token=token.to_jwt(token=key)
341
+ token=jwt
366
342
  )
367
343
  )
368
344
 
@@ -400,6 +376,7 @@ async def storage_rm_command(
400
376
  *,
401
377
  project_id: Annotated[Optional[str], typer.Option(..., help="Project ID (if remote)")] = None,
402
378
  room: Annotated[Optional[str], typer.Option(..., help="Room name (if remote)")] = None,
379
+ token_path: Annotated[Optional[str], typer.Option()] = None,
403
380
  api_key_id: Annotated[Optional[str], typer.Option(..., help="API Key ID (if remote)")] = None,
404
381
  name: Annotated[Optional[str], typer.Option(..., help="Participant name (if remote)")] = None,
405
382
  role: str = "user",
@@ -428,29 +405,20 @@ async def storage_rm_command(
428
405
  if storage_client is not None:
429
406
  return # Already set up
430
407
 
431
- if not room or not api_key_id or not name:
408
+ if not room:
432
409
  raise typer.BadParameter(
433
- "To remove a remote file or folder, you must provide --room, --api-key-id, and --name."
410
+ "To remove a remote file or folder, you must provide --room"
434
411
  )
435
412
 
436
413
  account_client = await get_client()
437
- resolved_proj_id = await resolve_project_id(project_id=project_id)
438
- api_key_id = resolve_api_key(resolved_proj_id, api_key_id)
439
- key = (await account_client.decrypt_project_api_key(project_id=resolved_proj_id, id=api_key_id))["token"]
440
-
441
- token = ParticipantToken(
442
- name=name,
443
- project_id=resolved_proj_id,
444
- api_key_id=api_key_id
445
- )
446
- token.add_role_grant(role=role)
447
- token.add_room_grant(room)
414
+ project_id = await resolve_project_id(project_id=project_id)
415
+ 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)
448
416
 
449
417
  print("[bold green]Connecting to room...[/bold green]")
450
418
  client = RoomClient(
451
419
  protocol=WebSocketClientProtocol(
452
420
  url=websocket_room_url(room_name=room, base_url=meshagent_base_url()),
453
- token=token.to_jwt(token=key)
421
+ token=jwt
454
422
  )
455
423
  )
456
424
 
@@ -593,6 +561,7 @@ async def storage_ls_command(
593
561
  *,
594
562
  project_id: Annotated[Optional[str], typer.Option(..., help="Project ID (if remote)")] = None,
595
563
  room: Annotated[Optional[str], typer.Option(..., help="Room name (if remote)")] = None,
564
+ token_path: Annotated[Optional[str], typer.Option()] = None,
596
565
  api_key_id: Annotated[Optional[str], typer.Option(..., help="API Key ID (if remote)")] = None,
597
566
  name: Annotated[Optional[str], typer.Option(..., help="Participant name (if remote)")] = None,
598
567
  role: str = "user",
@@ -613,31 +582,24 @@ async def storage_ls_command(
613
582
 
614
583
  # --- Set up remote connection if needed ---
615
584
  async def ensure_storage_client():
616
- nonlocal account_client, client, storage_client
585
+ nonlocal account_client, client, storage_client, project_id
617
586
  if storage_client is not None:
618
587
  return
619
588
 
620
- if not room or not api_key_id or not name:
589
+ if not room:
621
590
  raise typer.BadParameter(
622
- "To list a remote path, you must provide --room, --api-key-id, and --name."
591
+ "To list a remote path, you must provide --room"
623
592
  )
624
593
 
625
594
  account_client = await get_client()
626
- resolved_proj_id = await resolve_project_id(project_id=project_id)
627
- key = (await account_client.decrypt_project_api_key(project_id=resolved_proj_id, id=api_key_id))["token"]
628
-
629
- token = ParticipantToken(
630
- name=name,
631
- project_id=resolved_proj_id,
632
- api_key_id=api_key_id
633
- )
634
- token.add_role_grant(role=role)
635
- token.add_room_grant(room)
595
+ project_id = await resolve_project_id(project_id=project_id)
596
+
597
+ 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)
636
598
 
637
599
  client = RoomClient(
638
600
  protocol=WebSocketClientProtocol(
639
601
  url=websocket_room_url(room_name=room, base_url=meshagent_base_url()),
640
- token=token.to_jwt(token=key)
602
+ token=jwt
641
603
  )
642
604
  )
643
605
  await client.__aenter__()
@@ -0,0 +1 @@
1
+ __version__ = "0.0.18"
@@ -1,10 +1,11 @@
1
- from meshagent.cli import async_typer
2
1
  import typer
3
- from meshagent.cli.helper import get_client, print_json_table, resolve_project_id
4
2
  from rich import print
5
3
  import json
6
4
  from typing import Annotated, List, Optional
7
5
 
6
+ from meshagent.cli import async_typer
7
+ from meshagent.cli.helper import get_client, print_json_table, resolve_project_id
8
+
8
9
  app = async_typer.AsyncTyper()
9
10
 
10
11
  # ---------------------------------------------------------------------------
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: meshagent-cli
3
- Version: 0.0.17
3
+ Version: 0.0.18
4
4
  Summary: CLI for Meshagent
5
5
  License-Expression: LicenseRef-Proprietary
6
6
  Project-URL: Documentation, https://meshagent.com
@@ -10,9 +10,9 @@ Requires-Python: >=3.9.0
10
10
  Description-Content-Type: text/markdown
11
11
  Requires-Dist: typer~=0.15.3
12
12
  Requires-Dist: pydantic-yaml~=1.4.0
13
- Requires-Dist: meshagent-api~=0.0.17
14
- Requires-Dist: meshagent-agents~=0.0.17
15
- Requires-Dist: meshagent-tools~=0.0.17
13
+ Requires-Dist: meshagent-api~=0.0.18
14
+ Requires-Dist: meshagent-agents~=0.0.18
15
+ Requires-Dist: meshagent-tools~=0.0.18
16
16
 
17
17
  ### Meshagent CLI
18
18
 
@@ -0,0 +1,5 @@
1
+ typer~=0.15.3
2
+ pydantic-yaml~=1.4.0
3
+ meshagent-api~=0.0.18
4
+ meshagent-agents~=0.0.18
5
+ meshagent-tools~=0.0.18
@@ -11,9 +11,9 @@ keywords = []
11
11
  dependencies = [
12
12
  "typer~=0.15.3",
13
13
  "pydantic-yaml~=1.4.0",
14
- "meshagent-api~=0.0.17",
15
- "meshagent-agents~=0.0.17",
16
- "meshagent-tools~=0.0.17",
14
+ "meshagent-api~=0.0.18",
15
+ "meshagent-agents~=0.0.18",
16
+ "meshagent-tools~=0.0.18",
17
17
  ]
18
18
  dynamic = ["version", "readme"]
19
19
 
@@ -1 +0,0 @@
1
- __version__ = "0.0.17"
@@ -1,5 +0,0 @@
1
- typer~=0.15.3
2
- pydantic-yaml~=1.4.0
3
- meshagent-api~=0.0.17
4
- meshagent-agents~=0.0.17
5
- meshagent-tools~=0.0.17
File without changes
@@ -1,15 +1,15 @@
1
1
 
2
- from meshagent.cli import async_typer
3
2
  import typer
4
- from meshagent.cli.helper import get_client, print_json_table, set_active_project, resolve_project_id
5
3
  from rich import print
6
- from meshagent.api import RoomClient, ParticipantToken, WebSocketClientProtocol, RoomException
7
- from meshagent.cli.helper import set_active_project, get_active_project, resolve_project_id, resolve_api_key
8
4
  from typing import Annotated, Optional
9
- from meshagent.api.helpers import meshagent_base_url, websocket_room_url
10
5
  import json
11
6
  import aiohttp
7
+ from meshagent.api import RoomClient, ParticipantToken, WebSocketClientProtocol, RoomException
8
+ from meshagent.api.helpers import meshagent_base_url, websocket_room_url
12
9
  from meshagent.api.services import send_webhook
10
+ from meshagent.cli import async_typer
11
+ from meshagent.cli.helper import get_client, print_json_table, set_active_project, resolve_project_id
12
+ from meshagent.cli.helper import set_active_project, get_active_project, resolve_project_id, resolve_api_key
13
13
 
14
14
  app = async_typer.AsyncTyper()
15
15
 
@@ -1,12 +1,12 @@
1
1
  # --------------------------------------------------------------------------
2
2
  # Imports
3
3
  # --------------------------------------------------------------------------
4
- from meshagent.cli import async_typer
5
4
  import typer
6
5
  from rich import print
7
- from meshagent.cli.helper import get_client, print_json_table, resolve_project_id
8
6
  from typing import Annotated, Dict, Optional
9
7
 
8
+ from meshagent.cli import async_typer
9
+ from meshagent.cli.helper import get_client, print_json_table, resolve_project_id
10
10
  from meshagent.api.accounts_client import PullSecret, KeysSecret, SecretLike # or wherever you defined them
11
11
 
12
12
  # --------------------------------------------------------------------------
@@ -1,12 +1,12 @@
1
1
  import asyncio
2
2
  import json
3
- from meshagent.cli import async_typer
4
3
  import typer
4
+ from rich import print
5
+ from typing import Annotated, Optional
6
+ from meshagent.cli import async_typer
5
7
  from meshagent.cli.helper import get_client, resolve_project_id, resolve_api_key
6
8
  from meshagent.api import RoomClient, ParticipantToken, WebSocketClientProtocol
7
9
  from meshagent.api.helpers import meshagent_base_url, websocket_room_url
8
- from rich import print
9
- from typing import Annotated, Optional
10
10
 
11
11
  app = async_typer.AsyncTyper()
12
12
 
@@ -1,7 +1,7 @@
1
- from meshagent.cli import async_typer
2
1
  import typer
3
- from meshagent.cli.helper import get_client, print_json_table, set_active_project
4
2
  from rich import print
3
+ from meshagent.cli import async_typer
4
+ from meshagent.cli.helper import get_client, print_json_table, set_active_project
5
5
 
6
6
  app = async_typer.AsyncTyper()
7
7
 
@@ -1,16 +1,16 @@
1
1
  # ---------------------------------------------------------------------------
2
2
  # Imports
3
3
  # ---------------------------------------------------------------------------
4
- from meshagent.cli import async_typer
5
4
  import typer
6
5
  from rich import print
7
- from meshagent.cli.helper import get_client, print_json_table, resolve_project_id
8
6
  from typing import Annotated, List, Optional, Dict
9
7
  from datetime import datetime, timezone
10
8
  from pydantic_yaml import parse_yaml_raw_as, to_yaml_str
11
9
  from pydantic import PositiveInt
12
10
  import pydantic
13
11
  from typing import Literal
12
+ from meshagent.cli import async_typer
13
+ from meshagent.cli.helper import get_client, print_json_table, resolve_project_id
14
14
 
15
15
  # Pydantic basemodels
16
16
  from meshagent.api.accounts_client import Service, Port
File without changes