package activity import ( "context" "fmt" "github.com/rockliang/poimen/workflows/activity/llm" "github.com/rockliang/poimen/workflows/pkg/types" "github.com/rockliang/poimen/workflows/prompts" ) // CallRoleLLM is the shared pattern for calling an LLM with a role-based prompt. // Used by planner, implementer, and judge activities (DRY extraction). func CallRoleLLM(ctx context.Context, config types.OrchestratorConfig, role string, vars map[string]any) (string, error) { client, err := llm.NewClient() if err != nil { return "", fmt.Errorf("failed to create LLM client: %w", err) } spec, exists := config.RolePrompts[role] if !exists { return "", fmt.Errorf("%s role prompt not configured", role) } // Render template var content string if spec.RawTemplate != "" { content = spec.RawTemplate } else { content, err = prompts.Render(spec.TemplateRef, vars) if err != nil { return "", fmt.Errorf("failed to render %s template: %w", role, err) } } // Call LLM response, err := client.CreateMessage(ctx, llm.MessageInput{ Model: spec.Model, SystemPrompt: config.SystemPrompt, Messages: []llm.MessageParam{{Role: "user", Content: content}}, }) if err != nil { return "", fmt.Errorf("%s LLM call failed: %w", role, err) } return response, nil }