feat(agentic): add prompt snapshot lookup
Co-Authored-By: Virgil <virgil@lethean.io>
This commit is contained in:
parent
d6a03be140
commit
43e2efe7cd
6 changed files with 155 additions and 0 deletions
|
|
@ -57,6 +57,8 @@ func (s *PrepSubsystem) registerCommands(ctx context.Context) {
|
|||
c.Command("agentic:review-queue", core.Command{Description: "Process the CodeRabbit review queue", Action: s.cmdReviewQueue})
|
||||
c.Command("status", core.Command{Description: "List agent workspace statuses", Action: s.cmdStatus})
|
||||
c.Command("prompt", core.Command{Description: "Build and display an agent prompt for a repo", Action: s.cmdPrompt})
|
||||
c.Command("prompt/version", core.Command{Description: "Read the current prompt snapshot for a workspace", Action: s.cmdPromptVersion})
|
||||
c.Command("agentic:prompt/version", core.Command{Description: "Read the current prompt snapshot for a workspace", Action: s.cmdPromptVersion})
|
||||
c.Command("extract", core.Command{Description: "Extract a workspace template to a directory", Action: s.cmdExtract})
|
||||
s.registerPlanCommands()
|
||||
s.registerSessionCommands()
|
||||
|
|
@ -663,6 +665,38 @@ func (s *PrepSubsystem) cmdPrompt(options core.Options) core.Result {
|
|||
return core.Result{OK: true}
|
||||
}
|
||||
|
||||
func (s *PrepSubsystem) cmdPromptVersion(options core.Options) core.Result {
|
||||
workspace := optionStringValue(options, "workspace", "_arg")
|
||||
if workspace == "" {
|
||||
core.Print(nil, "usage: core-agent prompt version <workspace>")
|
||||
return core.Result{Value: core.E("agentic.cmdPromptVersion", "workspace is required", nil), OK: false}
|
||||
}
|
||||
|
||||
result := s.handlePromptVersion(s.commandContext(), core.NewOptions(
|
||||
core.Option{Key: "workspace", Value: workspace},
|
||||
))
|
||||
if !result.OK {
|
||||
err := commandResultError("agentic.cmdPromptVersion", result)
|
||||
core.Print(nil, "error: %v", err)
|
||||
return core.Result{Value: err, OK: false}
|
||||
}
|
||||
|
||||
output, ok := result.Value.(PromptVersionOutput)
|
||||
if !ok {
|
||||
err := core.E("agentic.cmdPromptVersion", "invalid prompt version output", nil)
|
||||
core.Print(nil, "error: %v", err)
|
||||
return core.Result{Value: err, OK: false}
|
||||
}
|
||||
|
||||
core.Print(nil, "workspace: %s", output.Workspace)
|
||||
core.Print(nil, "hash: %s", output.Snapshot.Hash)
|
||||
if output.Snapshot.CreatedAt != "" {
|
||||
core.Print(nil, "created: %s", output.Snapshot.CreatedAt)
|
||||
}
|
||||
core.Print(nil, "chars: %d", len(output.Snapshot.Content))
|
||||
return core.Result{Value: output, OK: true}
|
||||
}
|
||||
|
||||
func (s *PrepSubsystem) cmdExtract(options core.Options) core.Result {
|
||||
templateName := options.String("_arg")
|
||||
if templateName == "" {
|
||||
|
|
|
|||
|
|
@ -1376,6 +1376,7 @@ func TestCommands_RegisterCommands_Good_AllRegistered(t *testing.T) {
|
|||
assert.Contains(t, cmds, "brain:forget")
|
||||
assert.Contains(t, cmds, "status")
|
||||
assert.Contains(t, cmds, "prompt")
|
||||
assert.Contains(t, cmds, "prompt/version")
|
||||
assert.Contains(t, cmds, "extract")
|
||||
assert.Contains(t, cmds, "lang/detect")
|
||||
assert.Contains(t, cmds, "lang/list")
|
||||
|
|
|
|||
|
|
@ -261,6 +261,7 @@ func (s *PrepSubsystem) OnStartup(ctx context.Context) core.Result {
|
|||
c.Action("content.schema.generate", s.handleContentSchemaGenerate).Description = "Generate SEO schema JSON-LD for article, FAQ, or how-to content"
|
||||
|
||||
c.Action("agentic.prompt", s.handlePrompt).Description = "Read a system prompt by slug"
|
||||
c.Action("agentic.prompt.version", s.handlePromptVersion).Description = "Read the current prompt snapshot for a workspace"
|
||||
c.Action("agentic.task", s.handleTask).Description = "Read a task plan by slug"
|
||||
c.Action("agentic.flow", s.handleFlow).Description = "Read a build/release flow by slug"
|
||||
c.Action("agentic.persona", s.handlePersona).Description = "Read a persona by path"
|
||||
|
|
@ -809,6 +810,30 @@ func writePromptSnapshot(workspaceDir, prompt string) core.Result {
|
|||
return core.Result{Value: hash, OK: true}
|
||||
}
|
||||
|
||||
// snapshot := readPromptSnapshot("/srv/.core/workspace/core/go-io/task-42")
|
||||
func readPromptSnapshot(workspaceDir string) (PromptVersionSnapshot, error) {
|
||||
if workspaceDir == "" {
|
||||
return PromptVersionSnapshot{}, core.E("readPromptSnapshot", "workspace is required", nil)
|
||||
}
|
||||
|
||||
snapshotPath := core.JoinPath(WorkspaceMetaDir(workspaceDir), "prompt-version.json")
|
||||
result := fs.Read(snapshotPath)
|
||||
if !result.OK {
|
||||
err, _ := result.Value.(error)
|
||||
if err == nil {
|
||||
err = core.E("readPromptSnapshot", "prompt snapshot not found", nil)
|
||||
}
|
||||
return PromptVersionSnapshot{}, err
|
||||
}
|
||||
|
||||
var snapshot PromptVersionSnapshot
|
||||
if parseResult := core.JSONUnmarshalString(result.Value.(string), &snapshot); !parseResult.OK {
|
||||
err, _ := parseResult.Value.(error)
|
||||
return PromptVersionSnapshot{}, core.E("readPromptSnapshot", "failed to parse prompt snapshot", err)
|
||||
}
|
||||
return snapshot, nil
|
||||
}
|
||||
|
||||
// snapshot := PromptVersionSnapshot{Hash: "f2c8...", Content: "TASK: Fix tests"}
|
||||
type PromptVersionSnapshot struct {
|
||||
Hash string `json:"hash"`
|
||||
|
|
|
|||
|
|
@ -688,6 +688,9 @@ func TestPrep_OnStartup_Good_RegistersGenerateCommand(t *testing.T) {
|
|||
assert.Contains(t, c.Commands(), "session/replay")
|
||||
assert.Contains(t, c.Commands(), "review-queue")
|
||||
assert.Contains(t, c.Commands(), "agentic:review-queue")
|
||||
assert.Contains(t, c.Commands(), "prompt/version")
|
||||
assert.Contains(t, c.Commands(), "agentic:prompt/version")
|
||||
assert.True(t, c.Action("agentic.prompt.version").Exists())
|
||||
assert.Contains(t, c.Commands(), "task")
|
||||
assert.Contains(t, c.Commands(), "task/create")
|
||||
assert.Contains(t, c.Commands(), "task/update")
|
||||
|
|
|
|||
49
pkg/agentic/prompt_version.go
Normal file
49
pkg/agentic/prompt_version.go
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
// SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
package agentic
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
core "dappco.re/go/core"
|
||||
"github.com/modelcontextprotocol/go-sdk/mcp"
|
||||
)
|
||||
|
||||
// version := agentic.PromptVersionOutput{Success: true, Snapshot: agentic.PromptVersionSnapshot{Hash: "..." }}
|
||||
type PromptVersionOutput struct {
|
||||
Success bool `json:"success"`
|
||||
Workspace string `json:"workspace"`
|
||||
Snapshot PromptVersionSnapshot `json:"snapshot"`
|
||||
}
|
||||
|
||||
// result := c.Action("agentic.prompt.version").Run(ctx, core.NewOptions(
|
||||
//
|
||||
// core.Option{Key: "workspace", Value: "/srv/.core/workspace/core/go-io/task-42"},
|
||||
//
|
||||
// ))
|
||||
func (s *PrepSubsystem) handlePromptVersion(ctx context.Context, options core.Options) core.Result {
|
||||
workspace := optionStringValue(options, "workspace", "_arg")
|
||||
_, output, err := s.promptVersion(ctx, nil, workspace)
|
||||
if err != nil {
|
||||
return core.Result{Value: err, OK: false}
|
||||
}
|
||||
return core.Result{Value: output, OK: true}
|
||||
}
|
||||
|
||||
func (s *PrepSubsystem) promptVersion(_ context.Context, _ *mcp.CallToolRequest, workspace string) (*mcp.CallToolResult, PromptVersionOutput, error) {
|
||||
workspaceDir := s.resolveWorkspaceDir(workspace)
|
||||
if workspaceDir == "" {
|
||||
return nil, PromptVersionOutput{}, core.E("promptVersion", "workspace is required", nil)
|
||||
}
|
||||
|
||||
snapshot, err := readPromptSnapshot(workspaceDir)
|
||||
if err != nil {
|
||||
return nil, PromptVersionOutput{}, err
|
||||
}
|
||||
|
||||
return nil, PromptVersionOutput{
|
||||
Success: true,
|
||||
Workspace: workspace,
|
||||
Snapshot: snapshot,
|
||||
}, nil
|
||||
}
|
||||
43
pkg/agentic/prompt_version_test.go
Normal file
43
pkg/agentic/prompt_version_test.go
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
// SPDX-License-Identifier: EUPL-1.2
|
||||
|
||||
package agentic
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
core "dappco.re/go/core"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestPromptVersion_ReadPromptSnapshot_Good(t *testing.T) {
|
||||
workspaceDir := t.TempDir()
|
||||
prompt := "TASK: Fix tests\n\nRead CODEX.md and commit when done."
|
||||
|
||||
writeResult := writePromptSnapshot(workspaceDir, prompt)
|
||||
require.True(t, writeResult.OK)
|
||||
|
||||
snapshot, err := readPromptSnapshot(workspaceDir)
|
||||
require.NoError(t, err)
|
||||
|
||||
assert.Equal(t, promptSnapshotHash(prompt), snapshot.Hash)
|
||||
assert.Contains(t, snapshot.CreatedAt, "T")
|
||||
assert.Equal(t, prompt, snapshot.Content)
|
||||
}
|
||||
|
||||
func TestPromptVersion_ReadPromptSnapshot_Bad_MissingWorkspace(t *testing.T) {
|
||||
_, err := readPromptSnapshot("")
|
||||
require.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "workspace is required")
|
||||
}
|
||||
|
||||
func TestPromptVersion_ReadPromptSnapshot_Ugly_InvalidJson(t *testing.T) {
|
||||
workspaceDir := t.TempDir()
|
||||
metaDir := WorkspaceMetaDir(workspaceDir)
|
||||
require.True(t, fs.EnsureDir(metaDir).OK)
|
||||
require.True(t, fs.Write(core.JoinPath(metaDir, "prompt-version.json"), "{not-json").OK)
|
||||
|
||||
_, err := readPromptSnapshot(workspaceDir)
|
||||
require.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "failed to parse prompt snapshot")
|
||||
}
|
||||
Loading…
Add table
Reference in a new issue