meshagent-cli 0.21.0__py3-none-any.whl → 0.23.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/cli.py CHANGED
@@ -21,7 +21,7 @@ from meshagent.cli import voicebot
21
21
  from meshagent.cli import mailbot
22
22
  from meshagent.cli import worker
23
23
  from meshagent.cli import task_runner
24
- from meshagent.cli import oauth2
24
+ from meshagent.cli import cli_secrets
25
25
  from meshagent.cli import helpers
26
26
  from meshagent.cli import meeting_transcriber
27
27
  from meshagent.cli import rooms
@@ -53,11 +53,11 @@ app.add_typer(auth.app, name="auth")
53
53
  app.add_typer(projects.app, name="project")
54
54
  app.add_typer(api_keys.app, name="api-key")
55
55
  app.add_typer(sessions.app, name="session")
56
- app.add_typer(participant_token.app, name="participant-token")
56
+ app.add_typer(participant_token.app, name="token")
57
57
  app.add_typer(webhook.app, name="webhook")
58
58
  app.add_typer(services.app, name="service")
59
59
  app.add_typer(cli_mcp.app, name="mcp")
60
- app.add_typer(oauth2.app, name="oauth2")
60
+ app.add_typer(cli_secrets.app, name="secrets")
61
61
  app.add_typer(helpers.app, name="helpers")
62
62
  app.add_typer(rooms.app, name="rooms")
63
63
  app.add_typer(mailboxes.app, name="mailbox")
meshagent/cli/helper.py CHANGED
@@ -7,8 +7,14 @@ from typing import Optional
7
7
  from meshagent.cli import auth_async
8
8
  from meshagent.cli import async_typer
9
9
  from meshagent.api.helpers import meshagent_base_url
10
+ from meshagent.api.specs.service import ServiceSpec
11
+ from meshagent.agents.context import AgentChatContext
10
12
  from meshagent.api.client import Meshagent, RoomConnectionInfo
11
13
  import os
14
+ import aiofiles
15
+ from pydantic_yaml import parse_yaml_raw_as
16
+ import json
17
+
12
18
  from rich import print
13
19
 
14
20
  SETTINGS_FILE = Path.home() / ".meshagent" / "project.json"
@@ -61,6 +67,8 @@ async def set_active_api_key(project_id: str, key: str):
61
67
 
62
68
  async def get_active_api_key(project_id: str):
63
69
  settings = _load_settings()
70
+ if settings is None:
71
+ return None
64
72
  key: str = settings.active_api_keys.get(project_id)
65
73
  # Ignore old keys, API key format changed
66
74
  if key is not None and key.startswith("ma-"):
@@ -76,7 +84,7 @@ class CustomMeshagentClient(Meshagent):
76
84
  async def connect_room(self, *, project_id: str, room: str) -> RoomConnectionInfo:
77
85
  from urllib.parse import quote
78
86
 
79
- jwt = os.getenv("MESHAGENT_SESSION_TOKEN")
87
+ jwt = os.getenv("MESHAGENT_TOKEN")
80
88
 
81
89
  if jwt is not None and room == os.getenv("MESHAGENT_ROOM"):
