Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit7454e49

Browse files
committed
fix: handle new user messages correctly
Two things:1. Message IDs can be zero-based.2. We were not actually updating the last user message ID.I refactored a little to keep track of the last message in lastReport.
1 parent1006b98 commit7454e49

File tree

2 files changed

+64
-18
lines changed

2 files changed

+64
-18
lines changed

‎cli/exp_mcp.go

Lines changed: 34 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -362,11 +362,19 @@ func (*RootCmd) mcpConfigureCursor() *serpent.Command {
362362
}
363363

364364
typetaskReportstruct {
365-
linkstring
366-
messageIDint64
365+
// link is optional.
366+
linkstring
367+
// messageID must be set if this update is from a *user* message. A user
368+
// message only happens when interacting via the AI AgentAPI (as opposed to
369+
// interacting with the terminal directly).
370+
messageID*int64
371+
// selfReported must be set if the update is directly from the AI agent
372+
// (as opposed to the screen watcher).
367373
selfReportedbool
368-
state codersdk.WorkspaceAppStatusState
369-
summarystring
374+
// state must always be set.
375+
state codersdk.WorkspaceAppStatusState
376+
// summary is optional.
377+
summarystring
370378
}
371379

372380
typemcpServerstruct {
@@ -388,17 +396,17 @@ func (r *RootCmd) mcpServer() *serpent.Command {
388396
return&serpent.Command{
389397
Use:"server",
390398
Handler:func(inv*serpent.Invocation)error {
391-
// lastUserMessageID is the ID of the last *user* message that we saw. A
392-
// user message only happens when interacting via the AI AgentAPI (as
393-
// opposed to interacting with the terminal directly).
394-
varlastUserMessageIDint64
395399
varlastReporttaskReport
396400
// Create a queue that skips duplicates and preserves summaries.
397401
queue:= cliutil.NewQueue[taskReport](512).WithPredicate(func(reporttaskReport) (taskReport,bool) {
398-
// Use "working" status if this is a new user message. If this is not a
399-
// new user message, and the status is "working" and not self-reported
400-
// (meaning it came from the screen watcher), then it means one of two
401-
// things:
402+
// If this is a user message, discard if it is not new.
403+
ifreport.messageID!=nil&&
404+
lastReport.messageID!=nil&&*lastReport.messageID>=*report.messageID {
405+
returnreport,false
406+
}
407+
// If this is not a user message, and the status is "working" and not
408+
// self-reported (meaning it came from the screen watcher), then it
409+
// means one of two things:
402410
//
403411
// 1. The AI agent is not working; the user is interacting with the
404412
// terminal directly.
@@ -415,18 +423,27 @@ func (r *RootCmd) mcpServer() *serpent.Command {
415423
// user manually submits a new prompt and the AI agent becomes active
416424
// (and does not update itself), but it avoids spamming useless status
417425
// updates as the user is typing, so the tradeoff is worth it.
418-
ifreport.messageID>lastUserMessageID {
419-
report.state=codersdk.WorkspaceAppStatusStateWorking
420-
}elseifreport.state==codersdk.WorkspaceAppStatusStateWorking&&!report.selfReported&&lastReport.state!="" {
426+
ifreport.messageID==nil&&
427+
report.state==codersdk.WorkspaceAppStatusStateWorking&&
428+
!report.selfReported&&lastReport.state!="" {
421429
returnreport,false
422430
}
431+
// Keep track of the last message ID.
432+
ifreport.messageID==nil {
433+
report.messageID=lastReport.messageID
434+
}
423435
// Preserve previous message and URI if there was no message.
424436
ifreport.summary=="" {
425437
report.summary=lastReport.summary
426438
ifreport.link=="" {
427439
report.link=lastReport.link
428440
}
429441
}
442+
// Avoid queuing empty statuses (this would probably indicate a
443+
// developer error)
444+
ifreport.state=="" {
445+
returnreport,false
446+
}
430447
// Avoid queueing duplicate updates.
431448
ifreport.state==lastReport.state&&
432449
report.link==lastReport.link&&
@@ -607,7 +624,8 @@ func (s *mcpServer) startWatcher(ctx context.Context, inv *serpent.Invocation) {
607624
case agentapi.EventMessageUpdate:
608625
ifev.Role==agentapi.RoleUser {
609626
err:=s.queue.Push(taskReport{
610-
messageID:ev.Id,
627+
messageID:&ev.Id,
628+
state:codersdk.WorkspaceAppStatusStateWorking,
611629
})
612630
iferr!=nil {
613631
cliui.Warnf(inv.Stderr,"Failed to queue update: %s",err)

‎cli/exp_mcp_test.go

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -835,7 +835,7 @@ func TestExpMcpReporter(t *testing.T) {
835835
},
836836
// Agent messages are ignored.
837837
{
838-
event:makeMessageEvent(1,agentapi.RoleAgent),
838+
event:makeMessageEvent(0,agentapi.RoleAgent),
839839
},
840840
// AI agent reports that it failed and URI is blank.
841841
{
@@ -854,7 +854,7 @@ func TestExpMcpReporter(t *testing.T) {
854854
// ... but this time we have a new user message so we know there is AI
855855
// agent activity. This time the "working" update will not be skipped.
856856
{
857-
event:makeMessageEvent(2,agentapi.RoleUser),
857+
event:makeMessageEvent(1,agentapi.RoleUser),
858858
expected:&codersdk.WorkspaceAppStatus{
859859
State:codersdk.WorkspaceAppStatusStateWorking,
860860
Message:"oops",
@@ -895,6 +895,33 @@ func TestExpMcpReporter(t *testing.T) {
895895
URI:"",
896896
},
897897
},
898+
// Zero ID should be accepted.
899+
{
900+
event:makeMessageEvent(0,agentapi.RoleUser),
901+
expected:&codersdk.WorkspaceAppStatus{
902+
State:codersdk.WorkspaceAppStatusStateWorking,
903+
Message:"",
904+
URI:"",
905+
},
906+
},
907+
// Stable again.
908+
{
909+
event:makeStatusEvent(agentapi.StatusStable),
910+
expected:&codersdk.WorkspaceAppStatus{
911+
State:codersdk.WorkspaceAppStatusStateIdle,
912+
Message:"",
913+
URI:"",
914+
},
915+
},
916+
// Next ID.
917+
{
918+
event:makeMessageEvent(1,agentapi.RoleUser),
919+
expected:&codersdk.WorkspaceAppStatus{
920+
State:codersdk.WorkspaceAppStatusStateWorking,
921+
Message:"",
922+
URI:"",
923+
},
924+
},
898925
},
899926
},
900927
}
@@ -954,6 +981,7 @@ func TestExpMcpReporter(t *testing.T) {
954981
casew,ok:=<-watcher:
955982
require.True(t,ok,"watch channel closed")
956983
ifw.LatestAppStatus!=nil&&w.LatestAppStatus.ID!=lastAppStatus.ID {
984+
t.Logf("Got status update: %s > %s",lastAppStatus.State,w.LatestAppStatus.State)
957985
lastAppStatus=*w.LatestAppStatus
958986
returnlastAppStatus
959987
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp