Merge branch 'main' into fix-config-model-list-override-13448010885405533147

This commit is contained in:
Nhat Tan 2026-03-27 10:44:41 +07:00 committed by GitHub
commit 3db3bf879c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 64 additions and 10 deletions

View file

@ -223,6 +223,25 @@ install: build
@echo "Installed uninstaller script to $(INSTALL_BIN_DIR)/$(BINARY_NAME)-uninstall"
@echo "Installation complete!"
## install-pico: Build core, web and install picoclaw and picoclaw-launcher to system
install-pico: build build-launcher
@echo "Installing $(BINARY_NAME) and picoclaw-launcher..."
@mkdir -p $(INSTALL_BIN_DIR)
# Copy core binary with temporary suffix to ensure atomic update
@cp $(BUILD_DIR)/$(BINARY_NAME) $(INSTALL_BIN_DIR)/$(BINARY_NAME)$(INSTALL_TMP_SUFFIX)
@chmod +x $(INSTALL_BIN_DIR)/$(BINARY_NAME)$(INSTALL_TMP_SUFFIX)
@mv -f $(INSTALL_BIN_DIR)/$(BINARY_NAME)$(INSTALL_TMP_SUFFIX) $(INSTALL_BIN_DIR)/$(BINARY_NAME)
@echo "Installed binary to $(INSTALL_BIN_DIR)/$(BINARY_NAME)"
# Copy launcher binary with temporary suffix
@cp $(BUILD_DIR)/picoclaw-launcher $(INSTALL_BIN_DIR)/picoclaw-launcher$(INSTALL_TMP_SUFFIX)
@chmod +x $(INSTALL_BIN_DIR)/picoclaw-launcher$(INSTALL_TMP_SUFFIX)
@mv -f $(INSTALL_BIN_DIR)/picoclaw-launcher$(INSTALL_TMP_SUFFIX) $(INSTALL_BIN_DIR)/picoclaw-launcher
@echo "Installed launcher to $(INSTALL_BIN_DIR)/picoclaw-launcher"
@cp scripts/uninstall.sh $(INSTALL_BIN_DIR)/$(BINARY_NAME)-uninstall
@chmod +x $(INSTALL_BIN_DIR)/$(BINARY_NAME)-uninstall
@echo "Installed uninstaller script to $(INSTALL_BIN_DIR)/$(BINARY_NAME)-uninstall"
@echo "Installation complete!"
## uninstall: Remove picoclaw from system
uninstall:
@echo "Uninstalling $(BINARY_NAME)..."

View file

@ -1279,7 +1279,10 @@ func LoadConfig(path string) (*Config, error) {
data, err := os.ReadFile(path)
if err != nil {
if os.IsNotExist(err) {
logger.WarnF("config file not found, using default config", map[string]any{"path": path})
logger.WarnF(
"config file not found, using default config",
map[string]any{"path": path},
)
return DefaultConfig(), nil
}
logger.Errorf("failed to read config file: %v", err)
@ -1302,7 +1305,10 @@ func LoadConfig(path string) (*Config, error) {
var cfg *Config
switch versionInfo.Version {
case 0:
logger.InfoF("config migrate start", map[string]any{"from": versionInfo.Version, "to": CurrentVersion})
logger.InfoF(
"config migrate start",
map[string]any{"from": versionInfo.Version, "to": CurrentVersion},
)
// Legacy config (no version field)
v, e := loadConfigV0(data)
if e != nil {
@ -1310,10 +1316,16 @@ func LoadConfig(path string) (*Config, error) {
}
cfg, e = v.Migrate()
if e != nil {
logger.ErrorF("config migrate fail", map[string]any{"from": versionInfo.Version, "to": CurrentVersion})
logger.ErrorF(
"config migrate fail",
map[string]any{"from": versionInfo.Version, "to": CurrentVersion},
)
return nil, e
}
logger.InfoF("config migrate success", map[string]any{"from": versionInfo.Version, "to": CurrentVersion})
logger.InfoF(
"config migrate success",
map[string]any{"from": versionInfo.Version, "to": CurrentVersion},
)
err = makeBackup(path)
if err != nil {
return nil, err
@ -1321,13 +1333,19 @@ func LoadConfig(path string) (*Config, error) {
// Load existing security config and merge with migrated one to prevent data loss
existingSec, secErr := loadSecurityConfig(securityPath(path))
if secErr != nil {
logger.WarnF("failed to load existing security config during migration", map[string]any{"error": secErr})
logger.WarnF(
"failed to load existing security config during migration",
map[string]any{"error": secErr},
)
}
if existingSec != nil && cfg.security != nil {
cfg.security = mergeSecurityConfig(existingSec, cfg.security)
// Re-apply the merged security config to update all channels and models
if err = applySecurityConfig(cfg, cfg.security); err != nil {
logger.WarnF("failed to re-apply merged security config during migration", map[string]any{"error": err})
logger.WarnF(
"failed to re-apply merged security config during migration",
map[string]any{"error": err},
)
}
}
defer func(cfg *Config) {
@ -1348,7 +1366,10 @@ func LoadConfig(path string) (*Config, error) {
tmpCfgMigrated, e := tmpCfg.Migrate()
if e != nil {
logger.ErrorF("config migrate fail", map[string]any{"from": versionInfo.Version, "to": CurrentVersion})
logger.ErrorF(
"config migrate fail",
map[string]any{"from": versionInfo.Version, "to": CurrentVersion},
)
return nil, e
}
@ -1371,9 +1392,11 @@ func LoadConfig(path string) (*Config, error) {
for _, m := range cfg.ModelList {
for _, k := range m.apiKeys {
if k != "" && !strings.HasPrefix(k, "enc://") && !strings.HasPrefix(k, "file://") {
fmt.Fprintf(os.Stderr,
fmt.Fprintf(
os.Stderr,
"picoclaw: warning: model %q has a plaintext api_key; call SaveConfig to encrypt it\n",
m.ModelName)
m.ModelName,
)
break // Only warn once per model
}
}

View file

@ -445,7 +445,11 @@ func (p *Provider) ChatStream(
if part.FunctionCall != nil {
argsJSON, _ := json.Marshal(part.FunctionCall.Args)
toolCall := ToolCall{
ID: fmt.Sprintf("call_%s_%d", part.FunctionCall.Name, time.Now().UnixNano()),
ID: fmt.Sprintf(
"call_%s_%d",
part.FunctionCall.Name,
time.Now().UnixNano(),
),
Name: part.FunctionCall.Name,
Arguments: part.FunctionCall.Args,
Function: &FunctionCall{

View file

@ -20,6 +20,14 @@ else
echo "Executable ${INSTALL_BIN_DIR}/${BINARY_NAME} not found. Skipping."
fi
# Remove the launcher binary
if [ -f "${INSTALL_BIN_DIR}/picoclaw-launcher" ]; then
rm -f "${INSTALL_BIN_DIR}/picoclaw-launcher"
echo "Removed executable: ${INSTALL_BIN_DIR}/picoclaw-launcher"
else
echo "Executable ${INSTALL_BIN_DIR}/picoclaw-launcher not found. Skipping."
fi
# Remove the workspace and configurations
if [ -d "${PICOCLAW_HOME}" ]; then
rm -rf "${PICOCLAW_HOME}"