Add temperature option
- commit
- 85a3c3b73ec7be46abfcadc1b696d349eb9f1e58
- author
- patriceckhart · · 2026-06-14 09:42 UTC
- parent
- 798174c
- signature
- unsigned
- refs
- tag: v0.2.31
8 files · +87 -25
M packages/agent/args.go +14 -0
| @@ -3,6 +3,7 @@ package agent | |||
| 3 | 3 | import ( | |
| 4 | 4 | "fmt" | |
| 5 | 5 | "os" | |
| 6 | + | "strconv" | |
| 6 | 7 | "strings" | |
| 7 | 8 | ||
| 8 | 9 | "github.com/patriceckhart/zot/packages/tui" | |
| @@ -37,6 +38,7 @@ type Args struct { | |||
| 37 | 38 | SystemPrompt string | |
| 38 | 39 | AppendSystemPrompt []string | |
| 39 | 40 | Reasoning string | |
| 41 | + | Temperature *float32 | |
| 40 | 42 | ||
| 41 | 43 | Continue bool | |
| 42 | 44 | Resume bool | |
| @@ -201,6 +203,17 @@ func ParseArgs(in []string) (Args, error) { | |||
| 201 | 203 | default: | |
| 202 | 204 | return a, fmt.Errorf("--reasoning must be off|minimum|low|medium|high|maximum") | |
| 203 | 205 | } | |
| 206 | + | case "--temperature": | |
| 207 | + | v, err := want(&i, arg) | |
| 208 | + | if err != nil { | |
| 209 | + | return a, err | |
| 210 | + | } | |
| 211 | + | f, err := strconv.ParseFloat(v, 32) | |
| 212 | + | if err != nil || f < 0 || f > 2 { | |
| 213 | + | return a, fmt.Errorf("--temperature must be a number between 0 and 2") | |
| 214 | + | } | |
| 215 | + | t := float32(f) | |
| 216 | + | a.Temperature = &t | |
| 204 | 217 | case "--session": | |
| 205 | 218 | v, err := want(&i, arg) | |
| 206 | 219 | if err != nil { | |
| @@ -361,6 +374,7 @@ func PrintHelp(version string) { | |||
| 361 | 374 | row{"--api-key KEY", "api key for this run (env / auth.json fallback)"}, | |
| 362 | 375 | row{"--base-url URL", "override provider api base url"}, | |
| 363 | 376 | row{"--reasoning off|minimum|low|medium|high|maximum", "set thinking level on supported models"}, | |
| 377 | + | row{"--temperature N", "sampling temperature, 0 to 2 (omit for provider default)"}, | |
| 364 | 378 | ) | |
| 365 | 379 | section("prompt and session flags", | |
| 366 | 380 | row{"--system-prompt TEXT", "replace the default system prompt"}, | |
| @@ -3,6 +3,7 @@ package agent | |||||
| 3 | import ( | 3 | import ( | ||
| 4 | "fmt" | 4 | "fmt" | ||
| 5 | "os" | 5 | "os" | ||
| 6 | + | "strconv" | |||
| 6 | "strings" | 7 | "strings" | ||
| 7 | 8 | ||||
| 8 | "github.com/patriceckhart/zot/packages/tui" | 9 | "github.com/patriceckhart/zot/packages/tui" | ||
| @@ -37,6 +38,7 @@ type Args struct { | |||||
| 37 | SystemPrompt string | 38 | SystemPrompt string | ||
| 38 | AppendSystemPrompt []string | 39 | AppendSystemPrompt []string | ||
| 39 | Reasoning string | 40 | Reasoning string | ||
| 41 | + | Temperature *float32 | |||
| 40 | 42 | ||||
| 41 | Continue bool | 43 | Continue bool | ||
| 42 | Resume bool | 44 | Resume bool | ||
| @@ -201,6 +203,17 @@ func ParseArgs(in []string) (Args, error) { | |||||
| 201 | default: | 203 | default: | ||
| 202 | return a, fmt.Errorf("--reasoning must be off|minimum|low|medium|high|maximum") | 204 | return a, fmt.Errorf("--reasoning must be off|minimum|low|medium|high|maximum") | ||
| 203 | } | 205 | } | ||
| 206 | + | case "--temperature": | |||
| 207 | + | v, err := want(&i, arg) | |||
| 208 | + | if err != nil { | |||
| 209 | + | return a, err | |||
| 210 | + | } | |||
| 211 | + | f, err := strconv.ParseFloat(v, 32) | |||
| 212 | + | if err != nil || f < 0 || f > 2 { | |||
| 213 | + | return a, fmt.Errorf("--temperature must be a number between 0 and 2") | |||
| 214 | + | } | |||
| 215 | + | t := float32(f) | |||
| 216 | + | a.Temperature = &t | |||
| 204 | case "--session": | 217 | case "--session": | ||
| 205 | v, err := want(&i, arg) | 218 | v, err := want(&i, arg) | ||
| 206 | if err != nil { | 219 | if err != nil { | ||
| @@ -361,6 +374,7 @@ func PrintHelp(version string) { | |||||
| 361 | row{"--api-key KEY", "api key for this run (env / auth.json fallback)"}, | 374 | row{"--api-key KEY", "api key for this run (env / auth.json fallback)"}, | ||
| 362 | row{"--base-url URL", "override provider api base url"}, | 375 | row{"--base-url URL", "override provider api base url"}, | ||
| 363 | row{"--reasoning off|minimum|low|medium|high|maximum", "set thinking level on supported models"}, | 376 | row{"--reasoning off|minimum|low|medium|high|maximum", "set thinking level on supported models"}, | ||
| 377 | + | row{"--temperature N", "sampling temperature, 0 to 2 (omit for provider default)"}, | |||
| 364 | ) | 378 | ) | ||
| 365 | section("prompt and session flags", | 379 | section("prompt and session flags", | ||
| 366 | row{"--system-prompt TEXT", "replace the default system prompt"}, | 380 | row{"--system-prompt TEXT", "replace the default system prompt"}, | ||
A packages/agent/args_test.go +19 -0
| @@ -0,0 +1,19 @@ | |||
| 1 | + | package agent | |
| 2 | + | ||
| 3 | + | import "testing" | |
| 4 | + | ||
| 5 | + | func TestParseArgsTemperatureAllowsZero(t *testing.T) { | |
| 6 | + | args, err := ParseArgs([]string{"--temperature", "0"}) | |
| 7 | + | if err != nil { | |
| 8 | + | t.Fatalf("ParseArgs returned %v", err) | |
| 9 | + | } | |
| 10 | + | if args.Temperature == nil || *args.Temperature != 0 { | |
| 11 | + | t.Fatalf("Temperature = %v; want 0", args.Temperature) | |
| 12 | + | } | |
| 13 | + | } | |
| 14 | + | ||
| 15 | + | func TestParseArgsTemperatureRejectsOutOfRange(t *testing.T) { | |
| 16 | + | if _, err := ParseArgs([]string{"--temperature", "2.1"}); err == nil { | |
| 17 | + | t.Fatal("ParseArgs accepted out-of-range temperature") | |
| 18 | + | } | |
| 19 | + | } | |
| @@ -0,0 +1,19 @@ | |||||
| 1 | + | package agent | |||
| 2 | + | ||||
| 3 | + | import "testing" | |||
| 4 | + | ||||
| 5 | + | func TestParseArgsTemperatureAllowsZero(t *testing.T) { | |||
| 6 | + | args, err := ParseArgs([]string{"--temperature", "0"}) | |||
| 7 | + | if err != nil { | |||
| 8 | + | t.Fatalf("ParseArgs returned %v", err) | |||
| 9 | + | } | |||
| 10 | + | if args.Temperature == nil || *args.Temperature != 0 { | |||
| 11 | + | t.Fatalf("Temperature = %v; want 0", args.Temperature) | |||
| 12 | + | } | |||
| 13 | + | } | |||
| 14 | + | ||||
| 15 | + | func TestParseArgsTemperatureRejectsOutOfRange(t *testing.T) { | |||
| 16 | + | if _, err := ParseArgs([]string{"--temperature", "2.1"}); err == nil { | |||
| 17 | + | t.Fatal("ParseArgs accepted out-of-range temperature") | |||
| 18 | + | } | |||
| 19 | + | } | |||
M packages/agent/build.go +15 -8
| @@ -17,14 +17,15 @@ import ( | |||
| 17 | 17 | ||
| 18 | 18 | // Resolved is the effective configuration after merging CLI, config, defaults. | |
| 19 | 19 | type Resolved struct { | |
| 20 | - | Provider string | |
| 21 | - | Model string | |
| 22 | - | Credential string // api key or oauth access token | |
| 23 | - | AuthMethod string // "apikey" | "oauth" | "" (no credential yet) | |
| 24 | - | AccountID string // ChatGPT account id (for openai oauth), "" otherwise | |
| 25 | - | BaseURL string | |
| 26 | - | CWD string | |
| 27 | - | Reasoning string | |
| 20 | + | Provider string | |
| 21 | + | Model string | |
| 22 | + | Credential string // api key or oauth access token | |
| 23 | + | AuthMethod string // "apikey" | "oauth" | "" (no credential yet) | |
| 24 | + | AccountID string // ChatGPT account id (for openai oauth), "" otherwise | |
| 25 | + | BaseURL string | |
| 26 | + | CWD string | |
| 27 | + | Reasoning string | |
| 28 | + | Temperature *float32 | |
| 28 | 29 | ||
| 29 | 30 | ToolRegistry core.Registry | |
| 30 | 31 | ToolSummary []ToolSummary | |
| @@ -492,6 +493,10 @@ func Resolve(args Args, requireCred bool) (Resolved, error) { | |||
| 492 | 493 | }) | |
| 493 | 494 | ||
| 494 | 495 | reasoning := provider.NormalizeReasoning(firstNonEmpty(args.Reasoning, cfg.Reasoning)) | |
| 496 | + | temperature := args.Temperature | |
| 497 | + | if temperature == nil { | |
| 498 | + | temperature = cfg.Temperature | |
| 499 | + | } | |
| 495 | 500 | ||
| 496 | 501 | max := args.MaxSteps // 0 = unlimited | |
| 497 | 502 | ||
| @@ -504,6 +509,7 @@ func Resolve(args Args, requireCred bool) (Resolved, error) { | |||
| 504 | 509 | BaseURL: args.BaseURL, | |
| 505 | 510 | CWD: args.CWD, | |
| 506 | 511 | Reasoning: reasoning, | |
| 512 | + | Temperature: temperature, | |
| 507 | 513 | ToolRegistry: reg, | |
| 508 | 514 | ToolSummary: summaries, | |
| 509 | 515 | SystemPrompt: sys, | |
| @@ -778,6 +784,7 @@ func (r Resolved) NewAgent() *core.Agent { | |||
| 778 | 784 | a.MaxSteps = r.MaxSteps | |
| 779 | 785 | a.MaxTokens = r.MaxOutput | |
| 780 | 786 | a.Reasoning = r.Reasoning | |
| 787 | + | a.Temperature = r.Temperature | |
| 781 | 788 | return a | |
| 782 | 789 | } | |
| 783 | 790 | ||
| @@ -17,14 +17,15 @@ import ( | |||||
| 17 | 17 | ||||
| 18 | // Resolved is the effective configuration after merging CLI, config, defaults. | 18 | // Resolved is the effective configuration after merging CLI, config, defaults. | ||
| 19 | type Resolved struct { | 19 | type Resolved struct { | ||
| 20 | - | Provider string | 20 | + | Provider string |
| 21 | - | Model string | 21 | + | Model string |
| 22 | - | Credential string // api key or oauth access token | 22 | + | Credential string // api key or oauth access token |
| 23 | - | AuthMethod string // "apikey" | "oauth" | "" (no credential yet) | 23 | + | AuthMethod string // "apikey" | "oauth" | "" (no credential yet) |
| 24 | - | AccountID string // ChatGPT account id (for openai oauth), "" otherwise | 24 | + | AccountID string // ChatGPT account id (for openai oauth), "" otherwise |
| 25 | - | BaseURL string | 25 | + | BaseURL string |
| 26 | - | CWD string | 26 | + | CWD string |
| 27 | - | Reasoning string | 27 | + | Reasoning string |
| 28 | + | Temperature *float32 | |||
| 28 | 29 | ||||
| 29 | ToolRegistry core.Registry | 30 | ToolRegistry core.Registry | ||
| 30 | ToolSummary []ToolSummary | 31 | ToolSummary []ToolSummary | ||
| @@ -492,6 +493,10 @@ func Resolve(args Args, requireCred bool) (Resolved, error) { | |||||
| 492 | }) | 493 | }) | ||
| 493 | 494 | ||||
| 494 | reasoning := provider.NormalizeReasoning(firstNonEmpty(args.Reasoning, cfg.Reasoning)) | 495 | reasoning := provider.NormalizeReasoning(firstNonEmpty(args.Reasoning, cfg.Reasoning)) | ||
| 496 | + | temperature := args.Temperature | |||
| 497 | + | if temperature == nil { | |||
| 498 | + | temperature = cfg.Temperature | |||
| 499 | + | } | |||
| 495 | 500 | ||||
| 496 | max := args.MaxSteps // 0 = unlimited | 501 | max := args.MaxSteps // 0 = unlimited | ||
| 497 | 502 | ||||
| @@ -504,6 +509,7 @@ func Resolve(args Args, requireCred bool) (Resolved, error) { | |||||
| 504 | BaseURL: args.BaseURL, | 509 | BaseURL: args.BaseURL, | ||
| 505 | CWD: args.CWD, | 510 | CWD: args.CWD, | ||
| 506 | Reasoning: reasoning, | 511 | Reasoning: reasoning, | ||
| 512 | + | Temperature: temperature, | |||
| 507 | ToolRegistry: reg, | 513 | ToolRegistry: reg, | ||
| 508 | ToolSummary: summaries, | 514 | ToolSummary: summaries, | ||
| 509 | SystemPrompt: sys, | 515 | SystemPrompt: sys, | ||
| @@ -778,6 +784,7 @@ func (r Resolved) NewAgent() *core.Agent { | |||||
| 778 | a.MaxSteps = r.MaxSteps | 784 | a.MaxSteps = r.MaxSteps | ||
| 779 | a.MaxTokens = r.MaxOutput | 785 | a.MaxTokens = r.MaxOutput | ||
| 780 | a.Reasoning = r.Reasoning | 786 | a.Reasoning = r.Reasoning | ||
| 787 | + | a.Temperature = r.Temperature | |||
| 781 | return a | 788 | return a | ||
| 782 | } | 789 | } | ||
| 783 | 790 | ||||
M packages/agent/config.go +5 -4
| @@ -16,10 +16,11 @@ import ( | |||
| 16 | 16 | ||
| 17 | 17 | // Config is the persisted user configuration. | |
| 18 | 18 | type Config struct { | |
| 19 | - | Provider string `json:"provider"` | |
| 20 | - | Model string `json:"model"` | |
| 21 | - | Reasoning string `json:"reasoning"` | |
| 22 | - | Theme string `json:"theme"` | |
| 19 | + | Provider string `json:"provider"` | |
| 20 | + | Model string `json:"model"` | |
| 21 | + | Reasoning string `json:"reasoning"` | |
| 22 | + | Temperature *float32 `json:"temperature,omitempty"` | |
| 23 | + | Theme string `json:"theme"` | |
| 23 | 24 | ||
| 24 | 25 | // InlineImagesEnabled controls whether zot draws screenshots inline | |
| 25 | 26 | // when the terminal supports an image protocol. nil/missing means | |
| @@ -16,10 +16,11 @@ import ( | |||||
| 16 | 16 | ||||
| 17 | // Config is the persisted user configuration. | 17 | // Config is the persisted user configuration. | ||
| 18 | type Config struct { | 18 | type Config struct { | ||
| 19 | - | Provider string `json:"provider"` | 19 | + | Provider string `json:"provider"` |
| 20 | - | Model string `json:"model"` | 20 | + | Model string `json:"model"` |
| 21 | - | Reasoning string `json:"reasoning"` | 21 | + | Reasoning string `json:"reasoning"` |
| 22 | - | Theme string `json:"theme"` | 22 | + | Temperature *float32 `json:"temperature,omitempty"` |
| 23 | + | Theme string `json:"theme"` | |||
| 23 | 24 | ||||
| 24 | // InlineImagesEnabled controls whether zot draws screenshots inline | 25 | // InlineImagesEnabled controls whether zot draws screenshots inline | ||
| 25 | // when the terminal supports an image protocol. nil/missing means | 26 | // when the terminal supports an image protocol. nil/missing means | ||
M packages/agent/sdk/sdk.go +4 -0
| @@ -61,6 +61,9 @@ type Config struct { | |||
| 61 | 61 | // ("low", "medium", "high"). Empty = no reasoning. | |
| 62 | 62 | Reasoning string | |
| 63 | 63 | ||
| 64 | + | // Temperature sets the sampling temperature. Nil = provider default. | |
| 65 | + | Temperature *float32 | |
| 66 | + | ||
| 64 | 67 | // MaxSteps caps the agent loop iterations per Prompt call. | |
| 65 | 68 | // 0 uses the default (50). | |
| 66 | 69 | MaxSteps int | |
| @@ -112,6 +115,7 @@ func New(cfg Config) (*Runtime, error) { | |||
| 112 | 115 | SystemPrompt: cfg.SystemPrompt, | |
| 113 | 116 | AppendSystemPrompt: cfg.AppendSystemPrompt, | |
| 114 | 117 | Reasoning: cfg.Reasoning, | |
| 118 | + | Temperature: cfg.Temperature, | |
| 115 | 119 | MaxSteps: cfg.MaxSteps, | |
| 116 | 120 | Tools: cfg.Tools, | |
| 117 | 121 | NoTools: cfg.NoTools, | |
| @@ -61,6 +61,9 @@ type Config struct { | |||||
| 61 | // ("low", "medium", "high"). Empty = no reasoning. | 61 | // ("low", "medium", "high"). Empty = no reasoning. | ||
| 62 | Reasoning string | 62 | Reasoning string | ||
| 63 | 63 | ||||
| 64 | + | // Temperature sets the sampling temperature. Nil = provider default. | |||
| 65 | + | Temperature *float32 | |||
| 66 | + | ||||
| 64 | // MaxSteps caps the agent loop iterations per Prompt call. | 67 | // MaxSteps caps the agent loop iterations per Prompt call. | ||
| 65 | // 0 uses the default (50). | 68 | // 0 uses the default (50). | ||
| 66 | MaxSteps int | 69 | MaxSteps int | ||
| @@ -112,6 +115,7 @@ func New(cfg Config) (*Runtime, error) { | |||||
| 112 | SystemPrompt: cfg.SystemPrompt, | 115 | SystemPrompt: cfg.SystemPrompt, | ||
| 113 | AppendSystemPrompt: cfg.AppendSystemPrompt, | 116 | AppendSystemPrompt: cfg.AppendSystemPrompt, | ||
| 114 | Reasoning: cfg.Reasoning, | 117 | Reasoning: cfg.Reasoning, | ||
| 118 | + | Temperature: cfg.Temperature, | |||
| 115 | MaxSteps: cfg.MaxSteps, | 119 | MaxSteps: cfg.MaxSteps, | ||
| 116 | Tools: cfg.Tools, | 120 | Tools: cfg.Tools, | ||
| 117 | NoTools: cfg.NoTools, | 121 | NoTools: cfg.NoTools, | ||
M packages/core/agent.go +12 -10
| @@ -15,12 +15,13 @@ import ( | |||
| 15 | 15 | // Agent is a stateful conversation bound to a provider client, a model, | |
| 16 | 16 | // and a set of tools. | |
| 17 | 17 | type Agent struct { | |
| 18 | - | Client provider.Client | |
| 19 | - | Model string | |
| 20 | - | System string | |
| 21 | - | Tools Registry | |
| 22 | - | MaxSteps int | |
| 23 | - | Reasoning string | |
| 18 | + | Client provider.Client | |
| 19 | + | Model string | |
| 20 | + | System string | |
| 21 | + | Tools Registry | |
| 22 | + | MaxSteps int | |
| 23 | + | Reasoning string | |
| 24 | + | Temperature *float32 | |
| 24 | 25 | ||
| 25 | 26 | // MaxTokens caps the model's output tokens per turn. Zero leaves | |
| 26 | 27 | // the field unset on the provider request, letting each provider | |
| @@ -520,10 +521,11 @@ func (a *Agent) oneTurn(ctx context.Context, sink func(AgentEvent)) (provider.St | |||
| 520 | 521 | // next in-process request is rejected by providers like Anthropic | |
| 521 | 522 | // with "tool_use ids were found without tool_result blocks". The | |
| 522 | 523 | // repair is pure and a no-op on already-valid transcripts. | |
| 523 | - | Messages: repairToolUseResultPairs(a.Messages()), | |
| 524 | - | Tools: a.Tools.Specs(), | |
| 525 | - | Reasoning: a.Reasoning, | |
| 526 | - | MaxTokens: a.MaxTokens, | |
| 524 | + | Messages: repairToolUseResultPairs(a.Messages()), | |
| 525 | + | Tools: a.Tools.Specs(), | |
| 526 | + | Reasoning: a.Reasoning, | |
| 527 | + | MaxTokens: a.MaxTokens, | |
| 528 | + | Temperature: a.Temperature, | |
| 527 | 529 | } | |
| 528 | 530 | stream, err := a.Client.Stream(ctx, req) | |
| 529 | 531 | if err != nil { | |
| @@ -15,12 +15,13 @@ import ( | |||||
| 15 | // Agent is a stateful conversation bound to a provider client, a model, | 15 | // Agent is a stateful conversation bound to a provider client, a model, | ||
| 16 | // and a set of tools. | 16 | // and a set of tools. | ||
| 17 | type Agent struct { | 17 | type Agent struct { | ||
| 18 | - | Client provider.Client | 18 | + | Client provider.Client |
| 19 | - | Model string | 19 | + | Model string |
| 20 | - | System string | 20 | + | System string |
| 21 | - | Tools Registry | 21 | + | Tools Registry |
| 22 | - | MaxSteps int | 22 | + | MaxSteps int |
| 23 | - | Reasoning string | 23 | + | Reasoning string |
| 24 | + | Temperature *float32 | |||
| 24 | 25 | ||||
| 25 | // MaxTokens caps the model's output tokens per turn. Zero leaves | 26 | // MaxTokens caps the model's output tokens per turn. Zero leaves | ||
| 26 | // the field unset on the provider request, letting each provider | 27 | // the field unset on the provider request, letting each provider | ||
| @@ -520,10 +521,11 @@ func (a *Agent) oneTurn(ctx context.Context, sink func(AgentEvent)) (provider.St | |||||
| 520 | // next in-process request is rejected by providers like Anthropic | 521 | // next in-process request is rejected by providers like Anthropic | ||
| 521 | // with "tool_use ids were found without tool_result blocks". The | 522 | // with "tool_use ids were found without tool_result blocks". The | ||
| 522 | // repair is pure and a no-op on already-valid transcripts. | 523 | // repair is pure and a no-op on already-valid transcripts. | ||
| 523 | - | Messages: repairToolUseResultPairs(a.Messages()), | 524 | + | Messages: repairToolUseResultPairs(a.Messages()), |
| 524 | - | Tools: a.Tools.Specs(), | 525 | + | Tools: a.Tools.Specs(), |
| 525 | - | Reasoning: a.Reasoning, | 526 | + | Reasoning: a.Reasoning, |
| 526 | - | MaxTokens: a.MaxTokens, | 527 | + | MaxTokens: a.MaxTokens, |
| 528 | + | Temperature: a.Temperature, | |||
| 527 | } | 529 | } | ||
| 528 | stream, err := a.Client.Stream(ctx, req) | 530 | stream, err := a.Client.Stream(ctx, req) | ||
| 529 | if err != nil { | 531 | if err != nil { | ||
M packages/core/agent_retry_test.go +14 -0
| @@ -144,3 +144,17 @@ func TestAgentPropagatesMaxTokens(t *testing.T) { | |||
| 144 | 144 | t.Fatalf("request MaxTokens = %d; want 64000 (Agent.MaxTokens not propagated)", client.lastReq.MaxTokens) | |
| 145 | 145 | } | |
| 146 | 146 | } | |
| 147 | + | ||
| 148 | + | func TestAgentPropagatesTemperature(t *testing.T) { | |
| 149 | + | client := &captureClient{} | |
| 150 | + | a := NewAgent(client, "fake-model", "system", Registry{}) | |
| 151 | + | temp := float32(0) | |
| 152 | + | a.Temperature = &temp | |
| 153 | + | ||
| 154 | + | if err := a.Prompt(context.Background(), "hello", nil, nil); err != nil { | |
| 155 | + | t.Fatalf("Prompt returned %v", err) | |
| 156 | + | } | |
| 157 | + | if client.lastReq.Temperature == nil || *client.lastReq.Temperature != temp { | |
| 158 | + | t.Fatalf("request Temperature = %v; want %v", client.lastReq.Temperature, temp) | |
| 159 | + | } | |
| 160 | + | } | |
| @@ -144,3 +144,17 @@ func TestAgentPropagatesMaxTokens(t *testing.T) { | |||||
| 144 | t.Fatalf("request MaxTokens = %d; want 64000 (Agent.MaxTokens not propagated)", client.lastReq.MaxTokens) | 144 | t.Fatalf("request MaxTokens = %d; want 64000 (Agent.MaxTokens not propagated)", client.lastReq.MaxTokens) | ||
| 145 | } | 145 | } | ||
| 146 | } | 146 | } | ||
| 147 | + | ||||
| 148 | + | func TestAgentPropagatesTemperature(t *testing.T) { | |||
| 149 | + | client := &captureClient{} | |||
| 150 | + | a := NewAgent(client, "fake-model", "system", Registry{}) | |||
| 151 | + | temp := float32(0) | |||
| 152 | + | a.Temperature = &temp | |||
| 153 | + | ||||
| 154 | + | if err := a.Prompt(context.Background(), "hello", nil, nil); err != nil { | |||
| 155 | + | t.Fatalf("Prompt returned %v", err) | |||
| 156 | + | } | |||
| 157 | + | if client.lastReq.Temperature == nil || *client.lastReq.Temperature != temp { | |||
| 158 | + | t.Fatalf("request Temperature = %v; want %v", client.lastReq.Temperature, temp) | |||
| 159 | + | } | |||
| 160 | + | } | |||
M packages/core/compact.go +4 -3
| @@ -47,9 +47,10 @@ func (a *Agent) Compact(ctx context.Context, keepTail int, sink func(delta strin | |||
| 47 | 47 | prompt := "<conversation>\n" + transcript + "\n</conversation>\n\n" + compactionPrompt | |
| 48 | 48 | ||
| 49 | 49 | req := provider.Request{ | |
| 50 | - | Model: a.Model, | |
| 51 | - | System: summarizationSystem, | |
| 52 | - | MaxTokens: 4096, | |
| 50 | + | Model: a.Model, | |
| 51 | + | System: summarizationSystem, | |
| 52 | + | MaxTokens: 4096, | |
| 53 | + | Temperature: a.Temperature, | |
| 53 | 54 | Messages: []provider.Message{ | |
| 54 | 55 | { | |
| 55 | 56 | Role: provider.RoleUser, | |
| @@ -47,9 +47,10 @@ func (a *Agent) Compact(ctx context.Context, keepTail int, sink func(delta strin | |||||
| 47 | prompt := "<conversation>\n" + transcript + "\n</conversation>\n\n" + compactionPrompt | 47 | prompt := "<conversation>\n" + transcript + "\n</conversation>\n\n" + compactionPrompt | ||
| 48 | 48 | ||||
| 49 | req := provider.Request{ | 49 | req := provider.Request{ | ||
| 50 | - | Model: a.Model, | 50 | + | Model: a.Model, |
| 51 | - | System: summarizationSystem, | 51 | + | System: summarizationSystem, |
| 52 | - | MaxTokens: 4096, | 52 | + | MaxTokens: 4096, |
| 53 | + | Temperature: a.Temperature, | |||
| 53 | Messages: []provider.Message{ | 54 | Messages: []provider.Message{ | ||
| 54 | { | 55 | { | ||
| 55 | Role: provider.RoleUser, | 56 | Role: provider.RoleUser, | ||