package ckprompt_test import ( "context" "io" "testing" "go.maximumdirect.net/ckprompt" commandkit "go.maximumdirect.net/commandkit" promptkit "go.maximumdirect.net/promptkit" ) func TestReusableRequestFlagsOnApplicationCommand(t *testing.T) { type input struct { execution ckprompt.ExecutionInput resources ckprompt.ResourceInput prompt ckprompt.PromptInputs } execution := ckprompt.NewExecutionFlags(func(i *input) *ckprompt.ExecutionInput { return &i.execution }) resources := ckprompt.NewResourceFlags(func(i *input) *ckprompt.ResourceInput { return &i.resources }) inputs := ckprompt.NewPromptInputFlags(func(i *input) *ckprompt.PromptInputs { return &i.prompt }) flags := append(execution.All(), resources.Profile, inputs.Variable) var received input calls := 0 command := commandkit.NewCommand(commandkit.CommandSpec[input]{ Name: "run", Flags: flags, Run: func(_ commandkit.Invocation, i input) commandkit.Outcome { calls++ received = i return commandkit.Success() }, }) app, err := commandkit.New(commandkit.Identity{Name: "app"}, command) if err != nil { t.Fatal(err) } run := func(args ...string) commandkit.Outcome { return app.Execute(context.Background(), append([]string{"run"}, args...), commandkit.Streams{Out: io.Discard, Err: io.Discard}) } if result := run(); result.Kind != commandkit.OutcomeSuccess || received.execution.Execution != nil || received.execution.TransientRetries != nil || received.resources.Profile.Set { t.Fatalf("absent values: %#v %#v", result, received) } if result := run("--llm-profile=", "--llm-temperature=0", "--llm-reasoning-effort=", "--llm-transient-retries=0", "--llm-extra-params={\"n\":1,\"d\":1.5}", "--llm-var=x="); result.Kind != commandkit.OutcomeSuccess { t.Fatal(result) } e := received.execution if !received.resources.Profile.Set || received.resources.Profile.Value != "" || e.Execution == nil || e.Execution.Temperature == nil || *e.Execution.Temperature != 0 || e.Execution.ReasoningEffort == nil || *e.Execution.ReasoningEffort != "" || e.TransientRetries == nil || *e.TransientRetries != 0 || e.Execution.ExtraParams["n"] != int64(1) || e.Execution.ExtraParams["d"] != float64(1.5) || received.prompt.Vars["x"] != "" { t.Fatalf("explicit values: %#v", received) } if result := run("--llm-extra-params={}"); result.Kind != commandkit.OutcomeSuccess || received.execution.Execution == nil || received.execution.Execution.ExtraParams == nil || len(received.execution.Execution.ExtraParams) != 0 { t.Fatalf("empty object: %#v %#v", result, received) } for _, raw := range []string{"null", "[]", "1", "{invalid}"} { before := calls if result := run("--llm-extra-params=" + raw); result.Kind != commandkit.OutcomeUsage || calls != before { t.Fatalf("invalid object %q: %#v", raw, result) } } if result := run("--llm-backend=unused"); result.Kind != commandkit.OutcomeUsage { t.Fatalf("unselected flag: %#v", result) } } func TestValidationForwardsExecutionControls(t *testing.T) { var received promptkit.RunRequest suite := ckprompt.Suite[struct{}, struct{}]{ValidateRequest: func(_ context.Context, req ckprompt.ValidationRequest, _, _ struct{}) (commandkit.Acquired[struct{}], error) { received = req.Request return commandkit.Acquired[struct{}]{}, nil }} app, err := commandkit.New(commandkit.Identity{Name: "app"}, ckprompt.Command(suite)) if err != nil { t.Fatal(err) } result := app.Execute(context.Background(), []string{"promptkit", "requirements", "validate", "briefing", "--llm-profile=", "--llm-max-tokens=0", "--llm-extra-params={}", "--llm-transient-retries=0"}, commandkit.Streams{Out: io.Discard, Err: io.Discard}) if result.Kind != commandkit.OutcomeSuccess || received.Execution == nil || received.Execution.MaxTokens == nil || *received.Execution.MaxTokens != 0 || received.Execution.ExtraParams == nil || received.TransientRetries == nil || *received.TransientRetries != 0 { t.Fatalf("result/request = %#v %#v", result, received) } }