From 1b16900f70a891761f0ac750835e349d7bb82d4b Mon Sep 17 00:00:00 2001 From: sraibaby Date: Sat, 21 Feb 2026 09:18:05 +0300 Subject: [PATCH] feat: client WebUI/Cline compatibility and configurable env vars - Client: set Content-Type application/json for models list responses (fixes compatibility with WebUI, Cline and other OpenAI-compatible UIs) - cocoon-launch: configurable via env vars - COCOON_ROUTER_POLICY (default: tdx) for router listen policy - COCOON_CLIENT_VERBOSITY (default: 3) for client log level - COCOON_BUILD_JOBS to limit parallel build jobs (e.g. on WSL) - benchmark: run without Go by downloading hey binary when go not installed - .gitignore: benchmark/hey, nul (generated/downloaded artifacts) Co-authored-by: Cursor --- .gitignore | 2 ++ benchmark/run-benchmark.sh | 11 ++++++++++- runners/client/ClientRunner.cpp | 4 ++-- scripts/cocoon-launch | 14 +++++++++----- 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/.gitignore b/.gitignore index ab3bce4..0deb72e 100644 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,8 @@ libmicrohttpd-0.9.77-w32-bin.zip openssl-3.1.4.zip readline-5.0-1-lib.zip benchmark/server +benchmark/hey +nul mt-tools/data/ mt-tools/.venv/ mt-tools/uv.lock diff --git a/benchmark/run-benchmark.sh b/benchmark/run-benchmark.sh index 39adc9e..4becd9a 100755 --- a/benchmark/run-benchmark.sh +++ b/benchmark/run-benchmark.sh @@ -35,10 +35,19 @@ if command -v hey &> /dev/null; then HEY_CMD="hey" elif [ -f "$HOME/go/bin/hey" ]; then HEY_CMD="$HOME/go/bin/hey" -else +elif command -v go &> /dev/null; then echo "Installing hey..." go install github.com/rakyll/hey@latest HEY_CMD="$HOME/go/bin/hey" +else + echo "Go not found. Downloading hey binary..." + HEY_DIR="$(cd "$(dirname "$0")" && pwd)" + HEY_BIN="$HEY_DIR/hey" + if [ ! -f "$HEY_BIN" ]; then + curl -sSL -o "$HEY_BIN" "https://storage.googleapis.com/hey-releases/hey_linux_amd64" + chmod +x "$HEY_BIN" + fi + HEY_CMD="$HEY_BIN" fi # Parse arguments diff --git a/runners/client/ClientRunner.cpp b/runners/client/ClientRunner.cpp index f39442e..a19779a 100644 --- a/runners/client/ClientRunner.cpp +++ b/runners/client/ClientRunner.cpp @@ -93,7 +93,7 @@ void ClientRunner::run_get_models_request( jb.stop_object(); auto res = jb.as_cslice().str(); - http_send_static_answer(std::move(res), std::move(promise)); + http_send_static_answer(std::move(res), std::move(promise), "application/json"); }); } else { auto request = cocoon::create_serialize_tl_object(); @@ -134,7 +134,7 @@ void ClientRunner::run_get_models_request( jb.stop_object(); auto res = jb.as_cslice().str(); - http_send_static_answer(std::move(res), std::move(promise)); + http_send_static_answer(std::move(res), std::move(promise), "application/json"); }); } } diff --git a/scripts/cocoon-launch b/scripts/cocoon-launch index 228e9de..d84eb02 100755 --- a/scripts/cocoon-launch +++ b/scripts/cocoon-launch @@ -506,13 +506,15 @@ def run_client_local(cfg: Config): # Start router (SOCKS5 only, no reverse proxy) with colored output router = f'{cfg.build_dir}/tee/router' - router_proc = popen([router, '-S', '8116@tdx', '--serialize-info'], + router_policy = os.environ.get('COCOON_ROUTER_POLICY', 'tdx') + router_proc = popen([router, '-S', f'8116@{router_policy}', '--serialize-info'], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, bufsize=1) router_thread = threading.Thread(target=stream_output, args=(router_proc, 'ROUTER', '36'), daemon=True) router_thread.start() # Run client with colored output - client_cmd = [f'{cfg.build_dir}/client-runner', '--config', f'{cfg.local_run_dir}/client-config.json', '-v3'] + client_verbosity = os.environ.get('COCOON_CLIENT_VERBOSITY', '3') + client_cmd = [f'{cfg.build_dir}/client-runner', '--config', f'{cfg.local_run_dir}/client-config.json', f'-v{client_verbosity}'] if cfg.fake_ton: client_cmd += ['--disable-ton', f'{cfg.local_run_dir}/fake-ton-config.json'] @@ -651,9 +653,11 @@ def ensure_build(build_dir: Path, targets: list[str]): '-S', str(script_dir), '-B', str(build_dir)], check=True) - # Build targets - print(f'Building {", ".join(targets)}...') - run(['cmake', '--build', str(build_dir), '-j', str(os.cpu_count() or 4), + # Build targets (set COCOON_BUILD_JOBS if you hit OOM e.g. on WSL) + jobs = os.environ.get('COCOON_BUILD_JOBS') + jobs = int(jobs) if jobs is not None else (os.cpu_count() or 4) + print(f'Building {", ".join(targets)}... (jobs={jobs})') + run(['cmake', '--build', str(build_dir), '-j', str(jobs), '--target'] + targets, check=True)