Skip to content

fix(agui): isolate HITL sessions by user - #2856

Merged
jujn merged 5 commits into
agentscope-ai:mainfrom
dragondyt:fix/optimize-human-agent-interaction
Aug 27, 2026
Merged

fix(agui): isolate HITL sessions by user#2856
jujn merged 5 commits into
agentscope-ai:mainfrom
dragondyt:fix/optimize-human-agent-interaction

Conversation

@dragondyt

@dragondyt dragondyt commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

Related issues

  • Fixes [Bug]: AG-UI HITL sessions mix tenants by threadId #2855
  • Summary

  • Key ThreadSessionManager / AgentResolver by (userId, threadId) so hasMemory and agent reuse no longer mix tenants.
  • Inspect session memory without closing the live ReActAgent.
  • Keep messages after the last assistant turn, including tool results, so HITL can resume.
  • Do not emit interrupts for frontend tools.
  • Unwrap harness/stop interrupts via AguiUtil.asReActAgent so demo stopThread and processor interrupt target the live session.
  • Add unit coverage for user-scoped sessions, default AgentResolver, lifecycle interrupt filtering, and ProcessResult.interrupt().

Breaking Changes

This PR is source- and behavior-incompatible. Upgrading requires recompilation + minor migration.

API (source-incompatible)

  • AgentResolver#hasMemory(String threadId) -> hasMemory(RuntimeContext). Custom AgentResolver
    implementations must update the signature; the single-arg form is removed.
  • ThreadSessionManager#hasMemory(String threadId) -> hasMemory(RuntimeContext). Callers must pass
    a RuntimeContext carrying userId + sessionId.

Behavior (runtime-incompatible)

  • Session keying changed threadId -> (userId, threadId). Different users on the same thread id no
    longer share an agent instance. Anonymous callers (userId == null) stay on the shared __anon__
    slot, so single-tenant behavior is unchanged.
  • ThreadSessionManager#getSessions() now returns a threadId-keyed snapshot that is lossy when
    multiple users share a thread id; use getSession(userId, threadId) for tenant-safe lookup.
  • AG-UI event stream: frontend/external tools (SchemaOnlyTool / @Tool(externalTool=true)) no longer
    emit a TOOL_SUSPENDED interrupt. Results are delivered via message-based resume (a trailing
    role:"tool" message in the next run's transcript) instead of RunAgentInput.resume.

Key ThreadSessionManager by (userId, threadId) so hasMemory and
agent reuse no longer mix tenants. Inspecting session memory no
longer closes the live ReActAgent. Keep messages after the last
assistant turn, including tool results, so HITL can resume.
Do not emit interrupts for frontend tools.

@dragondyt dragondyt left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

仅在demo的stopThread有遗漏,对核心无影响

@codecov

codecov Bot commented Aug 27, 2026

Copy link
Copy Markdown

Jackson omits the @JsonTypeInfo discriminator when serializing concrete AguiEvent records through Map/bodyValue, and getType() is @JsonIgnore. Encode each replayed event to a map and set type explicitly so CopilotKit can load thread history.

Stop unwraps HarnessAgent via AguiUtil.asReActAgent so interrupt targets the live session without closing it.

Bump the CopilotKit frontend packages to 1.69.2.
@jujn
jujn merged commit a37bfa8 into agentscope-ai:main Aug 27, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: AG-UI HITL sessions mix tenants by threadId

2 participants