Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion pkg/bsql/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,6 @@ type ActionConfig struct {

type ArgumentConfig struct {
Name string `yaml:"name" json:"name" validate:"required"`
DisplayName string `yaml:"display_name,omitempty" json:"display_name,omitempty" validate:"omitempty"`
Description string `yaml:"description,omitempty" json:"description,omitempty" validate:"omitempty"`
//revive:disable-next-line:line-length-limit // because it's a long field
Type string `yaml:"type" json:"type" validate:"required,oneof=string boolean number string_list string_map" jsonschema:"enum=string,enum=boolean,enum=number,enum=string_list,enum=string_map"`
Expand Down
29 changes: 13 additions & 16 deletions pkg/connector/action.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,16 +57,13 @@ func (c *Connector) RegisterActionManager(ctx context.Context) (connectorbuilder
ActionType: convertActionTypes(actionCfg.ActionType),
}

for _, argCfg := range actionCfg.Arguments {
for k, argCfg := range actionCfg.Arguments {
arg := &config_sdk.Field{
Name: argCfg.Name,
DisplayName: argCfg.DisplayName,
Name: k,
DisplayName: argCfg.Name,
Description: argCfg.Description,
IsRequired: argCfg.Required,
}
if arg.DisplayName == "" {
arg.DisplayName = argCfg.Name
}
defaultValue := argCfg.Default
switch argCfg.Type {
case "string":
Expand Down Expand Up @@ -138,7 +135,7 @@ func (c *Connector) RegisterActionManager(ctx context.Context) (connectorbuilder
cfg := actionCfg

err := actionManager.RegisterAction(ctx, actionKey, actionSchema, func(ctx context.Context, args *structpb.Struct) (*structpb.Struct, annotations.Annotations, error) {
return c.handleQueryAction(ctx, cfg, args)
return c.handleQueryAction(ctx, actionKey, cfg, args)
})
if err != nil {
l.Error("failed to register action", zap.String("action", actionKey), zap.Error(err))
Expand All @@ -150,9 +147,9 @@ func (c *Connector) RegisterActionManager(ctx context.Context) (connectorbuilder
return actionManager, nil
}

func (c *Connector) handleQueryAction(ctx context.Context, actionCfg bsql.ActionConfig, args *structpb.Struct) (*structpb.Struct, annotations.Annotations, error) {
func (c *Connector) handleQueryAction(ctx context.Context, actionKey string, actionCfg bsql.ActionConfig, args *structpb.Struct) (*structpb.Struct, annotations.Annotations, error) {
l := ctxzap.Extract(ctx)
l.Debug("actionHandler", zap.String("action", actionCfg.Name))
l.Debug("actionHandler", zap.String("action", actionKey))

sqlSyncer, err := bsql.NewActionSyncer(ctx, c.db, c.dbEngine, c.celEnv, *c.config)
if err != nil {
Expand All @@ -163,7 +160,7 @@ func (c *Connector) handleQueryAction(ctx context.Context, actionCfg bsql.Action
for k, v := range actionCfg.Arguments {
if _, ok := args.Fields[k]; !ok {
if v.Required {
return nil, nil, fmt.Errorf("argument %s is required", v.Name)
return nil, nil, fmt.Errorf("argument %s is required", k)
}
if v.Default != nil {
argMap[k] = v.Default
Expand All @@ -172,22 +169,22 @@ func (c *Connector) handleQueryAction(ctx context.Context, actionCfg bsql.Action
}
switch v.Type {
case "string":
argMap[k] = args.Fields[v.Name].GetStringValue()
argMap[k] = args.Fields[k].GetStringValue()
case "boolean":
argMap[k] = args.Fields[v.Name].GetBoolValue()
argMap[k] = args.Fields[k].GetBoolValue()
case "number":
argMap[k] = args.Fields[v.Name].GetNumberValue()
argMap[k] = args.Fields[k].GetNumberValue()
case "string_list":
Comment on lines 171 to 177

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Ensure “number” args are integers at runtime and keep types consistent.

GetNumberValue yields float64; schema uses IntField. Validate and cast to int64 to avoid mixed types and SQL/CEL mismatches.

-		case "number":
-			argMap[k] = args.Fields[k].GetNumberValue()
+		case "number":
+			n := args.Fields[k].GetNumberValue()
+			if math.Trunc(n) != n {
+				return nil, nil, fmt.Errorf("argument %q must be an integer for action %q: got %v", k, actionKey, n)
+			}
+			argMap[k] = int64(n)

As per coding guidelines.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
case "string":
argMap[k] = args.Fields[v.Name].GetStringValue()
argMap[k] = args.Fields[k].GetStringValue()
case "boolean":
argMap[k] = args.Fields[v.Name].GetBoolValue()
argMap[k] = args.Fields[k].GetBoolValue()
case "number":
argMap[k] = args.Fields[v.Name].GetNumberValue()
argMap[k] = args.Fields[k].GetNumberValue()
case "string_list":
case "string":
argMap[k] = args.Fields[k].GetStringValue()
case "boolean":
argMap[k] = args.Fields[k].GetBoolValue()
case "number":
n := args.Fields[k].GetNumberValue()
if math.Trunc(n) != n {
return nil, nil, fmt.Errorf("argument %q must be an integer for action %q: got %v", k, actionKey, n)
}
argMap[k] = int64(n)
case "string_list":
🤖 Prompt for AI Agents
In pkg/connector/action.go around lines 171 to 177, the "number" branch
currently takes GetNumberValue() (float64) which can produce mixed types against
an IntField schema; change it to validate the float is an integer at runtime
(e.g., compare to its truncated value or use modulus), fail/return an error if
not integral, then cast the value to int64 and store that int64 in argMap so
downstream SQL/CEL sees a consistent integer type.

values := args.Fields[v.Name].GetListValue().GetValues()
values := args.Fields[k].GetListValue().GetValues()
var stringList []string
for _, value := range values {
stringList = append(stringList, value.GetStringValue())
}
argMap[k] = stringList
case "string_map":
argMap[k] = args.Fields[v.Name].GetStructValue().AsMap()
argMap[k] = args.Fields[k].GetStructValue().AsMap()
default:
return nil, nil, fmt.Errorf("unsupported argument type: %s", v.Type)
return nil, nil, fmt.Errorf("argument %s has unsupported type: %s", k, v.Type)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Action Argument Retrieval Mismatch

The action argument schema now uses the map key k as the argument name, but the handleQueryAction function still attempts to retrieve argument values using v.Name. This inconsistency means incoming arguments won't be found, causing action processing to fail.

Fix in Cursor Fix in Web

}
}

Expand Down