Support internal reasoning effort overrides

This commit is contained in:
2026-07-30 02:03:04 +00:00
parent 7a00e7049c
commit f603f7ac64
10 changed files with 149 additions and 45 deletions

View File

@@ -19,20 +19,22 @@ import (
const promptKitProviderName = "promptkit"
type PromptKitClientConfig struct {
ProfileDir string
ProfileFile string
Assets *AssetRegistry
Timeout time.Duration
HTTPClient *http.Client
EngineOptions []promptkit.Option
Recorder *LLMProfileRecorder
ProfileDir string
ProfileFile string
Assets *AssetRegistry
Timeout time.Duration
HTTPClient *http.Client
EngineOptions []promptkit.Option
Recorder *LLMProfileRecorder
ReasoningEffort *string
}
type PromptKitClient struct {
engine *promptkit.Engine
recorder *LLMProfileRecorder
profileDir string
profileFile string
engine *promptkit.Engine
recorder *LLMProfileRecorder
profileDir string
profileFile string
reasoningEffort *string
}
type LLMProfileRecorder struct {
@@ -71,11 +73,17 @@ func NewPromptKitClient(cfg PromptKitClientConfig) (*PromptKitClient, error) {
if recorder == nil {
recorder = NewLLMProfileRecorder()
}
var reasoningEffort *string
if cfg.ReasoningEffort != nil {
value := *cfg.ReasoningEffort
reasoningEffort = &value
}
return &PromptKitClient{
engine: engine,
recorder: recorder,
profileDir: strings.TrimSpace(cfg.ProfileDir),
profileFile: strings.TrimSpace(cfg.ProfileFile),
engine: engine,
recorder: recorder,
profileDir: strings.TrimSpace(cfg.ProfileDir),
profileFile: strings.TrimSpace(cfg.ProfileFile),
reasoningEffort: reasoningEffort,
}, nil
}
@@ -94,6 +102,13 @@ func (c *PromptKitClient) CompleteStructured(ctx context.Context, req contracts.
return contracts.StructuredCompletionResponse{}, fmt.Errorf("structured completion prompt_id must not be empty")
}
sessionID := strings.TrimSpace(req.SessionID)
var execution *promptkit.ExecutionTargetOverride
if c.reasoningEffort != nil {
reasoningEffort := *c.reasoningEffort
execution = &promptkit.ExecutionTargetOverride{
ReasoningEffort: &reasoningEffort,
}
}
runReq := promptkit.RunRequest{
PromptID: promptID,
@@ -102,6 +117,7 @@ func (c *PromptKitClient) CompleteStructured(ctx context.Context, req contracts.
SessionID: sessionID,
Inputs: promptKitInputs(req.Inputs),
Vars: promptKitVars(req, sessionID),
Execution: execution,
}
prepared, err := c.engine.Prepare(ctx, runReq)
if err != nil {

View File

@@ -150,6 +150,64 @@ func TestPromptKitClientDoesNotInventDirectSession(t *testing.T) {
}
}
func TestPromptKitClientAppliesReasoningEffortOverride(t *testing.T) {
tests := []struct {
name string
override func() *string
mutateAfterCreate bool
want string
}{
{
name: "inherit",
want: "profile-reasoning",
},
{
name: "replace",
override: func() *string { value := "focused"; return &value },
want: "focused",
},
{
name: "clear",
override: func() *string { value := ""; return &value },
want: "",
},
{
name: "defensive copy",
override: func() *string { value := "original"; return &value },
mutateAfterCreate: true,
want: "original",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
fake := &fakePromptKitLLM{content: `{"ok":true}`}
var override *string
if tt.override != nil {
override = tt.override()
}
client := newTestPromptKitClientWithReasoning(t, fake, override)
if tt.mutateAfterCreate {
*override = "mutated"
}
var out map[string]any
_, 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().Target.ReasoningEffort; got != tt.want {
t.Fatalf("reasoning effort = %q, want %q", got, tt.want)
}
})
}
}
func TestNewPromptKitClientReportsAssetAndEngineConstructionFailures(t *testing.T) {
t.Run("assets", func(t *testing.T) {
registry := NewAssetRegistry()
@@ -464,21 +522,28 @@ func TestPromptKitClientValidatesRequest(t *testing.T) {
}
func newTestPromptKitClient(t *testing.T, fake *fakePromptKitLLM) *PromptKitClient {
return newTestPromptKitClientWithReasoning(t, fake, nil)
}
func newTestPromptKitClientWithReasoning(t *testing.T, fake *fakePromptKitLLM, reasoningEffort *string) *PromptKitClient {
t.Helper()
registry := newTestPromptKitAssets(t)
client, err := NewPromptKitClient(PromptKitClientConfig{
Assets: registry,
Assets: registry,
ReasoningEffort: reasoningEffort,
EngineOptions: []promptkit.Option{
promptkit.WithProfiles(
promptkit.OpenAICompatibleProfile(promptkit.OpenAICompatibleProfileConfig{
ID: "default-profile",
Endpoint: "http://127.0.0.1:1/v1",
Model: "default-model",
ID: "default-profile",
Endpoint: "http://127.0.0.1:1/v1",
Model: "default-model",
ReasoningEffort: "profile-reasoning",
}),
promptkit.OpenAICompatibleProfile(promptkit.OpenAICompatibleProfileConfig{
ID: "explicit-profile",
Endpoint: "http://127.0.0.1:1/v1",
Model: "explicit-model",
ID: "explicit-profile",
Endpoint: "http://127.0.0.1:1/v1",
Model: "explicit-model",
ReasoningEffort: "profile-reasoning",
}),
),
promptkit.WithLLMClient(fake),