mirror of
https://github.com/coder/coder.git
synced 2026-06-02 20:48:20 +00:00
feat(agent/proto): add v2.10 PushContextState RPC
Add the ContextResource, PushContextStateRequest, and PushContextStateResponse messages plus a new PushContextState RPC on the Agent API. Bumps the tailnet+agent shared CurrentVersion to 2.10 and adds the DRPCAgentClient210 interface, plus ConnectRPC210/ConnectRPC210WithRole on codersdk/agentsdk's Client. Reserved kinds (PLUGIN, HOOK, SUBAGENT, COMMAND) ship in the enum but are not emitted by v1 agents. The wire shape matches the workspace context sources RFC. Coderd's server-side handler arrives separately.
This commit is contained in:
+743
-245
File diff suppressed because it is too large
Load Diff
@@ -538,6 +538,59 @@ message UpdateAppStatusRequest {
|
|||||||
|
|
||||||
message UpdateAppStatusResponse {}
|
message UpdateAppStatusResponse {}
|
||||||
|
|
||||||
|
// ContextResource is a single resolved workspace context
|
||||||
|
// resource (instruction file, skill meta, MCP config, or live
|
||||||
|
// MCP server tool list) pushed from the agent to coderd as part
|
||||||
|
// of a PushContextStateRequest snapshot.
|
||||||
|
//
|
||||||
|
// Reserved kinds (PLUGIN, HOOK, SUBAGENT, COMMAND) are not
|
||||||
|
// emitted by v2.10 agents; they are forward-compatible slots
|
||||||
|
// for the Claude Code plugin RFC.
|
||||||
|
message ContextResource {
|
||||||
|
string id = 1;
|
||||||
|
enum Kind {
|
||||||
|
KIND_UNSPECIFIED = 0;
|
||||||
|
INSTRUCTION_FILE = 1;
|
||||||
|
SKILL = 2;
|
||||||
|
MCP_CONFIG = 3;
|
||||||
|
MCP_SERVER = 4;
|
||||||
|
PLUGIN = 5;
|
||||||
|
HOOK = 6;
|
||||||
|
SUBAGENT = 7;
|
||||||
|
COMMAND = 8;
|
||||||
|
}
|
||||||
|
enum Status {
|
||||||
|
STATUS_UNSPECIFIED = 0;
|
||||||
|
OK = 1;
|
||||||
|
OVERSIZE = 2;
|
||||||
|
UNREADABLE = 3;
|
||||||
|
INVALID = 4;
|
||||||
|
EXCLUDED = 5;
|
||||||
|
}
|
||||||
|
Kind kind = 2;
|
||||||
|
string source = 3;
|
||||||
|
bytes content_hash = 4;
|
||||||
|
bytes payload = 5;
|
||||||
|
optional string source_path = 6;
|
||||||
|
Status status = 7;
|
||||||
|
uint64 size_bytes = 8;
|
||||||
|
string error = 9;
|
||||||
|
string description = 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
message PushContextStateRequest {
|
||||||
|
uint64 version = 1;
|
||||||
|
bytes aggregate_hash = 2;
|
||||||
|
repeated ContextResource resources = 3;
|
||||||
|
bool initial = 4;
|
||||||
|
uint64 schema_version = 5;
|
||||||
|
string snapshot_error = 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
message PushContextStateResponse {
|
||||||
|
bool accepted = 1;
|
||||||
|
}
|
||||||
|
|
||||||
service Agent {
|
service Agent {
|
||||||
rpc GetManifest(GetManifestRequest) returns (Manifest);
|
rpc GetManifest(GetManifestRequest) returns (Manifest);
|
||||||
rpc GetServiceBanner(GetServiceBannerRequest) returns (ServiceBanner);
|
rpc GetServiceBanner(GetServiceBannerRequest) returns (ServiceBanner);
|
||||||
@@ -557,4 +610,5 @@ service Agent {
|
|||||||
rpc ListSubAgents(ListSubAgentsRequest) returns (ListSubAgentsResponse);
|
rpc ListSubAgents(ListSubAgentsRequest) returns (ListSubAgentsResponse);
|
||||||
rpc ReportBoundaryLogs(ReportBoundaryLogsRequest) returns (ReportBoundaryLogsResponse);
|
rpc ReportBoundaryLogs(ReportBoundaryLogsRequest) returns (ReportBoundaryLogsResponse);
|
||||||
rpc UpdateAppStatus(UpdateAppStatusRequest) returns (UpdateAppStatusResponse);
|
rpc UpdateAppStatus(UpdateAppStatusRequest) returns (UpdateAppStatusResponse);
|
||||||
|
rpc PushContextState(PushContextStateRequest) returns (PushContextStateResponse);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ type DRPCAgentClient interface {
|
|||||||
ListSubAgents(ctx context.Context, in *ListSubAgentsRequest) (*ListSubAgentsResponse, error)
|
ListSubAgents(ctx context.Context, in *ListSubAgentsRequest) (*ListSubAgentsResponse, error)
|
||||||
ReportBoundaryLogs(ctx context.Context, in *ReportBoundaryLogsRequest) (*ReportBoundaryLogsResponse, error)
|
ReportBoundaryLogs(ctx context.Context, in *ReportBoundaryLogsRequest) (*ReportBoundaryLogsResponse, error)
|
||||||
UpdateAppStatus(ctx context.Context, in *UpdateAppStatusRequest) (*UpdateAppStatusResponse, error)
|
UpdateAppStatus(ctx context.Context, in *UpdateAppStatusRequest) (*UpdateAppStatusResponse, error)
|
||||||
|
PushContextState(ctx context.Context, in *PushContextStateRequest) (*PushContextStateResponse, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type drpcAgentClient struct {
|
type drpcAgentClient struct {
|
||||||
@@ -231,6 +232,15 @@ func (c *drpcAgentClient) UpdateAppStatus(ctx context.Context, in *UpdateAppStat
|
|||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *drpcAgentClient) PushContextState(ctx context.Context, in *PushContextStateRequest) (*PushContextStateResponse, error) {
|
||||||
|
out := new(PushContextStateResponse)
|
||||||
|
err := c.cc.Invoke(ctx, "/coder.agent.v2.Agent/PushContextState", drpcEncoding_File_agent_proto_agent_proto{}, in, out)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return out, nil
|
||||||
|
}
|
||||||
|
|
||||||
type DRPCAgentServer interface {
|
type DRPCAgentServer interface {
|
||||||
GetManifest(context.Context, *GetManifestRequest) (*Manifest, error)
|
GetManifest(context.Context, *GetManifestRequest) (*Manifest, error)
|
||||||
GetServiceBanner(context.Context, *GetServiceBannerRequest) (*ServiceBanner, error)
|
GetServiceBanner(context.Context, *GetServiceBannerRequest) (*ServiceBanner, error)
|
||||||
@@ -250,6 +260,7 @@ type DRPCAgentServer interface {
|
|||||||
ListSubAgents(context.Context, *ListSubAgentsRequest) (*ListSubAgentsResponse, error)
|
ListSubAgents(context.Context, *ListSubAgentsRequest) (*ListSubAgentsResponse, error)
|
||||||
ReportBoundaryLogs(context.Context, *ReportBoundaryLogsRequest) (*ReportBoundaryLogsResponse, error)
|
ReportBoundaryLogs(context.Context, *ReportBoundaryLogsRequest) (*ReportBoundaryLogsResponse, error)
|
||||||
UpdateAppStatus(context.Context, *UpdateAppStatusRequest) (*UpdateAppStatusResponse, error)
|
UpdateAppStatus(context.Context, *UpdateAppStatusRequest) (*UpdateAppStatusResponse, error)
|
||||||
|
PushContextState(context.Context, *PushContextStateRequest) (*PushContextStateResponse, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
type DRPCAgentUnimplementedServer struct{}
|
type DRPCAgentUnimplementedServer struct{}
|
||||||
@@ -326,9 +337,13 @@ func (s *DRPCAgentUnimplementedServer) UpdateAppStatus(context.Context, *UpdateA
|
|||||||
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
|
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *DRPCAgentUnimplementedServer) PushContextState(context.Context, *PushContextStateRequest) (*PushContextStateResponse, error) {
|
||||||
|
return nil, drpcerr.WithCode(errors.New("Unimplemented"), drpcerr.Unimplemented)
|
||||||
|
}
|
||||||
|
|
||||||
type DRPCAgentDescription struct{}
|
type DRPCAgentDescription struct{}
|
||||||
|
|
||||||
func (DRPCAgentDescription) NumMethods() int { return 18 }
|
func (DRPCAgentDescription) NumMethods() int { return 19 }
|
||||||
|
|
||||||
func (DRPCAgentDescription) Method(n int) (string, drpc.Encoding, drpc.Receiver, interface{}, bool) {
|
func (DRPCAgentDescription) Method(n int) (string, drpc.Encoding, drpc.Receiver, interface{}, bool) {
|
||||||
switch n {
|
switch n {
|
||||||
@@ -494,6 +509,15 @@ func (DRPCAgentDescription) Method(n int) (string, drpc.Encoding, drpc.Receiver,
|
|||||||
in1.(*UpdateAppStatusRequest),
|
in1.(*UpdateAppStatusRequest),
|
||||||
)
|
)
|
||||||
}, DRPCAgentServer.UpdateAppStatus, true
|
}, DRPCAgentServer.UpdateAppStatus, true
|
||||||
|
case 18:
|
||||||
|
return "/coder.agent.v2.Agent/PushContextState", drpcEncoding_File_agent_proto_agent_proto{},
|
||||||
|
func(srv interface{}, ctx context.Context, in1, in2 interface{}) (drpc.Message, error) {
|
||||||
|
return srv.(DRPCAgentServer).
|
||||||
|
PushContextState(
|
||||||
|
ctx,
|
||||||
|
in1.(*PushContextStateRequest),
|
||||||
|
)
|
||||||
|
}, DRPCAgentServer.PushContextState, true
|
||||||
default:
|
default:
|
||||||
return "", nil, nil, nil, false
|
return "", nil, nil, nil, false
|
||||||
}
|
}
|
||||||
@@ -790,3 +814,19 @@ func (x *drpcAgent_UpdateAppStatusStream) SendAndClose(m *UpdateAppStatusRespons
|
|||||||
}
|
}
|
||||||
return x.CloseSend()
|
return x.CloseSend()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type DRPCAgent_PushContextStateStream interface {
|
||||||
|
drpc.Stream
|
||||||
|
SendAndClose(*PushContextStateResponse) error
|
||||||
|
}
|
||||||
|
|
||||||
|
type drpcAgent_PushContextStateStream struct {
|
||||||
|
drpc.Stream
|
||||||
|
}
|
||||||
|
|
||||||
|
func (x *drpcAgent_PushContextStateStream) SendAndClose(m *PushContextStateResponse) error {
|
||||||
|
if err := x.MsgSend(m, drpcEncoding_File_agent_proto_agent_proto{}); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return x.CloseSend()
|
||||||
|
}
|
||||||
|
|||||||
@@ -90,3 +90,12 @@ type DRPCAgentClient28 interface {
|
|||||||
type DRPCAgentClient29 interface {
|
type DRPCAgentClient29 interface {
|
||||||
DRPCAgentClient28
|
DRPCAgentClient28
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DRPCAgentClient210 is the Agent API at v2.10. It adds the
|
||||||
|
// PushContextState RPC used by the agent to ship resolved
|
||||||
|
// workspace context snapshots (instruction files, skills, MCP
|
||||||
|
// configs, MCP server tool lists) to coderd.
|
||||||
|
type DRPCAgentClient210 interface {
|
||||||
|
DRPCAgentClient29
|
||||||
|
PushContextState(ctx context.Context, in *PushContextStateRequest) (*PushContextStateResponse, error)
|
||||||
|
}
|
||||||
|
|||||||
@@ -336,6 +336,32 @@ func (c *Client) ConnectRPC29WithRole(ctx context.Context, role string) (
|
|||||||
return proto.NewDRPCAgentClient(conn), tailnetproto.NewDRPCTailnetClient(conn), nil
|
return proto.NewDRPCAgentClient(conn), tailnetproto.NewDRPCTailnetClient(conn), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ConnectRPC210 returns a dRPC client to the Agent API v2.10. It is useful when
|
||||||
|
// you want to be maximally compatible with newer Coderd Release Versions that
|
||||||
|
// implement the PushContextState RPC.
|
||||||
|
func (c *Client) ConnectRPC210(ctx context.Context) (
|
||||||
|
proto.DRPCAgentClient210, tailnetproto.DRPCTailnetClient28, error,
|
||||||
|
) {
|
||||||
|
conn, err := c.connectRPCVersion(ctx, apiversion.New(2, 10), "")
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
return proto.NewDRPCAgentClient(conn), tailnetproto.NewDRPCTailnetClient(conn), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// ConnectRPC210WithRole is like ConnectRPC210 but sends an explicit role
|
||||||
|
// query parameter to the server. Use "agent" for workspace agents to
|
||||||
|
// enable connection monitoring.
|
||||||
|
func (c *Client) ConnectRPC210WithRole(ctx context.Context, role string) (
|
||||||
|
proto.DRPCAgentClient210, tailnetproto.DRPCTailnetClient28, error,
|
||||||
|
) {
|
||||||
|
conn, err := c.connectRPCVersion(ctx, apiversion.New(2, 10), role)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
return proto.NewDRPCAgentClient(conn), tailnetproto.NewDRPCTailnetClient(conn), nil
|
||||||
|
}
|
||||||
|
|
||||||
// ConnectRPC connects to the workspace agent API and tailnet API.
|
// ConnectRPC connects to the workspace agent API and tailnet API.
|
||||||
// It does not send a role query parameter, so the server will apply
|
// It does not send a role query parameter, so the server will apply
|
||||||
// its default behavior (currently: enable connection monitoring for
|
// its default behavior (currently: enable connection monitoring for
|
||||||
|
|||||||
@@ -69,9 +69,16 @@ import (
|
|||||||
// - Added session_id and confined_process fields to
|
// - Added session_id and confined_process fields to
|
||||||
// ReportBoundaryLogsRequest on the Agent API.
|
// ReportBoundaryLogsRequest on the Agent API.
|
||||||
// - Added sequence_number field to BoundaryLog on the Agent API.
|
// - Added sequence_number field to BoundaryLog on the Agent API.
|
||||||
|
//
|
||||||
|
// API v2.10:
|
||||||
|
// - Added PushContextState RPC on the Agent API for pushing
|
||||||
|
// resolved workspace context snapshots (instruction files,
|
||||||
|
// skills, MCP configs, MCP server tool lists) from the
|
||||||
|
// agent to coderd. Adds ContextResource, PushContextState
|
||||||
|
// Request, and PushContextStateResponse messages.
|
||||||
const (
|
const (
|
||||||
CurrentMajor = 2
|
CurrentMajor = 2
|
||||||
CurrentMinor = 9
|
CurrentMinor = 10
|
||||||
)
|
)
|
||||||
|
|
||||||
var CurrentVersion = apiversion.New(CurrentMajor, CurrentMinor)
|
var CurrentVersion = apiversion.New(CurrentMajor, CurrentMinor)
|
||||||
|
|||||||
Reference in New Issue
Block a user