Skip to content

Commit 62d872b

Browse files
authored
Merge branch 'main' into update-registry-from-release
2 parents ce1bbd3 + bd7ad01 commit 62d872b

35 files changed

+2073
-50
lines changed

.github/workflows/claude.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,6 @@ jobs:
4141

4242
- name: Run Claude Code
4343
id: claude
44-
uses: anthropics/claude-code-action@6337623ebba10cf8c8214b507993f8062fd4ccfb # v1
44+
uses: anthropics/claude-code-action@f0c8eb29807907de7f5412d04afceb5e24817127 # v1
4545
with:
4646
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}

.github/workflows/releaser.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ jobs:
7272
cache: true
7373

7474
- name: Install Syft
75-
uses: anchore/sbom-action/download-syft@fbfd9c6c189226748411491745178e0c2017392d # v0.20.10
75+
uses: anchore/sbom-action/download-syft@43a17d6e7add2b5535efe4dcae9952337c479a93 # v0.20.11
7676

7777
- name: Install Cosign
7878
uses: sigstore/cosign-installer@faadad0cce49287aee09b3a48701e75088a2c6ad # v4.0.0

cmd/thv-operator/api/v1alpha1/virtualmcpserver_types.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,16 @@ type WorkflowStep struct {
296296
// +kubebuilder:validation:Type=object
297297
Schema *runtime.RawExtension `json:"schema,omitempty"`
298298

299+
// OnDecline defines the action to take when the user explicitly declines the elicitation
300+
// Only used when Type is "elicitation"
301+
// +optional
302+
OnDecline *ElicitationResponseHandler `json:"onDecline,omitempty"`
303+
304+
// OnCancel defines the action to take when the user cancels/dismisses the elicitation
305+
// Only used when Type is "elicitation"
306+
// +optional
307+
OnCancel *ElicitationResponseHandler `json:"onCancel,omitempty"`
308+
299309
// DependsOn lists step IDs that must complete before this step
300310
// +optional
301311
DependsOn []string `json:"dependsOn,omitempty"`
@@ -333,6 +343,18 @@ type ErrorHandling struct {
333343
RetryDelay string `json:"retryDelay,omitempty"`
334344
}
335345

346+
// ElicitationResponseHandler defines how to handle user responses to elicitation requests
347+
type ElicitationResponseHandler struct {
348+
// Action defines the action to take when the user declines or cancels
349+
// - skip_remaining: Skip remaining steps in the workflow
350+
// - abort: Abort the entire workflow execution
351+
// - continue: Continue to the next step
352+
// +kubebuilder:validation:Enum=skip_remaining;abort;continue
353+
// +kubebuilder:default=abort
354+
// +optional
355+
Action string `json:"action,omitempty"`
356+
}
357+
336358
// OperationalConfig defines operational settings
337359
type OperationalConfig struct {
338360
// LogLevel sets the logging level for the Virtual MCP server.

cmd/thv-operator/api/v1alpha1/virtualmcpserver_webhook.go

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,12 @@ func validateCompositeToolStep(
269269
}
270270

271271
// Validate error handling
272-
return validateStepErrorHandling(toolIndex, stepIndex, step)
272+
if err := validateStepErrorHandling(toolIndex, stepIndex, step); err != nil {
273+
return err
274+
}
275+
276+
// Validate elicitation response handlers
277+
return validateStepElicitationResponseHandlers(toolIndex, stepIndex, step)
273278
}
274279

275280
// validateStepType validates the step type and type-specific requirements
@@ -347,3 +352,30 @@ func validateStepErrorHandling(toolIndex, stepIndex int, step WorkflowStep) erro
347352

348353
return nil
349354
}
355+
356+
// validateStepElicitationResponseHandlers validates elicitation response handler configuration for a step
357+
func validateStepElicitationResponseHandlers(toolIndex, stepIndex int, step WorkflowStep) error {
358+
validActions := map[string]bool{
359+
"skip_remaining": true,
360+
"abort": true,
361+
"continue": true,
362+
}
363+
364+
// Validate OnDecline action
365+
if step.OnDecline != nil && step.OnDecline.Action != "" {
366+
if !validActions[step.OnDecline.Action] {
367+
return fmt.Errorf("spec.compositeTools[%d].steps[%d].onDecline.action must be one of: skip_remaining, abort, continue",
368+
toolIndex, stepIndex)
369+
}
370+
}
371+
372+
// Validate OnCancel action
373+
if step.OnCancel != nil && step.OnCancel.Action != "" {
374+
if !validActions[step.OnCancel.Action] {
375+
return fmt.Errorf("spec.compositeTools[%d].steps[%d].onCancel.action must be one of: skip_remaining, abort, continue",
376+
toolIndex, stepIndex)
377+
}
378+
}
379+
380+
return nil
381+
}

