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

fix: initial app status and zero-based id#18622

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to ourterms of service andprivacy statement. We’ll occasionally send you account related emails.

Already on GitHub?Sign in to your account

Open
code-asher wants to merge2 commits intomain
base:main
Choose a base branch
Loading
fromasher/fix-initial-status
Open
Show file tree
Hide file tree
Changes fromall commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 51 additions & 25 deletionscli/exp_mcp.go
View file
Open in desktop
Original file line numberDiff line numberDiff line change
Expand Up@@ -362,11 +362,19 @@ func (*RootCmd) mcpConfigureCursor() *serpent.Command {
}

type taskReport struct {
link string
messageID int64
// link is optional.
link string
// messageID must be set if this update is from a *user* message. A user
// message only happens when interacting via the AI AgentAPI (as opposed to
// interacting with the terminal directly).
messageID *int64
// selfReported must be set if the update is directly from the AI agent
// (as opposed to the screen watcher).
selfReported bool
state codersdk.WorkspaceAppStatusState
summary string
// state must always be set.
state codersdk.WorkspaceAppStatusState
// summary is optional.
summary string
}

type mcpServer struct {
Expand All@@ -388,31 +396,48 @@ func (r *RootCmd) mcpServer() *serpent.Command {
return &serpent.Command{
Use: "server",
Handler: func(inv *serpent.Invocation) error {
// lastUserMessageID is the ID of the last *user* message that we saw. A
// user message only happens when interacting via the AI AgentAPI (as
// opposed to interacting with the terminal directly).
var lastUserMessageID int64
var lastReport taskReport
// Create a queue that skips duplicates and preserves summaries.
queue := cliutil.NewQueue[taskReport](512).WithPredicate(func(report taskReport) (taskReport, bool) {
// Use "working" status if this is a new user message. If this is not a
// new user message, and the status is "working" and not self-reported
// (meaning it came from the screen watcher), then it means one of two
// things:
// 1. The AI agent is still working, so there is nothing to update.
// 2. The AI agent stopped working, then the user has interacted with
// the terminal directly. For now, we are ignoring these updates.
// This risks missing cases where the user manually submits a new
// prompt and the AI agent becomes active and does not update itself,
// but it avoids spamming useless status updates as the user is
// typing, so the tradeoff is worth it. In the future, if we can
// reliably distinguish between user and AI agent activity, we can
// change this.
if report.messageID > lastUserMessageID {
report.state = codersdk.WorkspaceAppStatusStateWorking
} else if report.state == codersdk.WorkspaceAppStatusStateWorking && !report.selfReported {
// Avoid queuing empty statuses (this would probably indicate a
// developer error)
if report.state == "" {
return report, false
}
// If this is a user message, discard if it is not new.
if report.messageID != nil && lastReport.messageID != nil &&
*lastReport.messageID >= *report.messageID {
return report, false
}
// If this is not a user message, and the status is "working" and not
// self-reported (meaning it came from the screen watcher), then it
// means one of two things:
//
// 1. The AI agent is not working; the user is interacting with the
// terminal directly.
// 2. The AI agent is working.
//
// At the moment, we have no way to tell the difference between these
// two states. In the future, if we can reliably distinguish between
// user and AI agent activity, we can change this.
//
// If this is our first update, we assume it is the AI agent working and
// accept the update.
//
// Otherwise we discard the update. This risks missing cases where the
// user manually submits a new prompt and the AI agent becomes active
// (and does not update itself), but it avoids spamming useless status
// updates as the user is typing, so the tradeoff is worth it.
if report.messageID == nil &&
report.state == codersdk.WorkspaceAppStatusStateWorking &&
!report.selfReported && lastReport.state != "" {
return report, false
}
// Keep track of the last message ID so we can tell when a message is
// new or if it has been re-emitted.
if report.messageID == nil {
report.messageID = lastReport.messageID
}
// Preserve previous message and URI if there was no message.
if report.summary == "" {
report.summary = lastReport.summary
Expand DownExpand Up@@ -600,7 +625,8 @@ func (s *mcpServer) startWatcher(ctx context.Context, inv *serpent.Invocation) {
case agentapi.EventMessageUpdate:
if ev.Role == agentapi.RoleUser {
err := s.queue.Push(taskReport{
messageID: ev.Id,
messageID: &ev.Id,
state: codersdk.WorkspaceAppStatusStateWorking,
})
if err != nil {
cliui.Warnf(inv.Stderr, "Failed to queue update: %s", err)
Expand Down
Loading
Loading

[8]ページ先頭

©2009-2025 Movatter.jp