fix(agent): propagate SenderID in AgentEvent emitters

Expose the original acting sender ID in agent events so group-chat
telemetry and audit logs stay aligned with the real Telegram user
instead of only the group-scoped UserID.
This commit is contained in:
viettranx
2026-04-17 20:45:48 +07:00
parent 680521a882
commit a29938ceed
5 changed files with 10 additions and 1 deletions
@@ -28,6 +28,7 @@ func (l *Loop) pipelineCallbacks(req *RunRequest, bridgeRS *runState) pipelineCa
event.TeamID = req.TeamID
event.TeamTaskID = req.TeamTaskID
event.ParentAgentID = req.ParentAgentID
event.SenderID = req.SenderID
event.UserID = req.UserID
event.Channel = req.Channel
event.ChatID = req.ChatID
@@ -222,6 +222,7 @@ func makeToolEmitRun(l *Loop, req *RunRequest) func(AgentEvent) {
return func(event AgentEvent) {
event.RunKind = req.RunKind
event.SessionKey = req.SessionKey
event.SenderID = req.SenderID
event.UserID = req.UserID
event.Channel = req.Channel
l.emit(event)
@@ -71,6 +71,7 @@ func TestMakeExecuteToolCall_EmitsToolCallEvent(t *testing.T) {
RunID: "run-1",
SessionKey: "sess-A",
UserID: "u-1",
SenderID: "sender-1",
Channel: "ws",
RunKind: "",
}
@@ -102,6 +103,7 @@ func TestMakeExecuteToolRaw_EmitsToolCallEvent(t *testing.T) {
RunID: "run-2",
SessionKey: "sess-B",
UserID: "u-2",
SenderID: "sender-2",
Channel: "ws",
RunKind: "",
}
@@ -133,7 +135,7 @@ func TestMakeExecuteToolRaw_ConcurrentCallsEmitAllEvents(t *testing.T) {
col := &eventCollector{}
l := newTestLoopForToolCallbacks(col.onEvent)
req := &RunRequest{RunID: "run-3", SessionKey: "sess-C", UserID: "u-3", Channel: "ws"}
req := &RunRequest{RunID: "run-3", SessionKey: "sess-C", UserID: "u-3", SenderID: "sender-3", Channel: "ws"}
exec := l.makeExecuteToolRaw(req)
const n = 5
@@ -175,6 +177,9 @@ func assertToolCallPayload(t *testing.T, ev AgentEvent, tc providers.ToolCall, r
if ev.UserID != req.UserID {
t.Errorf("UserID: got %q, want %q", ev.UserID, req.UserID)
}
if ev.SenderID != req.SenderID {
t.Errorf("SenderID: got %q, want %q", ev.SenderID, req.SenderID)
}
payload, ok := ev.Payload.(map[string]any)
if !ok {
t.Fatalf("Payload is not map[string]any: %T", ev.Payload)
+1
View File
@@ -26,6 +26,7 @@ func (l *Loop) Run(ctx context.Context, req RunRequest) (*RunResult, error) {
event.TeamID = req.TeamID
event.TeamTaskID = req.TeamTaskID
event.ParentAgentID = req.ParentAgentID
event.SenderID = req.SenderID
event.UserID = req.UserID
event.Channel = req.Channel
event.ChatID = req.ChatID
+1
View File
@@ -277,6 +277,7 @@ type AgentEvent struct {
ParentAgentID string `json:"parentAgentId,omitempty"`
// Routing context (helps WS clients filter by user/channel/session)
SenderID string `json:"senderId,omitempty"` // original acting user; differs from UserID in group chats
UserID string `json:"userId,omitempty"`
Channel string `json:"channel,omitempty"`
ChatID string `json:"chatId,omitempty"`