cmdbox 0.6.0.3__py3-none-any.whl → 0.6.0.4__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 cmdbox might be problematic. Click here for more details.
- cmdbox/app/common.py +4 -2
- cmdbox/app/features/cli/agent_base.py +7 -65
- cmdbox/app/features/cli/cmdbox_cmd_list.py +1 -1
- cmdbox/app/features/cli/cmdbox_cmd_load.py +1 -1
- cmdbox/app/features/cli/cmdbox_web_apikey_add.py +1 -1
- cmdbox/app/features/cli/cmdbox_web_apikey_del.py +1 -1
- cmdbox/app/features/cli/cmdbox_web_group_add.py +1 -1
- cmdbox/app/features/cli/cmdbox_web_group_del.py +1 -1
- cmdbox/app/features/cli/cmdbox_web_group_edit.py +1 -1
- cmdbox/app/features/cli/cmdbox_web_group_list.py +1 -1
- cmdbox/app/features/cli/cmdbox_web_start.py +65 -26
- cmdbox/app/features/cli/cmdbox_web_user_add.py +1 -1
- cmdbox/app/features/cli/cmdbox_web_user_del.py +1 -1
- cmdbox/app/features/cli/cmdbox_web_user_edit.py +1 -1
- cmdbox/app/features/cli/cmdbox_web_user_list.py +1 -1
- cmdbox/app/features/web/cmdbox_web_agent.py +10 -4
- cmdbox/app/options.py +8 -0
- cmdbox/app/web.py +26 -47
- cmdbox/version.py +2 -2
- cmdbox/web/assets/cmdbox/agent.js +2 -3
- cmdbox/web/assets/cmdbox/common.js +26 -4
- cmdbox/web/assets/cmdbox/main.js +1 -2
- {cmdbox-0.6.0.3.dist-info → cmdbox-0.6.0.4.dist-info}/METADATA +2 -2
- {cmdbox-0.6.0.3.dist-info → cmdbox-0.6.0.4.dist-info}/RECORD +28 -28
- {cmdbox-0.6.0.3.dist-info → cmdbox-0.6.0.4.dist-info}/LICENSE +0 -0
- {cmdbox-0.6.0.3.dist-info → cmdbox-0.6.0.4.dist-info}/WHEEL +0 -0
- {cmdbox-0.6.0.3.dist-info → cmdbox-0.6.0.4.dist-info}/entry_points.txt +0 -0
- {cmdbox-0.6.0.3.dist-info → cmdbox-0.6.0.4.dist-info}/top_level.txt +0 -0
cmdbox/app/common.py
CHANGED
|
@@ -135,8 +135,10 @@ def create_console(stderr:bool=False, file=None) -> Console:
|
|
|
135
135
|
Returns:
|
|
136
136
|
Console: コンソール
|
|
137
137
|
"""
|
|
138
|
-
console = Console(height=
|
|
139
|
-
|
|
138
|
+
#console = Console(soft_wrap=True, height=True, highlighter=loghandler.LogLevelHighlighter(), theme=loghandler.theme,
|
|
139
|
+
# stderr=stderr, file=file)
|
|
140
|
+
console = Console(height=True, highlighter=loghandler.LogLevelHighlighter(), theme=loghandler.theme,
|
|
141
|
+
soft_wrap=True, stderr=stderr, file=file, log_time=True, log_path=False, log_time_format='[%Y-%m-%d %H:%M:%S]')
|
|
140
142
|
#console = Console(soft_wrap=True, stderr=stderr, file=file, log_time=True, log_path=False, log_time_format='[%Y-%m-%d %H:%M:%S]')
|
|
141
143
|
return console
|
|
142
144
|
|
|
@@ -30,8 +30,7 @@ class AgentBase(feature.ResultEdgeFeature):
|
|
|
30
30
|
dict(opt="agent", type=Options.T_STR, default="no", required=False, multi=False, hide=False, choice=["no", "use"],
|
|
31
31
|
discription_ja="エージェントを使用するかどうかを指定します。",
|
|
32
32
|
discription_en="Specifies whether the agent is used.",
|
|
33
|
-
choice_show=dict(use=["agent_name", "agent_description", "agent_instruction", "agent_session_store", "llmprov",
|
|
34
|
-
"mcp_listen_port", "mcp_ssl_listen_port"],)),
|
|
33
|
+
choice_show=dict(use=["agent_name", "agent_description", "agent_instruction", "agent_session_store", "llmprov",],)),
|
|
35
34
|
dict(opt="agent_name", type=Options.T_STR, default=self.ver.__appid__, required=False, multi=False, hide=False, choice=None,
|
|
36
35
|
discription_ja="エージェント名を指定します。",
|
|
37
36
|
discription_en="Specifies the agent name."),
|
|
@@ -45,12 +44,6 @@ class AgentBase(feature.ResultEdgeFeature):
|
|
|
45
44
|
discription_ja="エージェントのセッションを保存する方法を指定します。",
|
|
46
45
|
discription_en="Specify how the agent's session is to be saved.",
|
|
47
46
|
choice_show=dict(postgresql=["agent_pg_host", "agent_pg_port", "agent_pg_user", "agent_pg_password", "agent_pg_dbname"]),),
|
|
48
|
-
dict(opt="mcp_listen_port", type=Options.T_INT, default="9081", required=False, multi=False, hide=False, choice=None,
|
|
49
|
-
discription_ja="省略した時は `9081` を使用します。",
|
|
50
|
-
discription_en="If omitted, `9081` is used."),
|
|
51
|
-
dict(opt="mcp_ssl_listen_port", type=Options.T_INT, default="9443", required=False, multi=False, hide=False, choice=None,
|
|
52
|
-
discription_ja="省略した時は `9443` を使用します。",
|
|
53
|
-
discription_en="If omitted, `9443` is used."),
|
|
54
47
|
dict(opt="agent_pg_host", type=Options.T_STR, default='localhost', required=False, multi=False, hide=False, choice=None, web="mask",
|
|
55
48
|
discription_ja="postgresqlホストを指定する。",
|
|
56
49
|
discription_en="Specify the postgresql host."),
|
|
@@ -114,7 +107,7 @@ class AgentBase(feature.ResultEdgeFeature):
|
|
|
114
107
|
Returns:
|
|
115
108
|
Any: FastMCP
|
|
116
109
|
"""
|
|
117
|
-
from
|
|
110
|
+
from fastmcp import FastMCP
|
|
118
111
|
mcp = FastMCP(name=self.ver.__appid__)
|
|
119
112
|
return mcp
|
|
120
113
|
|
|
@@ -174,33 +167,6 @@ class AgentBase(feature.ResultEdgeFeature):
|
|
|
174
167
|
f"1. ユーザーのクエリからが実行したいコマンドを特定します。\n" + \
|
|
175
168
|
f"2. コマンド実行に必要なパラメータのなかで、ユーザーのクエリから取得できないものは、コマンド定義にあるデフォルト値を指定して実行してください。\n" + \
|
|
176
169
|
f"3. もしエラーが発生した場合は、ユーザーにコマンド名とパラメータとエラー内容を提示してください。\n"
|
|
177
|
-
"""
|
|
178
|
-
f"2. コマンド実行に必要なパラメータを特定します。\n" + \
|
|
179
|
-
f"3. ユーザーのクエリから指定しているパラメータを取得します。\n" + \
|
|
180
|
-
f"4. ユーザーが指定しているパラメータと、コマンド実行に必要なパラメータを比較し、不足しているパラメータを取得します。\n" + \
|
|
181
|
-
f"5. 以下に「パラメータ = デフォルト値」を示しているので、不足しているパラメータはデフォルト値を使用します。\n" + \
|
|
182
|
-
f" 但しコマンドが実行に必要のないパラメータは指定しないようにしてください。\n" + \
|
|
183
|
-
f" host = {args.host if hasattr(args, 'host') and args.host else self.default_host}\n" + \
|
|
184
|
-
f" port = {args.port if hasattr(args, 'port') and args.port else self.default_port}\n" + \
|
|
185
|
-
f" password = {args.password if hasattr(args, 'password') and args.password else self.default_pass}\n" + \
|
|
186
|
-
f" svname = {args.svname if hasattr(args, 'svname') and args.svname else self.default_svname}\n" + \
|
|
187
|
-
f" data = {args.data if hasattr(args, 'data') and args.data else self.default_data}\n" + \
|
|
188
|
-
f" retry_count = {args.retry_count if hasattr(args, 'retry_count') and args.retry_count else 3}\n" + \
|
|
189
|
-
f" retry_interval = {args.retry_interval if hasattr(args, 'retry_interval') and args.retry_interval else 3}\n" + \
|
|
190
|
-
f" timeout = {args.timeout if hasattr(args, 'timeout') and args.timeout else 15}\n" + \
|
|
191
|
-
f" output_json = {args.output_json if hasattr(args, 'output_json') and args.output_json else None}\n" + \
|
|
192
|
-
f" output_json_append = {args.output_json_append if hasattr(args, 'output_json_append') and args.output_json_append else False}\n" + \
|
|
193
|
-
f" stdout_log = {args.stdout_log if hasattr(args, 'stdout_log') and args.stdout_log else False}\n" + \
|
|
194
|
-
f" capture_stdout = {args.capture_stdout if hasattr(args, 'capture_stdout') and args.capture_stdout else False}\n" + \
|
|
195
|
-
f" capture_maxsize = {args.capture_maxsize if hasattr(args, 'capture_maxsize') and args.capture_maxsize else 100}\n" + \
|
|
196
|
-
f" tag = {args.tag if hasattr(args, 'tag') and args.tag else None}\n" + \
|
|
197
|
-
f" clmsg_id = {args.clmsg_id if hasattr(args, 'clmsg_id') and args.clmsg_id else None}\n" + \
|
|
198
|
-
f" signin_file = {args.signin_file if hasattr(args, 'signin_file') and args.signin_file else f'.{self.ver.__appid__}/user_list.yml'}\n" + \
|
|
199
|
-
f"6. 以上のパラメータを使用しても不足するパラメータは、Noneを使用します。\n" + \
|
|
200
|
-
f"7. 以上のパラメータを使用してコマンドを実行して、コマンドの結果はJSONでユーザーに提示してください。\n" + \
|
|
201
|
-
f"8. もし予期しないパラメータを受け取ったという旨のエラーが発生した場合は、そのパラメータを指定せずに再実行してください。\n" + \
|
|
202
|
-
f"9. もしエラーが発生した場合は、ユーザーにコマンド名とパラメータとエラー内容を提示してください。\n"
|
|
203
|
-
"""
|
|
204
170
|
|
|
205
171
|
description = description if is_japan else \
|
|
206
172
|
f"Command offer registered in {self.ver.__appid__}."
|
|
@@ -210,32 +176,6 @@ class AgentBase(feature.ResultEdgeFeature):
|
|
|
210
176
|
f"1. Identify the command you want to execute from the user's query.\n" + \
|
|
211
177
|
f"2. Any parameters required to execute the command that cannot be obtained from the user's query should be executed with the default values provided in the command definition.\n" + \
|
|
212
178
|
f"3. If an error occurs, provide the user with the command name, parameters, and error description.\n"
|
|
213
|
-
"""
|
|
214
|
-
f"2. Identify the parameters required to execute the command.\n" + \
|
|
215
|
-
f"3. Retrieve the specified parameters from the user's query.\n" + \
|
|
216
|
-
f"4. It compares the parameters specified by the user with those required to execute the command and obtains the missing parameters.\n" + \
|
|
217
|
-
f"5. The “Parameter = Default Value” is shown below, so use default values for missing parameters.\n" + \
|
|
218
|
-
f" However, do not specify parameters that the command does not require for execution.\n" + \
|
|
219
|
-
f" host = {args.host if hasattr(args, 'host') and args.host else self.default_host}\n" + \
|
|
220
|
-
f" port = {args.port if hasattr(args, 'port') and args.port else self.default_port}\n" + \
|
|
221
|
-
f" password = {args.password if hasattr(args, 'password') and args.password else self.default_pass}\n" + \
|
|
222
|
-
f" svname = {args.svname if hasattr(args, 'svname') and args.svname else self.default_svname}\n" + \
|
|
223
|
-
f" data = {args.data if hasattr(args, 'data') and args.data else self.default_data}\n" + \
|
|
224
|
-
f" retry_count = {args.retry_count if hasattr(args, 'retry_count') and args.retry_count else 3}\n" + \
|
|
225
|
-
f" retry_interval = {args.retry_interval if hasattr(args, 'retry_interval') and args.retry_interval else 3}\n" + \
|
|
226
|
-
f" timeout = {args.timeout if hasattr(args, 'timeout') and args.timeout else 15}\n" + \
|
|
227
|
-
f" output_json = {args.output_json if hasattr(args, 'output_json') and args.output_json else None}\n" + \
|
|
228
|
-
f" output_json_append = {args.output_json_append if hasattr(args, 'output_json_append') and args.output_json_append else False}\n" + \
|
|
229
|
-
f" stdout_log = {args.stdout_log if hasattr(args, 'stdout_log') and args.stdout_log else False}\n" + \
|
|
230
|
-
f" capture_stdout = {args.capture_stdout if hasattr(args, 'capture_stdout') and args.capture_stdout else False}\n" + \
|
|
231
|
-
f" capture_maxsize = {args.capture_maxsize if hasattr(args, 'capture_maxsize') and args.capture_maxsize else 100}\n" + \
|
|
232
|
-
f" tag = {args.tag if hasattr(args, 'tag') and args.tag else None}\n" + \
|
|
233
|
-
f" clmsg_id = {args.clmsg_id if hasattr(args, 'clmsg_id') and args.clmsg_id else None}\n" + \
|
|
234
|
-
f"6. Use None for parameters that are missing even with the above parameters.\n" + \
|
|
235
|
-
f"7. Execute the command using the above parameters and present the results of the command to the user in JSON.\n" + \
|
|
236
|
-
f"8. If you receive an error stating that an unexpected parameter was received, rerun the program without that parameter.\n" + \
|
|
237
|
-
f"9. If an error occurs, provide the user with the command name, parameters, and error description.\n"
|
|
238
|
-
"""
|
|
239
179
|
|
|
240
180
|
description = args.agent_description if args.agent_description else description
|
|
241
181
|
instruction = args.agent_instruction if args.agent_instruction else instruction
|
|
@@ -360,7 +300,7 @@ class AgentBase(feature.ResultEdgeFeature):
|
|
|
360
300
|
common.reset_logger("google_adk.google.adk.sessions.database_session_service")
|
|
361
301
|
common.reset_logger("mcp.server.streamable_http_manager")
|
|
362
302
|
# モジュールインポート
|
|
363
|
-
from
|
|
303
|
+
from fastmcp import FastMCP
|
|
364
304
|
from google.adk.sessions import BaseSessionService
|
|
365
305
|
mcp:FastMCP = self.create_mcpserver(args)
|
|
366
306
|
session_service:BaseSessionService = self.create_session_service(args)
|
|
@@ -410,8 +350,7 @@ class AgentBase(feature.ResultEdgeFeature):
|
|
|
410
350
|
discription_ja="サインイン可能なユーザーとパスワードを記載したファイルを指定します。省略した時は認証を要求しません。",
|
|
411
351
|
discription_en="Specify a file containing users and passwords with which they can signin. If omitted, no authentication is required."),)
|
|
412
352
|
fn = f"{mode}_{cmd}"
|
|
413
|
-
func_txt
|
|
414
|
-
func_txt += f'def {fn}(' + ", ".join([f'{o["opt"]}:{_t2s(o, False)}' for o in choices]) + '):\n'
|
|
353
|
+
func_txt = f'def {fn}(' + ", ".join([f'{o["opt"]}:{_t2s(o, False)}' for o in choices]) + '):\n'
|
|
415
354
|
func_txt += f' """\n'
|
|
416
355
|
func_txt += f' {discription}\n'
|
|
417
356
|
func_txt += f' Args:\n'
|
|
@@ -472,6 +411,9 @@ class AgentBase(feature.ResultEdgeFeature):
|
|
|
472
411
|
exec(func_txt,
|
|
473
412
|
dict(time=time,List=List, argparse=argparse, common=common, Options=Options, logging=logging, signin=signin,),
|
|
474
413
|
dict(tools=tools, mcp=mcp))
|
|
414
|
+
exec(f"@mcp.tool\n{func_txt}",
|
|
415
|
+
dict(time=time,List=List, argparse=argparse, common=common, Options=Options, logging=logging, signin=signin,),
|
|
416
|
+
dict(tools=[], mcp=mcp))
|
|
475
417
|
root_agent = self.create_agent(logger, args, tools)
|
|
476
418
|
runner = self.create_runner(logger, args, session_service, root_agent)
|
|
477
419
|
if logger.level == logging.DEBUG:
|
|
@@ -45,7 +45,7 @@ class CmdList(feature.OneshotResultEdgeFeature):
|
|
|
45
45
|
dict(opt="kwd", type=Options.T_STR, default=None, required=False, multi=False, hide=False, choice=None,
|
|
46
46
|
discription_ja=f"検索したいコマンド名を指定します。中間マッチで検索します。",
|
|
47
47
|
discription_en=f"Specify the name of the command you want to search. Search with intermediate matches."),
|
|
48
|
-
dict(opt="signin_file", type=Options.T_FILE, default=
|
|
48
|
+
dict(opt="signin_file", type=Options.T_FILE, default=f".{self.ver.__appid__}/user_list.yml", required=False, multi=False, hide=True, choice=None,
|
|
49
49
|
discription_ja="サインイン可能なユーザーとパスワードを記載したファイルを指定します。",
|
|
50
50
|
discription_en="Specify a file containing users and passwords with which they can signin."),
|
|
51
51
|
dict(opt="groups", type=Options.T_STR, default=None, required=False, multi=True, hide=True, choice=None,
|
|
@@ -45,7 +45,7 @@ class CmdLoad(feature.OneshotResultEdgeFeature):
|
|
|
45
45
|
dict(opt="title", type=Options.T_STR, default=None, required=False, multi=False, hide=False, choice=None,
|
|
46
46
|
discription_ja=f"読込みたいコマンド名を指定します。",
|
|
47
47
|
discription_en=f"Specify the name of the command to be read."),
|
|
48
|
-
dict(opt="signin_file", type=Options.T_FILE, default=
|
|
48
|
+
dict(opt="signin_file", type=Options.T_FILE, default=f".{self.ver.__appid__}/user_list.yml", required=False, multi=False, hide=True, choice=None,
|
|
49
49
|
discription_ja="サインイン可能なユーザーとパスワードを記載したファイルを指定します。",
|
|
50
50
|
discription_en="Specify a file containing users and passwords with which they can signin."),
|
|
51
51
|
dict(opt="groups", type=Options.T_STR, default=None, required=False, multi=True, hide=True, choice=None,
|
|
@@ -58,7 +58,7 @@ class WebApikeyAdd(feature.UnsupportEdgeFeature):
|
|
|
58
58
|
dict(opt="apikey_name", type=Options.T_STR, default=None, required=True, multi=False, hide=False, choice=None,
|
|
59
59
|
discription_ja="このユーザーのApiKey名を指定します。",
|
|
60
60
|
discription_en="Specify the ApiKey name for this user."),
|
|
61
|
-
dict(opt="signin_file", type=Options.T_FILE, default=
|
|
61
|
+
dict(opt="signin_file", type=Options.T_FILE, default=f".{self.ver.__appid__}/user_list.yml", required=True, multi=False, hide=False, choice=None,
|
|
62
62
|
discription_ja="サインイン可能なユーザーとパスワードを記載したファイルを指定します。省略した時は認証を要求しません。",
|
|
63
63
|
discription_en="Specify a file containing users and passwords with which they can signin. If omitted, no authentication is required."),
|
|
64
64
|
dict(opt="stdout_log", type=Options.T_BOOL, default=True, required=False, multi=False, hide=True, choice=[True, False],
|
|
@@ -58,7 +58,7 @@ class WebApikeyDel(feature.UnsupportEdgeFeature):
|
|
|
58
58
|
dict(opt="apikey_name", type=Options.T_STR, default=None, required=True, multi=False, hide=False, choice=None,
|
|
59
59
|
discription_ja="このユーザーのApiKey名を指定します。",
|
|
60
60
|
discription_en="Specify the ApiKey name for this user."),
|
|
61
|
-
dict(opt="signin_file", type=Options.T_FILE, default=
|
|
61
|
+
dict(opt="signin_file", type=Options.T_FILE, default=f".{self.ver.__appid__}/user_list.yml", required=True, multi=False, hide=False, choice=None,
|
|
62
62
|
discription_ja="サインイン可能なユーザーとパスワードを記載したファイルを指定します。省略した時は認証を要求しません。",
|
|
63
63
|
discription_en="Specify a file containing users and passwords with which they can signin. If omitted, no authentication is required."),
|
|
64
64
|
dict(opt="stdout_log", type=Options.T_BOOL, default=True, required=False, multi=False, hide=True, choice=[True, False],
|
|
@@ -61,7 +61,7 @@ class WebGroupAdd(feature.UnsupportEdgeFeature):
|
|
|
61
61
|
dict(opt="group_parent", type=Options.T_STR, default=None, required=False, multi=False, hide=False, choice=None,
|
|
62
62
|
discription_ja="親グループ名を指定します。",
|
|
63
63
|
discription_en="Specifies the parent group name."),
|
|
64
|
-
dict(opt="signin_file", type=Options.T_FILE, default=
|
|
64
|
+
dict(opt="signin_file", type=Options.T_FILE, default=f".{self.ver.__appid__}/user_list.yml", required=True, multi=False, hide=False, choice=None,
|
|
65
65
|
discription_ja="サインイン可能なユーザーとパスワードを記載したファイルを指定します。省略した時は認証を要求しません。",
|
|
66
66
|
discription_en="Specify a file containing users and passwords with which they can signin. If omitted, no authentication is required."),
|
|
67
67
|
dict(opt="stdout_log", type=Options.T_BOOL, default=True, required=False, multi=False, hide=True, choice=[True, False],
|
|
@@ -55,7 +55,7 @@ class WebGroupDel(feature.UnsupportEdgeFeature):
|
|
|
55
55
|
dict(opt="group_id", type=Options.T_INT, default=None, required=True, multi=False, hide=False, choice=None,
|
|
56
56
|
discription_ja="グループIDを指定します。",
|
|
57
57
|
discription_en="Specify the group ID. Do not duplicate other groups."),
|
|
58
|
-
dict(opt="signin_file", type=Options.T_FILE, default=
|
|
58
|
+
dict(opt="signin_file", type=Options.T_FILE, default=f".{self.ver.__appid__}/user_list.yml", required=True, multi=False, hide=False, choice=None,
|
|
59
59
|
discription_ja="サインイン可能なユーザーとパスワードを記載したファイルを指定します。省略した時は認証を要求しません。",
|
|
60
60
|
discription_en="Specify a file containing users and passwords with which they can signin. If omitted, no authentication is required."),
|
|
61
61
|
dict(opt="stdout_log", type=Options.T_BOOL, default=True, required=False, multi=False, hide=True, choice=[True, False],
|
|
@@ -61,7 +61,7 @@ class WebGroupEdit(feature.UnsupportEdgeFeature):
|
|
|
61
61
|
dict(opt="group_parent", type=Options.T_STR, default=None, required=False, multi=False, hide=False, choice=None,
|
|
62
62
|
discription_ja="親グループ名を指定します。",
|
|
63
63
|
discription_en="Specifies the parent group name."),
|
|
64
|
-
dict(opt="signin_file", type=Options.T_FILE, default=
|
|
64
|
+
dict(opt="signin_file", type=Options.T_FILE, default=f".{self.ver.__appid__}/user_list.yml", required=True, multi=False, hide=False, choice=None,
|
|
65
65
|
discription_ja="サインイン可能なユーザーとパスワードを記載したファイルを指定します。省略した時は認証を要求しません。",
|
|
66
66
|
discription_en="Specify a file containing users and passwords with which they can signin. If omitted, no authentication is required."),
|
|
67
67
|
dict(opt="stdout_log", type=Options.T_BOOL, default=True, required=False, multi=False, hide=True, choice=[True, False],
|
|
@@ -55,7 +55,7 @@ class WebGroupList(feature.OneshotResultEdgeFeature):
|
|
|
55
55
|
dict(opt="group_name", type=Options.T_STR, default=None, required=False, multi=False, hide=False, choice=None,
|
|
56
56
|
discription_ja="グループ名を指定して取得します。省略した時は全てのグループを取得します。",
|
|
57
57
|
discription_en="Retrieved by specifying a group name. If omitted, all groups are retrieved."),
|
|
58
|
-
dict(opt="signin_file", type=Options.T_FILE, default=
|
|
58
|
+
dict(opt="signin_file", type=Options.T_FILE, default=f".{self.ver.__appid__}/user_list.yml", required=True, multi=False, hide=False, choice=None,
|
|
59
59
|
discription_ja="サインイン可能なユーザーとパスワードを記載したファイルを指定します。省略した時は認証を要求しません。",
|
|
60
60
|
discription_en="Specify a file containing users and passwords with which they can signin. If omitted, no authentication is required."),
|
|
61
61
|
dict(opt="stdout_log", type=Options.T_BOOL, default=True, required=False, multi=False, hide=True, choice=[True, False],
|
|
@@ -157,32 +157,12 @@ class WebStart(feature.UnsupportEdgeFeature, agent_base.AgentBase):
|
|
|
157
157
|
w = None
|
|
158
158
|
try:
|
|
159
159
|
args.gui_mode = False if not hasattr(args, 'gui_mode') or not args.gui_mode else args.gui_mode
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
result_html=args.result_html, users_html=args.users_html,
|
|
167
|
-
assets=args.assets, signin_html=args.signin_html, signin_file=args.signin_file, gui_mode=args.gui_mode)
|
|
168
|
-
agent_runner = None
|
|
169
|
-
mcp = None
|
|
170
|
-
logger.info(f"Agent={args.agent}")
|
|
171
|
-
if args.agent=='use':
|
|
172
|
-
if args.agent_session_store == 'sqlite':
|
|
173
|
-
args.agent_session_dburl = "sqlite://" + pathname2url(str(w.agent_path / 'session.db'))
|
|
174
|
-
elif args.agent_session_store == 'postgresql':
|
|
175
|
-
args.agent_session_dburl = f"postgresql+psycopg://{args.agent_pg_user}:{args.agent_pg_password}@{args.agent_pg_host}:{args.agent_pg_port}/{args.agent_pg_dbname}"
|
|
176
|
-
else:
|
|
177
|
-
args.agent_session_dburl = None
|
|
178
|
-
agent_runner, mcp = self.init_agent_runner(logger, args)
|
|
179
|
-
w.start(allow_host=args.allow_host, listen_port=args.listen_port, ssl_listen_port=args.ssl_listen_port,
|
|
180
|
-
ssl_cert=ssl_cert, ssl_key=ssl_key, ssl_keypass=args.ssl_keypass, ssl_ca_certs=ssl_ca_certs,
|
|
181
|
-
session_domain=args.session_domain, session_path=args.session_path,
|
|
182
|
-
session_secure=args.session_secure, session_timeout=args.session_timeout,
|
|
183
|
-
outputs_key=args.outputs_key, guvicorn_workers=args.guvicorn_workers, guvicorn_timeout=args.guvicorn_timeout,
|
|
184
|
-
agent_runner=agent_runner, mcp=mcp, mcp_listen_port=args.mcp_listen_port, mcp_ssl_listen_port=args.mcp_ssl_listen_port)
|
|
185
|
-
|
|
160
|
+
w = self.createWeb(logger, args)
|
|
161
|
+
agent_runner, mcp = self._init_agent_runner(w, logger, args)
|
|
162
|
+
args.ssl_cert = None if args.ssl_cert is None else Path(args.ssl_cert)
|
|
163
|
+
args.ssl_key = None if args.ssl_key is None else Path(args.ssl_key)
|
|
164
|
+
args.ssl_ca_certs = None if args.ssl_ca_certs is None else Path(args.ssl_ca_certs)
|
|
165
|
+
self.start(w, agent_runner, mcp, logger, args)
|
|
186
166
|
msg = dict(success="web complate.")
|
|
187
167
|
common.print_format(msg, args.format, tm, args.output_json, args.output_json_append, pf=pf)
|
|
188
168
|
return 0, msg, w
|
|
@@ -191,3 +171,62 @@ class WebStart(feature.UnsupportEdgeFeature, agent_base.AgentBase):
|
|
|
191
171
|
msg = dict(warn=f"Web server start error. {e}")
|
|
192
172
|
common.print_format(msg, args.format, tm, args.output_json, args.output_json_append, pf=pf)
|
|
193
173
|
return 1, msg, w
|
|
174
|
+
|
|
175
|
+
def createWeb(self, logger:logging.Logger, args:argparse.Namespace) -> web.Web:
|
|
176
|
+
"""
|
|
177
|
+
Webオブジェクトを作成します
|
|
178
|
+
|
|
179
|
+
Args:
|
|
180
|
+
logger (logging.Logger): ロガー
|
|
181
|
+
args (argparse.Namespace): 引数
|
|
182
|
+
|
|
183
|
+
Returns:
|
|
184
|
+
web.Web: Webオブジェクト
|
|
185
|
+
"""
|
|
186
|
+
w = web.Web(logger, Path(args.data), appcls=self.appcls, ver=self.ver,
|
|
187
|
+
redis_host=args.host, redis_port=args.port, redis_password=args.password, svname=args.svname,
|
|
188
|
+
client_only=args.client_only, doc_root=args.doc_root, gui_html=args.gui_html, filer_html=args.filer_html,
|
|
189
|
+
result_html=args.result_html, users_html=args.users_html,
|
|
190
|
+
assets=args.assets, signin_html=args.signin_html, signin_file=args.signin_file, gui_mode=args.gui_mode)
|
|
191
|
+
return w
|
|
192
|
+
|
|
193
|
+
def _init_agent_runner(self, w:web.Web, logger:logging.Logger, args:argparse.Namespace) -> Tuple[Any, Any]:
|
|
194
|
+
"""
|
|
195
|
+
エージェントをセットアップします
|
|
196
|
+
|
|
197
|
+
Args:
|
|
198
|
+
w (web.Web): Webオブジェクト
|
|
199
|
+
logger (logging.Logger): ロガー
|
|
200
|
+
args (argparse.Namespace): 引数
|
|
201
|
+
|
|
202
|
+
Returns:
|
|
203
|
+
Tuple[agent_base.AgentBase, Any]: エージェントオブジェクト, MCPオブジェクト
|
|
204
|
+
"""
|
|
205
|
+
logger.info(f"Agent={args.agent}")
|
|
206
|
+
if args.agent=='use':
|
|
207
|
+
if args.agent_session_store == 'sqlite':
|
|
208
|
+
args.agent_session_dburl = "sqlite://" + pathname2url(str(w.agent_path / 'session.db'))
|
|
209
|
+
elif args.agent_session_store == 'postgresql':
|
|
210
|
+
args.agent_session_dburl = f"postgresql+psycopg://{args.agent_pg_user}:{args.agent_pg_password}@{args.agent_pg_host}:{args.agent_pg_port}/{args.agent_pg_dbname}"
|
|
211
|
+
else:
|
|
212
|
+
args.agent_session_dburl = None
|
|
213
|
+
return self.init_agent_runner(logger, args)
|
|
214
|
+
return None, None
|
|
215
|
+
|
|
216
|
+
def start(self, w:web.Web, agent_runner, mcp, logger:logging.Logger, args:argparse.Namespace) -> None:
|
|
217
|
+
"""
|
|
218
|
+
Webモードを起動します
|
|
219
|
+
|
|
220
|
+
Args:
|
|
221
|
+
w (web.Web): Webオブジェクト
|
|
222
|
+
agent_runner: エージェントランナー
|
|
223
|
+
mcp: MCPオブジェクト
|
|
224
|
+
logger (logging.Logger): ロガー
|
|
225
|
+
args (argparse.Namespace): 引数
|
|
226
|
+
"""
|
|
227
|
+
w.start(allow_host=args.allow_host, listen_port=args.listen_port, ssl_listen_port=args.ssl_listen_port,
|
|
228
|
+
ssl_cert=args.ssl_cert, ssl_key=args.ssl_key, ssl_keypass=args.ssl_keypass, ssl_ca_certs=args.ssl_ca_certs,
|
|
229
|
+
session_domain=args.session_domain, session_path=args.session_path,
|
|
230
|
+
session_secure=args.session_secure, session_timeout=args.session_timeout,
|
|
231
|
+
outputs_key=args.outputs_key, guvicorn_workers=args.guvicorn_workers, guvicorn_timeout=args.guvicorn_timeout,
|
|
232
|
+
agent_runner=agent_runner, mcp=mcp,)
|
|
@@ -70,7 +70,7 @@ class WebUserAdd(feature.UnsupportEdgeFeature):
|
|
|
70
70
|
dict(opt="user_group", type=Options.T_STR, default=None, required=True, multi=True, hide=False, choice=None,
|
|
71
71
|
discription_ja="ユーザーが所属するグループを指定します。",
|
|
72
72
|
discription_en="Specifies the groups to which the user belongs."),
|
|
73
|
-
dict(opt="signin_file", type=Options.T_FILE, default=
|
|
73
|
+
dict(opt="signin_file", type=Options.T_FILE, default=f".{self.ver.__appid__}/user_list.yml", required=True, multi=False, hide=False, choice=None,
|
|
74
74
|
discription_ja="サインイン可能なユーザーとパスワードを記載したファイルを指定します。省略した時は認証を要求しません。",
|
|
75
75
|
discription_en="Specify a file containing users and passwords with which they can signin. If omitted, no authentication is required."),
|
|
76
76
|
dict(opt="stdout_log", type=Options.T_BOOL, default=True, required=False, multi=False, hide=True, choice=[True, False],
|
|
@@ -55,7 +55,7 @@ class WebUserDel(feature.UnsupportEdgeFeature):
|
|
|
55
55
|
dict(opt="user_id", type=Options.T_INT, default=None, required=True, multi=False, hide=False, choice=None,
|
|
56
56
|
discription_ja="ユーザーIDを指定します。",
|
|
57
57
|
discription_en="Specify the user ID."),
|
|
58
|
-
dict(opt="signin_file", type=Options.T_FILE, default=
|
|
58
|
+
dict(opt="signin_file", type=Options.T_FILE, default=f".{self.ver.__appid__}/user_list.yml", required=True, multi=False, hide=False, choice=None,
|
|
59
59
|
discription_ja="サインイン可能なユーザーとパスワードを記載したファイルを指定します。省略した時は認証を要求しません。",
|
|
60
60
|
discription_en="Specify a file containing users and passwords with which they can signin. If omitted, no authentication is required."),
|
|
61
61
|
dict(opt="stdout_log", type=Options.T_BOOL, default=True, required=False, multi=False, hide=True, choice=[True, False],
|
|
@@ -70,7 +70,7 @@ class WebUserEdit(feature.UnsupportEdgeFeature):
|
|
|
70
70
|
dict(opt="user_group", type=Options.T_STR, default=None, required=True, multi=True, hide=False, choice=None,
|
|
71
71
|
discription_ja="ユーザーが所属するグループを指定します。",
|
|
72
72
|
discription_en="Specifies the groups to which the user belongs."),
|
|
73
|
-
dict(opt="signin_file", type=Options.T_FILE, default=
|
|
73
|
+
dict(opt="signin_file", type=Options.T_FILE, default=f".{self.ver.__appid__}/user_list.yml", required=True, multi=False, hide=False, choice=None,
|
|
74
74
|
discription_ja="サインイン可能なユーザーとパスワードを記載したファイルを指定します。省略した時は認証を要求しません。",
|
|
75
75
|
discription_en="Specify a file containing users and passwords with which they can signin. If omitted, no authentication is required."),
|
|
76
76
|
dict(opt="stdout_log", type=Options.T_BOOL, default=True, required=False, multi=False, hide=True, choice=[True, False],
|
|
@@ -55,7 +55,7 @@ class WebUserList(feature.OneshotResultEdgeFeature):
|
|
|
55
55
|
dict(opt="user_name", type=Options.T_STR, default=None, required=False, multi=False, hide=False, choice=None,
|
|
56
56
|
discription_ja="ユーザー名を指定して取得します。省略した時は全てのユーザーを取得します。",
|
|
57
57
|
discription_en="Retrieved by specifying a user name. If omitted, all users are retrieved."),
|
|
58
|
-
dict(opt="signin_file", type=Options.T_FILE, default=
|
|
58
|
+
dict(opt="signin_file", type=Options.T_FILE, default=f".{self.ver.__appid__}/user_list.yml", required=True, multi=False, hide=False, choice=None,
|
|
59
59
|
discription_ja="サインイン可能なユーザーとパスワードを記載したファイルを指定します。省略した時は認証を要求しません。",
|
|
60
60
|
discription_en="Specify a file containing users and passwords with which they can signin. If omitted, no authentication is required."),
|
|
61
61
|
dict(opt="stdout_log", type=Options.T_BOOL, default=True, required=False, multi=False, hide=True, choice=[True, False],
|
|
@@ -60,7 +60,7 @@ class Agent(feature.WebFeature):
|
|
|
60
60
|
session_id = form.get('session_id', None)
|
|
61
61
|
sessions = await web.list_agent_sessions(web.agent_runner.session_service, user_id, session_id=session_id)
|
|
62
62
|
data = [dict(id=s.id, app_name=s.app_name, user_id=s.user_id, last_update_time=s.last_update_time,
|
|
63
|
-
events=[dict(author=ev.author,text=ev.content.parts[0].text) for ev in s.events if ev.content and ev.content.parts]) for s in sessions]
|
|
63
|
+
events=[dict(author=ev.author,text=ev.content.parts[0].text) for ev in s.events if ev.content and ev.content.parts]) for s in sessions if s]
|
|
64
64
|
data.reverse() # 最新のセッションを先頭にする
|
|
65
65
|
return dict(success=data)
|
|
66
66
|
|
|
@@ -204,14 +204,20 @@ class Agent(feature.WebFeature):
|
|
|
204
204
|
outputs = dict()
|
|
205
205
|
if event.turn_complete:
|
|
206
206
|
outputs['turn_complete'] = True
|
|
207
|
-
yield
|
|
207
|
+
yield common.to_str(outputs)
|
|
208
208
|
if event.interrupted:
|
|
209
209
|
outputs['interrupted'] = True
|
|
210
|
-
yield
|
|
210
|
+
yield common.to_str(outputs)
|
|
211
211
|
#if event.is_final_response():
|
|
212
212
|
msg = None
|
|
213
213
|
if event.content and event.content.parts:
|
|
214
214
|
msg = "\n".join([p.text for p in event.content.parts if p and p.text])
|
|
215
|
+
calls = event.get_function_calls()
|
|
216
|
+
if calls:
|
|
217
|
+
msg += '\n```json{"function_calls":'+common.to_str([dict(fn=c.name,args=c.args) for c in calls])+'}```'
|
|
218
|
+
responses = event.get_function_responses()
|
|
219
|
+
if responses:
|
|
220
|
+
msg += '\n```json{"function_responses":'+common.to_str([dict(fn=r.name, res=r.response) for r in responses])+'}```'
|
|
215
221
|
elif event.actions and event.actions.escalate:
|
|
216
222
|
msg = f"Agent escalated: {event.error_message or 'No specific message.'}"
|
|
217
223
|
if msg:
|
|
@@ -219,7 +225,7 @@ class Agent(feature.WebFeature):
|
|
|
219
225
|
|
|
220
226
|
outputs['message'] = msg
|
|
221
227
|
web.options.audit_exec(sock, web, body=dict(agent_session=agent_session.id, result=msg))
|
|
222
|
-
yield
|
|
228
|
+
yield common.to_str(outputs)
|
|
223
229
|
if event.is_final_response():
|
|
224
230
|
break
|
|
225
231
|
except WebSocketDisconnect:
|
cmdbox/app/options.py
CHANGED
|
@@ -295,12 +295,18 @@ class Options:
|
|
|
295
295
|
discription_ja="クライアントのメッセージIDを指定します。省略した場合はuuid4で生成されます。",
|
|
296
296
|
discription_en="Specifies the message ID of the client. If omitted, uuid4 will be generated.",
|
|
297
297
|
choice=None)
|
|
298
|
+
self._options["description"] = dict(
|
|
299
|
+
type=Options.T_TEXT, default=None, required=False, multi=False, hide=True,
|
|
300
|
+
discription_ja="このコマンド登録の説明文を指定します。Agentがこのコマンドの用途を理解するのに使用します。",
|
|
301
|
+
discription_en="Specifies a description of this command registration, used to help the Agent understand the use of this command.",
|
|
302
|
+
choice=None)
|
|
298
303
|
|
|
299
304
|
def init_debugoption(self):
|
|
300
305
|
# デバックオプションを追加
|
|
301
306
|
self._options["debug"]["opt"] = "debug"
|
|
302
307
|
self._options["tag"]["opt"] = "tag"
|
|
303
308
|
self._options["clmsg_id"]["opt"] = "clmsg_id"
|
|
309
|
+
self._options["description"]["opt"] = "description"
|
|
304
310
|
for key, mode in self._options["cmd"].items():
|
|
305
311
|
if type(mode) is not dict:
|
|
306
312
|
continue
|
|
@@ -315,6 +321,8 @@ class Options:
|
|
|
315
321
|
c["choice"].append(self._options["tag"])
|
|
316
322
|
if "clmsg_id" not in [_o['opt'] for _o in c["choice"]]:
|
|
317
323
|
c["choice"].append(self._options["clmsg_id"])
|
|
324
|
+
if "description" not in [_o['opt'] for _o in c["choice"]]:
|
|
325
|
+
c["choice"].append(self._options["description"])
|
|
318
326
|
if c["opt"] not in [_o['opt'] for _o in self._options["cmd"]["choice"]]:
|
|
319
327
|
self._options["cmd"]["choice"] += [c]
|
|
320
328
|
self._options["mode"][key] = mode
|
cmdbox/app/web.py
CHANGED
|
@@ -5,7 +5,6 @@ from fastapi import FastAPI, Request, Response
|
|
|
5
5
|
from pathlib import Path
|
|
6
6
|
from starlette.applications import Starlette
|
|
7
7
|
from starlette.middleware.sessions import SessionMiddleware
|
|
8
|
-
from starlette.routing import Mount
|
|
9
8
|
from typing import Any, Dict, List
|
|
10
9
|
from uvicorn.config import Config
|
|
11
10
|
import asyncio
|
|
@@ -20,7 +19,6 @@ import platform
|
|
|
20
19
|
import requests
|
|
21
20
|
import queue
|
|
22
21
|
import signal
|
|
23
|
-
import string
|
|
24
22
|
import time
|
|
25
23
|
import threading
|
|
26
24
|
import traceback
|
|
@@ -30,10 +28,10 @@ import webbrowser
|
|
|
30
28
|
|
|
31
29
|
class Web:
|
|
32
30
|
def __init__(self, logger:logging.Logger, data:Path, appcls=None, ver=None,
|
|
33
|
-
redis_host:str
|
|
31
|
+
redis_host:str="localhost", redis_port:int=6379, redis_password:str=None, svname:str='server',
|
|
34
32
|
client_only:bool=False, doc_root:Path=None, gui_html:str=None, filer_html:str=None, result_html:str=None, users_html:str=None,
|
|
35
33
|
audit_html:str=None, agent_html:str=None, assets:List[str]=None, signin_html:str=None, signin_file:str=None, gui_mode:bool=False,
|
|
36
|
-
web_features_packages:List[str]=None, web_features_prefix:List[str]=
|
|
34
|
+
web_features_packages:List[str]=None, web_features_prefix:List[str]=[]):
|
|
37
35
|
"""
|
|
38
36
|
cmdboxクライアント側のwebapiサービス
|
|
39
37
|
|
|
@@ -679,7 +677,7 @@ class Web:
|
|
|
679
677
|
ssl_cert:Path=None, ssl_key:Path=None, ssl_keypass:str=None, ssl_ca_certs:Path=None,
|
|
680
678
|
session_domain:str=None, session_path:str='/', session_secure:bool=False, session_timeout:int=900, outputs_key:List[str]=[],
|
|
681
679
|
guvicorn_workers:int=-1, guvicorn_timeout:int=30,
|
|
682
|
-
agent_runner=None, mcp=None,
|
|
680
|
+
agent_runner=None, mcp=None,):
|
|
683
681
|
"""
|
|
684
682
|
Webサーバを起動する
|
|
685
683
|
|
|
@@ -700,8 +698,6 @@ class Web:
|
|
|
700
698
|
guvicorn_timeout (int, optional): Gunicornタイムアウト. Defaults to 30.
|
|
701
699
|
agent_runner (Runner, optional): エージェントランナー. Defaults to None.
|
|
702
700
|
mcp (MCP, optional): MCP. Defaults to None.
|
|
703
|
-
mcp_listen_port (int, optional): MCPリスンポート. Defaults to 9081.
|
|
704
|
-
mcp_ssl_listen_port (int, optional): MCP SSLリスンポート. Defaults to 9443.
|
|
705
701
|
"""
|
|
706
702
|
self.allow_host = allow_host
|
|
707
703
|
self.listen_port = listen_port
|
|
@@ -719,8 +715,6 @@ class Web:
|
|
|
719
715
|
self.guvicorn_timeout = guvicorn_timeout
|
|
720
716
|
self.agent_runner = agent_runner
|
|
721
717
|
self.mcp = mcp
|
|
722
|
-
self.mcp_listen_port = mcp_listen_port
|
|
723
|
-
self.mcp_ssl_listen_port = mcp_ssl_listen_port
|
|
724
718
|
if self.logger.level == logging.DEBUG:
|
|
725
719
|
self.logger.debug(f"web start parameter: allow_host={self.allow_host}")
|
|
726
720
|
self.logger.debug(f"web start parameter: listen_port={self.listen_port}")
|
|
@@ -738,8 +732,6 @@ class Web:
|
|
|
738
732
|
self.logger.debug(f"web start parameter: guvicorn_timeout={self.guvicorn_timeout}")
|
|
739
733
|
self.logger.debug(f"web start parameter: agent_runner={self.agent_runner}")
|
|
740
734
|
self.logger.debug(f"web start parameter: mcp={self.mcp}")
|
|
741
|
-
self.logger.debug(f"web start parameter: mcp_listen_port={self.mcp_listen_port}")
|
|
742
|
-
self.logger.debug(f"web start parameter: mcp_ssl_listen_port={self.mcp_ssl_listen_port}")
|
|
743
735
|
|
|
744
736
|
if self.agent_runner is not None:
|
|
745
737
|
# google.adkが大きいので必要な時にだけ読込む
|
|
@@ -778,7 +770,10 @@ class Web:
|
|
|
778
770
|
sessions = await session_service.list_sessions(app_name=self.ver.__appid__, user_id=user_id)
|
|
779
771
|
ret = []
|
|
780
772
|
for s in sessions.sessions:
|
|
781
|
-
|
|
773
|
+
session = await session_service.get_session(app_name=self.ver.__appid__, user_id=user_id, session_id=s.id)
|
|
774
|
+
if session is None:
|
|
775
|
+
continue
|
|
776
|
+
ret.append(session)
|
|
782
777
|
return ret
|
|
783
778
|
else:
|
|
784
779
|
session = await session_service.get_session(app_name=self.ver.__appid__, user_id=user_id, session_id=session_id)
|
|
@@ -801,17 +796,15 @@ class Web:
|
|
|
801
796
|
return await session_service.delete_session(app_name=self.ver.__appid__, user_id=user_id, session_id=session_id)
|
|
802
797
|
self.delete_agent_session = delete_agent_session
|
|
803
798
|
|
|
804
|
-
|
|
799
|
+
mcp_app:Starlette = None
|
|
805
800
|
if self.mcp is not None:
|
|
806
|
-
# MCPをFastAPIにマウント
|
|
807
801
|
mcp_app:Starlette = self.mcp.streamable_http_app()
|
|
808
|
-
|
|
809
|
-
|
|
810
|
-
|
|
802
|
+
#mcp_app:Starlette = self.mcp.http_app()
|
|
803
|
+
if mcp_app is not None:
|
|
804
|
+
app = FastAPI(lifespan=mcp_app.lifespan)
|
|
811
805
|
else:
|
|
812
806
|
app = FastAPI()
|
|
813
|
-
|
|
814
|
-
app = FastAPI()
|
|
807
|
+
|
|
815
808
|
@app.middleware("http")
|
|
816
809
|
async def set_context_cookie(req:Request, call_next):
|
|
817
810
|
res:Response = await call_next(req)
|
|
@@ -824,20 +817,13 @@ class Web:
|
|
|
824
817
|
if self.session_secure:
|
|
825
818
|
mwparam['https_only'] = True # セッションハイジャック対策
|
|
826
819
|
app.add_middleware(SessionMiddleware, **mwparam)
|
|
820
|
+
if mcp_app is not None:
|
|
821
|
+
app.mount("/mcpsv", mcp_app, name="mcp")
|
|
822
|
+
self.logger.info(f"mcp server mount: mount_path=/mcpsv app={mcp_app} routes={mcp_app.routes}")
|
|
827
823
|
self.init_webfeatures(app)
|
|
828
824
|
|
|
829
825
|
self.is_running = True
|
|
830
|
-
|
|
831
|
-
http_config = Config(app=app, host=self.allow_host, port=self.listen_port)
|
|
832
|
-
th = ThreadedUvicorn(self.logger, config=http_config,
|
|
833
|
-
guvicorn_config=dict(workers=self.guvicorn_workers, timeout=self.guvicorn_timeout))
|
|
834
|
-
th.start()
|
|
835
|
-
if self.mcp is not None and self.ssl_cert is None and self.ssl_key is None:
|
|
836
|
-
mcp_app:Starlette = self.mcp.streamable_http_app()
|
|
837
|
-
http_config = Config(app=mcp_app, host=self.allow_host, port=self.mcp_listen_port)
|
|
838
|
-
mcp_th = ThreadedUvicorn(self.logger, config=http_config, force_uvicorn=True)
|
|
839
|
-
mcp_th.start()
|
|
840
|
-
browser_port = self.listen_port
|
|
826
|
+
th = None
|
|
841
827
|
th_ssl = None
|
|
842
828
|
if self.ssl_cert is not None and self.ssl_key is not None:
|
|
843
829
|
https_config = Config(app=app, host=self.allow_host, port=self.ssl_listen_port,
|
|
@@ -847,13 +833,12 @@ class Web:
|
|
|
847
833
|
guvicorn_config=dict(workers=self.guvicorn_workers, timeout=self.guvicorn_timeout))
|
|
848
834
|
th_ssl.start()
|
|
849
835
|
browser_port = self.ssl_listen_port
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
mcp_th_ssl.start()
|
|
836
|
+
else:
|
|
837
|
+
http_config = Config(app=app, host=self.allow_host, port=self.listen_port)
|
|
838
|
+
th = ThreadedUvicorn(self.logger, config=http_config,
|
|
839
|
+
guvicorn_config=dict(workers=self.guvicorn_workers, timeout=self.guvicorn_timeout))
|
|
840
|
+
th.start()
|
|
841
|
+
browser_port = self.listen_port
|
|
857
842
|
try:
|
|
858
843
|
if self.gui_mode:
|
|
859
844
|
webbrowser.open(f'http://localhost:{browser_port}/gui')
|
|
@@ -861,21 +846,15 @@ class Web:
|
|
|
861
846
|
f.write(str(os.getpid()))
|
|
862
847
|
while self.is_running:
|
|
863
848
|
gevent.sleep(1)
|
|
864
|
-
th
|
|
865
|
-
|
|
866
|
-
mcp_th.stop()
|
|
849
|
+
if th is not None:
|
|
850
|
+
th.stop()
|
|
867
851
|
if th_ssl is not None:
|
|
868
852
|
th_ssl.stop()
|
|
869
|
-
if self.mcp is not None:
|
|
870
|
-
mcp_th_ssl.stop()
|
|
871
853
|
except KeyboardInterrupt:
|
|
872
|
-
th
|
|
873
|
-
|
|
874
|
-
mcp_th.stop()
|
|
854
|
+
if th is not None:
|
|
855
|
+
th.stop()
|
|
875
856
|
if th_ssl is not None:
|
|
876
857
|
th_ssl.stop()
|
|
877
|
-
if self.mcp is not None:
|
|
878
|
-
mcp_th_ssl.stop()
|
|
879
858
|
|
|
880
859
|
def stop(self):
|
|
881
860
|
"""
|
cmdbox/version.py
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import datetime
|
|
2
2
|
|
|
3
|
-
dt_now = datetime.datetime(2025, 6,
|
|
3
|
+
dt_now = datetime.datetime(2025, 6, 15)
|
|
4
4
|
__appid__ = 'cmdbox'
|
|
5
5
|
__title__ = 'cmdbox (Command Development Application)'
|
|
6
|
-
__version__ = '0.6.0.
|
|
6
|
+
__version__ = '0.6.0.4'
|
|
7
7
|
__copyright__ = f'Copyright © 2023-{dt_now.strftime("%Y")} hamacom2004jp'
|
|
8
8
|
__pypiurl__ = 'https://pypi.org/project/cmdbox/'
|
|
9
9
|
__srcurl__ = 'https://github.com/hamacom2004jp/cmdbox'
|
|
@@ -49,7 +49,7 @@ agent.format_agent_message = (container, messages, txt, message) => {
|
|
|
49
49
|
const rand = cmdbox.random_string(16);
|
|
50
50
|
txt.append(`<span id="${rand}"/>`);
|
|
51
51
|
agent.recursive_json_parse(jobj);
|
|
52
|
-
render_result_func(txt.find(`#${rand}`), jobj,
|
|
52
|
+
render_result_func(txt.find(`#${rand}`), jobj, 256);
|
|
53
53
|
} catch (e) {
|
|
54
54
|
const msg = message.replace(/\n/g, '<br/>');
|
|
55
55
|
txt.append(msg);
|
|
@@ -176,8 +176,7 @@ agent.init_form = async () => {
|
|
|
176
176
|
if (agent.chat_reconnect_count >= max_reconnect_count) {
|
|
177
177
|
clearInterval(agent.chat_reconnectInterval_handler);
|
|
178
178
|
cmdbox.message({'error':'Connection to the agent has failed for several minutes. Please reload to resume reconnection.'});
|
|
179
|
-
|
|
180
|
-
location.href = `../signin/agent?r=${rand}`;
|
|
179
|
+
location.reload(true);
|
|
181
180
|
return;
|
|
182
181
|
}
|
|
183
182
|
agent.chat_reconnect_count++;
|
|
@@ -203,6 +203,24 @@ cmdbox.editapikey = async () => {
|
|
|
203
203
|
daialog.draggable({cursor:'move',cancel:'.modal-body'});
|
|
204
204
|
editapikey_modal.modal('show');
|
|
205
205
|
};
|
|
206
|
+
cmdbox.agentsetting = async () => {
|
|
207
|
+
const user = await cmdbox.user_info();
|
|
208
|
+
if (!user) {
|
|
209
|
+
cmdbox.message('user not found');
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
const agentsetting_modal = $('#agentsetting_modal').length?$('#agentsetting_modal'):$(`<div id="agentsetting_modal" class="modal" tabindex="-1" style="display: none;" aria-hidden="true"/>`);
|
|
213
|
+
agentsetting_modal.html('');
|
|
214
|
+
const daialog = $(`<div class="modal-dialog ui-draggable ui-draggable-handle"/>`).appendTo(agentsetting_modal);
|
|
215
|
+
const form = $(`<form id="agentsetting_form" class="modal-content novalidate"/>`).appendTo(daialog);
|
|
216
|
+
const header = $(`<div class="modal-header"/>`).appendTo(form);
|
|
217
|
+
header.append('<h5 class="modal-title">Agent Setting</h5>');
|
|
218
|
+
header.append('<button type="button" class="btn btn_close p-0 m-0" data-bs-dismiss="modal" aria-label="Close" style="margin-left: 0px;">'
|
|
219
|
+
+'<svg class="bi bi-x" width="24" height="24" fill="currentColor"><use href="#btn_x"></use></svg>'
|
|
220
|
+
+'</button>');
|
|
221
|
+
const body = $(`<div class="modal-body"/>`).appendTo(form);
|
|
222
|
+
const row_content = $(`<div class="row row_content"/>`).appendTo(body);
|
|
223
|
+
};
|
|
206
224
|
/**
|
|
207
225
|
* 現在のユーザーのパスワード変更
|
|
208
226
|
*/
|
|
@@ -324,14 +342,18 @@ $(()=>{
|
|
|
324
342
|
const user_info_menu = $('.user_info');
|
|
325
343
|
user_info_menu.removeClass('d-none').addClass('d-flex');
|
|
326
344
|
|
|
327
|
-
if (!user_info_menu.find('.dropdown-menu .editapikey-menu-item').length) {
|
|
328
|
-
const editapikey_item = $(`<li><a class="dropdown-item editapikey-menu-item" href="#" onclick="cmdbox.editapikey();">Edit ApiKey</a></li>`);
|
|
329
|
-
user_info_menu.find('.dropdown-menu').append(editapikey_item);
|
|
330
|
-
}
|
|
331
345
|
if (!user_info_menu.find('.dropdown-menu .changepass-menu-item').length) {
|
|
332
346
|
const changepass_item = $(`<li><a class="dropdown-item changepass-menu-item" href="#" onclick="cmdbox.passchange();">Change Password</a></li>`);
|
|
333
347
|
user_info_menu.find('.dropdown-menu').append(changepass_item);
|
|
334
348
|
}
|
|
349
|
+
if (!user_info_menu.find('.dropdown-menu .editapikey-menu-item').length) {
|
|
350
|
+
const editapikey_item = $(`<li><a class="dropdown-item editapikey-menu-item" href="#" onclick="cmdbox.editapikey();">Edit ApiKey</a></li>`);
|
|
351
|
+
user_info_menu.find('.dropdown-menu').append(editapikey_item);
|
|
352
|
+
}
|
|
353
|
+
/*if (!user_info_menu.find('.dropdown-menu .agentsetting-menu-item').length) {
|
|
354
|
+
const agentsetting_item = $(`<li><a class="dropdown-item agentsetting-menu-item" href="#" onclick="cmdbox.agentsetting();">Agent Setting</a></li>`);
|
|
355
|
+
user_info_menu.find('.dropdown-menu').append(agentsetting_item);
|
|
356
|
+
}*/
|
|
335
357
|
if (!user_info_menu.find('.dropdown-menu .signout-menu-item').length) {
|
|
336
358
|
const parts = location.pathname.split('/');
|
|
337
359
|
const sitepath = parts[parts.length-1];
|
cmdbox/web/assets/cmdbox/main.js
CHANGED
|
@@ -86,8 +86,7 @@ $(() => {
|
|
|
86
86
|
if (cmdbox.callback_reconnect_count >= max_reconnect_count) {
|
|
87
87
|
clearInterval(cmdbox.gui_callback_reconnectInterval_handler);
|
|
88
88
|
cmdbox.message({'error':'Connection to the agent has failed for several minutes. Please reload to resume reconnection.'});
|
|
89
|
-
|
|
90
|
-
location.href = `../signin${path}?r=${rand}`;
|
|
89
|
+
location.reload(true);
|
|
91
90
|
return;
|
|
92
91
|
}
|
|
93
92
|
cmdbox.callback_reconnect_count++;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: cmdbox
|
|
3
|
-
Version: 0.6.0.
|
|
3
|
+
Version: 0.6.0.4
|
|
4
4
|
Summary: cmdbox: It is a command line application with a plugin mechanism.
|
|
5
5
|
Home-page: https://github.com/hamacom2004jp/cmdbox
|
|
6
6
|
Download-URL: https://github.com/hamacom2004jp/cmdbox
|
|
@@ -73,7 +73,7 @@ apt-get install -y pkg-config libxml2-dev libxmlsec1-dev libxmlsec1-openssl buil
|
|
|
73
73
|
|
|
74
74
|
- When using `--agent use` in web mode, install the modules with dependencies.
|
|
75
75
|
```bash
|
|
76
|
-
pip install google-adk litellm
|
|
76
|
+
pip install google-adk litellm fastmcp
|
|
77
77
|
```
|
|
78
78
|
|
|
79
79
|
# Run
|
|
@@ -8,18 +8,18 @@ cmdbox/logconf_edge.yml,sha256=vRY-LxfWztk2QZOUN9kj_Eq6Y4qj8WzmiO9H0IRvjtQ,1081
|
|
|
8
8
|
cmdbox/logconf_gui.yml,sha256=-95vyd0q-aB1gsabdk8rg9dJ2zRKAZc8hRxyhNOQboU,1076
|
|
9
9
|
cmdbox/logconf_server.yml,sha256=n3c5-KVzjUzcUX5BQ6uE-PN9rp81yXaJql3whyCcSDQ,1091
|
|
10
10
|
cmdbox/logconf_web.yml,sha256=pPbdAwckbK0cgduxcVkx2mbk-Ymz5hVzR4guIsfApMQ,1076
|
|
11
|
-
cmdbox/version.py,sha256=
|
|
11
|
+
cmdbox/version.py,sha256=ebybePVS1-vifRTcWVutek50i0oYp1dzvReDgMD9JOA,2032
|
|
12
12
|
cmdbox/app/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
13
13
|
cmdbox/app/app.py,sha256=YkzNBd1S1oNVwnNj1eYQUFOcrcjwdsQzv0z4mMOb_mw,9149
|
|
14
14
|
cmdbox/app/client.py,sha256=n986lXeV7hhaki4iyyvsfhNptmCXDFphxlNoNe2XhKg,19542
|
|
15
|
-
cmdbox/app/common.py,sha256=
|
|
15
|
+
cmdbox/app/common.py,sha256=puw9sEKa6EgCAEUnXmjRd6R3l01ApZEQtP23kq34SZs,25599
|
|
16
16
|
cmdbox/app/edge.py,sha256=yskob1ewd5hHbPJKWvjXm6j4IpawE4gM_lOqe70gX1w,41422
|
|
17
17
|
cmdbox/app/edge_tool.py,sha256=QqigDHcxRJa1BvK_DVq-ccNTVXg4BEBsHkYsaauMDu0,8050
|
|
18
18
|
cmdbox/app/feature.py,sha256=O3MTyQFinKXONeCvSRAt81HqZWgXV-je_-nUZi0cdCE,9910
|
|
19
19
|
cmdbox/app/filer.py,sha256=L_DSMTvnbN_ffr3JIt0obbOmVoTHEfVm2cAVz3rLH-Q,16059
|
|
20
|
-
cmdbox/app/options.py,sha256=
|
|
20
|
+
cmdbox/app/options.py,sha256=N0O1NBjkeceCgDOQrsxMEQjzPwg24DB-cUttdFOWfLk,45933
|
|
21
21
|
cmdbox/app/server.py,sha256=woOmIk901ONn5a_2yz_b3I1JpLYIF8g42uQRd0_MRuQ,10417
|
|
22
|
-
cmdbox/app/web.py,sha256=
|
|
22
|
+
cmdbox/app/web.py,sha256=H3r_Jc0YTsNCD2OtoRqAup2Gz4rLc6TF4MzfIFNbKX4,51700
|
|
23
23
|
cmdbox/app/auth/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
24
24
|
cmdbox/app/auth/azure_signin.py,sha256=ZVJTeZwdgM4y2loKiTMEPiXxbJwbdoTVMWciyJhgqc8,1666
|
|
25
25
|
cmdbox/app/auth/azure_signin_saml.py,sha256=oM2buGTK4t6-OsUuiUXTlZk0YXZL01khuPYVB84dMDU,472
|
|
@@ -31,7 +31,7 @@ cmdbox/app/commons/convert.py,sha256=mkXPNQtX_pEH4L5DzonOY6Dh38SzJ5JQma_EY7UDBqU
|
|
|
31
31
|
cmdbox/app/commons/loghandler.py,sha256=go5Ui1c4AKqRSnxLzwrtPakYSjRHguXk4dGat1jD738,6323
|
|
32
32
|
cmdbox/app/commons/module.py,sha256=w63zqz5c6gLy-BZJ9dh4Q4C5PZyqM2Iqat5Zr9swJCI,4993
|
|
33
33
|
cmdbox/app/commons/redis_client.py,sha256=cOHshqAGI3CRWLcc2IMhk6MtXsVKlQq6HwcdqYsoA-0,14821
|
|
34
|
-
cmdbox/app/features/cli/agent_base.py,sha256=
|
|
34
|
+
cmdbox/app/features/cli/agent_base.py,sha256=7Hkdb1wqZZ_oCKD16fhEu9XMw0-L44x3tN4W4CY-0Gw,26657
|
|
35
35
|
cmdbox/app/features/cli/audit_base.py,sha256=wWWK31EUczvP4a1MNuz2KlqwaSn9yyt908ueRvjkuow,9405
|
|
36
36
|
cmdbox/app/features/cli/cmdbox_audit_createdb.py,sha256=Hmq3NVrAUBbj-UB9fum2TuWU7MIH71754S_s0X9oj40,12133
|
|
37
37
|
cmdbox/app/features/cli/cmdbox_audit_delete.py,sha256=2X6A8XtViOnUH7iDj02ZrqQhYBq7WOAwi-nL10der64,18922
|
|
@@ -46,8 +46,8 @@ cmdbox/app/features/cli/cmdbox_client_file_remove.py,sha256=e7e8iG-SBYbSZEwEsLaE
|
|
|
46
46
|
cmdbox/app/features/cli/cmdbox_client_file_rmdir.py,sha256=pNrJ3YW8GSNUd7mXFt_HOHOQSehv9zYIdwwGLdUCHIA,11530
|
|
47
47
|
cmdbox/app/features/cli/cmdbox_client_file_upload.py,sha256=X216q8dVAs_iuoOLUQ3wE-adD6QlHJJ9KVddCSxZhs0,13407
|
|
48
48
|
cmdbox/app/features/cli/cmdbox_client_server_info.py,sha256=Nnnu4bcKyHU6drHvebIDIiu0PznqdDks0OartZgnVEM,9575
|
|
49
|
-
cmdbox/app/features/cli/cmdbox_cmd_list.py,sha256=
|
|
50
|
-
cmdbox/app/features/cli/cmdbox_cmd_load.py,sha256=
|
|
49
|
+
cmdbox/app/features/cli/cmdbox_cmd_list.py,sha256=XGsUjwpFhSofsJQE27LWdY0r4gOyCY-MFv_LP_Asixw,6604
|
|
50
|
+
cmdbox/app/features/cli/cmdbox_cmd_load.py,sha256=JYCRg5JREhRgMLTlkFDrzlc7SiDA14NL2fXkMEwLtEo,6390
|
|
51
51
|
cmdbox/app/features/cli/cmdbox_edge_config.py,sha256=KGqBXFQzjlYesTsP5JpeXvAsehdATHWlny5Ujnx7fUw,9460
|
|
52
52
|
cmdbox/app/features/cli/cmdbox_edge_start.py,sha256=rtlYxFkW3Ud5sBKiuk8NWZ3DVXV-3T3KH4i5qwKxP_4,3824
|
|
53
53
|
cmdbox/app/features/cli/cmdbox_gui_start.py,sha256=dzoso_s8-eYvL2YOK0hlJUG46LFbVNyZmSoJhpyxjg0,1390
|
|
@@ -55,21 +55,21 @@ cmdbox/app/features/cli/cmdbox_gui_stop.py,sha256=IRr73L2wIGCq9Om6aHgkgsZHhtA5CV
|
|
|
55
55
|
cmdbox/app/features/cli/cmdbox_server_list.py,sha256=bGtV6YETNrZBVg4s-OGuZQAAppBkeJ1pqYVyJvYPGf4,5777
|
|
56
56
|
cmdbox/app/features/cli/cmdbox_server_start.py,sha256=RHxK6IoSe2qeeLp-fY0OdwXKhr5zF99NritYQPGM9_4,7280
|
|
57
57
|
cmdbox/app/features/cli/cmdbox_server_stop.py,sha256=PqC8TRlAbfS-ZMkiyqW-xqnqVKOdIeKNICl36A9hrw0,8644
|
|
58
|
-
cmdbox/app/features/cli/cmdbox_web_apikey_add.py,sha256=
|
|
59
|
-
cmdbox/app/features/cli/cmdbox_web_apikey_del.py,sha256=
|
|
58
|
+
cmdbox/app/features/cli/cmdbox_web_apikey_add.py,sha256=ZFIiDCR7KEhHCvCkVKwFKaLDcYDnAzRrB8Ajnmc34_o,7139
|
|
59
|
+
cmdbox/app/features/cli/cmdbox_web_apikey_del.py,sha256=Ciw1nPw-wdzhUELO_pU4_tAOKPb3fF2rPkEqlk_PqfI,7117
|
|
60
60
|
cmdbox/app/features/cli/cmdbox_web_gencert.py,sha256=mnGv18yUBkCuwhy-k-2Q6uTz0MNDBGhdWdpcHKCc_TE,9323
|
|
61
61
|
cmdbox/app/features/cli/cmdbox_web_genpass.py,sha256=8eJTCRtZJLuj7d5NaZhJ326oCsPH1bGmfy4Pw363NLA,9541
|
|
62
|
-
cmdbox/app/features/cli/cmdbox_web_group_add.py,sha256=
|
|
63
|
-
cmdbox/app/features/cli/cmdbox_web_group_del.py,sha256=
|
|
64
|
-
cmdbox/app/features/cli/cmdbox_web_group_edit.py,sha256=
|
|
65
|
-
cmdbox/app/features/cli/cmdbox_web_group_list.py,sha256=
|
|
66
|
-
cmdbox/app/features/cli/cmdbox_web_start.py,sha256=
|
|
62
|
+
cmdbox/app/features/cli/cmdbox_web_group_add.py,sha256=N_MUGdi2wckZe4UCU1Kgm_-nwDNHMCtrfDWWY1SVcZY,7407
|
|
63
|
+
cmdbox/app/features/cli/cmdbox_web_group_del.py,sha256=d7j6UaxepvjOr6SEy_biNT4nSp7gFjLEo2UqNmAYNjM,6617
|
|
64
|
+
cmdbox/app/features/cli/cmdbox_web_group_edit.py,sha256=8WQGtKtMdnGBhgI8_ZwUfenWLQGwj678daW5madZ_WY,7346
|
|
65
|
+
cmdbox/app/features/cli/cmdbox_web_group_list.py,sha256=1UlFEFf9GA248qe0o_LjnnUPE8BwGxnhRgY7aBTThfg,6712
|
|
66
|
+
cmdbox/app/features/cli/cmdbox_web_start.py,sha256=bW6JrnNC-sskNFfFp3zCG6K-ydqRPAzdrgRbk3Keeh0,17531
|
|
67
67
|
cmdbox/app/features/cli/cmdbox_web_stop.py,sha256=yRLHhCR1sQvNep4-9-OITQkzeEQr1M-ZSLzd059D3EA,3568
|
|
68
|
-
cmdbox/app/features/cli/cmdbox_web_user_add.py,sha256=
|
|
69
|
-
cmdbox/app/features/cli/cmdbox_web_user_del.py,sha256=
|
|
70
|
-
cmdbox/app/features/cli/cmdbox_web_user_edit.py,sha256=
|
|
71
|
-
cmdbox/app/features/cli/cmdbox_web_user_list.py,sha256=
|
|
72
|
-
cmdbox/app/features/web/cmdbox_web_agent.py,sha256=
|
|
68
|
+
cmdbox/app/features/cli/cmdbox_web_user_add.py,sha256=8STmtxwiCYuClcYGzK_kt7hzhxyFI7ZI0Lg1gpTiSY4,8599
|
|
69
|
+
cmdbox/app/features/cli/cmdbox_web_user_del.py,sha256=2De84-SMYnOhl32tICUYe02g7m4EI991ZP9GGsfN4xU,6580
|
|
70
|
+
cmdbox/app/features/cli/cmdbox_web_user_edit.py,sha256=yvZ2oGYv9QVEg2tUiQkS1RpaCqG4CkpWhDrzIAsETAE,8507
|
|
71
|
+
cmdbox/app/features/cli/cmdbox_web_user_list.py,sha256=xzSJvhICU5cXzsQ5krJUFryhSWlsfObI3slUyRDDADU,6700
|
|
72
|
+
cmdbox/app/features/web/cmdbox_web_agent.py,sha256=uqdjhbnWHy5LSFc0pmDSYUun083Crb8UJRuINFPw4A8,14691
|
|
73
73
|
cmdbox/app/features/web/cmdbox_web_assets.py,sha256=D1dYNrvC7xBAVAAHX6PkoB6RFehEofET4hkHeCFYq7s,1931
|
|
74
74
|
cmdbox/app/features/web/cmdbox_web_audit.py,sha256=-flyijdnh3hN-BKnw0GI3gSiduLP0vQFg_AiYCLXRBY,3359
|
|
75
75
|
cmdbox/app/features/web/cmdbox_web_audit_metrics.py,sha256=4zcWNcI_mCT36B0CNrtYz9rOAK6QXqyLzloFIgginxw,3189
|
|
@@ -301,16 +301,16 @@ cmdbox/web/assets/apexcharts/apexcharts.css,sha256=l-xkqykcV8a22g04B-Vpt4JFWcHlw
|
|
|
301
301
|
cmdbox/web/assets/apexcharts/apexcharts.min.js,sha256=zceUTsCKa8Y2SqjqZjLjifXQDnqsvKRTmT8fTIUix_4,570304
|
|
302
302
|
cmdbox/web/assets/bootstrap/bootstrap.bundle.min.5.3.0.js,sha256=qlPVgvl-tZTCpcxYJFdHB_m6mDe84wRr-l81VoYPTgQ,80421
|
|
303
303
|
cmdbox/web/assets/bootstrap/bootstrap.min.5.3.0.css,sha256=fx038NkLY4U1TCrBDiu5FWPEa9eiZu01EiLryshJbCo,232914
|
|
304
|
-
cmdbox/web/assets/cmdbox/agent.js,sha256=
|
|
304
|
+
cmdbox/web/assets/cmdbox/agent.js,sha256=NJwNfnIzTP23qGsuQr7ov-u4Mo9ibU7h3FN66-yTEpA,15763
|
|
305
305
|
cmdbox/web/assets/cmdbox/audit.js,sha256=5wFt4ejO4bwrOpt9yxOiwUz5XXXLOP8eo0ITTUwROZ0,19332
|
|
306
306
|
cmdbox/web/assets/cmdbox/color_mode.css,sha256=U4UGBnWiBMcrSEEusgT-_o-pt4MP3myoA9Lgnn1g6qE,19803
|
|
307
|
-
cmdbox/web/assets/cmdbox/common.js,sha256=
|
|
307
|
+
cmdbox/web/assets/cmdbox/common.js,sha256=q0CvDq3sFuz381CyxjogQJrdS9o1R7h1vccE1ih3jRk,66748
|
|
308
308
|
cmdbox/web/assets/cmdbox/favicon.ico,sha256=2U4MhqzJklRksOQwnK-MZigZCubxCHqKG_AuNJnvYtA,34494
|
|
309
309
|
cmdbox/web/assets/cmdbox/filer_modal.js,sha256=iKhNN9urjUm22na4vHYWhbj__2De9iAuDJE7TvBWtQ0,8566
|
|
310
310
|
cmdbox/web/assets/cmdbox/icon.png,sha256=xdEwDdCS8CoPQk7brW-1mV8FIGYtUeSMBRlY9Oh-3nE,296172
|
|
311
311
|
cmdbox/web/assets/cmdbox/list_cmd.js,sha256=4oVpXoSaUWXHKkxxCBEjoHgtrjTP1FSsL3QEHwjtaKc,21437
|
|
312
312
|
cmdbox/web/assets/cmdbox/list_pipe.js,sha256=2rPkauw9VHRMXl76qRgqy81Y815Y8B1tnVKOSKKfRwc,11315
|
|
313
|
-
cmdbox/web/assets/cmdbox/main.js,sha256=
|
|
313
|
+
cmdbox/web/assets/cmdbox/main.js,sha256=UCI2m8GT0Ba6dQtmwBwZMUGXihYGJpFKd4xqxJaGCo8,5659
|
|
314
314
|
cmdbox/web/assets/cmdbox/open_capture.js,sha256=W4IQlOYLN4Y8OaS8Xc5yp-BRlm82TVjujChr3hJKS0M,709
|
|
315
315
|
cmdbox/web/assets/cmdbox/open_output_json.js,sha256=4q7mCdVmSzFudlTlW9MuIJ1-f-kDvpD6rDUU01IbKi8,727
|
|
316
316
|
cmdbox/web/assets/cmdbox/result.js,sha256=m7u6-VTXT4AK_6frn4dTIjEzDg0bfajD_Jv1MWgLZRo,3154
|
|
@@ -360,9 +360,9 @@ cmdbox/web/assets/tree-menu/image/file.png,sha256=Uw4zYkHyuoZ_kSVkesHAeSeA_g9_LP
|
|
|
360
360
|
cmdbox/web/assets/tree-menu/image/folder-close.png,sha256=TcgsKTBBF2ejgzekOEDBFBxsJf-Z5u0x9IZVi4GBR-I,284
|
|
361
361
|
cmdbox/web/assets/tree-menu/image/folder-open.png,sha256=DT7y1GRK4oXJkFvqTN_oSGM5ZYARzPvjoCGL6wqkoo0,301
|
|
362
362
|
cmdbox/web/assets/tree-menu/js/tree-menu.js,sha256=-GkZxI7xzHuXXHYQBHAVTcuKX4TtoiMuyIms6Xc3pxk,1029
|
|
363
|
-
cmdbox-0.6.0.
|
|
364
|
-
cmdbox-0.6.0.
|
|
365
|
-
cmdbox-0.6.0.
|
|
366
|
-
cmdbox-0.6.0.
|
|
367
|
-
cmdbox-0.6.0.
|
|
368
|
-
cmdbox-0.6.0.
|
|
363
|
+
cmdbox-0.6.0.4.dist-info/LICENSE,sha256=sBzzPc5v-5LBuIFi2V4olsnoVg-3EBI0zRX5r19SOxE,1117
|
|
364
|
+
cmdbox-0.6.0.4.dist-info/METADATA,sha256=ffkuAk5l_kg_k2YURFYc3bOkhDP8NEUqtr_LENF1JfU,30889
|
|
365
|
+
cmdbox-0.6.0.4.dist-info/WHEEL,sha256=tZoeGjtWxWRfdplE7E3d45VPlLNQnvbKiYnx7gwAy8A,92
|
|
366
|
+
cmdbox-0.6.0.4.dist-info/entry_points.txt,sha256=1LdoMUjTD_YdxlsAiAiJ1cREcXFG8-Xg2xQTNYoNpT4,47
|
|
367
|
+
cmdbox-0.6.0.4.dist-info/top_level.txt,sha256=eMEkD5jn8_0PkCAL8h5xJu4qAzF2O8Wf3vegFkKUXR4,7
|
|
368
|
+
cmdbox-0.6.0.4.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|