fix: align agent registration contract

This commit is contained in:
ZacharyZhang-NY committed 2026-07-19 14:16:49 -04:00
1 parent eae9015a61
commit c9d1075585
4 files changed
+147 -80

No files matched your search

+1
View File
@@ -193,6 +193,7 @@ agent, err := client.RegisterAgent(&elydora.RegisterAgentRequest{
AgentID: "my-agent", AgentID: "my-agent",
DisplayName: "My Agent", DisplayName: "My Agent",
ResponsibleEntity: "team@example.com", ResponsibleEntity: "team@example.com",
IntegrationType: elydora.IntegrationTypeSDK,
Keys: []elydora.RegisterAgentKeyInput{ Keys: []elydora.RegisterAgentKeyInput{
{KID: "key-v1", PublicKey: "<base64url>", Algorithm: "ed25519"}, {KID: "key-v1", PublicKey: "<base64url>", Algorithm: "ed25519"},
}, },
+1
View File
@@ -106,6 +106,7 @@ func TestSDKCompatibilityAgainstLatestAPI(t *testing.T) {
AgentID: agentID, AgentID: agentID,
DisplayName: "Go SDK Compat Agent", DisplayName: "Go SDK Compat Agent",
ResponsibleEntity: "sdk-matrix", ResponsibleEntity: "sdk-matrix",
IntegrationType: elydora.IntegrationTypeSDK,
Keys: []elydora.RegisterAgentKeyInput{ Keys: []elydora.RegisterAgentKeyInput{
{ {
KID: kid, KID: kid,
+86 -80
View File
@@ -23,20 +23,25 @@ const (
type IntegrationType string type IntegrationType string
const ( const (
IntegrationTypeClaudecode IntegrationType = "claudecode" IntegrationTypeAugment IntegrationType = "augment"
IntegrationTypeCursor IntegrationType = "cursor" IntegrationTypeClaudecode IntegrationType = "claudecode"
IntegrationTypeGemini IntegrationType = "gemini" IntegrationTypeCline IntegrationType = "cline"
IntegrationTypeKiroCLI IntegrationType = "kirocli" IntegrationTypeCodex IntegrationType = "codex"
IntegrationTypeKiroIDE IntegrationType = "kiroide" IntegrationTypeCopilot IntegrationType = "copilot"
IntegrationTypeOpenCode IntegrationType = "opencode" IntegrationTypeCursor IntegrationType = "cursor"
IntegrationTypeCopilot IntegrationType = "copilot" IntegrationTypeDroid IntegrationType = "droid"
IntegrationTypeLetta IntegrationType = "letta" IntegrationTypeGemini IntegrationType = "gemini"
IntegrationTypeCodex IntegrationType = "codex" IntegrationTypeGrok IntegrationType = "grok"
IntegrationTypeKimi IntegrationType = "kimi" IntegrationTypeKimi IntegrationType = "kimi"
IntegrationTypeEnterprise IntegrationType = "enterprise" IntegrationTypeKiroCLI IntegrationType = "kirocli"
IntegrationTypeGUI IntegrationType = "gui" IntegrationTypeKiroIDE IntegrationType = "kiroide"
IntegrationTypeSDK IntegrationType = "sdk" IntegrationTypeLetta IntegrationType = "letta"
IntegrationTypeOther IntegrationType = "other" IntegrationTypeOpenCode IntegrationType = "opencode"
IntegrationTypeQwen IntegrationType = "qwen"
IntegrationTypeEnterprise IntegrationType = "enterprise"
IntegrationTypeGUI IntegrationType = "gui"
IntegrationTypeSDK IntegrationType = "sdk"
IntegrationTypeOther IntegrationType = "other"
) )
type ExportStatus string type ExportStatus string
@@ -51,30 +56,30 @@ const (
type RbacRole string type RbacRole string
const ( const (
RbacRoleOrgOwner RbacRole = "org_owner" RbacRoleOrgOwner RbacRole = "org_owner"
RbacRoleSecurityAdmin RbacRole = "security_admin" RbacRoleSecurityAdmin RbacRole = "security_admin"
RbacRoleComplianceAuditor RbacRole = "compliance_auditor" RbacRoleComplianceAuditor RbacRole = "compliance_auditor"
RbacRoleReadonlyInvestigator RbacRole = "readonly_investigator" RbacRoleReadonlyInvestigator RbacRole = "readonly_investigator"
RbacRoleIntegrationEngineer RbacRole = "integration_engineer" RbacRoleIntegrationEngineer RbacRole = "integration_engineer"
) )
type ErrorCode string type ErrorCode string
const ( const (
ErrorCodeInvalidSignature ErrorCode = "INVALID_SIGNATURE" ErrorCodeInvalidSignature ErrorCode = "INVALID_SIGNATURE"
ErrorCodeUnknownAgent ErrorCode = "UNKNOWN_AGENT" ErrorCodeUnknownAgent ErrorCode = "UNKNOWN_AGENT"
ErrorCodeKeyRevoked ErrorCode = "KEY_REVOKED" ErrorCodeKeyRevoked ErrorCode = "KEY_REVOKED"
ErrorCodeAgentFrozen ErrorCode = "AGENT_FROZEN" ErrorCodeAgentFrozen ErrorCode = "AGENT_FROZEN"
ErrorCodeTTLExpired ErrorCode = "TTL_EXPIRED" ErrorCodeTTLExpired ErrorCode = "TTL_EXPIRED"
ErrorCodeReplayDetected ErrorCode = "REPLAY_DETECTED" ErrorCodeReplayDetected ErrorCode = "REPLAY_DETECTED"
ErrorCodePrevHashMismatch ErrorCode = "PREV_HASH_MISMATCH" ErrorCodePrevHashMismatch ErrorCode = "PREV_HASH_MISMATCH"
ErrorCodePayloadTooLarge ErrorCode = "PAYLOAD_TOO_LARGE" ErrorCodePayloadTooLarge ErrorCode = "PAYLOAD_TOO_LARGE"
ErrorCodeRateLimited ErrorCode = "RATE_LIMITED" ErrorCodeRateLimited ErrorCode = "RATE_LIMITED"
ErrorCodeInternalError ErrorCode = "INTERNAL_ERROR" ErrorCodeInternalError ErrorCode = "INTERNAL_ERROR"
ErrorCodeUnauthorized ErrorCode = "UNAUTHORIZED" ErrorCodeUnauthorized ErrorCode = "UNAUTHORIZED"
ErrorCodeForbidden ErrorCode = "FORBIDDEN" ErrorCodeForbidden ErrorCode = "FORBIDDEN"
ErrorCodeNotFound ErrorCode = "NOT_FOUND" ErrorCodeNotFound ErrorCode = "NOT_FOUND"
ErrorCodeValidationError ErrorCode = "VALIDATION_ERROR" ErrorCodeValidationError ErrorCode = "VALIDATION_ERROR"
) )
type ExportFormat string type ExportFormat string
@@ -110,23 +115,23 @@ type AgentKey struct {
} }
type Operation struct { type Operation struct {
OperationID string `json:"operation_id"` OperationID string `json:"operation_id"`
OrgID string `json:"org_id"` OrgID string `json:"org_id"`
AgentID string `json:"agent_id"` AgentID string `json:"agent_id"`
SeqNo int64 `json:"seq_no"` SeqNo int64 `json:"seq_no"`
OperationType string `json:"operation_type"` OperationType string `json:"operation_type"`
IssuedAt int64 `json:"issued_at"` IssuedAt int64 `json:"issued_at"`
TTLMs int64 `json:"ttl_ms"` TTLMs int64 `json:"ttl_ms"`
Nonce string `json:"nonce"` Nonce string `json:"nonce"`
Subject string `json:"subject"` Subject string `json:"subject"`
Action string `json:"action"` Action string `json:"action"`
PayloadHash string `json:"payload_hash"` PayloadHash string `json:"payload_hash"`
PrevChainHash string `json:"prev_chain_hash"` PrevChainHash string `json:"prev_chain_hash"`
ChainHash string `json:"chain_hash"` ChainHash string `json:"chain_hash"`
AgentPubkeyKID string `json:"agent_pubkey_kid"` AgentPubkeyKID string `json:"agent_pubkey_kid"`
Signature string `json:"signature"` Signature string `json:"signature"`
R2PayloadKey *string `json:"r2_payload_key"` R2PayloadKey *string `json:"r2_payload_key"`
CreatedAt int64 `json:"created_at"` CreatedAt int64 `json:"created_at"`
} }
type Receipt struct { type Receipt struct {
@@ -183,36 +188,36 @@ type Export struct {
// EOR is the Elydora Operation Record — the fundamental unit of auditable activity. // EOR is the Elydora Operation Record — the fundamental unit of auditable activity.
type EOR struct { type EOR struct {
OpVersion string `json:"op_version"` OpVersion string `json:"op_version"`
OperationID string `json:"operation_id"` OperationID string `json:"operation_id"`
OrgID string `json:"org_id"` OrgID string `json:"org_id"`
AgentID string `json:"agent_id"` AgentID string `json:"agent_id"`
IssuedAt int64 `json:"issued_at"` IssuedAt int64 `json:"issued_at"`
TTLMs int64 `json:"ttl_ms"` TTLMs int64 `json:"ttl_ms"`
Nonce string `json:"nonce"` Nonce string `json:"nonce"`
OperationType string `json:"operation_type"` OperationType string `json:"operation_type"`
Subject interface{} `json:"subject"` Subject interface{} `json:"subject"`
Action interface{} `json:"action"` Action interface{} `json:"action"`
Payload interface{} `json:"payload"` Payload interface{} `json:"payload"`
PayloadHash string `json:"payload_hash"` PayloadHash string `json:"payload_hash"`
PrevChainHash string `json:"prev_chain_hash"` PrevChainHash string `json:"prev_chain_hash"`
AgentPubkeyKID string `json:"agent_pubkey_kid"` AgentPubkeyKID string `json:"agent_pubkey_kid"`
Signature string `json:"signature"` Signature string `json:"signature"`
} }
// EAR is the Elydora Acknowledgment Receipt — server-issued receipt confirming acceptance. // EAR is the Elydora Acknowledgment Receipt — server-issued receipt confirming acceptance.
type EAR struct { type EAR struct {
ReceiptVersion string `json:"receipt_version"` ReceiptVersion string `json:"receipt_version"`
ReceiptID string `json:"receipt_id"` ReceiptID string `json:"receipt_id"`
OperationID string `json:"operation_id"` OperationID string `json:"operation_id"`
OrgID string `json:"org_id"` OrgID string `json:"org_id"`
AgentID string `json:"agent_id"` AgentID string `json:"agent_id"`
ServerReceivedAt int64 `json:"server_received_at"` ServerReceivedAt int64 `json:"server_received_at"`
SeqNo int64 `json:"seq_no"` SeqNo int64 `json:"seq_no"`
ChainHash string `json:"chain_hash"` ChainHash string `json:"chain_hash"`
QueueMessageID string `json:"queue_message_id"` QueueMessageID string `json:"queue_message_id"`
ReceiptHash string `json:"receipt_hash"` ReceiptHash string `json:"receipt_hash"`
ElydoraKID string `json:"elydora_kid"` ElydoraKID string `json:"elydora_kid"`
ElydoraSignature string `json:"elydora_signature"` ElydoraSignature string `json:"elydora_signature"`
} }
@@ -230,6 +235,7 @@ type RegisterAgentRequest struct {
AgentID string `json:"agent_id"` AgentID string `json:"agent_id"`
DisplayName string `json:"display_name,omitempty"` DisplayName string `json:"display_name,omitempty"`
ResponsibleEntity string `json:"responsible_entity,omitempty"` ResponsibleEntity string `json:"responsible_entity,omitempty"`
IntegrationType IntegrationType `json:"integration_type"`
Keys []RegisterAgentKeyInput `json:"keys"` Keys []RegisterAgentKeyInput `json:"keys"`
} }
@@ -353,9 +359,9 @@ type GetEpochResponse struct {
} }
type EpochAnchor struct { type EpochAnchor struct {
TSAToken string `json:"tsa_token,omitempty"` TSAToken string `json:"tsa_token,omitempty"`
TSAUrl string `json:"tsa_url,omitempty"` TSAUrl string `json:"tsa_url,omitempty"`
AnchoredAt *int64 `json:"anchored_at,omitempty"` AnchoredAt *int64 `json:"anchored_at,omitempty"`
} }
type ListEpochsResponse struct { type ListEpochsResponse struct {
@@ -375,7 +381,7 @@ type CreateExportResponse struct {
} }
type GetExportResponse struct { type GetExportResponse struct {
Export Export `json:"export"` Export Export `json:"export"`
DownloadURL string `json:"download_url,omitempty"` DownloadURL string `json:"download_url,omitempty"`
} }
+59
View File
@@ -0,0 +1,59 @@
package elydora
import (
"encoding/json"
"reflect"
"testing"
)
func TestRegisterAgentRequestIncludesIntegrationType(t *testing.T) {
payload, err := json.Marshal(RegisterAgentRequest{
AgentID: "agent-1",
IntegrationType: IntegrationTypeSDK,
Keys: []RegisterAgentKeyInput{},
})
if err != nil {
t.Fatalf("marshal register agent request: %v", err)
}
var decoded map[string]any
if err := json.Unmarshal(payload, &decoded); err != nil {
t.Fatalf("unmarshal register agent request: %v", err)
}
if got := decoded["integration_type"]; got != "sdk" {
t.Fatalf("integration_type = %v, want sdk", got)
}
}
func TestIntegrationTypesMatchPublicAPIContract(t *testing.T) {
got := []IntegrationType{
IntegrationTypeAugment,
IntegrationTypeClaudecode,
IntegrationTypeCline,
IntegrationTypeCodex,
IntegrationTypeCopilot,
IntegrationTypeCursor,
IntegrationTypeDroid,
IntegrationTypeGemini,
IntegrationTypeGrok,
IntegrationTypeKimi,
IntegrationTypeKiroCLI,
IntegrationTypeKiroIDE,
IntegrationTypeLetta,
IntegrationTypeOpenCode,
IntegrationTypeQwen,
IntegrationTypeEnterprise,
IntegrationTypeGUI,
IntegrationTypeSDK,
IntegrationTypeOther,
}
want := []IntegrationType{
"augment", "claudecode", "cline", "codex", "copilot", "cursor", "droid",
"gemini", "grok", "kimi", "kirocli", "kiroide", "letta", "opencode", "qwen",
"enterprise", "gui", "sdk", "other",
}
if !reflect.DeepEqual(got, want) {
t.Fatalf("integration types = %v, want %v", got, want)
}
}