cmd/thv-operator/api/v1alpha1/virtualmcpserver_webhook_test.go

Lines changed: 230 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -691,6 +691,236 @@ func TestValidateCompositeToolsWithDependencies(t *testing.T) {
691691
wantErr: true,
692692
errMsg: "spec.compositeTools[0].steps[0].dependsOn references unknown step \"unknown-step\"",
693693
},
694+
{
695+
name: "valid elicitation with OnDecline skip_remaining",
696+
vmcp: &VirtualMCPServer{
697+
Spec: VirtualMCPServerSpec{
698+
GroupRef: GroupRef{Name: "test-group"},
699+
CompositeTools: []CompositeToolSpec{
700+
{
701+
Name: "test-tool",
702+
Description: "Test composite tool",
703+
Steps: []WorkflowStep{
704+
{
705+
ID: "step1",
706+
Type: WorkflowStepTypeElicitation,
707+
Message: "Please provide input",
708+
OnDecline: &ElicitationResponseHandler{
709+
Action: "skip_remaining",
710+
},
711+
},
712+
},
713+
},
714+
},
715+
},
716+
},
717+
wantErr: false,
718+
},
719+
{
720+
name: "valid elicitation with OnDecline abort",
721+
vmcp: &VirtualMCPServer{
722+
Spec: VirtualMCPServerSpec{
723+
GroupRef: GroupRef{Name: "test-group"},
724+
CompositeTools: []CompositeToolSpec{
725+
{
726+
Name: "test-tool",
727+
Description: "Test composite tool",
728+
Steps: []WorkflowStep{
729+
{
730+
ID: "step1",
731+
Type: WorkflowStepTypeElicitation,
732+
Message: "Please provide input",
733+
OnDecline: &ElicitationResponseHandler{
734+
Action: "abort",
735+
},
736+
},
737+
},
738+
},
739+
},
740+
},
741+
},
742+
wantErr: false,
743+
},
744+
{
745+
name: "valid elicitation with OnDecline continue",
746+
vmcp: &VirtualMCPServer{
747+
Spec: VirtualMCPServerSpec{
748+
GroupRef: GroupRef{Name: "test-group"},
749+
CompositeTools: []CompositeToolSpec{
750+
{
751+
Name: "test-tool",
752+
Description: "Test composite tool",
753+
Steps: []WorkflowStep{
754+
{
755+
ID: "step1",
756+
Type: WorkflowStepTypeElicitation,
757+
Message: "Please provide input",
758+
OnDecline: &ElicitationResponseHandler{
759+
Action: "continue",
760+
},
761+
},
762+
},
763+
},
764+
},
765+
},
766+
},
767+
wantErr: false,
768+
},
769+
{
770+
name: "valid elicitation with OnCancel skip_remaining",
771+
vmcp: &VirtualMCPServer{
772+
Spec: VirtualMCPServerSpec{
773+
GroupRef: GroupRef{Name: "test-group"},
774+
CompositeTools: []CompositeToolSpec{
775+
{
776+
Name: "test-tool",
777+
Description: "Test composite tool",
778+
Steps: []WorkflowStep{
779+
{
780+
ID: "step1",
781+
Type: WorkflowStepTypeElicitation,
782+
Message: "Please provide input",
783+
OnCancel: &ElicitationResponseHandler{
784+
Action: "skip_remaining",
785+
},
786+
},
787+
},
788+
},
789+
},
790+
},
791+
},
792+
wantErr: false,
793+
},
794+
{
795+
name: "valid elicitation with OnCancel abort",
796+
vmcp: &VirtualMCPServer{
797+
Spec: VirtualMCPServerSpec{
798+
GroupRef: GroupRef{Name: "test-group"},
799+
CompositeTools: []CompositeToolSpec{
800+
{
801+
Name: "test-tool",
802+
Description: "Test composite tool",
803+
Steps: []WorkflowStep{
804+
{
805+
ID: "step1",
806+
Type: WorkflowStepTypeElicitation,
807+
Message: "Please provide input",
808+
OnCancel: &ElicitationResponseHandler{
809+
Action: "abort",
810+
},
811+
},
812+
},
813+
},
814+
},
815+
},
816+
},
817+
wantErr: false,
818+
},
819+
{
820+
name: "valid elicitation with OnCancel continue",
821+
vmcp: &VirtualMCPServer{
822+
Spec: VirtualMCPServerSpec{
823+
GroupRef: GroupRef{Name: "test-group"},
824+
CompositeTools: []CompositeToolSpec{
825+
{
826+
Name: "test-tool",
827+
Description: "Test composite tool",
828+
Steps: []WorkflowStep{
829+
{
830+
ID: "step1",
831+
Type: WorkflowStepTypeElicitation,
832+
Message: "Please provide input",
833+
OnCancel: &ElicitationResponseHandler{
834+
Action: "continue",
835+
},
836+
},
837+
},
838+
},
839+
},
840+
},
841+
},
842+
wantErr: false,
843+
},
844+
{
845+
name: "valid elicitation with both OnDecline and OnCancel",
846+
vmcp: &VirtualMCPServer{
847+
Spec: VirtualMCPServerSpec{
848+
GroupRef: GroupRef{Name: "test-group"},
849+
CompositeTools: []CompositeToolSpec{
850+
{
851+
Name: "test-tool",
852+
Description: "Test composite tool",
853+
Steps: []WorkflowStep{
854+
{
855+
ID: "step1",
856+
Type: WorkflowStepTypeElicitation,
857+
Message: "Please provide input",
858+
OnDecline: &ElicitationResponseHandler{
859+
Action: "skip_remaining",
860+
},
861+
OnCancel: &ElicitationResponseHandler{
862+
Action: "abort",
863+
},
864+
},
865+
},
866+
},
867+
},
868+
},
869+
},
870+
wantErr: false,
871+
},
872+
{
873+
name: "invalid elicitation - OnDecline with invalid action",
874+
vmcp: &VirtualMCPServer{
875+
Spec: VirtualMCPServerSpec{
876+
GroupRef: GroupRef{Name: "test-group"},
877+
CompositeTools: []CompositeToolSpec{
878+
{
879+
Name: "test-tool",
880+
Description: "Test composite tool",
881+
Steps: []WorkflowStep{
882+
{
883+
ID: "step1",
884+
Type: WorkflowStepTypeElicitation,
885+
Message: "Please provide input",
886+
OnDecline: &ElicitationResponseHandler{
887+
Action: "invalid-action",
888+
},
889+
},
890+
},
891+
},
892+
},
893+
},
894+
},
895+
wantErr: true,
896+
errMsg: "spec.compositeTools[0].steps[0].onDecline.action must be one of: skip_remaining, abort, continue",
897+
},
898+
{
899+
name: "invalid elicitation - OnCancel with invalid action",
900+
vmcp: &VirtualMCPServer{
901+
Spec: VirtualMCPServerSpec{
902+
GroupRef: GroupRef{Name: "test-group"},
903+
CompositeTools: []CompositeToolSpec{
904+
{
905+
Name: "test-tool",
906+
Description: "Test composite tool",
907+
Steps: []WorkflowStep{
908+
{
909+
ID: "step1",
910+
Type: WorkflowStepTypeElicitation,
911+
Message: "Please provide input",
912+
OnCancel: &ElicitationResponseHandler{
913+
Action: "invalid-action",
914+
},
915+
},
916+
},
917+
},
918+
},
919+
},
920+
},
921+
wantErr: true,
922+
errMsg: "spec.compositeTools[0].steps[0].onCancel.action must be one of: skip_remaining, abort, continue",
923+
},
694924
}
695925

696926
for _, tt := range tests {

cmd/thv-operator/api/v1alpha1/zz_generated.deepcopy.go

Lines changed: 25 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cmd/thv-operator/pkg/controllerutil/oidc.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ func AddOIDCConfigOptions(
3232
}
3333

3434
// Add OIDC config to options
35+
// Note: Scopes are passed as nil until the operator CRD supports them
3536
*options = append(*options, runner.WithOIDCConfig(
3637
oidcConfig.Issuer,
3738
oidcConfig.Audience,
@@ -44,6 +45,7 @@ func AddOIDCConfigOptions(
4445
oidcConfig.ResourceURL,
4546
oidcConfig.JWKSAllowPrivateIP,
4647
oidcConfig.InsecureAllowHTTP,
48+
nil, // Scopes - TODO: add operator CRD support
4749
))
4850

4951
return nil

0 commit comments

Comments
 (0)