hyf

Context-aware query service for Radroots
git clone https://radroots.dev/git/hyf.git
Log | Files | Refs | README | LICENSE

commit d42fcda80966df1031bcd18f8587ead58ddb427f
parent 742de92125d8f7479e384f4bcc48189b1b2d01b0
Author: triesap <tyson@radroots.org>
Date:   Sun, 14 Jun 2026 14:58:19 -0700

build: prune deferred provider dependencies

- remove inactive provider and assist bridge source

- drop envo and tempo from the Pixi dependency graph

- keep the active stdio surface on git-pinned json and morph packages

Diffstat:
Mpixi.lock | 230-------------------------------------------------------------------------------
Mpixi.toml | 2--
Dsrc/hyf_assist/bridge.mojo | 462-------------------------------------------------------------------------------
Msrc/hyf_assist/contract.mojo | 20--------------------
Dsrc/hyf_provider/__init__.mojo | 1-
Dsrc/hyf_provider/client.mojo | 21---------------------
Dsrc/hyf_provider/config.mojo | 40----------------------------------------
Dsrc/hyf_provider/health.mojo | 31-------------------------------
Dsrc/hyf_provider/max_local.mojo | 56--------------------------------------------------------
Dsrc/hyf_provider/result.mojo | 120-------------------------------------------------------------------------------
Dsrc/hyf_provider/schema.mojo | 129-------------------------------------------------------------------------------
11 files changed, 0 insertions(+), 1112 deletions(-)

