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