Skip to content

fix(harness/examples): Fix the reading of historical sessions of the data agent in examples - #2946

Open
xy-ygz wants to merge 2 commits into
agentscope-ai:mainfrom
xy-ygz:fix/fix_historical_sessions_reading
Open

fix(harness/examples): Fix the reading of historical sessions of the data agent in examples#2946
xy-ygz wants to merge 2 commits into
agentscope-ai:mainfrom
xy-ygz:fix/fix_historical_sessions_reading

Conversation

@xy-ygz

@xy-ygz xy-ygz commented Sep 2, 2026

Copy link
Copy Markdown

AgentScope-Java Version

2.0.3-SNAPSHOT

Description

Background
After the data-agent is launched locally, clicking on the history session fails to display any information and remains blank. An error message "No active sandbox" is also displayed. Please refer to the attached image.:
dataAgent-你好
沙箱绑定出错

Fixes #1626

Root causes:
There are issues throughout the entire read-write link. Looking at the current source code design, when writing messages, they are first written to the local workspace on the host machine, and then asynchronously segmented and written to the corresponding workspace in the sandbox. When reading, it starts by reading the sandbox, and if the sandbox cannot be read, it then reads the local fallback. The idea is fine, but there are flaws in the implementation:

  1. Write: If the conversation content is normal, it will be written to agents//sessions/.log.jsonl. It is written locally normally. However, when the sandbox part is enabled and segment-based transcription is activated (default is enabled), flush only asynchronously writes events/segments. This does not align with the local content and misses the conversation content part. When the UI reads the sandbox, it will definitely not be able to read it (the content is empty []).
    Also, there is an inconsistency in AgentId used for sandbox operations:
  • When writing via gateway, the AgentId is obtained from HarnessAgent.getAgentId();
  • When reading sandbox content for history fetching and workspace‑UI rendering, the hard‑coded value "data agent" is used instead.
    Even if data is asynchronously written into the sandbox successfully, reading will return empty results due to this mismatched sandbox AgentId.
  1. Reading: "Get /api/agents/{agentId}/sessions/{key}", if it is done normally, it will first read the sandbox (SandboxBackedFilesystem). Before the agent reads the file, it will call requireSandbox (it must first obtain the "current round" bound sandbox), and the binding relationship of the sandbox only exists during the Agent.call execution phase. Reading history is a separate HTTP read request and will not start another round of Agent.call. If the binding relationship of the sandbox is obtained after the Agent.call execution is over, it will definitely be null → directly throw "No active sandbox", and the host machine's fallback will definitely not work.

Repair Ideas
1.When writing the sandbox asynchronously, you can directly use the existing (userId, agentId) → sandbox registration table (WorkspaceManagerFactory) to get the corresponding sandbox for the session, without relying on the sandbox dependency bound by the Agent.call phase. Avoid the problem of No active sandbox
2.Supplement the .jsonl / .log.jsonl session content during asynchronous segmented writes to the sandbox environment, aligning with local file paths to prevent loss of sandbox session data.
3.Make the agentId used by Gateway when mounting the sandbox consistent with gatewayAgentId used on the directory and UI side.
Changes

Aligned with the repair approach above:

  1. History read without call-bound sandbox
    SessionController no longer uses the call-scoped sandbox FS for GET .../sessions/{key}. It borrows the live sandbox from the existing (userId, agentId) registry via WorkspaceManagerFactory, so history HTTP never depends on an in-flight Agent.call binding and no longer throws No active sandbox before host fallback. If the sandbox is empty/unavailable, it falls back to the namespaced host workspace path.

  2. Async write: keep segments, also mirror canonical session files
    SessionTree.flush still appends TranscriptStore segments, and also async-mirrors canonical .jsonl / .log.jsonl (same relative paths as local). PinnedSandboxFilesystem (+ ObjectStoreTranscriptStore#withFilesystem) pins the sandbox at schedule time so the async upload can finish after call unbind. Window before the mirror lands is covered by local fallback.

  3. Same sandbox key for write and UI/history read
    HarnessGateway borrows the sandbox with catalog/UI gatewayAgentId (e.g. data-agent), not the internal harness UUID, so chat write and history/workspace read hit the same registry entry.

After fixing the above issue, I discovered another bug related to session deletion: new‑session entries could not be added after deleting historical sessions, and clicking to create a new session had no response.When deleting a session, entries are only removed from SessionAgentManager, while the in‑memory mapping contextKeyToSessionKey (gateKey → sessionKey) is not cleared.
This change also addresses this problem. isSessionFresh now treats deleted sessions as non‑fresh. Consequently, a new MAIN session will be re‑registered once the user clears history records, so the inbox can correctly display subsequent chat messages again.

How to test

After fix:
修复后-你好
Now the session‑history sidebar can display correctly after deleting old sessions and creating new ones.

How to test

  1. mvn -pl agentscope-harness,agentscope-examples/agents/agentscope-dataagent -am test (or at least -Dtest=SessionTreeMirrorTest).
  2. Run DataAgent → chat → open history → turns load (no No active sandbox).
  3. Delete all sessions → send again → inbox shows a new session.
  4. Optional: same process after a turn → history hits sandbox; after JVM restart (empty registry) → local fallback still works.

Checklist

Please check the following items before code is ready to be reviewed.

  • Code has been formatted with mvn spotless:apply
  • All tests are passing (mvn test) — verified: mvn -pl agentscope-harness,agentscope-examples/agents/agentscope-dataagent -am test (BUILD SUCCESS)
  • Javadoc comments are complete and follow project conventions
  • Related documentation has been updated (e.g. links, examples, etc.)
  • Code is ready for review

@xy-ygz
xy-ygz force-pushed the fix/fix_historical_sessions_reading branch from 4888429 to 6f0f0ee Compare September 2, 2026 14:06
@xy-ygz
xy-ygz force-pushed the fix/fix_historical_sessions_reading branch from 6f0f0ee to 86ddf8e Compare September 2, 2026 14:29
@codecov

codecov Bot commented Sep 2, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 78.57143% with 6 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
...cope/harness/agent/memory/session/SessionTree.java 77.27% 2 Missing and 3 partials ⚠️
...nt/filesystem/sandbox/PinnedSandboxFilesystem.java 80.00% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

如何加载历史对话?

1 participant