Migrate repo fixtures to separated prompts/ and execution profiles/ with file-backed prompt templates
This commit is contained in:
15
README.md
15
README.md
@@ -51,13 +51,14 @@ go test ./...
|
||||
|
||||
Required flags:
|
||||
|
||||
- `--prompt-dir`
|
||||
- `--profile-dir`
|
||||
- `--prompt-id`
|
||||
- `--prompt`
|
||||
- `--input` (repeatable `name=path`)
|
||||
|
||||
Common optional flags:
|
||||
|
||||
- `--profile-id` (execution profile selector; falls back to prompt `default_profile`)
|
||||
- `--profile` (execution profile selector; falls back to prompt `default_profile`)
|
||||
- `--var` (repeatable `name=value`)
|
||||
- `--out`
|
||||
- `--llm-base-url`
|
||||
@@ -76,9 +77,10 @@ Example:
|
||||
export SCRIPTORIUM_API_KEY="your-key"
|
||||
|
||||
go run ./cmd/scriptorium run \
|
||||
--prompt-dir ./prompts \
|
||||
--profile-dir ./profiles \
|
||||
--prompt-id generic.markdown_summary \
|
||||
--profile-id local-default \
|
||||
--prompt generic.markdown_summary \
|
||||
--profile local-fast \
|
||||
--input transcript=./examples/fixtures/transcript.md \
|
||||
--input glossary=./examples/fixtures/glossary.yml \
|
||||
--llm-base-url http://localhost:8000/v1 \
|
||||
@@ -99,8 +101,8 @@ Starts HTTP API.
|
||||
|
||||
Required flags:
|
||||
|
||||
- `--prompt-dir`
|
||||
- `--profile-dir`
|
||||
- `--llm-base-url`
|
||||
|
||||
Common optional flags:
|
||||
|
||||
@@ -267,7 +269,8 @@ Validation content failures are returned in the structured result; raw model out
|
||||
|
||||
## Examples
|
||||
|
||||
- Prompt definitions: `profiles/`
|
||||
- Prompt definitions: `prompts/`
|
||||
- Execution profiles: `profiles/`
|
||||
- Schemas: `schemas/`
|
||||
- Fixtures: `examples/fixtures/`
|
||||
- Local experimentation: `local-test/`
|
||||
|
||||
@@ -209,7 +209,7 @@ func TestRunCommandVarsOptional(t *testing.T) {
|
||||
var stderr bytes.Buffer
|
||||
|
||||
code := runCommand([]string{
|
||||
"--prompt-dir", "./profiles",
|
||||
"--prompt-dir", "./prompts",
|
||||
"--profile-dir", "./profiles",
|
||||
"--prompt", "p",
|
||||
"--input", "transcript=./t.md",
|
||||
|
||||
@@ -2,7 +2,6 @@ package usecase
|
||||
|
||||
import (
|
||||
"context"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
@@ -27,24 +26,21 @@ func (f *integrationLLM) Generate(ctx context.Context, req domain.GenerateReques
|
||||
}, nil
|
||||
}
|
||||
|
||||
func TestRunnerIntegrationWithProfilesFixturesAndValidation(t *testing.T) {
|
||||
func TestRunnerIntegrationWithPromptAndProfileFixturesAndValidation(t *testing.T) {
|
||||
root, err := filepath.Abs(filepath.Join("..", ".."))
|
||||
if err != nil {
|
||||
t.Fatalf("failed to resolve repo root: %v", err)
|
||||
}
|
||||
|
||||
promptsDir := filepath.Join(root, "prompts")
|
||||
profilesDir := filepath.Join(root, "profiles")
|
||||
execProfilesDir := t.TempDir()
|
||||
schemasDir := filepath.Join(root, "schemas")
|
||||
fixturesDir := filepath.Join(root, "examples", "fixtures")
|
||||
if err := os.WriteFile(filepath.Join(execProfilesDir, "local-default.yaml"), []byte(
|
||||
"id: local-default\nendpoint: http://llm/v1\nmodel: test-model\n"), 0644); err != nil {
|
||||
t.Fatalf("failed to write execution profile fixture: %v", err)
|
||||
}
|
||||
t.Setenv("SCRIPTORIUM_API_KEY", "test-key")
|
||||
|
||||
runner := NewRunner(
|
||||
promptdef.NewFilesystemRepository(profilesDir),
|
||||
profile.NewFilesystemRepository(execProfilesDir),
|
||||
promptdef.NewFilesystemRepository(promptsDir),
|
||||
profile.NewFilesystemRepository(profilesDir),
|
||||
artifact.NewCompositeReader(),
|
||||
prompt.NewGoRenderer(),
|
||||
&integrationLLM{},
|
||||
@@ -52,8 +48,7 @@ func TestRunnerIntegrationWithProfilesFixturesAndValidation(t *testing.T) {
|
||||
)
|
||||
|
||||
res, err := runner.Run(context.Background(), domain.RunRequest{
|
||||
PromptID: "generic.structured_events",
|
||||
ProfileID: "local-default",
|
||||
PromptID: "generic.structured_events",
|
||||
Inputs: map[string]domain.ArtifactRef{
|
||||
"transcript": {
|
||||
Type: domain.ArtifactRefFile,
|
||||
@@ -72,6 +67,9 @@ func TestRunnerIntegrationWithProfilesFixturesAndValidation(t *testing.T) {
|
||||
if res.PromptID != "generic.structured_events" {
|
||||
t.Fatalf("unexpected prompt id: %q", res.PromptID)
|
||||
}
|
||||
if res.SelectedProfileID != "local-quality" {
|
||||
t.Fatalf("expected selected profile local-quality from prompt default, got %q", res.SelectedProfileID)
|
||||
}
|
||||
if res.RunID == "" {
|
||||
t.Fatal("expected run id")
|
||||
}
|
||||
|
||||
7
profiles/local-fast.yaml
Normal file
7
profiles/local-fast.yaml
Normal file
@@ -0,0 +1,7 @@
|
||||
id: local-fast
|
||||
endpoint: http://localhost:8000/v1
|
||||
model: gpt-4o-mini
|
||||
temperature: 0.2
|
||||
max_tokens: 500
|
||||
top_p: 1.0
|
||||
timeout_seconds: 90
|
||||
8
profiles/local-quality.yaml
Normal file
8
profiles/local-quality.yaml
Normal file
@@ -0,0 +1,8 @@
|
||||
id: local-quality
|
||||
endpoint: http://localhost:8000/v1
|
||||
model: gpt-4.1
|
||||
temperature: 0.0
|
||||
max_tokens: 1200
|
||||
top_p: 1.0
|
||||
timeout_seconds: 180
|
||||
api_key_env: SCRIPTORIUM_API_KEY
|
||||
2
prompts/dnd.session_recap.system.md
Normal file
2
prompts/dnd.session_recap.system.md
Normal file
@@ -0,0 +1,2 @@
|
||||
You create concise tabletop RPG session recaps.
|
||||
Stay factual and avoid inventing events.
|
||||
10
prompts/dnd.session_recap.user.md
Normal file
10
prompts/dnd.session_recap.user.md
Normal file
@@ -0,0 +1,10 @@
|
||||
Produce a recap with these sections:
|
||||
- Session Highlights
|
||||
- Open Threads
|
||||
- NPC Mentions
|
||||
|
||||
Transcript:
|
||||
{{input "transcript"}}
|
||||
|
||||
Glossary:
|
||||
{{input "glossary"}}
|
||||
@@ -1,31 +1,21 @@
|
||||
id: dnd.session_recap
|
||||
version: "1.0.0"
|
||||
default_profile: local-default
|
||||
default_profile: local-quality
|
||||
description: Example D&D session recap prompt definition for demonstration only.
|
||||
inputs:
|
||||
- name: transcript
|
||||
required: true
|
||||
content_type: text/markdown
|
||||
description: Session source content
|
||||
- name: glossary
|
||||
required: false
|
||||
content_type: text/yaml
|
||||
description: Optional glossary context
|
||||
messages:
|
||||
- role: system
|
||||
content: |
|
||||
You create concise tabletop RPG session recaps.
|
||||
Stay factual and avoid inventing events.
|
||||
content_file: ./dnd.session_recap.system.md
|
||||
- role: user
|
||||
content: |
|
||||
Produce a recap with these sections:
|
||||
- Session Highlights
|
||||
- Open Threads
|
||||
- NPC Mentions
|
||||
|
||||
Transcript:
|
||||
{{input "transcript"}}
|
||||
|
||||
Glossary:
|
||||
{{input "glossary"}}
|
||||
content_file: ./dnd.session_recap.user.md
|
||||
output:
|
||||
format: markdown
|
||||
validation_mode: basic
|
||||
2
prompts/generic.markdown_summary.system.md
Normal file
2
prompts/generic.markdown_summary.system.md
Normal file
@@ -0,0 +1,2 @@
|
||||
You are a concise analysis assistant.
|
||||
Write clear Markdown output.
|
||||
7
prompts/generic.markdown_summary.user.md
Normal file
7
prompts/generic.markdown_summary.user.md
Normal file
@@ -0,0 +1,7 @@
|
||||
Summarize the following source transcript:
|
||||
|
||||
{{input "transcript"}}
|
||||
|
||||
Reference glossary:
|
||||
|
||||
{{input "glossary"}}
|
||||
@@ -1,6 +1,6 @@
|
||||
id: generic.markdown_summary
|
||||
version: "1.0.0"
|
||||
default_profile: local-default
|
||||
default_profile: local-fast
|
||||
description: Generic markdown summary from transcript and glossary.
|
||||
inputs:
|
||||
- name: transcript
|
||||
@@ -13,18 +13,9 @@ inputs:
|
||||
description: Optional glossary context
|
||||
messages:
|
||||
- role: system
|
||||
content: |
|
||||
You are a concise analysis assistant.
|
||||
Write clear Markdown output.
|
||||
content_file: ./generic.markdown_summary.system.md
|
||||
- role: user
|
||||
content: |
|
||||
Summarize the following source transcript:
|
||||
|
||||
{{input "transcript"}}
|
||||
|
||||
Reference glossary:
|
||||
|
||||
{{input "glossary"}}
|
||||
content_file: ./generic.markdown_summary.user.md
|
||||
output:
|
||||
format: markdown
|
||||
validation_mode: basic
|
||||
2
prompts/generic.structured_events.system.md
Normal file
2
prompts/generic.structured_events.system.md
Normal file
@@ -0,0 +1,2 @@
|
||||
Return only JSON following the requested schema.
|
||||
Do not include commentary.
|
||||
7
prompts/generic.structured_events.user.md
Normal file
7
prompts/generic.structured_events.user.md
Normal file
@@ -0,0 +1,7 @@
|
||||
Extract important events from the transcript and emit JSON.
|
||||
|
||||
Transcript:
|
||||
{{input "transcript"}}
|
||||
|
||||
Glossary:
|
||||
{{input "glossary"}}
|
||||
@@ -1,28 +1,21 @@
|
||||
id: generic.structured_events
|
||||
version: "1.0.0"
|
||||
default_profile: local-default
|
||||
default_profile: local-quality
|
||||
description: Produce structured event JSON from a transcript.
|
||||
inputs:
|
||||
- name: transcript
|
||||
required: true
|
||||
content_type: text/markdown
|
||||
description: Source transcript content
|
||||
- name: glossary
|
||||
required: false
|
||||
content_type: text/yaml
|
||||
description: Optional glossary context
|
||||
messages:
|
||||
- role: system
|
||||
content: |
|
||||
Return only JSON following the requested schema.
|
||||
Do not include commentary.
|
||||
content_file: ./generic.structured_events.system.md
|
||||
- role: user
|
||||
content: |
|
||||
Extract important events from the transcript and emit JSON.
|
||||
|
||||
Transcript:
|
||||
{{input "transcript"}}
|
||||
|
||||
Glossary:
|
||||
{{input "glossary"}}
|
||||
content_file: ./generic.structured_events.user.md
|
||||
output:
|
||||
format: json
|
||||
validation_mode: json_schema
|
||||
Reference in New Issue
Block a user