Skip to content

WorkspaceJsonlSink keeps flushed event bytes in memory for the whole session #3640

@luochen211

Description

@luochen211

Please read this first

  • I have read the Agents SDK docs.
  • I searched for related issues and did not find one for WorkspaceJsonlSink buffer flush memory.

Describe the bug

WorkspaceJsonlSink keeps all emitted event bytes in _buf even after a flush succeeds.

In src/agents/sandbox/session/sinks.py:

def _buffer_event(self, event: SandboxSessionEvent) -> bool:
    self._buf.extend(event_to_json_line(event).encode("utf-8"))
    ...

async def _flush_buffer(self) -> None:
    ...
    await self._session.write(relpath, io.BytesIO(bytes(self._buf)))

_flush_buffer() writes the full buffer to the workspace outbox, but never clears or compacts _buf. For long-running sandbox sessions with many audit events, the client-side buffer grows for the lifetime of the session even when flush_every=1.

This is observable behavior in the sandbox instrumentation/runtime path, not a docs-only issue.

Debug information

  • Agents SDK version: main branch
  • Python version: N/A, code inspection

Repro steps

Minimal code-inspection reproduction:

from pathlib import Path
from agents.sandbox.session.sinks import WorkspaceJsonlSink

sink = WorkspaceJsonlSink(workspace_relpath=Path("logs/events.jsonl"), flush_every=1)

# After each handled event, _buffer_event appends bytes to sink._buf.
# _flush_buffer writes bytes(sink._buf), but does not clear sink._buf after success.
# Therefore len(sink._buf) grows monotonically with event volume.

Code path:

  1. Open src/agents/sandbox/session/sinks.py.
  2. Inspect WorkspaceJsonlSink._buffer_event() and _flush_buffer().
  3. Observe that _buf is appended to for every event.
  4. Observe that _flush_buffer() writes bytes(self._buf) but does not clear _buf after a successful write.

Expected behavior

Either the sink should clear flushed bytes and append to the existing workspace outbox, or it should explicitly document and bound the in-memory full-file rewrite strategy. As implemented, flush_every controls write frequency but not memory growth.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions