feat(cli): run the ingest gateway's AI stamping on local traces - #1178
JeremyFunk wants to merge 2 commits into
Conversation
Local ingest skipped the gateway's maple_ai.* stamping, so the local ai_trace_index (which projects stamped spans only) stayed empty and Agent Sessions showed nothing in local mode. The stamping moves into its own crate (apps/ingest/crates/ai-session), which the gateway links as before and crates/ai-session-wasm compiles to WebAssembly. The CLI embeds that module and stamps every trace request before encoding it, so local and cloud run one implementation.
A panic in the stamping is a bug, not bad input: ingest the batch unstamped on a fresh instance instead of rejecting it. Re-instantiate once wasm memory passes 64 MiB, since it never shrinks. Tests cover parent and link ids, a multi-MiB attribute and prost's rejection message.
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 11 minutes. View limit detailsLimit details: You’ve used all 4 included reviews currently available. Review configuration: ⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: ⛔ Files ignored due to path filters (1)
📒 Files selected for processing (34)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Maple review🟡 Confidence 3/5 · needs attention Warning This review ended early; what follows is what it established. Repoints the AI-stamping doc comments from
What was checked
|
Problem
The local CLI server (
apps/cli, chDB mode) ingests OTLP traces without the ingest gateway's AI stamping. The localai_trace_indexMV projects only spans withmaple_ai.vendor.id != ''and reads onlymaple_ai.*stamps, so Agent Sessions is always empty in local mode.Plan: options considered
apps/ingest; Rust + wasm32 target needed wherever the CLI is built or testedmaple-ingestbinaryai_session*.rsAlso considered: checking the
.wasminto git. That avoids Rust in CI lanes, but every stamping PR would then commit a ~370 KB binary and hit merge conflicts on it (several stamping PRs are in flight at once), and CI would need a drift check to catch a forgotten rebuild. Building from source means the embedded module can't drift from the source.What changed
apps/ingest/crates/ai-session:src/ai_session*.rsmoved as-is, plus theAnyValuehelpers it used fromtelemetry.rs(value.rs).maple-ingestre-exports it asmaple_ingest::ai_session, somain.rsand the bench are unchanged.apps/ingestbecomes a Cargo workspace with shared lints.apps/ingest/crates/ai-session-wasm: a ~50-line cdylib with no wasm-bindgen. Protocol:input(len)→ host writes the protobufExportTraceServiceRequest→stamp()→output()/output_len()(on failure the output holds prost's decode error).[profile.wasm]optimizes for size: 377 KB, about 12 s cold build.apps/cli/src/server/otlp/ai-stamp.ts: instantiates the embedded module (import … with { type: "file" }, verified to embed underbun build --compile).decodeOtlpnow stamps every trace request before anything reads it. The gateway itself runs the stamping at decode time, so encoders and local eventing both see stamped spans.bun run --cwd apps/cli build:ai-stamp; the package'stestandstartscripts run it first. It is a no-op rebuild when nothing changed.scripts/build-local-binary.shbuilds it beforebun build --compile.mise.tomladds thewasm32-unknown-unknowntarget..cargo/config.tomlsetsgetrandom_backend="unsupported"for wasm32, becauseopentelemetry-proto'stracefeature pulls rand; the stamping never draws randomness.testslane installs Rust only when it runs@maple/cli.clipaths filter and the@maple/cli#testturbo inputs includeapps/ingest/crates/**.native-checkpoint-smoke.shPOSTs an AI SDK span to the real binary and asserts theai_trace_indexrow: an end-to-end check against chDB.gen-ai.test.ts, turbo inputs. Migration 0035's comment is left as history.Decisions made without the owner
Pre-PR review (Effect v4 + tests) had no criticals. Taken: trap and memory handling, more test coverage. Skipped: a tagged error for the stamping failure (it is a string mapped straight to
OtlpDecodeFailed), and lazy instantiation (the embedded file import fails at load anyway when missing).opentelemetry(a hard dependency ofopentelemetry-proto) linksjs-syson wasm32. Its four wasm-bindgen imports are stubbed as no-ops; the stamping never reaches them.JSON decoding stays in TypeScript (protobufjs + hex-id fixup) rather than moving the gateway's
otlp_jsonleniency pass into the crate. That keeps the wasm module trace-stamping-only.Verification
cargo test -p maple-ai-session: 82 pass.cargo clippyis clean on both new crates.cargo check -p maple-ingest --all-targetspasses.apps/cli: newtest/ai-stamp.test.tscovers protobuf, JSON and invalid bodies against the gateway's ownvercel_v7fixture. It checks that a forgedmaple_ai.tool_callis stripped, that trace/span/parent/link ids round-trip as hex, that an 8 MiB attribute grows wasm memory and survives, and that the rejection carries prost's error. Existing trace tests pass (local-eventing-ingest,server-network,serve-describe-thrown,encode), andtscforapps/clipasses.packages/domaingen-ai.test.ts(which pins stamp keys against the moved sources): 15 pass.local-checkpoint-nativejob runs them.Dev impact
Running the CLI from source now needs the mise Rust toolchain with the wasm32 target (
docs/local-mode.mdupdated). In-flight PRs that editapps/ingest/src/ai_session*.rsfollow the rename on merge; git rename detection handles the pure move.Need help on this PR? Tag
@codesmith-botwith what you need. Autofix is disabled.