Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
📝 WalkthroughWalkthroughIntroduces span-based tracing and collectors across the runtime and bridges: a new bex_events crate (events, event store, collector, serialization), VM span notifications and Collector handles, engine-level per-call span plumbing, Python PyO3 bridge + HostSpanManager and Collector bindings, and accompanying tests and manifest updates. Changes
Sequence Diagram(s)sequenceDiagram
participant Host as Host (Python)
participant HostMgr as HostSpanManager
participant Engine as BexEngine
participant VM as BexVm
participant EventStore as EventStore
Host->>HostMgr: enter(function, args)
HostMgr->>EventStore: emit(FunctionStart)
HostMgr->>Engine: call_function(name, args, host_ctx, collectors)
Engine->>Engine: init span_state
Engine->>EventStore: emit(FunctionStart with host prefix)
Engine->>VM: execute(bytecode)
alt traced frame
VM->>VM: push traced_frame
VM->>Engine: SpanNotify(FunctionEnter)
Engine->>EventStore: emit(FunctionStart for nested span)
end
VM->>VM: run instructions
alt function return
VM->>Engine: SpanNotify(FunctionExit)
Engine->>EventStore: emit(FunctionEnd for nested span)
end
VM-->>Engine: result
Engine->>EventStore: emit(FunctionEnd with duration)
Engine-->>Host: result
Host->>HostMgr: exit_ok()
HostMgr->>EventStore: emit(FunctionEnd)
Host->>EventStore: flush()
EventStore->>EventStore: write JSONL
Estimated code review effort🎯 5 (Critical) | ⏱️ ~120 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
| {"call_id":"16d19392-a0dc-4e7c-b7b3-290ca870fc28","call_stack":["ae83f415-8dd2-46a8-ba04-89b5aca2c561","4b5b39b6-bd73-4f87-83f4-1cd749c56410","41c787dd-05c1-402e-8095-8240fcababf6","16d19392-a0dc-4e7c-b7b3-290ca870fc28"],"content":{"data":{"duration_ms":1,"function_display_name":"SummarizeInfo","result":"<handle>"},"type":"function_end"},"function_event_id":"7912535a-2790-4b2e-8678-c86fbb1d6684","timestamp_epoch_ms":1770875826293} | ||
| {"call_id":"41c787dd-05c1-402e-8095-8240fcababf6","call_stack":["ae83f415-8dd2-46a8-ba04-89b5aca2c561","4b5b39b6-bd73-4f87-83f4-1cd749c56410","41c787dd-05c1-402e-8095-8240fcababf6"],"content":{"data":{"duration_ms":20,"function_display_name":"OuterPipeline","result":"<handle>"},"type":"function_end"},"function_event_id":"3dfd1fcd-c0c1-424c-ac4d-d2e71a1e291f","timestamp_epoch_ms":1770875826293} | ||
| {"call_id":"4b5b39b6-bd73-4f87-83f4-1cd749c56410","call_stack":["ae83f415-8dd2-46a8-ba04-89b5aca2c561","4b5b39b6-bd73-4f87-83f4-1cd749c56410"],"content":{"data":{"duration_ms":21,"function_display_name":"child_py","result":null},"type":"function_end"},"function_event_id":"3b51e2c5-5ec0-484f-820d-1bd260780994","timestamp_epoch_ms":1770875826294} | ||
| {"call_id":"ae83f415-8dd2-46a8-ba04-89b5aca2c561","call_stack":["ae83f415-8dd2-46a8-ba04-89b5aca2c561"],"content":{"data":{"duration_ms":22,"function_display_name":"parent_py","result":null},"type":"function_end"},"function_event_id":"c8bfd012-0ba3-4028-a121-060341eb66a6","timestamp_epoch_ms":1770875826294} |
There was a problem hiding this comment.
Debug output files accidentally committed to repository
Low Severity
debug_events.json and debug_events.jsonl contain trace output generated during development (specific UUIDs, timestamps, function names like parent_py, child_py). These are not referenced by any code and appear to be debug artifacts that were accidentally included in the commit.
Additional Locations (1)
Resolve merge conflicts between the tracing feature branch and canary: - bex_engine: adapt call_function signature with tracing params (host_ctx, collectors) - bex_vm: keep traced_frames and CallWithTrace instruction support - bridge_cffi: integrate bex_factory pattern while preserving collector module - bridge_python: use bex_factory::new_engine for direct engine access, remove env_vars param - bex_factory: add new_engine() for concrete Arc<BexEngine> access Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
| /// Call a function AND notify the engine that this call is traced. | ||
| /// | ||
| /// Behaves exactly like `Call(n)`: pushes a frame, sets up locals. | ||
| /// Additionally, when `tracing_enabled` is true: | ||
| /// 1. Snapshots the arguments from the eval stack | ||
| /// 2. Records the new frame's depth in `traced_frames` | ||
| /// 3. Yields `SpanNotification::FunctionEnter` to the engine | ||
| /// | ||
| /// When `tracing_enabled` is false, behaves identically to `Call(n)`. | ||
| CallWithTrace(usize), |
There was a problem hiding this comment.
I think this is unnecessary, when you Call a function in the VM you get access to a FunctionKind enum, if you add Llm there you don't need a new instruction.
Merging this PR will not alter performance
|
Binary size checks passed✅ 7 passed
Generated by |
|
|
||
| /// Whether this function should be traced (emit span notifications on call/return). | ||
| /// Set to `true` for LLM functions by the compiler. | ||
| pub trace: bool, |
There was a problem hiding this comment.
Redundant trace field duplicates body_meta information
Low Severity
The trace: bool field on Function is set to true exactly when body_meta is Some(FunctionMeta::Llm { .. }), making it fully redundant. Having two fields that must stay in sync risks divergence during future changes. As the reviewer noted, the FunctionKind enum or body_meta already encodes this information and could be checked directly in the VM's Call handler.
Additional Locations (1)
Addressed Antonio's feedback (but need to dismiss the review to be able to merge).
| pub fn id(&self, span_id_str: &str) -> Option<FunctionLog> { | ||
| self.inner.id(span_id_str) | ||
| } | ||
| } |
There was a problem hiding this comment.
Unused bridge_cffi Collector wrapper is dead code
Low Severity
The bridge_cffi::collector::Collector wrapper struct is exported but never imported or used anywhere in the codebase. The bridge_python crate wraps bex_events::Collector directly via its own types::collector::Collector. This entire file is dead code that adds unnecessary indirection.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.
|
|
||
| @property | ||
| def calls(self): | ||
| return [_wrap_log(c) for c in self._inner.calls] |
There was a problem hiding this comment.
FunctionLog.calls wraps LLMCall objects with wrong type
High Severity
The FunctionLog.calls property passes each LLMCall from the Rust layer through _wrap_log, which wraps it in a Python FunctionLog. Since LLMCall lacks id, result, and tags getters, accessing those properties on items returned by calls raises AttributeError at runtime. The items from self._inner.calls are LLMCall objects and need to remain unwrapped or be wrapped in an appropriate LLMCall wrapper.
| pub fn id(&self, span_id_str: &str) -> Option<FunctionLog> { | ||
| self.inner.id(span_id_str) | ||
| } | ||
| } |
There was a problem hiding this comment.
Unused bridge_cffi::collector module duplicates bex_events::Collector
Low Severity
The bridge_cffi::collector::Collector struct is a 1:1 delegation wrapper around bex_events::Collector that adds no logic. It's exported as a public module but never imported or used anywhere in the codebase. bridge_python wraps bex_events::Collector directly via its own PyO3 types instead.
Integrates 4 canary PRs: - #3126: MIR analysis soundness (StatementRef, unified walkers) - #3124: Type variants for type expressions (parse takes Type) - #3122: InitLocals(n) instruction - #3107: Full tracing system (bex_events, Collector) Conflict resolutions: - llm.baml: keep orchestration loop with panic, update parse() to use get_return_type - baml_builtins: keep both Enum and Type TypePattern variants, add get_return_type alongside orchestration builtins - baml_compiler_emit: keep HIDDEN_LLM_BUILTINS removal - baml_compiler_tir: add both Enum and Type arms in substitute functions - bex_vm_types: merge both ClientBuild* and CollectorRef re-exports - llm_render tests: use new 4-arg call_function signature, fix PromptAst FQN


Note
High Risk
Touches core execution (
call_function/VMexec) and heap object model by adding tracing notifications, a new object type, and global event buffering, which can affect runtime behavior and performance across all calls.Overview
Adds end-to-end runtime tracing by introducing a new
bex_eventscrate (span IDs/contexts, in-memory event store with JSONL flush, andCollector/FunctionLogviews) and wiring it intobex_engine.Extends
BexEngine::call_functionto accept an optionalHostSpanContextplus attached collectors, emits root + nested traced span start/end events, and deep-copies VM values for event payloads.Updates the VM/bytecode pipeline to support tracing via a per-function
traceflag (enabled for LLM functions) and newVmExecState::SpanNotifyenter/exit notifications; adds a new heap object/ADT typeCollectorto pass collector handles through the runtime. Tests are updated and new tracing tests are added; workspace/build config is adjusted (new deps, newbridge_pythoncrate, size-gate baselines, and ignoredebug_events*).Written by Cursor Bugbot for commit bf1143c. This will update automatically on new commits. Configure here.
Summary by CodeRabbit
New Features
Improvements
Tests