Forward sessions through PromptKit requests
This commit is contained in:
@@ -93,13 +93,15 @@ func (c *PromptKitClient) CompleteStructured(ctx context.Context, req contracts.
|
||||
if promptID == "" {
|
||||
return contracts.StructuredCompletionResponse{}, fmt.Errorf("structured completion prompt_id must not be empty")
|
||||
}
|
||||
sessionID := strings.TrimSpace(req.SessionID)
|
||||
|
||||
runReq := promptkit.RunRequest{
|
||||
PromptID: promptID,
|
||||
PromptVersion: strings.TrimSpace(req.PromptVersion),
|
||||
ProfileID: strings.TrimSpace(req.ProfileID),
|
||||
SessionID: sessionID,
|
||||
Inputs: promptKitInputs(req.Inputs),
|
||||
Vars: promptKitVars(req),
|
||||
Vars: promptKitVars(req, sessionID),
|
||||
}
|
||||
prepared, err := c.engine.Prepare(ctx, runReq)
|
||||
if err != nil {
|
||||
@@ -342,7 +344,7 @@ func promptKitInputs(inputs contracts.LLMInputSet) map[string]promptkit.Artifact
|
||||
return out
|
||||
}
|
||||
|
||||
func promptKitVars(req contracts.StructuredCompletionRequest) map[string]string {
|
||||
func promptKitVars(req contracts.StructuredCompletionRequest, sessionID string) map[string]string {
|
||||
vars := make(map[string]string, len(req.Vars)+1)
|
||||
for key, value := range req.Vars {
|
||||
name := strings.TrimSpace(key)
|
||||
@@ -351,7 +353,7 @@ func promptKitVars(req contracts.StructuredCompletionRequest) map[string]string
|
||||
}
|
||||
vars[name] = fmt.Sprint(value)
|
||||
}
|
||||
if sessionID := strings.TrimSpace(req.SessionID); sessionID != "" {
|
||||
if sessionID != "" {
|
||||
vars["session_id"] = sessionID
|
||||
}
|
||||
if len(vars) == 0 {
|
||||
|
||||
@@ -28,10 +28,10 @@ func TestPromptKitClientMapsPromptRequestAndUnmarshalsOutput(t *testing.T) {
|
||||
}
|
||||
resp, err := client.CompleteStructured(context.Background(), contracts.StructuredCompletionRequest{
|
||||
StageName: "test-stage",
|
||||
PromptID: "adapter.test",
|
||||
PromptID: "adapter.direct-session",
|
||||
PromptVersion: "v1",
|
||||
ProfileID: "explicit-profile",
|
||||
SessionID: "session-123",
|
||||
SessionID: " session-123 ",
|
||||
Inputs: contracts.LLMInputSet{
|
||||
"transcript": contracts.NewLLMInputMaterial("transcript", "application/json", []byte(`{"source":true}`), "sha256:source", "file:///source.json"),
|
||||
},
|
||||
@@ -52,8 +52,10 @@ func TestPromptKitClientMapsPromptRequestAndUnmarshalsOutput(t *testing.T) {
|
||||
if resp.Debug == nil || resp.Debug.Prompt == nil {
|
||||
t.Fatalf("debug prompt = nil, want prepared prompt material")
|
||||
}
|
||||
if resp.Debug.Prompt.PromptID != "adapter.test" || resp.Debug.Prompt.SelectedProfileID != "explicit-profile" {
|
||||
t.Fatalf("debug prompt metadata = %#v, want prompt/profile", resp.Debug.Prompt)
|
||||
if resp.Debug.Prompt.PromptID != "adapter.direct-session" ||
|
||||
resp.Debug.Prompt.SelectedProfileID != "explicit-profile" ||
|
||||
resp.Debug.Prompt.SessionID != "session-123" {
|
||||
t.Fatalf("debug prompt metadata = %#v, want prompt/profile/session", resp.Debug.Prompt)
|
||||
}
|
||||
if len(resp.Debug.Prompt.Messages) != 1 || !strings.Contains(resp.Debug.Prompt.Messages[0].Content, `{"source":true}`) {
|
||||
t.Fatalf("debug prompt messages = %#v, want rendered input content", resp.Debug.Prompt.Messages)
|
||||
@@ -95,6 +97,59 @@ func TestPromptKitClientMapsPromptRequestAndUnmarshalsOutput(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestPromptKitClientRetainsSessionPromptVariable(t *testing.T) {
|
||||
fake := &fakePromptKitLLM{content: `{"ok":true}`}
|
||||
client := newTestPromptKitClient(t, fake)
|
||||
|
||||
var out map[string]any
|
||||
_, err := client.CompleteStructured(context.Background(), contracts.StructuredCompletionRequest{
|
||||
PromptID: "adapter.test",
|
||||
SessionID: " canonical-session ",
|
||||
Inputs: contracts.LLMInputSet{
|
||||
"transcript": contracts.NewLLMInputMaterial("transcript", "application/json", []byte(`{"source":true}`), "", ""),
|
||||
},
|
||||
Vars: map[string]any{
|
||||
"custom": "value",
|
||||
"session_id": "caller-session",
|
||||
},
|
||||
}, &out)
|
||||
if err != nil {
|
||||
t.Fatalf("CompleteStructured() error = %v, want nil", err)
|
||||
}
|
||||
gotReq := fake.lastRequest()
|
||||
if gotReq.Prompt.SessionID != "canonical-session" {
|
||||
t.Fatalf("session id = %q, want canonical-session", gotReq.Prompt.SessionID)
|
||||
}
|
||||
if len(gotReq.Prompt.Messages) != 1 ||
|
||||
!strings.Contains(gotReq.Prompt.Messages[0].Content, "Session: canonical-session") ||
|
||||
strings.Contains(gotReq.Prompt.Messages[0].Content, "caller-session") {
|
||||
t.Fatalf("rendered messages = %#v, want canonical session compatibility variable", gotReq.Prompt.Messages)
|
||||
}
|
||||
}
|
||||
|
||||
func TestPromptKitClientDoesNotInventDirectSession(t *testing.T) {
|
||||
fake := &fakePromptKitLLM{content: `{"ok":true}`}
|
||||
client := newTestPromptKitClient(t, fake)
|
||||
|
||||
var out map[string]any
|
||||
resp, err := client.CompleteStructured(context.Background(), contracts.StructuredCompletionRequest{
|
||||
PromptID: "adapter.direct-session",
|
||||
Inputs: contracts.LLMInputSet{
|
||||
"transcript": contracts.NewLLMInputMaterial("transcript", "application/json", []byte(`{"source":true}`), "", ""),
|
||||
},
|
||||
Vars: map[string]any{"custom": "value"},
|
||||
}, &out)
|
||||
if err != nil {
|
||||
t.Fatalf("CompleteStructured() error = %v, want nil", err)
|
||||
}
|
||||
if got := fake.lastRequest().Prompt.SessionID; got != "" {
|
||||
t.Fatalf("session id = %q, want empty", got)
|
||||
}
|
||||
if resp.Debug == nil || resp.Debug.Prompt == nil || resp.Debug.Prompt.SessionID != "" {
|
||||
t.Fatalf("debug prompt = %#v, want no effective session", resp.Debug)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNewPromptKitClientReportsAssetAndEngineConstructionFailures(t *testing.T) {
|
||||
t.Run("assets", func(t *testing.T) {
|
||||
registry := NewAssetRegistry()
|
||||
@@ -443,6 +498,22 @@ func newTestPromptKitAssets(t *testing.T) *AssetRegistry {
|
||||
version: "v1"
|
||||
default_profile: default-profile
|
||||
session_id: "{{ .session_id }}"
|
||||
inputs:
|
||||
- name: transcript
|
||||
required: true
|
||||
content_type: application/json
|
||||
messages:
|
||||
- role: user
|
||||
content: "Transcript: {{ input \"transcript\" }} Custom: {{ index . \"custom\" }} Session: {{ .session_id }}"
|
||||
output:
|
||||
format: json
|
||||
validation_mode: json_schema
|
||||
schema_path: adapter.schema.json
|
||||
repair_attempts: 0
|
||||
`)},
|
||||
"adapter.direct-session.yaml": {Data: []byte(`id: adapter.direct-session
|
||||
version: "v1"
|
||||
default_profile: default-profile
|
||||
inputs:
|
||||
- name: transcript
|
||||
required: true
|
||||
|
||||
Reference in New Issue
Block a user