Files
2026-07-20 04:48:15 +00:00

107 lines
4.2 KiB
Go

package client
import (
"context"
"errors"
"net/http"
"strings"
)
const (
ioStreamCapabilityRegisterPath = "/agentcompat/io-stream-capability/register"
ioStreamCapabilityWaitPath = "/agentcompat/io-stream-capability/wait"
ioStreamCapabilityCancelPath = "/agentcompat/io-stream-capability/cancel"
ioStreamCapabilityUnregisterPath = "/agentcompat/io-stream-capability/unregister"
)
const (
ioStreamCapabilityInvalidMessage = "agentcompat capability request is invalid"
ioStreamCapabilityUnavailableMessage = "agentcompat capability is not available"
ioStreamCapabilityConflictMessage = "agentcompat capability is active"
ioStreamCapabilityCleanupMessage = "agentcompat capability cleanup failed"
)
type IOStreamCapabilityClient struct {
transport *Client
}
func (client *Client) IOStreamCapabilities() IOStreamCapabilityClient {
return IOStreamCapabilityClient{transport: client}
}
func (client IOStreamCapabilityClient) Register(ctx context.Context, request IOStreamCapabilityRegisterRequest) (IOStreamCapabilityRegisterResponse, error) {
if err := validateIOStreamCapabilityIdentity(request.Purpose, request.ServerID, request.ResourceID); err != nil {
return IOStreamCapabilityRegisterResponse{}, err
}
response, err := DoREST[IOStreamCapabilityRegisterRequest, IOStreamCapabilityRegisterResponse](ctx, client.transport, RESTRequest[IOStreamCapabilityRegisterRequest]{
Method: http.MethodPost, Path: ioStreamCapabilityRegisterPath, Body: &request,
})
if err != nil {
return IOStreamCapabilityRegisterResponse{}, mapIOStreamCapabilityError(err)
}
if response.Capability.value == "" {
return IOStreamCapabilityRegisterResponse{}, ErrIOStreamCapabilityUnavailable
}
return response, nil
}
func (client IOStreamCapabilityClient) Wait(ctx context.Context, request IOStreamCapabilityWaitRequest) (IOStreamCapabilityWaitResponse, error) {
access := IOStreamCapabilityAccessRequest(request)
if err := validateIOStreamCapabilityAccess(access); err != nil {
return IOStreamCapabilityWaitResponse{}, err
}
response, err := DoREST[IOStreamCapabilityWaitRequest, IOStreamCapabilityWaitResponse](ctx, client.transport, RESTRequest[IOStreamCapabilityWaitRequest]{
Method: http.MethodPost, Path: ioStreamCapabilityWaitPath, Body: &request,
})
if err != nil {
return IOStreamCapabilityWaitResponse{}, mapIOStreamCapabilityError(err)
}
if response.StreamID.value == "" {
return IOStreamCapabilityWaitResponse{}, ErrIOStreamCapabilityUnavailable
}
return response, nil
}
func (client IOStreamCapabilityClient) Cancel(ctx context.Context, request IOStreamCapabilityAccessRequest) error {
if err := validateIOStreamCapabilityAccess(request); err != nil {
return err
}
_, err := DoREST[IOStreamCapabilityAccessRequest, ioStreamCapabilityEmptyResponse](ctx, client.transport, RESTRequest[IOStreamCapabilityAccessRequest]{
Method: http.MethodPost, Path: ioStreamCapabilityCancelPath, Body: &request,
})
return mapIOStreamCapabilityError(err)
}
func (client IOStreamCapabilityClient) Unregister(ctx context.Context, request IOStreamCapabilityAccessRequest) error {
if err := validateIOStreamCapabilityAccess(request); err != nil {
return err
}
_, err := DoREST[IOStreamCapabilityAccessRequest, ioStreamCapabilityEmptyResponse](ctx, client.transport, RESTRequest[IOStreamCapabilityAccessRequest]{
Method: http.MethodPost, Path: ioStreamCapabilityUnregisterPath, Body: &request,
})
return mapIOStreamCapabilityError(err)
}
func mapIOStreamCapabilityError(err error) error {
if err == nil || errors.Is(err, context.Canceled) || errors.Is(err, context.DeadlineExceeded) {
return err
}
if errors.Is(err, ErrUnauthorized) {
return ErrUnauthorized
}
if errors.Is(err, ErrSemanticFailure) {
message := err.Error()
switch {
case strings.HasSuffix(message, ioStreamCapabilityInvalidMessage):
return ErrInvalidIOStreamCapabilityRequest
case strings.HasSuffix(message, ioStreamCapabilityConflictMessage):
return ErrIOStreamCapabilityConflict
case strings.HasSuffix(message, ioStreamCapabilityCleanupMessage):
return ErrIOStreamCapabilityCleanup
case strings.HasSuffix(message, ioStreamCapabilityUnavailableMessage):
return ErrIOStreamCapabilityUnavailable
}
}
return ErrIOStreamCapabilityUnavailable
}