refactor: remove pkg/prompts — consolidated into pkg/lib
Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
53482cb0c8
commit
dc7c89fdae
4 changed files with 14 additions and 167 deletions
|
|
@ -18,7 +18,6 @@ import (
|
|||
"time"
|
||||
|
||||
"forge.lthn.ai/core/agent/pkg/lib"
|
||||
"forge.lthn.ai/core/agent/pkg/prompts"
|
||||
coreio "forge.lthn.ai/core/go-io"
|
||||
coreerr "forge.lthn.ai/core/go-log"
|
||||
"github.com/modelcontextprotocol/go-sdk/mcp"
|
||||
|
|
@ -209,12 +208,12 @@ func (s *PrepSubsystem) prepWorkspace(ctx context.Context, _ *mcp.CallToolReques
|
|||
wsTmpl = "review"
|
||||
}
|
||||
|
||||
promptContent, _ := prompts.Prompt(input.Template)
|
||||
promptContent, _ := lib.Prompt(input.Template)
|
||||
personaContent := ""
|
||||
if input.Persona != "" {
|
||||
personaContent, _ = prompts.Persona(input.Persona)
|
||||
personaContent, _ = lib.Persona(input.Persona)
|
||||
}
|
||||
flowContent, _ := prompts.Flow(detectLanguage(repoPath))
|
||||
flowContent, _ := lib.Flow(detectLanguage(repoPath))
|
||||
|
||||
wsData := &lib.WorkspaceData{
|
||||
Repo: input.Repo,
|
||||
|
|
@ -278,10 +277,10 @@ func (s *PrepSubsystem) prepWorkspace(ctx context.Context, _ *mcp.CallToolReques
|
|||
// --- Prompt templates ---
|
||||
|
||||
func (s *PrepSubsystem) writePromptTemplate(template, wsDir string) {
|
||||
prompt, err := prompts.Template(template)
|
||||
prompt, err := lib.Template(template)
|
||||
if err != nil {
|
||||
// Fallback to default template
|
||||
prompt, _ = prompts.Template("default")
|
||||
prompt, _ = lib.Template("default")
|
||||
if prompt == "" {
|
||||
prompt = "Read TODO.md and complete the task. Work in src/.\n"
|
||||
}
|
||||
|
|
@ -296,7 +295,7 @@ func (s *PrepSubsystem) writePromptTemplate(template, wsDir string) {
|
|||
// and writes PLAN.md into the workspace src/ directory.
|
||||
func (s *PrepSubsystem) writePlanFromTemplate(templateSlug string, variables map[string]string, task string, wsDir string) {
|
||||
// Load template from embedded prompts package
|
||||
data, err := prompts.Template(templateSlug)
|
||||
data, err := lib.Template(templateSlug)
|
||||
if err != nil {
|
||||
return // Template not found, skip silently
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,6 +48,14 @@ var workspaceFS embed.FS
|
|||
|
||||
// --- Prompts ---
|
||||
|
||||
// Template tries Prompt then Task (backwards compat).
|
||||
func Template(slug string) (string, error) {
|
||||
if content, err := Prompt(slug); err == nil {
|
||||
return content, nil
|
||||
}
|
||||
return Task(slug)
|
||||
}
|
||||
|
||||
func Prompt(slug string) (string, error) {
|
||||
data, err := promptFS.ReadFile("prompt/" + slug + ".md")
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -1,19 +0,0 @@
|
|||
// SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
// Package prompts re-exports the lib package for backwards compatibility.
|
||||
// New code should import pkg/lib directly.
|
||||
package prompts
|
||||
|
||||
import "forge.lthn.ai/core/agent/pkg/lib"
|
||||
|
||||
func Prompt(slug string) (string, error) { return lib.Prompt(slug) }
|
||||
func Task(slug string) (string, error) { return lib.Task(slug) }
|
||||
func TaskBundle(slug string) (string, map[string]string, error) { return lib.TaskBundle(slug) }
|
||||
func Flow(slug string) (string, error) { return lib.Flow(slug) }
|
||||
func Persona(path string) (string, error) { return lib.Persona(path) }
|
||||
func Template(slug string) (string, error) { return lib.Prompt(slug) }
|
||||
func ListPrompts() []string { return lib.ListPrompts() }
|
||||
func ListTasks() []string { return lib.ListTasks() }
|
||||
func ListFlows() []string { return lib.ListFlows() }
|
||||
func ListPersonas() []string { return lib.ListPersonas() }
|
||||
func ListTemplates() []string { return append(lib.ListPrompts(), lib.ListTasks()...) }
|
||||
|
|
@ -1,141 +0,0 @@
|
|||
// SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
package prompts
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestPrompt_Good(t *testing.T) {
|
||||
content, err := Prompt("coding")
|
||||
require.NoError(t, err)
|
||||
assert.Contains(t, content, "SANDBOX")
|
||||
assert.Contains(t, content, "Closeout Sequence")
|
||||
}
|
||||
|
||||
func TestPrompt_Bad_NotFound(t *testing.T) {
|
||||
_, err := Prompt("nonexistent")
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestTask_Good(t *testing.T) {
|
||||
content, err := Task("bug-fix")
|
||||
require.NoError(t, err)
|
||||
assert.Contains(t, content, "name:")
|
||||
}
|
||||
|
||||
func TestTask_Good_Nested(t *testing.T) {
|
||||
content, err := Task("code/review")
|
||||
require.NoError(t, err)
|
||||
assert.Contains(t, content, "Code Review")
|
||||
}
|
||||
|
||||
func TestTaskBundle_Good(t *testing.T) {
|
||||
main, bundle, err := TaskBundle("code/review")
|
||||
require.NoError(t, err)
|
||||
assert.Contains(t, main, "Code Review")
|
||||
assert.NotNil(t, bundle)
|
||||
assert.Contains(t, bundle, "conventions.md")
|
||||
assert.Contains(t, bundle, "severity.md")
|
||||
assert.Contains(t, bundle["conventions.md"], "coreerr.E")
|
||||
}
|
||||
|
||||
func TestTaskBundle_Good_NoBundleDir(t *testing.T) {
|
||||
main, bundle, err := TaskBundle("bug-fix")
|
||||
require.NoError(t, err)
|
||||
assert.Contains(t, main, "name:")
|
||||
assert.Nil(t, bundle)
|
||||
}
|
||||
|
||||
func TestTask_Bad_NotFound(t *testing.T) {
|
||||
_, err := Task("nonexistent")
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestTemplate_Good_BackwardsCompat(t *testing.T) {
|
||||
content, err := Template("coding")
|
||||
require.NoError(t, err)
|
||||
assert.Contains(t, content, "SANDBOX")
|
||||
|
||||
content, err = Template("bug-fix")
|
||||
require.NoError(t, err)
|
||||
assert.Contains(t, content, "name:")
|
||||
}
|
||||
|
||||
func TestFlow_Good(t *testing.T) {
|
||||
content, err := Flow("go")
|
||||
require.NoError(t, err)
|
||||
assert.Contains(t, content, "go build")
|
||||
}
|
||||
|
||||
func TestFlow_Good_Docker(t *testing.T) {
|
||||
content, err := Flow("docker")
|
||||
require.NoError(t, err)
|
||||
assert.Contains(t, content, "docker build")
|
||||
}
|
||||
|
||||
func TestPersona_Good(t *testing.T) {
|
||||
content, err := Persona("secops/developer")
|
||||
require.NoError(t, err)
|
||||
assert.Contains(t, content, "name:")
|
||||
}
|
||||
|
||||
func TestPersona_Good_SMM(t *testing.T) {
|
||||
content, err := Persona("smm/security-developer")
|
||||
require.NoError(t, err)
|
||||
assert.Contains(t, content, "OAuth")
|
||||
}
|
||||
|
||||
func TestPersona_Bad_NotFound(t *testing.T) {
|
||||
_, err := Persona("nonexistent/persona")
|
||||
assert.Error(t, err)
|
||||
}
|
||||
|
||||
func TestListPrompts_Good(t *testing.T) {
|
||||
list := ListPrompts()
|
||||
assert.Contains(t, list, "coding")
|
||||
assert.Contains(t, list, "verify")
|
||||
assert.True(t, len(list) >= 5)
|
||||
}
|
||||
|
||||
func TestListTasks_Good(t *testing.T) {
|
||||
list := ListTasks()
|
||||
assert.Contains(t, list, "bug-fix")
|
||||
// Nested tasks
|
||||
hasCodeReview := false
|
||||
for _, t := range list {
|
||||
if t == "code/review" {
|
||||
hasCodeReview = true
|
||||
}
|
||||
}
|
||||
assert.True(t, hasCodeReview, "code/review not found in tasks")
|
||||
}
|
||||
|
||||
func TestListFlows_Good(t *testing.T) {
|
||||
list := ListFlows()
|
||||
assert.Contains(t, list, "go")
|
||||
assert.Contains(t, list, "php")
|
||||
assert.Contains(t, list, "docker")
|
||||
assert.True(t, len(list) >= 9)
|
||||
}
|
||||
|
||||
func TestListPersonas_Good(t *testing.T) {
|
||||
personas := ListPersonas()
|
||||
assert.True(t, len(personas) >= 90)
|
||||
}
|
||||
|
||||
func TestListPersonas_Good_NoPrefixDuplication(t *testing.T) {
|
||||
for _, p := range ListPersonas() {
|
||||
parts := strings.Split(p, "/")
|
||||
if len(parts) == 2 {
|
||||
domain := parts[0]
|
||||
file := parts[1]
|
||||
assert.False(t, strings.HasPrefix(file, domain+"-"),
|
||||
"persona %q has redundant domain prefix in filename", p)
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue