-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathvalidations.go
More file actions
179 lines (168 loc) · 5.69 KB
/
Copy pathvalidations.go
File metadata and controls
179 lines (168 loc) · 5.69 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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
package main
import (
"flag"
"fmt"
"strings"
"github.com/jdevoo/gen/core"
"google.golang.org/genai"
)
// isFlagSet visits the flags passed to the command at runtime.
func isFlagSet(name string) bool {
res := false
flag.Visit(func(f *flag.Flag) {
if f.Name == name {
res = true
}
})
return res
}
// validPrompts checks prompts against regular interactive vs no redirect or piped content session.
func validPrompts(params *core.Parameters) error {
if (params.Interactive &&
// no regular prompt privided
((len(params.Args) == 0 && !anyMatches(params.FilePaths, PExt)) ||
// system instruction
(params.SystemInstruction &&
// not provided as file
((len(params.Args) == 0 && !anyMatches(params.FilePaths, SPExt)) ||
// provided as argument but no prompt as file and no chat mode
(len(params.Args) > 0 && !anyMatches(params.FilePaths, PExt) && !params.ChatMode))))) ||
(!params.Interactive &&
// not set as file xor argument
((!oneMatches(params.FilePaths, "-") && !(len(params.Args) == 1 && params.Args[0] == "-")) ||
// system instruction
(params.SystemInstruction &&
// stdin as file, but no prompt as file or argument
((len(params.Args) == 0 &&
!oneMatches(params.FilePaths, "-") && !anyMatches(params.FilePaths, PExt)) ||
// stdin as argument, no prompt as file
(len(params.Args) == 1 &&
params.Args[0] == "-" && !anyMatches(params.FilePaths, PExt) && !params.ChatMode))))) {
return fmt.Errorf("invalid or missing prompt")
}
return nil
}
func validRanges(params *core.Parameters) error {
// ThinkingLevel
if strings.HasPrefix(string(genai.ThinkingLevelMinimal), string(params.ThinkingLevel)) {
params.ThinkingLevel = genai.ThinkingLevelMinimal
}
if strings.HasPrefix(string(genai.ThinkingLevelLow), string(params.ThinkingLevel)) {
params.ThinkingLevel = genai.ThinkingLevelLow
}
if strings.HasPrefix(string(genai.ThinkingLevelMedium), string(params.ThinkingLevel)) {
params.ThinkingLevel = genai.ThinkingLevelMedium
}
if strings.HasPrefix(string(genai.ThinkingLevelHigh), string(params.ThinkingLevel)) {
params.ThinkingLevel = genai.ThinkingLevelHigh
}
if
// invalid thinking level
(len(params.ThinkingLevel) < 3 ||
params.ThinkingLevel != genai.ThinkingLevelUnspecified &&
params.ThinkingLevel != genai.ThinkingLevelMinimal &&
params.ThinkingLevel != genai.ThinkingLevelLow &&
params.ThinkingLevel != genai.ThinkingLevelMedium &&
params.ThinkingLevel != genai.ThinkingLevelHigh) ||
// invalid out path
(len(params.OutPath) > 0 && !isValidPath(params.OutPath)) ||
// invalid k values
(params.K < 0 || params.K > 10) ||
// invalid lambda values
(params.Lambda < 0 || params.Lambda > 1) ||
// invalid temperature values
(params.Temp < 0 || params.Temp > 2) ||
// invalid topP values
(params.TopP < 0 || params.TopP > 1) {
return fmt.Errorf("invalid option values")
}
return nil
}
func validCombos(params *core.Parameters) error {
if
// at most one JSON schema
(params.JSON && !zeroOrOneMatches(params.FilePaths, ".json")) ||
// code execution with incompatible flags
(params.CodeGen &&
(params.Tool || params.GoogleSearch || params.Embed)) ||
// tool registration with incompatible flags
(params.Tool &&
(params.CodeGen || params.GoogleSearch ||
params.SystemInstruction || params.Embed)) ||
// search with incompatible flags
(params.GoogleSearch &&
(params.Tool || params.CodeGen || params.Embed)) ||
// image modality with incompatible flags
(params.ImgModality &&
(params.GoogleSearch || params.CodeGen ||
params.Tool || params.JSON || params.ChatMode || params.Embed)) ||
// out path only with -img and no redirect
(len(params.OutPath) > 0 &&
(!(params.ImgModality || params.CodeGen) || params.OutRedirected)) ||
// walk without file attached that is not some prompt
(params.Walk &&
(len(params.FilePaths) == 0 ||
allMatch(params.FilePaths, PExt) || allMatch(params.FilePaths, SPExt))) ||
// chat mode
(params.ChatMode &&
// with incompatible flags
(params.JSON || params.ImgModality || params.Embed)) {
return fmt.Errorf("invalid options combination")
}
return nil
}
func validEmbeddings(params *core.Parameters, keyVals core.ParamMap) error {
if
// embeddings
params.Embed &&
// incompatible flags
(params.Unsafe || params.JSON ||
isFlagSet("temp") || isFlagSet("top_p") || isFlagSet("k") || isFlagSet("l") ||
// no digest set
len(params.DigestPaths) != 1 ||
// metadata missing
(params.OnlyKvs && len(keyVals) == 0) ||
// prompts set
anyMatches(params.FilePaths, PExt) || anyMatches(params.FilePaths, SPExt) ||
// no arguments or files to digest
(!params.Interactive &&
!((len(params.Args) == 1 && params.Args[0] == "-") || oneMatches(params.FilePaths, "-")))) {
return fmt.Errorf("invalid use of -e")
}
return nil
}
// validArgs checks if there are still unhandled flags inside params.Args
func validArgs(fs *flag.FlagSet, params *core.Parameters) error {
var err error
flag.CommandLine.VisitAll(func(f *flag.Flag) {
if err != nil {
return
}
for _, arg := range params.Args {
if arg == "-"+f.Name || strings.HasPrefix(arg, "-"+f.Name+"=") {
err = fmt.Errorf("misplaced or unhandled flag '%s'", arg)
return
}
}
})
return err
}
// isArgsInvalid performs a complete argument validation.
func isArgsInvalid(fs *flag.FlagSet, params *core.Parameters, keyVals core.ParamMap) error {
if err := validArgs(fs, params); err != nil {
return err
}
if err := validPrompts(params); err != nil {
return err
}
if err := validRanges(params); err != nil {
return err
}
if err := validCombos(params); err != nil {
return err
}
if err := validEmbeddings(params, keyVals); err != nil {
return err
}
return nil
}