Skip to content

Commit dd0935f

Browse files
authored
Merge pull request #1597 from ksylvan/0708-more-refactoring-fixes-for-patterns-loading
CLI Refactoring: Modular Command Processing and Pattern Loading Improvements
2 parents 42d3f45 + e64bdd8 commit dd0935f

File tree

10 files changed

+542
-256
lines changed

10 files changed

+542
-256
lines changed

internal/cli/chat.go

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package cli
2+
3+
import (
4+
"fmt"
5+
"os"
6+
"strings"
7+
8+
"github.com/danielmiessler/fabric/internal/core"
9+
"github.com/danielmiessler/fabric/internal/domain"
10+
"github.com/danielmiessler/fabric/internal/plugins/db/fsdb"
11+
)
12+
13+
// handleChatProcessing handles the main chat processing logic
14+
func handleChatProcessing(currentFlags *Flags, registry *core.PluginRegistry, messageTools string) (err error) {
15+
if messageTools != "" {
16+
currentFlags.AppendMessage(messageTools)
17+
}
18+
19+
var chatter *core.Chatter
20+
if chatter, err = registry.GetChatter(currentFlags.Model, currentFlags.ModelContextLength,
21+
currentFlags.Strategy, currentFlags.Stream, currentFlags.DryRun); err != nil {
22+
return
23+
}
24+
25+
var session *fsdb.Session
26+
var chatReq *domain.ChatRequest
27+
if chatReq, err = currentFlags.BuildChatRequest(strings.Join(os.Args[1:], " ")); err != nil {
28+
return
29+
}
30+
31+
if chatReq.Language == "" {
32+
chatReq.Language = registry.Language.DefaultLanguage.Value
33+
}
34+
var chatOptions *domain.ChatOptions
35+
if chatOptions, err = currentFlags.BuildChatOptions(); err != nil {
36+
return
37+
}
38+
if session, err = chatter.Send(chatReq, chatOptions); err != nil {
39+
return
40+
}
41+
42+
result := session.GetLastMessage().Content
43+
44+
if !currentFlags.Stream {
45+
// print the result if it was not streamed already
46+
fmt.Println(result)
47+
}
48+
49+
// if the copy flag is set, copy the message to the clipboard
50+
if currentFlags.Copy {
51+
if err = CopyToClipboard(result); err != nil {
52+
return
53+
}
54+
}
55+
56+
// if the output flag is set, create an output file
57+
if currentFlags.Output != "" {
58+
if currentFlags.OutputSession {
59+
sessionAsString := session.String()
60+
err = CreateOutputFile(sessionAsString, currentFlags.Output)
61+
} else {
62+
err = CreateOutputFile(result, currentFlags.Output)
63+
}
64+
}
65+
return
66+
}

internal/cli/cli.go

Lines changed: 28 additions & 245 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,11 @@ import (
44
"encoding/json"
55
"fmt"
66
"os"
7-
"path/filepath"
8-
"strconv"
97
"strings"
108

11-
"github.com/danielmiessler/fabric/internal/tools/youtube"
12-
139
"github.com/danielmiessler/fabric/internal/core"
14-
"github.com/danielmiessler/fabric/internal/domain"
15-
"github.com/danielmiessler/fabric/internal/plugins/ai"
16-
"github.com/danielmiessler/fabric/internal/plugins/db/fsdb"
17-
restapi "github.com/danielmiessler/fabric/internal/server"
1810
"github.com/danielmiessler/fabric/internal/tools/converter"
11+
"github.com/danielmiessler/fabric/internal/tools/youtube"
1912
)
2013

2114
// Cli Controls the cli. It takes in the flags and runs the appropriate functions
@@ -30,277 +23,67 @@ func Cli(version string) (err error) {
3023
return
3124
}
3225

