mirror of
https://gitcode.com/JianFeeeee/homeagent-sdk.git
synced 2026-09-20 00:48:12 +00:00
fix: use short config keys in RegisterDef, remove generics helpers
- qq, a2a, bili, files, rss: RegisterDef keys changed from
namespaced (e.g. "plugin.qq.listen") to short flat keys ("listen")
- a2a, bili: Get() calls updated to match short keys
- rss: replaced readCfg generics with getSetting, added SetAutoRestart(true)
- files: already uses short key Get, only RegisterDef needed fixing
This commit is contained in:
@ -28,7 +28,7 @@ func (p *Plugin) Start(s *sdk.PluginSDK) error {
|
||||
tp := p.name + "_"
|
||||
|
||||
s.Settings().RegisterDef(sdk.ConfigDef{
|
||||
Key: "plugin." + p.name + ".listen", Default: "127.0.0.1:12000",
|
||||
Key: "listen", Default: "127.0.0.1:12000",
|
||||
Type: "string", DisplayName: "监听地址",
|
||||
Description: "A2A 服务端监听地址,设为空可禁用 HTTP 服务",
|
||||
Category: p.name,
|
||||
@ -60,7 +60,7 @@ func (p *Plugin) Start(s *sdk.PluginSDK) error {
|
||||
}, p.handleA2ADiscover)
|
||||
|
||||
// Inbound HTTP server
|
||||
if addr, _ := s.Settings().Get("plugin." + p.name + ".listen"); addr != nil {
|
||||
if addr, _ := s.Settings().Get("listen"); addr != nil {
|
||||
if addrStr, ok := addr.(string); ok && addrStr != "" {
|
||||
p.startServer(addrStr)
|
||||
}
|
||||
|
||||
@ -29,50 +29,48 @@ func NewPlugin(name string, config map[string]interface{}) (sdk.Plugin, error) {
|
||||
|
||||
func (p *Plugin) Name() string { return p.name }
|
||||
|
||||
func readCfg[T string | int64 | float64](s sdk.SettingsAPI, key string, fallback T) T {
|
||||
func getSetting[T string | int64 | float64](s sdk.SettingsAPI, key string, def T) T {
|
||||
v, err := s.Get(key)
|
||||
if err == nil && v != nil {
|
||||
if sv, ok := v.(string); ok && sv != "" {
|
||||
switch any(fallback).(type) {
|
||||
case string:
|
||||
return any(sv).(T)
|
||||
case int64:
|
||||
if n, err := strconv.ParseInt(sv, 10, 64); err == nil {
|
||||
return any(n).(T)
|
||||
}
|
||||
case float64:
|
||||
if n, err := strconv.ParseFloat(sv, 64); err == nil {
|
||||
return any(n).(T)
|
||||
}
|
||||
if err != nil || v == nil {
|
||||
return def
|
||||
}
|
||||
switch any(def).(type) {
|
||||
case string:
|
||||
if sv, ok := v.(string); ok {
|
||||
return any(sv).(T)
|
||||
}
|
||||
case int64:
|
||||
switch n := v.(type) {
|
||||
case float64:
|
||||
return any(int64(n)).(T)
|
||||
case int64:
|
||||
return any(n).(T)
|
||||
case string:
|
||||
if i, err := strconv.ParseInt(n, 10, 64); err == nil {
|
||||
return any(i).(T)
|
||||
}
|
||||
}
|
||||
case float64:
|
||||
switch n := v.(type) {
|
||||
case float64:
|
||||
return any(n).(T)
|
||||
case int64:
|
||||
return any(float64(n)).(T)
|
||||
case string:
|
||||
if f, err := strconv.ParseFloat(n, 64); err == nil {
|
||||
return any(f).(T)
|
||||
}
|
||||
}
|
||||
}
|
||||
v2, err2 := s.GetCore("plugin." + "ai_image" + "." + key)
|
||||
if err2 == nil && v2 != nil {
|
||||
if sv, ok := v2.(string); ok && sv != "" {
|
||||
switch any(fallback).(type) {
|
||||
case string:
|
||||
return any(sv).(T)
|
||||
case int64:
|
||||
if n, err := strconv.ParseInt(sv, 10, 64); err == nil {
|
||||
return any(n).(T)
|
||||
}
|
||||
case float64:
|
||||
if n, err := strconv.ParseFloat(sv, 64); err == nil {
|
||||
return any(n).(T)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return fallback
|
||||
return def
|
||||
}
|
||||
|
||||
func readArg[T string | int64 | float64](args map[string]interface{}, key string, fallback T) T {
|
||||
func getArg[T string | int64 | float64](args map[string]interface{}, key string, def T) T {
|
||||
v, ok := args[key]
|
||||
if !ok || v == nil {
|
||||
return fallback
|
||||
return def
|
||||
}
|
||||
switch any(fallback).(type) {
|
||||
switch any(def).(type) {
|
||||
case string:
|
||||
if s, ok := v.(string); ok {
|
||||
return any(s).(T)
|
||||
@ -100,40 +98,40 @@ func readArg[T string | int64 | float64](args map[string]interface{}, key string
|
||||
}
|
||||
}
|
||||
}
|
||||
return fallback
|
||||
return def
|
||||
}
|
||||
|
||||
func (p *Plugin) Start(s *sdk.PluginSDK) error {
|
||||
s.SetAutoRestart(true)
|
||||
p.sdk = s
|
||||
|
||||
p.apiKey = readCfg(s.Settings(), "api_key", "")
|
||||
p.provider = readCfg(s.Settings(), "provider", "openai")
|
||||
p.model = readCfg(s.Settings(), "model", "dall-e-3")
|
||||
p.size = readCfg(s.Settings(), "size", "1024x1024")
|
||||
|
||||
p.client = &http.Client{Timeout: 120 * time.Second}
|
||||
|
||||
s.Settings().RegisterDef(sdk.ConfigDef{
|
||||
Key: "plugin.ai_image.api_key", Default: "", Type: "string",
|
||||
Key: "api_key", Default: "", Type: "string",
|
||||
DisplayName: "API Key", Description: "OpenAI / Stable Diffusion API Key",
|
||||
Category: "ai_image", Secret: true,
|
||||
})
|
||||
s.Settings().RegisterDef(sdk.ConfigDef{
|
||||
Key: "plugin.ai_image.provider", Default: "openai", Type: "string",
|
||||
Key: "provider", Default: "openai", Type: "string",
|
||||
DisplayName: "Provider", Description: "Image generation provider: openai / stability",
|
||||
Category: "ai_image",
|
||||
})
|
||||
s.Settings().RegisterDef(sdk.ConfigDef{
|
||||
Key: "plugin.ai_image.model", Default: "dall-e-3", Type: "string",
|
||||
Key: "model", Default: "dall-e-3", Type: "string",
|
||||
DisplayName: "Model", Description: "Model name (dall-e-3, sd-xl, etc.)",
|
||||
Category: "ai_image",
|
||||
})
|
||||
s.Settings().RegisterDef(sdk.ConfigDef{
|
||||
Key: "plugin.ai_image.size", Default: "1024x1024", Type: "string",
|
||||
Key: "size", Default: "1024x1024", Type: "string",
|
||||
DisplayName: "Size", Description: "Default image size (1024x1024, 1024x1792, 1792x1024)",
|
||||
Category: "ai_image",
|
||||
})
|
||||
|
||||
p.apiKey = getSetting(s.Settings(), "api_key", "")
|
||||
p.provider = getSetting(s.Settings(), "provider", "openai")
|
||||
p.model = getSetting(s.Settings(), "model", "dall-e-3")
|
||||
p.size = getSetting(s.Settings(), "size", "1024x1024")
|
||||
|
||||
tp := p.name + "_"
|
||||
s.RegisterTool(tp+"generate", sdk.ToolDef{
|
||||
Name: tp + "generate", Description: "Generate image from text prompt using AI. Returns image URL.",
|
||||
@ -179,20 +177,20 @@ type openAIResp struct {
|
||||
}
|
||||
|
||||
func (p *Plugin) handleGenerate(args map[string]interface{}) (interface{}, error) {
|
||||
prompt := readArg(args, "prompt", "")
|
||||
prompt := getArg(args, "prompt", "")
|
||||
if prompt == "" {
|
||||
return map[string]interface{}{"isError": true, "content": "prompt is required"}, nil
|
||||
}
|
||||
|
||||
p.apiKey = readCfg(p.sdk.Settings(), "api_key", p.apiKey)
|
||||
if p.apiKey == "" {
|
||||
key := getSetting(p.sdk.Settings(), "api_key", p.apiKey)
|
||||
if key == "" {
|
||||
return map[string]interface{}{"isError": true, "content": "API key not configured. Set plugin.ai_image.api_key via CLI."}, nil
|
||||
}
|
||||
|
||||
provider := readCfg(p.sdk.Settings(), "provider", p.provider)
|
||||
model := readArg(args, "model", readCfg(p.sdk.Settings(), "model", p.model))
|
||||
size := readArg(args, "size", readCfg(p.sdk.Settings(), "size", p.size))
|
||||
n := readArg(args, "n", int64(1))
|
||||
provider := getSetting(p.sdk.Settings(), "provider", p.provider)
|
||||
model := getArg(args, "model", getSetting(p.sdk.Settings(), "model", p.model))
|
||||
size := getArg(args, "size", getSetting(p.sdk.Settings(), "size", p.size))
|
||||
n := getArg(args, "n", int64(1))
|
||||
if n < 1 {
|
||||
n = 1
|
||||
}
|
||||
@ -202,15 +200,15 @@ func (p *Plugin) handleGenerate(args map[string]interface{}) (interface{}, error
|
||||
|
||||
switch provider {
|
||||
case "openai":
|
||||
return p.generateOpenAI(prompt, model, size, int(n))
|
||||
return p.generateOpenAI(prompt, model, size, int(n), key)
|
||||
case "stability":
|
||||
return p.generateStability(prompt, model, size, int(n))
|
||||
return p.generateStability(prompt, model, size, int(n), key)
|
||||
default:
|
||||
return map[string]interface{}{"isError": true, "content": "Unknown provider: " + provider + ". Supported: openai, stability"}, nil
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Plugin) generateOpenAI(prompt, model, size string, n int) (interface{}, error) {
|
||||
func (p *Plugin) generateOpenAI(prompt, model, size string, n int, apiKey string) (interface{}, error) {
|
||||
body := openAIReq{
|
||||
Model: model,
|
||||
Prompt: prompt,
|
||||
@ -222,7 +220,7 @@ func (p *Plugin) generateOpenAI(prompt, model, size string, n int) (interface{},
|
||||
b, _ := json.Marshal(body)
|
||||
req, _ := http.NewRequest("POST", "https://api.openai.com/v1/images/generations", bytes.NewReader(b))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
req.Header.Set("Authorization", "Bearer "+p.apiKey)
|
||||
req.Header.Set("Authorization", "Bearer "+apiKey)
|
||||
|
||||
resp, err := p.client.Do(req)
|
||||
if err != nil {
|
||||
@ -279,7 +277,7 @@ type stabilityResp struct {
|
||||
Message string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
func (p *Plugin) generateStability(prompt, model, size string, n int) (interface{}, error) {
|
||||
func (p *Plugin) generateStability(prompt, model, size string, n int, apiKey string) (interface{}, error) {
|
||||
width, height := 1024, 1024
|
||||
if parts := strings.Split(size, "x"); len(parts) == 2 {
|
||||
if w, err := strconv.Atoi(parts[0]); err == nil {
|
||||
@ -302,7 +300,7 @@ func (p *Plugin) generateStability(prompt, model, size string, n int) (interface
|
||||
b, _ := json.Marshal(body)
|
||||
req, _ := http.NewRequest("POST", apiURL, bytes.NewReader(b))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
req.Header.Set("Authorization", "Bearer "+p.apiKey)
|
||||
req.Header.Set("Authorization", "Bearer "+apiKey)
|
||||
req.Header.Set("Accept", "application/json")
|
||||
|
||||
resp, err := p.client.Do(req)
|
||||
|
||||
@ -25,7 +25,7 @@ func (p *Plugin) Start(s *sdk.PluginSDK) error {
|
||||
tp := p.name + "_"
|
||||
|
||||
s.Settings().RegisterDef(sdk.ConfigDef{
|
||||
Key: "plugin." + p.name + ".output_dir", Default: "/tmp/bili_videos",
|
||||
Key: "output_dir", Default: "/tmp/bili_videos",
|
||||
Type: "string", DisplayName: "下载目录",
|
||||
Description: "B站视频下载后的保存目录",
|
||||
Category: p.name,
|
||||
@ -81,7 +81,7 @@ func (p *Plugin) handleBiliVideo(args map[string]interface{}) (interface{}, erro
|
||||
|
||||
outputDir := "/tmp/bili_videos"
|
||||
if p.sdk != nil {
|
||||
if v, _ := p.sdk.Settings().Get("plugin." + p.name + ".output_dir"); v != nil {
|
||||
if v, _ := p.sdk.Settings().Get("output_dir"); v != nil {
|
||||
if s, ok := v.(string); ok && s != "" {
|
||||
outputDir = s
|
||||
}
|
||||
|
||||
@ -25,7 +25,7 @@ func (p *Plugin) Start(s *sdk.PluginSDK) error {
|
||||
s.SetAutoRestart(true)
|
||||
p.sdk = s
|
||||
s.Settings().RegisterDef(sdk.ConfigDef{
|
||||
Key: "plugin.files.dir",
|
||||
Key: "dir",
|
||||
Default: "/",
|
||||
Type: "string",
|
||||
DisplayName: "文件系统根目录",
|
||||
|
||||
@ -123,17 +123,17 @@ func (p *Plugin) Start(s *sdk.PluginSDK) error {
|
||||
s.SetAutoRestart(true)
|
||||
p.sdk = s
|
||||
|
||||
s.Settings().RegisterDef(sdk.ConfigDef{Key: "plugin.qq.listen", Default: "0.0.0.0:25580", Type: "string", DisplayName: "监听地址", Description: "Webhook HTTP 监听地址", Category: "qq"})
|
||||
s.Settings().RegisterDef(sdk.ConfigDef{Key: "plugin.qq.napcat_url", Default: "http://127.0.0.1:3000", Type: "string", DisplayName: "NapCat 地址", Description: "NapCat HTTP API 基础 URL", Category: "qq"})
|
||||
s.Settings().RegisterDef(sdk.ConfigDef{Key: "plugin.qq.admin", Default: "", Type: "string", DisplayName: "管理员 QQ", Description: "管理员 QQ 号,收到其消息时标记【重要!老大消息】", Category: "qq"})
|
||||
s.Settings().RegisterDef(sdk.ConfigDef{Key: "plugin.qq.dm_policy", Default: "open", Type: "string", DisplayName: "私聊策略", Description: "open / allowlist / disabled", Category: "qq", Options: []string{"open", "allowlist", "disabled"}})
|
||||
s.Settings().RegisterDef(sdk.ConfigDef{Key: "plugin.qq.allow_from", Default: "", Type: "string", DisplayName: "私聊白名单", Description: "允许私聊机器人的 QQ 号列表,逗号分隔", Category: "qq"})
|
||||
s.Settings().RegisterDef(sdk.ConfigDef{Key: "plugin.qq.group_policy", Default: "open", Type: "string", DisplayName: "群聊策略", Description: "open / allowlist / disabled", Category: "qq", Options: []string{"open", "allowlist", "disabled"}})
|
||||
s.Settings().RegisterDef(sdk.ConfigDef{Key: "plugin.qq.group_allow_from", Default: "", Type: "string", DisplayName: "群聊白名单", Description: "允许接入的群号列表,逗号分隔", Category: "qq"})
|
||||
s.Settings().RegisterDef(sdk.ConfigDef{Key: "plugin.qq.forward_rules", Default: "[]", Type: "string", DisplayName: "转发规则", Description: "JSON 数组,每项 {group_id,host,port,password,template}。匹配的群消息通过 RCON 转发到 Minecraft。template 支持 {nickname} {message} 占位", Category: "qq"})
|
||||
s.Settings().RegisterDef(sdk.ConfigDef{Key: "plugin.qq.files_dir", Default: "/home/newqqagent/agentfs/merged/qq_files", Type: "string", DisplayName: "文件存储目录", Description: "从QQ接收的文件保存目录(CQ file/image 自动下载到此目录)", Category: "qq"})
|
||||
s.Settings().RegisterDef(sdk.ConfigDef{Key: "plugin.qq.remote_dir", Default: "/home/program/qq-workspace/remote", Type: "string", DisplayName: "NapCat容器共享目录", Description: "与NapCat容器共享的文件目录,主机路径。发文件时文件会复制到此目录,NapCat内部映射为/app/files/", Category: "qq"})
|
||||
s.Settings().RegisterDef(sdk.ConfigDef{Key: "plugin.qq.agentfs_dir", Default: "/home/newqqagent/agentfs/merged", Type: "string", DisplayName: "AgentFS目录", Description: "文件读写的工作目录,read_document/video_download 等工具的默认工作目录", Category: "qq"})
|
||||
s.Settings().RegisterDef(sdk.ConfigDef{Key: "listen", Default: "0.0.0.0:25580", Type: "string", DisplayName: "监听地址", Description: "Webhook HTTP 监听地址", Category: "qq"})
|
||||
s.Settings().RegisterDef(sdk.ConfigDef{Key: "napcat_url", Default: "http://127.0.0.1:3000", Type: "string", DisplayName: "NapCat 地址", Description: "NapCat HTTP API 基础 URL", Category: "qq"})
|
||||
s.Settings().RegisterDef(sdk.ConfigDef{Key: "admin", Default: "", Type: "string", DisplayName: "管理员 QQ", Description: "管理员 QQ 号,收到其消息时标记【重要!老大消息】", Category: "qq"})
|
||||
s.Settings().RegisterDef(sdk.ConfigDef{Key: "dm_policy", Default: "open", Type: "string", DisplayName: "私聊策略", Description: "open / allowlist / disabled", Category: "qq", Options: []string{"open", "allowlist", "disabled"}})
|
||||
s.Settings().RegisterDef(sdk.ConfigDef{Key: "allow_from", Default: "", Type: "string", DisplayName: "私聊白名单", Description: "允许私聊机器人的 QQ 号列表,逗号分隔", Category: "qq"})
|
||||
s.Settings().RegisterDef(sdk.ConfigDef{Key: "group_policy", Default: "open", Type: "string", DisplayName: "群聊策略", Description: "open / allowlist / disabled", Category: "qq", Options: []string{"open", "allowlist", "disabled"}})
|
||||
s.Settings().RegisterDef(sdk.ConfigDef{Key: "group_allow_from", Default: "", Type: "string", DisplayName: "群聊白名单", Description: "允许接入的群号列表,逗号分隔", Category: "qq"})
|
||||
s.Settings().RegisterDef(sdk.ConfigDef{Key: "forward_rules", Default: "[]", Type: "string", DisplayName: "转发规则", Description: "JSON 数组,每项 {group_id,host,port,password,template}。匹配的群消息通过 RCON 转发到 Minecraft。template 支持 {nickname} {message} 占位", Category: "qq"})
|
||||
s.Settings().RegisterDef(sdk.ConfigDef{Key: "files_dir", Default: "/home/newqqagent/agentfs/merged/qq_files", Type: "string", DisplayName: "文件存储目录", Description: "从QQ接收的文件保存目录(CQ file/image 自动下载到此目录)", Category: "qq"})
|
||||
s.Settings().RegisterDef(sdk.ConfigDef{Key: "remote_dir", Default: "/home/program/qq-workspace/remote", Type: "string", DisplayName: "NapCat容器共享目录", Description: "与NapCat容器共享的文件目录,主机路径。发文件时文件会复制到此目录,NapCat内部映射为/app/files/", Category: "qq"})
|
||||
s.Settings().RegisterDef(sdk.ConfigDef{Key: "agentfs_dir", Default: "/home/newqqagent/agentfs/merged", Type: "string", DisplayName: "AgentFS目录", Description: "文件读写的工作目录,read_document/video_download 等工具的默认工作目录", Category: "qq"})
|
||||
|
||||
settings := s.Settings()
|
||||
|
||||
|
||||
@ -43,81 +43,61 @@ func NewPlugin(name string, config map[string]interface{}) (sdk.Plugin, error) {
|
||||
|
||||
func (p *Plugin) Name() string { return p.name }
|
||||
|
||||
func readCfg[T string | int64 | float64](s sdk.SettingsAPI, key string, fallback T) T {
|
||||
func getSetting[T string | int64 | float64](s sdk.SettingsAPI, key string, fallback T) T {
|
||||
v, err := s.Get(key)
|
||||
if err == nil && v != nil {
|
||||
if sv, ok := v.(string); ok && sv != "" {
|
||||
switch any(fallback).(type) {
|
||||
case string:
|
||||
return any(sv).(T)
|
||||
case int64:
|
||||
if n, err := strconv.ParseInt(sv, 10, 64); err == nil {
|
||||
return any(n).(T)
|
||||
}
|
||||
case float64:
|
||||
if n, err := strconv.ParseFloat(sv, 64); err == nil {
|
||||
return any(n).(T)
|
||||
}
|
||||
if err != nil || v == nil {
|
||||
return fallback
|
||||
}
|
||||
switch any(fallback).(type) {
|
||||
case string:
|
||||
if sv, ok := v.(string); ok {
|
||||
return any(sv).(T)
|
||||
}
|
||||
case int64:
|
||||
switch val := v.(type) {
|
||||
case float64:
|
||||
return any(int64(val)).(T)
|
||||
case string:
|
||||
if n, err := strconv.ParseInt(val, 10, 64); err == nil {
|
||||
return any(n).(T)
|
||||
}
|
||||
}
|
||||
}
|
||||
v2, err2 := s.GetCore("plugin." + "rss" + "." + key)
|
||||
if err2 == nil && v2 != nil {
|
||||
if sv, ok := v2.(string); ok && sv != "" {
|
||||
switch any(fallback).(type) {
|
||||
case string:
|
||||
return any(sv).(T)
|
||||
case int64:
|
||||
if n, err := strconv.ParseInt(sv, 10, 64); err == nil {
|
||||
return any(n).(T)
|
||||
}
|
||||
case float64:
|
||||
if n, err := strconv.ParseFloat(sv, 64); err == nil {
|
||||
return any(n).(T)
|
||||
}
|
||||
case float64:
|
||||
switch val := v.(type) {
|
||||
case float64:
|
||||
return any(val).(T)
|
||||
case string:
|
||||
if n, err := strconv.ParseFloat(val, 64); err == nil {
|
||||
return any(n).(T)
|
||||
}
|
||||
}
|
||||
}
|
||||
return fallback
|
||||
}
|
||||
|
||||
func readArg[T string | int64 | float64](args map[string]interface{}, key string, fallback T) T {
|
||||
v, ok := args[key]
|
||||
if !ok || v == nil {
|
||||
return fallback
|
||||
}
|
||||
switch any(fallback).(type) {
|
||||
case string:
|
||||
func readArg(args map[string]interface{}, key string) string {
|
||||
if v, ok := args[key]; ok && v != nil {
|
||||
if s, ok := v.(string); ok {
|
||||
return any(s).(T)
|
||||
return s
|
||||
}
|
||||
case int64:
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func readArgInt(args map[string]interface{}, key string, fallback int) int {
|
||||
if v, ok := args[key]; ok && v != nil {
|
||||
switch n := v.(type) {
|
||||
case float64:
|
||||
return any(int64(n)).(T)
|
||||
return int(n)
|
||||
case int64:
|
||||
return any(n).(T)
|
||||
case string:
|
||||
if i, err := strconv.ParseInt(n, 10, 64); err == nil {
|
||||
return any(i).(T)
|
||||
}
|
||||
}
|
||||
case float64:
|
||||
switch n := v.(type) {
|
||||
case float64:
|
||||
return any(n).(T)
|
||||
case int64:
|
||||
return any(float64(n)).(T)
|
||||
case string:
|
||||
if f, err := strconv.ParseFloat(n, 64); err == nil {
|
||||
return any(f).(T)
|
||||
}
|
||||
return int(n)
|
||||
}
|
||||
}
|
||||
return fallback
|
||||
}
|
||||
|
||||
func (p *Plugin) Start(s *sdk.PluginSDK) error {
|
||||
s.SetAutoRestart(true)
|
||||
p.sdk = s
|
||||
p.client = &http.Client{Timeout: 30 * time.Second}
|
||||
p.fp = gofeed.NewParser()
|
||||
@ -134,7 +114,7 @@ func (p *Plugin) Start(s *sdk.PluginSDK) error {
|
||||
p.loadData()
|
||||
|
||||
s.Settings().RegisterDef(sdk.ConfigDef{
|
||||
Key: "plugin.rss.poll_interval", Default: "30", Type: "string",
|
||||
Key: "poll_interval", Default: "30", Type: "string",
|
||||
DisplayName: "Poll Interval", Description: "Default polling interval in minutes (default: 30)",
|
||||
Category: "rss",
|
||||
})
|
||||
@ -179,7 +159,7 @@ func (p *Plugin) Start(s *sdk.PluginSDK) error {
|
||||
},
|
||||
}, p.handleCheckNow)
|
||||
|
||||
pollMin := int(readCfg(s.Settings(), "poll_interval", int64(30)))
|
||||
pollMin := int(getSetting(s.Settings(), "poll_interval", int64(30)))
|
||||
if pollMin < 5 {
|
||||
pollMin = 5
|
||||
}
|
||||
@ -300,7 +280,7 @@ func (p *Plugin) checkFeed(sub FeedSub) {
|
||||
}
|
||||
|
||||
func (p *Plugin) handleSubscribe(args map[string]interface{}) (interface{}, error) {
|
||||
url := readArg(args, "url", "")
|
||||
url := readArg(args, "url")
|
||||
if url == "" {
|
||||
return map[string]interface{}{"isError": true, "content": "URL is required"}, nil
|
||||
}
|
||||
@ -314,7 +294,7 @@ func (p *Plugin) handleSubscribe(args map[string]interface{}) (interface{}, erro
|
||||
}
|
||||
p.mu.RUnlock()
|
||||
|
||||
interval := int(readArg(args, "interval", int64(30)))
|
||||
interval := readArgInt(args, "interval", 30)
|
||||
if interval < 5 {
|
||||
interval = 5
|
||||
}
|
||||
@ -360,7 +340,7 @@ func (p *Plugin) handleSubscribe(args map[string]interface{}) (interface{}, erro
|
||||
}
|
||||
|
||||
func (p *Plugin) handleUnsubscribe(args map[string]interface{}) (interface{}, error) {
|
||||
url := readArg(args, "url", "")
|
||||
url := readArg(args, "url")
|
||||
if url == "" {
|
||||
return map[string]interface{}{"isError": true, "content": "URL is required"}, nil
|
||||
}
|
||||
|
||||
@ -32,18 +32,15 @@ func (p *Plugin) Start(s *sdk.PluginSDK) error {
|
||||
p.sdk = s
|
||||
p.client = &http.Client{Timeout: 15 * time.Second}
|
||||
|
||||
loc, err := s.Settings().Get("default_location")
|
||||
if err == nil && loc != nil {
|
||||
if v, ok := loc.(string); ok && v != "" {
|
||||
p.defaultLoc = v
|
||||
}
|
||||
}
|
||||
if p.defaultLoc == "" {
|
||||
v, err := s.Settings().GetCore("plugin.weather.default_location")
|
||||
if err == nil && v != nil {
|
||||
if vs, ok := v.(string); ok && vs != "" {
|
||||
p.defaultLoc = vs
|
||||
}
|
||||
s.Settings().RegisterDef(sdk.ConfigDef{
|
||||
Key: "default_location", Default: "", Type: "string",
|
||||
DisplayName: "Default Location", Description: "Default city name for weather queries, e.g. Beijing",
|
||||
Category: "weather",
|
||||
})
|
||||
|
||||
if v, _ := s.Settings().Get("default_location"); v != nil {
|
||||
if vs, ok := v.(string); ok {
|
||||
p.defaultLoc = vs
|
||||
}
|
||||
}
|
||||
|
||||
@ -51,14 +48,7 @@ func (p *Plugin) Start(s *sdk.PluginSDK) error {
|
||||
if dataHome == "" {
|
||||
dataHome = "/tmp"
|
||||
}
|
||||
dataDir := filepath.Join(dataHome, ".homeagent", "weather")
|
||||
os.MkdirAll(dataDir, 0755)
|
||||
|
||||
s.Settings().RegisterDef(sdk.ConfigDef{
|
||||
Key: "plugin.weather.default_location", Default: "", Type: "string",
|
||||
DisplayName: "Default Location", Description: "Default city name for weather queries, e.g. Beijing",
|
||||
Category: "weather",
|
||||
})
|
||||
os.MkdirAll(filepath.Join(dataHome, ".homeagent", "weather"), 0755)
|
||||
|
||||
tp := p.name + "_"
|
||||
s.RegisterTool(tp+"current", sdk.ToolDef{
|
||||
@ -382,7 +372,7 @@ func (p *Plugin) handleSetLocation(args map[string]interface{}) (interface{}, er
|
||||
return map[string]interface{}{"isError": true, "content": "Location is required"}, nil
|
||||
}
|
||||
|
||||
p.sdk.Settings().SetCore("plugin.weather.default_location", loc)
|
||||
p.sdk.Settings().Set("default_location", loc)
|
||||
p.defaultLoc = loc
|
||||
return map[string]interface{}{"content": fmt.Sprintf("Default location set to: %s", loc)}, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user