Skip to content

Commit da54208

Browse files
committed
fix: address delegation client review feedback
Signed-off-by: Michael Kantor <6068672+kantorcodes@users.noreply.github.com>
1 parent dd6112b commit da54208

File tree

4 files changed

+149
-5
lines changed

4 files changed

+149
-5
lines changed

examples/registry-broker-delegation/main.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ const (
1717

1818
func main() {
1919
if err := run(); err != nil {
20-
fmt.Println("error:", err)
20+
_, _ = fmt.Fprintf(os.Stderr, "error: %v\n", err)
21+
os.Exit(1)
2122
}
2223
}
2324

examples/registry-broker-delegation/main_test.go

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,25 @@ package main
33
import "testing"
44

55
func TestGetEnvOrDefault(t *testing.T) {
6-
if value := getEnvOrDefault("REGISTRY_BROKER_DELEGATION_EXAMPLE_MISSING", "fallback"); value != "fallback" {
7-
t.Fatalf("expected fallback, got %s", value)
8-
}
6+
t.Run("returns fallback when env var is not set", func(t *testing.T) {
7+
if value := getEnvOrDefault("REGISTRY_BROKER_DELEGATION_EXAMPLE_MISSING", "fallback"); value != "fallback" {
8+
t.Fatalf("expected fallback, got %s", value)
9+
}
10+
})
11+
12+
t.Run("returns env var value when set", func(t *testing.T) {
13+
t.Setenv("REGISTRY_BROKER_DELEGATION_EXAMPLE_SET", "env-value")
14+
15+
if value := getEnvOrDefault("REGISTRY_BROKER_DELEGATION_EXAMPLE_SET", "fallback"); value != "env-value" {
16+
t.Fatalf("expected env-value, got %s", value)
17+
}
18+
})
19+
20+
t.Run("returns trimmed env var value when set with whitespace", func(t *testing.T) {
21+
t.Setenv("REGISTRY_BROKER_DELEGATION_EXAMPLE_SPACED", " env-value ")
22+
23+
if value := getEnvOrDefault("REGISTRY_BROKER_DELEGATION_EXAMPLE_SPACED", "fallback"); value != "env-value" {
24+
t.Fatalf("expected env-value, got %s", value)
25+
}
26+
})
927
}

pkg/registrybroker/delegation_plan_test.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,14 @@ func TestDelegate(t *testing.T) {
105105
if len(response.Opportunities) != 1 {
106106
t.Fatalf("expected one opportunity, got %d", len(response.Opportunities))
107107
}
108-
candidate := response.Opportunities[0].Candidates[0]
108+
if response.Extras["extraRootField"] != "preserved" {
109+
t.Fatalf("expected additive root field to survive, got %#v", response.Extras)
110+
}
111+
opportunity := response.Opportunities[0]
112+
if opportunity.Extras["extraOpportunityField"] != "preserved" {
113+
t.Fatalf("expected additive opportunity field to survive, got %#v", opportunity.Extras)
114+
}
115+
candidate := opportunity.Candidates[0]
109116
if candidate.Registry != "hcs-11" {
110117
t.Fatalf("expected registry to parse, got %q", candidate.Registry)
111118
}
@@ -115,6 +122,9 @@ func TestDelegate(t *testing.T) {
115122
if candidate.Verified == nil || !*candidate.Verified {
116123
t.Fatal("expected verified candidate")
117124
}
125+
if candidate.Extras["extraCandidateField"] != "preserved" {
126+
t.Fatalf("expected additive candidate field to survive, got %#v", candidate.Extras)
127+
}
118128
if candidate.Agent["extraAgentField"] != "preserved" {
119129
t.Fatalf("expected additive agent field to survive, got %#v", candidate.Agent)
120130
}

pkg/registrybroker/types.go

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package registrybroker
22

33
import (
44
"context"
5+
"encoding/json"
56
"net/http"
67
"time"
78
)
@@ -107,6 +108,7 @@ type DelegationPlanCandidate struct {
107108
Reasons []string `json:"reasons,omitempty"`
108109
SuggestedMessage string `json:"suggestedMessage,omitempty"`
109110
Agent JSONObject `json:"agent,omitempty"`
111+
Extras JSONObject `json:"-"`
110112
}
111113

112114
type DelegationOpportunity struct {
@@ -122,6 +124,7 @@ type DelegationOpportunity struct {
122124
Languages []string `json:"languages,omitempty"`
123125
Artifacts []string `json:"artifacts,omitempty"`
124126
Candidates []DelegationPlanCandidate `json:"candidates,omitempty"`
127+
Extras JSONObject `json:"-"`
125128
}
126129

127130
type DelegationPlanResponse struct {
@@ -137,6 +140,118 @@ type DelegationPlanResponse struct {
137140
LocalFirstReason string `json:"localFirstReason,omitempty"`
138141
Recommendation *DelegationPlanRecommendation `json:"recommendation,omitempty"`
139142
Opportunities []DelegationOpportunity `json:"opportunities,omitempty"`
143+
Extras JSONObject `json:"-"`
144+
}
145+
146+
func (c *DelegationPlanCandidate) UnmarshalJSON(data []byte) error {
147+
type candidateAlias DelegationPlanCandidate
148+
aux := candidateAlias{}
149+
if err := json.Unmarshal(data, &aux); err != nil {
150+
return err
151+
}
152+
candidate := DelegationPlanCandidate(aux)
153+
extras, err := extractUnknownFields(
154+
data,
155+
"uaid",
156+
"label",
157+
"registry",
158+
"score",
159+
"trustScore",
160+
"verified",
161+
"communicationSupported",
162+
"availability",
163+
"explanation",
164+
"matchedQueries",
165+
"matchedRoles",
166+
"matchedProtocols",
167+
"matchedSurfaces",
168+
"matchedLanguages",
169+
"matchedArtifacts",
170+
"matchedTaskTags",
171+
"reasons",
172+
"suggestedMessage",
173+
"agent",
174+
)
175+
if err != nil {
176+
return err
177+
}
178+
candidate.Extras = extras
179+
*c = candidate
180+
return nil
181+
}
182+
183+
func (o *DelegationOpportunity) UnmarshalJSON(data []byte) error {
184+
type opportunityAlias DelegationOpportunity
185+
aux := opportunityAlias{}
186+
if err := json.Unmarshal(data, &aux); err != nil {
187+
return err
188+
}
189+
opportunity := DelegationOpportunity(aux)
190+
extras, err := extractUnknownFields(
191+
data,
192+
"id",
193+
"title",
194+
"reason",
195+
"role",
196+
"type",
197+
"suggestedMode",
198+
"searchQueries",
199+
"protocols",
200+
"surfaces",
201+
"languages",
202+
"artifacts",
203+
"candidates",
204+
)
205+
if err != nil {
206+
return err
207+
}
208+
opportunity.Extras = extras
209+
*o = opportunity
210+
return nil
211+
}
212+
213+
func (r *DelegationPlanResponse) UnmarshalJSON(data []byte) error {
214+
type responseAlias DelegationPlanResponse
215+
aux := responseAlias{}
216+
if err := json.Unmarshal(data, &aux); err != nil {
217+
return err
218+
}
219+
response := DelegationPlanResponse(aux)
220+
extras, err := extractUnknownFields(
221+
data,
222+
"task",
223+
"context",
224+
"summary",
225+
"intents",
226+
"surfaces",
227+
"protocols",
228+
"languages",
229+
"artifacts",
230+
"shouldDelegate",
231+
"localFirstReason",
232+
"recommendation",
233+
"opportunities",
234+
)
235+
if err != nil {
236+
return err
237+
}
238+
response.Extras = extras
239+
*r = response
240+
return nil
241+
}
242+
243+
func extractUnknownFields(data []byte, knownKeys ...string) (JSONObject, error) {
244+
var payload map[string]any
245+
if err := json.Unmarshal(data, &payload); err != nil {
246+
return nil, err
247+
}
248+
for _, key := range knownKeys {
249+
delete(payload, key)
250+
}
251+
if len(payload) == 0 {
252+
return nil, nil
253+
}
254+
return JSONObject(payload), nil
140255
}
141256

142257
type VectorSearchFilter struct {

0 commit comments

Comments
 (0)