myagent-ai 1.27.4 → 1.27.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/web/api_server.py +93 -178
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "myagent-ai",
3
- "version": "1.27.4",
3
+ "version": "1.27.5",
4
4
  "description": "本地桌面端执行型AI助手 - Open Interpreter 风格 | Local Desktop Execution-Oriented AI Assistant",
5
5
  "main": "main.py",
6
6
  "bin": {
package/web/api_server.py CHANGED
@@ -1819,8 +1819,8 @@ window.addEventListener('beforeunload', function() {{
1819
1819
  if not message:
1820
1820
  return web.json_response({"error": "message is required"}, status=400)
1821
1821
 
1822
- agent_name = data.get("agent_name", "default") or "default"
1823
- # 支持 path 格式 (如 "coder/python-expert")
1822
+ agent_name = data.get("agent_name", "1") or "1"
1823
+ # 支持 path 格式 (如 "3")
1824
1824
  agent_path = data.get("agent_path", agent_name)
1825
1825
  # 获取数字 agent_id
1826
1826
  agent_id = self.core.memory.get_agent_id(agent_path)
@@ -1984,7 +1984,7 @@ window.addEventListener('beforeunload', function() {{
1984
1984
  if not message and not user_images and not user_files:
1985
1985
  return web.Response(text="data: " + json.dumps({"error": "message is required"}) + "\n\n", content_type="text/event-stream")
1986
1986
 
1987
- agent_path = data.get("agent_path", data.get("agent_name", "default")) or "default"
1987
+ agent_path = data.get("agent_path", data.get("agent_name", "1")) or "1"
1988
1988
  # [v1.23.35] 直接使用前端传来的 session_id,不再拼接 agent_path 前缀
1989
1989
  session_id = data.get("session_id", "") or "web_default"
1990
1990
  chat_mode = data.get("mode", "")
@@ -2375,7 +2375,7 @@ window.addEventListener('beforeunload', function() {{
2375
2375
  if not message:
2376
2376
  return web.json_response({"error": "message is required"}, status=400)
2377
2377
 
2378
- agent_path = data.get("agent_path", "default")
2378
+ agent_path = data.get("agent_path", "1") or "1"
2379
2379
  # [v1.23.35] 直接使用前端传来的 session_id,不再拼接 agent_path 前缀
2380
2380
  session_id = data.get("session_id", "web_default")
2381
2381
  choice = data.get("choice", "queue") # "continue" (插入后继续) 或 "queue" (排队)
@@ -2423,7 +2423,7 @@ window.addEventListener('beforeunload', function() {{
2423
2423
  if not raw_text:
2424
2424
  return web.json_response({"error": "text is required"}, status=400)
2425
2425
 
2426
- agent_path = data.get("agent_path", "default") or "default"
2426
+ agent_path = data.get("agent_path", "1") or "1"
2427
2427
  session_id = data.get("session_id", "")
2428
2428
  chat_mode = data.get("mode", "")
2429
2429
 
@@ -3071,7 +3071,7 @@ window.addEventListener('beforeunload', function() {{
3071
3071
  优先使用 session_id 查找(与聊天流存储键一致),
3072
3072
  回退到 agent_path 查找(手动创建的任务)。
3073
3073
  """
3074
- agent_path = request.query.get("agent", "default")
3074
+ agent_path = request.query.get("agent", "1")
3075
3075
  session_id = request.query.get("session", "")
3076
3076
  # 优先按 session_id 查找(聊天流生成的任务列表存储在此键下)
3077
3077
  if session_id:
@@ -3085,7 +3085,7 @@ window.addEventListener('beforeunload', function() {{
3085
3085
  async def handle_update_task_plan(self, request):
3086
3086
  """PUT /api/task-plan - Overwrite entire task list."""
3087
3087
  data = await request.json()
3088
- agent_path = data.get("agent", "default")
3088
+ agent_path = data.get("agent", "1")
3089
3089
  session_id = data.get("session", "")
3090
3090
  tasks = data.get("tasks", [])
3091
3091
  # 优先按 session_id 存储(与聊天流一致),回退到 agent_path
@@ -3096,7 +3096,7 @@ window.addEventListener('beforeunload', function() {{
3096
3096
  async def handle_add_task_item(self, request):
3097
3097
  """POST /api/task-plan - Add a new task item."""
3098
3098
  data = await request.json()
3099
- agent_path = data.get("agent", "default")
3099
+ agent_path = data.get("agent", "1")
3100
3100
  session_id = data.get("session", "")
3101
3101
  text = data.get("text", "").strip()
3102
3102
  if not text:
@@ -3111,7 +3111,7 @@ window.addEventListener('beforeunload', function() {{
3111
3111
  async def handle_delete_task_item(self, request):
3112
3112
  """DELETE /api/task-plan/{idx} - Delete task by index."""
3113
3113
  idx = int(request.match_info["idx"])
3114
- agent_path = request.query.get("agent", "default")
3114
+ agent_path = request.query.get("agent", "1")
3115
3115
  session_id = request.query.get("session", "")
3116
3116
  # 优先按 session_id 查找,回退到 agent_path
3117
3117
  store_key = session_id or agent_path
@@ -3157,32 +3157,29 @@ window.addEventListener('beforeunload', function() {{
3157
3157
  return web.json_response({"ok": True})
3158
3158
 
3159
3159
  # --- Agents (层级体系) ---
3160
- # 目录结构: agents/default/{config.json, soul.md, ...}
3161
- # agents/coder/{config.json, soul.md, ...}
3162
- # agents/coder/python-expert/{config.json, soul.md, ...}
3163
- # agent path = 相对于 agents/ 的路径, 如 "default", "coder", "coder/python-expert"
3160
+ # 目录结构: agents/1/{config.json, soul.md, ...}
3161
+ # agents/2/{config.json, soul.md, ...}
3162
+ # agent path = agent ID, 如 "1", "2", "3"
3164
3163
 
3165
3164
  def _agents_dir(self):
3166
3165
  d = self.core.config_mgr.data_dir / "agents"
3167
3166
  d.mkdir(parents=True, exist_ok=True)
3168
3167
  return d
3169
3168
 
3170
- def _agent_dir(self, path: str) -> Path:
3171
- """根据 agent path 返回目录 (path 如 'coder/python-expert')"""
3172
- return self._agents_dir() / path
3169
+ def _agent_dir(self, aid: str) -> Path:
3170
+ """根据 agent ID 返回目录 (aid 如 '1', '2')"""
3171
+ return self._agents_dir() / aid
3173
3172
 
3174
3173
  def _ensure_default_agent(self):
3175
- """确保默认 agent 存在(名为「全权Agent」,目录名保持 default)"""
3176
- ad = self._agent_dir("default")
3177
- # 先尝试迁移(会自动修复损坏的 config.json)
3178
- if (ad / "config.json").exists():
3179
- self._migrate_agent_config("default", "全权Agent")
3180
- # 迁移后再次检查(损坏文件可能已被删除)
3174
+ """确保默认 agent 存在(ID=1,名为「全权Agent」,目录名=1)"""
3175
+ aid = "1"
3176
+ ad = self._agent_dir(aid)
3181
3177
  if not (ad / "config.json").exists():
3182
3178
  ad.mkdir(parents=True, exist_ok=True)
3183
3179
  now = _now_iso()
3184
3180
  cfg = {
3185
- "id": next_agent_id(),
3181
+ "id": 1,
3182
+ "path": aid,
3186
3183
  "name": "全权Agent",
3187
3184
  "description": "全权Agent - 拥有完整权限的本地助手",
3188
3185
  "avatar_color": _agent_color("全权Agent"),
@@ -3203,49 +3200,26 @@ window.addEventListener('beforeunload', function() {{
3203
3200
  if not (ad / fn).exists():
3204
3201
  (ad / fn).write_text(default, encoding="utf-8")
3205
3202
  logger.info("已创建默认 Agent (全权Agent)")
3206
- else:
3207
- # 即使已存在也同步其基本配置(如系统提示词可能更新)
3208
- self._migrate_agent_config("default")
3209
3203
 
3210
3204
  self._ensure_config_helper()
3211
3205
 
3212
- def _migrate_agent_config(self, path: str, intended_name: str = None):
3213
- """为旧 agent config 添加缺失的 id, created_at, updated_at 字段;JSON 损坏则自动重建"""
3214
- cfg_file = self._agent_dir(path) / "config.json"
3206
+ def _migrate_agent_config(self, aid: str):
3207
+ """为旧 agent config 补全缺失字段"""
3208
+ cfg_file = self._agent_dir(aid) / "config.json"
3215
3209
  if not cfg_file.exists():
3216
3210
  return
3217
3211
  try:
3218
3212
  cfg = json.loads(cfg_file.read_text(encoding="utf-8"))
3219
3213
  except (json.JSONDecodeError, ValueError):
3220
- logger.warning(f"Agent config JSON 解析失败,自动删除重建: {path}")
3221
- try:
3222
- cfg_file.unlink()
3223
- except OSError:
3224
- pass
3225
- # 如果是 default 或配置助手,由 _ensure_default_agent / _ensure_config_helper 重建
3226
- if path in ("default", "配置助手", "p"):
3227
- return
3228
- # 其他 agent:创建一个最小 config
3229
- ad = self._agent_dir(path)
3230
- if ad.exists():
3231
- now = _now_iso()
3232
- cfg = {
3233
- "id": next_agent_id(),
3234
- "name": path,
3235
- "description": "",
3236
- "avatar_emoji": "🤖",
3237
- "execution_mode": "sandbox",
3238
- "enabled": True,
3239
- "created_at": now,
3240
- "updated_at": now,
3241
- }
3242
- cfg_file.write_text(json.dumps(cfg, indent=2, ensure_ascii=False), encoding="utf-8")
3243
- logger.info(f"已重建 Agent 配置: {path}")
3214
+ logger.warning(f"Agent config JSON 解析失败: {aid}")
3244
3215
  return
3245
3216
  changed = False
3246
3217
  now = _now_iso()
3247
3218
  if "id" not in cfg:
3248
- cfg["id"] = next_agent_id()
3219
+ cfg["id"] = int(aid) if aid.isdigit() else next_agent_id()
3220
+ changed = True
3221
+ if "path" not in cfg:
3222
+ cfg["path"] = aid
3249
3223
  changed = True
3250
3224
  if "created_at" not in cfg:
3251
3225
  cfg["created_at"] = now
@@ -3253,25 +3227,19 @@ window.addEventListener('beforeunload', function() {{
3253
3227
  if "updated_at" not in cfg:
3254
3228
  cfg["updated_at"] = now
3255
3229
  changed = True
3256
- # 修正旧 default agent 的名字
3257
- if intended_name and cfg.get("name") == "default":
3258
- cfg["name"] = intended_name
3259
- changed = True
3260
3230
  if changed:
3261
3231
  cfg_file.write_text(json.dumps(cfg, indent=2, ensure_ascii=False), encoding="utf-8")
3262
3232
 
3263
3233
  def _ensure_config_helper(self):
3264
- """确保系统级「配置助手」agent 存在(不可删除、不可改名、核心字段不可修改)"""
3265
- ad = self._agent_dir("配置助手")
3266
- # 先尝试迁移(会自动修复损坏的 config.json)
3267
- if (ad / "config.json").exists():
3268
- self._migrate_agent_config("配置助手")
3269
- # 迁移后再次检查(损坏文件可能已被删除)
3234
+ """确保系统级「配置助手」agent 存在(ID=2,目录名=2)"""
3235
+ aid = "2"
3236
+ ad = self._agent_dir(aid)
3270
3237
  if not (ad / "config.json").exists():
3271
3238
  ad.mkdir(parents=True, exist_ok=True)
3272
3239
  now = _now_iso()
3273
3240
  cfg = {
3274
- "id": next_agent_id(),
3241
+ "id": 2,
3242
+ "path": aid,
3275
3243
  "name": "配置助手",
3276
3244
  "description": "MyAgent 智能配置助手 - 内置系统Agent,帮助用户完成初始配置和日常配置管理",
3277
3245
  "avatar_color": "#4f46e5",
@@ -3304,21 +3272,12 @@ window.addEventListener('beforeunload', function() {{
3304
3272
  except Exception as e:
3305
3273
  logger.warning(f"同步配置助手提示词失败: {e}")
3306
3274
 
3307
- # 创建快捷方式 p -> 配置助手(符号链接)
3308
- p_dir = self._agent_dir("p")
3309
- if not p_dir.exists() and ad.exists():
3310
- try:
3311
- # 在 agents 目录下创建 p -> 配置助手 的符号链接
3312
- p_dir.symlink_to(ad)
3313
- logger.info("已创建配置助手快捷方式: p -> 配置助手")
3314
- except OSError as e:
3315
- logger.debug(f"创建快捷方式 p 失败(非关键): {e}")
3316
3275
  # 自动绑定知识库:将 配置使用说明.md 复制到配置助手的知识库目录
3317
3276
  self._bind_config_helper_kb()
3318
3277
 
3319
3278
  def _bind_config_helper_kb(self):
3320
3279
  """将 docs/配置使用说明.md 绑定到配置助手的知识库目录"""
3321
- kb_dir = self._get_agent_knowledge_dir("配置助手")
3280
+ kb_dir = self._get_agent_knowledge_dir("2")
3322
3281
  kb_dir.mkdir(parents=True, exist_ok=True)
3323
3282
  target = kb_dir / "配置使用说明.md"
3324
3283
 
@@ -3351,8 +3310,8 @@ window.addEventListener('beforeunload', function() {{
3351
3310
  target.write_text(content, encoding="utf-8")
3352
3311
  logger.info(f"配置助手知识库已绑定: {source} -> {target}")
3353
3312
  # 刷新 RAG 索引
3354
- if hasattr(self, '_agent_rags') and "配置助手" in self._agent_rags:
3355
- self._agent_rags["配置助手"].build_index()
3313
+ if hasattr(self, '_agent_rags') and "2" in self._agent_rags:
3314
+ self._agent_rags["2"].build_index()
3356
3315
  else:
3357
3316
  logger.warning(f"未找到 配置使用说明.md 源文件,已搜索: {[str(c) for c in source_candidates]}")
3358
3317
 
@@ -3416,56 +3375,43 @@ window.addEventListener('beforeunload', function() {{
3416
3375
 
3417
3376
  return user_message, agent_system_prompt
3418
3377
 
3419
- def _scan_agents_flat(self, base_dir: Path = None, prefix: str = "") -> list[dict]:
3420
- """递归扫描所有 agent,返回扁平列表(含迁移补全字段)"""
3421
- if base_dir is None:
3422
- base_dir = self._agents_dir()
3378
+ def _scan_agents_flat(self) -> list[dict]:
3379
+ """扫描所有 agent 目录,返回扁平列表(目录名即为 agent ID)"""
3380
+ base_dir = self._agents_dir()
3423
3381
  agents = []
3424
3382
  if not base_dir.exists():
3425
3383
  return agents
3426
3384
  for d in sorted(base_dir.iterdir()):
3427
- if not d.is_dir():
3385
+ if not d.is_dir() or d.is_symlink():
3428
3386
  continue
3429
3387
  cfg_file = d / "config.json"
3430
3388
  if not cfg_file.exists():
3431
3389
  continue
3432
- agent_path = f"{prefix}{d.name}" if not prefix else f"{prefix}/{d.name}"
3433
- # 跳过符号链接目录(如 p -> 配置助手),避免重复处理
3434
- if d.is_symlink():
3390
+ aid = d.name
3391
+ self._migrate_agent_config(aid)
3392
+ if not cfg_file.exists():
3435
3393
  continue
3436
- # 迁移: 为缺少 id/created_at/updated_at 的旧 agent 补全字段
3437
- else:
3438
- self._migrate_agent_config(agent_path)
3439
- # 迁移可能删除了损坏的文件
3440
- if not cfg_file.exists():
3441
- continue
3442
- try:
3443
- cfg = json.loads(cfg_file.read_text(encoding="utf-8"))
3444
- except (json.JSONDecodeError, ValueError):
3445
- logger.warning(f"Agent config JSON 解析失败,跳过: {agent_path}")
3446
- continue
3447
- agent = {"path": agent_path, "name": d.name, **cfg}
3448
- agent["avatar_color"] = cfg.get("avatar_color") or _agent_color(d.name)
3449
- agent["depth"] = agent_path.count("/")
3450
- # [v1.20.13] 自动检测 avatar.png 文件,补全 avatar_image 字段
3394
+ try:
3395
+ cfg = json.loads(cfg_file.read_text(encoding="utf-8"))
3396
+ except (json.JSONDecodeError, ValueError):
3397
+ continue
3398
+ agent = {"path": aid, "id": int(aid) if aid.isdigit() else cfg.get("id", aid), "name": cfg.get("name", aid), **cfg}
3399
+ agent["avatar_color"] = cfg.get("avatar_color") or _agent_color(cfg.get("name", aid))
3400
+ # [v1.20.13] 自动检测 avatar.png
3451
3401
  if not agent.get("avatar_image") and (d / "avatar.png").exists():
3452
- agent["avatar_image"] = f"/api/agents/{agent_path}/avatar.png"
3402
+ agent["avatar_image"] = f"/api/agents/{aid}/avatar.png"
3453
3403
  agents.append(agent)
3454
- # 递归子目录
3455
- agents.extend(self._scan_agents_flat(d, agent_path))
3456
3404
  return agents
3457
3405
 
3458
3406
  def _build_agent_tree(self, agents_flat: list[dict]) -> list[dict]:
3459
- """将扁平 agent 列表构建为树结构"""
3460
- # path 索引
3461
- by_path = {a["path"]: {**a, "children": []} for a in agents_flat}
3407
+ """将扁平 agent 列表构建为树结构(通过 parent 字段关联)"""
3408
+ by_id = {a["path"]: {**a, "children": []} for a in agents_flat}
3462
3409
  roots = []
3463
3410
  for a in agents_flat:
3464
- path = a["path"]
3465
- parent_path = "/".join(path.split("/")[:-1]) if "/" in path else None
3466
- node = by_path[path]
3467
- if parent_path and parent_path in by_path:
3468
- by_path[parent_path]["children"].append(node)
3411
+ parent = a.get("parent", "")
3412
+ node = by_id[a["path"]]
3413
+ if parent and parent in by_id:
3414
+ by_id[parent]["children"].append(node)
3469
3415
  else:
3470
3416
  roots.append(node)
3471
3417
  return roots
@@ -3525,13 +3471,15 @@ window.addEventListener('beforeunload', function() {{
3525
3471
  if "/" in name or "\\" in name or name == "default":
3526
3472
  return web.json_response({"error": "invalid name (no slashes, cannot be 'default')"}, status=400)
3527
3473
 
3528
- ad = self._agent_dir(name)
3474
+ aid = str(next_agent_id())
3475
+ ad = self._agent_dir(aid)
3529
3476
  if (ad / "config.json").exists():
3530
3477
  return web.json_response({"error": f"Agent '{name}' already exists"}, status=409)
3531
3478
 
3532
3479
  now = _now_iso()
3533
3480
  cfg = {
3534
- "id": next_agent_id(),
3481
+ "id": int(aid),
3482
+ "path": aid,
3535
3483
  "name": name,
3536
3484
  "description": data.get("description", ""),
3537
3485
  "avatar_color": data.get("avatar_color") or _agent_color(name),
@@ -3576,13 +3524,13 @@ window.addEventListener('beforeunload', function() {{
3576
3524
  if data.get("department"):
3577
3525
  try:
3578
3526
  dm = self._get_dept_manager()
3579
- dm.assign_agent(data["department"], agents=[name], action="add")
3527
+ dm.assign_agent(data["department"], agents=[aid], action="add")
3580
3528
  logger.info(f"Agent {name} 已自动分配到部门: {data['department']}")
3581
3529
  except Exception as e:
3582
3530
  logger.warning(f"自动分配 Agent {name} 到部门失败: {e}")
3583
3531
 
3584
- logger.info(f"创建 Agent: {name} (sandbox模式)")
3585
- return web.json_response({"ok": True, "path": name, "name": name, "avatar_color": cfg["avatar_color"]})
3532
+ logger.info(f"创建 Agent: {name} (ID={aid})")
3533
+ return web.json_response({"ok": True, "path": aid, "id": int(aid), "name": name, "avatar_color": cfg["avatar_color"]})
3586
3534
 
3587
3535
  async def handle_create_child(self, request):
3588
3536
  """POST /api/agents/{parent}/children - 创建子 agent"""
@@ -3601,11 +3549,14 @@ window.addEventListener('beforeunload', function() {{
3601
3549
  return web.json_response({"error": "invalid name (no slashes)"}, status=400)
3602
3550
 
3603
3551
  child_path = f"{parent_path}/{name}"
3604
- ad = self._agent_dir(child_path)
3552
+ child_aid = str(next_agent_id())
3553
+ ad = self._agent_dir(child_aid)
3605
3554
  if (ad / "config.json").exists():
3606
- return web.json_response({"error": f"Agent '{child_path}' already exists"}, status=409)
3555
+ return web.json_response({"error": f"Agent '{name}' already exists"}, status=409)
3607
3556
 
3608
3557
  cfg = {
3558
+ "id": int(child_aid),
3559
+ "path": child_aid,
3609
3560
  "name": name,
3610
3561
  "parent": parent_path,
3611
3562
  "description": data.get("description", ""),
@@ -3641,30 +3592,18 @@ window.addEventListener('beforeunload', function() {{
3641
3592
  if not (ad / fn).exists():
3642
3593
  (ad / fn).write_text(default, encoding="utf-8")
3643
3594
 
3644
- logger.info(f"创建子 Agent: {child_path} (sandbox模式)")
3645
- return web.json_response({"ok": True, "path": child_path, "name": name, "parent": parent_path, "avatar_color": cfg["avatar_color"]})
3595
+ logger.info(f"创建子 Agent: {name} (ID={child_aid}, parent={parent_path})")
3596
+ return web.json_response({"ok": True, "path": child_aid, "id": int(child_aid), "name": name, "parent": parent_path, "avatar_color": cfg["avatar_color"]})
3646
3597
 
3647
3598
  async def handle_list_children(self, request):
3648
- """GET /api/agents/{parent}/children - 列出子 agent"""
3599
+ """GET /api/agents/{parent}/children - 列出子 agent(通过 parent 字段)"""
3649
3600
  parent_path = request.match_info["name"]
3650
- parent_dir = self._agent_dir(parent_path)
3651
- if not (parent_dir / "config.json").exists():
3601
+ parent_cfg = self._read_agent_config(parent_path)
3602
+ if not parent_cfg:
3652
3603
  return web.json_response({"error": f"Agent '{parent_path}' not found"}, status=404)
3653
3604
 
3654
- children = []
3655
- if parent_dir.exists():
3656
- for d in sorted(parent_dir.iterdir()):
3657
- if d.is_dir() and (d / "config.json").exists():
3658
- try:
3659
- cfg = json.loads((d / "config.json").read_text(encoding="utf-8"))
3660
- except (json.JSONDecodeError, ValueError):
3661
- logger.warning(f"Agent config JSON 解析失败,跳过: {parent_path}/{d.name}")
3662
- continue
3663
- child_path = f"{parent_path}/{d.name}"
3664
- child = {"path": child_path, "name": d.name, "parent": parent_path, **cfg}
3665
- child["avatar_color"] = cfg.get("avatar_color") or _agent_color(d.name)
3666
- child["depth"] = child_path.count("/")
3667
- children.append(child)
3605
+ all_agents = self._scan_agents_flat()
3606
+ children = [a for a in all_agents if a.get("parent") == parent_path]
3668
3607
  return web.json_response(children)
3669
3608
 
3670
3609
  async def handle_get_agent(self, request):
@@ -3719,8 +3658,7 @@ window.addEventListener('beforeunload', function() {{
3719
3658
  return web.json_response({"error": "config.json 解析失败"}, status=500)
3720
3659
 
3721
3660
  # 系统 Agent(内置 Agent)保护:核心字段不可修改
3722
- # "p" "配置助手" 的快捷方式,同样受保护
3723
- is_system = cfg.get("system") or path in ("p",)
3661
+ is_system = cfg.get("system") or path in ("1", "2")
3724
3662
  if is_system:
3725
3663
  blocked = [k for k in data if k in self._SYSTEM_AGENT_PROTECTED_FIELDS]
3726
3664
  if blocked:
@@ -3772,39 +3710,16 @@ window.addEventListener('beforeunload', function() {{
3772
3710
  if "soul" in data and not is_system: (ad / "soul.md").write_text(data["soul"], encoding="utf-8")
3773
3711
  if "identity" in data and not is_system: (ad / "identity.md").write_text(data["identity"], encoding="utf-8")
3774
3712
  if "user" in data: (ad / "user.md").write_text(data["user"], encoding="utf-8")
3775
- # 如果 name 改变,需要重命名目录
3776
- new_name = data.get("name")
3777
- renamed_to = None
3778
- if new_name and new_name != path and not is_system:
3779
- agents_dir = self._agents_dir()
3780
- new_ad = agents_dir / new_name
3781
- if not new_ad.exists():
3782
- ad.rename(new_ad)
3783
- logger.info(f"Agent 目录已重命名: {path} -> {new_name}")
3784
- renamed_to = new_name
3785
- # [v1.20.2] 重命名后更新 avatar_image URL 中的路径
3786
- old_avatar = cfg.get("avatar_image", "")
3787
- if old_avatar and f"/api/agents/{path}/" in old_avatar:
3788
- cfg["avatar_image"] = old_avatar.replace(f"/api/agents/{path}/", f"/api/agents/{new_name}/")
3789
- (new_ad / "config.json").write_text(
3790
- json.dumps(cfg, indent=2, ensure_ascii=False), encoding="utf-8"
3791
- )
3792
- else:
3793
- logger.warning(f"目标目录已存在,无法重命名: {new_name}")
3713
+ # 名字改变不再需要重命名目录(目录名是 agent ID,与名字无关)
3794
3714
  logger.info(f"更新 Agent: {path}")
3795
- result = {"ok": True, "hot_reload": True}
3796
- if renamed_to:
3797
- result["renamed_to"] = renamed_to
3798
- return web.json_response(result)
3715
+ return web.json_response({"ok": True, "hot_reload": True})
3799
3716
 
3800
3717
  async def handle_delete_agent(self, request):
3801
3718
  """DELETE /api/agents/{path} - 删除 agent 及其所有子 agent"""
3802
3719
  path = request.match_info["name"]
3803
- if path == "default":
3804
- return web.json_response({"error": "cannot delete default agent"}, status=403)
3805
- if path in ("配置助手", "p"):
3720
+ if path in ("1", "2"):
3806
3721
  return web.json_response({
3807
- "error": f"系统 Agent '{path}' 是内置 Agent,不可删除也不可重命名",
3722
+ "error": "系统 Agent 不可删除",
3808
3723
  "agent_path": path,
3809
3724
  }, status=403)
3810
3725
  ad = self._agent_dir(path)
@@ -4318,7 +4233,7 @@ window.addEventListener('beforeunload', function() {{
4318
4233
  if agent:
4319
4234
  # [v1.27.2] 先将 agent 路径转为数字 ID,用数字 ID 精确过滤
4320
4235
  target_aid = self.core.memory.get_agent_id(agent) if agent else 0
4321
- if agent == "default":
4236
+ if agent == "1":
4322
4237
  # default agent: agent_id=0(未分配)或 agent_id=1(default 的数字 ID)或 旧格式
4323
4238
  rows = conn.execute(
4324
4239
  f"""SELECT DISTINCT session_id, COUNT(*) as cnt, MAX(created_at) as last,
@@ -4387,7 +4302,7 @@ window.addEventListener('beforeunload', function() {{
4387
4302
  return web.json_response({"agent": name, "sessions": []})
4388
4303
  # [v1.27.2] 使用数字 agent_id 精确过滤,同时兼容旧数据
4389
4304
  target_aid = self.core.memory.get_agent_id(name)
4390
- if name == "default":
4305
+ if name == "1":
4391
4306
  # default agent: agent_id=0 或 agent_id=1 或 旧格式
4392
4307
  rows = self.core.memory._get_conn().execute(
4393
4308
  """SELECT DISTINCT session_id, COUNT(*) as cnt, MAX(created_at) as last FROM memories
@@ -5472,7 +5387,7 @@ window.addEventListener('beforeunload', function() {{
5472
5387
  else:
5473
5388
  # 兜底到全局默认 LLM 配置
5474
5389
  chain.append({
5475
- "id": "default",
5390
+ "id": "1",
5476
5391
  "name": llm_defaults.model,
5477
5392
  "provider": llm_defaults.provider,
5478
5393
  "api_type": llm_defaults.api_type,
@@ -5664,7 +5579,7 @@ window.addEventListener('beforeunload', function() {{
5664
5579
  self.core.main_agent._agent_override_path = agent_path
5665
5580
  # [v1.23.52] 为非默认 Agent 设置独立工作目录(executor 层面)
5666
5581
  _original_exec_work_dir = None
5667
- if agent_path and agent_path != "default" and self.core.main_agent and self.core.main_agent.executor:
5582
+ if agent_path and agent_path != "1" and self.core.main_agent and self.core.main_agent.executor:
5668
5583
  from config import ConfigManager
5669
5584
  _cm = ConfigManager()
5670
5585
  _agent_wd = _cm.data_dir / "agents" / agent_path / "workspace"
@@ -5993,7 +5908,7 @@ window.addEventListener('beforeunload', function() {{
5993
5908
  _original_exec_mode = agent.executor.execution_mode
5994
5909
  agent.executor.set_execution_mode(_exec_mode)
5995
5910
  # [v1.23.52] 为非默认 Agent 设置独立工作目录
5996
- if agent_path and agent_path != "default" and agent.executor:
5911
+ if agent_path and agent_path != "1" and agent.executor:
5997
5912
  from config import ConfigManager
5998
5913
  cm = ConfigManager()
5999
5914
  agent_work_dir = cm.data_dir / "agents" / agent_path / "workspace"
@@ -7142,14 +7057,14 @@ window.addEventListener('beforeunload', function() {{
7142
7057
  needs_setup = not config.llm.api_key
7143
7058
  # 确保配置助手存在
7144
7059
  self._ensure_config_helper()
7145
- helper_exists = (self._agent_dir("配置助手") / "config.json").exists()
7060
+ helper_exists = (self._agent_dir("2") / "config.json").exists()
7146
7061
  return web.json_response({
7147
7062
  "needs_setup": needs_setup,
7148
7063
  "helper_exists": helper_exists,
7149
7064
  "has_api_key": bool(config.llm.api_key),
7150
7065
  "provider": config.llm.provider,
7151
7066
  "model": config.llm.model,
7152
- "default_agent": "配置助手",
7067
+ "default_agent": "1",
7153
7068
  })
7154
7069
 
7155
7070
  async def handle_setup_complete(self, request):
@@ -7298,7 +7213,7 @@ window.addEventListener('beforeunload', function() {{
7298
7213
  def _check_org_admin(self, agent_path: str = "") -> bool:
7299
7214
  """检查 agent 是否是组织知识库管理员"""
7300
7215
  org_cfg = self.core.config.organization
7301
- admin = org_cfg.knowledge_admin or "default"
7216
+ admin = org_cfg.knowledge_admin or "1"
7302
7217
  return agent_path == admin
7303
7218
 
7304
7219
  async def handle_get_organization(self, request):
@@ -7358,7 +7273,7 @@ window.addEventListener('beforeunload', function() {{
7358
7273
  async def handle_upload_org_knowledge(self, request):
7359
7274
  """POST /api/organization/knowledge/upload - 上传文件到组织知识库(支持文件和文件夹上传)"""
7360
7275
  # 权限检查
7361
- agent = request.query.get("agent", "default")
7276
+ agent = request.query.get("agent", "1")
7362
7277
  if not self._check_org_admin(agent):
7363
7278
  return web.json_response(
7364
7279
  {"ok": False, "error": "权限不足:只有知识库管理员才能上传"},
@@ -7386,7 +7301,7 @@ window.addEventListener('beforeunload', function() {{
7386
7301
  async def handle_delete_org_knowledge(self, request):
7387
7302
  """DELETE /api/organization/knowledge?path=xxx - 删除组织知识库文件"""
7388
7303
  # 权限检查
7389
- agent = request.query.get("agent", "default")
7304
+ agent = request.query.get("agent", "1")
7390
7305
  if not self._check_org_admin(agent):
7391
7306
  return web.json_response(
7392
7307
  {"ok": False, "error": "权限不足:只有知识库管理员才能删除"},
@@ -7728,7 +7643,7 @@ window.addEventListener('beforeunload', function() {{
7728
7643
  name = data.get("name", "").strip()
7729
7644
  if not name:
7730
7645
  return web.json_response({"error": "群名不能为空"}, status=400)
7731
- owner = data.get("owner", "default")
7646
+ owner = data.get("owner", "1")
7732
7647
  description = data.get("description", "")
7733
7648
  avatar_emoji = data.get("avatar_emoji", "👥")
7734
7649
  avatar_color = data.get("avatar_color", "")
@@ -9042,7 +8957,7 @@ window.addEventListener('beforeunload', function() {{
9042
8957
  return web.json_response({"error": "invalid JSON"}, status=400)
9043
8958
 
9044
8959
  text = data.get("text", "")
9045
- agent_path = data.get("agent_path", "default")
8960
+ agent_path = data.get("agent_path", "1") or "1"
9046
8961
  filename = data.get("filename", "").strip()
9047
8962
 
9048
8963
  if not text: