feat: add image generation model and generate_image agent tool

Bots can now be configured with an image generation model (must have
image-output compatibility). When set, the agent exposes a generate_image
tool that calls the model via Twilight AI SDK, saves the result to the
bot container filesystem, and returns the file path.

- Add image_model_id column to bots table (migration 0053)
- Update settings SQL queries, service, and types
- New ImageGenProvider tool provider in internal/agent/tools/
- Wire provider in both cmd/agent and cmd/memoh entry points
- Add image model selector to frontend bot settings with compat filtering
- Regenerate swagger, SDK types, and sqlc code
This commit is contained in:
Acbox
2026-04-03 01:15:57 +08:00
parent 7ce1306505
commit a9a9f7e955
19 changed files with 294 additions and 6 deletions
+15
View File
@@ -131,6 +131,14 @@ func (s *Service) UpsertBot(ctx context.Context, botID string, req UpsertRequest
}
titleModelUUID = modelID
}
imageModelUUID := pgtype.UUID{}
if value := strings.TrimSpace(req.ImageModelID); value != "" {
modelID, err := s.resolveModelUUID(ctx, value)
if err != nil {
return Settings{}, err
}
imageModelUUID = modelID
}
searchProviderUUID := pgtype.UUID{}
if value := strings.TrimSpace(req.SearchProviderID); value != "" {
providerID, err := db.ParseUUID(value)
@@ -178,6 +186,7 @@ func (s *Service) UpsertBot(ctx context.Context, botID string, req UpsertRequest
HeartbeatModelID: heartbeatModelUUID,
CompactionModelID: compactionModelUUID,
TitleModelID: titleModelUUID,
ImageModelID: imageModelUUID,
SearchProviderID: searchProviderUUID,
MemoryProviderID: memoryProviderUUID,
TtsModelID: ttsModelUUID,
@@ -269,6 +278,7 @@ func normalizeBotSettingsReadRow(row sqlc.GetSettingsByBotIDRow) Settings {
row.HeartbeatModelID,
row.CompactionModelID,
row.TitleModelID,
row.ImageModelID,
row.SearchProviderID,
row.MemoryProviderID,
row.TtsModelID,
@@ -290,6 +300,7 @@ func normalizeBotSettingsWriteRow(row sqlc.UpsertBotSettingsRow) Settings {
row.HeartbeatModelID,
row.CompactionModelID,
row.TitleModelID,
row.ImageModelID,
row.SearchProviderID,
row.MemoryProviderID,
row.TtsModelID,
@@ -310,6 +321,7 @@ func normalizeBotSettingsFields(
heartbeatModelID pgtype.UUID,
compactionModelID pgtype.UUID,
titleModelID pgtype.UUID,
imageModelID pgtype.UUID,
searchProviderID pgtype.UUID,
memoryProviderID pgtype.UUID,
ttsModelID pgtype.UUID,
@@ -328,6 +340,9 @@ func normalizeBotSettingsFields(
if titleModelID.Valid {
settings.TitleModelID = uuid.UUID(titleModelID.Bytes).String()
}
if imageModelID.Valid {
settings.ImageModelID = uuid.UUID(imageModelID.Bytes).String()
}
if searchProviderID.Valid {
settings.SearchProviderID = uuid.UUID(searchProviderID.Bytes).String()
}