33-
var homedir string
34-
if homedir, err = os.UserHomeDir(); err != nil {
35-
return
36-
}
37-
38-
fabricDb := fsdb.NewDb(filepath.Join(homedir, ".config/fabric"))
39-
40-
if err = fabricDb.Configure(); err != nil {
26+
// Initialize database and registry
27+
var registry, err2 = initializeFabric()
28+
if err2 != nil {
4129
if !currentFlags.Setup {
42-
println(err.Error())
30+
fmt.Fprintln(os.Stderr, err2.Error())
4331
currentFlags.Setup = true
4432
}
45-
}
46-
47-
var registry *core.PluginRegistry
48-
if registry, err = core.NewPluginRegistry(fabricDb); err != nil {
49-
return
50-
}
51-
52-
// if the setup flag is set, run the setup function
53-
if currentFlags.Setup {
54-
err = registry.Setup()
55-
return
56-
}
57-
58-
if currentFlags.Serve {
59-
registry.ConfigureVendors()
60-
err = restapi.Serve(registry, currentFlags.ServeAddress, currentFlags.ServeAPIKey)
61-
return
62-
}
63-
64-
if currentFlags.ServeOllama {
65-
registry.ConfigureVendors()
66-
err = restapi.ServeOllama(registry, currentFlags.ServeAddress, version)
67-
return
68-
}
69-
70-
if currentFlags.UpdatePatterns {
71-
err = registry.PatternsLoader.PopulateDB()
72-
return
73-
}
74-
75-
if currentFlags.ChangeDefaultModel {
76-
if err = registry.Defaults.Setup(); err != nil {
77-
return
78-
}
79-
err = registry.SaveEnvFile()
80-
return
81-
}
82-
83-
if currentFlags.LatestPatterns != "0" {
84-
var parsedToInt int
85-
if parsedToInt, err = strconv.Atoi(currentFlags.LatestPatterns); err != nil {
86-
return
87-
}
88-
89-
if err = fabricDb.Patterns.PrintLatestPatterns(parsedToInt); err != nil {
90-
return
91-
}
92-
return
93-
}
94-
95-
if currentFlags.ListPatterns {
96-
err = fabricDb.Patterns.ListNames(currentFlags.ShellCompleteOutput)
97-
return
98-
}
99-
100-
if currentFlags.ListAllModels {
101-
var models *ai.VendorsModels
102-
if models, err = registry.VendorManager.GetModels(); err != nil {
103-
return
33+
// Return early if registry is nil to prevent panics in subsequent handlers
34+
if registry == nil {
35+
return err2
10436
}
105-
models.Print(currentFlags.ShellCompleteOutput)
106-
return
10737
}
10838

109-
if currentFlags.ListAllContexts {
110-
err = fabricDb.Contexts.ListNames(currentFlags.ShellCompleteOutput)
39+
// Handle setup and server commands
40+
var handled bool
41+
if handled, err = handleSetupAndServerCommands(currentFlags, registry, version); err != nil || handled {
11142
return
11243
}
11344

114-
if currentFlags.ListAllSessions {
115-
err = fabricDb.Sessions.ListNames(currentFlags.ShellCompleteOutput)
45+
// Handle configuration commands
46+
if handled, err = handleConfigurationCommands(currentFlags, registry); err != nil || handled {
11647
return
11748
}
11849

119-
if currentFlags.WipeContext != "" {
120-
err = fabricDb.Contexts.Delete(currentFlags.WipeContext)
50+
// Handle listing commands
51+
if handled, err = handleListingCommands(currentFlags, registry.Db, registry); err != nil || handled {
12152
return
12253
}
12354

124-
if currentFlags.WipeSession != "" {
125-
err = fabricDb.Sessions.Delete(currentFlags.WipeSession)
55+
// Handle management commands
56+
if handled, err = handleManagementCommands(currentFlags, registry.Db); err != nil || handled {
12657
return
12758
}
12859

129-
if currentFlags.PrintSession != "" {
130-
err = fabricDb.Sessions.PrintSession(currentFlags.PrintSession)
131-
return
132-
}
133-
134-
if currentFlags.PrintContext != "" {
135-
err = fabricDb.Contexts.PrintContext(currentFlags.PrintContext)
60+
// Handle extension commands
61+
if handled, err = handleExtensionCommands(currentFlags, registry); err != nil || handled {
13662
return
13763
}
13864

65+
// Process HTML readability if needed
13966
if currentFlags.HtmlReadability {
14067
if msg, cleanErr := converter.HtmlReadability(currentFlags.Message); cleanErr != nil {
141-
fmt.Println("use original input, because can't apply html readability", err)
68+
fmt.Println("use original input, because can't apply html readability", cleanErr)
14269
} else {
14370
currentFlags.Message = msg
14471
}
14572
}
14673

147-
if currentFlags.ListExtensions {
148-
err = registry.TemplateExtensions.ListExtensions()
149-
return
150-
}
151-
152-
if currentFlags.AddExtension != "" {
153-
err = registry.TemplateExtensions.RegisterExtension(currentFlags.AddExtension)
154-
return
155-
}
156-
157-
if currentFlags.RemoveExtension != "" {
158-
err = registry.TemplateExtensions.RemoveExtension(currentFlags.RemoveExtension)
159-
return
160-
}
161-
162-
if currentFlags.ListStrategies {
163-
err = registry.Strategies.ListStrategies(currentFlags.ShellCompleteOutput)
164-
return
165-
}
166-
167-
if currentFlags.ListVendors {
168-
err = registry.ListVendors(os.Stdout)
169-
return
170-
}
171-
172-
// if the interactive flag is set, run the interactive function
173-
// if currentFlags.Interactive {
174-
// interactive.Interactive()
175-
// }
176-
177-
// if none of the above currentFlags are set, run the initiate chat function
178-
74+
// Handle tool-based message processing
17975
var messageTools string
180-
181-
if currentFlags.YouTube != "" {
182-
if !registry.YouTube.IsConfigured() {
183-
err = fmt.Errorf("YouTube is not configured, please run the setup procedure")
184-
return
185-
}
186-
187-
var videoId string
188-
var playlistId string
189-
if videoId, playlistId, err = registry.YouTube.GetVideoOrPlaylistId(currentFlags.YouTube); err != nil {
190-
return
191-
} else if (videoId == "" || currentFlags.YouTubePlaylist) && playlistId != "" {
192-
if currentFlags.Output != "" {
193-
err = registry.YouTube.FetchAndSavePlaylist(playlistId, currentFlags.Output)
194-
} else {
195-
var videos []*youtube.VideoMeta
196-
if videos, err = registry.YouTube.FetchPlaylistVideos(playlistId); err != nil {
197-
err = fmt.Errorf("error fetching playlist videos: %v", err)
198-
return
199-
}
200-
201-
for _, video := range videos {
202-
var message string
203-
if message, err = processYoutubeVideo(currentFlags, registry, video.Id); err != nil {
204-
return
205-
}
206-
207-
if !currentFlags.IsChatRequest() {
208-
if err = WriteOutput(message, fmt.Sprintf("%v.md", video.TitleNormalized)); err != nil {
209-
return
210-
}
211-
} else {
212-
messageTools = AppendMessage(messageTools, message)
213-
}
214-
}
215-
}
216-
return
217-
}
218-
219-
if messageTools, err = processYoutubeVideo(currentFlags, registry, videoId); err != nil {
220-
return
221-
}
222-
if !currentFlags.IsChatRequest() {
223-
err = currentFlags.WriteOutput(messageTools)
224-
return
225-
}
226-
}
227-
228-
if (currentFlags.ScrapeURL != "" || currentFlags.ScrapeQuestion != "") && registry.Jina.IsConfigured() {
229-
// Check if the scrape_url flag is set and call ScrapeURL
230-
if currentFlags.ScrapeURL != "" {
231-
var website string
232-
if website, err = registry.Jina.ScrapeURL(currentFlags.ScrapeURL); err != nil {
233-
return
234-
}
235-
messageTools = AppendMessage(messageTools, website)
236-
}
237-
238-
// Check if the scrape_question flag is set and call ScrapeQuestion
239-
if currentFlags.ScrapeQuestion != "" {
240-
var website string
241-
if website, err = registry.Jina.ScrapeQuestion(currentFlags.ScrapeQuestion); err != nil {
242-
return
243-
}
244-
245-
messageTools = AppendMessage(messageTools, website)
246-
}
247-
248-
if !currentFlags.IsChatRequest() {
249-
err = currentFlags.WriteOutput(messageTools)
250-
return
251-
}
252-
}
253-
254-
if messageTools != "" {
255-
currentFlags.AppendMessage(messageTools)
256-
}
257-
258-
var chatter *core.Chatter
259-
if chatter, err = registry.GetChatter(currentFlags.Model, currentFlags.ModelContextLength,
260-
currentFlags.Strategy, currentFlags.Stream, currentFlags.DryRun); err != nil {
261-
return
262-
}
263-
264-
var session *fsdb.Session
265-
var chatReq *domain.ChatRequest
266-
if chatReq, err = currentFlags.BuildChatRequest(strings.Join(os.Args[1:], " ")); err != nil {
76+
if messageTools, err = handleToolProcessing(currentFlags, registry); err != nil {
26777
return
26878
}
26979

270-
if chatReq.Language == "" {
271-
chatReq.Language = registry.Language.DefaultLanguage.Value
272-
}
273-
var chatOptions *domain.ChatOptions
274-
if chatOptions, err = currentFlags.BuildChatOptions(); err != nil {
275-
return
276-
}
277-
if session, err = chatter.Send(chatReq, chatOptions); err != nil {
278-
return
279-
}
280-
281-
result := session.GetLastMessage().Content
282-
283-
if !currentFlags.Stream {
284-
// print the result if it was not streamed already
285-
fmt.Println(result)
80+
// Return early for non-chat tool operations
81+
if messageTools != "" && !currentFlags.IsChatRequest() {
82+
return nil
28683
}
28784

288-
// if the copy flag is set, copy the message to the clipboard
289-
if currentFlags.Copy {
290-
if err = CopyToClipboard(result); err != nil {
291-
return
292-
}
293-
}
294-
295-
// if the output flag is set, create an output file
296-
if currentFlags.Output != "" {
297-
if currentFlags.OutputSession {
298-
sessionAsString := session.String()
299-
err = CreateOutputFile(sessionAsString, currentFlags.Output)
300-
} else {
301-
err = CreateOutputFile(result, currentFlags.Output)
302-
}
303-
}
85+
// Handle chat processing
86+
err = handleChatProcessing(currentFlags, registry, messageTools)
30487
return
30588
}
30689

0 commit comments

Comments
 (0)