feat(runner): append spec instructions to llm system prompt

This commit is contained in:
pj committed 2026-07-13 07:02:17 +05:30
1 parent d9d206ee00
commit 637f89ab08
3 files changed
+35 -8

No files matched your search

+16 -3
View File
@@ -52,8 +52,11 @@ type llmSource struct {
verifier *verifier.Verifier
client *llmclient.Client
model string
logger *slog.Logger
history *actionHistory
// instructions is optional spec-level guidance appended to the system prompt
// to steer the model's bug-hunting (empty when unset).
instructions string
logger *slog.Logger
history *actionHistory
// lastSource/lastReasoning describe the most recent NextAction so the runner
// can stamp the trace. lastSource is "llm" only when the LLM (not setup)
@@ -159,13 +162,23 @@ func (s *llmSource) buildRequest(candidates []verifier.ActionCandidate) llmclien
return llmclient.Request{
Model: s.model,
Messages: []llmclient.Message{
{Role: "system", Content: []llmclient.ContentPart{llmclient.TextPart(llmSystemPrompt)}},
{Role: "system", Content: []llmclient.ContentPart{llmclient.TextPart(s.systemPrompt())}},
{Role: "user", Content: userParts},
},
ResponseFormat: rankedResponseFormat(),
}
}
// systemPrompt is the base framing plus any spec-level instructions, appended as
// extra guidance so a spec can steer the model's bug-hunting without losing the
// candidate-kind semantics the base prompt establishes.
func (s *llmSource) systemPrompt() string {
if strings.TrimSpace(s.instructions) == "" {
return llmSystemPrompt
}
return llmSystemPrompt + "\n\n" + s.instructions
}
// userPrompt renders the numbered candidate list and the recent-action memory.
func (s *llmSource) userPrompt(candidates []verifier.ActionCandidate) string {
var builder strings.Builder
+13
View File
@@ -141,6 +141,19 @@ func TestParseRanked(t *testing.T) {
}
}
func TestSystemPromptAppendsInstructions(t *testing.T) {
if got := (&llmSource{}).systemPrompt(); got != llmSystemPrompt {
t.Error("empty instructions should yield the base prompt unchanged")
}
withInstr := (&llmSource{instructions: "hunt for double submits"}).systemPrompt()
if !strings.Contains(withInstr, llmSystemPrompt) {
t.Error("system prompt must retain the base framing")
}
if !strings.Contains(withInstr, "hunt for double submits") {
t.Error("system prompt must include the spec instructions")
}
}
// fakeOpenRouter is a configurable in-process OpenRouter server. Set ranked /
// reasoning before each call; it echoes them as a json_schema content body.
type fakeOpenRouter struct {
+6 -5
View File
@@ -83,11 +83,12 @@ func pickSources(options Options) (ActionSource, ExtractorSource, error) {
logger = slog.Default()
}
action := &llmSource{
verifier: options.Verifier,
client: client,
model: config.Model,
logger: logger,
history: newActionHistory(llmHistorySize),
verifier: options.Verifier,
client: client,
model: config.Model,
instructions: config.Instructions,
logger: logger,
history: newActionHistory(llmHistorySize),
}
return action, gojaSource{verifier: options.Verifier}, nil
}