meshagent-cli 0.5.15__py3-none-any.whl → 0.6.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.
Potentially problematic release.
This version of meshagent-cli might be problematic. Click here for more details.
- meshagent/cli/agent.py +11 -62
- meshagent/cli/api_keys.py +46 -93
- meshagent/cli/auth_async.py +225 -68
- meshagent/cli/call.py +82 -19
- meshagent/cli/chatbot.py +83 -49
- meshagent/cli/cli.py +26 -70
- meshagent/cli/cli_mcp.py +61 -27
- meshagent/cli/cli_secrets.py +1 -1
- meshagent/cli/common_options.py +2 -10
- meshagent/cli/containers.py +577 -0
- meshagent/cli/developer.py +7 -25
- meshagent/cli/exec.py +162 -76
- meshagent/cli/helper.py +35 -67
- meshagent/cli/helpers.py +131 -0
- meshagent/cli/mailbot.py +31 -26
- meshagent/cli/meeting_transcriber.py +124 -0
- meshagent/cli/messaging.py +12 -51
- meshagent/cli/oauth2.py +189 -0
- meshagent/cli/participant_token.py +32 -21
- meshagent/cli/queue.py +6 -37
- meshagent/cli/services.py +300 -335
- meshagent/cli/storage.py +24 -89
- meshagent/cli/version.py +1 -1
- meshagent/cli/voicebot.py +39 -28
- meshagent/cli/webhook.py +3 -3
- {meshagent_cli-0.5.15.dist-info → meshagent_cli-0.6.0.dist-info}/METADATA +17 -11
- meshagent_cli-0.6.0.dist-info/RECORD +35 -0
- meshagent/cli/otel.py +0 -122
- meshagent_cli-0.5.15.dist-info/RECORD +0 -32
- {meshagent_cli-0.5.15.dist-info → meshagent_cli-0.6.0.dist-info}/WHEEL +0 -0
- {meshagent_cli-0.5.15.dist-info → meshagent_cli-0.6.0.dist-info}/entry_points.txt +0 -0
- {meshagent_cli-0.5.15.dist-info → meshagent_cli-0.6.0.dist-info}/top_level.txt +0 -0
meshagent/cli/exec.py
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import sys
|
|
2
|
-
import
|
|
3
|
-
import termios
|
|
2
|
+
import os
|
|
4
3
|
from meshagent.api.websocket_protocol import WebSocketClientProtocol
|
|
5
4
|
from meshagent.api import RoomClient
|
|
6
5
|
from meshagent.api.helpers import websocket_room_url
|
|
7
6
|
from typing import Annotated, Optional
|
|
8
|
-
from meshagent.cli.common_options import ProjectIdOption,
|
|
7
|
+
from meshagent.cli.common_options import ProjectIdOption, RoomOption
|
|
9
8
|
import asyncio
|
|
10
9
|
import typer
|
|
11
10
|
from rich import print
|
|
@@ -15,18 +14,69 @@ import signal
|
|
|
15
14
|
import shutil
|
|
16
15
|
import json
|
|
17
16
|
from urllib.parse import quote
|
|
17
|
+
import threading
|
|
18
|
+
import time
|
|
18
19
|
|
|
19
|
-
from meshagent.api import ParticipantToken
|
|
20
20
|
|
|
21
21
|
import logging
|
|
22
22
|
|
|
23
23
|
from meshagent.cli.helper import (
|
|
24
24
|
get_client,
|
|
25
25
|
resolve_project_id,
|
|
26
|
-
resolve_api_key,
|
|
27
26
|
resolve_room,
|
|
28
27
|
)
|
|
29
28
|
|
|
29
|
+
if os.name == "nt":
|
|
30
|
+
import msvcrt
|
|
31
|
+
import ctypes
|
|
32
|
+
from ctypes import wintypes
|
|
33
|
+
|
|
34
|
+
_kernel32 = ctypes.windll.kernel32
|
|
35
|
+
_ENABLE_ECHO_INPUT = 0x0004
|
|
36
|
+
_ENABLE_LINE_INPUT = 0x0002
|
|
37
|
+
|
|
38
|
+
def set_raw(f):
|
|
39
|
+
"""Disable line and echo mode for the given file handle."""
|
|
40
|
+
handle = msvcrt.get_osfhandle(f.fileno())
|
|
41
|
+
original_mode = wintypes.DWORD()
|
|
42
|
+
if not _kernel32.GetConsoleMode(handle, ctypes.byref(original_mode)):
|
|
43
|
+
return None
|
|
44
|
+
new_mode = original_mode.value & ~(_ENABLE_ECHO_INPUT | _ENABLE_LINE_INPUT)
|
|
45
|
+
_kernel32.SetConsoleMode(handle, new_mode)
|
|
46
|
+
return handle, original_mode.value
|
|
47
|
+
|
|
48
|
+
def restore(f, state):
|
|
49
|
+
if state is None:
|
|
50
|
+
return None
|
|
51
|
+
handle, mode = state
|
|
52
|
+
_kernel32.SetConsoleMode(handle, mode)
|
|
53
|
+
return None
|
|
54
|
+
|
|
55
|
+
else:
|
|
56
|
+
import termios
|
|
57
|
+
import tty as _tty
|
|
58
|
+
|
|
59
|
+
def set_raw(fd):
|
|
60
|
+
old = termios.tcgetattr(fd)
|
|
61
|
+
_tty.setraw(fd)
|
|
62
|
+
return old
|
|
63
|
+
|
|
64
|
+
def restore(fd, old_settings):
|
|
65
|
+
termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
class _StdWriter:
|
|
69
|
+
"""Simple asyncio-friendly wrapper for standard streams on Windows."""
|
|
70
|
+
|
|
71
|
+
def __init__(self, file):
|
|
72
|
+
self._file = file
|
|
73
|
+
|
|
74
|
+
def write(self, data: bytes) -> None:
|
|
75
|
+
self._file.buffer.write(data)
|
|
76
|
+
|
|
77
|
+
async def drain(self) -> None:
|
|
78
|
+
await asyncio.get_running_loop().run_in_executor(None, self._file.flush)
|
|
79
|
+
|
|
30
80
|
|
|
31
81
|
def register(app: typer.Typer):
|
|
32
82
|
@app.async_command("exec")
|
|
@@ -36,7 +86,6 @@ def register(app: typer.Typer):
|
|
|
36
86
|
room: RoomOption,
|
|
37
87
|
name: Annotated[Optional[str], typer.Option()] = None,
|
|
38
88
|
image: Annotated[Optional[str], typer.Option()] = None,
|
|
39
|
-
api_key_id: ApiKeyIdOption = None,
|
|
40
89
|
command: Annotated[list[str], typer.Argument(...)] = None,
|
|
41
90
|
tty: bool = False,
|
|
42
91
|
room_storage_path: str = "/data",
|
|
@@ -45,27 +94,12 @@ def register(app: typer.Typer):
|
|
|
45
94
|
client = await get_client()
|
|
46
95
|
try:
|
|
47
96
|
project_id = await resolve_project_id(project_id=project_id)
|
|
48
|
-
api_key_id = await resolve_api_key(
|
|
49
|
-
project_id=project_id, api_key_id=api_key_id
|
|
50
|
-
)
|
|
51
97
|
room = resolve_room(room)
|
|
52
98
|
|
|
53
|
-
|
|
54
|
-
name="tty", project_id=project_id, api_key_id=api_key_id
|
|
55
|
-
)
|
|
56
|
-
|
|
57
|
-
key = (
|
|
58
|
-
await client.decrypt_project_api_key(
|
|
59
|
-
project_id=project_id, id=api_key_id
|
|
60
|
-
)
|
|
61
|
-
)["token"]
|
|
62
|
-
|
|
63
|
-
token.add_role_grant(role="user")
|
|
64
|
-
token.add_room_grant(room)
|
|
99
|
+
connection = await client.connect_room(project_id=project_id, room=room)
|
|
65
100
|
|
|
66
101
|
ws_url = (
|
|
67
|
-
websocket_room_url(room_name=room)
|
|
68
|
-
+ f"/exec?token={token.to_jwt(token=key)}"
|
|
102
|
+
websocket_room_url(room_name=room) + f"/exec?token={connection.jwt}"
|
|
69
103
|
)
|
|
70
104
|
|
|
71
105
|
if image:
|
|
@@ -98,13 +132,12 @@ def register(app: typer.Typer):
|
|
|
98
132
|
|
|
99
133
|
if tty:
|
|
100
134
|
# Save current terminal settings so we can restore them later.
|
|
101
|
-
old_tty_settings =
|
|
102
|
-
_tty.setraw(sys.stdin)
|
|
135
|
+
old_tty_settings = set_raw(sys.stdin)
|
|
103
136
|
|
|
104
137
|
async with RoomClient(
|
|
105
138
|
protocol=WebSocketClientProtocol(
|
|
106
139
|
url=websocket_room_url(room_name=room),
|
|
107
|
-
token=
|
|
140
|
+
token=connection.jwt,
|
|
108
141
|
)
|
|
109
142
|
):
|
|
110
143
|
try:
|
|
@@ -113,25 +146,29 @@ def register(app: typer.Typer):
|
|
|
113
146
|
send_queue = asyncio.Queue[bytes]()
|
|
114
147
|
|
|
115
148
|
loop = asyncio.get_running_loop()
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
149
|
+
if os.name == "nt":
|
|
150
|
+
stdout_writer = _StdWriter(sys.stdout)
|
|
151
|
+
stderr_writer = _StdWriter(sys.stderr)
|
|
152
|
+
else:
|
|
153
|
+
(
|
|
154
|
+
stdout_transport,
|
|
155
|
+
stdout_protocol,
|
|
156
|
+
) = await loop.connect_write_pipe(
|
|
157
|
+
asyncio.streams.FlowControlMixin, sys.stdout
|
|
158
|
+
)
|
|
159
|
+
stdout_writer = asyncio.StreamWriter(
|
|
160
|
+
stdout_transport, stdout_protocol, None, loop
|
|
161
|
+
)
|
|
125
162
|
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
163
|
+
(
|
|
164
|
+
stderr_transport,
|
|
165
|
+
stderr_protocol,
|
|
166
|
+
) = await loop.connect_write_pipe(
|
|
167
|
+
asyncio.streams.FlowControlMixin, sys.stderr
|
|
168
|
+
)
|
|
169
|
+
stderr_writer = asyncio.StreamWriter(
|
|
170
|
+
stderr_transport, stderr_protocol, None, loop
|
|
171
|
+
)
|
|
135
172
|
|
|
136
173
|
async def recv_from_websocket():
|
|
137
174
|
while True:
|
|
@@ -206,46 +243,97 @@ def register(app: typer.Typer):
|
|
|
206
243
|
|
|
207
244
|
task.add_done_callback(on_done)
|
|
208
245
|
|
|
209
|
-
|
|
246
|
+
if hasattr(signal, "SIGWINCH"):
|
|
247
|
+
loop.add_signal_handler(signal.SIGWINCH, on_sigwinch)
|
|
210
248
|
|
|
211
249
|
async def read_stdin():
|
|
212
250
|
loop = asyncio.get_running_loop()
|
|
213
251
|
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
252
|
+
if os.name == "nt":
|
|
253
|
+
queue: asyncio.Queue[bytes] = asyncio.Queue()
|
|
254
|
+
stop_event = threading.Event()
|
|
255
|
+
|
|
256
|
+
if sys.stdin.isatty():
|
|
257
|
+
|
|
258
|
+
def reader() -> None:
|
|
259
|
+
try:
|
|
260
|
+
while not stop_event.is_set():
|
|
261
|
+
if msvcrt.kbhit():
|
|
262
|
+
data = msvcrt.getch()
|
|
263
|
+
loop.call_soon_threadsafe(
|
|
264
|
+
queue.put_nowait, data
|
|
265
|
+
)
|
|
266
|
+
else:
|
|
267
|
+
time.sleep(0.01)
|
|
268
|
+
finally:
|
|
269
|
+
loop.call_soon_threadsafe(
|
|
270
|
+
queue.put_nowait, b""
|
|
271
|
+
)
|
|
272
|
+
else:
|
|
219
273
|
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
274
|
+
def reader() -> None:
|
|
275
|
+
try:
|
|
276
|
+
while not stop_event.is_set():
|
|
277
|
+
data = sys.stdin.buffer.read(1)
|
|
278
|
+
loop.call_soon_threadsafe(
|
|
279
|
+
queue.put_nowait, data
|
|
280
|
+
)
|
|
281
|
+
if not data:
|
|
282
|
+
break
|
|
283
|
+
finally:
|
|
284
|
+
loop.call_soon_threadsafe(
|
|
285
|
+
queue.put_nowait, b""
|
|
286
|
+
)
|
|
287
|
+
|
|
288
|
+
thread = threading.Thread(target=reader)
|
|
289
|
+
thread.start()
|
|
290
|
+
|
|
291
|
+
async def reader_task() -> bytes:
|
|
292
|
+
return await queue.get()
|
|
293
|
+
else:
|
|
294
|
+
reader = asyncio.StreamReader()
|
|
295
|
+
protocol = asyncio.StreamReaderProtocol(reader)
|
|
296
|
+
await loop.connect_read_pipe(
|
|
297
|
+
lambda: protocol, sys.stdin
|
|
228
298
|
)
|
|
229
299
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
300
|
+
async def reader_task():
|
|
301
|
+
return await reader.read(1)
|
|
302
|
+
|
|
303
|
+
try:
|
|
304
|
+
while True:
|
|
305
|
+
# Read one character at a time from stdin without blocking the event loop.
|
|
306
|
+
done, pending = await asyncio.wait(
|
|
307
|
+
[
|
|
308
|
+
asyncio.create_task(reader_task()),
|
|
309
|
+
websocket_recv_task,
|
|
310
|
+
],
|
|
311
|
+
return_when=asyncio.FIRST_COMPLETED,
|
|
312
|
+
)
|
|
313
|
+
|
|
314
|
+
first = done.pop()
|
|
315
|
+
if first == websocket_recv_task:
|
|
316
|
+
break
|
|
237
317
|
|
|
238
|
-
|
|
239
|
-
|
|
318
|
+
data = first.result()
|
|
319
|
+
if not data:
|
|
320
|
+
break
|
|
240
321
|
|
|
241
|
-
|
|
242
|
-
if data == b"\x04":
|
|
322
|
+
if websocket.closed:
|
|
243
323
|
break
|
|
244
324
|
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
325
|
+
if tty:
|
|
326
|
+
if data == b"\x04":
|
|
327
|
+
break
|
|
328
|
+
|
|
329
|
+
if data:
|
|
330
|
+
send_queue.put_nowait(b"\0" + data)
|
|
331
|
+
else:
|
|
332
|
+
break
|
|
333
|
+
finally:
|
|
334
|
+
if os.name == "nt":
|
|
335
|
+
stop_event.set()
|
|
336
|
+
thread.join()
|
|
249
337
|
|
|
250
338
|
send_queue.put_nowait(b"\0")
|
|
251
339
|
|
|
@@ -283,9 +371,7 @@ def register(app: typer.Typer):
|
|
|
283
371
|
finally:
|
|
284
372
|
if not sys.stdin.closed and tty:
|
|
285
373
|
# Restore original terminal settings even if the coroutine is cancelled.
|
|
286
|
-
|
|
287
|
-
sys.stdin, termios.TCSADRAIN, old_tty_settings
|
|
288
|
-
)
|
|
374
|
+
restore(sys.stdin, old_tty_settings)
|
|
289
375
|
|
|
290
376
|
except Exception as e:
|
|
291
377
|
print(f"[red]{e}[/red]")
|
meshagent/cli/helper.py
CHANGED
|
@@ -7,10 +7,9 @@ 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.
|
|
11
|
-
from meshagent.api.participant_token import ParticipantToken
|
|
12
|
-
|
|
10
|
+
from meshagent.api.client import Meshagent
|
|
13
11
|
import os
|
|
12
|
+
from rich import print
|
|
14
13
|
|
|
15
14
|
SETTINGS_FILE = Path.home() / ".meshagent" / "project.json"
|
|
16
15
|
|
|
@@ -50,25 +49,38 @@ async def set_active_project(project_id: str | None):
|
|
|
50
49
|
_save_settings(settings)
|
|
51
50
|
|
|
52
51
|
|
|
53
|
-
async def
|
|
52
|
+
async def set_active_api_key(project_id: str, key: str):
|
|
54
53
|
settings = _load_settings()
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
return settings.active_api_keys.get(project_id, None)
|
|
54
|
+
settings.active_api_keys[project_id] = key
|
|
55
|
+
_save_settings(settings)
|
|
58
56
|
|
|
59
57
|
|
|
60
|
-
async def
|
|
58
|
+
async def get_active_api_key(project_id: str):
|
|
61
59
|
settings = _load_settings()
|
|
62
|
-
settings.active_api_keys
|
|
63
|
-
|
|
60
|
+
key: str = settings.active_api_keys.get(project_id)
|
|
61
|
+
# Ignore old keys, API key format changed
|
|
62
|
+
if key is not None and key.startswith("ma-"):
|
|
63
|
+
return key
|
|
64
|
+
else:
|
|
65
|
+
return None
|
|
64
66
|
|
|
65
67
|
|
|
66
68
|
app = async_typer.AsyncTyper()
|
|
67
69
|
|
|
68
70
|
|
|
69
71
|
async def get_client():
|
|
70
|
-
|
|
71
|
-
|
|
72
|
+
key = os.getenv("MESHAGENT_API_KEY")
|
|
73
|
+
if key is not None:
|
|
74
|
+
return Meshagent(
|
|
75
|
+
base_url=meshagent_base_url(),
|
|
76
|
+
token=key,
|
|
77
|
+
)
|
|
78
|
+
else:
|
|
79
|
+
access_token = await auth_async.get_access_token()
|
|
80
|
+
return Meshagent(
|
|
81
|
+
base_url=meshagent_base_url(),
|
|
82
|
+
token=access_token,
|
|
83
|
+
)
|
|
72
84
|
|
|
73
85
|
|
|
74
86
|
def print_json_table(records: list, *cols):
|
|
@@ -118,62 +130,18 @@ async def resolve_project_id(project_id: Optional[str] = None):
|
|
|
118
130
|
return project_id
|
|
119
131
|
|
|
120
132
|
|
|
121
|
-
async def
|
|
122
|
-
|
|
123
|
-
|
|
133
|
+
async def resolve_key(project_id: str | None, key: str | None):
|
|
134
|
+
project_id = await resolve_project_id(project_id=project_id)
|
|
135
|
+
if key is None:
|
|
136
|
+
key = await get_active_api_key(project_id=project_id)
|
|
137
|
+
|
|
138
|
+
if key is None:
|
|
139
|
+
key = os.getenv("MESHAGENT_API_KEY")
|
|
124
140
|
|
|
125
|
-
if
|
|
141
|
+
if key is None:
|
|
126
142
|
print(
|
|
127
|
-
"[red]
|
|
143
|
+
"[red]--key is required if MESHGENT_API_KEY is not set. You can use meshagent api-key create to create a new api key."
|
|
128
144
|
)
|
|
129
|
-
raise typer.Exit(
|
|
145
|
+
raise typer.Exit(1)
|
|
130
146
|
|
|
131
|
-
return
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
async def resolve_token_jwt(
|
|
135
|
-
*,
|
|
136
|
-
project_id: str,
|
|
137
|
-
api_key_id: Optional[str] = None,
|
|
138
|
-
token_path: Optional[str] = None,
|
|
139
|
-
name: Optional[str] = None,
|
|
140
|
-
role: Optional[str] = None,
|
|
141
|
-
room: Optional[str] = None,
|
|
142
|
-
) -> str:
|
|
143
|
-
jwt = None
|
|
144
|
-
|
|
145
|
-
if api_key_id is None:
|
|
146
|
-
if token_path is not None:
|
|
147
|
-
if token_path is None:
|
|
148
|
-
token_path = os.getenv(
|
|
149
|
-
"MESHAGENT_TOKEN_PATH",
|
|
150
|
-
(Path.home() / ".meshagent" / "token").as_posix(),
|
|
151
|
-
)
|
|
152
|
-
|
|
153
|
-
p = Path(token_path)
|
|
154
|
-
jwt = p.read_text().strip()
|
|
155
|
-
|
|
156
|
-
else:
|
|
157
|
-
jwt = os.getenv("MESHAGENT_TOKEN", None)
|
|
158
|
-
|
|
159
|
-
if jwt is None:
|
|
160
|
-
account_client = await get_client()
|
|
161
|
-
try:
|
|
162
|
-
key = (
|
|
163
|
-
await account_client.decrypt_project_api_key(
|
|
164
|
-
project_id=project_id, id=api_key_id
|
|
165
|
-
)
|
|
166
|
-
)["token"]
|
|
167
|
-
|
|
168
|
-
token = ParticipantToken(
|
|
169
|
-
name=name, project_id=project_id, api_key_id=api_key_id
|
|
170
|
-
)
|
|
171
|
-
|
|
172
|
-
token.add_role_grant(role=role)
|
|
173
|
-
token.add_room_grant(room)
|
|
174
|
-
|
|
175
|
-
jwt = token.to_jwt(token=key)
|
|
176
|
-
finally:
|
|
177
|
-
await account_client.close()
|
|
178
|
-
|
|
179
|
-
return jwt
|
|
147
|
+
return key
|
meshagent/cli/helpers.py
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
from meshagent.cli import async_typer
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
from meshagent.api import SchemaRegistry, SchemaRegistration
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
import logging
|
|
8
|
+
|
|
9
|
+
app = async_typer.AsyncTyper(help="Join a mailbot to a room")
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@app.async_command("service")
|
|
13
|
+
async def helpers_service():
|
|
14
|
+
from meshagent.agents.planning import DynamicPlanningResponder, PlanningResponder
|
|
15
|
+
from meshagent.openai.tools import OpenAIResponsesAdapter
|
|
16
|
+
from meshagent.tools.storage import StorageToolkit
|
|
17
|
+
from meshagent.api.services import ServiceHost
|
|
18
|
+
|
|
19
|
+
from meshagent.agents.schemas.gallery import gallery_schema
|
|
20
|
+
from meshagent.agents.schemas.document import document_schema
|
|
21
|
+
from meshagent.agents.schemas.transcript import transcript_schema
|
|
22
|
+
from meshagent.agents.schemas.super_editor_document import (
|
|
23
|
+
super_editor_document_schema,
|
|
24
|
+
)
|
|
25
|
+
from meshagent.agents.schemas.presentation import presentation_schema
|
|
26
|
+
from meshagent.agents import thread_schema
|
|
27
|
+
|
|
28
|
+
logging.getLogger("openai").setLevel(logging.ERROR)
|
|
29
|
+
logging.getLogger("httpx").setLevel(logging.ERROR)
|
|
30
|
+
|
|
31
|
+
service = ServiceHost(port=9000)
|
|
32
|
+
|
|
33
|
+
@service.path("/planner")
|
|
34
|
+
class Planner(PlanningResponder):
|
|
35
|
+
def __init__(self, **kwargs):
|
|
36
|
+
super().__init__(
|
|
37
|
+
name="meshagent.planner",
|
|
38
|
+
title="Generic Task Runner",
|
|
39
|
+
description="an agent that will perform a task with the selected tools",
|
|
40
|
+
llm_adapter=OpenAIResponsesAdapter(model="gpt-4.1"),
|
|
41
|
+
supports_tools=True,
|
|
42
|
+
input_prompt=True,
|
|
43
|
+
output_schema={
|
|
44
|
+
"type": "object",
|
|
45
|
+
"required": ["result"],
|
|
46
|
+
"additionalProperties": False,
|
|
47
|
+
"properties": {"result": {"type": "string"}},
|
|
48
|
+
},
|
|
49
|
+
)
|
|
50
|
+
|
|
51
|
+
@service.path("/schema_planner")
|
|
52
|
+
class DynamicPlanner(DynamicPlanningResponder):
|
|
53
|
+
def __init__(self, **kwargs):
|
|
54
|
+
super().__init__(
|
|
55
|
+
name="meshagent.schema_planner",
|
|
56
|
+
title="Schema Task Runner",
|
|
57
|
+
description="an agent that can produces output that matches a schema",
|
|
58
|
+
llm_adapter=OpenAIResponsesAdapter(model="gpt-4.1"),
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
@service.path("/schemas/document")
|
|
62
|
+
class DocumentSchemaRegistry(SchemaRegistry):
|
|
63
|
+
def __init__(self):
|
|
64
|
+
name = "document"
|
|
65
|
+
schema = document_schema
|
|
66
|
+
super().__init__(
|
|
67
|
+
name=f"meshagent.schema.{name}",
|
|
68
|
+
validate_webhook_secret=False,
|
|
69
|
+
schemas=[SchemaRegistration(name=name, schema=schema)],
|
|
70
|
+
)
|
|
71
|
+
|
|
72
|
+
@service.path("/schemas/superdoc")
|
|
73
|
+
class SuperdocDocumentSchemaRegistry(SchemaRegistry):
|
|
74
|
+
def __init__(self):
|
|
75
|
+
name = "superdoc"
|
|
76
|
+
schema = super_editor_document_schema
|
|
77
|
+
super().__init__(
|
|
78
|
+
name=f"meshagent.schema.{name}",
|
|
79
|
+
validate_webhook_secret=False,
|
|
80
|
+
schemas=[SchemaRegistration(name=name, schema=schema)],
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
@service.path("/schemas/gallery")
|
|
84
|
+
class GalleryDocumentSchemaRegistry(SchemaRegistry):
|
|
85
|
+
def __init__(self):
|
|
86
|
+
name = "gallery"
|
|
87
|
+
schema = gallery_schema
|
|
88
|
+
super().__init__(
|
|
89
|
+
name=f"meshagent.schema.{name}",
|
|
90
|
+
validate_webhook_secret=False,
|
|
91
|
+
schemas=[SchemaRegistration(name=name, schema=schema)],
|
|
92
|
+
)
|
|
93
|
+
|
|
94
|
+
@service.path("/schemas/thread")
|
|
95
|
+
class ThreadDocumentSchemaRegistry(SchemaRegistry):
|
|
96
|
+
def __init__(self):
|
|
97
|
+
name = "thread"
|
|
98
|
+
schema = thread_schema
|
|
99
|
+
super().__init__(
|
|
100
|
+
name=f"meshagent.schema.{name}",
|
|
101
|
+
validate_webhook_secret=False,
|
|
102
|
+
schemas=[SchemaRegistration(name=name, schema=schema)],
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
@service.path("/schemas/presentation")
|
|
106
|
+
class PresentationDocumentSchemaRegistry(SchemaRegistry):
|
|
107
|
+
def __init__(presentation):
|
|
108
|
+
name = "presentation"
|
|
109
|
+
schema = presentation_schema
|
|
110
|
+
super().__init__(
|
|
111
|
+
name=f"meshagent.schema.{name}",
|
|
112
|
+
validate_webhook_secret=False,
|
|
113
|
+
schemas=[SchemaRegistration(name=name, schema=schema)],
|
|
114
|
+
)
|
|
115
|
+
|
|
116
|
+
@service.path("/schemas/transcript")
|
|
117
|
+
class TranscriptRegistry(SchemaRegistry):
|
|
118
|
+
def __init__(self):
|
|
119
|
+
name = "transcript"
|
|
120
|
+
schema = transcript_schema
|
|
121
|
+
super().__init__(
|
|
122
|
+
name=f"meshagent.schema.{name}",
|
|
123
|
+
validate_webhook_secret=False,
|
|
124
|
+
schemas=[SchemaRegistration(name=name, schema=schema)],
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
@service.path("/toolkits/storage")
|
|
128
|
+
class HostedStorageToolkit(StorageToolkit):
|
|
129
|
+
pass
|
|
130
|
+
|
|
131
|
+
await service.run()
|