-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconfig_group.py
More file actions
269 lines (207 loc) · 8.63 KB
/
config_group.py
File metadata and controls
269 lines (207 loc) · 8.63 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
#!/usr/bin/env python3
"""
IMClaw 群聊配置管理脚本
管理每个群聊的响应模式配置。
用法:
# 查看所有群聊及其配置
python config_group.py --list
# 设置某个群聊的响应模式
python config_group.py --group <group_id> --mode silent
python config_group.py --group <group_id> --mode smart
# 设置默认响应模式
python config_group.py --default --mode smart
# 重置某个群聊为默认配置
python config_group.py --group <group_id> --reset
响应模式说明:
- silent: 静默模式 - 只有被 @ 或明确提到名字才响应
- smart: 智能模式 - 被 @ / 提名 / AI 判断在进行中的对话时响应(默认)
"""
import sys
import os
import json
import argparse
from pathlib import Path
from datetime import datetime
def get_skill_dir() -> Path:
"""自动检测 skill 目录路径"""
if os.environ.get("IMCLAW_SKILL_DIR"):
return Path(os.environ["IMCLAW_SKILL_DIR"])
script_dir = Path(__file__).parent.resolve()
if (script_dir / "scripts" / "imclaw_skill").is_dir():
return script_dir
return Path.home() / ".openclaw" / "workspace" / "skills" / "imclaw"
SKILL_DIR = get_skill_dir()
ASSETS_DIR = SKILL_DIR / "assets"
SESSIONS_DIR = SKILL_DIR / "sessions"
GROUP_SETTINGS_FILE = ASSETS_DIR / "group_settings.yaml"
sys.path.insert(0, str(SKILL_DIR / "scripts"))
def _load_gateway_env():
env_file = Path.home() / ".openclaw" / "gateway.env"
if not env_file.exists():
return
for line in env_file.read_text().splitlines():
line = line.strip()
if not line or line.startswith("#"):
continue
if "=" in line:
key, _, value = line.partition("=")
os.environ.setdefault(key.strip(), value.strip())
_load_gateway_env()
def load_settings() -> dict:
"""加载群聊配置"""
if not GROUP_SETTINGS_FILE.exists():
return {"default": {"response_mode": "smart"}, "groups": {}}
try:
import yaml
with open(GROUP_SETTINGS_FILE, 'r', encoding='utf-8') as f:
settings = yaml.safe_load(f) or {}
return {
"default": settings.get("default", {"response_mode": "smart"}),
"groups": settings.get("groups", {})
}
except Exception as e:
print(f"❌ 加载配置失败: {e}")
return {"default": {"response_mode": "smart"}, "groups": {}}
def save_settings(settings: dict):
"""保存群聊配置"""
try:
import yaml
with open(GROUP_SETTINGS_FILE, 'w', encoding='utf-8') as f:
yaml.dump(settings, f, allow_unicode=True, default_flow_style=False, sort_keys=False)
print(f"✅ 配置已保存到 {GROUP_SETTINGS_FILE}")
except Exception as e:
print(f"❌ 保存配置失败: {e}")
sys.exit(1)
def get_imclaw_client():
"""获取 IMClaw 客户端,从环境变量加载配置"""
try:
from imclaw_skill import resolve_env, IMClawClient
token = resolve_env("IMCLAW_TOKEN")
if not token:
print("⚠️ 未找到 token:请设置环境变量 IMCLAW_TOKEN", file=sys.stderr)
return None
hub_url = resolve_env("IMCLAW_HUB_URL", "https://imclaw-server.app.mosi.cn")
return IMClawClient(
hub_url=hub_url,
token=token
)
except Exception as e:
print(f"⚠️ 无法初始化 IMClaw 客户端: {e}")
return None
def list_groups_and_settings():
"""列出所有群聊及其配置"""
settings = load_settings()
default_mode = settings["default"].get("response_mode", "smart")
print(f"\n📋 群聊响应配置")
print(f"{'=' * 60}")
print(f"默认模式: {default_mode}")
print(f"{'=' * 60}\n")
# 尝试获取群聊列表
client = get_imclaw_client()
groups = []
if client:
try:
groups = client.list_groups()
except Exception as e:
print(f"⚠️ 无法获取群聊列表: {e}")
if groups:
print(f"{'群聊名称':<20} {'群聊ID':<40} {'响应模式':<10}")
print(f"{'-' * 70}")
for group in groups:
group_id = group.get("id", "")
group_name = group.get("name", "未命名")[:18]
group_config = settings["groups"].get(group_id, {})
mode = group_config.get("response_mode", f"{default_mode} (默认)")
print(f"{group_name:<20} {group_id:<40} {mode:<10}")
else:
print("未找到群聊,或无法连接到 Hub")
# 显示已配置但可能不在当前群聊列表的配置
configured_groups = settings.get("groups", {})
if configured_groups:
known_ids = {g.get("id") for g in groups}
orphan_configs = {k: v for k, v in configured_groups.items() if k not in known_ids}
if orphan_configs:
print(f"\n⚠️ 以下群聊有配置但未在当前群聊列表中:")
for gid, config in orphan_configs.items():
print(f" {gid}: {config.get('response_mode', '?')}")
print()
def set_group_mode(group_id: str, mode: str):
"""设置指定群聊的响应模式"""
if mode not in ("silent", "smart"):
print(f"❌ 无效的模式: {mode}")
print(" 有效模式: silent, smart")
sys.exit(1)
settings = load_settings()
if "groups" not in settings:
settings["groups"] = {}
settings["groups"][group_id] = {"response_mode": mode}
save_settings(settings)
# 同步写入 session 文件,供 bridge 读取群聊响应模式
SESSIONS_DIR.mkdir(parents=True, exist_ok=True)
session_file = SESSIONS_DIR / f"session_{group_id}.json"
try:
data = {"group_id": group_id, "response_mode": mode, "updated_at": datetime.now().isoformat()}
if session_file.exists():
existing = json.loads(session_file.read_text(encoding="utf-8"))
data["group_name"] = existing.get("group_name", "")
with open(session_file, "w", encoding="utf-8") as f:
json.dump(data, f, ensure_ascii=False, indent=2)
except Exception as e:
print(f"⚠️ 同步 session 文件失败: {e}")
print(f"✅ 群聊 {group_id} 的响应模式已设置为: {mode}")
def set_default_mode(mode: str):
"""设置默认响应模式"""
if mode not in ("silent", "smart"):
print(f"❌ 无效的模式: {mode}")
print(" 有效模式: silent, smart")
sys.exit(1)
settings = load_settings()
settings["default"] = {"response_mode": mode}
save_settings(settings)
print(f"✅ 默认响应模式已设置为: {mode}")
def reset_group(group_id: str):
"""重置某个群聊的配置(使用默认值)"""
settings = load_settings()
if group_id in settings.get("groups", {}):
del settings["groups"][group_id]
save_settings(settings)
print(f"✅ 群聊 {group_id} 的配置已重置为默认")
else:
print(f"ℹ️ 群聊 {group_id} 没有自定义配置")
def main():
parser = argparse.ArgumentParser(
description="IMClaw 群聊配置管理",
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog="""
响应模式说明:
silent - 静默模式: 只有被 @ 或明确提到名字才响应
smart - 智能模式: 被 @ / 提名 / AI 判断在进行中的对话时响应(默认)
示例:
config_group.py --list # 查看所有配置
config_group.py --group abc-123 --mode silent # 设置群聊为静默模式
config_group.py --default --mode smart # 设置默认模式
config_group.py --group abc-123 --reset # 重置群聊配置
"""
)
parser.add_argument("--list", "-l", action="store_true", help="列出所有群聊及其配置")
parser.add_argument("--group", "-g", help="指定群聊 ID")
parser.add_argument("--mode", "-m", choices=["silent", "smart"], help="响应模式")
parser.add_argument("--default", "-d", action="store_true", help="操作默认配置")
parser.add_argument("--reset", "-r", action="store_true", help="重置群聊为默认配置")
args = parser.parse_args()
if args.list:
list_groups_and_settings()
return
if args.default and args.mode:
set_default_mode(args.mode)
return
if args.group and args.reset:
reset_group(args.group)
return
if args.group and args.mode:
set_group_mode(args.group, args.mode)
return
# 没有有效参数,显示帮助
parser.print_help()
if __name__ == "__main__":
main()