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 {}
|
||||
|
||||
// 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 {
|
||||
rpc GetManifest(GetManifestRequest) returns (Manifest);
|
||||
rpc GetServiceBanner(GetServiceBannerRequest) returns (ServiceBanner);
|
||||
@@ -557,4 +610,5 @@ service Agent {
|
||||
rpc ListSubAgents(ListSubAgentsRequest) returns (ListSubAgentsResponse);
|
||||
rpc ReportBoundaryLogs(ReportBoundaryLogsRequest) returns (ReportBoundaryLogsResponse);
|
||||
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)
|
||||
ReportBoundaryLogs(ctx context.Context, in *ReportBoundaryLogsRequest) (*ReportBoundaryLogsResponse, error)
|
||||
UpdateAppStatus(ctx context.Context, in *UpdateAppStatusRequest) (*UpdateAppStatusResponse, error)
|
||||
PushContextState(ctx context.Context, in *PushContextStateRequest) (*PushContextStateResponse, error)
|
||||
}
|
||||
|
||||
type drpcAgentClient struct {
|
||||
@@ -231,6 +232,15 @@ func (c *drpcAgentClient) UpdateAppStatus(ctx context.Context, in *UpdateAppStat
|
||||
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 {
|
||||
GetManifest(context.Context, *GetManifestRequest) (*Manifest, error)
|
||||
GetServiceBanner(context.Context, *GetServiceBannerRequest) (*ServiceBanner, error)
|
||||
@@ -250,6 +260,7 @@ type DRPCAgentServer interface {
|
||||
ListSubAgents(context.Context, *ListSubAgentsRequest) (*ListSubAgentsResponse, error)
|
||||
ReportBoundaryLogs(context.Context, *ReportBoundaryLogsRequest) (*ReportBoundaryLogsResponse, error)
|
||||
UpdateAppStatus(context.Context, *UpdateAppStatusRequest) (*UpdateAppStatusResponse, error)
|
||||
PushContextState(context.Context, *PushContextStateRequest) (*PushContextStateResponse, error)
|
||||
}
|
||||
|
||||
type DRPCAgentUnimplementedServer struct{}
|
||||
@@ -326,9 +337,13 @@ func (s *DRPCAgentUnimplementedServer) UpdateAppStatus(context.Context, *UpdateA
|
||||
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{}
|
||||
|
||||
func (DRPCAgentDescription) NumMethods() int { return 18 }
|
||||
func (DRPCAgentDescription) NumMethods() int { return 19 }
|
||||
|
||||
func (DRPCAgentDescription) Method(n int) (string, drpc.Encoding, drpc.Receiver, interface{}, bool) {
|
||||
switch n {
|
||||
@@ -494,6 +509,15 @@ func (DRPCAgentDescription) Method(n int) (string, drpc.Encoding, drpc.Receiver,
|
||||
in1.(*UpdateAppStatusRequest),
|
||||
)
|
||||
}, 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:
|
||||
return "", nil, nil, nil, false
|
||||
}
|
||||
@@ -790,3 +814,19 @@ func (x *drpcAgent_UpdateAppStatusStream) SendAndClose(m *UpdateAppStatusRespons
|
||||
}
|
||||
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 {
|
||||
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
|
||||
}
|
||||
|
||||
// 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.
|
||||
// It does not send a role query parameter, so the server will apply
|
||||
// its default behavior (currently: enable connection monitoring for
|
||||
|
||||
@@ -69,9 +69,16 @@ import (
|
||||
// - Added session_id and confined_process fields to
|
||||
// ReportBoundaryLogsRequest 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 (
|
||||
CurrentMajor = 2
|
||||
CurrentMinor = 9
|
||||
CurrentMinor = 10
|
||||
)
|
||||
|
||||
var CurrentVersion = apiversion.New(CurrentMajor, CurrentMinor)
|
||||
|
||||
Reference in New Issue
Block a user