From 1853dd1d40308deb829bc621beb79c5d39b9c57f Mon Sep 17 00:00:00 2001 From: Adam Malczewski Date: Sun, 31 May 2026 22:32:34 +0900 Subject: feat(debug): wire LLM debug logger end-to-end MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The debug-logger.ts module existed but was completely orphaned — none of its functions had any callsites, so DISPATCH_DEBUG_LLM=1 did nothing. Wires it in across the stack: - llm/debug-logger.ts: add wrapFetchWithLogging() that tees SSE bodies via TransformStream + response.clone() so we capture every chunk without draining the body the AI SDK consumes. Redacts authorization / x-api-key / cookie headers in logs. Also exports nextDebugSeq() so requests and log files share an id. - llm/provider.ts: all 3 factories (Claude OAuth, plain-API-key Anthropic, OpenAI-compatible) now pass fetch: wrapFetchWithLogging(globalThis.fetch). For Claude OAuth the wrap goes on the inner base fetch so logged bodies reflect the post-transform shape + Claude-Code session headers. Added tabId to ProviderConfig for log labelling. - agent/agent.ts: threads tabId through createProvider and emits logAgentLoop / logStepLifecycle / logStreamEvent at every meaningful point in the run loop — step start/end, tool count, every fullStream event. All are no-ops when DISPATCH_DEBUG_LLM is unset. - core/index.ts: re-exports the debug helpers. - tests/llm/provider.test.ts: switch one full-object equality assertion to property assertions so the test survives the new fetch: wrapper. Plumbing the env var into the container required three more fixes: - bin/up: re-export DISPATCH_DEBUG_LLM* so docker compose forwards them (compose only forwards vars referenced in the environment: block). Also pre-creates /tmp/dispatch/llm-debug and chowns it on first run so the container's UID-1000 bun process can write into it without EACCES. - docker-compose.yml: declare the debug vars on api.environment and bind-mount /tmp/dispatch/llm-debug:/tmp/dispatch/llm-debug so logs are inspectable from the host without docker exec. - docker/entrypoint.dev.sh: explicitly forward DISPATCH_DEBUG_* through the 'su -' login-shell barrier — su - resets the environment to TERM/ PATH/HOME/SHELL/USER/LOGNAME only, silently stripping everything else. This is why the vars appeared via 'docker exec env' (which spawns a new process inheriting the container env) but were absent from the actual bun process's /proc//environ. bin/build: drop stray sudo for consistency with bin/up and bin/down. --- docker/entrypoint.dev.sh | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) mode change 100644 => 100755 docker/entrypoint.dev.sh (limited to 'docker') diff --git a/docker/entrypoint.dev.sh b/docker/entrypoint.dev.sh old mode 100644 new mode 100755 index dd0d423..0feb37a --- a/docker/entrypoint.dev.sh +++ b/docker/entrypoint.dev.sh @@ -43,5 +43,29 @@ if [ "${SKIP_INSTALL:-}" != "1" ]; then su -s /bin/bash - "$USER_NAME" -c "export HOME=$USER_HOME && cd /app && bun install" fi +# ─── Env vars that must survive the `su -` login-shell barrier ── +# `su -` resets the environment to a clean login profile (TERM, PATH, +# HOME, SHELL, USER, LOGNAME, MAIL only — everything else is wiped). +# Anything compose/Dockerfile set on PID 1 that the actual app process +# needs has to be re-exported explicitly here. The +# `${VAR-}` form (note: NOT `${VAR:-}`) preserves the empty-string case +# so a deliberately-blank var stays blank instead of going undefined. +FORWARD_VARS=( + DISPATCH_DEBUG_LLM + DISPATCH_DEBUG_LLM_VERBOSITY + DISPATCH_DEBUG_LLM_DIR + DISPATCH_DEBUG_USAGE + DISPATCH_WORKING_DIR + PORT +) +EXPORTS="" +for var in "${FORWARD_VARS[@]}"; do + # Use indirect expansion to read the var's current value, default to empty. + val="${!var-}" + # Single-quote-escape the value so shell-meaningful chars survive. + esc=${val//\'/\'\\\'\'} + EXPORTS+="export $var='$esc'; " +done + # Execute the main command as the target user -exec su -s /bin/bash - "$USER_NAME" -c "export HOME=$USER_HOME && cd /app && exec $*" +exec su -s /bin/bash - "$USER_NAME" -c "export HOME=$USER_HOME && $EXPORTS cd /app && exec $*" -- cgit v1.2.3