返回 DeepSeek-Reasonix
model_settings.go
根目录 / internal / control / model_settings.go
1 package control
2
3 import (
4 "crypto/rand"
5 "errors"
6 "fmt"
7 )
8
9 var ErrModelChoiceStale = errors.New("model configuration or runtime changed; review the current settings")
10 var ErrModelContinuationDenied = errors.New("current configuration cannot be used")
11
12 type ModelApplicationChoice struct {
13 Mode string `json:"mode"`
14 ExpectedAppliedRevision string `json:"expectedAppliedRevision"`
15 ExpectedDesiredRevision string `json:"expectedDesiredRevision"`
16 ExpectedRuntimeIdentity string `json:"expectedRuntimeIdentity"`
17 ConfirmationToken string `json:"confirmationToken,omitempty"`
18 }
19
20 func (c *Controller) ModelRuntimeIdentity() string { return c.modelSettings.identity }
21 func (c *Controller) ModelConnectionTarget() string { return c.modelSettings.connectionTarget }
22
23 func (c *Controller) ValidateModelContinuation() error {
24 if c.modelSettings.continuation == nil {
25 return fmt.Errorf("runtime cannot verify the current configuration")
26 }
27 return c.modelSettings.continuation()
28 }
29
30 func (c *Controller) ValidateModelApplicationChoice(choice ModelApplicationChoice) error {
31 if choice.Mode != "applied_once" {
32 return fmt.Errorf("unsupported model application choice")
33 }
34 applied, desired, err := c.ModelSettingsState()
35 if err != nil {
36 return err
37 }
38 if choice.ExpectedRuntimeIdentity != c.ModelRuntimeIdentity() || choice.ExpectedAppliedRevision != applied || choice.ExpectedDesiredRevision != desired {
39 return ErrModelChoiceStale
40 }
41 if err := c.ValidateModelContinuation(); err != nil {
42 return errors.Join(ErrModelContinuationDenied, err)
43 }
44 _, latest, err := c.ModelSettingsState()
45 if err != nil {
46 return err
47 }
48 if latest != desired {
49 return ErrModelChoiceStale
50 }
51 return nil
52 }
53
54 // TracksModelSettings reports whether the host supplied a live configuration
55 // observer. Unmanaged controllers have no settings I/O to perform on admission.
56 func (c *Controller) TracksModelSettings() bool { return c.modelSettings.current != nil }
57
58 // ModelSettingsState compares this immutable runtime with current disk config.
59 // It is intentionally separate from provider-visible messages and metadata.
60 func (c *Controller) ModelSettingsState() (applied, desired string, err error) {
61 if c.modelSettings.current == nil {
62 return "", "", nil
63 }
64 desired, err = c.modelSettings.current()
65 return c.modelSettings.revision, desired, err
66 }
67
68 // ModelSettingsSourceRevision identifies an immutable Desktop resolver bundle.
69 // It is transport bookkeeping only, never part of the conversation.
70 func (c *Controller) ModelSettingsSourceRevision() string { return c.modelSettings.sourceRevision }
71
72 // controllerModelSettings keeps the immutable snapshot and its host admission
73 // callback together for the lifetime of one controller. The callback is guarded
74 // by Controller.mu; snapshot fields are immutable after construction.
75 type controllerModelSettings struct {
76 connectionTarget string
77 identity string
78 continuation func() error
79 revision string
80 sourceRevision string
81 current func() (string, error)
82 beforeInboxDispatch func(*Controller) (func(), error)
83 }
84
85 func newControllerModelSettings(opts Options) controllerModelSettings {
86 return controllerModelSettings{
87 connectionTarget: opts.ModelConnectionTarget,
88 identity: rand.Text(),
89 continuation: opts.ModelSettingsContinuation,
90 revision: opts.ModelSettingsRevision,
91 sourceRevision: opts.ModelSettingsSourceRevision,
92 current: opts.ModelSettingsCurrent,
93 beforeInboxDispatch: opts.BeforeInboxDispatch,
94 }
95 }
96
96 lines GO