Skip to content

Commit bf4a5ff

Browse files
feat: Add system prompt configuration support (#26)
This PR implements system prompt configuration for the Inference Gateway CLI as requested in issue #25. ## Changes - Add `system_prompt` field to ChatConfig in config structure - Implement `infer config set-system` command for setting system prompts - Update chat service to include system prompt in API messages - Modify service container to pass system prompt to chat service - Update documentation with new command and configuration examples ## Usage ```bash # Set a system prompt infer config set-system "You are a helpful assistant." # The system prompt is now included with every chat session infer chat ``` The system prompt is configurable via command or by modifying the config directly and is included in SDK messages as a system prompt. Resolves #25 Generated with [Claude Code](https://claude.ai/code) --------- Signed-off-by: Eden Reich <[email protected]> Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com> Co-authored-by: Eden Reich <[email protected]>
1 parent 217c425 commit bf4a5ff

File tree

6 files changed

+66
-3
lines changed

6 files changed

+66
-3
lines changed

.infer/config.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,4 @@ compact:
3131
output_dir: .infer
3232
chat:
3333
default_model: ""
34+
system_prompt: ""

CLAUDE.md

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ compact:
159159
output_dir: ".infer" # Directory for compact command exports (default: project root/.infer)
160160
chat:
161161
default_model: "" # Default model for chat sessions (when set, skips model selection)
162+
system_prompt: "" # System prompt included with every chat session
162163
```
163164
164165
### Command Structure
@@ -170,6 +171,7 @@ chat:
170171
- `config`: Manage CLI configuration
171172
- `init [--overwrite]`: Initialize local project configuration
172173
- `set-model [MODEL_NAME]`: Set default model for chat sessions
174+
- `set-system [SYSTEM_PROMPT]`: Set system prompt for chat sessions
173175
- `tools`: Manage tool execution settings
174176
- `enable`: Enable tool execution for LLMs
175177
- `disable`: Disable tool execution for LLMs
@@ -212,6 +214,16 @@ infer config set-model gpt-4-turbo
212214
infer chat
213215
```
214216

217+
### Setting a System Prompt
218+
```bash
219+
# Set a system prompt for chat sessions
220+
infer config set-system "You are a helpful assistant."
221+
222+
# The system prompt will now be included with every chat session
223+
# providing context and instructions to the AI model
224+
infer chat
225+
```
226+
215227
### Configuration Management
216228
```bash
217229
# Initialize a new project configuration
@@ -223,9 +235,10 @@ infer config init --overwrite
223235
# View current configuration (check .infer/config.yaml)
224236
cat .infer/config.yaml
225237
226-
# The default model will be saved in the chat section:
238+
# The default model and system prompt will be saved in the chat section:
227239
# chat:
228240
# default_model: "gpt-4-turbo"
241+
# system_prompt: "You are a helpful assistant."
229242
```
230243

231244
### Tool Management

cmd/config.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,18 @@ the chat command will skip the model selection view and use the configured model
3131
},
3232
}
3333

