mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
feat: add display name field for tasks (#20856)
## Problem Tasks currently only expose a machine-friendly name field (e.g. `task-python-debug-a1b2`), but this value is primarily an identifier rather than a clean, descriptive label. We need a separate display-friendly name for use in the UI. This PR introduces a new `display_name` field and updates the task-name generation flow. The Claude system prompt was updated to return valid JSON with both `name` and `display_name`. The name generation logic follows a fallback chain (Anthropic > prompt sanitization > random fallback). To make task names more closely resemble their display names, the legacy `task-` prefix has been removed. For context, PR https://github.com/coder/coder/pull/20834 introduced a small Task icon to the workspace list to help identify workspaces associated to tasks. ## Changes - Database migration: Added `display_name` column to tasks table - Updated system prompt to generate both task name and display name as valid JSON - Task name generation now follows a fallback chain: Anthropic > prompt sanitization > random fallback - Removed `task-` prefix from task names to allow more descriptive names - Note: PR https://github.com/coder/coder/pull/20834 adds a Task icon to workspaces in the workspace list to distinguish task-created workspaces **Note:** UI changes will be addressed in a follow-up PR Related to: https://github.com/coder/coder/issues/20801
This commit is contained in:
@@ -15,42 +15,51 @@ const (
|
||||
anthropicEnvVar = "ANTHROPIC_API_KEY"
|
||||
)
|
||||
|
||||
func TestGenerateFallback(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
name := taskname.GenerateFallback()
|
||||
err := codersdk.NameValid(name)
|
||||
require.NoErrorf(t, err, "expected fallback to be valid workspace name, instead found %s", name)
|
||||
}
|
||||
|
||||
func TestGenerateTaskName(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
t.Run("Fallback", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
func TestGenerate(t *testing.T) {
|
||||
t.Run("FromPrompt", func(t *testing.T) {
|
||||
// Ensure no API key in env for this test
|
||||
t.Setenv("ANTHROPIC_API_KEY", "")
|
||||
|
||||
ctx := testutil.Context(t, testutil.WaitShort)
|
||||
|
||||
name, err := taskname.Generate(ctx, "Some random prompt")
|
||||
require.ErrorIs(t, err, taskname.ErrNoAPIKey)
|
||||
require.Equal(t, "", name)
|
||||
taskName := taskname.Generate(ctx, testutil.Logger(t), "Create a finance planning app")
|
||||
|
||||
// Should succeed via prompt sanitization
|
||||
require.NoError(t, codersdk.NameValid(taskName.Name))
|
||||
require.Contains(t, taskName.Name, "create-a-finance-planning-")
|
||||
require.NotEmpty(t, taskName.DisplayName)
|
||||
require.Equal(t, "Create a finance planning app", taskName.DisplayName)
|
||||
})
|
||||
|
||||
t.Run("Anthropic", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
t.Run("FromAnthropic", func(t *testing.T) {
|
||||
apiKey := os.Getenv(anthropicEnvVar)
|
||||
if apiKey == "" {
|
||||
t.Skipf("Skipping test as %s not set", anthropicEnvVar)
|
||||
}
|
||||
|
||||
// Set API key for this test
|
||||
t.Setenv("ANTHROPIC_API_KEY", apiKey)
|
||||
|
||||
ctx := testutil.Context(t, testutil.WaitShort)
|
||||
|
||||
name, err := taskname.Generate(ctx, "Create a finance planning app", taskname.WithAPIKey(apiKey))
|
||||
require.NoError(t, err)
|
||||
require.NotEqual(t, "", name)
|
||||
taskName := taskname.Generate(ctx, testutil.Logger(t), "Create a finance planning app")
|
||||
|
||||
err = codersdk.NameValid(name)
|
||||
require.NoError(t, err, "name should be valid")
|
||||
// Should succeed with Claude-generated names
|
||||
require.NoError(t, codersdk.NameValid(taskName.Name))
|
||||
require.NotEmpty(t, taskName.DisplayName)
|
||||
})
|
||||
|
||||
t.Run("Fallback", func(t *testing.T) {
|
||||
// Ensure no API key
|
||||
t.Setenv("ANTHROPIC_API_KEY", "")
|
||||
|
||||
ctx := testutil.Context(t, testutil.WaitShort)
|
||||
|
||||
// Use a prompt that can't be sanitized (only special chars)
|
||||
taskName := taskname.Generate(ctx, testutil.Logger(t), "!@#$%^&*()")
|
||||
|
||||
// Should fall back to random name
|
||||
require.NoError(t, codersdk.NameValid(taskName.Name))
|
||||
require.NotEmpty(t, taskName.DisplayName)
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user