internal/genai: move prompt template to files

Store prompt text in files instead of constants.

Change-Id: I121784e70f650f3505bede7a96cc3c5ff25c9c81
Reviewed-on: https://go-review.googlesource.com/c/vulndb/+/553515
LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Reviewed-by: Damien Neil <dneil@google.com>
diff --git a/internal/genai/data/prompt.txt b/internal/genai/data/example_prompt.txt
similarity index 100%
rename from internal/genai/data/prompt.txt
rename to internal/genai/data/example_prompt.txt
diff --git a/internal/genai/examples.go b/internal/genai/examples.go
index 0ad3fc1..a0abbaa 100644
--- a/internal/genai/examples.go
+++ b/internal/genai/examples.go
@@ -28,7 +28,7 @@
 
 const (
 	dataFolder = "data"
-	promptFile = "prompt.txt"
+	promptFile = "example_prompt.txt"
 	csvFile    = "examples.csv"
 	jsonFile   = "examples.json"
 )
diff --git a/internal/genai/prompt.go b/internal/genai/prompt.go
index 4b715c2..62cac1b 100644
--- a/internal/genai/prompt.go
+++ b/internal/genai/prompt.go
@@ -12,16 +12,19 @@
 	"text/template"
 )
 
-const (
-	defaultPreamble = `You are an expert computer security researcher. You are helping the Go programming language security team write high-quality, correct, and
-concise summaries and descriptions for the Go vulnerability database.
+var (
+	//go:embed templates/preamble.txt
+	defaultPreamble string
 
-Given an affected module and a description of a vulnerability, output a JSON object containing 1) Summary: a short phrase identifying the core vulnerability, ending in the module name, and 2) Description: a plain text, one-to-two paragraph description of the vulnerability, omitting version numbers, written in the present tense that highlights the impact of the vulnerability. The description should be concise, accurate, and easy to understand. It should also be written in a style that is consistent with the existing Go vulnerability database.`
-	defaultMaxExamples = 15
+	//go:embed templates/prompt.tmpl
+	promptTmpl string
+	prompt     = template.Must(template.New("prompt").Funcs(template.FuncMap{"toJSON": toJSON}).Parse(promptTmpl))
+
+	//go:embed data/examples.json
+	defaultExamples []byte
 )
 
-//go:embed data/examples.json
-var defaultExamples []byte
+const defaultMaxExamples = 15
 
 func defaultPrompt(in *Input) (string, error) {
 	var es Examples
@@ -31,15 +34,6 @@
 	return newPrompt(in, defaultPreamble, es, defaultMaxExamples)
 }
 
-const (
-	promptTmpl = `
-{{ range .Examples }}
-input: {{ .Input | toJSON }}
-output: {{ .Suggestion | toJSON }}{{ end }}
-input: {{ .Input | toJSON }}
-output:`
-)
-
 func toJSON(v any) string {
 	b, err := json.Marshal(v)
 	if err != nil {
@@ -48,20 +42,17 @@
 	return string(b)
 }
 
-var prompt = template.Must(template.New("prompt").Funcs(template.FuncMap{"toJSON": toJSON}).Parse(promptTmpl))
-
 func newPrompt(in *Input, preamble string, examples Examples, maxExamples int) (string, error) {
 	if len(examples) > maxExamples {
 		examples = examples[:maxExamples]
 	}
 	var b strings.Builder
-	if _, err := b.WriteString(preamble); err != nil {
-		return "", err
-	}
 	if err := prompt.Execute(&b, struct {
+		Preamble string
 		Examples Examples
 		Input    *Input
 	}{
+		Preamble: preamble,
 		Examples: examples,
 		Input:    in,
 	}); err != nil {
diff --git a/internal/genai/templates/preamble.txt b/internal/genai/templates/preamble.txt
new file mode 100644
index 0000000..d6e1ee5
--- /dev/null
+++ b/internal/genai/templates/preamble.txt
@@ -0,0 +1,4 @@
+You are an expert computer security researcher. You are helping the Go programming language security team write high-quality, correct, and
+concise summaries and descriptions for the Go vulnerability database.
+
+Given an affected module and a description of a vulnerability, output a JSON object containing 1) Summary: a short phrase identifying the core vulnerability, ending in the module name, and 2) Description: a plain text, one-to-two paragraph description of the vulnerability, omitting version numbers, written in the present tense that highlights the impact of the vulnerability. The description should be concise, accurate, and easy to understand. It should also be written in a style that is consistent with the existing Go vulnerability database.
\ No newline at end of file
diff --git a/internal/genai/templates/prompt.tmpl b/internal/genai/templates/prompt.tmpl
new file mode 100644
index 0000000..996a29f
--- /dev/null
+++ b/internal/genai/templates/prompt.tmpl
@@ -0,0 +1,6 @@
+{{ .Preamble }}
+{{ range .Examples }}
+input: {{ .Input | toJSON }}
+output: {{ .Suggestion | toJSON }}{{ end }}
+input: {{ .Input | toJSON }}
+output:
\ No newline at end of file