configure image generation under tool settings
This commit is contained in:
parent
cd0b4f025e
commit
135f721dfc
6 changed files with 117 additions and 31 deletions
|
|
@ -427,6 +427,10 @@
|
|||
"i2c": {
|
||||
"enabled": false
|
||||
},
|
||||
"image_generate": {
|
||||
"enabled": false,
|
||||
"model": "openai-codex/gpt-image-2"
|
||||
},
|
||||
"install_skill": {
|
||||
"enabled": true
|
||||
},
|
||||
|
|
|
|||
|
|
@ -156,6 +156,30 @@ If `range` is omitted, PicoClaw performs an unrestricted search.
|
|||
}
|
||||
```
|
||||
|
||||
## Image Generation Tool
|
||||
|
||||
The `image_generate` tool creates image files through a provider that supports
|
||||
image generation.
|
||||
|
||||
| Config | Type | Default | Description |
|
||||
|--------|------|---------|-------------|
|
||||
| `enabled` | bool | false | Enable the image generation tool |
|
||||
| `model` | string | `gpt-image-2` | Image generation model. Values may include a provider prefix, for example `openai-codex/gpt-image-2` |
|
||||
|
||||
If `tools.image_generate.model` is not set, PicoClaw falls back to the legacy
|
||||
`agents.defaults.image_model` setting, then to `gpt-image-2`.
|
||||
|
||||
```json
|
||||
{
|
||||
"tools": {
|
||||
"image_generate": {
|
||||
"enabled": true,
|
||||
"model": "openai-codex/gpt-image-2"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Exec Tool
|
||||
|
||||
The exec tool is used to execute shell commands.
|
||||
|
|
|
|||
|
|
@ -216,10 +216,7 @@ func registerSharedTools(
|
|||
}
|
||||
|
||||
if cfg.Tools.IsToolEnabled("image_generate") {
|
||||
imageModel := cfg.Agents.Defaults.ImageModel
|
||||
if imageModel == "" {
|
||||
imageModel = "gpt-image-2"
|
||||
}
|
||||
imageModel := cfg.Tools.ImageGenerate.EffectiveModel(cfg.Agents.Defaults)
|
||||
agent.Tools.Register(tools.NewImageGenerateTool(agent.Workspace, imageModel, nil))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -626,6 +626,21 @@ type ToolConfig struct {
|
|||
Enabled bool `json:"enabled" yaml:"-" env:"ENABLED"`
|
||||
}
|
||||
|
||||
type ImageGenerateToolsConfig struct {
|
||||
ToolConfig `yaml:"-" envPrefix:"PICOCLAW_TOOLS_IMAGE_GENERATE_"`
|
||||
Model string `json:"model,omitempty" yaml:"-" env:"PICOCLAW_TOOLS_IMAGE_GENERATE_MODEL"`
|
||||
}
|
||||
|
||||
func (c ImageGenerateToolsConfig) EffectiveModel(defaults AgentDefaults) string {
|
||||
if model := strings.TrimSpace(c.Model); model != "" {
|
||||
return model
|
||||
}
|
||||
if model := strings.TrimSpace(defaults.ImageModel); model != "" {
|
||||
return model
|
||||
}
|
||||
return "gpt-image-2"
|
||||
}
|
||||
|
||||
type BraveConfig struct {
|
||||
Enabled bool `json:"enabled" yaml:"-" env:"PICOCLAW_TOOLS_WEB_BRAVE_ENABLED"`
|
||||
APIKeys SecureStrings `json:"api_keys,omitzero" yaml:"api_keys,omitempty" env:"PICOCLAW_TOOLS_WEB_BRAVE_API_KEYS"`
|
||||
|
|
@ -816,31 +831,31 @@ type ToolsConfig struct {
|
|||
// FilterMinLength is the minimum content length required for filtering.
|
||||
// Content shorter than this will be returned unchanged for performance.
|
||||
// Default: 8
|
||||
FilterMinLength int `json:"filter_min_length" yaml:"-" env:"PICOCLAW_TOOLS_FILTER_MIN_LENGTH"`
|
||||
Web WebToolsConfig `json:"web" yaml:"web,omitempty"`
|
||||
Cron CronToolsConfig `json:"cron" yaml:"-"`
|
||||
Exec ExecConfig `json:"exec" yaml:"-"`
|
||||
Skills SkillsToolsConfig `json:"skills" yaml:"skills,omitempty"`
|
||||
MediaCleanup MediaCleanupConfig `json:"media_cleanup" yaml:"-"`
|
||||
MCP MCPConfig `json:"mcp" yaml:"-"`
|
||||
AppendFile ToolConfig `json:"append_file" yaml:"-" envPrefix:"PICOCLAW_TOOLS_APPEND_FILE_"`
|
||||
EditFile ToolConfig `json:"edit_file" yaml:"-" envPrefix:"PICOCLAW_TOOLS_EDIT_FILE_"`
|
||||
FindSkills ToolConfig `json:"find_skills" yaml:"-" envPrefix:"PICOCLAW_TOOLS_FIND_SKILLS_"`
|
||||
I2C ToolConfig `json:"i2c" yaml:"-" envPrefix:"PICOCLAW_TOOLS_I2C_"`
|
||||
ImageGenerate ToolConfig `json:"image_generate" yaml:"-" envPrefix:"PICOCLAW_TOOLS_IMAGE_GENERATE_"`
|
||||
InstallSkill ToolConfig `json:"install_skill" yaml:"-" envPrefix:"PICOCLAW_TOOLS_INSTALL_SKILL_"`
|
||||
ListDir ToolConfig `json:"list_dir" yaml:"-" envPrefix:"PICOCLAW_TOOLS_LIST_DIR_"`
|
||||
Message ToolConfig `json:"message" yaml:"-" envPrefix:"PICOCLAW_TOOLS_MESSAGE_"`
|
||||
ReadFile ReadFileToolConfig `json:"read_file" yaml:"-" envPrefix:"PICOCLAW_TOOLS_READ_FILE_"`
|
||||
Serial ToolConfig `json:"serial" yaml:"-" envPrefix:"PICOCLAW_TOOLS_SERIAL_"`
|
||||
SendFile ToolConfig `json:"send_file" yaml:"-" envPrefix:"PICOCLAW_TOOLS_SEND_FILE_"`
|
||||
SendTTS ToolConfig `json:"send_tts" yaml:"-" envPrefix:"PICOCLAW_TOOLS_SEND_TTS_"`
|
||||
Spawn ToolConfig `json:"spawn" yaml:"-" envPrefix:"PICOCLAW_TOOLS_SPAWN_"`
|
||||
SpawnStatus ToolConfig `json:"spawn_status" yaml:"-" envPrefix:"PICOCLAW_TOOLS_SPAWN_STATUS_"`
|
||||
SPI ToolConfig `json:"spi" yaml:"-" envPrefix:"PICOCLAW_TOOLS_SPI_"`
|
||||
Subagent ToolConfig `json:"subagent" yaml:"-" envPrefix:"PICOCLAW_TOOLS_SUBAGENT_"`
|
||||
WebFetch ToolConfig `json:"web_fetch" yaml:"-" envPrefix:"PICOCLAW_TOOLS_WEB_FETCH_"`
|
||||
WriteFile ToolConfig `json:"write_file" yaml:"-" envPrefix:"PICOCLAW_TOOLS_WRITE_FILE_"`
|
||||
FilterMinLength int `json:"filter_min_length" yaml:"-" env:"PICOCLAW_TOOLS_FILTER_MIN_LENGTH"`
|
||||
Web WebToolsConfig `json:"web" yaml:"web,omitempty"`
|
||||
Cron CronToolsConfig `json:"cron" yaml:"-"`
|
||||
Exec ExecConfig `json:"exec" yaml:"-"`
|
||||
Skills SkillsToolsConfig `json:"skills" yaml:"skills,omitempty"`
|
||||
MediaCleanup MediaCleanupConfig `json:"media_cleanup" yaml:"-"`
|
||||
MCP MCPConfig `json:"mcp" yaml:"-"`
|
||||
AppendFile ToolConfig `json:"append_file" yaml:"-" envPrefix:"PICOCLAW_TOOLS_APPEND_FILE_"`
|
||||
EditFile ToolConfig `json:"edit_file" yaml:"-" envPrefix:"PICOCLAW_TOOLS_EDIT_FILE_"`
|
||||
FindSkills ToolConfig `json:"find_skills" yaml:"-" envPrefix:"PICOCLAW_TOOLS_FIND_SKILLS_"`
|
||||
I2C ToolConfig `json:"i2c" yaml:"-" envPrefix:"PICOCLAW_TOOLS_I2C_"`
|
||||
ImageGenerate ImageGenerateToolsConfig `json:"image_generate" yaml:"-"`
|
||||
InstallSkill ToolConfig `json:"install_skill" yaml:"-" envPrefix:"PICOCLAW_TOOLS_INSTALL_SKILL_"`
|
||||
ListDir ToolConfig `json:"list_dir" yaml:"-" envPrefix:"PICOCLAW_TOOLS_LIST_DIR_"`
|
||||
Message ToolConfig `json:"message" yaml:"-" envPrefix:"PICOCLAW_TOOLS_MESSAGE_"`
|
||||
ReadFile ReadFileToolConfig `json:"read_file" yaml:"-" envPrefix:"PICOCLAW_TOOLS_READ_FILE_"`
|
||||
Serial ToolConfig `json:"serial" yaml:"-" envPrefix:"PICOCLAW_TOOLS_SERIAL_"`
|
||||
SendFile ToolConfig `json:"send_file" yaml:"-" envPrefix:"PICOCLAW_TOOLS_SEND_FILE_"`
|
||||
SendTTS ToolConfig `json:"send_tts" yaml:"-" envPrefix:"PICOCLAW_TOOLS_SEND_TTS_"`
|
||||
Spawn ToolConfig `json:"spawn" yaml:"-" envPrefix:"PICOCLAW_TOOLS_SPAWN_"`
|
||||
SpawnStatus ToolConfig `json:"spawn_status" yaml:"-" envPrefix:"PICOCLAW_TOOLS_SPAWN_STATUS_"`
|
||||
SPI ToolConfig `json:"spi" yaml:"-" envPrefix:"PICOCLAW_TOOLS_SPI_"`
|
||||
Subagent ToolConfig `json:"subagent" yaml:"-" envPrefix:"PICOCLAW_TOOLS_SUBAGENT_"`
|
||||
WebFetch ToolConfig `json:"web_fetch" yaml:"-" envPrefix:"PICOCLAW_TOOLS_WEB_FETCH_"`
|
||||
WriteFile ToolConfig `json:"write_file" yaml:"-" envPrefix:"PICOCLAW_TOOLS_WRITE_FILE_"`
|
||||
}
|
||||
|
||||
// IsFilterSensitiveDataEnabled returns true if sensitive data filtering is enabled
|
||||
|
|
|
|||
|
|
@ -195,6 +195,50 @@ func TestLoadConfig_MCPMaxInlineTextChars(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestImageGenerateToolsConfig_EffectiveModel(t *testing.T) {
|
||||
defaults := AgentDefaults{ImageModel: "legacy-image-model"}
|
||||
|
||||
if got := (ImageGenerateToolsConfig{}).EffectiveModel(defaults); got != "legacy-image-model" {
|
||||
t.Fatalf("legacy fallback model = %q, want legacy-image-model", got)
|
||||
}
|
||||
|
||||
cfg := ImageGenerateToolsConfig{Model: "openai-codex/gpt-image-2"}
|
||||
if got := cfg.EffectiveModel(defaults); got != "openai-codex/gpt-image-2" {
|
||||
t.Fatalf("tool model = %q, want openai-codex/gpt-image-2", got)
|
||||
}
|
||||
|
||||
if got := (ImageGenerateToolsConfig{}).EffectiveModel(AgentDefaults{}); got != "gpt-image-2" {
|
||||
t.Fatalf("default model = %q, want gpt-image-2", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestLoadConfig_ImageGenerateModel(t *testing.T) {
|
||||
dir := t.TempDir()
|
||||
configPath := filepath.Join(dir, "config.json")
|
||||
raw := `{
|
||||
"tools": {
|
||||
"image_generate": {
|
||||
"enabled": true,
|
||||
"model": "openai-codex/gpt-image-2"
|
||||
}
|
||||
}
|
||||
}`
|
||||
if err := os.WriteFile(configPath, []byte(raw), 0o644); err != nil {
|
||||
t.Fatalf("WriteFile(configPath): %v", err)
|
||||
}
|
||||
|
||||
cfg, err := LoadConfig(configPath)
|
||||
if err != nil {
|
||||
t.Fatalf("LoadConfig() error: %v", err)
|
||||
}
|
||||
if !cfg.Tools.ImageGenerate.Enabled {
|
||||
t.Fatal("cfg.Tools.ImageGenerate.Enabled should be true")
|
||||
}
|
||||
if got := cfg.Tools.ImageGenerate.Model; got != "openai-codex/gpt-image-2" {
|
||||
t.Fatalf("cfg.Tools.ImageGenerate.Model = %q, want openai-codex/gpt-image-2", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestConfig_BackwardCompat_NoAgentsList(t *testing.T) {
|
||||
jsonData := `{
|
||||
"agents": {
|
||||
|
|
|
|||
|
|
@ -397,8 +397,10 @@ func DefaultConfig() *Config {
|
|||
SendFile: ToolConfig{
|
||||
Enabled: true,
|
||||
},
|
||||
ImageGenerate: ToolConfig{
|
||||
Enabled: false,
|
||||
ImageGenerate: ImageGenerateToolsConfig{
|
||||
ToolConfig: ToolConfig{
|
||||
Enabled: false,
|
||||
},
|
||||
},
|
||||
SendTTS: ToolConfig{
|
||||
Enabled: false,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue