Repository navigation
Conversation
…put (SAO-19572)
When an app re-sends the whole conversation as graph state (for example a
LangGraph {"messages": [...]} state), every agent and workflow span exported
all earlier turns in gen_ai.input.messages. Each new trace's input therefore
repeated the previous inputs and outputs, and O11y Cloud rendered them as one
growing block.
Trim the exported input of full-history message containers to the messages
from the last user message onward, so tool-call and tool-response messages of
the current turn are kept. The untrimmed input is still used for the existing
output history dedup. Partial update containers, bare lists, inputs without a
user message, and LLM span inputs (the full prompt sent to the model) are
unchanged.
Co-Authored-By: Claude <noreply@anthropic.com>
…(SAO-19572)
The first change only trimmed inputs shaped as {"messages": [...]} graph
state. The LangChain agent middleware logs the agent input as a bare list of
messages, so create_agent apps still repeated every earlier turn in each new
trace's input (root input 1 / 5 / 9 messages over three turns).
Trim a bare list of role-tagged messages the same way: keep the messages from
the last user message onward. Partial update containers, single-turn lists,
lists with no user message, and LLM span inputs are unchanged. A workflow or
agent input that is deliberately a message list (for example few-shot
examples) is trimmed too, because it cannot be told apart from conversation
state.
Co-Authored-By: Claude <noreply@anthropic.com>
…re, OpenAI Agents, CrewAI (SAO-19572) Add one end-to-end regression test per integration that re-sends the whole conversation over three turns and asserts what the root span exports: - LangGraph callback handler: root and node input stay at the current user question; the chat span keeps the full prompt (1, 3, 5 messages). - LangChain agent middleware: same, for the bare message-list state it logs. - OpenAI Agents: the workflow input is the latest user message (pins existing behaviour); the chat span keeps the full prompt. - CrewAI: kickoff inputs that carry the conversation export only the current question; the chat span keeps every earlier question. The LangGraph handler, middleware and CrewAI tests fail on origin/main without the converter change; the OpenAI Agents test is a guard and passes on both. Co-Authored-By: Claude <noreply@anthropic.com>
This branch has not been deployed
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.
Problem
When an app re-sends the whole conversation (as graph state or as a message list), every agent and workflow span
exported all earlier turns in
gen_ai.input.messages. Each new trace's input repeated the previous inputs and outputs,and O11y Cloud rendered them as one block that grows with the conversation. The output side already trims history; the
input side did not.
Change
_set_orchestration_contentnow trims the exported input to the messages from the last user message onward, when theinput is either a
{"messages": [...]}state container or a bare list of role-tagged messages (the shape the LangChainagent middleware logs). Tool-call and tool-response messages of the current turn are kept. The untrimmed input is still
used for the existing output history dedup.
Unchanged: partial
updatecontainers, single-turn inputs, inputs with no user message, and LLM (chat) span inputs(see Notes).
Verification
Multi-turn runs (3 turns, the full history re-sent each turn), spans captured on a local collector. Message counts of
the root agent or workflow span input per trace, before → after:
create_agent+SplunkAOMiddlewarechromadbwheel for macOS arm64Inner
chatbot,tools_conditionandtoolsspans of the LangGraph run now show only their own turn, and the lab0session view shows each question once. Chat span inputs are identical before and after in every run.
tests/test_attribute_mapping.py: 75 passed, including 15 new cases (behaviours and guards, with most run for bothworkflow and agent spans). The cases for the first change failed before it.
ruff check,ruff format --checkon the changed files, andmypy(invoke type-check) pass.serialization and two collection errors. The identical set fails on unmodified
origin/main, so none come fromthis change.
Notes
LLM span inputs.
gen_ai.input.messagesrecords the exact messages the frameworksent to the model (system prompt, earlier turns, tool calls and results), so it is not trimmed. In the
verification run, the third turn's chat span input held 6 messages (system, then the whole conversation), and its
follow-up call after the tool call held 8. Only agent and workflow spans carry app state rather than a prompt, so
only they are trimmed. This is how the LLM span path already worked (
set_llm_attributeswritesspan.inputasis), and this PR does not change it.
deliberately a message list (for example few-shot examples or a system prompt) is trimmed to the current turn too.
tests/test_langchain_middleware.pyalready errors at collection on
origin/main. The live run above is the evidence for that path.CHANGELOG.mdupdated under Unreleased.