Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/loongsuite_test_0.yml

Large diffs are not rendered by default.

8 changes: 8 additions & 0 deletions CHANGELOG-loongsuite.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased

### Added

- Test LoongSuite instrumentation packages and `loongsuite-distro` on Python
3.14 and add the Python 3.14 classifier. CrewAI, LangChain, OpenHands and
QwenPaw stay on Python 3.13 and older: `crewai`, `openhands-ai` and `qwenpaw`
require Python < 3.14, and the LangChain tests use `langchain` 0.3, whose
`langchain.chains` does not import on Python 3.14.

## Version 0.9.0 (2026-09-07)

### Added
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
]
dependencies = [
"opentelemetry-api >= 1.37.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
]
dependencies = [
"opentelemetry-api ~= 1.37",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,15 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## Unreleased

### Fixed

- Close the Agno stream when an application stops reading an instrumented
streaming agent run early (`close()`, `aclose()`, `break`), so Agno's own
cleanup runs at that point. The abandoned stream was otherwise only
finalized by the garbage collector, which ended its model span late and could
set an ended span from that run as the current OpenTelemetry context in
whatever code was running at the time.

## Version 0.9.0 (2026-09-07)

There are no changelog entries for this release.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
]
dependencies = [
"opentelemetry-api ~= 1.37",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,18 @@ def _is_stream_close(exc: BaseException) -> bool:
return isinstance(exc, (GeneratorExit, StopIteration, StopAsyncIteration))


def _close_stream(stream: Any) -> None:
close = getattr(stream, "close", None)
if close is not None:
close()


async def _aclose_stream(stream: Any) -> None:
aclose = getattr(stream, "aclose", None)
if aclose is not None:
await aclose()


@dataclass
class _AgnoRunState:
handler: ExtendedTelemetryHandler
Expand Down Expand Up @@ -279,6 +291,7 @@ def generator() -> Iterator[Any]:
error = None
state = None
state_token = None
stream = None
self._handler.start_invoke_agent(
invocation, context=parent_context
)
Expand Down Expand Up @@ -336,6 +349,10 @@ def exit_run_state() -> None:
finalized = True
except BaseException as exc:
error = exc
# Close the Agno stream before this run's spans end, so its
# cleanup runs now rather than whenever the garbage collector
# frees the suspended generator.
_close_stream(stream)
raise
finally:
try:
Expand Down Expand Up @@ -450,6 +467,7 @@ async def _arun_stream(
error = None
state = None
state_token = None
stream = None
self._handler.start_invoke_agent(invocation, context=parent_context)
identity_token = None
state = _AgnoRunState(
Expand Down Expand Up @@ -505,6 +523,10 @@ def exit_run_state() -> None:
finalized = True
except BaseException as exc:
error = exc
# Close the Agno stream before this run's spans end, so its
# cleanup runs now rather than whenever the garbage collector
# frees the suspended generator.
await _aclose_stream(stream)
raise
finally:
try:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -815,6 +815,8 @@ def test_streaming_agent_span_finishes_when_consumer_breaks(

spans = _spans_by_name(span_exporter)
assert "invoke_agent BreakAgent" in spans
# Closing the stream closes Agno's stream too, which ends its model span.
assert "chat echo-model" in spans
agent_attrs = spans["invoke_agent BreakAgent"].attributes
assert agent_attrs["gen_ai.span.kind"] == "AGENT"
assert "he" in agent_attrs["gen_ai.output.messages"]
Expand Down Expand Up @@ -915,6 +917,47 @@ async def run_agent():
assert "gen_ai.session.id" not in tool_attrs


def test_async_streaming_agent_closes_agno_stream_when_consumer_breaks(
span_exporter: InMemorySpanExporter,
):
agno_stream_closed = []

async def agno_stream(*args: Any, **kwargs: Any) -> AsyncIterator[Any]:
try:
yield SimpleNamespace(content="he")
yield SimpleNamespace(content="llo")
finally:
agno_stream_closed.append(True)

agent = SimpleNamespace(
name="AsyncBreakAgent",
id="agent-id",
model=EchoModel(),
tools=[],
instructions=[],
)
wrapper = AgnoAgentWrapper(get_extended_telemetry_handler())

async def run_agent():
stream = wrapper._arun_stream(
agno_stream,
agent,
("stream please",),
{},
{"input": "stream please"},
otel_context.get_current(),
)
first_chunk = await stream.__anext__()
assert first_chunk.content == "he"
await stream.aclose()
# Check before asyncio.run() closes leftover async generators.
return list(agno_stream_closed)

assert asyncio.run(run_agent()) == [True]
spans = _spans_by_name(span_exporter)
assert "invoke_agent AsyncBreakAgent" in spans


def test_tool_call_loop_emits_react_steps_and_split_llm_spans(
span_exporter: InMemorySpanExporter,
):
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
]
dependencies = [
"opentelemetry-api >= 1.37.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
]
dependencies = [
"opentelemetry-api ~= 1.37",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
]
dependencies = [
"opentelemetry-api >= 1.37.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
]
dependencies = [
"opentelemetry-api ~= 1.37",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
]
dependencies = [
"opentelemetry-api >= 1.37.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
]
dependencies = [
"opentelemetry-api ~= 1.37",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
]
dependencies = [
"loongsuite-instrumentation-langchain",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
]

dependencies = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
]
dependencies = [
"opentelemetry-api >= 1.37.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
]
dependencies = [
"opentelemetry-api >= 1.37.0, < 1.40",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
]
dependencies = [
"opentelemetry-api ~= 1.37",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
]
dependencies = [
"opentelemetry-api >= 1.37.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
]
dependencies = [
"opentelemetry-api >= 1.37.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ conventions** and should be treated as experimental.

## Compatibility

- Python: `>= 3.8, <= 3.13`
- Python: `>= 3.8, <= 3.14`
- Mem0 / `mem0ai`: `>= 1.0.0`
- OpenTelemetry API: `>= 1.20.0`

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
]
dependencies = [
"wrapt >=1.17.3, < 2.0.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
]
dependencies = [
"opentelemetry-api ~= 1.37",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
]
dependencies = [
"opentelemetry-api >= 1.37.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
]
dependencies = [
"opentelemetry-api ~= 1.37",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
]
dependencies = [
"opentelemetry-api >= 1.37.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
]
dependencies = [
"opentelemetry-api ~= 1.37",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
]
dependencies = [
"opentelemetry-api >= 1.37.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
]
dependencies = [
"opentelemetry-api >= 1.37.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
]
dependencies = [
"opentelemetry-api >= 1.37.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
]
dependencies = [
"opentelemetry-api ~= 1.37",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
]
dependencies = [
"opentelemetry-api ~= 1.37",
Expand Down
1 change: 1 addition & 0 deletions loongsuite-distro/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ classifiers = [
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: 3.14",
"Typing :: Typed",
]
dependencies = [
Expand Down
Loading
Loading