fix(deploy): remove hardcoded docker env defaults and dynamic model list
This commit is contained in:
parent
79497a13c1
commit
55c2a0f9d1
3 changed files with 41 additions and 64 deletions
|
|
@ -34,10 +34,8 @@ RUN /usr/local/bin/picoclaw onboard
|
||||||
COPY entrypoint-coolify.sh /usr/local/bin/entrypoint-coolify.sh
|
COPY entrypoint-coolify.sh /usr/local/bin/entrypoint-coolify.sh
|
||||||
RUN chmod +x /usr/local/bin/entrypoint-coolify.sh
|
RUN chmod +x /usr/local/bin/entrypoint-coolify.sh
|
||||||
|
|
||||||
# Default env vars (overridden by Coolify)
|
# Default env vars (can be overridden by Coolify)
|
||||||
ENV PICOCLAW_AGENTS_DEFAULTS_PROVIDER="gemini"
|
ENV TZ=UTC
|
||||||
ENV PICOCLAW_AGENTS_DEFAULTS_MODEL="gemini-2.5-flash-lite"
|
|
||||||
ENV PICOCLAW_PROVIDERS_GEMINI_API_KEY=""
|
|
||||||
|
|
||||||
ENTRYPOINT ["/usr/local/bin/entrypoint-coolify.sh"]
|
ENTRYPOINT ["/usr/local/bin/entrypoint-coolify.sh"]
|
||||||
CMD ["gateway"]
|
CMD ["gateway"]
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"sync/atomic"
|
"sync/atomic"
|
||||||
|
|
@ -217,65 +218,43 @@ func (al *AgentLoop) listModelsResponse() string {
|
||||||
sb.WriteString(fmt.Sprintf("**Active model:** `%s`\n", al.model))
|
sb.WriteString(fmt.Sprintf("**Active model:** `%s`\n", al.model))
|
||||||
sb.WriteString(fmt.Sprintf("**Active provider:** `%s`\n\n", al.cfg.Agents.Defaults.Provider))
|
sb.WriteString(fmt.Sprintf("**Active provider:** `%s`\n\n", al.cfg.Agents.Defaults.Provider))
|
||||||
|
|
||||||
// List all configured providers
|
sb.WriteString("**Configured providers:**\n")
|
||||||
type providerEntry struct {
|
|
||||||
Name string
|
// Use reflection to iterate over Config.Providers fields
|
||||||
APIBase string
|
v := reflect.ValueOf(al.cfg.Providers)
|
||||||
}
|
t := v.Type()
|
||||||
providersList := []providerEntry{
|
|
||||||
{"gemini", al.cfg.Providers.Gemini.APIBase},
|
|
||||||
{"openrouter", al.cfg.Providers.OpenRouter.APIBase},
|
|
||||||
{"openai", al.cfg.Providers.OpenAI.APIBase},
|
|
||||||
{"anthropic", al.cfg.Providers.Anthropic.APIBase},
|
|
||||||
{"vllm", al.cfg.Providers.VLLM.APIBase},
|
|
||||||
{"groq", al.cfg.Providers.Groq.APIBase},
|
|
||||||
{"deepseek", al.cfg.Providers.DeepSeek.APIBase},
|
|
||||||
{"nvidia", al.cfg.Providers.Nvidia.APIBase},
|
|
||||||
{"moonshot", al.cfg.Providers.Moonshot.APIBase},
|
|
||||||
{"zhipu", al.cfg.Providers.Zhipu.APIBase},
|
|
||||||
}
|
|
||||||
|
|
||||||
hasConfigured := false
|
hasConfigured := false
|
||||||
for _, p := range providersList {
|
for i := 0; i < v.NumField(); i++ {
|
||||||
// Show providers that have either an API key or API base configured
|
field := v.Field(i)
|
||||||
hasKey := false
|
fieldName := strings.ToLower(t.Field(i).Name)
|
||||||
switch p.Name {
|
|
||||||
case "gemini":
|
// Provider name from json tag if available
|
||||||
hasKey = al.cfg.Providers.Gemini.APIKey != ""
|
jsonTag := t.Field(i).Tag.Get("json")
|
||||||
case "openrouter":
|
if jsonTag != "" {
|
||||||
hasKey = al.cfg.Providers.OpenRouter.APIKey != ""
|
fieldName = strings.Split(jsonTag, ",")[0]
|
||||||
case "openai":
|
|
||||||
hasKey = al.cfg.Providers.OpenAI.APIKey != ""
|
|
||||||
case "anthropic":
|
|
||||||
hasKey = al.cfg.Providers.Anthropic.APIKey != ""
|
|
||||||
case "vllm":
|
|
||||||
hasKey = al.cfg.Providers.VLLM.APIKey != "" || al.cfg.Providers.VLLM.APIBase != ""
|
|
||||||
case "groq":
|
|
||||||
hasKey = al.cfg.Providers.Groq.APIKey != ""
|
|
||||||
case "deepseek":
|
|
||||||
hasKey = al.cfg.Providers.DeepSeek.APIKey != ""
|
|
||||||
case "nvidia":
|
|
||||||
hasKey = al.cfg.Providers.Nvidia.APIKey != ""
|
|
||||||
case "moonshot":
|
|
||||||
hasKey = al.cfg.Providers.Moonshot.APIKey != ""
|
|
||||||
case "zhipu":
|
|
||||||
hasKey = al.cfg.Providers.Zhipu.APIKey != ""
|
|
||||||
}
|
|
||||||
if hasKey {
|
|
||||||
if !hasConfigured {
|
|
||||||
sb.WriteString("**Configured providers:**\n")
|
|
||||||
hasConfigured = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if provider has API key or Base URL
|
||||||
|
apiKey := field.FieldByName("APIKey").String()
|
||||||
|
apiBase := field.FieldByName("APIBase").String()
|
||||||
|
|
||||||
|
if apiKey != "" || apiBase != "" {
|
||||||
active := ""
|
active := ""
|
||||||
if p.Name == al.cfg.Agents.Defaults.Provider {
|
if fieldName == al.cfg.Agents.Defaults.Provider {
|
||||||
active = " ✅"
|
active = " ✅"
|
||||||
}
|
}
|
||||||
if p.APIBase != "" {
|
if apiBase != "" {
|
||||||
sb.WriteString(fmt.Sprintf("- `%s` → %s%s\n", p.Name, p.APIBase, active))
|
sb.WriteString(fmt.Sprintf("- `%s` → %s%s\n", fieldName, apiBase, active))
|
||||||
} else {
|
} else {
|
||||||
sb.WriteString(fmt.Sprintf("- `%s`%s\n", p.Name, active))
|
sb.WriteString(fmt.Sprintf("- `%s`%s\n", fieldName, active))
|
||||||
|
}
|
||||||
|
hasConfigured = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !hasConfigured {
|
||||||
|
sb.WriteString("_None configured_\n")
|
||||||
}
|
}
|
||||||
|
|
||||||
sb.WriteString("\n_Usage: `/model <name>` or `/model <provider>/<model>`_")
|
sb.WriteString("\n_Usage: `/model <name>` or `/model <provider>/<model>`_")
|
||||||
|
|
|
||||||
|
|
@ -31,14 +31,14 @@ type TelegramChannel struct {
|
||||||
config *config.Config
|
config *config.Config
|
||||||
chatIDs map[string]int64
|
chatIDs map[string]int64
|
||||||
transcriber *voice.GroqTranscriber
|
transcriber *voice.GroqTranscriber
|
||||||
stopThinking sync.Map // chatID -> typingCancel
|
typingTasks sync.Map // chatID -> *typingTask
|
||||||
}
|
}
|
||||||
|
|
||||||
type thinkingCancel struct {
|
type typingTask struct {
|
||||||
fn context.CancelFunc
|
fn context.CancelFunc
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *thinkingCancel) Cancel() {
|
func (c *typingTask) Cancel() {
|
||||||
if c != nil && c.fn != nil {
|
if c != nil && c.fn != nil {
|
||||||
c.fn()
|
c.fn()
|
||||||
}
|
}
|
||||||
|
|
@ -74,7 +74,7 @@ func NewTelegramChannel(cfg *config.Config, bus *bus.MessageBus) (*TelegramChann
|
||||||
config: cfg,
|
config: cfg,
|
||||||
chatIDs: make(map[string]int64),
|
chatIDs: make(map[string]int64),
|
||||||
transcriber: nil,
|
transcriber: nil,
|
||||||
stopThinking: sync.Map{},
|
typingTasks: sync.Map{},
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -149,11 +149,11 @@ func (c *TelegramChannel) Send(ctx context.Context, msg bus.OutboundMessage) err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Stop typing indicator goroutine
|
// Stop typing indicator goroutine
|
||||||
if stop, ok := c.stopThinking.Load(msg.ChatID); ok {
|
if stop, ok := c.typingTasks.Load(msg.ChatID); ok {
|
||||||
if cf, ok := stop.(*thinkingCancel); ok && cf != nil {
|
if cf, ok := stop.(*typingTask); ok && cf != nil {
|
||||||
cf.Cancel()
|
cf.Cancel()
|
||||||
}
|
}
|
||||||
c.stopThinking.Delete(msg.ChatID)
|
c.typingTasks.Delete(msg.ChatID)
|
||||||
}
|
}
|
||||||
|
|
||||||
htmlContent := markdownToTelegramHTML(msg.Content)
|
htmlContent := markdownToTelegramHTML(msg.Content)
|
||||||
|
|
@ -312,13 +312,13 @@ func (c *TelegramChannel) handleMessage(ctx context.Context, message *telego.Mes
|
||||||
// so we re-send every 4s until the response arrives)
|
// so we re-send every 4s until the response arrives)
|
||||||
chatIDStr := fmt.Sprintf("%d", chatID)
|
chatIDStr := fmt.Sprintf("%d", chatID)
|
||||||
// Cancel any previous typing goroutine for this chat
|
// Cancel any previous typing goroutine for this chat
|
||||||
if prevStop, ok := c.stopThinking.Load(chatIDStr); ok {
|
if prevStop, ok := c.typingTasks.Load(chatIDStr); ok {
|
||||||
if cf, ok := prevStop.(*thinkingCancel); ok && cf != nil {
|
if cf, ok := prevStop.(*typingTask); ok && cf != nil {
|
||||||
cf.Cancel()
|
cf.Cancel()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
typingCtx, typingCancel := context.WithCancel(ctx)
|
typingCtx, typingCancel := context.WithCancel(ctx)
|
||||||
c.stopThinking.Store(chatIDStr, &thinkingCancel{fn: typingCancel})
|
c.typingTasks.Store(chatIDStr, &typingTask{fn: typingCancel})
|
||||||
go func() {
|
go func() {
|
||||||
ticker := time.NewTicker(4 * time.Second)
|
ticker := time.NewTicker(4 * time.Second)
|
||||||
defer ticker.Stop()
|
defer ticker.Stop()
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue