Compose appended request messages
This commit is contained in:
@@ -4,10 +4,13 @@ import (
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"crypto/sha256"
|
||||
"encoding/binary"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"hash"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
@@ -444,9 +447,11 @@ func (r *Runner) completePreparationWithStructuredOutput(
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("%w: %w", ErrPromptRender, err)
|
||||
}
|
||||
effectivePrompt := *renderedPrompt
|
||||
if state.directSessionID != "" {
|
||||
renderedPrompt.SessionID = state.directSessionID
|
||||
effectivePrompt.SessionID = state.directSessionID
|
||||
}
|
||||
effectivePrompt.Messages = domain.ConcatRenderedMessages(renderedPrompt.Messages, req.AppendedMessages)
|
||||
|
||||
end := time.Now().UTC()
|
||||
effectiveModel := state.effectiveModel
|
||||
@@ -462,9 +467,9 @@ func (r *Runner) completePreparationWithStructuredOutput(
|
||||
OutputContract: state.effectiveContract,
|
||||
StructuredOutput: structuredOutput,
|
||||
InputHashes: inputHashes,
|
||||
SessionID: renderedPrompt.SessionID,
|
||||
RenderedPromptHash: hashRenderedPrompt(*renderedPrompt),
|
||||
Messages: renderedPrompt.Messages,
|
||||
SessionID: effectivePrompt.SessionID,
|
||||
RenderedPromptHash: hashRenderedPrompt(effectivePrompt),
|
||||
Messages: effectivePrompt.Messages,
|
||||
StartTime: state.start,
|
||||
EndTime: end,
|
||||
DurationMS: end.Sub(state.start).Milliseconds(),
|
||||
@@ -714,29 +719,38 @@ func resolveOutputContract(def *domain.PromptDefinition, override *domain.Output
|
||||
return contract, nil
|
||||
}
|
||||
|
||||
const renderedPromptHashVersion = "promptkit/rendered-prompt/v2\x00"
|
||||
|
||||
func hashRenderedPrompt(p domain.RenderedPrompt) string {
|
||||
var b strings.Builder
|
||||
if p.SessionID != "" {
|
||||
b.WriteString("session_id=")
|
||||
b.WriteString(p.SessionID)
|
||||
b.WriteString("\n---\n")
|
||||
}
|
||||
for _, msg := range p.Messages {
|
||||
b.WriteString(msg.Role)
|
||||
b.WriteByte('\n')
|
||||
b.WriteString(msg.Content)
|
||||
if msg.CacheControl != nil {
|
||||
b.WriteString("\ncache_control.type=")
|
||||
b.WriteString(string(msg.CacheControl.Type))
|
||||
if msg.CacheControl.TTL != "" {
|
||||
b.WriteString("\ncache_control.ttl=")
|
||||
b.WriteString(msg.CacheControl.TTL)
|
||||
}
|
||||
hasher := sha256.New()
|
||||
var lengthBuffer [8]byte
|
||||
_, _ = io.WriteString(hasher, renderedPromptHashVersion)
|
||||
writeRenderedPromptHashString(hasher, &lengthBuffer, p.SessionID)
|
||||
writeRenderedPromptHashLength(hasher, &lengthBuffer, len(p.Messages))
|
||||
for _, message := range p.Messages {
|
||||
writeRenderedPromptHashString(hasher, &lengthBuffer, message.Role)
|
||||
writeRenderedPromptHashString(hasher, &lengthBuffer, message.Content)
|
||||
if message.CacheControl == nil {
|
||||
lengthBuffer[0] = 0
|
||||
_, _ = hasher.Write(lengthBuffer[:1])
|
||||
continue
|
||||
}
|
||||
b.WriteString("\n---\n")
|
||||
lengthBuffer[0] = 1
|
||||
_, _ = hasher.Write(lengthBuffer[:1])
|
||||
writeRenderedPromptHashString(hasher, &lengthBuffer, string(message.CacheControl.Type))
|
||||
writeRenderedPromptHashString(hasher, &lengthBuffer, message.CacheControl.TTL)
|
||||
}
|
||||
h := sha256.Sum256([]byte(b.String()))
|
||||
return hex.EncodeToString(h[:])
|
||||
return hex.EncodeToString(hasher.Sum(nil))
|
||||
}
|
||||
|
||||
func writeRenderedPromptHashLength(hasher hash.Hash, buffer *[8]byte, length int) {
|
||||
binary.BigEndian.PutUint64(buffer[:], uint64(length))
|
||||
_, _ = hasher.Write(buffer[:])
|
||||
}
|
||||
|
||||
func writeRenderedPromptHashString(hasher hash.Hash, buffer *[8]byte, value string) {
|
||||
writeRenderedPromptHashLength(hasher, buffer, len(value))
|
||||
_, _ = io.WriteString(hasher, value)
|
||||
}
|
||||
|
||||
func buildOutputArtifact(content string, format domain.OutputFormat) domain.Artifact {
|
||||
|
||||
Reference in New Issue
Block a user