cmdbox 0.6.0.4__py3-none-any.whl → 0.6.1.1__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/app.py +2 -2
- cmdbox/app/auth/azure_signin.py +5 -1
- cmdbox/app/auth/signin.py +144 -28
- cmdbox/app/common.py +40 -3
- cmdbox/app/edge.py +1 -1
- cmdbox/app/edge_tool.py +1 -1
- cmdbox/app/features/cli/agent_base.py +1 -335
- cmdbox/app/features/cli/cmdbox_audit_search.py +0 -2
- cmdbox/app/features/cli/cmdbox_audit_write.py +9 -0
- 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_mcp_proxy.py +90 -0
- cmdbox/app/features/cli/cmdbox_web_gencert.py +25 -2
- cmdbox/app/features/cli/cmdbox_web_start.py +5 -2
- cmdbox/app/features/web/cmdbox_web_signin.py +1 -1
- cmdbox/app/mcp.py +375 -0
- cmdbox/app/options.py +2 -0
- cmdbox/app/web.py +34 -6
- cmdbox/autoload.py +10 -0
- cmdbox/extensions/user_list.yml +25 -1
- cmdbox/licenses/{LICENSE.Deprecated.1.2.18(MIT License).txt → LICENSE_PyJWT_2_10_1_MIT_License.txt} +2 -2
- cmdbox/licenses/LICENSE_exceptiongroup_1_3_0_MIT_License.txt +73 -0
- cmdbox/licenses/LICENSE_fastmcp_2_9_2_Apache_Software_License.txt +201 -0
- cmdbox/licenses/{LICENSE.graphviz.0.20.3(MIT License).txt → LICENSE_graphviz_0_21_UNKNOWN.txt} +1 -1
- cmdbox/licenses/LICENSE_jaraco_functools_4_2_1_UNKNOWN.txt +18 -0
- cmdbox/licenses/{LICENSE.numpy.2.2.5(BSD License).txt → LICENSE_numpy_2_3_1_BSD_License.txt} +8 -8
- cmdbox/licenses/LICENSE_openapi-pydantic_0_5_1_MIT_License.txt +40 -0
- cmdbox/licenses/LICENSE_propcache_0_3_2_Apache_Software_License.txt +202 -0
- cmdbox/licenses/LICENSE_proto-plus_1_26_1_Apache_Software_License.txt +202 -0
- cmdbox/licenses/LICENSE_shellingham_1_5_4_ISC_License-ISCL.txt +13 -0
- cmdbox/licenses/LICENSE_sphinx-last-updated-by-git_0_3_8_BSD_License.txt +22 -0
- cmdbox/licenses/LICENSE_tenacity_8_5_0_Apache_Software_License.txt +202 -0
- cmdbox/licenses/LICENSE_tokenizers_0_21_2_Apache_Software_License.txt +1 -0
- cmdbox/licenses/LICENSE_typer_0_16_0_MIT_License.txt +21 -0
- cmdbox/licenses/LICENSE_typing-inspection_0_4_1_UNKNOWN.txt +21 -0
- cmdbox/licenses/LICENSE_yarl_1_20_1_Apache_Software_License.txt +202 -0
- cmdbox/licenses/LICENSE_zipp_3_23_0_UNKNOWN.txt +18 -0
- cmdbox/licenses/files.txt +176 -166
- cmdbox/logconf_mcp.yml +43 -0
- cmdbox/version.py +2 -2
- cmdbox/web/agent.html +1 -33
- cmdbox/web/assets/cmdbox/audit.js +1 -1
- cmdbox/web/assets/cmdbox/common.js +47 -4
- cmdbox/web/assets/cmdbox/svgicon.js +122 -0
- cmdbox/web/assets/cmdbox/users.js +4 -3
- cmdbox/web/audit.html +1 -35
- cmdbox/web/filer.html +1 -13
- cmdbox/web/gui.html +2 -50
- cmdbox/web/result.html +2 -46
- cmdbox/web/signin.html +30 -32
- cmdbox/web/users.html +1 -41
- {cmdbox-0.6.0.4.dist-info → cmdbox-0.6.1.1.dist-info}/METADATA +31 -6
- cmdbox-0.6.1.1.dist-info/RECORD +383 -0
- cmdbox/licenses/LICENSE.keyring.25.6.0(MIT License).txt +0 -17
- cmdbox/licenses/LICENSE.typing-inspection.0.4.0(MIT License).txt +0 -21
- cmdbox/licenses/LICENSE.wrapt.1.17.2(BSD License).txt +0 -24
- cmdbox/licenses/LICENSE.zipp.3.21.0(MIT License).txt +0 -17
- cmdbox-0.6.0.4.dist-info/RECORD +0 -368
- /cmdbox/licenses/{LICENSE.Authlib.1.5.2(BSD License).txt → LICENSE_Authlib_1_6_0_BSD_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.Jinja2.3.1.6(BSD License).txt → LICENSE_Jinja2_3_1_6_BSD_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.MarkupSafe.3.0.2(BSD License).txt → LICENSE_MarkupSafe_3_0_2_BSD_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.PyYAML.6.0.2(MIT License).txt → LICENSE_PyYAML_6_0_2_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.Pygments.2.19.1(BSD License).txt → LICENSE_Pygments_2_19_2_BSD_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.SQLAlchemy.2.0.40(MIT License).txt → LICENSE_SQLAlchemy_2_0_41_MIT.txt} +0 -0
- /cmdbox/licenses/{LICENSE.Sphinx.8.2.3(UNKNOWN).txt → LICENSE_Sphinx_8_2_3_UNKNOWN.txt} +0 -0
- /cmdbox/licenses/{LICENSE.aiohappyeyeballs.2.6.1(Python Software Foundation License).txt → LICENSE_aiohappyeyeballs_2_6_1_Python_Software_Foundation_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.aiohttp.3.11.18(Apache Software License).txt → LICENSE_aiohttp_3_12_13_Apache-2_0.txt} +0 -0
- /cmdbox/licenses/{LICENSE.aiosignal.1.3.2(Apache Software License).txt → LICENSE_aiosignal_1_3_2_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.alabaster.1.0.0(BSD License).txt → LICENSE_alabaster_1_0_0_BSD_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.annotated-types.0.7.0(MIT License).txt → LICENSE_annotated-types_0_7_0_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.anyio.4.9.0(MIT License).txt → LICENSE_anyio_4_9_0_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.argcomplete.3.6.2(Apache Software License).txt → LICENSE_argcomplete_3_6_2_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.async-timeout.5.0.1(Apache Software License).txt → LICENSE_async-timeout_5_0_1_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.attrs.25.3.0(UNKNOWN).txt → LICENSE_attrs_25_3_0_UNKNOWN.txt} +0 -0
- /cmdbox/licenses/{LICENSE.babel.2.17.0(BSD License).txt → LICENSE_babel_2_17_0_BSD_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.backports.tarfile.1.2.0(MIT License).txt → LICENSE_backports_tarfile_1_2_0_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.cachetools.5.5.2(MIT License).txt → LICENSE_cachetools_5_5_2_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.certifi.2025.4.26(Mozilla Public License 2.0 (MPL 2.0)).txt → LICENSE_certifi_2025_6_15_Mozilla_Public_License_2_0-MPL_2_0.txt} +0 -0
- /cmdbox/licenses/{LICENSE.cffi.1.17.1(MIT License).txt → LICENSE_cffi_1_17_1_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.charset-normalizer.3.4.2(MIT License).txt → LICENSE_charset-normalizer_3_4_2_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.click.8.2.0(UNKNOWN).txt → LICENSE_click_8_2_1_UNKNOWN.txt} +0 -0
- /cmdbox/licenses/{LICENSE.jiter.0.9.0(MIT License).txt → LICENSE_cloudpickle_3_1_1_BSD_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.colorama.0.4.6(BSD License).txt → LICENSE_colorama_0_4_6_BSD_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.cryptography.44.0.3(Apache Software License; BSD License).txt → LICENSE_cryptography_45_0_4_Apache-2_0_OR_BSD-3-Clause.txt} +0 -0
- /cmdbox/licenses/{LICENSE.distro.1.9.0(Apache Software License).txt → LICENSE_distro_1_9_0_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.docstring_parser.0.16(MIT License).txt → LICENSE_docstring_parser_0_16_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.docutils.0.21.2(BSD License; GNU General Public License (GPL); Public Domain; Python Software Foundation License).txt → LICENSE_docutils_0_21_2_BSD_License-GNU_General_Public_License-GPL-Public_Domain-Python_Software_Foundation_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.fastapi.0.115.12(MIT License).txt → LICENSE_fastapi_0_115_14_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.filelock.3.18.0(The Unlicense (Unlicense)).txt → LICENSE_filelock_3_18_0_The_Unlicense-Unlicense.txt} +0 -0
- /cmdbox/licenses/{LICENSE.frozenlist.1.6.0(Apache-2.0).txt → LICENSE_frozenlist_1_7_0_Apache-2_0.txt} +0 -0
- /cmdbox/licenses/{LICENSE.fsspec.2025.3.2(BSD License).txt → LICENSE_fsspec_2025_5_1_BSD_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.gevent.25.4.2(MIT).txt → LICENSE_gevent_25_5_1_MIT.txt} +0 -0
- /cmdbox/licenses/{LICENSE.google-adk.0.5.0(Apache Software License).txt → LICENSE_google-adk_1_5_0_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.google-api-core.2.24.2(Apache Software License).txt → LICENSE_google-api-core_2_25_1_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.google-api-python-client.2.169.0(Apache Software License).txt → LICENSE_google-api-python-client_2_174_0_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.google-auth-httplib2.0.2.0(Apache Software License).txt → LICENSE_google-auth-httplib2_0_2_0_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.google-auth.2.40.1(Apache Software License).txt → LICENSE_google-auth_2_40_3_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.google-cloud-aiplatform.1.92.0(Apache 2.0).txt → LICENSE_google-cloud-aiplatform_1_100_0_Apache_2_0.txt} +0 -0
- /cmdbox/licenses/{LICENSE.google-cloud-bigquery.3.31.0(Apache Software License).txt → LICENSE_google-cloud-appengine-logging_1_6_2_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.google-cloud-core.2.4.3(Apache Software License).txt → LICENSE_google-cloud-audit-log_0_3_2_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.google-cloud-resource-manager.1.14.2(Apache Software License).txt → LICENSE_google-cloud-bigquery_3_34_0_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.google-cloud-secret-manager.2.23.3(Apache Software License).txt → LICENSE_google-cloud-core_2_4_3_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.google-cloud-speech.2.32.0(Apache Software License).txt → LICENSE_google-cloud-logging_3_12_1_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.google-cloud-storage.2.19.0(Apache Software License).txt → LICENSE_google-cloud-resource-manager_1_14_2_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.google-cloud-trace.1.16.1(Apache Software License).txt → LICENSE_google-cloud-secret-manager_2_24_0_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.google-crc32c.1.7.1(Apache 2.0).txt → LICENSE_google-cloud-speech_2_33_0_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.google-genai.1.14.0(Apache Software License).txt → LICENSE_google-cloud-storage_2_19_0_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.google-resumable-media.2.7.2(Apache Software License).txt → LICENSE_google-cloud-trace_1_16_2_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.googleapis-common-protos.1.70.0(Apache Software License).txt → LICENSE_google-crc32c_1_7_1_Apache_2_0.txt} +0 -0
- /cmdbox/licenses/{LICENSE.grpc-google-iam-v1.0.14.2(Apache Software License).txt → LICENSE_google-genai_1_23_0_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.id.1.5.0(Apache Software License).txt → LICENSE_google-resumable-media_2_7_2_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.importlib_metadata.8.6.1(Apache Software License).txt → LICENSE_googleapis-common-protos_1_70_0_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.greenlet.3.2.2(MIT AND Python-2.0).txt → LICENSE_greenlet_3_2_3_MIT_AND_Python-2_0.txt} +0 -0
- /cmdbox/licenses/{LICENSE.propcache.0.3.1(Apache Software License).txt → LICENSE_grpc-google-iam-v1_0_14_2_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.grpcio-status.1.71.0(Apache Software License).txt → LICENSE_grpcio-status_1_73_1_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.grpcio.1.71.0(Apache Software License).txt → LICENSE_grpcio_1_73_1_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.gunicorn.23.0.0(MIT License).txt → LICENSE_gunicorn_23_0_0_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.h11.0.16.0(MIT License).txt → LICENSE_h11_0_16_0_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.httpcore.1.0.9(BSD License).txt → LICENSE_httpcore_1_0_9_BSD_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.httplib2.0.22.0(MIT License).txt → LICENSE_httplib2_0_22_0_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.httptools.0.6.4(MIT License).txt → LICENSE_httptools_0_6_4_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.httpx-sse.0.4.0(MIT).txt → LICENSE_httpx-sse_0_4_1_MIT.txt} +0 -0
- /cmdbox/licenses/{LICENSE.httpx.0.28.1(BSD License).txt → LICENSE_httpx_0_28_1_BSD_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.huggingface-hub.0.31.1(Apache Software License).txt → LICENSE_huggingface-hub_0_33_1_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.proto-plus.1.26.1(Apache Software License).txt → LICENSE_id_1_5_0_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.idna.3.10(BSD License).txt → LICENSE_idna_3_10_BSD_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.imagesize.1.4.1(MIT License).txt → LICENSE_imagesize_1_4_1_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.yarl.1.20.0(Apache Software License).txt → LICENSE_importlib_metadata_8_7_0_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.itsdangerous.2.2.0(BSD License).txt → LICENSE_itsdangerous_2_2_0_BSD_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.jaraco.classes.3.4.0(MIT License).txt → LICENSE_jaraco_classes_3_4_0_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.jaraco.context.6.0.1(MIT License).txt → LICENSE_jaraco_context_6_0_1_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.sphinxcontrib-applehelp.2.0.0(BSD License).txt → LICENSE_jiter_0_10_0_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.jsonschema-specifications.2025.4.1(UNKNOWN).txt → LICENSE_jsonschema-specifications_2025_4_1_UNKNOWN.txt} +0 -0
- /cmdbox/licenses/{LICENSE.jsonschema.4.23.0(MIT License).txt → LICENSE_jsonschema_4_24_0_UNKNOWN.txt} +0 -0
- /cmdbox/licenses/{LICENSE.jaraco.functools.4.1.0(MIT License).txt → LICENSE_keyring_25_6_0_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.litellm.1.69.0(MIT License).txt → LICENSE_litellm_1_73_6_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.markdown-it-py.3.0.0(MIT License).txt → LICENSE_markdown-it-py_3_0_0_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.mcp.1.8.0(MIT License).txt → LICENSE_mcp_1_9_4_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.mdurl.0.1.2(MIT License).txt → LICENSE_mdurl_0_1_2_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.more-itertools.10.7.0(MIT License).txt → LICENSE_more-itertools_10_7_0_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.multidict.6.4.3(Apache Software License).txt → LICENSE_multidict_6_6_2_Apache_License_2_0.txt} +0 -0
- /cmdbox/licenses/{LICENSE.nh3.0.2.21(MIT).txt → LICENSE_nh3_0_2_21_MIT.txt} +0 -0
- /cmdbox/licenses/{LICENSE.openai.1.75.0(Apache Software License).txt → LICENSE_openai_1_93_0_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.opentelemetry-api.1.33.0(Apache Software License).txt → LICENSE_opentelemetry-api_1_34_1_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.opentelemetry-exporter-gcp-trace.1.9.0(Apache Software License).txt → LICENSE_opentelemetry-exporter-gcp-trace_1_9_0_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.opentelemetry-resourcedetector-gcp.1.9.0a0(Apache Software License).txt → LICENSE_opentelemetry-resourcedetector-gcp_1_9_0a0_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.opentelemetry-sdk.1.33.0(Apache Software License).txt → LICENSE_opentelemetry-sdk_1_34_1_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.opentelemetry-semantic-conventions.0.54b0(Apache Software License).txt → LICENSE_opentelemetry-semantic-conventions_0_55b1_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.packaging.25.0(Apache Software License; BSD License).txt → LICENSE_packaging_25_0_Apache_Software_License-BSD_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.pillow.11.2.1(UNKNOWN).txt → LICENSE_pillow_11_2_1_UNKNOWN.txt} +0 -0
- /cmdbox/licenses/{LICENSE.pip.24.0(MIT License).txt → LICENSE_pip_24_0_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.plyer.2.1.0(MIT License).txt → LICENSE_plyer_2_1_0_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.prettytable.3.16.0(UNKNOWN).txt → LICENSE_prettytable_3_16_0_UNKNOWN.txt} +0 -0
- /cmdbox/licenses/{LICENSE.prompt_toolkit.3.0.51(BSD License).txt → LICENSE_prompt_toolkit_3_0_51_BSD_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.protobuf.5.29.4(3-Clause BSD License).txt → LICENSE_protobuf_6_31_1_3-Clause_BSD_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.psycopg-binary.3.2.7(GNU Lesser General Public License v3 (LGPLv3)).txt → LICENSE_psycopg-binary_3_2_9_GNU_Lesser_General_Public_License_v3-LGPLv3.txt} +0 -0
- /cmdbox/licenses/{LICENSE.psycopg.3.2.7(GNU Lesser General Public License v3 (LGPLv3)).txt → LICENSE_psycopg_3_2_9_GNU_Lesser_General_Public_License_v3-LGPLv3.txt} +0 -0
- /cmdbox/licenses/{LICENSE.pyasn1.0.6.1(BSD License).txt → LICENSE_pyasn1_0_6_1_BSD_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.pyasn1_modules.0.4.2(BSD License).txt → LICENSE_pyasn1_modules_0_4_2_BSD_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.pycparser.2.22(BSD License).txt → LICENSE_pycparser_2_22_BSD_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.pycryptodome.3.22.0(BSD License; Public Domain).txt → LICENSE_pycryptodome_3_23_0_BSD_License-Public_Domain.txt} +0 -0
- /cmdbox/licenses/{LICENSE.pydantic-settings.2.9.1(MIT License).txt → LICENSE_pydantic-settings_2_10_1_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.pydantic.2.11.4(MIT License).txt → LICENSE_pydantic_2_11_7_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.pydantic_core.2.33.2(MIT License).txt → LICENSE_pydantic_core_2_33_2_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.pyparsing.3.2.3(MIT License).txt → LICENSE_pyparsing_3_2_3_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.pystray.0.19.5(GNU Lesser General Public License v3 (LGPLv3)).txt → LICENSE_pystray_0_19_5_GNU_Lesser_General_Public_License_v3-LGPLv3.txt} +0 -0
- /cmdbox/licenses/{LICENSE.python-dateutil.2.9.0.post0(Apache Software License; BSD License).txt → LICENSE_python-dateutil_2_9_0_post0_Apache_Software_License-BSD_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.python-dotenv.1.1.0(BSD License).txt → LICENSE_python-dotenv_1_1_1_BSD_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.python-multipart.0.0.20(Apache Software License).txt → LICENSE_python-multipart_0_0_20_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.pywin32-ctypes.0.2.3(BSD-3-Clause).txt → LICENSE_pywin32-ctypes_0_2_3_BSD-3-Clause.txt} +0 -0
- /cmdbox/licenses/{LICENSE.questionary.2.1.0(MIT License).txt → LICENSE_questionary_2_1_0_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.readme_renderer.44.0(Apache Software License).txt → LICENSE_readme_renderer_44_0_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.redis.6.0.0(MIT License).txt → LICENSE_redis_6_2_0_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.referencing.0.36.2(UNKNOWN).txt → LICENSE_referencing_0_36_2_UNKNOWN.txt} +0 -0
- /cmdbox/licenses/{LICENSE.regex.2024.11.6(Apache Software License).txt → LICENSE_regex_2024_11_6_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.requests-toolbelt.1.0.0(Apache Software License).txt → LICENSE_requests-toolbelt_1_0_0_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.requests.2.32.3(Apache Software License).txt → LICENSE_requests_2_32_4_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.rfc3986.2.0.0(Apache Software License).txt → LICENSE_rfc3986_2_0_0_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.rich.14.0.0(MIT License).txt → LICENSE_rich_14_0_0_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.roman-numerals-py.3.1.0(CC0 1.0 Universal (CC0 1.0) Public Domain Dedication; Zero-Clause BSD (0BSD)).txt → LICENSE_roman-numerals-py_3_1_0_CC0_1_0_Universal-CC0_1_0-Public_Domain_Dedication-Zero-Clause_BSD-0BSD.txt} +0 -0
- /cmdbox/licenses/{LICENSE.rpds-py.0.24.0(MIT).txt → LICENSE_rpds-py_0_25_1_MIT.txt} +0 -0
- /cmdbox/licenses/{LICENSE.rsa.4.9.1(Apache Software License).txt → LICENSE_rsa_4_9_1_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.setuptools.65.5.0(MIT License).txt → LICENSE_setuptools_65_5_0_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.shapely.2.1.0(BSD License).txt → LICENSE_shapely_2_1_1_BSD_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.six.1.17.0(MIT License).txt → LICENSE_six_1_17_0_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.sniffio.1.3.1(Apache Software License; MIT License).txt → LICENSE_sniffio_1_3_1_Apache_Software_License-MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.snowballstemmer.3.0.1(BSD License).txt → LICENSE_snowballstemmer_3_0_1_BSD_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.sphinx-intl.2.3.1(BSD License).txt → LICENSE_sphinx-intl_2_3_1_BSD_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.sphinx-rtd-theme.3.0.2(MIT License).txt → LICENSE_sphinx-rtd-theme_3_0_2_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.sphinx-sitemap.2.6.0(MIT License).txt → LICENSE_sphinx-sitemap_2_7_2_UNKNOWN.txt} +0 -0
- /cmdbox/licenses/{LICENSE.sphinx_fontawesome.0.0.6(GNU General Public License v2 (GPLv2)).txt → LICENSE_sphinx_fontawesome_0_0_6_GNU_General_Public_License_v2-GPLv2.txt} +0 -0
- /cmdbox/licenses/{LICENSE.sphinxcontrib-devhelp.2.0.0(BSD License).txt → LICENSE_sphinxcontrib-applehelp_2_0_0_BSD_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.sphinxcontrib-htmlhelp.2.1.0(BSD License).txt → LICENSE_sphinxcontrib-devhelp_2_0_0_BSD_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.sphinxcontrib-jquery.4.1(BSD License).txt → LICENSE_sphinxcontrib-htmlhelp_2_1_0_BSD_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.sphinxcontrib-qthelp.2.0.0(BSD License).txt → LICENSE_sphinxcontrib-jquery_4_1_BSD_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.sphinxcontrib-jsmath.1.0.1(BSD License).txt → LICENSE_sphinxcontrib-jsmath_1_0_1_BSD_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.sphinxcontrib-serializinghtml.2.0.0(BSD License).txt → LICENSE_sphinxcontrib-qthelp_2_0_0_BSD_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.tokenizers.0.21.1(Apache Software License).txt → LICENSE_sphinxcontrib-serializinghtml_2_0_0_BSD_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.sse-starlette.2.3.4(BSD License).txt → LICENSE_sse-starlette_2_3_6_BSD_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.starlette.0.46.2(BSD License).txt → LICENSE_starlette_0_46_2_BSD_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.tabulate.0.9.0(MIT License).txt → LICENSE_tabulate_0_9_0_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.tiktoken.0.9.0(MIT License).txt → LICENSE_tiktoken_0_9_0_MIT_License-Copyright-c-2022_OpenAI-Shantanu_Jain-Permission_is_hereby_granted-free_of_charge-to_any_pers.txt} +0 -0
- /cmdbox/licenses/{LICENSE.tomli.2.2.1(MIT License).txt → LICENSE_tomli_2_2_1_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.tqdm.4.67.1(MIT License; Mozilla Public License 2.0 (MPL 2.0)).txt → LICENSE_tqdm_4_67_1_MIT_License-Mozilla_Public_License_2_0-MPL_2_0.txt} +0 -0
- /cmdbox/licenses/{LICENSE.twine.6.1.0(Apache Software License).txt → LICENSE_twine_6_1_0_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.typing_extensions.4.13.2(UNKNOWN).txt → LICENSE_typing_extensions_4_14_0_UNKNOWN.txt} +0 -0
- /cmdbox/licenses/{LICENSE.tzdata.2025.2(Apache Software License).txt → LICENSE_tzdata_2025_2_Apache_Software_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.tzlocal.5.3.1(MIT License).txt → LICENSE_tzlocal_5_3_1_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.uritemplate.4.1.1(Apache Software License; BSD License).txt → LICENSE_uritemplate_4_2_0_BSD_3-Clause_OR_Apache-2_0.txt} +0 -0
- /cmdbox/licenses/{LICENSE.urllib3.2.4.0(UNKNOWN).txt → LICENSE_urllib3_2_5_0_UNKNOWN.txt} +0 -0
- /cmdbox/licenses/{LICENSE.uvicorn.0.34.2(BSD License).txt → LICENSE_uvicorn_0_35_0_BSD_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.watchfiles.1.0.5(MIT License).txt → LICENSE_watchfiles_1_1_0_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.wcwidth.0.2.13(MIT License).txt → LICENSE_wcwidth_0_2_13_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.websockets.15.0.1(BSD License).txt → LICENSE_websockets_15_0_1_BSD_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.wheel.0.45.1(MIT License).txt → LICENSE_wheel_0_45_1_MIT_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.zope.event.5.0(Zope Public License).txt → LICENSE_zope_event_5_1_Zope_Public_License.txt} +0 -0
- /cmdbox/licenses/{LICENSE.zope.interface.7.2(Zope Public License).txt → LICENSE_zope_interface_7_2_Zope_Public_License.txt} +0 -0
- {cmdbox-0.6.0.4.dist-info → cmdbox-0.6.1.1.dist-info}/LICENSE +0 -0
- {cmdbox-0.6.0.4.dist-info → cmdbox-0.6.1.1.dist-info}/WHEEL +0 -0
- {cmdbox-0.6.0.4.dist-info → cmdbox-0.6.1.1.dist-info}/entry_points.txt +0 -0
- {cmdbox-0.6.0.4.dist-info → cmdbox-0.6.1.1.dist-info}/top_level.txt +0 -0
|
@@ -1,16 +1,5 @@
|
|
|
1
|
-
from cmdbox.app import common, feature
|
|
2
|
-
from cmdbox.app.auth import signin
|
|
3
|
-
from cmdbox.app.features.cli import cmdbox_cmd_list
|
|
1
|
+
from cmdbox.app import common, feature, mcp
|
|
4
2
|
from cmdbox.app.options import Options
|
|
5
|
-
from pathlib import Path
|
|
6
|
-
from typing import Any, Callable, Dict, Tuple, List
|
|
7
|
-
import argparse
|
|
8
|
-
import asyncio
|
|
9
|
-
import locale
|
|
10
|
-
import logging
|
|
11
|
-
import json
|
|
12
|
-
import re
|
|
13
|
-
import time
|
|
14
3
|
|
|
15
4
|
|
|
16
5
|
class AgentBase(feature.ResultEdgeFeature):
|
|
@@ -96,326 +85,3 @@ class AgentBase(feature.ResultEdgeFeature):
|
|
|
96
85
|
discription_ja="llmのモデルを使用するときのtemperatureを指定します。",
|
|
97
86
|
discription_en="Specifies the temperature when using llm model."),
|
|
98
87
|
])
|
|
99
|
-
|
|
100
|
-
def create_mcpserver(self, args:argparse.Namespace) -> Any:
|
|
101
|
-
"""
|
|
102
|
-
mcpserverを作成します
|
|
103
|
-
|
|
104
|
-
Args:
|
|
105
|
-
args (argparse.Namespace): 引数
|
|
106
|
-
|
|
107
|
-
Returns:
|
|
108
|
-
Any: FastMCP
|
|
109
|
-
"""
|
|
110
|
-
from fastmcp import FastMCP
|
|
111
|
-
mcp = FastMCP(name=self.ver.__appid__)
|
|
112
|
-
return mcp
|
|
113
|
-
|
|
114
|
-
def create_session_service(self, args:argparse.Namespace) -> Any:
|
|
115
|
-
"""
|
|
116
|
-
セッションサービスを作成します
|
|
117
|
-
|
|
118
|
-
Args:
|
|
119
|
-
args (argparse.Namespace): 引数
|
|
120
|
-
|
|
121
|
-
Returns:
|
|
122
|
-
BaseSessionService: セッションサービス
|
|
123
|
-
"""
|
|
124
|
-
from google.adk.events import Event
|
|
125
|
-
from google.adk.sessions import DatabaseSessionService, InMemorySessionService, session
|
|
126
|
-
from typing_extensions import override
|
|
127
|
-
if hasattr(args, 'agent_session_dburl') and args.agent_session_dburl is not None:
|
|
128
|
-
class _DatabaseSessionService(DatabaseSessionService):
|
|
129
|
-
@override
|
|
130
|
-
async def append_event(self, session: session.Session, event: Event) -> Event:
|
|
131
|
-
# 永続化されるセッションには <important> タグを含めない
|
|
132
|
-
bk_parts = event.content.parts.copy()
|
|
133
|
-
for part in event.content.parts:
|
|
134
|
-
if not part.text: continue
|
|
135
|
-
part.text = re.sub(r"<important>.*</important>", "", part.text)
|
|
136
|
-
for part in bk_parts:
|
|
137
|
-
if not part.text: continue
|
|
138
|
-
part.text = part.text.replace("<important>", "").replace("</important>", "")
|
|
139
|
-
ret = await super().append_event(session, event)
|
|
140
|
-
ret.content.parts = bk_parts
|
|
141
|
-
return ret
|
|
142
|
-
dss = _DatabaseSessionService(db_url=args.agent_session_dburl)
|
|
143
|
-
#dss.db_engine.echo = True
|
|
144
|
-
return dss
|
|
145
|
-
else:
|
|
146
|
-
return InMemorySessionService()
|
|
147
|
-
|
|
148
|
-
def create_agent(self, logger:logging.Logger, args:argparse.Namespace, tools:List[Callable]) -> Any:
|
|
149
|
-
"""
|
|
150
|
-
エージェントを作成します
|
|
151
|
-
|
|
152
|
-
Args:
|
|
153
|
-
logger (logging.Logger): ロガー
|
|
154
|
-
args (argparse.Namespace): 引数
|
|
155
|
-
tools (List[Callable]): 関数
|
|
156
|
-
|
|
157
|
-
Returns:
|
|
158
|
-
Agent: エージェント
|
|
159
|
-
"""
|
|
160
|
-
if logger.level == logging.DEBUG:
|
|
161
|
-
logger.debug(f"create_agent processing..")
|
|
162
|
-
language, _ = locale.getlocale()
|
|
163
|
-
is_japan = language.find('Japan') >= 0 or language.find('ja_JP') >= 0
|
|
164
|
-
description = f"{self.ver.__appid__}に登録されているコマンド提供"
|
|
165
|
-
instruction = f"あなたはコマンドの意味を熟知しているエキスパートです。" + \
|
|
166
|
-
f"ユーザーがコマンドを実行したいとき、あなたは以下の手順に従ってコマンドを確実に実行してください。\n" + \
|
|
167
|
-
f"1. ユーザーのクエリからが実行したいコマンドを特定します。\n" + \
|
|
168
|
-
f"2. コマンド実行に必要なパラメータのなかで、ユーザーのクエリから取得できないものは、コマンド定義にあるデフォルト値を指定して実行してください。\n" + \
|
|
169
|
-
f"3. もしエラーが発生した場合は、ユーザーにコマンド名とパラメータとエラー内容を提示してください。\n"
|
|
170
|
-
|
|
171
|
-
description = description if is_japan else \
|
|
172
|
-
f"Command offer registered in {self.ver.__appid__}."
|
|
173
|
-
instruction = instruction if is_japan else \
|
|
174
|
-
f"You are the expert who knows what the commands mean." + \
|
|
175
|
-
f"When a user wants to execute a command, you follow these steps to ensure that the command is executed.\n" + \
|
|
176
|
-
f"1. Identify the command you want to execute from the user's query.\n" + \
|
|
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" + \
|
|
178
|
-
f"3. If an error occurs, provide the user with the command name, parameters, and error description.\n"
|
|
179
|
-
|
|
180
|
-
description = args.agent_description if args.agent_description else description
|
|
181
|
-
instruction = args.agent_instruction if args.agent_instruction else instruction
|
|
182
|
-
if logger.level == logging.DEBUG:
|
|
183
|
-
logger.debug(f"google-adk loading..")
|
|
184
|
-
from google.adk.agents import Agent
|
|
185
|
-
if logger.level == logging.DEBUG:
|
|
186
|
-
logger.debug(f"litellm loading..")
|
|
187
|
-
from google.adk.models.lite_llm import LiteLlm
|
|
188
|
-
# loggerの初期化
|
|
189
|
-
common.reset_logger("LiteLLM Proxy")
|
|
190
|
-
common.reset_logger("LiteLLM Router")
|
|
191
|
-
common.reset_logger("LiteLLM")
|
|
192
|
-
if args.llmprov == 'openai':
|
|
193
|
-
if args.llmmodel is None: raise ValueError("llmmodel is required.")
|
|
194
|
-
if args.llmapikey is None: raise ValueError("llmapikey is required.")
|
|
195
|
-
agent = Agent(
|
|
196
|
-
name=args.agent_name,
|
|
197
|
-
model=LiteLlm(
|
|
198
|
-
model=args.llmmodel,
|
|
199
|
-
api_key=args.llmapikey,
|
|
200
|
-
endpoint=args.llmendpoint,
|
|
201
|
-
),
|
|
202
|
-
description=description,
|
|
203
|
-
instruction=instruction,
|
|
204
|
-
tools=tools,
|
|
205
|
-
)
|
|
206
|
-
elif args.llmprov == 'azureopenai':
|
|
207
|
-
if args.llmmodel is None: raise ValueError("llmmodel is required.")
|
|
208
|
-
if args.llmendpoint is None: raise ValueError("llmendpoint is required.")
|
|
209
|
-
if args.llmapikey is None: raise ValueError("llmapikey is required.")
|
|
210
|
-
if args.llmapiversion is None: raise ValueError("llmapiversion is required.")
|
|
211
|
-
agent = Agent(
|
|
212
|
-
name=args.agent_name,
|
|
213
|
-
model=LiteLlm(
|
|
214
|
-
model=args.llmmodel,
|
|
215
|
-
api_key=args.llmapikey,
|
|
216
|
-
endpoint=args.llmendpoint,
|
|
217
|
-
api_version=args.llmapiversion,
|
|
218
|
-
),
|
|
219
|
-
description=description,
|
|
220
|
-
instruction=instruction,
|
|
221
|
-
tools=tools,
|
|
222
|
-
)
|
|
223
|
-
elif args.llmprov == 'vertexai':
|
|
224
|
-
if args.llmmodel is None: raise ValueError("llmmodel is required.")
|
|
225
|
-
if args.llmlocation is None: raise ValueError("llmlocation is required.")
|
|
226
|
-
if args.llmsvaccountfile is not None:
|
|
227
|
-
with open(args.llmsvaccountfile, "r", encoding="utf-8") as f:
|
|
228
|
-
vertex_credentials = json.load(f)
|
|
229
|
-
elif args.llmprojectid is None: raise ValueError("llmprojectid is required.")
|
|
230
|
-
agent = Agent(
|
|
231
|
-
name=args.agent_name,
|
|
232
|
-
model=LiteLlm(
|
|
233
|
-
model=args.llmmodel,
|
|
234
|
-
#vertex_project=args.llmprojectid,
|
|
235
|
-
vertex_credentials=vertex_credentials,
|
|
236
|
-
vertex_location=args.llmlocation,
|
|
237
|
-
#seed=args.llmseed,
|
|
238
|
-
#temperature=args.llmtemperature,
|
|
239
|
-
),
|
|
240
|
-
description=description,
|
|
241
|
-
instruction=instruction,
|
|
242
|
-
tools=tools,
|
|
243
|
-
)
|
|
244
|
-
elif args.llmprov == 'ollama':
|
|
245
|
-
if args.llmmodel is None: raise ValueError("llmmodel is required.")
|
|
246
|
-
if args.llmendpoint is None: raise ValueError("llmendpoint is required.")
|
|
247
|
-
agent = Agent(
|
|
248
|
-
name=args.agent_name,
|
|
249
|
-
model=LiteLlm(
|
|
250
|
-
model=f"ollama/{args.llmmodel}",
|
|
251
|
-
api_base=args.llmendpoint,
|
|
252
|
-
temperature=args.llmtemperature,
|
|
253
|
-
stream=True
|
|
254
|
-
),
|
|
255
|
-
description=description,
|
|
256
|
-
instruction=instruction,
|
|
257
|
-
tools=tools,
|
|
258
|
-
)
|
|
259
|
-
else:
|
|
260
|
-
raise ValueError("llmprov is required.")
|
|
261
|
-
if logger.level == logging.DEBUG:
|
|
262
|
-
logger.debug(f"create_agent complate.")
|
|
263
|
-
return agent
|
|
264
|
-
|
|
265
|
-
def create_runner(self, logger:logging.Logger, args:argparse.Namespace, session_service, agent) -> Any:
|
|
266
|
-
"""
|
|
267
|
-
ランナーを作成します
|
|
268
|
-
|
|
269
|
-
Args:
|
|
270
|
-
logger (logging.Logger): ロガー
|
|
271
|
-
args (argparse.Namespace): 引数
|
|
272
|
-
session_service (BaseSessionService): セッションサービス
|
|
273
|
-
agent (Agent): エージェント
|
|
274
|
-
|
|
275
|
-
Returns:
|
|
276
|
-
Runner: ランナー
|
|
277
|
-
"""
|
|
278
|
-
from google.adk.runners import Runner
|
|
279
|
-
return Runner(
|
|
280
|
-
app_name=self.ver.__appid__,
|
|
281
|
-
agent=agent,
|
|
282
|
-
session_service=session_service,
|
|
283
|
-
)
|
|
284
|
-
|
|
285
|
-
def init_agent_runner(self, logger:logging.Logger, args:argparse.Namespace) -> Tuple[Any, Any]:
|
|
286
|
-
"""
|
|
287
|
-
エージェントの初期化を行います
|
|
288
|
-
|
|
289
|
-
Args:
|
|
290
|
-
logger (logging.Logger): ロガー
|
|
291
|
-
args (argparse.Namespace): 引数
|
|
292
|
-
|
|
293
|
-
Returns:
|
|
294
|
-
Tuple[Any, Any]: ランナーとFastMCP
|
|
295
|
-
"""
|
|
296
|
-
if logger.level == logging.DEBUG:
|
|
297
|
-
logger.debug(f"init_agent_runner processing..")
|
|
298
|
-
# loggerの初期化
|
|
299
|
-
common.reset_logger("httpx")
|
|
300
|
-
common.reset_logger("google_adk.google.adk.sessions.database_session_service")
|
|
301
|
-
common.reset_logger("mcp.server.streamable_http_manager")
|
|
302
|
-
# モジュールインポート
|
|
303
|
-
from fastmcp import FastMCP
|
|
304
|
-
from google.adk.sessions import BaseSessionService
|
|
305
|
-
mcp:FastMCP = self.create_mcpserver(args)
|
|
306
|
-
session_service:BaseSessionService = self.create_session_service(args)
|
|
307
|
-
options = Options.getInstance()
|
|
308
|
-
tools:Callable[[logging.Logger, argparse.Namespace, float, Dict], Tuple[int, Dict[str, Any], Any]] = []
|
|
309
|
-
|
|
310
|
-
def _ds(d:str) -> str:
|
|
311
|
-
return f'"{d}"' if d is not None else 'None'
|
|
312
|
-
def _t2s(o:Dict[str, Any], req=True) -> str:
|
|
313
|
-
t, m, d, r = o["type"], o["multi"], o["default"], o["required"]
|
|
314
|
-
if t == Options.T_BOOL: return ("List[bool]=[]" if m else f"bool={d}") if req else ("List[bool]" if m else f"bool")
|
|
315
|
-
if t == Options.T_DATE: return ("List[str]=[]" if m else f"str={_ds(d)}") if req else ("List[str]" if m else f"str")
|
|
316
|
-
if t == Options.T_DATETIME: return ("List[str]=[]" if m else f"str={_ds(d)}") if req else ("List[str]" if m else f"str")
|
|
317
|
-
if t == Options.T_DICT: return ("List[dict]=[]" if m else f"dict={d}") if req else ("List[dict]" if m else f"dict")
|
|
318
|
-
if t == Options.T_DIR or t == Options.T_FILE:
|
|
319
|
-
if d is not None: d = str(d).replace('\\', '/')
|
|
320
|
-
return ("List[str]=[]" if m else f"str={_ds(d)}") if req else ("List[str]" if m else f"str")
|
|
321
|
-
if t == Options.T_FLOAT: return ("List[float]=[]" if m else f"float={d}") if req else ("List[float]" if m else f"float")
|
|
322
|
-
if t == Options.T_INT: return ("List[int]=[]" if m else f"int={d}") if req else ("List[int]" if m else f"int")
|
|
323
|
-
if t == Options.T_STR: return ("List[str]=[]" if m else f"str={_ds(d)}") if req else ("List[str]" if m else f"str")
|
|
324
|
-
if t == Options.T_TEXT: return ("List[str]=[]" if m else f"str={_ds(d)}") if req else ("List[str]" if m else f"str")
|
|
325
|
-
raise ValueError(f"Unknown type: {t} for option {o['opt']}")
|
|
326
|
-
def _arg(o:Dict[str, Any], is_japan) -> str:
|
|
327
|
-
t, d = o["type"], o["default"]
|
|
328
|
-
s = f' {o["opt"]}:'
|
|
329
|
-
if t == Options.T_DIR or t == Options.T_FILE:
|
|
330
|
-
d = str(d).replace("\\", "/")
|
|
331
|
-
s += f'Optional[{_t2s(o, False)}]={d}:'
|
|
332
|
-
s += f'{o["discription_ja"] if is_japan else o["discription_en"]}'
|
|
333
|
-
return s
|
|
334
|
-
def _coercion(a:argparse.Namespace, key:str, dval) -> str:
|
|
335
|
-
dval = f'opt["{key}"] if "{key}" in opt else ' + f'"{dval}"' if isinstance(dval, str) else dval
|
|
336
|
-
aval = args.__dict__[key] if hasattr(args, key) and args.__dict__[key] else None
|
|
337
|
-
aval = f'"{aval}"' if isinstance(aval, str) else aval
|
|
338
|
-
ret = f'opt["{key}"] = {aval}' if aval is not None else f'opt["{key}"] = {dval}'
|
|
339
|
-
return ret
|
|
340
|
-
language, _ = locale.getlocale()
|
|
341
|
-
is_japan = language.find('Japan') >= 0 or language.find('ja_JP') >= 0
|
|
342
|
-
for mode in options.get_mode_keys():
|
|
343
|
-
for cmd in options.get_cmd_keys(mode):
|
|
344
|
-
if not options.get_cmd_attr(mode, cmd, 'use_agent'):
|
|
345
|
-
continue
|
|
346
|
-
discription = options.get_cmd_attr(mode, cmd, 'discription_ja' if is_japan else 'discription_en')
|
|
347
|
-
choices = options.get_cmd_choices(mode, cmd, False)
|
|
348
|
-
if len([opt for opt in choices if 'opt' in opt and opt['opt'] == 'signin_file']) <= 0:
|
|
349
|
-
choices.append(dict(opt="signin_file", type=Options.T_FILE, default=f'.{self.ver.__appid__}/user_list.yml', required=True, multi=False, hide=True, choice=None,
|
|
350
|
-
discription_ja="サインイン可能なユーザーとパスワードを記載したファイルを指定します。省略した時は認証を要求しません。",
|
|
351
|
-
discription_en="Specify a file containing users and passwords with which they can signin. If omitted, no authentication is required."),)
|
|
352
|
-
fn = f"{mode}_{cmd}"
|
|
353
|
-
func_txt = f'def {fn}(' + ", ".join([f'{o["opt"]}:{_t2s(o, False)}' for o in choices]) + '):\n'
|
|
354
|
-
func_txt += f' """\n'
|
|
355
|
-
func_txt += f' {discription}\n'
|
|
356
|
-
func_txt += f' Args:\n'
|
|
357
|
-
func_txt += "\n".join([_arg(o, is_japan) for o in choices])
|
|
358
|
-
func_txt += f'\n'
|
|
359
|
-
func_txt += f' Returns:\n'
|
|
360
|
-
func_txt += f' Dict[str, Any]:{"処理結果" if is_japan else "Processing Result"}\n'
|
|
361
|
-
func_txt += f' """\n'
|
|
362
|
-
func_txt += f' scope = signin.get_request_scope()\n'
|
|
363
|
-
func_txt += f' logger = common.default_logger()\n'
|
|
364
|
-
func_txt += f' opt = dict()\n'
|
|
365
|
-
func_txt += f' opt["mode"] = "{mode}"\n'
|
|
366
|
-
func_txt += f' opt["cmd"] = "{cmd}"\n'
|
|
367
|
-
func_txt += f' opt["data"] = opt["data"] if hasattr(opt, "data") else common.HOME_DIR / ".{self.ver.__appid__}"\n'
|
|
368
|
-
func_txt += f' opt["format"] = False\n'
|
|
369
|
-
func_txt += f' opt["output_json"] = None\n'
|
|
370
|
-
func_txt += f' opt["output_json_append"] = False\n'
|
|
371
|
-
func_txt += f' opt["debug"] = logger.level == logging.DEBUG\n'
|
|
372
|
-
func_txt += '\n'.join([f' opt["{o["opt"]}"] = {o["opt"]}' for o in choices])+'\n'
|
|
373
|
-
func_txt += f' {_coercion(args, "host", self.default_host)}\n'
|
|
374
|
-
func_txt += f' {_coercion(args, "port", self.default_port)}\n'
|
|
375
|
-
func_txt += f' {_coercion(args, "password", self.default_pass)}\n'
|
|
376
|
-
func_txt += f' {_coercion(args, "svname", self.default_svname)}\n'
|
|
377
|
-
func_txt += f' {_coercion(args, "retry_count", 3)}\n'
|
|
378
|
-
func_txt += f' {_coercion(args, "retry_interval", 3)}\n'
|
|
379
|
-
func_txt += f' {_coercion(args, "timeout", 15)}\n'
|
|
380
|
-
func_txt += f' {_coercion(args, "output_json", None)}\n'
|
|
381
|
-
func_txt += f' {_coercion(args, "output_json_append", False)}\n'
|
|
382
|
-
func_txt += f' {_coercion(args, "stdout_log", False)}\n'
|
|
383
|
-
func_txt += f' {_coercion(args, "capture_stdout", False)}\n'
|
|
384
|
-
func_txt += f' {_coercion(args, "capture_maxsize", 1024*1024)}\n'
|
|
385
|
-
func_txt += f' {_coercion(args, "tag", None)}\n'
|
|
386
|
-
func_txt += f' {_coercion(args, "clmsg_id", None)}\n'
|
|
387
|
-
func_txt += f' opt["signin_file"] = signin_file if signin_file else ".{self.ver.__appid__}/user_list.yml"\n'
|
|
388
|
-
func_txt += f' args = argparse.Namespace(**opt)\n'
|
|
389
|
-
func_txt += f' signin_data = signin.Signin.load_signin_file(args.signin_file)\n'
|
|
390
|
-
func_txt += f' req = scope["req"] if scope["req"] is not None else scope["websocket"]\n'
|
|
391
|
-
func_txt += f' sign = signin.Signin._check_signin(req, scope["res"], signin_data, logger)\n'
|
|
392
|
-
func_txt += f' if sign is not None:\n'
|
|
393
|
-
func_txt += f' logger.warning("Unable to execute command because authentication information cannot be obtained")\n'
|
|
394
|
-
func_txt += f' return dict(warn="Unable to execute command because authentication information cannot be obtained")\n'
|
|
395
|
-
func_txt += f' groups = req.session["signin"]["groups"]\n'
|
|
396
|
-
func_txt += f' logger.info("Call agent tool `{mode}_{cmd}`:user="+str(req.session["signin"]["name"])+" groups="+str(groups)+" args="+str(args))\n'
|
|
397
|
-
func_txt += f' if not signin.Signin._check_cmd(signin_data, groups, "{mode}", "{cmd}", logger):\n'
|
|
398
|
-
func_txt += f' logger.warning("You do not have permission to execute this command.")\n'
|
|
399
|
-
func_txt += f' return dict(warn="You do not have permission to execute this command.")\n'
|
|
400
|
-
func_txt += f' feat = Options.getInstance().get_cmd_attr("{mode}", "{cmd}", "feature")\n'
|
|
401
|
-
func_txt += f' try:\n'
|
|
402
|
-
func_txt += f' st, ret, _ = feat.apprun(logger, args, time.perf_counter(), [])\n'
|
|
403
|
-
func_txt += f' return ret\n'
|
|
404
|
-
func_txt += f' except Exception as e:\n'
|
|
405
|
-
func_txt += f' logger.error("Error occurs when tool is executed:", exc_info=True)\n'
|
|
406
|
-
func_txt += f' raise e\n'
|
|
407
|
-
func_txt += f'tools.append({fn})\n'
|
|
408
|
-
if logger.level == logging.DEBUG:
|
|
409
|
-
logger.debug(f"generating agent tool: {fn}")
|
|
410
|
-
|
|
411
|
-
exec(func_txt,
|
|
412
|
-
dict(time=time,List=List, argparse=argparse, common=common, Options=Options, logging=logging, signin=signin,),
|
|
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))
|
|
417
|
-
root_agent = self.create_agent(logger, args, tools)
|
|
418
|
-
runner = self.create_runner(logger, args, session_service, root_agent)
|
|
419
|
-
if logger.level == logging.DEBUG:
|
|
420
|
-
logger.debug(f"init_agent_runner complate.")
|
|
421
|
-
return runner, mcp
|
|
@@ -210,8 +210,6 @@ class AuditSearch(audit_base.AuditBase):
|
|
|
210
210
|
ret = buf.getvalue()
|
|
211
211
|
ret = ret.replace('\r\n', '\n') if ret is not None else ''
|
|
212
212
|
|
|
213
|
-
common.print_format(ret, getattr(args, 'format', False), tm, None, False, pf=pf)
|
|
214
|
-
|
|
215
213
|
return 0, ret, cl
|
|
216
214
|
|
|
217
215
|
def is_cluster_redirect(self):
|
|
@@ -41,6 +41,9 @@ class AuditWrite(audit_base.AuditBase):
|
|
|
41
41
|
opt['discription_ja'] = "監査を記録します。"
|
|
42
42
|
opt['discription_en'] = "Record the audit."
|
|
43
43
|
opt['choice'] += [
|
|
44
|
+
dict(opt="client_only", type=Options.T_BOOL, default=False, required=False, multi=False, hide=True, choice=[True, False],
|
|
45
|
+
discription_ja="サーバーへの接続を行わないようにします。",
|
|
46
|
+
discription_en="Do not make connections to the server."),
|
|
44
47
|
dict(opt="audit_type", type=Options.T_STR, default=None, required=True, multi=False, hide=False, choice=Options.AUDITS,
|
|
45
48
|
discription_ja="監査の種類を指定します。",
|
|
46
49
|
discription_en="Specifies the audit type."),
|
|
@@ -105,6 +108,12 @@ class AuditWrite(audit_base.AuditBase):
|
|
|
105
108
|
args.clmsg_id = str(uuid.uuid4())
|
|
106
109
|
if args.clmsg_date is None:
|
|
107
110
|
args.clmsg_date = datetime.now().strftime('%Y-%m-%d %H:%M:%S') + common.get_tzoffset_str()
|
|
111
|
+
if hasattr(args, 'client_only') and args.client_only==True:
|
|
112
|
+
# クライアントのみの場合は、サーバーへの接続を行わない
|
|
113
|
+
logger.warning(f"client_only is True. Not connecting to server. Skip writing the audit log.")
|
|
114
|
+
ret = dict(success={k:v for k, v in vars(args).items() if v})
|
|
115
|
+
common.print_format(ret, False, tm, args.output_json, args.output_json_append, pf=pf)
|
|
116
|
+
return 0, ret, None
|
|
108
117
|
|
|
109
118
|
audit_type_b64 = convert.str2b64str(args.audit_type)
|
|
110
119
|
clmsg_id_b64 = convert.str2b64str(args.clmsg_id)
|
|
@@ -90,7 +90,7 @@ class CmdList(feature.OneshotResultEdgeFeature):
|
|
|
90
90
|
if kwd is None or kwd == '':
|
|
91
91
|
kwd = '*'
|
|
92
92
|
if not hasattr(self, 'signin_file_data') or self.signin_file_data is None:
|
|
93
|
-
self.signin_file_data = signin.Signin.load_signin_file(args.signin_file, None)
|
|
93
|
+
self.signin_file_data = signin.Signin.load_signin_file(args.signin_file, None, self=self)
|
|
94
94
|
paths = glob.glob(str(Path(args.data) / ".cmds" / f"cmd-{kwd}.json"))
|
|
95
95
|
ret = [common.loadopt(path, True) for path in paths]
|
|
96
96
|
ret = sorted(ret, key=lambda cmd: cmd["title"])
|
|
@@ -91,7 +91,7 @@ class CmdLoad(feature.OneshotResultEdgeFeature):
|
|
|
91
91
|
common.print_format(msg, args.format, tm, args.output_json, args.output_json_append, pf=pf)
|
|
92
92
|
return 1, msg, None
|
|
93
93
|
if not hasattr(self, 'signin_file_data') or self.signin_file_data is None:
|
|
94
|
-
self.signin_file_data = signin.Signin.load_signin_file(args.signin_file, None)
|
|
94
|
+
self.signin_file_data = signin.Signin.load_signin_file(args.signin_file, None, self=self)
|
|
95
95
|
opt_path = Path(args.data) / ".cmds" / f"cmd-{args.title}.json"
|
|
96
96
|
opt = common.loadopt(opt_path, True)
|
|
97
97
|
ret = dict(success=opt)
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
from cmdbox.app import common, feature
|
|
2
|
+
from cmdbox.app.features.cli import cmdbox_web_start
|
|
3
|
+
from cmdbox.app.options import Options
|
|
4
|
+
from typing import Dict, Any, Tuple, List, Union
|
|
5
|
+
import argparse
|
|
6
|
+
import logging
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class McpStart(feature.UnsupportEdgeFeature):
|
|
10
|
+
def get_mode(self) -> Union[str, List[str]]:
|
|
11
|
+
"""
|
|
12
|
+
この機能のモードを返します
|
|
13
|
+
|
|
14
|
+
Returns:
|
|
15
|
+
Union[str, List[str]]: モード
|
|
16
|
+
"""
|
|
17
|
+
return 'mcp'
|
|
18
|
+
|
|
19
|
+
def get_cmd(self) -> str:
|
|
20
|
+
"""
|
|
21
|
+
この機能のコマンドを返します
|
|
22
|
+
|
|
23
|
+
Returns:
|
|
24
|
+
str: コマンド
|
|
25
|
+
"""
|
|
26
|
+
return 'proxy'
|
|
27
|
+
|
|
28
|
+
def get_option(self):
|
|
29
|
+
"""
|
|
30
|
+
この機能のオプションを返します
|
|
31
|
+
|
|
32
|
+
Returns:
|
|
33
|
+
Dict[str, Any]: オプション
|
|
34
|
+
"""
|
|
35
|
+
return dict(
|
|
36
|
+
use_redis=self.USE_REDIS_FALSE, nouse_webmode=False, use_agent=False,
|
|
37
|
+
discription_ja="標準入力を受け付け、リモートMCPサーバーにリクエストを行うProxyサーバーを起動します。",
|
|
38
|
+
discription_en="-",
|
|
39
|
+
choice=[
|
|
40
|
+
dict(opt="mcpserver_name", type=Options.T_STR, default='mcpserver', required=True, multi=False, hide=False, choice=None,
|
|
41
|
+
discription_ja="リモートMCPサーバーの名前を指定します。省略した場合は`mcpserver`となります。",
|
|
42
|
+
discription_en="Specify the name of the MCP server. If omitted, it will be `mcpserver`.",),
|
|
43
|
+
dict(opt="mcpserver_url", type=Options.T_STR, default='http://localhost:8081/mcpsv/mcp', required=True, multi=False, hide=False, choice=None,
|
|
44
|
+
discription_ja="リモートMCPサーバーのURLを指定します。省略した場合は`http://localhost:8081/mcpsv/mcp`となります。",
|
|
45
|
+
discription_en="Specifies the URL of the remote MCP server. If omitted, it will be `http://localhost:8081/mcpsv/mcp`.",),
|
|
46
|
+
dict(opt="mcpserver_transport", type=Options.T_STR, default='streamable-http', required=True, multi=False, hide=False, choice=['', 'streamable-http', 'sse', 'http'],
|
|
47
|
+
discription_ja="リモートMCPサーバーのトランスポートを指定します。省略した場合は`streamable-http`となります。",
|
|
48
|
+
discription_en="Specifies the transport of the remote MCP server. If omitted, it is `streamable-http`.",),
|
|
49
|
+
dict(opt="mcpserver_transport", type=Options.T_STR, default='streamable-http', required=True, multi=False, hide=False, choice=['', 'streamable-http', 'sse', 'http'],
|
|
50
|
+
discription_ja="リモートMCPサーバーのトランスポートを指定します。省略した場合は`streamable-http`となります。",
|
|
51
|
+
discription_en="Specifies the transport of the remote MCP server. If omitted, it is `streamable-http`.",),
|
|
52
|
+
])
|
|
53
|
+
|
|
54
|
+
def apprun(self, logger:logging.Logger, args:argparse.Namespace, tm:float, pf:List[Dict[str, float]]=[]) -> Tuple[int, Dict[str, Any], Any]:
|
|
55
|
+
"""
|
|
56
|
+
この機能の実行を行います
|
|
57
|
+
|
|
58
|
+
Args:
|
|
59
|
+
logger (logging.Logger): ロガー
|
|
60
|
+
args (argparse.Namespace): 引数
|
|
61
|
+
tm (float): 実行開始時間
|
|
62
|
+
pf (List[Dict[str, float]]): 呼出元のパフォーマンス情報
|
|
63
|
+
|
|
64
|
+
Returns:
|
|
65
|
+
Tuple[int, Dict[str, Any], Any]: 終了コード, 結果, オブジェクト
|
|
66
|
+
"""
|
|
67
|
+
if not hasattr(args, 'mcpserver_name'):
|
|
68
|
+
args.mcpserver_name = 'mcpserver'
|
|
69
|
+
if not hasattr(args, 'mcpserver_url'):
|
|
70
|
+
args.mcpserver_url = 'http://localhost:8081/mcpsv/mcp'
|
|
71
|
+
if not hasattr(args, 'mcpserver_transport'):
|
|
72
|
+
args.mcpserver_transport = 'streamable-http'
|
|
73
|
+
|
|
74
|
+
from fastmcp import FastMCP
|
|
75
|
+
config = dict(
|
|
76
|
+
mcpServers=dict(
|
|
77
|
+
default=dict(
|
|
78
|
+
url=args.mcpserver_url,
|
|
79
|
+
transport=args.mcpserver_transport,
|
|
80
|
+
)
|
|
81
|
+
)
|
|
82
|
+
)
|
|
83
|
+
try:
|
|
84
|
+
common.reset_logger('FastMCP.fastmcp.server.server')
|
|
85
|
+
proxy = FastMCP.as_proxy(config, name="Config-Based Proxy")
|
|
86
|
+
proxy.run()
|
|
87
|
+
except Exception as e:
|
|
88
|
+
logger.error(f"Failed to start MCP proxy: {e}", exc_info=True)
|
|
89
|
+
return self.RESP_ERROR, dict(warn=f"Failed to start MCP proxy: {e}"), None
|
|
90
|
+
return self.RESP_SCCESS, dict(info="MCP proxy successfully."), None
|
|
@@ -51,6 +51,12 @@ class WebGencert(feature.UnsupportEdgeFeature):
|
|
|
51
51
|
dict(opt="output_cert_format", type=Options.T_STR, default="PEM", required=False, multi=False, hide=False, choice=["DER", "PEM"],
|
|
52
52
|
discription_ja="出力する自己署名証明書のファイルフォーマットを指定します。",
|
|
53
53
|
discription_en="Specifies the file format of the self-signed certificate to be output."),
|
|
54
|
+
dict(opt="output_pkey", type=Options.T_FILE, default=None, required=False, multi=False, hide=False, choice=None,
|
|
55
|
+
discription_ja="出力する自己署名証明書の公開鍵のファイルを指定します。省略した場合は `webhostオプションに指定したホスト名` .pkey に出力されます。",
|
|
56
|
+
discription_en="Specifies the public key file of the self-signed certificate to output. If omitted, the output will be in the `hostname specified in the `webhost option` .pkey."),
|
|
57
|
+
dict(opt="output_pkey_format", type=Options.T_STR, default="PEM", required=False, multi=False, hide=False, choice=["DER", "PEM"],
|
|
58
|
+
discription_ja="出力する自己署名証明書の公開鍵のファイルフォーマットを指定します。",
|
|
59
|
+
discription_en="Specifies the file format of the public key of the self-signed certificate to be output."),
|
|
54
60
|
dict(opt="output_key", type=Options.T_FILE, default=None, required=False, multi=False, hide=False, choice=None,
|
|
55
61
|
discription_ja="出力する自己署名証明書の秘密鍵ファイルを指定します。省略した場合は `webhostオプションに指定したホスト名` .key に出力されます。",
|
|
56
62
|
discription_en="Specifies the private key file of the self-signed certificate to be output.If omitted, the hostname specified in the `webhost option` .key will be output."),
|
|
@@ -91,22 +97,32 @@ class WebGencert(feature.UnsupportEdgeFeature):
|
|
|
91
97
|
return 1, msg, None
|
|
92
98
|
if args.output_cert is None:
|
|
93
99
|
args.output_cert = f"{args.webhost}.crt"
|
|
100
|
+
if args.output_pkey is None:
|
|
101
|
+
args.output_pkey = f"{args.webhost}.pkey"
|
|
94
102
|
if args.output_key is None:
|
|
95
103
|
args.output_key = f"{args.webhost}.key"
|
|
96
104
|
output_cert = Path(args.output_cert)
|
|
105
|
+
output_pkey = Path(args.output_pkey)
|
|
97
106
|
output_key = Path(args.output_key)
|
|
98
107
|
if not args.overwrite and output_cert.exists():
|
|
99
108
|
msg = dict(warn=f"File already exists. {output_cert}")
|
|
100
109
|
common.print_format(msg, args.format, tm, args.output_json, args.output_json_append, pf=pf)
|
|
101
110
|
return 1, msg, None
|
|
111
|
+
if not args.overwrite and output_pkey.exists():
|
|
112
|
+
msg = dict(warn=f"File already exists. {output_pkey}")
|
|
113
|
+
common.print_format(msg, args.format, tm, args.output_json, args.output_json_append, pf=pf)
|
|
114
|
+
return 1, msg, None
|
|
102
115
|
if not args.overwrite and output_key.exists():
|
|
103
116
|
msg = dict(warn=f"File already exists. {output_key}")
|
|
104
117
|
common.print_format(msg, args.format, tm, args.output_json, args.output_json_append, pf=pf)
|
|
105
118
|
return 1, msg, None
|
|
106
119
|
|
|
107
120
|
try:
|
|
108
|
-
self.gen_cert(logger, args.webhost,
|
|
109
|
-
|
|
121
|
+
self.gen_cert(logger, args.webhost,
|
|
122
|
+
output_cert, args.output_cert_format,
|
|
123
|
+
output_pkey, args.output_pkey_format,
|
|
124
|
+
output_key, args.output_key_format)
|
|
125
|
+
ret = dict(success=f"Generate certificate. {output_cert}, {output_pkey}, {output_key}")
|
|
110
126
|
except Exception as e:
|
|
111
127
|
msg = dict(error=f"Failed to generate certificate. {e}")
|
|
112
128
|
common.print_format(msg, args.format, tm, args.output_json, args.output_json_append, pf=pf)
|
|
@@ -115,6 +131,7 @@ class WebGencert(feature.UnsupportEdgeFeature):
|
|
|
115
131
|
|
|
116
132
|
def gen_cert(self, logger:logging.Logger, webhost:str,
|
|
117
133
|
output_cert:Path, output_cert_format:str,
|
|
134
|
+
output_pkey:Path, output_pkey_format:str,
|
|
118
135
|
output_key:Path, output_key_format:str) -> None:
|
|
119
136
|
# 秘密鍵の作成
|
|
120
137
|
private_key = rsa.generate_private_key(public_exponent=65537, key_size=2048)
|
|
@@ -151,6 +168,12 @@ class WebGencert(feature.UnsupportEdgeFeature):
|
|
|
151
168
|
critical=False,
|
|
152
169
|
).sign(private_key, hashes.SHA256())
|
|
153
170
|
|
|
171
|
+
# 自己署名証明書の公開鍵の保存
|
|
172
|
+
with open(output_pkey, "wb") as f:
|
|
173
|
+
f.write(self_cert.public_key().public_bytes(serialization.Encoding.DER if output_pkey_format == "DER" else serialization.Encoding.PEM,
|
|
174
|
+
format=serialization.PublicFormat.SubjectPublicKeyInfo))
|
|
175
|
+
logger.info(f"Save self-signed public key. {output_pkey}")
|
|
176
|
+
|
|
154
177
|
# 自己署名証明書の保存
|
|
155
178
|
with open(output_cert, "wb") as f:
|
|
156
179
|
f.write(self_cert.public_bytes(serialization.Encoding.DER if output_cert_format == "DER" else serialization.Encoding.PEM))
|
|
@@ -204,13 +204,16 @@ class WebStart(feature.UnsupportEdgeFeature, agent_base.AgentBase):
|
|
|
204
204
|
"""
|
|
205
205
|
logger.info(f"Agent={args.agent}")
|
|
206
206
|
if args.agent=='use':
|
|
207
|
+
if not hasattr(self, 'mcp'):
|
|
208
|
+
from cmdbox.app import mcp
|
|
209
|
+
self.mcp = mcp.Mcp(logger, args.data, w.signin, self.appcls, self.ver)
|
|
207
210
|
if args.agent_session_store == 'sqlite':
|
|
208
|
-
args.agent_session_dburl = "sqlite
|
|
211
|
+
args.agent_session_dburl = "sqlite:" + pathname2url(str(w.agent_path / 'session.db'))
|
|
209
212
|
elif args.agent_session_store == 'postgresql':
|
|
210
213
|
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
214
|
else:
|
|
212
215
|
args.agent_session_dburl = None
|
|
213
|
-
return self.init_agent_runner(logger, args)
|
|
216
|
+
return self.mcp.init_agent_runner(logger, args)
|
|
214
217
|
return None, None
|
|
215
218
|
|
|
216
219
|
def start(self, w:web.Web, agent_runner, mcp, logger:logging.Logger, args:argparse.Namespace) -> None:
|
|
@@ -16,7 +16,7 @@ class Signin(feature.WebFeature):
|
|
|
16
16
|
web (Web): Webオブジェクト
|
|
17
17
|
app (FastAPI): FastAPIオブジェクト
|
|
18
18
|
"""
|
|
19
|
-
web.signin.signin_file_data = web.signin.load_signin_file(web.signin_file, web.signin.get_data())
|
|
19
|
+
web.signin.signin_file_data = web.signin.load_signin_file(web.signin_file, web.signin.get_data(), self=self)
|
|
20
20
|
if web.signin_html is not None:
|
|
21
21
|
if not web.signin_html.is_file():
|
|
22
22
|
raise HTTPException(status_code=500, detail=f'signin_html is not found. ({web.signin_html})')
|