MCPcopy Index your code
hub / github.com/coder/coder / generateFromAnthropic

Function generateFromAnthropic

coderd/taskname/taskname.go:211–301  ·  view source on GitHub ↗

generateFromAnthropic uses Claude (Anthropic) to generate semantic task and display names from a user prompt. It sends the prompt to Claude with a structured system prompt requesting JSON output containing both names. Returns an error if the API call fails, the response is invalid, or Claude returns

(ctx context.Context, prompt string, apiKey string, model anthropic.Model, opts ...anthropicoption.RequestOption)

Source from the content-addressed store, hash-verified

209// It sends the prompt to Claude with a structured system prompt requesting JSON output containing both names.
210// Returns an error if the API call fails, the response is invalid, or Claude returns an "unnamed" placeholder.
211func generateFromAnthropic(ctx context.Context, prompt string, apiKey string, model anthropic.Model, opts ...anthropicoption.RequestOption) (TaskName, error) {
212 anthropicModel := model
213 if anthropicModel == "" {
214 anthropicModel = defaultModel
215 }
216 if apiKey == "" {
217 return TaskName{}, ErrNoAPIKey
218 }
219
220 conversation := []aisdk.Message{
221 {
222 Role: "system",
223 Parts: []aisdk.Part{{
224 Type: aisdk.PartTypeText,
225 Text: systemPrompt,
226 }},
227 },
228 {
229 Role: "user",
230 Parts: []aisdk.Part{{
231 Type: aisdk.PartTypeText,
232 Text: prompt,
233 }},
234 },
235 }
236
237 anthropicOptions := anthropic.DefaultClientOptions()
238 anthropicOptions = append(anthropicOptions, anthropicoption.WithAPIKey(apiKey))
239 anthropicOptions = append(anthropicOptions, opts...)
240 anthropicClient := anthropic.NewClient(anthropicOptions...)
241
242 stream, err := anthropicDataStream(ctx, anthropicClient, anthropicModel, conversation)
243 if err != nil {
244 return TaskName{}, xerrors.Errorf("create anthropic data stream: %w", err)
245 }
246
247 var acc aisdk.DataStreamAccumulator
248 stream = stream.WithAccumulator(&acc)
249
250 if err := stream.Pipe(io.Discard); err != nil {
251 return TaskName{}, xerrors.Errorf("pipe data stream")
252 }
253
254 if len(acc.Messages()) == 0 {
255 return TaskName{}, ErrNoNameGenerated
256 }
257
258 // Parse the JSON response. LLMs sometimes wrap JSON in
259 // markdown code fences (```json ... ```), so we strip
260 // those before unmarshalling.
261 var taskNameResponse TaskName
262 if err := json.Unmarshal([]byte(extractJSON(acc.Messages()[0].Content)), &taskNameResponse); err != nil {
263 return TaskName{}, xerrors.Errorf("failed to parse anthropic response: %w", err)
264 }
265
266 taskNameResponse.Name = strings.TrimSpace(taskNameResponse.Name)
267 taskNameResponse.DisplayName = strings.TrimSpace(taskNameResponse.DisplayName)
268

Callers 3

GenerateFunction · 0.85

Calls 6

NameValidFunction · 0.92
anthropicDataStreamFunction · 0.85
extractJSONFunction · 0.85
generateSuffixFunction · 0.85
ErrorfMethod · 0.45
UnmarshalMethod · 0.45

Tested by 2