Skip to content

V42: Keep lousho build working without the optional OTel packages - #700

Merged
LinuxDevil merged 2 commits into
mainfrom
v42-otel-optional-build
Oct 20, 2026
Merged

LinuxDevil merged 2 commits into
mainfrom
v42-otel-optional-build

Conversation

@LinuxDevil

Copy link
Copy Markdown
Owner

Fixes audit finding V42 (Vercel competitor audit, 2026-10-19). Regression from #695.

What was wrong

Since #695 the deploy runtime re-exports otelTracing.ts, which statically imported src/execution/otel.ts and with it @opentelemetry/api, an optional peer a scaffolded project does not install (ai keeps its own copy nested under node_modules/ai). So npm run build in a fresh create-lousho-agent project failed: Could not resolve "@opentelemetry/api" / LOUSHO_DEPLOY_FAILED. CI missed it because the repo has the package as a devDependency and the e2e template test never ran npm run build.

What changed

  • src/deploy/otelTracing.ts: the OTel exporter module is imported lazily inside otelTracingFromEnv(), only once OTEL_EXPORTER_OTLP_ENDPOINT (or ..._TRACES_ENDPOINT) is set. @opentelemetry/api joins the list of packages the "install these" message names.
  • src/deploy/bundle.ts: new runtimePeerPlugin() for node-server/docker builds. When the build can resolve @opentelemetry/api, it bundles it as before. When it can't, the import becomes a require() that runs only when the exporter loads. The build succeeds, the server starts, and packages installed next to dist/server.js later still work.
  • src/deploy/adapters/node-server.ts (outside the ticket's file list, one line): registers the plugin.
  • docs/observability.md: the install line includes @opentelemetry/api (llms.txt regenerated).

Tests

  • New src/deploy/runtimePeer.test.ts bundles otelTracing.ts with esbuild while @opentelemetry/api is hidden from the SDK source, as in a scaffold, then loads the output from a temp dir:
    • With the endpoint unset: nothing is logged.
    • With it set: otelTracingFromEnv() returns undefined and logs npm install @opentelemetry/api ....
    • With the old static import, loading the bundle throws Cannot find module '@opentelemetry/api'. Without the plugin, the build fails with "Could not resolve".
    • A second case checks the package is still bundled when it resolves.
  • packages/create-lousho-agent/src/template.e2e.test.ts now runs npm run build in the generated project, starts dist/server.js and expects GET /health to return 200 (openai + openrouter). Both cases pass locally.
  • otelTracing.test.ts message assertions are updated. node-server-otel.test.ts and node-server-externals.test.ts still pass.
  • npx tsc --noEmit, npm run typecheck:tests and npm run lint pass. npm run test:coverage passes (414 files). npm run fallow exits 0. npm run api:check is up to date.
    • In the first coverage run, src/tools/mcp/connect.test.ts failed on timing under load. It passed on its own and on the full re-run.

Manual check: packed the SDK (npm pack --ignore-scripts), then ran node packages/create-lousho-agent/bin/cli.js app --yes --no-git --provider openrouter --template tools --package-manager npm --sdk-path <tgz> in a temp dir (no node_modules/@opentelemetry in the project):

> app@0.1.0 build
> lousho build src/agent.ts --target=node-server

Built node-server in .lousho\build\node-server. From there, run:
node dist/server.js

Starting the built server with OTEL_EXPORTER_OTLP_ENDPOINT set (GET /health -> 200):

[lousho server] OTEL_EXPORTER_OTLP_ENDPOINT is set but traces are not exported: it needs @opentelemetry/api, @opentelemetry/sdk-trace-node, @opentelemetry/resources, @opentelemetry/exporter-trace-otlp-http. Install them next to dist/server.js (npm install @opentelemetry/api @opentelemetry/sdk-trace-node@^2 @opentelemetry/resources@^2 @opentelemetry/exporter-trace-otlp-http, ...). See docs/observability.md.
lousho server: listening on http://127.0.0.1:38421

After running that npm install next to dist/server.js (no rebuild):

lousho server: exporting OTel traces to http://127.0.0.1:4318/v1/traces
lousho server: listening on http://127.0.0.1:38422

Changelog: Fixed lousho build --target=node-server|docker failing with "Could not resolve @opentelemetry/api" in projects without the optional OTel packages, including every create-lousho-agent scaffold (regression in the previous release's OTel trace export).

🤖 Generated with Claude Code

The deploy runtime statically imported the OTel exporter module, so a
node-server build of a project without @opentelemetry/api (every scaffold)
failed with 'Could not resolve'. The exporter is now imported lazily, and
the node-server build turns an unresolvable @opentelemetry/api into a
runtime require that only runs when OTEL_EXPORTER_OTLP_ENDPOINT is set.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@LinuxDevil
LinuxDevil force-pushed the v42-otel-optional-build branch from 270c03a to c42cdc5 Compare October 20, 2026 11:21
On Linux the killed server logs its SIGTERM line before it exits; the
helper probed /health again on that output and the late failure replaced
the 200. Probe once, settle once, read the port from the whole line, and
put the server's output in any failure.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@LinuxDevil
LinuxDevil merged commit 3b5ea03 into main Oct 20, 2026
2 checks passed
LinuxDevil added a commit that referenced this pull request Oct 20, 2026
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant