Repository navigation
Expand file tree
/
Copy pathconvert.go
More file actions
131 lines (122 loc) · 4.37 KB
/
Copy pathconvert.go
File metadata and controls
131 lines (122 loc) · 4.37 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package engine
import "github.com/GrayCodeAI/flux/provider/core"
// toClientMessages returns the messages unchanged: the engine and the client
// both speak the canonical contract message type, so no per-field conversion
// is needed.
func toClientMessages(in []Message) []core.FluxMessage {
return in
}
// toClientOptions maps a normalized generation request onto the client's
// wire-format chat options. Provider-specific translation continues to live in
// the adapters; this is the contract-level mapping.
func toClientOptions(req GenerateRequest, route Route, stream bool) core.ChatOptions {
tools := append([]core.FluxTool(nil), req.Tools...)
opts := core.ChatOptions{
Provider: route.Provider, Model: route.Model, Stream: stream,
System: req.SystemPrompt, Tools: tools, Temperature: req.Temperature,
MaxTokens: req.Limits.MaxOutputTokens, MetadataUserID: req.Metadata.UserID,
}
advanced := req.Options
opts.EnableCaching = advanced.EnableCaching
opts.ReasoningEffort = advanced.ReasoningEffort
opts.ThinkingBudgetTokens = advanced.ThinkingBudgetTokens
opts.ThinkingMode = advanced.ThinkingMode
opts.ThinkingDisplay = advanced.ThinkingDisplay
opts.GLMThinkingEnabled = advanced.GLMThinkingEnabled
opts.VirtualKeyID = advanced.VirtualKeyID
opts.KimiContextCacheID = advanced.KimiContextCacheID
opts.KimiCacheResetTTL = advanced.KimiCacheResetTTL
opts.TopP = advanced.TopP
opts.TopK = advanced.TopK
opts.StopSequences = append([]string(nil), advanced.StopSequences...)
if advanced.ToolChoice != nil {
opts.ToolChoice = &core.ToolChoiceOption{
Type: advanced.ToolChoice.Type, Name: advanced.ToolChoice.Name,
DisableParallelToolUse: advanced.ToolChoice.DisableParallelToolUse,
}
}
opts.ServiceTier = advanced.ServiceTier
opts.OutputEffort = advanced.OutputEffort
opts.PresencePenalty = advanced.PresencePenalty
opts.FrequencyPenalty = advanced.FrequencyPenalty
opts.N = advanced.N
opts.LogProbs = advanced.LogProbs
opts.TopLogProbs = advanced.TopLogProbs
opts.Seed = advanced.Seed
opts.Store = advanced.Store
opts.Metadata = cloneStringMap(advanced.Metadata)
if opts.Metadata == nil {
opts.Metadata = make(map[string]string)
}
setMetadataIfPresent(opts.Metadata, "session.id", req.Metadata.SessionID)
setMetadataIfPresent(opts.Metadata, "turn.id", req.Metadata.TurnID)
setMetadataIfPresent(opts.Metadata, "project.id", req.Metadata.ProjectID)
if len(opts.Metadata) == 0 {
opts.Metadata = nil
}
opts.Modalities = append([]string(nil), advanced.Modalities...)
opts.AudioConfig = advanced.AudioConfig
opts.Prediction = advanced.Prediction
opts.WebSearchOptions = advanced.WebSearchOptions
if req.OutputSchema != "" {
opts.ResponseFormat = &core.ResponseFormat{Type: "json_schema", Schema: req.OutputSchema}
opts.OutputSchema = req.OutputSchema
}
return opts
}
func setMetadataIfPresent(metadata map[string]string, key, value string) {
if value != "" {
metadata[key] = value
}
}
func cloneStringMap(in map[string]string) map[string]string {
if in == nil {
return nil
}
out := make(map[string]string, len(in))
for key, value := range in {
out[key] = value
}
return out
}
func cloneRoute(route *Route) *Route {
if route == nil {
return nil
}
cloned := *route
return &cloned
}
// mergeRoute keeps the route the provider reported and fills any blank
// identity fields from the route the engine planned.
func mergeRoute(actual *Route, planned Route) *Route {
if actual == nil {
return cloneRoute(&planned)
}
merged := *actual
if merged.Provider == "" {
merged.Provider = planned.Provider
}
if merged.Model == "" {
merged.Model = planned.Model
}
if !merged.DeploymentRouting {
merged.DeploymentRouting = planned.DeploymentRouting
}
return &merged
}
// fromClientResponse attaches the resolved route to a client response. The
// engine and the client both speak the canonical contract response type. A
// route the provider already reported (for example the deployment that served
// the request after a failover) wins; the planned route only fills blanks.
func fromClientResponse(resp *core.FluxResponse, route Route) *GenerateResponse {
if resp == nil {
return &GenerateResponse{Route: cloneRoute(&route)}
}
resp.Route = mergeRoute(resp.Route, route)
return resp
}
// fromClientUsage returns the usage unchanged: the engine and the client both
// speak the canonical contract usage type.
func fromClientUsage(usage *core.FluxUsage) *Usage {
return usage
}