Skip to content

Commit 1d69afa

Browse files
authored
Merge pull request #1624 from ksylvan/0716-default-config-yaml
Feature: Add Automatic ~/.fabric.yaml Config Detection
2 parents 1c33799 + 96c18b4 commit 1d69afa

File tree

4 files changed

+85
-22
lines changed

4 files changed

+85
-22
lines changed

internal/cli/flags.go

Lines changed: 47 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -102,26 +102,34 @@ func Init() (ret *Flags, err error) {
102102
usedFlags := make(map[string]bool)
103103
yamlArgsScan := os.Args[1:]
104104

105-
// Get list of fields that have yaml tags, could be in yaml config
106-
yamlFields := make(map[string]bool)
105+
// Create mapping from flag names (both short and long) to yaml tag names
106+
flagToYamlTag := make(map[string]string)
107107
t := reflect.TypeOf(Flags{})
108108
for i := 0; i < t.NumField(); i++ {
109-
if yamlTag := t.Field(i).Tag.Get("yaml"); yamlTag != "" {
110-
yamlFields[yamlTag] = true
111-
//Debugf("Found yaml-configured field: %s\n", yamlTag)
109+
field := t.Field(i)
110+
yamlTag := field.Tag.Get("yaml")
111+
if yamlTag != "" {
112+
longTag := field.Tag.Get("long")
113+
shortTag := field.Tag.Get("short")
114+
if longTag != "" {
115+
flagToYamlTag[longTag] = yamlTag
116+
Debugf("Mapped long flag %s to yaml tag %s\n", longTag, yamlTag)
117+
}
118+
if shortTag != "" {
119+
flagToYamlTag[shortTag] = yamlTag
120+
Debugf("Mapped short flag %s to yaml tag %s\n", shortTag, yamlTag)
121+
}
112122
}
113123
}
114124

115125
// Scan args for that are provided by cli and might be in yaml
116126
for _, arg := range yamlArgsScan {
117-
if strings.HasPrefix(arg, "--") {
118-
flag := strings.TrimPrefix(arg, "--")
119-
if i := strings.Index(flag, "="); i > 0 {
120-
flag = flag[:i]
121-
}
122-
if yamlFields[flag] {
123-
usedFlags[flag] = true
124-
Debugf("CLI flag used: %s\n", flag)
127+
flag := extractFlag(arg)
128+
129+
if flag != "" {
130+
if yamlTag, exists := flagToYamlTag[flag]; exists {
131+
usedFlags[yamlTag] = true
132+
Debugf("CLI flag used: %s (yaml: %s)\n", flag, yamlTag)
125133
}
126134
}
127135
}
@@ -134,6 +142,16 @@ func Init() (ret *Flags, err error) {
134142
return
135143
}
136144

145+
// Check to see if a ~/.fabric.yaml config file exists (only when user didn't specify a config)
146+
if ret.Config == "" {
147+
// Default to ~/.fabric.yaml if no config specified
148+
if defaultConfigPath, err := util.GetDefaultConfigPath(); err == nil && defaultConfigPath != "" {
149+
ret.Config = defaultConfigPath
150+
} else if err != nil {
151+
Debugf("Could not determine default config path: %v\n", err)
152+
}
153+
}
154+
137155
// If config specified, load and apply YAML for unused flags
138156
if ret.Config != "" {
139157
var yamlFlags *Flags
@@ -168,7 +186,6 @@ func Init() (ret *Flags, err error) {
168186
}
169187
}
170188

171-
// Handle stdin and messages
172189
// Handle stdin and messages
173190
info, _ := os.Stdin.Stat()
174191
pipedToStdin := (info.Mode() & os.ModeCharDevice) == 0
@@ -188,6 +205,22 @@ func Init() (ret *Flags, err error) {
188205
return
189206
}
190207

208+
func extractFlag(arg string) string {
209+
var flag string
210+
if strings.HasPrefix(arg, "--") {
211+
flag = strings.TrimPrefix(arg, "--")
212+
if i := strings.Index(flag, "="); i > 0 {
213+
flag = flag[:i]
214+
}
215+
} else if strings.HasPrefix(arg, "-") && len(arg) > 1 {
216+
flag = strings.TrimPrefix(arg, "-")
217+
if i := strings.Index(flag, "="); i > 0 {
218+
flag = flag[:i]
219+
}
220+
}
221+
return flag
222+
}
223+
191224
func assignWithConversion(targetField, sourceField reflect.Value) error {
192225
// Handle string source values
193226
if sourceField.Kind() == reflect.String {

internal/core/chatter.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ func (o *Chatter) Send(request *domain.ChatRequest, opts *domain.ChatOptions) (s
103103
}
104104
}
105105

106-
if opts.SuppressThink {
106+
if opts.SuppressThink && !o.DryRun {
107107
message = domain.StripThinkBlocks(message, opts.ThinkStartTag, opts.ThinkEndTag)
108108
}
109109

internal/plugins/ai/dryrun/dryrun.go

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import (
1212
"github.com/danielmiessler/fabric/internal/plugins"
1313
)
1414

15+
const DryRunResponse = "Dry run: Fake response sent by DryRun plugin\n"
16+
1517
type Client struct {
1618
*plugins.PluginBase
1719
}
@@ -85,27 +87,37 @@ func (c *Client) formatOptions(opts *domain.ChatOptions) string {
8587
if opts.ImageFile != "" {
8688
builder.WriteString(fmt.Sprintf("ImageFile: %s\n", opts.ImageFile))
8789
}
90+
if opts.SuppressThink {
91+
builder.WriteString("SuppressThink: enabled\n")
92+
builder.WriteString(fmt.Sprintf("Thinking Start Tag: %s\n", opts.ThinkStartTag))
93+
builder.WriteString(fmt.Sprintf("Thinking End Tag: %s\n", opts.ThinkEndTag))
94+
}
8895

8996
return builder.String()
9097
}
9198

92-
func (c *Client) SendStream(msgs []*chat.ChatCompletionMessage, opts *domain.ChatOptions, channel chan string) error {
99+
func (c *Client) constructRequest(msgs []*chat.ChatCompletionMessage, opts *domain.ChatOptions) string {
93100
var builder strings.Builder
94101
builder.WriteString("Dry run: Would send the following request:\n\n")
95102
builder.WriteString(c.formatMessages(msgs))
96103
builder.WriteString(c.formatOptions(opts))
97104

98-
channel <- builder.String()
99-
close(channel)
105+
return builder.String()
106+
}
107+
108+
func (c *Client) SendStream(msgs []*chat.ChatCompletionMessage, opts *domain.ChatOptions, channel chan string) error {
109+
defer close(channel)
110+
request := c.constructRequest(msgs, opts)
111+
channel <- request
112+
channel <- "\n"
113+
channel <- DryRunResponse
100114
return nil
101115
}
102116

103117
func (c *Client) Send(_ context.Context, msgs []*chat.ChatCompletionMessage, opts *domain.ChatOptions) (string, error) {
104-
fmt.Println("Dry run: Would send the following request:")
105-
fmt.Print(c.formatMessages(msgs))
106-
fmt.Print(c.formatOptions(opts))
118+
request := c.constructRequest(msgs, opts)
107119

108-
return "", nil
120+
return request + "\n" + DryRunResponse, nil
109121
}
110122

111123
func (c *Client) Setup() error {

internal/util/utils.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,21 @@ func IsSymlinkToDir(path string) bool {
7171

7272
return false // Regular directories should not be treated as symlinks
7373
}
74+
75+
// GetDefaultConfigPath returns the default path for the configuration file
76+
// if it exists, otherwise returns an empty string.
77+
func GetDefaultConfigPath() (string, error) {
78+
homeDir, err := os.UserHomeDir()
79+
if err != nil {
80+
return "", fmt.Errorf("could not determine user home directory: %w", err)
81+
}
82+
83+
defaultConfigPath := filepath.Join(homeDir, ".fabric.yaml")
84+
if _, err := os.Stat(defaultConfigPath); err != nil {
85+
if os.IsNotExist(err) {
86+
return "", nil // Return no error for non-existent config path
87+
}
88+
return "", fmt.Errorf("error accessing default config path: %w", err)
89+
}
90+
return defaultConfigPath, nil
91+
}

0 commit comments

Comments
 (0)