82
90
  return RoomConnectionInfo(
@@ -151,6 +159,32 @@ async def resolve_project_id(project_id: Optional[str] = None):
151
159
  return project_id
152
160
 
153
161
 
162
+ async def init_context_from_spec(context: AgentChatContext) -> None:
163
+ path = os.getenv("MESHAGENT_SPEC_PATH")
164
+
165
+ if path is None:
166
+ return None
167
+
168
+ async with aiofiles.open(path, "r") as file:
169
+ spec_str = await file.read()
170
+ try:
171
+ json.loads(spec_str)
172
+ spec = ServiceSpec.model_validate_json(spec_str)
173
+ except ValueError:
174
+ # fallback on yaml parser if spec can't
175
+ spec = parse_yaml_raw_as(ServiceSpec, spec_str)
176
+
177
+ readme = spec.metadata.annotations.get("meshagent.service.readme")
178
+
179
+ if spec.metadata.description:
180
+ context.append_assistant_message(
181
+ f"This agent's description:\n{spec.metadata.description}"
182
+ )
183
+
184
+ if readme is not None:
185
+ context.append_assistant_message(f"This agent's README:\n{readme}")
186
+
187
+
154
188
  async def resolve_key(project_id: str | None, key: str | None):
155
189
  project_id = await resolve_project_id(project_id=project_id)
156
190
  if key is None:
@@ -159,7 +193,7 @@ async def resolve_key(project_id: str | None, key: str | None):
159
193
  if key is None:
160
194
  key = os.getenv("MESHAGENT_API_KEY")
161
195
 
162
- if key is None:
196
+ if key is None and os.getenv("MESHAGENT_TOKEN") is None:
163
197
  print(
164
198
  "[red]--key is required if MESHAGENT_API_KEY is not set. You can use meshagent api-key create to create a new api key."
165
199
  )
@@ -192,6 +226,10 @@ def cleanup_args(args: list[str]):
192
226
  pass
193
227
  elif args[i].startswith("--room="):
194
228
  pass
229
+ elif args[i] == "deploy":
230
+ pass
231
+ elif args[i] == "spec":
232
+ pass
195
233
  else:
196
234
  out.append(args[i])
197
235
  i += 1
meshagent/cli/helpers.py CHANGED
@@ -36,7 +36,6 @@ async def helpers_service():
36
36
  class Runner(LLMTaskRunner):
37
37
  def __init__(self, **kwargs):
38
38
  super().__init__(
39
- name="meshagent.runner",
40
39
  title="Generic Task Runner",
41
40
  description="an agent that will perform a task with the selected tools",
42
41
  llm_adapter=OpenAIResponsesAdapter(model="gpt-5.2"),
@@ -68,7 +67,6 @@ async def helpers_service():
68
67
  class Planner(LLMTaskRunner):
69
68
  def __init__(self, **kwargs):
70
69
  super().__init__(
71
- name="meshagent.planner",
72
70
  title="Generic Task Runner (Legacy)",
73
71
  description="an agent that will perform a task with the selected tools",
74
72
  llm_adapter=OpenAIResponsesAdapter(model="gpt-5.2"),
@@ -86,7 +84,6 @@ async def helpers_service():
86
84
  class DynamicPlanner(DynamicLLMTaskRunner):
87
85
  def __init__(self, **kwargs):
88
86
  super().__init__(
89
- name="meshagent.schema_planner",
90
87
  title="Schema Task Runner",
91
88
  description="an agent that can produces output that matches a schema",
92
89
  llm_adapter=OpenAIResponsesAdapter(model="gpt-5.2"),
meshagent/cli/host.py CHANGED
@@ -1,12 +1,16 @@
1
1
  from meshagent.api.services import ServiceHost
2
2
  from meshagent.api.specs.service import ServiceSpec
3
3
  import asyncio
4
+ from meshagent.agents import Agent
4
5
 
5
6
 
6
7
  options = {"deferred": False}
7
8
  services = {}
8
9
 
9
10
 
11
+ agents: list[tuple[Agent, str]] = []
12
+
13
+
10
14
  def set_deferred(deferred: bool):
11
15
  options["deferred"] = deferred
12
16
 
meshagent/cli/mailbot.py CHANGED
@@ -1,6 +1,7 @@
1
1
  import typer
2
2
  from meshagent.cli import async_typer
3
3
  from rich import print
4
+ import os
4
5
 
5
6
  from meshagent.api import ParticipantToken
6
7
  from typing import Annotated, Optional
@@ -19,6 +20,7 @@ from meshagent.cli.helper import (
19
20
  cleanup_args,
20
21
  )
21
22
  from meshagent.openai import OpenAIResponsesAdapter
23
+ from meshagent.anthropic import AnthropicOpenAIResponsesStreamAdapter
22
24
 
23
25
  from meshagent.agents.config import RulesConfig
24
26
 
@@ -64,7 +66,6 @@ app = async_typer.AsyncTyper(help="Join a mailbot to a room")
64
66
  def build_mailbot(
65
67
  *,
66
68
  model: str,
67
- agent_name: str,
68
69
  rule: List[str],
69
70
  toolkit: List[str],
70
71
  schema: List[str],
@@ -76,7 +77,7 @@ def build_mailbot(
76
77
  Optional[bool], typer.Option(..., help="Enable web search tool calling")
77
78
  ] = False,
78
79
  toolkit_name: Optional[str] = None,
79
- queue: str,
80
+ queue: Optional[str] = None,
80
81
  email_address: str,
81
82
  room_rules_paths: list[str],
82
83
  whitelist=list[str],
@@ -96,9 +97,10 @@ def build_mailbot(
96
97
  skill_dirs: Optional[list[str]] = None,
97
98
  shell_image: Optional[str] = None,
98
99
  llm_participant: Optional[str] = None,
100
+ delegate_shell_token: Optional[bool] = None,
99
101
  log_llm_requests: Optional[bool] = None,
100
102
  ):
101
- from meshagent.agents.mail import MailWorker
103
+ from meshagent.agents.mail import MailBot
102
104
 
103
105
  if (require_storage or require_read_only_storage) and len(whitelist) == 0:
104
106
  logger.warning(
@@ -122,7 +124,7 @@ def build_mailbot(
122
124
  except FileNotFoundError:
123
125
  print(f"[yellow]rules file not found at {rules_file}[/yellow]")
124
126
 
125
- BaseClass = MailWorker
127
+ BaseClass = MailBot
126
128
  if llm_participant:
127
129
  llm_adapter = MessageStreamLLMAdapter(
128
130
  participant_name=llm_participant,
@@ -139,10 +141,16 @@ def build_mailbot(
139
141
  )
140
142
 
141
143
  else:
142
- llm_adapter = OpenAIResponsesAdapter(
143
- model=model,
144
- log_requests=log_llm_requests,
145
- )
144
+ if model.startswith("claude-"):
145
+ llm_adapter = AnthropicOpenAIResponsesStreamAdapter(
146
+ model=model,
147
+ log_requests=log_llm_requests,
148
+ )
149
+ else:
150
+ llm_adapter = OpenAIResponsesAdapter(
151
+ model=model,
152
+ log_requests=log_llm_requests,
153
+ )
146
154
 
147
155
  parsed_whitelist = []
148
156
  if len(whitelist) > 0:
@@ -156,7 +164,6 @@ def build_mailbot(
156
164
  def __init__(self):
157
165
  super().__init__(
158
166
  llm_adapter=llm_adapter,
159
- name=agent_name,
160
167
  requires=requirements,
161
168
  toolkits=toolkits,
162
169
  queue=queue,
@@ -169,6 +176,14 @@ def build_mailbot(
169
176
  skill_dirs=skill_dirs,
170
177
  )
171
178
 
179
+ async def init_chat_context(self):
180
+ from meshagent.cli.helper import init_context_from_spec
181
+
182
+ context = await super().init_chat_context()
183
+ await init_context_from_spec(context)
184
+
185
+ return context
186
+
172
187
  async def start(self, *, room: RoomClient):
173
188
  print(
174
189
  "[bold green]Configure and send an email interact with your mailbot[/bold green]"
@@ -231,12 +246,17 @@ def build_mailbot(
231
246
  LocalShellTool(thread_context=thread_context)
232
247
  )
233
248
 
249
+ env = {}
250
+ if delegate_shell_token:
251
+ env["MESHAGENT_TOKEN"] = self.room.protocol.token
252
+
234
253
  if require_shell:
235
254
  thread_toolkit.tools.append(
236
255
  ShellTool(
237
256
  working_directory=working_directory,
238
257
  config=ShellConfig(name="shell"),
239
258
  image=shell_image or "python:3.13",
259
+ env=env,
240
260
  )
241
261
  )
242
262
 
@@ -316,12 +336,14 @@ def build_mailbot(
316
336
 
317
337
 
318
338
  @app.async_command("join")
319
- async def make_call(
339
+ async def join(
320
340
  *,
321
341
  project_id: ProjectIdOption,
322
342
  room: RoomOption,
323
343
  role: str = "agent",
324
- agent_name: Annotated[str, typer.Option(..., help="Name of the agent to call")],
344
+ agent_name: Annotated[
345
+ Optional[str], typer.Option(..., help="Name of the agent to call")
346
+ ] = None,
325
347
  rule: Annotated[List[str], typer.Option("--rule", "-r", help="a system rule")] = [],
326
348
  rules_file: Optional[str] = None,
327
349
  require_toolkit: Annotated[
@@ -365,7 +387,9 @@ async def make_call(
365
387
  str,
366
388
  typer.Option("--key", help="an api key to sign the token with"),
367
389
  ] = None,
368
- queue: Annotated[str, typer.Option(..., help="the name of the mail queue")],
390
+ queue: Annotated[
391
+ Optional[str], typer.Option(..., help="the name of the mail queue")
392
+ ] = None,
369
393
  email_address: Annotated[
370
394
  str, typer.Option(..., help="the email address of the agent")
371
395
  ],
@@ -451,6 +475,10 @@ async def make_call(
451
475
  Optional[str],
452
476
  typer.Option(..., help="an image tag to use to run shell commands in"),
453
477
  ] = None,
478
+ delegate_shell_token: Annotated[
479
+ Optional[bool],
480
+ typer.Option(..., help="Delegate the room token to shell tools"),
481
+ ] = False,
454
482
  log_llm_requests: Annotated[
455
483
  Optional[bool],
456
484
  typer.Option(..., help="log all requests to the llm"),
@@ -464,69 +492,84 @@ async def make_call(
464
492
 
465
493
  room = resolve_room(room)
466
494
 
467
- token = ParticipantToken(
468
- name=agent_name,
469
- )
495
+ jwt = os.getenv("MESHAGENT_TOKEN")
496
+ if jwt is None:
497
+ if agent_name is None:
498
+ print(
499
+ "[bold red]--agent-name must be specified when the MESHAGENT_TOKEN environment variable is not set[/bold red]"
500
+ )
501
+ raise typer.Exit(1)
470
502
 
471
- token.add_api_grant(ApiScope.agent_default(tunnels=require_computer_use))
503
+ token = ParticipantToken(
504
+ name=agent_name,
505
+ )
506
+
507
+ token.add_api_grant(ApiScope.agent_default(tunnels=require_computer_use))
472
508
 
473
- token.add_role_grant(role=role)
474
- token.add_room_grant(room)
509
+ token.add_role_grant(role=role)
510
+ token.add_room_grant(room)
475
511
 
476
- jwt = token.to_jwt(api_key=key)
512
+ jwt = token.to_jwt(api_key=key)
477
513
 
478
514
  print("[bold green]Connecting to room...[/bold green]", flush=True)
479
- async with RoomClient(
480
- protocol=WebSocketClientProtocol(
481
- url=websocket_room_url(room_name=room, base_url=meshagent_base_url()),
482
- token=jwt,
483
- )
484
- ) as client:
485
- CustomMailbot = build_mailbot(
486
- computer_use=None,
487
- model=model,
488
- local_shell=require_local_shell,
489
- agent_name=agent_name,
490
- rule=rule,
491
- schema=require_schema + schema,
492
- toolkit=require_toolkit + toolkit,
493
- image_generation=None,
494
- web_search=require_web_search,
495
- rules_file=rules_file,
496
- queue=queue,
497
- email_address=email_address,
498
- toolkit_name=toolkit_name,
499
- room_rules_paths=room_rules,
500
- whitelist=whitelist,
501
- require_shell=require_shell,
502
- require_apply_patch=require_apply_patch,
503
- require_storage=require_storage,
504
- require_read_only_storage=require_read_only_storage,
505
- require_time=require_time,
506
- require_uuid=require_uuid,
507
- require_table_read=require_table_read,
508
- require_table_write=require_table_write,
509
- require_computer_use=require_computer_use,
510
- reply_all=reply_all,
511
- database_namespace=database_namespace,
512
- enable_attachments=enable_attachments,
513
- working_directory=working_directory,
514
- skill_dirs=skill_dir,
515
- shell_image=shell_image,
516
- llm_participant=llm_participant,
517
- log_llm_requests=log_llm_requests,
518
- )
515
+ CustomMailbot = build_mailbot(
516
+ computer_use=None,
517
+ model=model,
518
+ local_shell=require_local_shell,
519
+ rule=rule,
520
+ schema=require_schema + schema,
521
+ toolkit=require_toolkit + toolkit,
522
+ image_generation=None,
523
+ web_search=require_web_search,
524
+ rules_file=rules_file,
525
+ queue=queue,
526
+ email_address=email_address,
527
+ toolkit_name=toolkit_name,
528
+ room_rules_paths=room_rules,
529
+ whitelist=whitelist,
530
+ require_shell=require_shell,
531
+ require_apply_patch=require_apply_patch,
532
+ require_storage=require_storage,
533
+ require_read_only_storage=require_read_only_storage,
534
+ require_time=require_time,
535
+ require_uuid=require_uuid,
536
+ require_table_read=require_table_read,
537
+ require_table_write=require_table_write,
538
+ require_computer_use=require_computer_use,
539
+ reply_all=reply_all,
540
+ database_namespace=database_namespace,
541
+ enable_attachments=enable_attachments,
542
+ working_directory=working_directory,
543
+ skill_dirs=skill_dir,
544
+ shell_image=shell_image,
545
+ llm_participant=llm_participant,
546
+ delegate_shell_token=delegate_shell_token,
547
+ log_llm_requests=log_llm_requests,
548
+ )
519
549
 
520
- bot = CustomMailbot()
550
+ bot = CustomMailbot()
521
551
 
522
- await bot.start(room=client)
523
- try:
524
- print(
525
- flush=True,
552
+ if get_deferred():
553
+ from meshagent.cli.host import agents
554
+
555
+ agents.append((bot, jwt))
556
+ else:
557
+ async with RoomClient(
558
+ protocol=WebSocketClientProtocol(
559
+ url=websocket_room_url(
560
+ room_name=room, base_url=meshagent_base_url()
561
+ ),
562
+ token=jwt,
526
563
  )
527
- await client.protocol.wait_for_close()
528
- except KeyboardInterrupt:
529
- await bot.stop()
564
+ ) as client:
565
+ await bot.start(room=client)
566
+ try:
567
+ print(
568
+ flush=True,
569
+ )
570
+ await client.protocol.wait_for_close()
571
+ except KeyboardInterrupt:
572
+ await bot.stop()
530
573
 
531
574
  finally:
532
575
  await account_client.close()
@@ -588,7 +631,9 @@ async def service(
588
631
  path: Annotated[
589
632
  Optional[str], typer.Option(help="HTTP path to mount the service at")
590
633
  ] = None,
591
- queue: Annotated[str, typer.Option(..., help="the name of the mail queue")],
634
+ queue: Annotated[
635
+ Optional[str], typer.Option(..., help="the name of the mail queue")
636
+ ] = None,
592
637
  email_address: Annotated[
593
638
  str, typer.Option(..., help="the email address of the agent")
594
639
  ],
@@ -674,6 +719,10 @@ async def service(
674
719
  Optional[str],
675
720
  typer.Option(..., help="an image tag to use to run shell commands in"),
676
721
  ] = None,
722
+ delegate_shell_token: Annotated[
723
+ Optional[bool],
724
+ typer.Option(..., help="Delegate the room token to shell tools"),
725
+ ] = False,
677
726
  log_llm_requests: Annotated[
678
727
  Optional[bool],
679
728
  typer.Option(..., help="log all requests to the llm"),
@@ -688,7 +737,7 @@ async def service(
688
737
  path = f"/agent{i}"
689
738
 
690
739
  service.agents.append(
691
- AgentSpec(name=agent_name, annotations={ANNOTATION_AGENT_TYPE: "ChatBot"})
740
+ AgentSpec(name=agent_name, annotations={ANNOTATION_AGENT_TYPE: "MailBot"})
692
741
  )
693
742
 
694
743
  service.add_path(
@@ -700,7 +749,6 @@ async def service(
700
749
  model=model,
701
750
  local_shell=require_local_shell,
702
751
  web_search=require_web_search,
703
- agent_name=agent_name,
704
752
  rule=rule,
705
753
  schema=require_schema + schema,
706
754
  toolkit=require_toolkit + toolkit,
@@ -726,6 +774,7 @@ async def service(
726
774
  skill_dirs=skill_dir,
727
775
  shell_image=shell_image,
728
776
  llm_participant=llm_participant,
777
+ delegate_shell_token=delegate_shell_token,
729
778
  log_llm_requests=log_llm_requests,
730
779
  ),
731
780
  )
@@ -798,7 +847,9 @@ async def spec(
798
847
  path: Annotated[
799
848
  Optional[str], typer.Option(help="HTTP path to mount the service at")
800
849
  ] = None,
801
- queue: Annotated[str, typer.Option(..., help="the name of the mail queue")],
850
+ queue: Annotated[
851
+ Optional[str], typer.Option(..., help="the name of the mail queue")
852
+ ] = None,
802
853
  email_address: Annotated[
803
854
  str, typer.Option(..., help="the email address of the agent")
804
855
  ],
@@ -884,6 +935,10 @@ async def spec(
884
935
  Optional[str],
885
936
  typer.Option(..., help="an image tag to use to run shell commands in"),
886
937
  ] = None,
938
+ delegate_shell_token: Annotated[
939
+ Optional[bool],
940
+ typer.Option(..., help="Delegate the room token to shell tools"),
941
+ ] = False,
887
942
  log_llm_requests: Annotated[
888
943
  Optional[bool],
889
944
  typer.Option(..., help="log all requests to the llm"),
@@ -898,7 +953,7 @@ async def spec(
898
953
  path = f"/agent{i}"
899
954
 
900
955
  service.agents.append(
901
- AgentSpec(name=agent_name, annotations={ANNOTATION_AGENT_TYPE: "ChatBot"})
956
+ AgentSpec(name=agent_name, annotations={ANNOTATION_AGENT_TYPE: "MailBot"})
902
957
  )
903
958
 
904
959
  service.add_path(
@@ -910,7 +965,6 @@ async def spec(
910
965
  model=model,
911
966
  local_shell=require_local_shell,
912
967
  web_search=require_web_search,
913
- agent_name=agent_name,
914
968
  rule=rule,
915
969
  schema=require_schema + schema,
916
970
  toolkit=require_toolkit + toolkit,
@@ -936,6 +990,7 @@ async def spec(
936
990
  skill_dirs=skill_dir,
937
991
  shell_image=shell_image,
938
992
  llm_participant=llm_participant,
993
+ delegate_shell_token=delegate_shell_token,
939
994
  log_llm_requests=log_llm_requests,
940
995
  ),
941
996
  )
@@ -1021,7 +1076,9 @@ async def deploy(
1021
1076
  path: Annotated[
1022
1077
  Optional[str], typer.Option(help="HTTP path to mount the service at")
1023
1078
  ] = None,
1024
- queue: Annotated[str, typer.Option(..., help="the name of the mail queue")],
1079
+ queue: Annotated[
1080
+ Optional[str], typer.Option(..., help="the name of the mail queue")
1081
+ ] = None,
1025
1082
  email_address: Annotated[
1026
1083
  str, typer.Option(..., help="the email address of the agent")
1027
1084
  ],
@@ -1107,6 +1164,10 @@ async def deploy(
1107
1164
  Optional[str],
1108
1165
  typer.Option(..., help="an image tag to use to run shell commands in"),
1109
1166
  ] = None,
1167
+ delegate_shell_token: Annotated[
1168
+ Optional[bool],
1169
+ typer.Option(..., help="Delegate the room token to shell tools"),
1170
+ ] = False,
1110
1171
  log_llm_requests: Annotated[
1111
1172
  Optional[bool],
1112
1173
  typer.Option(..., help="log all requests to the llm"),
@@ -1128,7 +1189,7 @@ async def deploy(
1128
1189
  path = f"/agent{i}"
1129
1190
 
1130
1191
  service.agents.append(
1131
- AgentSpec(name=agent_name, annotations={ANNOTATION_AGENT_TYPE: "ChatBot"})
1192
+ AgentSpec(name=agent_name, annotations={ANNOTATION_AGENT_TYPE: "MailBot"})
1132
1193
  )
1133
1194
 
1134
1195
  service.add_path(
@@ -1140,7 +1201,6 @@ async def deploy(
1140
1201
  model=model,
1141
1202
  local_shell=require_local_shell,
1142
1203
  web_search=require_web_search,
1143
- agent_name=agent_name,
1144
1204
  rule=rule,
1145
1205
  schema=require_schema + schema,
1146
1206
  toolkit=require_toolkit + toolkit,
@@ -1166,6 +1226,7 @@ async def deploy(
1166
1226
  skill_dirs=skill_dir,
1167
1227
  shell_image=shell_image,
1168
1228
  llm_participant=llm_participant,
1229
+ delegate_shell_token=delegate_shell_token,
1169
1230
  log_llm_requests=log_llm_requests,
1170
1231
  ),
1171
1232
  )
@@ -12,7 +12,7 @@ from meshagent.cli.helper import (
12
12
  resolve_room,
13
13
  resolve_key,
14
14
  )
15
-
15
+ import os
16
16
  from meshagent.api import RequiredSchema
17
17
  from meshagent.api.services import ServiceHost
18
18
 
@@ -24,7 +24,9 @@ async def join(
24
24
  *,
25
25
  project_id: ProjectIdOption,
26
26
  room: RoomOption,
27
- agent_name: Annotated[str, typer.Option(..., help="Name of the agent")],
27
+ agent_name: Annotated[
28
+ Optional[str], typer.Option(..., help="Name of the agent")
29
+ ] = None,
28
30
  key: Annotated[
29
31
  str,
30
32
  typer.Option("--key", help="an api key to sign the token with"),
@@ -47,16 +49,24 @@ async def join(
47
49
  project_id = await resolve_project_id(project_id=project_id)
48
50
  room = resolve_room(room)
49
51
 
50
- token = ParticipantToken(
51
- name=agent_name,
52
- )
52
+ jwt = os.getenv("MESHAGENT_TOKEN")
53
+ if jwt is None:
54
+ if agent_name is None:
55
+ print(
56
+ "[bold red]--agent-name must be specified when the MESHAGENT_TOKEN environment variable is not set[/bold red]"
57
+ )
58
+ raise typer.Exit(1)
59
+
60
+ token = ParticipantToken(
61
+ name=agent_name,
62
+ )
53
63
 
54
- token.add_api_grant(ApiScope.agent_default())
64
+ token.add_api_grant(ApiScope.agent_default())
55
65
 
56
- token.add_role_grant(role="agent")
57
- token.add_room_grant(room)
66
+ token.add_role_grant(role="agent")
67
+ token.add_room_grant(room)
58
68
 
59
- jwt = token.to_jwt(api_key=key)
69
+ jwt = token.to_jwt(api_key=key)
60
70
 
61
71
  print("[bold green]Connecting to room...[/bold green]", flush=True)
62
72
  async with RoomClient(
@@ -70,7 +80,6 @@ async def join(
70
80
  requirements.append(RequiredSchema(name="transcript"))
71
81
 
72
82
  bot = MeetingTranscriber(
73
- name=agent_name,
74
83
  requires=requirements,
75
84
  )
76
85
 
@@ -123,7 +132,6 @@ async def service(
123
132
  class CustomMeetingTranscriber(MeetingTranscriber):
124
133
  def __init__(self):
125
134
  super().__init__(
126
- name=agent_name,
127
135
  requires=requirements,
128
136
  )
129
137
 
@@ -19,7 +19,7 @@ from meshagent.cli.helper import (
19
19
  app = async_typer.AsyncTyper(help="Send and receive messages in a room")
20
20
 
21
21
 
22
- @app.async_command("list-participants", help="List messaging-enabled participants")
22
+ @app.async_command("list", help="List messaging-enabled participants")
23
23
  async def messaging_list_participants_command(
24
24
  *,
25
25
  project_id: ProjectIdOption,
@@ -46,7 +46,6 @@ async def messaging_list_participants_command(
46
46
  ) as client:
47
47
  # Must enable before we can see who else is enabled
48
48
  await client.messaging.enable()
49
- await client.messaging.start()
50
49
 
51
50
  participants = client.messaging.get_participants()
52
51
  output = []
@@ -92,7 +91,6 @@ async def messaging_send_command(
92
91
  ) as client:
93
92
  # Create and enable messaging
94
93
  await client.messaging.enable()
95
- await client.messaging.start()
96
94
 
97
95
  # Find the participant we want to message
98
96
  participant = None
@@ -147,7 +145,6 @@ async def messaging_broadcast_command(
147
145
  ) as client:
148
146
  # Create and enable messaging
149
147
  await client.messaging.enable()
150
- await client.messaging.start()
151
148
 
152
149
  # Broadcast the message
153
150
  await client.messaging.broadcast_message(