Implement support for passing a session_id variable to scriptorium to support sticky routing
This commit is contained in:
@@ -347,6 +347,7 @@ func executeAnalyzeArtifact(
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("analyze: resolve vars for artifact %q: %w", artifactName, err)
|
||||
}
|
||||
vars = withScriptoriumStickySessionVar(vars, sessionID)
|
||||
|
||||
canonicalOutputPath, err := resolveScriptoriumOutputPath(paths, artifactCfg.OutputPath)
|
||||
if err != nil {
|
||||
|
||||
@@ -54,6 +54,9 @@ func TestAnalyzeGeneratesSessionRecapFromTrimmedTranscript(t *testing.T) {
|
||||
if req.Timeout != 2*time.Minute {
|
||||
t.Fatalf("timeout = %s, want 2m", req.Timeout)
|
||||
}
|
||||
if req.Vars["session_id"] != "narratio-session-2026-05-03" {
|
||||
t.Fatalf("session_id var = %q, want sticky narratio session id", req.Vars["session_id"])
|
||||
}
|
||||
|
||||
if len(result.Outputs) != 1 || result.Outputs[0].Kind != "session_recap" {
|
||||
t.Fatalf("outputs = %#v, want one session_recap output", result.Outputs)
|
||||
@@ -69,6 +72,34 @@ func TestAnalyzeGeneratesSessionRecapFromTrimmedTranscript(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestAnalyzeStickySessionVarOverridesConfiguredAndPreservesArbitraryVars(t *testing.T) {
|
||||
env, m, fake := setupAnalyzeEnv(t)
|
||||
paths := sessionPathsForEnv(env, m.SessionID)
|
||||
writeAnalyzeFile(t, filepath.Join(paths.TranscriptsDir, "final.trimmed.json"), `{"segments":[]}`)
|
||||
|
||||
artifact := env.Config.Pipeline.Scriptorium.Artifacts["session_recap"]
|
||||
artifact.Vars = map[string]any{
|
||||
"session_id": "configured-session",
|
||||
"character_name": "Hrank",
|
||||
"character_class": "Fighter",
|
||||
}
|
||||
env.Config.Pipeline.Scriptorium.Artifacts["session_recap"] = artifact
|
||||
|
||||
if _, err := (analyzeStage{}).Run(context.Background(), env, m); err != nil {
|
||||
t.Fatalf("Run() error = %v", err)
|
||||
}
|
||||
req := fake.RunRequests[0]
|
||||
if req.Vars["session_id"] != "narratio-session-2026-05-03" {
|
||||
t.Fatalf("session_id var = %q, want sticky value", req.Vars["session_id"])
|
||||
}
|
||||
if req.Vars["character_name"] != "Hrank" {
|
||||
t.Fatalf("character_name var = %q, want Hrank", req.Vars["character_name"])
|
||||
}
|
||||
if req.Vars["character_class"] != "Fighter" {
|
||||
t.Fatalf("character_class var = %q, want Fighter", req.Vars["character_class"])
|
||||
}
|
||||
}
|
||||
|
||||
func TestAnalyzeRenderDebugFalseDoesNotCallRenderArtifact(t *testing.T) {
|
||||
env, m, fake := setupAnalyzeEnv(t)
|
||||
paths := sessionPathsForEnv(env, m.SessionID)
|
||||
@@ -142,6 +173,12 @@ func TestAnalyzeRenderOutputPathIsRecorded(t *testing.T) {
|
||||
if len(fake.RenderRequests) != 1 {
|
||||
t.Fatalf("render requests = %d, want 1", len(fake.RenderRequests))
|
||||
}
|
||||
if fake.RenderRequests[0].Vars["session_id"] != "narratio-session-2026-05-03" {
|
||||
t.Fatalf("render session_id var = %q, want sticky narratio session id", fake.RenderRequests[0].Vars["session_id"])
|
||||
}
|
||||
if fake.RunRequests[0].Vars["session_id"] != "narratio-session-2026-05-03" {
|
||||
t.Fatalf("run session_id var = %q, want sticky narratio session id", fake.RunRequests[0].Vars["session_id"])
|
||||
}
|
||||
if result.Metadata["render_output_path"] != filepath.Join(paths.ArtifactsDir, "session_recap.render.json") {
|
||||
t.Fatalf("render_output_path = %#v, want session_recap.render.json path", result.Metadata["render_output_path"])
|
||||
}
|
||||
|
||||
21
internal/stage/scriptorium_vars.go
Normal file
21
internal/stage/scriptorium_vars.go
Normal file
@@ -0,0 +1,21 @@
|
||||
package stage
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
"gitea.maximumdirect.net/eric/narratio/internal/config"
|
||||
)
|
||||
|
||||
func withScriptoriumStickySessionVar(vars map[string]string, sessionID string) map[string]string {
|
||||
out := make(map[string]string, len(vars)+1)
|
||||
for k, v := range vars {
|
||||
out[k] = v
|
||||
}
|
||||
if trimmedSessionID := strings.TrimSpace(sessionID); trimmedSessionID != "" {
|
||||
out[config.DefaultScriptoriumStickySessionVarName] = config.DefaultScriptoriumStickySessionVarPrefix + trimmedSessionID
|
||||
}
|
||||
if len(out) == 0 {
|
||||
return nil
|
||||
}
|
||||
return out
|
||||
}
|
||||
@@ -150,7 +150,7 @@ func (trimStage) Run(ctx context.Context, env *Env, m *manifest.Manifest) (*Stag
|
||||
inputPaths := map[string]string{
|
||||
boundsCfg.TranscriptInputName: normalizedPath,
|
||||
}
|
||||
vars := map[string]string{}
|
||||
vars := withScriptoriumStickySessionVar(nil, sessionID)
|
||||
|
||||
metadata["bounds_prompt_id"] = boundsCfg.PromptID
|
||||
metadata["bounds_profile_id"] = boundsCfg.ProfileID
|
||||
|
||||
@@ -34,6 +34,9 @@ func TestTrimStageConsumesNormalizedAndProducesTrimmedTranscript(t *testing.T) {
|
||||
if len(scr.RunRequests) != 1 {
|
||||
t.Fatalf("scriptorium run requests = %d, want 1", len(scr.RunRequests))
|
||||
}
|
||||
if scr.RunRequests[0].Vars["session_id"] != "narratio-session-2026-05-03" {
|
||||
t.Fatalf("session_id var = %q, want sticky narratio session id", scr.RunRequests[0].Vars["session_id"])
|
||||
}
|
||||
if len(ser.TrimRequests) != 1 {
|
||||
t.Fatalf("seriatim trim requests = %d, want 1", len(ser.TrimRequests))
|
||||
}
|
||||
@@ -129,6 +132,12 @@ func TestTrimStageRenderDebugDiagnosticsAreNotStageOutputs(t *testing.T) {
|
||||
if len(scr.RenderRequests) != 1 {
|
||||
t.Fatalf("scriptorium render requests = %d, want 1", len(scr.RenderRequests))
|
||||
}
|
||||
if scr.RenderRequests[0].Vars["session_id"] != "narratio-session-2026-05-03" {
|
||||
t.Fatalf("render session_id var = %q, want sticky narratio session id", scr.RenderRequests[0].Vars["session_id"])
|
||||
}
|
||||
if scr.RunRequests[0].Vars["session_id"] != "narratio-session-2026-05-03" {
|
||||
t.Fatalf("run session_id var = %q, want sticky narratio session id", scr.RunRequests[0].Vars["session_id"])
|
||||
}
|
||||
for _, out := range result.Outputs {
|
||||
if out.Kind == "session_bounds_render" {
|
||||
t.Fatalf("render diagnostics should not be stage outputs: %#v", result.Outputs)
|
||||
|
||||
Reference in New Issue
Block a user