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/chatbot.py
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import typer
|
|
2
2
|
from rich import print
|
|
3
|
-
from typing import Annotated, Optional
|
|
4
|
-
from meshagent.tools import Toolkit
|
|
5
|
-
from meshagent.tools.storage import StorageToolkitBuilder
|
|
3
|
+
from typing import Annotated, Optional, List
|
|
4
|
+
from meshagent.tools import Toolkit, ToolkitConfig
|
|
5
|
+
from meshagent.tools.storage import StorageToolkitBuilder, StorageToolkitConfig
|
|
6
6
|
from meshagent.tools.datetime import DatetimeToolkit
|
|
7
7
|
from meshagent.tools.uuid import UUIDToolkit
|
|
8
8
|
from meshagent.tools.document_tools import (
|
|
@@ -35,8 +35,8 @@ from meshagent.cli.helper import (
|
|
|
35
35
|
)
|
|
36
36
|
|
|
37
37
|
from meshagent.openai import OpenAIResponsesAdapter
|
|
38
|
+
from meshagent.anthropic import AnthropicOpenAIResponsesStreamAdapter
|
|
38
39
|
|
|
39
|
-
from typing import List
|
|
40
40
|
from pathlib import Path
|
|
41
41
|
|
|
42
42
|
from meshagent.openai.tools.responses_adapter import (
|
|
@@ -74,6 +74,9 @@ import yaml
|
|
|
74
74
|
import shlex
|
|
75
75
|
import sys
|
|
76
76
|
|
|
77
|
+
import asyncio
|
|
78
|
+
|
|
79
|
+
|
|
77
80
|
from meshagent.api.client import ConflictError
|
|
78
81
|
|
|
79
82
|
logger = logging.getLogger("chatbot")
|
|
@@ -84,7 +87,6 @@ app = async_typer.AsyncTyper(help="Join a chatbot to a room")
|
|
|
84
87
|
def build_chatbot(
|
|
85
88
|
*,
|
|
86
89
|
model: str,
|
|
87
|
-
agent_name: str,
|
|
88
90
|
rule: List[str],
|
|
89
91
|
toolkit: List[str],
|
|
90
92
|
schema: List[str],
|
|
@@ -120,6 +122,7 @@ def build_chatbot(
|
|
|
120
122
|
skill_dirs: Optional[list[str]] = None,
|
|
121
123
|
shell_image: Optional[str] = None,
|
|
122
124
|
log_llm_requests: Optional[bool] = None,
|
|
125
|
+
delegate_shell_token: Optional[bool] = None,
|
|
123
126
|
):
|
|
124
127
|
from meshagent.agents.chat import ChatBot
|
|
125
128
|
|
|
@@ -148,6 +151,7 @@ def build_chatbot(
|
|
|
148
151
|
print(f"[yellow]rules file not found at {rules_file}[/yellow]")
|
|
149
152
|
|
|
150
153
|
BaseClass = ChatBot
|
|
154
|
+
decision_model = None
|
|
151
155
|
if llm_participant:
|
|
152
156
|
llm_adapter = MessageStreamLLMAdapter(
|
|
153
157
|
participant_name=llm_participant,
|
|
@@ -163,22 +167,29 @@ def build_chatbot(
|
|
|
163
167
|
log_requests=log_llm_requests,
|
|
164
168
|
)
|
|
165
169
|
else:
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
+
if model.startswith("claude-"):
|
|
171
|
+
llm_adapter = AnthropicOpenAIResponsesStreamAdapter(
|
|
172
|
+
model=model,
|
|
173
|
+
log_requests=log_llm_requests,
|
|
174
|
+
)
|
|
175
|
+
decision_model = model
|
|
176
|
+
else:
|
|
177
|
+
llm_adapter = OpenAIResponsesAdapter(
|
|
178
|
+
model=model,
|
|
179
|
+
log_requests=log_llm_requests,
|
|
180
|
+
)
|
|
170
181
|
|
|
171
182
|
class CustomChatbot(BaseClass):
|
|
172
183
|
def __init__(self):
|
|
173
184
|
super().__init__(
|
|
174
185
|
llm_adapter=llm_adapter,
|
|
175
|
-
name=agent_name,
|
|
176
186
|
requires=requirements,
|
|
177
187
|
toolkits=toolkits,
|
|
178
188
|
rules=rule if len(rule) > 0 else None,
|
|
179
189
|
client_rules=client_rules,
|
|
180
190
|
always_reply=always_reply,
|
|
181
191
|
skill_dirs=skill_dirs,
|
|
192
|
+
decision_model=decision_model,
|
|
182
193
|
)
|
|
183
194
|
|
|
184
195
|
async def start(self, *, room: RoomClient):
|
|
@@ -188,6 +199,14 @@ def build_chatbot(
|
|
|
188
199
|
for p in room_rules_path:
|
|
189
200
|
await self._load_room_rules(path=p)
|
|
190
201
|
|
|
202
|
+
async def init_chat_context(self):
|
|
203
|
+
from meshagent.cli.helper import init_context_from_spec
|
|
204
|
+
|
|
205
|
+
context = await super().init_chat_context()
|
|
206
|
+
await init_context_from_spec(context)
|
|
207
|
+
|
|
208
|
+
return context
|
|
209
|
+
|
|
191
210
|
async def _load_room_rules(
|
|
192
211
|
self,
|
|
193
212
|
*,
|
|
@@ -268,12 +287,18 @@ def build_chatbot(
|
|
|
268
287
|
)
|
|
269
288
|
)
|
|
270
289
|
|
|
290
|
+
env = {}
|
|
291
|
+
|
|
292
|
+
if delegate_shell_token:
|
|
293
|
+
env["MESHAGENT_TOKEN"] = self.room.protocol.token
|
|
294
|
+
|
|
271
295
|
if require_shell:
|
|
272
296
|
providers.append(
|
|
273
297
|
ShellTool(
|
|
274
298
|
working_directory=working_directory,
|
|
275
299
|
config=ShellConfig(name="shell"),
|
|
276
300
|
image=shell_image or "python:3.13",
|
|
301
|
+
env=env,
|
|
277
302
|
)
|
|
278
303
|
)
|
|
279
304
|
|
|
@@ -419,12 +444,14 @@ def build_chatbot(
|
|
|
419
444
|
|
|
420
445
|
|
|
421
446
|
@app.async_command("join")
|
|
422
|
-
async def
|
|
447
|
+
async def join(
|
|
423
448
|
*,
|
|
424
449
|
project_id: ProjectIdOption,
|
|
425
450
|
room: RoomOption,
|
|
426
451
|
role: str = "agent",
|
|
427
|
-
agent_name: Annotated[
|
|
452
|
+
agent_name: Annotated[
|
|
453
|
+
Optional[str], typer.Option(..., help="Name of the agent to call")
|
|
454
|
+
] = None,
|
|
428
455
|
rule: Annotated[List[str], typer.Option("--rule", "-r", help="a system rule")] = [],
|
|
429
456
|
room_rules: Annotated[
|
|
430
457
|
List[str],
|
|
@@ -584,6 +611,10 @@ async def make_call(
|
|
|
584
611
|
Optional[str],
|
|
585
612
|
typer.Option(..., help="an image tag to use to run shell commands in"),
|
|
586
613
|
] = None,
|
|
614
|
+
delegate_shell_token: Annotated[
|
|
615
|
+
Optional[bool],
|
|
616
|
+
typer.Option(..., help="log all requests to the llm"),
|
|
617
|
+
] = False,
|
|
587
618
|
log_llm_requests: Annotated[
|
|
588
619
|
Optional[bool],
|
|
589
620
|
typer.Option(..., help="log all requests to the llm"),
|
|
@@ -598,76 +629,92 @@ async def make_call(
|
|
|
598
629
|
project_id = await resolve_project_id(project_id=project_id)
|
|
599
630
|
room = resolve_room(room)
|
|
600
631
|
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
632
|
+
jwt = os.getenv("MESHAGENT_TOKEN")
|
|
633
|
+
if jwt is None:
|
|
634
|
+
if agent_name is None:
|
|
635
|
+
print(
|
|
636
|
+
"[bold red]--agent-name must be specified when the MESHAGENT_TOKEN environment variable is not set[/bold red]"
|
|
637
|
+
)
|
|
638
|
+
raise typer.Exit(1)
|
|
604
639
|
|
|
605
|
-
|
|
640
|
+
token = ParticipantToken(
|
|
641
|
+
name=agent_name,
|
|
642
|
+
)
|
|
606
643
|
|
|
607
|
-
|
|
608
|
-
token.add_room_grant(room)
|
|
644
|
+
token.add_api_grant(ApiScope.agent_default(tunnels=require_computer_use))
|
|
609
645
|
|
|
610
|
-
|
|
646
|
+
token.add_role_grant(role=role)
|
|
647
|
+
token.add_room_grant(room)
|
|
648
|
+
|
|
649
|
+
jwt = token.to_jwt(api_key=key)
|
|
611
650
|
|
|
612
651
|
print("[bold green]Connecting to room...[/bold green]", flush=True)
|
|
613
|
-
async with RoomClient(
|
|
614
|
-
protocol=WebSocketClientProtocol(
|
|
615
|
-
url=websocket_room_url(room_name=room, base_url=meshagent_base_url()),
|
|
616
|
-
token=jwt,
|
|
617
|
-
)
|
|
618
|
-
) as client:
|
|
619
|
-
CustomChatbot = build_chatbot(
|
|
620
|
-
computer_use=computer_use,
|
|
621
|
-
require_computer_use=require_computer_use,
|
|
622
|
-
model=model,
|
|
623
|
-
agent_name=agent_name,
|
|
624
|
-
rule=rule,
|
|
625
|
-
toolkit=require_toolkit + toolkit,
|
|
626
|
-
schema=require_schema + schema,
|
|
627
|
-
rules_file=rules_file,
|
|
628
|
-
local_shell=local_shell,
|
|
629
|
-
shell=shell,
|
|
630
|
-
apply_patch=apply_patch,
|
|
631
|
-
image_generation=image_generation,
|
|
632
|
-
web_search=web_search,
|
|
633
|
-
mcp=mcp,
|
|
634
|
-
storage=storage,
|
|
635
|
-
require_apply_patch=require_apply_patch,
|
|
636
|
-
require_web_search=require_web_search,
|
|
637
|
-
require_local_shell=require_local_shell,
|
|
638
|
-
require_shell=require_shell,
|
|
639
|
-
require_image_generation=require_image_generation,
|
|
640
|
-
require_mcp=require_mcp,
|
|
641
|
-
require_storage=require_storage,
|
|
642
|
-
require_table_read=require_table_read,
|
|
643
|
-
require_table_write=require_table_write,
|
|
644
|
-
require_read_only_storage=require_read_only_storage,
|
|
645
|
-
require_time=require_time,
|
|
646
|
-
require_uuid=require_uuid,
|
|
647
|
-
room_rules_path=room_rules,
|
|
648
|
-
require_document_authoring=require_document_authoring,
|
|
649
|
-
require_discovery=require_discovery,
|
|
650
|
-
working_directory=working_directory,
|
|
651
|
-
llm_participant=llm_participant,
|
|
652
|
-
always_reply=always_reply,
|
|
653
|
-
database_namespace=database_namespace,
|
|
654
|
-
skill_dirs=skill_dir,
|
|
655
|
-
shell_image=shell_image,
|
|
656
|
-
log_llm_requests=log_llm_requests,
|
|
657
|
-
)
|
|
658
652
|
|
|
659
|
-
|
|
653
|
+
CustomChatbot = build_chatbot(
|
|
654
|
+
computer_use=computer_use,
|
|
655
|
+
require_computer_use=require_computer_use,
|
|
656
|
+
model=model,
|
|
657
|
+
rule=rule,
|
|
658
|
+
toolkit=require_toolkit + toolkit,
|
|
659
|
+
schema=require_schema + schema,
|
|
660
|
+
rules_file=rules_file,
|
|
661
|
+
local_shell=local_shell,
|
|
662
|
+
shell=shell,
|
|
663
|
+
apply_patch=apply_patch,
|
|
664
|
+
image_generation=image_generation,
|
|
665
|
+
web_search=web_search,
|
|
666
|
+
mcp=mcp,
|
|
667
|
+
storage=storage,
|
|
668
|
+
require_apply_patch=require_apply_patch,
|
|
669
|
+
require_web_search=require_web_search,
|
|
670
|
+
require_local_shell=require_local_shell,
|
|
671
|
+
require_shell=require_shell,
|
|
672
|
+
require_image_generation=require_image_generation,
|
|
673
|
+
require_mcp=require_mcp,
|
|
674
|
+
require_storage=require_storage,
|
|
675
|
+
require_table_read=require_table_read,
|
|
676
|
+
require_table_write=require_table_write,
|
|
677
|
+
require_read_only_storage=require_read_only_storage,
|
|
678
|
+
require_time=require_time,
|
|
679
|
+
require_uuid=require_uuid,
|
|
680
|
+
room_rules_path=room_rules,
|
|
681
|
+
require_document_authoring=require_document_authoring,
|
|
682
|
+
require_discovery=require_discovery,
|
|
683
|
+
working_directory=working_directory,
|
|
684
|
+
llm_participant=llm_participant,
|
|
685
|
+
always_reply=always_reply,
|
|
686
|
+
database_namespace=database_namespace,
|
|
687
|
+
skill_dirs=skill_dir,
|
|
688
|
+
shell_image=shell_image,
|
|
689
|
+
delegate_shell_token=delegate_shell_token,
|
|
690
|
+
log_llm_requests=log_llm_requests,
|
|
691
|
+
)
|
|
660
692
|
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
693
|
+
bot = CustomChatbot()
|
|
694
|
+
|
|
695
|
+
if get_deferred():
|
|
696
|
+
from meshagent.cli.host import agents
|
|
697
|
+
|
|
698
|
+
agents.append((bot, jwt))
|
|
699
|
+
else:
|
|
700
|
+
async with RoomClient(
|
|
701
|
+
protocol=WebSocketClientProtocol(
|
|
702
|
+
url=websocket_room_url(
|
|
703
|
+
room_name=room, base_url=meshagent_base_url()
|
|
704
|
+
),
|
|
705
|
+
token=jwt,
|
|
666
706
|
)
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
707
|
+
) as client:
|
|
708
|
+
await bot.start(room=client)
|
|
709
|
+
try:
|
|
710
|
+
print(
|
|
711
|
+
f"[bold green]Open the studio to interact with your agent: {meshagent_base_url().replace('api.', 'studio.')}/projects/{project_id}/rooms/{client.room_name}[/bold green]",
|
|
712
|
+
flush=True,
|
|
713
|
+
)
|
|
714
|
+
await client.protocol.wait_for_close()
|
|
670
715
|
|
|
716
|
+
except KeyboardInterrupt:
|
|
717
|
+
await bot.stop()
|
|
671
718
|
finally:
|
|
672
719
|
await account_client.close()
|
|
673
720
|
|
|
@@ -839,6 +886,10 @@ async def service(
|
|
|
839
886
|
Optional[str],
|
|
840
887
|
typer.Option(..., help="an image tag to use to run shell commands in"),
|
|
841
888
|
] = None,
|
|
889
|
+
delegate_shell_token: Annotated[
|
|
890
|
+
Optional[bool],
|
|
891
|
+
typer.Option(..., help="log all requests to the llm"),
|
|
892
|
+
] = False,
|
|
842
893
|
log_llm_requests: Annotated[
|
|
843
894
|
Optional[bool],
|
|
844
895
|
typer.Option(..., help="log all requests to the llm"),
|
|
@@ -870,7 +921,6 @@ async def service(
|
|
|
870
921
|
local_shell=local_shell,
|
|
871
922
|
shell=shell,
|
|
872
923
|
apply_patch=apply_patch,
|
|
873
|
-
agent_name=agent_name,
|
|
874
924
|
rule=rule,
|
|
875
925
|
toolkit=require_toolkit + toolkit,
|
|
876
926
|
schema=require_schema + schema,
|
|
@@ -900,6 +950,7 @@ async def service(
|
|
|
900
950
|
always_reply=always_reply,
|
|
901
951
|
skill_dirs=skill_dir,
|
|
902
952
|
shell_image=shell_image,
|
|
953
|
+
delegate_shell_token=delegate_shell_token,
|
|
903
954
|
log_llm_requests=log_llm_requests,
|
|
904
955
|
),
|
|
905
956
|
)
|
|
@@ -1083,6 +1134,10 @@ async def spec(
|
|
|
1083
1134
|
Optional[str],
|
|
1084
1135
|
typer.Option(..., help="an image tag to use to run shell commands in"),
|
|
1085
1136
|
] = None,
|
|
1137
|
+
delegate_shell_token: Annotated[
|
|
1138
|
+
Optional[bool],
|
|
1139
|
+
typer.Option(..., help="log all requests to the llm"),
|
|
1140
|
+
] = False,
|
|
1086
1141
|
log_llm_requests: Annotated[
|
|
1087
1142
|
Optional[bool],
|
|
1088
1143
|
typer.Option(..., help="log all requests to the llm"),
|
|
@@ -1114,7 +1169,6 @@ async def spec(
|
|
|
1114
1169
|
local_shell=local_shell,
|
|
1115
1170
|
shell=shell,
|
|
1116
1171
|
apply_patch=apply_patch,
|
|
1117
|
-
agent_name=agent_name,
|
|
1118
1172
|
rule=rule,
|
|
1119
1173
|
toolkit=require_toolkit + toolkit,
|
|
1120
1174
|
schema=require_schema + schema,
|
|
@@ -1144,6 +1198,7 @@ async def spec(
|
|
|
1144
1198
|
always_reply=always_reply,
|
|
1145
1199
|
skill_dirs=skill_dir,
|
|
1146
1200
|
shell_image=shell_image,
|
|
1201
|
+
delegate_shell_token=delegate_shell_token,
|
|
1147
1202
|
log_llm_requests=log_llm_requests,
|
|
1148
1203
|
),
|
|
1149
1204
|
)
|
|
@@ -1340,6 +1395,10 @@ async def deploy(
|
|
|
1340
1395
|
Optional[str],
|
|
1341
1396
|
typer.Option(..., help="an image tag to use to run shell commands in"),
|
|
1342
1397
|
] = None,
|
|
1398
|
+
delegate_shell_token: Annotated[
|
|
1399
|
+
Optional[bool],
|
|
1400
|
+
typer.Option(..., help="log all requests to the llm"),
|
|
1401
|
+
] = False,
|
|
1343
1402
|
log_llm_requests: Annotated[
|
|
1344
1403
|
Optional[bool],
|
|
1345
1404
|
typer.Option(..., help="log all requests to the llm"),
|
|
@@ -1378,7 +1437,6 @@ async def deploy(
|
|
|
1378
1437
|
local_shell=local_shell,
|
|
1379
1438
|
shell=shell,
|
|
1380
1439
|
apply_patch=apply_patch,
|
|
1381
|
-
agent_name=agent_name,
|
|
1382
1440
|
rule=rule,
|
|
1383
1441
|
toolkit=require_toolkit + toolkit,
|
|
1384
1442
|
schema=require_schema + schema,
|
|
@@ -1408,12 +1466,16 @@ async def deploy(
|
|
|
1408
1466
|
always_reply=always_reply,
|
|
1409
1467
|
skill_dirs=skill_dir,
|
|
1410
1468
|
shell_image=shell_image,
|
|
1469
|
+
delegate_shell_token=delegate_shell_token,
|
|
1411
1470
|
log_llm_requests=log_llm_requests,
|
|
1412
1471
|
),
|
|
1413
1472
|
)
|
|
1414
1473
|
|
|
1415
1474
|
spec = service_specs()[0]
|
|
1416
1475
|
|
|
1476
|
+
for port in spec.ports:
|
|
1477
|
+
port
|
|
1478
|
+
|
|
1417
1479
|
spec.metadata.annotations = {
|
|
1418
1480
|
"meshagent.service.id": service_name,
|
|
1419
1481
|
}
|
|
@@ -1477,3 +1539,445 @@ async def deploy(
|
|
|
1477
1539
|
|
|
1478
1540
|
finally:
|
|
1479
1541
|
await client.close()
|
|
1542
|
+
|
|
1543
|
+
|
|
1544
|
+
async def chat_with(
|
|
1545
|
+
*,
|
|
1546
|
+
participant_name: str,
|
|
1547
|
+
project_id: str,
|
|
1548
|
+
room: str,
|
|
1549
|
+
thread_path: str,
|
|
1550
|
+
message: Optional[str] = None,
|
|
1551
|
+
use_web_search: bool = False,
|
|
1552
|
+
use_image_gen: bool = False,
|
|
1553
|
+
use_storage: bool = False,
|
|
1554
|
+
):
|
|
1555
|
+
from prompt_toolkit.shortcuts import PromptSession
|
|
1556
|
+
from prompt_toolkit.key_binding import KeyBindings
|
|
1557
|
+
from meshagent.agents.chat import ChatBotClient
|
|
1558
|
+
|
|
1559
|
+
kb = KeyBindings()
|
|
1560
|
+
|
|
1561
|
+
session = PromptSession("> ", key_bindings=kb)
|
|
1562
|
+
|
|
1563
|
+
account_client = await get_client()
|
|
1564
|
+
try:
|
|
1565
|
+
connection = await account_client.connect_room(project_id=project_id, room=room)
|
|
1566
|
+
async with RoomClient(
|
|
1567
|
+
protocol=WebSocketClientProtocol(
|
|
1568
|
+
url=websocket_room_url(room_name=room, base_url=meshagent_base_url()),
|
|
1569
|
+
token=connection.jwt,
|
|
1570
|
+
),
|
|
1571
|
+
) as user_client:
|
|
1572
|
+
await user_client.messaging.enable()
|
|
1573
|
+
|
|
1574
|
+
if thread_path is None:
|
|
1575
|
+
thread_path = f".threads/{participant_name}/{user_client.local_participant.get_attribute('name')}.thread"
|
|
1576
|
+
|
|
1577
|
+
async with ChatBotClient(
|
|
1578
|
+
room=user_client,
|
|
1579
|
+
participant_name=participant_name,
|
|
1580
|
+
thread_path=thread_path,
|
|
1581
|
+
) as chat_client:
|
|
1582
|
+
|
|
1583
|
+
@kb.add("c-l")
|
|
1584
|
+
def _(event):
|
|
1585
|
+
event.app.renderer.clear()
|
|
1586
|
+
asyncio.ensure_future(chat_client.clear())
|
|
1587
|
+
|
|
1588
|
+
while True:
|
|
1589
|
+
user_input = message or await session.prompt_async()
|
|
1590
|
+
|
|
1591
|
+
if user_input == "/clear":
|
|
1592
|
+
await chat_client.clear()
|
|
1593
|
+
|
|
1594
|
+
else:
|
|
1595
|
+
tools: list[ToolkitConfig] = []
|
|
1596
|
+
|
|
1597
|
+
if use_web_search:
|
|
1598
|
+
tools.append(WebSearchConfig())
|
|
1599
|
+
|
|
1600
|
+
elif use_image_gen:
|
|
1601
|
+
tools.append(ImageGenerationConfig())
|
|
1602
|
+
|
|
1603
|
+
elif use_storage:
|
|
1604
|
+
tools.append(StorageToolkitConfig())
|
|
1605
|
+
|
|
1606
|
+
await chat_client.send(text=user_input, tools=tools)
|
|
1607
|
+
|
|
1608
|
+
response = await chat_client.receive()
|
|
1609
|
+
|
|
1610
|
+
print(response)
|
|
1611
|
+
|
|
1612
|
+
if message:
|
|
1613
|
+
break
|
|
1614
|
+
|
|
1615
|
+
except asyncio.CancelledError:
|
|
1616
|
+
pass
|
|
1617
|
+
|
|
1618
|
+
finally:
|
|
1619
|
+
await account_client.close()
|
|
1620
|
+
|
|
1621
|
+
|
|
1622
|
+
@app.async_command("run")
|
|
1623
|
+
async def run(
|
|
1624
|
+
*,
|
|
1625
|
+
project_id: ProjectIdOption,
|
|
1626
|
+
room: RoomOption,
|
|
1627
|
+
role: str = "agent",
|
|
1628
|
+
agent_name: Annotated[
|
|
1629
|
+
Optional[str], typer.Option(..., help="Name of the agent to call")
|
|
1630
|
+
] = None,
|
|
1631
|
+
rule: Annotated[List[str], typer.Option("--rule", "-r", help="a system rule")] = [],
|
|
1632
|
+
room_rules: Annotated[
|
|
1633
|
+
List[str],
|
|
1634
|
+
typer.Option(
|
|
1635
|
+
"--room-rules",
|
|
1636
|
+
"-rr",
|
|
1637
|
+
help="a path to a rules file within the room that can be used to customize the agent's behavior",
|
|
1638
|
+
),
|
|
1639
|
+
] = [],
|
|
1640
|
+
rules_file: Optional[str] = None,
|
|
1641
|
+
require_toolkit: Annotated[
|
|
1642
|
+
List[str],
|
|
1643
|
+
typer.Option(
|
|
1644
|
+
"--require-toolkit", "-rt", help="the name or url of a required toolkit"
|
|
1645
|
+
),
|
|
1646
|
+
] = [],
|
|
1647
|
+
require_schema: Annotated[
|
|
1648
|
+
List[str],
|
|
1649
|
+
typer.Option(
|
|
1650
|
+
"--require-schema", "-rs", help="the name or url of a required schema"
|
|
1651
|
+
),
|
|
1652
|
+
] = [],
|
|
1653
|
+
toolkit: Annotated[
|
|
1654
|
+
List[str],
|
|
1655
|
+
typer.Option(
|
|
1656
|
+
"--toolkit", "-t", help="the name or url of a required toolkit", hidden=True
|
|
1657
|
+
),
|
|
1658
|
+
] = [],
|
|
1659
|
+
schema: Annotated[
|
|
1660
|
+
List[str],
|
|
1661
|
+
typer.Option(
|
|
1662
|
+
"--schema", "-s", help="the name or url of a required schema", hidden=True
|
|
1663
|
+
),
|
|
1664
|
+
] = [],
|
|
1665
|
+
model: Annotated[
|
|
1666
|
+
str, typer.Option(..., help="Name of the LLM model to use for the chatbot")
|
|
1667
|
+
] = "gpt-5.2",
|
|
1668
|
+
image_generation: Annotated[
|
|
1669
|
+
Optional[str], typer.Option(..., help="Name of an image gen model")
|
|
1670
|
+
] = None,
|
|
1671
|
+
computer_use: Annotated[
|
|
1672
|
+
Optional[bool],
|
|
1673
|
+
typer.Option(
|
|
1674
|
+
..., help="Enable computer use (requires computer-use-preview model)"
|
|
1675
|
+
),
|
|
1676
|
+
] = False,
|
|
1677
|
+
local_shell: Annotated[
|
|
1678
|
+
Optional[bool], typer.Option(..., help="Enable local shell tool calling")
|
|
1679
|
+
] = False,
|
|
1680
|
+
shell: Annotated[
|
|
1681
|
+
Optional[bool], typer.Option(..., help="Enable function shell tool calling")
|
|
1682
|
+
] = False,
|
|
1683
|
+
apply_patch: Annotated[
|
|
1684
|
+
Optional[bool], typer.Option(..., help="Enable apply patch tool")
|
|
1685
|
+
] = False,
|
|
1686
|
+
web_search: Annotated[
|
|
1687
|
+
Optional[bool], typer.Option(..., help="Enable web search tool calling")
|
|
1688
|
+
] = False,
|
|
1689
|
+
mcp: Annotated[
|
|
1690
|
+
Optional[bool], typer.Option(..., help="Enable mcp tool calling")
|
|
1691
|
+
] = False,
|
|
1692
|
+
storage: Annotated[
|
|
1693
|
+
Optional[bool], typer.Option(..., help="Enable storage toolkit")
|
|
1694
|
+
] = False,
|
|
1695
|
+
require_image_generation: Annotated[
|
|
1696
|
+
Optional[str], typer.Option(..., help="Name of an image gen model")
|
|
1697
|
+
] = None,
|
|
1698
|
+
require_computer_use: Annotated[
|
|
1699
|
+
Optional[bool],
|
|
1700
|
+
typer.Option(
|
|
1701
|
+
...,
|
|
1702
|
+
help="Enable computer use (requires computer-use-preview model)",
|
|
1703
|
+
hidden=True,
|
|
1704
|
+
),
|
|
1705
|
+
] = False,
|
|
1706
|
+
require_local_shell: Annotated[
|
|
1707
|
+
Optional[bool],
|
|
1708
|
+
typer.Option(..., help="Enable local shell tool calling"),
|
|
1709
|
+
] = False,
|
|
1710
|
+
require_shell: Annotated[
|
|
1711
|
+
Optional[bool],
|
|
1712
|
+
typer.Option(..., help="Enable function shell tool calling"),
|
|
1713
|
+
] = False,
|
|
1714
|
+
require_apply_patch: Annotated[
|
|
1715
|
+
Optional[bool],
|
|
1716
|
+
typer.Option(..., help="Enable apply patch tool calling"),
|
|
1717
|
+
] = False,
|
|
1718
|
+
require_web_search: Annotated[
|
|
1719
|
+
Optional[bool],
|
|
1720
|
+
typer.Option(..., help="Enable web search tool calling"),
|
|
1721
|
+
] = False,
|
|
1722
|
+
require_mcp: Annotated[
|
|
1723
|
+
Optional[bool], typer.Option(..., help="Enable mcp tool calling")
|
|
1724
|
+
] = False,
|
|
1725
|
+
require_storage: Annotated[
|
|
1726
|
+
Optional[bool], typer.Option(..., help="Enable storage toolkit")
|
|
1727
|
+
] = False,
|
|
1728
|
+
database_namespace: Annotated[
|
|
1729
|
+
Optional[str],
|
|
1730
|
+
typer.Option(..., help="Use a specific database namespace"),
|
|
1731
|
+
] = None,
|
|
1732
|
+
require_table_read: Annotated[
|
|
1733
|
+
list[str],
|
|
1734
|
+
typer.Option(..., help="Enable table read tools for a specific table"),
|
|
1735
|
+
] = [],
|
|
1736
|
+
require_table_write: Annotated[
|
|
1737
|
+
list[str],
|
|
1738
|
+
typer.Option(..., help="Enable table write tools for a specific table"),
|
|
1739
|
+
] = [],
|
|
1740
|
+
require_read_only_storage: Annotated[
|
|
1741
|
+
Optional[bool],
|
|
1742
|
+
typer.Option(..., help="Enable read only storage toolkit"),
|
|
1743
|
+
] = False,
|
|
1744
|
+
require_time: Annotated[
|
|
1745
|
+
bool,
|
|
1746
|
+
typer.Option(
|
|
1747
|
+
...,
|
|
1748
|
+
help="Enable time/datetime tools",
|
|
1749
|
+
),
|
|
1750
|
+
] = True,
|
|
1751
|
+
require_uuid: Annotated[
|
|
1752
|
+
bool,
|
|
1753
|
+
typer.Option(
|
|
1754
|
+
...,
|
|
1755
|
+
help="Enable UUID generation tools",
|
|
1756
|
+
),
|
|
1757
|
+
] = False,
|
|
1758
|
+
require_document_authoring: Annotated[
|
|
1759
|
+
Optional[bool],
|
|
1760
|
+
typer.Option(..., help="Enable MeshDocument authoring"),
|
|
1761
|
+
] = False,
|
|
1762
|
+
require_discovery: Annotated[
|
|
1763
|
+
Optional[bool],
|
|
1764
|
+
typer.Option(..., help="Enable discovery of agents and tools"),
|
|
1765
|
+
] = False,
|
|
1766
|
+
working_directory: Annotated[
|
|
1767
|
+
Optional[str],
|
|
1768
|
+
typer.Option(..., help="The default working directory for shell commands"),
|
|
1769
|
+
] = None,
|
|
1770
|
+
key: Annotated[
|
|
1771
|
+
str,
|
|
1772
|
+
typer.Option("--key", help="an api key to sign the token with"),
|
|
1773
|
+
] = None,
|
|
1774
|
+
llm_participant: Annotated[
|
|
1775
|
+
Optional[str],
|
|
1776
|
+
typer.Option(..., help="Delegate LLM interactions to a remote participant"),
|
|
1777
|
+
] = None,
|
|
1778
|
+
always_reply: Annotated[
|
|
1779
|
+
Optional[bool],
|
|
1780
|
+
typer.Option(..., help="Always reply"),
|
|
1781
|
+
] = None,
|
|
1782
|
+
skill_dir: Annotated[
|
|
1783
|
+
list[str],
|
|
1784
|
+
typer.Option(..., help="an agent skills directory"),
|
|
1785
|
+
] = [],
|
|
1786
|
+
shell_image: Annotated[
|
|
1787
|
+
Optional[str],
|
|
1788
|
+
typer.Option(..., help="an image tag to use to run shell commands in"),
|
|
1789
|
+
] = None,
|
|
1790
|
+
delegate_shell_token: Annotated[
|
|
1791
|
+
Optional[bool],
|
|
1792
|
+
typer.Option(..., help="log all requests to the llm"),
|
|
1793
|
+
] = False,
|
|
1794
|
+
log_llm_requests: Annotated[
|
|
1795
|
+
Optional[bool],
|
|
1796
|
+
typer.Option(..., help="log all requests to the llm"),
|
|
1797
|
+
] = False,
|
|
1798
|
+
thread_path: Annotated[
|
|
1799
|
+
Optional[str],
|
|
1800
|
+
typer.Option(..., help="log all requests to the llm"),
|
|
1801
|
+
] = None,
|
|
1802
|
+
message: Annotated[
|
|
1803
|
+
Optional[str],
|
|
1804
|
+
typer.Option(..., help="the input message to use"),
|
|
1805
|
+
] = None,
|
|
1806
|
+
use_web_search: Annotated[
|
|
1807
|
+
Optional[bool],
|
|
1808
|
+
typer.Option(..., help="request the web search tool"),
|
|
1809
|
+
] = None,
|
|
1810
|
+
use_image_gen: Annotated[
|
|
1811
|
+
Optional[bool],
|
|
1812
|
+
typer.Option(..., help="request the image gen tool"),
|
|
1813
|
+
] = None,
|
|
1814
|
+
use_storage: Annotated[
|
|
1815
|
+
Optional[bool],
|
|
1816
|
+
typer.Option(..., help="request the storage tool"),
|
|
1817
|
+
] = None,
|
|
1818
|
+
):
|
|
1819
|
+
root = logging.getLogger()
|
|
1820
|
+
root.setLevel(logging.ERROR)
|
|
1821
|
+
|
|
1822
|
+
if database_namespace is not None:
|
|
1823
|
+
database_namespace = database_namespace.split("::")
|
|
1824
|
+
|
|
1825
|
+
key = await resolve_key(project_id=project_id, key=key)
|
|
1826
|
+
account_client = await get_client()
|
|
1827
|
+
try:
|
|
1828
|
+
project_id = await resolve_project_id(project_id=project_id)
|
|
1829
|
+
room = resolve_room(room)
|
|
1830
|
+
|
|
1831
|
+
jwt = os.getenv("MESHAGENT_TOKEN")
|
|
1832
|
+
if jwt is None:
|
|
1833
|
+
if agent_name is None:
|
|
1834
|
+
print(
|
|
1835
|
+
"[bold red]--agent-name must be specified when the MESHAGENT_TOKEN environment variable is not set[/bold red]"
|
|
1836
|
+
)
|
|
1837
|
+
raise typer.Exit(1)
|
|
1838
|
+
|
|
1839
|
+
token = ParticipantToken(
|
|
1840
|
+
name=agent_name,
|
|
1841
|
+
)
|
|
1842
|
+
|
|
1843
|
+
token.add_api_grant(ApiScope.agent_default(tunnels=require_computer_use))
|
|
1844
|
+
|
|
1845
|
+
token.add_role_grant(role=role)
|
|
1846
|
+
token.add_room_grant(room)
|
|
1847
|
+
|
|
1848
|
+
jwt = token.to_jwt(api_key=key)
|
|
1849
|
+
|
|
1850
|
+
async with RoomClient(
|
|
1851
|
+
protocol=WebSocketClientProtocol(
|
|
1852
|
+
url=websocket_room_url(room_name=room, base_url=meshagent_base_url()),
|
|
1853
|
+
token=jwt,
|
|
1854
|
+
)
|
|
1855
|
+
) as client:
|
|
1856
|
+
CustomChatbot = build_chatbot(
|
|
1857
|
+
computer_use=computer_use,
|
|
1858
|
+
require_computer_use=require_computer_use,
|
|
1859
|
+
model=model,
|
|
1860
|
+
rule=rule,
|
|
1861
|
+
toolkit=require_toolkit + toolkit,
|
|
1862
|
+
schema=require_schema + schema,
|
|
1863
|
+
rules_file=rules_file,
|
|
1864
|
+
local_shell=local_shell,
|
|
1865
|
+
shell=shell,
|
|
1866
|
+
apply_patch=apply_patch,
|
|
1867
|
+
image_generation=image_generation,
|
|
1868
|
+
web_search=web_search,
|
|
1869
|
+
mcp=mcp,
|
|
1870
|
+
storage=storage,
|
|
1871
|
+
require_apply_patch=require_apply_patch,
|
|
1872
|
+
require_web_search=require_web_search,
|
|
1873
|
+
require_local_shell=require_local_shell,
|
|
1874
|
+
require_shell=require_shell,
|
|
1875
|
+
require_image_generation=require_image_generation,
|
|
1876
|
+
require_mcp=require_mcp,
|
|
1877
|
+
require_storage=require_storage,
|
|
1878
|
+
require_table_read=require_table_read,
|
|
1879
|
+
require_table_write=require_table_write,
|
|
1880
|
+
require_read_only_storage=require_read_only_storage,
|
|
1881
|
+
require_time=require_time,
|
|
1882
|
+
require_uuid=require_uuid,
|
|
1883
|
+
room_rules_path=room_rules,
|
|
1884
|
+
require_document_authoring=require_document_authoring,
|
|
1885
|
+
require_discovery=require_discovery,
|
|
1886
|
+
working_directory=working_directory,
|
|
1887
|
+
llm_participant=llm_participant,
|
|
1888
|
+
always_reply=always_reply,
|
|
1889
|
+
database_namespace=database_namespace,
|
|
1890
|
+
skill_dirs=skill_dir,
|
|
1891
|
+
shell_image=shell_image,
|
|
1892
|
+
delegate_shell_token=delegate_shell_token,
|
|
1893
|
+
log_llm_requests=log_llm_requests,
|
|
1894
|
+
)
|
|
1895
|
+
|
|
1896
|
+
bot = CustomChatbot()
|
|
1897
|
+
|
|
1898
|
+
await bot.start(room=client)
|
|
1899
|
+
|
|
1900
|
+
_, pending = await asyncio.wait(
|
|
1901
|
+
[
|
|
1902
|
+
asyncio.create_task(client.protocol.wait_for_close()),
|
|
1903
|
+
asyncio.create_task(
|
|
1904
|
+
chat_with(
|
|
1905
|
+
participant_name=client.local_participant.get_attribute(
|
|
1906
|
+
"name"
|
|
1907
|
+
),
|
|
1908
|
+
room=room,
|
|
1909
|
+
project_id=project_id,
|
|
1910
|
+
thread_path=thread_path,
|
|
1911
|
+
message=message,
|
|
1912
|
+
use_web_search=use_web_search,
|
|
1913
|
+
use_image_gen=use_image_gen,
|
|
1914
|
+
use_storage=use_storage,
|
|
1915
|
+
)
|
|
1916
|
+
),
|
|
1917
|
+
],
|
|
1918
|
+
return_when="FIRST_COMPLETED",
|
|
1919
|
+
)
|
|
1920
|
+
|
|
1921
|
+
for t in pending:
|
|
1922
|
+
t.cancel()
|
|
1923
|
+
|
|
1924
|
+
except asyncio.CancelledError:
|
|
1925
|
+
return
|
|
1926
|
+
|
|
1927
|
+
finally:
|
|
1928
|
+
await account_client.close()
|
|
1929
|
+
|
|
1930
|
+
|
|
1931
|
+
@app.async_command("use")
|
|
1932
|
+
async def use(
|
|
1933
|
+
*,
|
|
1934
|
+
project_id: ProjectIdOption,
|
|
1935
|
+
room: RoomOption,
|
|
1936
|
+
agent_name: Annotated[
|
|
1937
|
+
Optional[str], typer.Option(..., help="Name of the agent to call")
|
|
1938
|
+
] = None,
|
|
1939
|
+
thread_path: Annotated[
|
|
1940
|
+
Optional[str],
|
|
1941
|
+
typer.Option(..., help="log all requests to the llm"),
|
|
1942
|
+
] = None,
|
|
1943
|
+
message: Annotated[
|
|
1944
|
+
Optional[str],
|
|
1945
|
+
typer.Option(..., help="the input message to use"),
|
|
1946
|
+
] = None,
|
|
1947
|
+
use_web_search: Annotated[
|
|
1948
|
+
Optional[bool],
|
|
1949
|
+
typer.Option(..., help="request the web search tool"),
|
|
1950
|
+
] = None,
|
|
1951
|
+
use_image_gen: Annotated[
|
|
1952
|
+
Optional[bool],
|
|
1953
|
+
typer.Option(..., help="request the image gen tool"),
|
|
1954
|
+
] = None,
|
|
1955
|
+
use_storage: Annotated[
|
|
1956
|
+
Optional[bool],
|
|
1957
|
+
typer.Option(..., help="request the storage tool"),
|
|
1958
|
+
] = None,
|
|
1959
|
+
):
|
|
1960
|
+
root = logging.getLogger()
|
|
1961
|
+
root.setLevel(logging.ERROR)
|
|
1962
|
+
|
|
1963
|
+
account_client = await get_client()
|
|
1964
|
+
try:
|
|
1965
|
+
project_id = await resolve_project_id(project_id=project_id)
|
|
1966
|
+
room = resolve_room(room)
|
|
1967
|
+
|
|
1968
|
+
await chat_with(
|
|
1969
|
+
participant_name=agent_name,
|
|
1970
|
+
room=room,
|
|
1971
|
+
project_id=project_id,
|
|
1972
|
+
thread_path=thread_path,
|
|
1973
|
+
message=message,
|
|
1974
|
+
use_web_search=use_web_search,
|
|
1975
|
+
use_image_gen=use_image_gen,
|
|
1976
|
+
use_storage=use_storage,
|
|
1977
|
+
)
|
|
1978
|
+
|
|
1979
|
+
except asyncio.CancelledError:
|
|
1980
|
+
return
|
|
1981
|
+
|
|
1982
|
+
finally:
|
|
1983
|
+
await account_client.close()
|