mirror of
https://github.com/coder/coder.git
synced 2026-06-02 20:48:20 +00:00
fix(coderd/x/chatd/chattool): parse complete goal IDs from strings
This commit is contained in:
@@ -32,8 +32,8 @@ type GoalToolOptions struct {
|
||||
type getGoalArgs struct{}
|
||||
|
||||
type completeGoalArgs struct {
|
||||
GoalID uuid.UUID `json:"goal_id" description:"The expected current goal ID. The tool fails if the current goal changed."`
|
||||
Summary string `json:"summary" description:"A concise non-empty summary of how the goal was completed."`
|
||||
GoalID string `json:"goal_id" description:"The expected current goal ID. The tool fails if the current goal changed."`
|
||||
Summary string `json:"summary" description:"A concise non-empty summary of how the goal was completed."`
|
||||
}
|
||||
|
||||
type goalResult struct {
|
||||
@@ -74,9 +74,16 @@ func CompleteGoal(db database.Store, options GoalToolOptions) fantasy.AgentTool
|
||||
if !options.IsRootChat {
|
||||
return fantasy.NewTextErrorResponse("complete_goal can only be used from the root chat"), nil
|
||||
}
|
||||
if args.GoalID == uuid.Nil {
|
||||
goalIDStr := strings.TrimSpace(args.GoalID)
|
||||
if goalIDStr == "" {
|
||||
return fantasy.NewTextErrorResponse("goal_id is required"), nil
|
||||
}
|
||||
goalID, err := uuid.Parse(goalIDStr)
|
||||
if err != nil {
|
||||
return fantasy.NewTextErrorResponse(
|
||||
xerrors.Errorf("invalid goal_id: %w", err).Error(),
|
||||
), nil
|
||||
}
|
||||
summary := strings.TrimSpace(args.Summary)
|
||||
if summary == "" {
|
||||
return fantasy.NewTextErrorResponse("summary is required"), nil
|
||||
@@ -98,7 +105,7 @@ func CompleteGoal(db database.Store, options GoalToolOptions) fantasy.AgentTool
|
||||
}
|
||||
return err
|
||||
}
|
||||
if current.ID != args.GoalID {
|
||||
if current.ID != goalID {
|
||||
return sql.ErrNoRows
|
||||
}
|
||||
if current.Status != database.ChatGoalStatusActive {
|
||||
@@ -109,7 +116,7 @@ func CompleteGoal(db database.Store, options GoalToolOptions) fantasy.AgentTool
|
||||
}
|
||||
completed, err = tx.CompleteChatGoalByID(ctx, database.CompleteChatGoalByIDParams{
|
||||
RootChatID: options.RootChatID,
|
||||
ID: args.GoalID,
|
||||
ID: goalID,
|
||||
CompletionSummary: sql.NullString{
|
||||
String: summary,
|
||||
Valid: true,
|
||||
|
||||
@@ -81,6 +81,17 @@ func TestGoalTools(t *testing.T) {
|
||||
require.Equal(t, database.ChatGoalStatusComplete, completedGoal.Status)
|
||||
}
|
||||
|
||||
func TestCompleteGoalSchemaUsesStringGoalID(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
tool := chattool.CompleteGoal(nil, chattool.GoalToolOptions{})
|
||||
info := tool.Info()
|
||||
goalIDParam, ok := info.Parameters["goal_id"].(map[string]any)
|
||||
require.True(t, ok)
|
||||
require.Equal(t, "string", goalIDParam["type"])
|
||||
require.NotEqual(t, "array", goalIDParam["type"])
|
||||
}
|
||||
|
||||
func TestGetGoalReturnsNullWithoutCurrentGoal(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
@@ -134,6 +145,16 @@ func TestCompleteGoalValidatesInput(t *testing.T) {
|
||||
input: `{"summary":"done"}`,
|
||||
message: "goal_id is required",
|
||||
},
|
||||
{
|
||||
name: "empty goal id",
|
||||
input: `{"goal_id":" ","summary":"done"}`,
|
||||
message: "goal_id is required",
|
||||
},
|
||||
{
|
||||
name: "invalid goal id",
|
||||
input: `{"goal_id":"not-a-uuid","summary":"done"}`,
|
||||
message: "invalid goal_id",
|
||||
},
|
||||
{
|
||||
name: "empty summary",
|
||||
input: `{"goal_id":"00000000-0000-4000-8000-000000000001","summary":" "}`,
|
||||
|
||||
Reference in New Issue
Block a user