34+
var setSystemCmd = &cobra.Command{
35+
Use: "set-system [SYSTEM_PROMPT]",
36+
Short: "Set the system prompt for chat sessions",
37+
Long: `Set the system prompt that will be included with every chat session.
38+
The system prompt provides context and instructions to the AI model about how to behave.`,
39+
Args: cobra.ExactArgs(1),
40+
RunE: func(cmd *cobra.Command, args []string) error {
41+
systemPrompt := args[0]
42+
return setSystemPrompt(systemPrompt)
43+
},
44+
}
45+
3446
var configInitCmd = &cobra.Command{
3547
Use: "init",
3648
Short: "Initialize a new project configuration",
@@ -176,8 +188,27 @@ func setDefaultModel(modelName string) error {
176188
return nil
177189
}
178190

191+
func setSystemPrompt(systemPrompt string) error {
192+
cfg, err := config.LoadConfig("")
193+
if err != nil {
194+
return fmt.Errorf("failed to load config: %w", err)
195+
}
196+
197+
cfg.Chat.SystemPrompt = systemPrompt
198+
199+
if err := cfg.SaveConfig(""); err != nil {
200+
return fmt.Errorf("failed to save config: %w", err)
201+
}
202+
203+
fmt.Printf("✅ System prompt set successfully\n")
204+
fmt.Printf("System prompt: %s\n", systemPrompt)
205+
fmt.Println("This prompt will be included with every chat session.")
206+
return nil
207+
}
208+
179209
func init() {
180210
configCmd.AddCommand(setModelCmd)
211+
configCmd.AddCommand(setSystemCmd)
181212
configCmd.AddCommand(configInitCmd)
182213
configCmd.AddCommand(configToolsCmd)
183214

config/config.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ type CompactConfig struct {
5959
// ChatConfig contains chat-related settings
6060
type ChatConfig struct {
6161
DefaultModel string `yaml:"default_model"`
62+
SystemPrompt string `yaml:"system_prompt"`
6263
}
6364

6465
// DefaultConfig returns a default configuration
@@ -100,6 +101,7 @@ func DefaultConfig() *Config {
100101
},
101102
Chat: ChatConfig{
102103
DefaultModel: "",
104+
SystemPrompt: "",
103105
},
104106
}
105107
}

internal/container/container.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ func (c *ServiceContainer) initializeDomainServices() {
6868
c.config.Gateway.APIKey,
6969
c.config.Gateway.Timeout,
7070
c.toolService,
71+
c.config.Chat.SystemPrompt,
7172
)
7273
}
7374

internal/services/chat.go

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ type StreamingChatService struct {
2020
timeoutSeconds int
2121
client sdk.Client
2222
toolService domain.ToolService
23+
systemPrompt string
2324

2425
// Request tracking
2526
activeRequests map[string]context.CancelFunc
@@ -31,7 +32,7 @@ type StreamingChatService struct {
3132
}
3233

3334
// NewStreamingChatService creates a new streaming chat service
34-
func NewStreamingChatService(baseURL, apiKey string, timeoutSeconds int, toolService domain.ToolService) *StreamingChatService {
35+
func NewStreamingChatService(baseURL, apiKey string, timeoutSeconds int, toolService domain.ToolService, systemPrompt string) *StreamingChatService {
3536
if !strings.HasSuffix(baseURL, "/v1") {
3637
baseURL = strings.TrimSuffix(baseURL, "/") + "/v1"
3738
}
@@ -47,6 +48,7 @@ func NewStreamingChatService(baseURL, apiKey string, timeoutSeconds int, toolSer
4748
timeoutSeconds: timeoutSeconds,
4849
client: client,
4950
toolService: toolService,
51+
systemPrompt: systemPrompt,
5052
activeRequests: make(map[string]context.CancelFunc),
5153
metrics: make(map[string]*domain.ChatMetrics),
5254
}
@@ -78,13 +80,26 @@ func (s *StreamingChatService) validateSendMessageParams(model string, messages
7880
}
7981

8082
func (s *StreamingChatService) addToolsIfAvailable(messages []sdk.Message) []sdk.Message {
83+
var systemMessages []sdk.Message
84+
85+
if s.systemPrompt != "" {
86+
systemMessages = append(systemMessages, sdk.Message{
87+
Role: sdk.System,
88+
Content: s.systemPrompt,
89+
})
90+
}
91+
8192
if s.toolService != nil {
8293
availableTools := s.toolService.ListTools()
8394
if len(availableTools) > 0 {
8495
toolsMessage := s.createToolsSystemMessage(availableTools)
85-
messages = append([]sdk.Message{toolsMessage}, messages...)
96+
systemMessages = append(systemMessages, toolsMessage)
8697
}
8798
}
99+
100+
if len(systemMessages) > 0 {
101+
messages = append(systemMessages, messages...)
102+
}
88103
return messages
89104
}
90105

0 commit comments

Comments
 (0)