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/agent.py +8 -2
- meshagent/cli/call.py +15 -28
- meshagent/cli/chatbot.py +580 -76
- meshagent/cli/cli.py +3 -3
- meshagent/cli/helper.py +40 -2
- meshagent/cli/helpers.py +0 -3
- meshagent/cli/host.py +4 -0
- meshagent/cli/mailbot.py +137 -76
- meshagent/cli/meeting_transcriber.py +19 -11
- meshagent/cli/messaging.py +1 -4
- meshagent/cli/multi.py +53 -98
- meshagent/cli/oauth2.py +164 -35
- meshagent/cli/room.py +6 -2
- meshagent/cli/services.py +238 -15
- meshagent/cli/sync.py +434 -0
- meshagent/cli/task_runner.py +625 -78
- meshagent/cli/version.py +1 -1
- meshagent/cli/voicebot.py +54 -34
- meshagent/cli/worker.py +151 -75
- {meshagent_cli-0.21.0.dist-info → meshagent_cli-0.23.0.dist-info}/METADATA +13 -11
- meshagent_cli-0.23.0.dist-info/RECORD +45 -0
- {meshagent_cli-0.21.0.dist-info → meshagent_cli-0.23.0.dist-info}/WHEEL +1 -1
- meshagent_cli-0.21.0.dist-info/RECORD +0 -44
- {meshagent_cli-0.21.0.dist-info → meshagent_cli-0.23.0.dist-info}/entry_points.txt +0 -0
- {meshagent_cli-0.21.0.dist-info → meshagent_cli-0.23.0.dist-info}/top_level.txt +0 -0
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
|
|
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="
|
|
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(
|
|
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("
|
|
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
|
|
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 =
|
|
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
|
-
|
|
143
|
-
|
|
144
|
-
|
|
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
|
|
339
|
+
async def join(
|
|
320
340
|
*,
|
|
321
341
|
project_id: ProjectIdOption,
|
|
322
342
|
room: RoomOption,
|
|
323
343
|
role: str = "agent",
|
|
324
|
-
agent_name: Annotated[
|
|
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[
|
|
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
|
-
|
|
468
|
-
|
|
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
|
-
|
|
503
|
+
token = ParticipantToken(
|
|
504
|
+
name=agent_name,
|
|
505
|
+
)
|
|
506
|
+
|
|
507
|
+
token.add_api_grant(ApiScope.agent_default(tunnels=require_computer_use))
|
|
472
508
|
|
|
473
|
-
|
|
474
|
-
|
|
509
|
+
token.add_role_grant(role=role)
|
|
510
|
+
token.add_room_grant(room)
|
|
475
511
|
|
|
476
|
-
|
|
512
|
+
jwt = token.to_jwt(api_key=key)
|
|
477
513
|
|
|
478
514
|
print("[bold green]Connecting to room...[/bold green]", flush=True)
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
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
|
-
|
|
550
|
+
bot = CustomMailbot()
|
|
521
551
|
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
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
|
-
|
|
528
|
-
|
|
529
|
-
|
|
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[
|
|
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: "
|
|
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[
|
|
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: "
|
|
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[
|
|
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: "
|
|
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[
|
|
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
|
-
|
|
51
|
-
|
|
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
|
-
|
|
64
|
+
token.add_api_grant(ApiScope.agent_default())
|
|
55
65
|
|
|
56
|
-
|
|
57
|
-
|
|
66
|
+
token.add_role_grant(role="agent")
|
|
67
|
+
token.add_room_grant(room)
|
|
58
68
|
|
|
59
|
-
|
|
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
|
|
meshagent/cli/messaging.py
CHANGED
|
@@ -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
|
|
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(
|