Skip to content

Commit 137da36

Browse files
committed
feat: error out early for incompatible flags
1 parent d5f79fd commit 137da36

File tree

3 files changed

+103
-16
lines changed

3 files changed

+103
-16
lines changed

cmd/chatgpt/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,7 @@ func run(cmd *cobra.Command, args []string) error {
134134
changedFlags[f.Name] = true
135135
})
136136

137-
if err := utils.ValidateFlags(changedFlags); err != nil {
137+
if err := utils.ValidateFlags(cfg.Model, changedFlags); err != nil {
138138
return err
139139
}
140140

cmd/chatgpt/utils/utils.go

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,13 @@ import (
99
"unicode/utf8"
1010
)
1111

12+
const (
13+
AudioPattern = "-audio"
14+
TranscribePattern = "-transcribe"
15+
TTSPattern = "-tts"
16+
O1ProPattern = "o1-pro"
17+
)
18+
1219
func ColorToAnsi(color string) (string, string) {
1320
if color == "" {
1421
return "", ""
@@ -100,7 +107,7 @@ func IsBinary(data []byte) bool {
100107
return binaryCount > threshold
101108
}
102109

103-
func ValidateFlags(flags map[string]bool) error {
110+
func ValidateFlags(model string, flags map[string]bool) error {
104111
if flags["new-thread"] && (flags["set-thread"] || flags["thread"]) {
105112
return errors.New("the --new-thread flag cannot be used with the --set-thread or --thread flags")
106113
}
@@ -110,6 +117,21 @@ func ValidateFlags(flags map[string]bool) error {
110117
if !flags["speak"] && flags["output"] {
111118
return errors.New("the --speak flag cannot be used without the --output flag")
112119
}
120+
if flags["audio"] && !strings.Contains(model, AudioPattern) {
121+
return errors.New("the --audio flag cannot be used without a compatible model, ie gpt-4o-audio-preview (see --list-models)")
122+
}
123+
if flags["transcribe"] && !strings.Contains(model, TranscribePattern) {
124+
return errors.New("the --transcribe flag cannot be used without a compatible model, ie gpt-4o-transcribe (see --list-models)")
125+
}
126+
if flags["speak"] && flags["output"] && !strings.Contains(model, TTSPattern) {
127+
return errors.New("the --speak and --output flags cannot be used without a compatible model, ie gpt-4o-mini-tts (see --list-models)")
128+
}
129+
if flags["voice"] && !strings.Contains(model, TTSPattern) {
130+
return errors.New("the --voice flag cannot be used without a compatible model, ie gpt-4o-mini-tts (see --list-models)")
131+
}
132+
if flags["effort"] && !strings.Contains(model, O1ProPattern) {
133+
return errors.New("the --effort flag cannot be used with non o1-pro models (see --list-models)")
134+
}
113135

114136
return nil
115137
}

cmd/chatgpt/utils/utils_test.go

Lines changed: 79 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -190,39 +190,104 @@ func testUtils(t *testing.T, when spec.G, it spec.S) {
190190
})
191191

192192
when("ValidateFlags()", func() {
193+
const defaultModel = "mock-model"
194+
195+
var flags map[string]bool
196+
197+
it.Before(func() {
198+
flags = make(map[string]bool)
199+
})
200+
193201
it("doesn't throw an error when no flags are provided", func() {
194-
flags := make(map[string]bool)
195-
Expect(utils.ValidateFlags(flags)).To(Succeed())
202+
Expect(utils.ValidateFlags(defaultModel, flags)).To(Succeed())
196203
})
197-
it("should return an error when new-thread and set-thread are both used", func() {
198-
flags := make(map[string]bool)
204+
it("should return an error when --new-thread and --set-thread are both used", func() {
199205
flags["new-thread"] = true
200206
flags["set-thread"] = true
201207

202-
err := utils.ValidateFlags(flags)
208+
err := utils.ValidateFlags(defaultModel, flags)
203209
Expect(err).To(HaveOccurred())
204210
})
205-
it("should return an error when new-thread and thread are both used", func() {
206-
flags := make(map[string]bool)
211+
it("should return an error when --new-thread and --thread are both used", func() {
207212
flags["new-thread"] = true
208213
flags["thread"] = true
209214

210-
err := utils.ValidateFlags(flags)
215+
err := utils.ValidateFlags(defaultModel, flags)
211216
Expect(err).To(HaveOccurred())
212217
})
213-
it("should return an error when speak is used but output is omitted", func() {
214-
flags := make(map[string]bool)
218+
it("should return an error when --speak is used but --output is omitted", func() {
215219
flags["speak"] = true
216220

217-
err := utils.ValidateFlags(flags)
221+
err := utils.ValidateFlags(defaultModel, flags)
218222
Expect(err).To(HaveOccurred())
219223
})
220-
it("should return an error when output is used but speak is omitted", func() {
221-
flags := make(map[string]bool)
224+
it("should return an error when --output is used but --speak is omitted", func() {
222225
flags["output"] = true
223226

224-
err := utils.ValidateFlags(flags)
227+
err := utils.ValidateFlags(defaultModel, flags)
225228
Expect(err).To(HaveOccurred())
226229
})
230+
it("should return an error when --audio is used with an incompatible model", func() {
231+
flags["audio"] = true
232+
233+
err := utils.ValidateFlags(defaultModel, flags)
234+
Expect(err).To(HaveOccurred())
235+
})
236+
it("should NOT return an error when --audio is used with a compatible model", func() {
237+
flags["audio"] = true
238+
239+
err := utils.ValidateFlags(defaultModel+utils.AudioPattern, flags)
240+
Expect(err).NotTo(HaveOccurred())
241+
})
242+
it("should return an error when --transcribe is used with an incompatible model", func() {
243+
flags["transcribe"] = true
244+
245+
err := utils.ValidateFlags(defaultModel, flags)
246+
Expect(err).To(HaveOccurred())
247+
})
248+
it("should NOT return an error when --transcribe is used with a compatible model", func() {
249+
flags["transcribe"] = true
250+
251+
err := utils.ValidateFlags(defaultModel+utils.TranscribePattern, flags)
252+
Expect(err).NotTo(HaveOccurred())
253+
})
254+
it("should return an error when --speak and --output flags are used with an incompatible model", func() {
255+
flags["speak"] = true
256+
flags["output"] = true
257+
258+
err := utils.ValidateFlags(defaultModel, flags)
259+
Expect(err).To(HaveOccurred())
260+
})
261+
it("should NOT return an error when --speak and --output flags are used with a compatible model", func() {
262+
flags["speak"] = true
263+
flags["output"] = true
264+
265+
err := utils.ValidateFlags(defaultModel+utils.TTSPattern, flags)
266+
Expect(err).NotTo(HaveOccurred())
267+
})
268+
it("should return an error when --voice is used with an incompatible model", func() {
269+
flags["voice"] = true
270+
271+
err := utils.ValidateFlags(defaultModel, flags)
272+
Expect(err).To(HaveOccurred())
273+
})
274+
it("should NOT return an error when --voice is used with a compatible model", func() {
275+
flags["voice"] = true
276+
277+
err := utils.ValidateFlags(defaultModel+utils.TTSPattern, flags)
278+
Expect(err).NotTo(HaveOccurred())
279+
})
280+
it("should return an error when --effort is used with an incompatible model", func() {
281+
flags["effort"] = true
282+
283+
err := utils.ValidateFlags(defaultModel, flags)
284+
Expect(err).To(HaveOccurred())
285+
})
286+
it("should NOT return an error when --effort is used with a compatible model", func() {
287+
flags["effort"] = true
288+
289+
err := utils.ValidateFlags(defaultModel+utils.O1ProPattern, flags)
290+
Expect(err).NotTo(HaveOccurred())
291+
})
227292
})
228293
}

0 commit comments

Comments
 (0)