Render only captured prompt templates

This commit is contained in:
2026-11-05 19:57:55 +00:00
parent 97e5739bfb
commit acaf2ccd8b
3 changed files with 22 additions and 45 deletions

View File

@@ -42,6 +42,8 @@ Ordinary preparation selects the full prompt definition and construction-time
hash. It retains its early request-ID check before direct-session hash. It retains its early request-ID check before direct-session
normalization. Referenced message content and static template syntax were normalization. Referenced message content and static template syntax were
captured when the engine was built. captured when the engine was built.
Rendering uses those captured parses, cloning them per call to bind request
input helpers; it does not parse templates during execution.
`InspectPrompt` selects captured metadata directly from the repository. It `InspectPrompt` selects captured metadata directly from the repository. It
returns owned metadata without returns owned metadata without

View File

@@ -165,6 +165,10 @@ inspection tests. Renderer-related failures may be deferred through Stage 6.
## Stage 5: Keep Only Captured Rendering ## Stage 5: Keep Only Captured Rendering
**Completed:** Rendering now requires captured templates and no longer parses
messages or sessions per call. Go 1.27.3 `go build ./...` passed; renderer and
use-case test migrations and their checks are deferred to the next stage.
**Finding:** 3. **Files:** `internal/prompt/go_renderer.go`, template helpers, engine assembly. **Finding:** 3. **Files:** `internal/prompt/go_renderer.go`, template helpers, engine assembly.
1. Remove `NewGoRenderer` and the nil-template lookup mode. Keep 1. Remove `NewGoRenderer` and the nil-template lookup mode. Keep

View File

@@ -24,10 +24,6 @@ type goRenderer struct {
templates TemplateLookup templates TemplateLookup
} }
func NewGoRenderer() Renderer {
return &goRenderer{}
}
// NewCompiledRenderer renders definitions using templates captured with the // NewCompiledRenderer renders definitions using templates captured with the
// configuration snapshot. Per-call clones bind request-specific input helpers. // configuration snapshot. Per-call clones bind request-specific input helpers.
func NewCompiledRenderer(templates TemplateLookup) Renderer { func NewCompiledRenderer(templates TemplateLookup) Renderer {
@@ -56,13 +52,12 @@ func (r *goRenderer) Render(ctx context.Context, definition *domain.PromptDefini
funcs := template.FuncMap{ funcs := template.FuncMap{
"input": resolver.resolve, "input": resolver.resolve,
} }
var compiled CompiledTemplates if r.templates == nil {
if r.templates != nil { return nil, fmt.Errorf("%w: captured templates are unavailable", ErrRenderFailure)
var found bool }
compiled, found = r.templates.GetCompiledTemplates(definition.ID) compiled, found := r.templates.GetCompiledTemplates(definition.ID)
if !found || len(compiled.Messages) != len(definition.Templates) { if !found || len(compiled.Messages) != len(definition.Templates) {
return nil, fmt.Errorf("%w: captured templates are unavailable", ErrRenderFailure) return nil, fmt.Errorf("%w: captured templates are unavailable", ErrRenderFailure)
}
} }
if err := ctx.Err(); err != nil { if err := ctx.Err(); err != nil {
@@ -70,15 +65,11 @@ func (r *goRenderer) Render(ctx context.Context, definition *domain.PromptDefini
} }
var sessionID string var sessionID string
var err error var err error
if r.templates != nil { if definition.SessionID != "" {
if definition.SessionID != "" { if compiled.Session == nil {
if compiled.Session == nil { return nil, fmt.Errorf("%w: captured session template is unavailable", ErrRenderFailure)
return nil, fmt.Errorf("%w: captured session template is unavailable", ErrRenderFailure)
}
sessionID, err = renderCompiledSessionID(ctx, compiled.Session, funcs, vars)
} }
} else { sessionID, err = renderCompiledSessionID(ctx, compiled.Session, funcs, vars)
sessionID, err = renderSessionID(ctx, definition.SessionID, funcs, vars)
} }
if err != nil { if err != nil {
return nil, err return nil, err
@@ -102,18 +93,12 @@ func (r *goRenderer) Render(ctx context.Context, definition *domain.PromptDefini
if err := ctx.Err(); err != nil { if err := ctx.Err(); err != nil {
return nil, err return nil, err
} }
var tmpl *template.Template if compiled.Messages[i] == nil {
var parseErr error return nil, fmt.Errorf("%w: captured message template is unavailable", ErrRenderFailure)
if r.templates != nil { }
if compiled.Messages[i] == nil { tmpl, parseErr := compiled.Messages[i].Clone()
return nil, fmt.Errorf("%w: captured message template is unavailable", ErrRenderFailure) if parseErr == nil {
} tmpl.Funcs(funcs)
tmpl, parseErr = compiled.Messages[i].Clone()
if parseErr == nil {
tmpl.Funcs(funcs)
}
} else {
tmpl, parseErr = parseTemplate(fmt.Sprintf("msg_%d", i), tmplMsg.Content, funcs)
} }
if err := ctx.Err(); err != nil { if err := ctx.Err(); err != nil {
return nil, err return nil, err
@@ -201,20 +186,6 @@ func (r *artifactTextResolver) resolve(name string) (string, error) {
return text, nil return text, nil
} }
func renderSessionID(ctx context.Context, raw string, funcs template.FuncMap, vars map[string]string) (string, error) {
if err := ctx.Err(); err != nil {
return "", err
}
tmpl, parseErr := parseTemplate("session_id", raw, funcs)
if err := ctx.Err(); err != nil {
return "", err
}
if parseErr != nil {
return "", fmt.Errorf("%w: session_id: %v", ErrInvalidTemplate, parseErr)
}
return executeSessionTemplate(ctx, tmpl, vars)
}
func renderCompiledSessionID(ctx context.Context, compiled *template.Template, funcs template.FuncMap, vars map[string]string) (string, error) { func renderCompiledSessionID(ctx context.Context, compiled *template.Template, funcs template.FuncMap, vars map[string]string) (string, error) {
if err := ctx.Err(); err != nil { if err := ctx.Err(); err != nil {
return "", err return "", err