feat(instrument): typed events Bundle #3 — google_adk + llama_index + ms_agent_framework#151
Closed
mmercuri wants to merge 3 commits into
Conversation
Migrate all 11 emission sites in google_adk lifecycle.py from emit_dict_event(...) to emit_event(TypedModel.create(...)) using the canonical Pydantic models from layerlens.instrument._compat.events (PR #129 foundation). Sites migrated (grep-counted, not estimated): - _before_agent_callback -> AgentInputEvent - _after_agent_callback -> AgentOutputEvent - _after_model_callback -> ModelInvokeEvent + CostRecordEvent - _after_tool_callback -> ToolCallEvent - on_agent_start -> AgentInputEvent - on_agent_end -> AgentOutputEvent - on_handoff -> AgentHandoffEvent (sha256:<hex64> format) - on_tool_use -> ToolCallEvent - on_llm_call -> ModelInvokeEvent - _emit_agent_config -> EnvironmentConfigEvent Total: 11 emission sites (matches estimate). ADK-specific provenance (framework, agent_name, timestamp_ns, session_id, description, instruction) is carried on canonical metadata / attributes / parameters slots. Helpers added: - _stringify: coerce ADK Content/dict/None to canonical message string - _sha256_of: produce sha256:<hex64> for handoff context hash - _coerce_to_dict: wrap scalar tool input/output in {value: ...} - _detect_provider: derive provider from model identifier (Gemini default) Regression tests added: - test_google_adk_lifecycle_emits_typed_payloads_only — every emission is a Pydantic model instance, not a dict - test_google_adk_emit_does_not_warn_after_migration — no DeprecationWarning fires from any lifecycle path mypy --strict: clean (2 source files) pytest: 15/15 passing
Migrate all 12 emission sites in llama_index lifecycle.py from emit_dict_event(...) to emit_event(TypedModel.create(...)) using the canonical Pydantic models from layerlens.instrument._compat.events (PR #129 foundation). Sites migrated (grep-counted, not estimated): - _on_llm_end -> ModelInvokeEvent + CostRecordEvent (when usage) - _on_tool_call -> ToolCallEvent - _on_retrieval_end -> ToolCallEvent (name=retrieval, library) - _on_agent_step_start -> AgentInputEvent - _on_agent_step_end -> AgentOutputEvent - on_agent_start -> AgentInputEvent - on_agent_end -> AgentOutputEvent - on_tool_use -> ToolCallEvent - on_llm_call -> ModelInvokeEvent - on_handoff -> AgentHandoffEvent (sha256:<hex64> format) - _emit_agent_config -> EnvironmentConfigEvent Total: 12 emission sites (matches estimate). LlamaIndex-specific provenance (framework, agent_name, step, timestamp_ns, tool_type, result_count) is carried on canonical metadata / attributes / parameters / input slots. Retrieval events map onto ToolCallEvent with name='retrieval' and integration=IntegrationType.LIBRARY — the canonical schema has no dedicated retrieval shape, mirroring agno reference adapter. Helpers added: _stringify, _coerce_to_dict, _sha256_of, _detect_provider. Regression tests added: - test_llama_index_lifecycle_emits_typed_payloads_only - test_llama_index_emit_does_not_warn_after_migration mypy --strict: clean (2 source files) pytest: 15/15 passing
Migrate all 12 emission sites in ms_agent_framework lifecycle.py from emit_dict_event(...) to emit_event(TypedModel.create(...)) using the canonical Pydantic models from layerlens.instrument._compat.events (PR #129 foundation). Sites migrated (grep-counted, not estimated): - _process_message handoff -> AgentHandoffEvent - _process_message FunctionCall -> ToolCallEvent (input) - _process_message FunctionResult -> ToolCallEvent (output) - _process_message model metadata -> ModelInvokeEvent - _process_message usage metadata -> CostRecordEvent - on_run_start -> AgentInputEvent - on_run_end (output) -> AgentOutputEvent - on_run_end (state.change) -> COLLAPSED into AgentOutputEvent metadata - on_tool_use -> ToolCallEvent - on_llm_call -> ModelInvokeEvent - on_handoff -> AgentHandoffEvent (sha256:<hex64> format) - _emit_chat_config -> EnvironmentConfigEvent Total: 12 emission sites (matches estimate). Behavioural change: the previous adapter emitted an ad-hoc agent.state.change payload alongside agent.output to carry a run_complete / run_failed marker. That payload did not satisfy the canonical AgentStateChangeEvent before_hash / after_hash contract (the run boundary has no real state mutation to hash). The post- migration mapping carries the same signal as run_status on the AgentOutputEvent metadata, preserving the cross-cutting completion marker without violating the canonical schema. Test coverage updated to assert agent.state.change is no longer emitted and run_status is on AgentOutputEvent.metadata. MS Agent Framework-specific provenance (framework, agent_name, chat_name, chat_type, timestamp_ns, selection_strategy, termination_strategy, plugins) is carried on canonical metadata / attributes / parameters / input slots. Helpers added: _stringify, _coerce_to_dict, _sha256_of. Regression tests added: - test_ms_agent_framework_lifecycle_emits_typed_payloads_only - test_ms_agent_framework_emit_does_not_warn_after_migration mypy --strict: clean (2 source files) pytest: 16/16 passing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Migrates the next 3 framework adapters from
emit_dict_event(...)to typedemit_event(TypedModel.create(...))against the canonical Pydantic modelsfrom
layerlens.instrument._compat.events(PR #129 foundation).This is Bundle #3 of 6 in the typed-events migration series. Bundle
#1 (PR #129) shipped the foundation + agno reference. Bundle #2 (PR #138)
shipped autogen + crewai + smolagents. This bundle ships google_adk +
llama_index + ms_agent_framework.
Honest site counts (grep, not estimated)
Per CLAUDE.md item 11 — counts verified with
grep -E 'emit_dict_event' src/.../<adapter>/:google_adkllama_indexms_agent_frameworkEstimates were honest in this bundle.
Per-adapter status
google_adk (commit
ffa1aca)_stringify,_sha256_of,_coerce_to_dict,_detect_providerno-DeprecationWarning assertion
llama_index (commit
4fc3a29)ToolCallEventwithname="retrieval",integration=IntegrationType.LIBRARY(no canonical retrieval shape;mirrors agno reference)
_stringify,_coerce_to_dict,_sha256_of,_detect_providerms_agent_framework (commit
0917481)agent.state.changepayload alongsideagent.outputcarrying arun_complete/run_failedmarker. That payload did not satisfythe canonical
AgentStateChangeEventbefore_hash/after_hashcontract (no real state mutation to hash at the run boundary).
The post-migration mapping carries the same signal as
run_statuson
AgentOutputEvent.metadata— preserves the cross-cuttingcompletion marker without violating the canonical schema.
_stringify,_coerce_to_dict,_sha256_ofCombined verification
Multi-tenancy compliance
Per PR #129 foundation:
BaseAdapter.emit_eventstampsorg_idontoevery typed payload before delegating to
self._stratix.emit(...).No emit site in this bundle bypasses the typed path, so every
emission is tenant-scoped by construction.
Test plan
uv run mypy --strictpassesemit_dict_eventcall replaced(
grep -c 'emit_dict_event' = 0)emission shape on the wire
agent.state.changecollapse is the right call (vs. emitting a synthetic state-
change with hashed metadata)
Bundle progression