diff --git a/pixi.lock b/pixi.lock @@ -61,10 +61,8 @@ environments: - conda: https://conda.modular.com/max-nightly/linux-64/mojo-compiler-1.0.0b1-release.conda - conda: https://conda.modular.com/max-nightly/noarch/mblack-26.3.0-release.conda - conda: https://conda.modular.com/max-nightly/noarch/mojo-python-1.0.0b1-release.conda - - conda_source: envo[19b7a3fd] @ git+https://github.com/triesap/mojo_envo?rev=50e1a62ef333862427d32e63098e782816475549#50e1a62ef333862427d32e63098e782816475549 - conda_source: json[9dd23c1f] @ git+https://github.com/triesap/mojo_json?rev=56025d73631054d7803143fa5e68c5de578e33f5#56025d73631054d7803143fa5e68c5de578e33f5 - conda_source: morph[39ce1c7e] @ git+https://github.com/triesap/mojo_morph?rev=ea73f909990f3d3f5d12b786fec2f09e1e09f462#ea73f909990f3d3f5d12b786fec2f09e1e09f462 - - conda_source: tempo[8d2678e8] @ git+https://github.com/triesap/mojo_tempo?rev=4a4b9f051286f2ef24cb0c8b0614f7ac7314e4bd#4a4b9f051286f2ef24cb0c8b0614f7ac7314e4bd osx-arm64: - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.2.25-hbd8a1cb_0.conda @@ -111,10 +109,8 @@ environments: - conda: https://conda.modular.com/max-nightly/noarch/mojo-python-1.0.0b1-release.conda - conda: https://conda.modular.com/max-nightly/osx-arm64/mojo-1.0.0b1-release.conda - conda: https://conda.modular.com/max-nightly/osx-arm64/mojo-compiler-1.0.0b1-release.conda - - conda_source: envo[25995647] @ git+https://github.com/triesap/mojo_envo?rev=50e1a62ef333862427d32e63098e782816475549#50e1a62ef333862427d32e63098e782816475549 - conda_source: json[1efb775d] @ git+https://github.com/triesap/mojo_json?rev=56025d73631054d7803143fa5e68c5de578e33f5#56025d73631054d7803143fa5e68c5de578e33f5 - conda_source: morph[70142729] @ git+https://github.com/triesap/mojo_morph?rev=ea73f909990f3d3f5d12b786fec2f09e1e09f462#ea73f909990f3d3f5d12b786fec2f09e1e09f462 - - conda_source: tempo[8f0a7ebb] @ git+https://github.com/triesap/mojo_tempo?rev=4a4b9f051286f2ef24cb0c8b0614f7ac7314e4bd#4a4b9f051286f2ef24cb0c8b0614f7ac7314e4bd packages: - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda build_number: 20 @@ -1816,119 +1812,6 @@ packages: run_exports: {} size: 67503416 timestamp: 1777596016502 -- conda_source: envo[19b7a3fd] @ git+https://github.com/triesap/mojo_envo?rev=50e1a62ef333862427d32e63098e782816475549#50e1a62ef333862427d32e63098e782816475549 - version: 0.1.2 - build: hb0f4dca_0 - subdir: linux-64 - variants: - target_platform: linux-64 - depends: - - mojo ==1.0.0b1 - license: MIT - host_packages: - - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.1-hecca717_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_19.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_19.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.22-h280c20c_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.2-h0c1763c_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_19.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42.1-h5347b49_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.3-h35e630c_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.14.6-habeac84_100_cp314.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.1.0-py312hda471dd_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.7-py314h5bd0f2a_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h09e67af_11.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.5.20-hbd8a1cb_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/click-8.4.1-pyhc90fa1f_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.6-py314hd8ed1ab_100.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-9.0.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.3-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyhc90fa1f_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.1.0-pyha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.1.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.10.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.14.6-h4df99d1_100.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.15.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-4.1.0-pyhcf101f3_0.conda - - conda: https://conda.modular.com/max-nightly/linux-64/mojo-1.0.0b1-release.conda - - conda: https://conda.modular.com/max-nightly/linux-64/mojo-compiler-1.0.0b1-release.conda - - conda: https://conda.modular.com/max-nightly/noarch/mblack-26.3.0-release.conda - - conda: https://conda.modular.com/max-nightly/noarch/mojo-python-1.0.0b1-release.conda -- conda_source: envo[25995647] @ git+https://github.com/triesap/mojo_envo?rev=50e1a62ef333862427d32e63098e782816475549#50e1a62ef333862427d32e63098e782816475549 - version: 0.1.2 - build: h60d57d3_0 - subdir: osx-arm64 - variants: - target_platform: osx-arm64 - depends: - - mojo ==1.0.0b1 - license: MIT - host_packages: - - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.5.20-hbd8a1cb_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/click-8.4.1-pyhc90fa1f_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.6-py314hd8ed1ab_100.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-9.0.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.3-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyhc90fa1f_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.1.0-pyha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.1.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.10.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.14.6-h4df99d1_100.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.15.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-4.1.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.3-hef89b57_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/krb5-1.22.2-h385eeb1_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-22.1.7-h55c6f16_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libedit-3.1.20250104-pl5321hafb1f1b_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.8.1-hf6b4638_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.3-h8088a28_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h84a0fba_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsodium-1.0.22-h1a92334_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.53.2-h1ae2325_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.2-h8088a28_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.6-h1d4f5a5_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.3-hd24854e_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.14.6-h156bc91_100_cp314.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyzmq-27.1.0-py312h022ad19_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h010d191_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.5.7-py314h6c2aa35_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zeromq-4.3.5-h10816f8_11.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda - - conda: https://conda.modular.com/max-nightly/noarch/mblack-26.3.0-release.conda - - conda: https://conda.modular.com/max-nightly/noarch/mojo-python-1.0.0b1-release.conda - - conda: https://conda.modular.com/max-nightly/osx-arm64/mojo-1.0.0b1-release.conda - - conda: https://conda.modular.com/max-nightly/osx-arm64/mojo-compiler-1.0.0b1-release.conda - conda_source: json[1efb775d] @ git+https://github.com/triesap/mojo_json?rev=56025d73631054d7803143fa5e68c5de578e33f5#56025d73631054d7803143fa5e68c5de578e33f5 version: 0.2.0 build: h60d57d3_0 @@ -2132,116 +2015,3 @@ packages: - conda: https://conda.modular.com/max-nightly/noarch/mojo-python-1.0.0b1-release.conda - conda: https://conda.modular.com/max-nightly/osx-arm64/mojo-1.0.0b1-release.conda - conda: https://conda.modular.com/max-nightly/osx-arm64/mojo-compiler-1.0.0b1-release.conda -- conda_source: tempo[8d2678e8] @ git+https://github.com/triesap/mojo_tempo?rev=4a4b9f051286f2ef24cb0c8b0614f7ac7314e4bd#4a4b9f051286f2ef24cb0c8b0614f7ac7314e4bd - version: 0.1.2 - build: hb0f4dca_0 - subdir: linux-64 - variants: - target_platform: linux-64 - depends: - - mojo ==1.0.0b1 - license: MIT - host_packages: - - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-20_gnu.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hda65f42_9.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.3-hb9d3cd8_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.22.2-ha1258a1_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.45.1-default_hbd61a6d_102.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20250104-pl5321h7949ede_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.8.1-hecca717_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.5.2-h3435931_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-15.2.0-he0feb66_19.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-15.2.0-he0feb66_19.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/liblzma-5.8.3-hb03c661_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libmpdec-4.0.0-hb03c661_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.22-h280c20c_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.53.2-h0c1763c_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-15.2.0-h934c35e_19.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.42.1-h5347b49_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.2-h25fd6f3_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.6-hdb14827_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.6.3-h35e630c_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.14.6-habeac84_100_cp314.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/pyzmq-27.1.0-py312hda471dd_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.3-h853b02a_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h366c992_103.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.5.7-py314h5bd0f2a_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h09e67af_11.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.7-hb78ec9c_6.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.5.20-hbd8a1cb_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/click-8.4.1-pyhc90fa1f_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.6-py314hd8ed1ab_100.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-9.0.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.3-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyhc90fa1f_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.1.0-pyha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.1.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.10.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.14.6-h4df99d1_100.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.15.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-4.1.0-pyhcf101f3_0.conda - - conda: https://conda.modular.com/max-nightly/linux-64/mojo-1.0.0b1-release.conda - - conda: https://conda.modular.com/max-nightly/linux-64/mojo-compiler-1.0.0b1-release.conda - - conda: https://conda.modular.com/max-nightly/noarch/mblack-26.3.0-release.conda - - conda: https://conda.modular.com/max-nightly/noarch/mojo-python-1.0.0b1-release.conda -- conda_source: tempo[8f0a7ebb] @ git+https://github.com/triesap/mojo_tempo?rev=4a4b9f051286f2ef24cb0c8b0614f7ac7314e4bd#4a4b9f051286f2ef24cb0c8b0614f7ac7314e4bd - version: 0.1.2 - build: h60d57d3_0 - subdir: osx-arm64 - variants: - target_platform: osx-arm64 - depends: - - mojo ==1.0.0b1 - license: MIT - host_packages: - - conda: https://conda.anaconda.org/conda-forge/noarch/_python_abi3_support-1.0-hd8ed1ab_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ca-certificates-2026.5.20-hbd8a1cb_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/click-8.4.1-pyhc90fa1f_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/cpython-3.14.6-py314hd8ed1ab_100.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/importlib-metadata-9.0.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.3-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_core-5.9.1-pyhc90fa1f_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.1.0-pyha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-26.2-pyhc364b38_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-1.1.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.10.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0.post0-pyhe01879c_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python-gil-3.14.6-h4df99d1_100.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python_abi-3.14-8_cp314.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/six-1.17.0-pyhe01879c_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.4.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.15.1-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2025c-hc9c84f9_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-4.1.0-pyhcf101f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-hd037594_9.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-78.3-hef89b57_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/krb5-1.22.2-h385eeb1_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-22.1.7-h55c6f16_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libedit-3.1.20250104-pl5321hafb1f1b_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.8.1-hf6b4638_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.5.2-hcf2aa1b_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblzma-5.8.3-h8088a28_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libmpdec-4.0.0-h84a0fba_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsodium-1.0.22-h1a92334_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.53.2-h1ae2325_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.2-h8088a28_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.6-h1d4f5a5_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.6.3-hd24854e_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.14.6-h156bc91_100_cp314.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyzmq-27.1.0-py312h022ad19_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.3-h46df422_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h010d191_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.5.7-py314h6c2aa35_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zeromq-4.3.5-h10816f8_11.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.7-hbf9d68e_6.conda - - conda: https://conda.modular.com/max-nightly/noarch/mblack-26.3.0-release.conda - - conda: https://conda.modular.com/max-nightly/noarch/mojo-python-1.0.0b1-release.conda - - conda: https://conda.modular.com/max-nightly/osx-arm64/mojo-1.0.0b1-release.conda - - conda: https://conda.modular.com/max-nightly/osx-arm64/mojo-compiler-1.0.0b1-release.conda diff --git a/pixi.toml b/pixi.toml @@ -15,8 +15,6 @@ preview = ["pixi-build"] mojo = "==1.0.0b1" json = { git = "https://github.com/triesap/mojo_json.git", rev = "56025d73631054d7803143fa5e68c5de578e33f5" } morph = { git = "https://github.com/triesap/mojo_morph.git", rev = "ea73f909990f3d3f5d12b786fec2f09e1e09f462" } -envo = { git = "https://github.com/triesap/mojo_envo.git", rev = "50e1a62ef333862427d32e63098e782816475549" } -tempo = { git = "https://github.com/triesap/mojo_tempo.git", rev = "4a4b9f051286f2ef24cb0c8b0614f7ac7314e4bd" } [tasks] run = "mojo run -I src src/main.mojo" diff --git a/src/hyf_assist/bridge.mojo b/src/hyf_assist/bridge.mojo @@ -1,462 +0,0 @@ -from std.collections import List, Optional -from std.ffi import CStringSlice, c_int, external_call -from std.os import Pipe, Process -from std.sys._libc import close - -from json import Value, dumps, loads - -from hyf_core.capabilities.query_analysis import ( - ExtractedFilters, - QueryAnalysis, - analyze_query_text, - copy_string_list, -) -from hyf_core.request_context import RequestContext -from hyf_assist.contract import ( - AssistQueryRewriteResult, - AssistBridgeStatus, - assist_bridge_contract_version, - assist_bridge_fake_endpoint_prefix, - assist_bridge_runtime_id, - assist_bridge_supported_business_capabilities, - provider_runtime_id, -) -from hyf_provider.config import ( - default_max_local_provider_config, - load_max_local_provider_config, -) -from hyf_provider.max_local import max_local_provider_status -from hyf_runtime.config import ( - HyfLoadedRuntimeConfig, - assist_bridge_configured, - assisted_execution_enabled, -) - - -def _dup2(oldfd: c_int, newfd: c_int) -> c_int: - return external_call["dup2", c_int](oldfd, newfd) - - -@always_inline -def _fork() -> c_int: - return external_call["fork", c_int]() - - -@always_inline -def _exit_child(code: c_int): - _ = external_call["_exit", c_int](code) - - -def _read_pipe_to_string(mut pipe: Pipe) raises -> String: - var buffer = InlineArray[Byte, 4096](fill=0) - var output = String("") - while True: - var read = pipe.read_bytes(Span(buffer)) - if read == 0: - break - output += String( - from_utf8=Span(ptr=buffer.unsafe_ptr(), length=Int(read)) - ) - return output^ - - -def _run_stdio_endpoint_json(endpoint: String, request_json: String) raises -> Value: - var command = String(String(endpoint).strip()) - if command == "": - raise Error("assist bridge endpoint must not be empty") - - var stdin_pipe = Pipe() - var stdout_pipe = Pipe() - var argv = List[Optional[CStringSlice[ImmutAnyOrigin]]](length=2, fill={}) - argv[0] = rebind[CStringSlice[ImmutAnyOrigin]](command.as_c_string_slice()) - var command_ptr = command.as_c_string_slice().unsafe_ptr() - var argv_ptr = argv.unsafe_ptr() - - var stdin_read_fd = c_int(stdin_pipe.fd_in.value().value) - var stdin_write_fd = c_int(stdin_pipe.fd_out.value().value) - var stdout_read_fd = c_int(stdout_pipe.fd_in.value().value) - var stdout_write_fd = c_int(stdout_pipe.fd_out.value().value) - - var pid = _fork() - if pid < 0: - raise Error("failed to spawn assist bridge endpoint") - - if pid == 0: - if _dup2(stdin_read_fd, 0) < 0: - _exit_child(c_int(126)) - if _dup2(stdout_write_fd, 1) < 0: - _exit_child(c_int(126)) - _ = close(stdin_read_fd) - _ = close(stdin_write_fd) - _ = close(stdout_read_fd) - _ = close(stdout_write_fd) - _ = external_call["execvp", c_int](command_ptr, argv_ptr) - _exit_child(c_int(127)) - - stdin_pipe.set_output_only() - stdout_pipe.set_input_only() - stdin_pipe.write_bytes((request_json + "\n").as_bytes()) - stdin_pipe.set_input_only() - - var output = _read_pipe_to_string(stdout_pipe) - stdout_pipe.set_output_only() - - var process = Process(Int(pid)) - var status = process.wait() - if not status.exit_code or status.exit_code.value() != 0: - raise Error("assist bridge endpoint exited unexpectedly") - if output == "": - raise Error("assist bridge endpoint returned no stdout payload") - return loads(output) - - -def _fake_bridge_endpoint_is_reachable(endpoint: String) -> Bool: - var trimmed = String(endpoint).strip() - return trimmed.startswith(assist_bridge_fake_endpoint_prefix()) - - -def _has_key(value: Value, key: String) -> Bool: - for candidate in value.object_keys(): - if candidate == key: - return True - return False - - -def _string_array(value: Value, context: String) raises -> List[String]: - if not value.is_array(): - raise Error(context + " must be an array") - - var items = List[String]() - for item in value.array_items(): - if not item.is_string(): - raise Error(context + " items must be strings") - items.append(item.string_value()) - return items^ - - -def _build_status_request_json() raises -> String: - var value = loads("{}") - value.set("contract_version", Value(assist_bridge_contract_version())) - value.set("request_kind", Value("status")) - return dumps(value) - - -def _build_query_rewrite_request_json( - text: String, context: RequestContext -) raises -> String: - var value = loads("{}") - value.set("contract_version", Value(assist_bridge_contract_version())) - value.set("request_kind", Value("query_rewrite")) - - var input_value = loads("{}") - input_value.set("text", Value(String(text))) - value.set("input", input_value) - - var context_value = loads("{}") - context_value.set("deadline_ms", Value(context.deadline_ms)) - context_value.set("evidence_limit", Value(context.evidence_limit)) - context_value.set("consistency", Value(String(context.consistency))) - context_value.set("explain_plan", Value(context.explain_plan)) - - var listing_ids = loads("[]") - if context.scope: - for listing_id in context.scope.value().listing_ids: - listing_ids.append(Value(String(listing_id))) - context_value.set("scope_listing_ids", listing_ids) - - if context.time_range: - var time_range = loads("{}") - time_range.set( - "start", Value(String(context.time_range.value().start)) - ) - time_range.set("end", Value(String(context.time_range.value().end))) - context_value.set("time_range", time_range) - else: - context_value.set("time_range", Value(None)) - - value.set("context", context_value) - return dumps(value) - - -def _resolve_real_bridge_status(endpoint: String) raises -> AssistBridgeStatus: - var response = _run_stdio_endpoint_json(endpoint, _build_status_request_json()) - if not response.is_object(): - raise Error("assist bridge status response must be an object") - if not _has_key(response, "ok") or not response["ok"].bool_value(): - raise Error("assist bridge status request failed") - - var supported = List[String]() - if _has_key(response, "supported_business_capabilities"): - supported = _string_array( - response["supported_business_capabilities"].clone(), - "assist bridge supported_business_capabilities", - ) - - var reachable = ( - _has_key(response, "reachable") and response["reachable"].bool_value() - ) - var state = ( - response["state"].string_value() - if _has_key(response, "state") - else ("ready" if reachable else "unavailable") - ) - - return AssistBridgeStatus( - id=( - response["runtime_id"].string_value() - if _has_key(response, "runtime_id") - else assist_bridge_runtime_id() - ), - kind="assist_bridge", - contract_version=( - Int(response["contract_version"].int_value()) - if _has_key(response, "contract_version") - else assist_bridge_contract_version() - ), - transport="stdio", - endpoint=String(endpoint), - backend_kind=( - response["backend_kind"].string_value() - if _has_key(response, "backend_kind") - else "assist_bridge" - ), - provider=( - response["provider"].string_value() - if _has_key(response, "provider") - else "" - ), - route=( - response["route"].string_value() - if _has_key(response, "route") - else "" - ), - model=( - response["model"].string_value() - if _has_key(response, "model") - else "" - ), - configured=True, - reachable=reachable, - state=String(state), - fallback_contract="deterministic_baseline_preserved", - supported_business_capabilities=supported^, - ) - - -def resolve_assist_bridge_status( - config: HyfLoadedRuntimeConfig, -) -> AssistBridgeStatus: - var provider_config = default_max_local_provider_config() - try: - provider_config = load_max_local_provider_config() - except: - pass - - var configured = assist_bridge_configured(config) - var state = "disabled_by_runtime_config" - var reachable = False - var runtime_id = provider_runtime_id() - var kind = "provider_runtime" - var transport = "in_process" - var endpoint = String("") - var backend_kind = "max_local" - var provider = "" - var route = String(provider_config.route) - var model = String(provider_config.model) - var supported_capabilities = assist_bridge_supported_business_capabilities() - if assisted_execution_enabled(config): - if configured: - endpoint = String(config.effective.assist.endpoint) - if _fake_bridge_endpoint_is_reachable(endpoint): - runtime_id = assist_bridge_runtime_id() - kind = "assist_bridge" - transport = String(config.effective.assist.transport) - reachable = True - state = "ready" - backend_kind = "fake" - provider = "fake" - route = "assist_bridge.query_rewrite.fake" - model = "fake_query_rewrite_v1" - else: - var resolved = max_local_provider_status(provider_config) - reachable = resolved.reachable - state = String(resolved.state) - backend_kind = String(resolved.backend_kind) - provider = String(resolved.provider) - endpoint = "" - supported_capabilities = assist_bridge_supported_business_capabilities() - else: - state = "unconfigured" - - return AssistBridgeStatus( - id=runtime_id, - kind=kind, - contract_version=assist_bridge_contract_version(), - transport=transport, - endpoint=endpoint, - backend_kind=String(backend_kind), - provider=String(provider), - route=String(route), - model=String(model), - configured=configured, - reachable=reachable, - state=state, - fallback_contract="deterministic_baseline_preserved", - supported_business_capabilities=supported_capabilities^, - ) - - -def assisted_execution_state_for_capability( - bridge_status: AssistBridgeStatus, capability_id: String -) -> String: - if capability_id != "query_rewrite": - return "deferred" - - var unavailable_state = "provider_unavailable" - var unconfigured_state = "provider_unconfigured" - if bridge_status.kind == "assist_bridge": - unavailable_state = "bridge_unavailable" - unconfigured_state = "bridge_unconfigured" - - if bridge_status.state == "disabled_by_runtime_config": - return "disabled_by_runtime_config" - if bridge_status.state == "unconfigured": - return unconfigured_state - if bridge_status.state == "unavailable": - return unavailable_state - if bridge_status.reachable: - return "enabled" - return unavailable_state - - -def assisted_backend_available_for_capability( - bridge_status: AssistBridgeStatus, capability_id: String -) -> Bool: - if not bridge_status.reachable: - return False - for supported in bridge_status.supported_business_capabilities: - if supported == capability_id: - return True - return False - - -def serialize_assist_bridge_status_value( - bridge_status: AssistBridgeStatus, -) raises -> Value: - var value = loads("{}") - value.set("id", Value(String(bridge_status.id))) - value.set("kind", Value(String(bridge_status.kind))) - value.set("contract_version", Value(bridge_status.contract_version)) - value.set("transport", Value(String(bridge_status.transport))) - if bridge_status.endpoint != "": - value.set("endpoint", Value(String(bridge_status.endpoint))) - value.set("backend_kind", Value(String(bridge_status.backend_kind))) - if bridge_status.provider != "": - value.set("provider", Value(String(bridge_status.provider))) - if bridge_status.route != "": - value.set("route", Value(String(bridge_status.route))) - if bridge_status.model != "": - value.set("model", Value(String(bridge_status.model))) - value.set("configured", Value(bridge_status.configured)) - value.set("reachable", Value(bridge_status.reachable)) - value.set("state", Value(String(bridge_status.state))) - value.set( - "fallback_contract", Value(String(bridge_status.fallback_contract)) - ) - - var capabilities = loads("[]") - for capability in bridge_status.supported_business_capabilities: - capabilities.append(Value(String(capability))) - value.set("supported_business_capabilities", capabilities) - return value^ - - -def execute_query_rewrite_via_assist_bridge( - bridge_status: AssistBridgeStatus, - text: String, - context: RequestContext, -) raises -> AssistQueryRewriteResult: - var endpoint = String(bridge_status.endpoint) - if _fake_bridge_endpoint_is_reachable(endpoint): - var analysis = analyze_query_text(text, context) - var normalization_signals = copy_string_list( - analysis.normalization_signals - ) - normalization_signals.append("assist_bridge_fake") - var ranking_hints = copy_string_list(analysis.ranking_hints) - ranking_hints.append("assist_bridge_route") - - return AssistQueryRewriteResult( - analysis=QueryAnalysis( - original_text=String(analysis.original_text), - normalized_text=String(analysis.normalized_text), - rewritten_text=String(analysis.rewritten_text), - query_terms=copy_string_list(analysis.query_terms), - normalization_signals=normalization_signals^, - ranking_hints=ranking_hints^, - extracted_filters=ExtractedFilters( - local_intent=analysis.extracted_filters.local_intent, - fulfillment=String( - analysis.extracted_filters.fulfillment - ), - time_window=String(analysis.extracted_filters.time_window), - ), - ), - provider="fake", - route="assist_bridge.query_rewrite.fake", - model="fake_query_rewrite_v1", - latency_ms=1, - schema_version=1, - ) - - if not bridge_status.reachable: - raise Error( - "assist bridge '" + String(bridge_status.id) + "' is unavailable" - ) - - var response = _run_stdio_endpoint_json( - endpoint, _build_query_rewrite_request_json(text, context) - ) - if not response.is_object(): - raise Error("assist bridge query_rewrite response must be an object") - if not _has_key(response, "ok") or not response["ok"].bool_value(): - raise Error("assist bridge query_rewrite request failed") - if not _has_key(response, "analysis"): - raise Error("assist bridge query_rewrite response missing analysis") - - var analysis_value = response["analysis"].clone() - return AssistQueryRewriteResult( - analysis=QueryAnalysis( - original_text=analysis_value["original_text"].string_value(), - normalized_text=analysis_value["normalized_text"].string_value(), - rewritten_text=analysis_value["rewritten_text"].string_value(), - query_terms=_string_array( - analysis_value["query_terms"].clone(), - "assist bridge query_terms", - ), - normalization_signals=_string_array( - analysis_value["normalization_signals"].clone(), - "assist bridge normalization_signals", - ), - ranking_hints=_string_array( - analysis_value["ranking_hints"].clone(), - "assist bridge ranking_hints", - ), - extracted_filters=ExtractedFilters( - local_intent=analysis_value["extracted_filters"][ - "local_intent" - ].bool_value(), - fulfillment=analysis_value["extracted_filters"][ - "fulfillment" - ].string_value(), - time_window=analysis_value["extracted_filters"][ - "time_window" - ].string_value(), - ), - ), - provider=response["provider"].string_value(), - route=response["route"].string_value(), - model=response["model"].string_value(), - latency_ms=Int(response["latency_ms"].int_value()), - schema_version=Int(response["schema_version"].int_value()), - ) diff --git a/src/hyf_assist/contract.mojo b/src/hyf_assist/contract.mojo @@ -1,16 +1,10 @@ from std.collections import List -from hyf_core.capabilities.query_analysis import QueryAnalysis - def assist_bridge_contract_version() -> Int: return 1 -def assist_bridge_runtime_id() -> String: - return "hyf_assistd" - - def provider_runtime_id() -> String: return "hyf_provider_runtime" @@ -21,10 +15,6 @@ def assist_bridge_supported_business_capabilities() -> List[String]: return capabilities^ -def assist_bridge_fake_endpoint_prefix() -> String: - return "hyf-assistd://fake" - - @fieldwise_init struct AssistBridgeStatus(Copyable, Movable): var id: String @@ -41,13 +31,3 @@ struct AssistBridgeStatus(Copyable, Movable): var state: String var fallback_contract: String var supported_business_capabilities: List[String] - - -@fieldwise_init -struct AssistQueryRewriteResult(Copyable, Movable): - var analysis: QueryAnalysis - var provider: String - var route: String - var model: String - var latency_ms: Int - var schema_version: Int diff --git a/src/hyf_provider/__init__.mojo b/src/hyf_provider/__init__.mojo @@ -1 +0,0 @@ -"""Pure-Mojo provider integration modules for HYF.""" diff --git a/src/hyf_provider/client.mojo b/src/hyf_provider/client.mojo @@ -1,21 +0,0 @@ -from flare.http import HttpClient - -from hyf_provider.config import MaxLocalProviderConfig - - -def _trim_trailing_slash(url: String) -> String: - if url.endswith("/") and url.byte_length() > 1: - return String(url[byte = 0 : url.byte_length() - 1]) - return String(url) - - -def make_max_local_http_client( - config: MaxLocalProviderConfig, -) -> HttpClient: - return HttpClient(timeout_ms=config.request_timeout_ms) - - -def max_local_chat_completions_url( - config: MaxLocalProviderConfig, -) -> String: - return _trim_trailing_slash(config.base_url) + "/chat/completions" diff --git a/src/hyf_provider/config.mojo b/src/hyf_provider/config.mojo @@ -1,40 +0,0 @@ -from envo import getenv_or - - -@fieldwise_init -struct MaxLocalProviderConfig(Defaultable, Copyable, Movable): - var base_url: String - var health_url: String - var model: String - var route: String - var request_timeout_ms: Int - - def __init__(out self): - self.base_url = "http://127.0.0.1:8000/v1" - self.health_url = "http://127.0.0.1:8000/health" - self.model = "max-local-query-rewrite" - self.route = "provider_runtime.query_rewrite.max_local" - self.request_timeout_ms = 15_000 - - -def default_max_local_provider_config() -> MaxLocalProviderConfig: - return MaxLocalProviderConfig() - - -def load_max_local_provider_config() raises -> MaxLocalProviderConfig: - var config = default_max_local_provider_config() - config.base_url = getenv_or("HYF_MAX_LOCAL_BASE_URL", config.base_url) - config.health_url = getenv_or( - "HYF_MAX_LOCAL_HEALTH_URL", config.health_url - ) - config.model = getenv_or("HYF_MAX_LOCAL_MODEL", config.model) - config.route = getenv_or("HYF_MAX_LOCAL_ROUTE", config.route) - - var timeout_value = getenv_or( - "HYF_MAX_LOCAL_REQUEST_TIMEOUT_MS", String(config.request_timeout_ms) - ) - var parsed_timeout = atol(timeout_value) - if parsed_timeout > 0: - config.request_timeout_ms = parsed_timeout - - return config^ diff --git a/src/hyf_provider/health.mojo b/src/hyf_provider/health.mojo @@ -1,31 +0,0 @@ -from hyf_provider.client import make_max_local_http_client -from hyf_provider.config import MaxLocalProviderConfig -from hyf_provider.result import MaxLocalProviderStatus - - -def resolve_max_local_provider_status( - config: MaxLocalProviderConfig, -) -> MaxLocalProviderStatus: - try: - with make_max_local_http_client(config) as client: - var response = client.get(config.health_url) - var reachable = response.ok() - return MaxLocalProviderStatus( - backend_kind="max_local", - provider="max_local", - route=String(config.route), - model=String(config.model), - reachable=reachable, - state="ready" if reachable else "unavailable", - ) - except: - pass - - return MaxLocalProviderStatus( - backend_kind="max_local", - provider="max_local", - route=String(config.route), - model=String(config.model), - reachable=False, - state="unavailable", - ) diff --git a/src/hyf_provider/max_local.mojo b/src/hyf_provider/max_local.mojo @@ -1,56 +0,0 @@ -from tempo import Timestamp - -from hyf_assist.contract import AssistQueryRewriteResult -from hyf_core.request_context import RequestContext -from hyf_provider.client import ( - make_max_local_http_client, - max_local_chat_completions_url, -) -from hyf_provider.config import MaxLocalProviderConfig -from hyf_provider.health import resolve_max_local_provider_status -from hyf_provider.result import ( - MaxLocalProviderStatus, - parse_query_analysis_from_chat_completion, -) -from hyf_provider.schema import ( - build_query_rewrite_request_body, - query_rewrite_schema_version, -) - - -def execute_query_rewrite_via_max_local_provider( - config: MaxLocalProviderConfig, text: String, context: RequestContext -) raises -> AssistQueryRewriteResult: - var started_at_ms = Timestamp.now().unix_ms() - with make_max_local_http_client(config) as client: - var response = client.post( - max_local_chat_completions_url(config), - build_query_rewrite_request_body(config, text, context), - ) - if not response.ok(): - raise Error( - "max_local provider returned HTTP " - + String(response.status) - ) - - var analysis = parse_query_analysis_from_chat_completion( - response.json() - ) - var latency_ms = Int(Timestamp.now().unix_ms() - started_at_ms) - if latency_ms < 0: - latency_ms = 0 - - return AssistQueryRewriteResult( - analysis=analysis^, - provider="max_local", - route=String(config.route), - model=String(config.model), - latency_ms=latency_ms, - schema_version=query_rewrite_schema_version(), - ) - - -def max_local_provider_status( - config: MaxLocalProviderConfig, -) -> MaxLocalProviderStatus: - return resolve_max_local_provider_status(config) diff --git a/src/hyf_provider/result.mojo b/src/hyf_provider/result.mojo @@ -1,120 +0,0 @@ -from std.collections import List - -from json import Value, loads, validate - -from hyf_core.capabilities.query_analysis import ( - ExtractedFilters, - QueryAnalysis, -) -from hyf_provider.schema import query_rewrite_schema - - -@fieldwise_init -struct MaxLocalProviderStatus(Copyable, Movable): - var backend_kind: String - var provider: String - var route: String - var model: String - var reachable: Bool - var state: String - - -def _has_key(value: Value, key: String) -> Bool: - for candidate in value.object_keys(): - if candidate == key: - return True - return False - - -def _string_array(value: Value, context: String) raises -> List[String]: - if not value.is_array(): - raise Error(context + " must be an array") - - var items = List[String]() - for item in value.array_items(): - if not item.is_string(): - raise Error(context + " items must be strings") - items.append(item.string_value()) - return items^ - - -def _first_validation_error(value: Value) raises -> String: - var validation = validate(value, query_rewrite_schema()) - if validation.valid: - return "" - if len(validation.errors) == 0: - return "query_rewrite structured output failed schema validation" - var error = validation.errors[0].copy() - if error.path == "": - return String(error.message) - return String(error.path) + ": " + String(error.message) - - -def extract_chat_completion_text(response: Value) raises -> String: - if not response.is_object(): - raise Error("max_local response must be a JSON object") - if not _has_key(response, "choices"): - raise Error("max_local response must contain choices") - if ( - not response["choices"].is_array() - or len(response["choices"].array_items()) == 0 - ): - raise Error("max_local response choices must be a non-empty array") - - var message = response["choices"][0]["message"].clone() - if not message.is_object(): - raise Error("max_local response choice message must be an object") - - var content = message["content"].clone() - if content.is_string(): - return content.string_value() - - if content.is_array(): - var collected = String("") - for part in content.array_items(): - if ( - part.is_object() - and _has_key(part, "type") - and part["type"].is_string() - and part["type"].string_value() == "text" - and _has_key(part, "text") - and part["text"].is_string() - ): - collected += part["text"].string_value() - - if collected != "": - return collected^ - - raise Error("max_local response contained no text content") - - -def parse_query_analysis_json(value: Value) raises -> QueryAnalysis: - if not value.is_object(): - raise Error("query_rewrite structured output must be an object") - - var validation_error = _first_validation_error(value.clone()) - if validation_error != "": - raise Error(validation_error) - - var filters = value["extracted_filters"].clone() - return QueryAnalysis( - original_text=value["original_text"].string_value(), - normalized_text=value["normalized_text"].string_value(), - rewritten_text=value["rewritten_text"].string_value(), - query_terms=_string_array(value["query_terms"], "query_terms"), - normalization_signals=_string_array( - value["normalization_signals"], "normalization_signals" - ), - ranking_hints=_string_array(value["ranking_hints"], "ranking_hints"), - extracted_filters=ExtractedFilters( - local_intent=filters["local_intent"].bool_value(), - fulfillment=filters["fulfillment"].string_value(), - time_window=filters["time_window"].string_value(), - ), - ) - - -def parse_query_analysis_from_chat_completion( - response: Value, -) raises -> QueryAnalysis: - return parse_query_analysis_json(loads(extract_chat_completion_text(response))) diff --git a/src/hyf_provider/schema.mojo b/src/hyf_provider/schema.mojo @@ -1,129 +0,0 @@ -from json import Value, loads - -from hyf_core.request_context import RequestContext -from hyf_provider.config import MaxLocalProviderConfig - - -def query_rewrite_schema_version() -> Int: - return 1 - - -def query_rewrite_schema() raises -> Value: - var schema = loads("{}") - schema.set("type", Value("object")) - schema.set("additionalProperties", Value(False)) - - var required = loads("[]") - required.append(Value("original_text")) - required.append(Value("normalized_text")) - required.append(Value("rewritten_text")) - required.append(Value("query_terms")) - required.append(Value("normalization_signals")) - required.append(Value("ranking_hints")) - required.append(Value("extracted_filters")) - schema.set("required", required) - - var properties = loads("{}") - properties.set("original_text", loads('{"type":"string"}')) - properties.set("normalized_text", loads('{"type":"string"}')) - properties.set("rewritten_text", loads('{"type":"string"}')) - properties.set( - "query_terms", - loads('{"type":"array","items":{"type":"string"}}'), - ) - properties.set( - "normalization_signals", - loads('{"type":"array","items":{"type":"string"}}'), - ) - properties.set( - "ranking_hints", - loads('{"type":"array","items":{"type":"string"}}'), - ) - properties.set( - "extracted_filters", - loads( - '{"type":"object","additionalProperties":false,"required":["local_intent","fulfillment","time_window"],"properties":{"local_intent":{"type":"boolean"},"fulfillment":{"type":"string"},"time_window":{"type":"string"}}}' - ), - ) - schema.set("properties", properties) - return schema^ - - -def query_rewrite_system_prompt() -> String: - return ( - "Return only strict JSON matching the supplied schema. Preserve " - + "original_text, normalized_text, rewritten_text, query_terms, " - + "normalization_signals, ranking_hints, and extracted_filters." - ) - - -def build_query_rewrite_user_prompt( - text: String, context: RequestContext -) -> String: - var prompt = ( - "Rewrite the market search query into normalized search terms and " - + "extracted filters.\nquery: " - + text - + "\n" - ) - - if context.scope and len(context.scope.value().listing_ids) > 0: - var first = True - prompt += "scope_listing_ids: " - for listing_id in context.scope.value().listing_ids: - if not first: - prompt += "," - prompt += String(listing_id) - first = False - prompt += "\n" - - if context.time_range: - prompt += ( - "time_range: " - + context.time_range.value().start - + " -> " - + context.time_range.value().end - + "\n" - ) - - prompt += "consistency: " + context.consistency + "\n" - prompt += "evidence_limit: " + String(context.evidence_limit) + "\n" - prompt += "explain_plan: " + String(context.explain_plan) + "\n" - return prompt^ - - -def build_query_rewrite_request_body( - config: MaxLocalProviderConfig, text: String, context: RequestContext -) raises -> Value: - var body = loads("{}") - body.set("model", Value(String(config.model))) - - var messages = loads("[]") - - var system_message = loads("{}") - system_message.set("role", Value("system")) - system_message.set("content", Value(query_rewrite_system_prompt())) - messages.append(system_message) - - var user_message = loads("{}") - user_message.set("role", Value("user")) - user_message.set( - "content", Value(build_query_rewrite_user_prompt(text, context)) - ) - messages.append(user_message) - - body.set("messages", messages) - body.set("temperature", Value(0.1)) - body.set("max_tokens", Value(256)) - - var response_format = loads("{}") - response_format.set("type", Value("json_schema")) - - var json_schema = loads("{}") - json_schema.set("name", Value("query_rewrite")) - json_schema.set("strict", Value(True)) - json_schema.set("schema", query_rewrite_schema()) - response_format.set("json_schema", json_schema) - - body.set("response_format", response_format) - return body^