myagent-ai 1.27.5 → 1.27.7

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.
@@ -226,9 +226,9 @@ class MainAgent(BaseAgent):
226
226
  def init_context_builder(self, memory_manager=None, skill_registry=None, knowledge_base_dir=None, context_window=None):
227
227
  """初始化 Context Builder(在系统启动后调用,注入依赖)"""
228
228
  if context_window is None and self.llm:
229
- context_window = getattr(self.llm, 'context_window', 128000)
229
+ context_window = getattr(self.llm, 'context_window', 200000)
230
230
  if context_window is None:
231
- context_window = 128000
231
+ context_window = 200000
232
232
  self.context_builder = ContextBuilder(
233
233
  memory_manager=memory_manager,
234
234
  skill_registry=skill_registry,
@@ -562,7 +562,7 @@ class MainAgent(BaseAgent):
562
562
  auto_kb_dir.mkdir(parents=True, exist_ok=True)
563
563
 
564
564
  # 使用 session_id 作为文件名(取前8位避免过长)
565
- # 注意: session_id 可能包含 '/' (来自 agent_path 如 "coder/python-expert"),
565
+ # 注意: session_id 可能包含 '/' (来自旧版 agent_path 格式),
566
566
  # 必须替换为安全字符,避免创建意外的子目录
567
567
  safe_session = session_id.replace("-", "").replace("/", "_")[:12] if session_id else "default"
568
568
  kb_file = auto_kb_dir / f"{safe_session}.md"
@@ -667,7 +667,7 @@ class MainAgent(BaseAgent):
667
667
  stream_callback: 可选的 SSE 事件回调 (callable 或 async callable)
668
668
  stream_response: 可选的流式响应对象(用于 LLM 流式输出)
669
669
  text_delta_callback: 可选的文本增量回调
670
- agent_path: Agent 路径(用于独立工作目录)
670
+ agent_path: Agent 的数字 aid(用于独立工作目录)
671
671
  """
672
672
  task_id = context.task_id or generate_id("task")
673
673
  context.task_id = task_id
@@ -1264,7 +1264,7 @@ class MainAgent(BaseAgent):
1264
1264
  logger.info(f"[{task_id}] 会话自动命名: {subject}")
1265
1265
  await self._emit_v2_event(
1266
1266
  "v2_session_rename",
1267
- {"session_id": context.session_id, "name": subject},
1267
+ {"sid": context.session_id, "name": subject},
1268
1268
  stream_callback,
1269
1269
  )
1270
1270
  except Exception as e:
@@ -38,8 +38,8 @@ class Message:
38
38
  """A communication message between agents."""
39
39
 
40
40
  id: str = ""
41
- from_agent: str = "" # Sender agent_id
42
- to_agent: str = "" # Recipient agent_id
41
+ from_agent: str = "" # Sender 的数字 aid
42
+ to_agent: str = "" # Recipient 的数字 aid
43
43
  content: str = "" # Plaintext content
44
44
  timestamp: float = 0.0
45
45
  encrypted: bool = False
@@ -16,7 +16,7 @@ from typing import Optional, List, Dict
16
16
  class Peer:
17
17
  """Represents a known remote/local agent peer."""
18
18
 
19
- agent_id: str # Short hex ID (16 chars)
19
+ agent_id: str # Agent 的数字 aid(如 "1", "2")或对端标识
20
20
  public_key: str # Ed25519 public key (hex, 64 chars)
21
21
  display_name: str = "" # Human-readable name
22
22
  added_at: float = 0.0 # Unix timestamp
package/config.py CHANGED
@@ -27,9 +27,9 @@ class LLMConfig:
27
27
  api_key: str = ""
28
28
  base_url: str = "https://api.openai.com/v1"
29
29
  model: str = "gpt-4"
30
- temperature: float = 0.1
31
- max_tokens: int = 30000
32
- context_window: int = 128000 # 上下文窗口大小
30
+ temperature: float = 0.8
31
+ max_tokens: int = 10240
32
+ context_window: int = 200000 # 上下文窗口大小
33
33
  input_modes: List[str] = field(default_factory=lambda: ["text"]) # 支持的输入模式
34
34
  reasoning: bool = False # 是否支持推理
35
35
  timeout: int = 120 # 请求超时(秒)
@@ -94,9 +94,9 @@ class ModelEntry:
94
94
  model: str = "" # API 调用使用的实际模型字符串
95
95
  base_url: str = "" # 自定义 Base URL(空=使用 provider 默认值)
96
96
  api_key: str = "" # 专用 API Key(空=使用全局默认值)
97
- max_tokens: int = 30000
98
- temperature: float = 0.1
99
- context_window: int = 128000 # 上下文窗口大小(token)
97
+ max_tokens: int = 10240
98
+ temperature: float = 0.8
99
+ context_window: int = 200000 # 上下文窗口大小(token)
100
100
  input_modes: List[str] = field(default_factory=lambda: ["text"]) # 支持的输入模式: text, image, video, audio
101
101
  reasoning: bool = True # 是否支持推理(如 o1 系列)
102
102
  enabled: bool = True
@@ -133,8 +133,8 @@ class CommunicationConfig:
133
133
  """Agent 间通信配置"""
134
134
  enabled: bool = False # 默认不启用
135
135
  server_url: str = "wss://aicq.online/ws" # AICQ 中继服务器
136
- agent_id: str = "" # 本机 Agent ID (Ed25519 公钥,空=自动生成)
137
- private_key: str = "" # 本机私钥 (Ed25519,空=自动生成)
136
+ agent_id: str = "" # Ed25519 公钥(持久化用,空=自动生成)
137
+ private_key: str = "" # Ed25519 私钥(持久化用,空=自动生成)
138
138
  max_friends: int = 200
139
139
  auto_accept: bool = False # 自动接受好友请求
140
140
 
@@ -35,8 +35,8 @@ logger = get_logger("myagent.agent_storage")
35
35
  @dataclass
36
36
  class AgentConfig:
37
37
  """Agent 配置(对应数据库一行)"""
38
- path: str = "" # Agent 路径,如 "default", "coder/python-expert"
39
- id: str = "" # 唯一 ID,12位 hex
38
+ path: str = "" # Agent 路径 = 数字 aid,如 "1", "2", "3"
39
+ id: str = "" # 数字 Agent ID,自增整数
40
40
  name: str = "" # 显示名称
41
41
  description: str = "" # 描述
42
42
  avatar_color: str = "" # 头像颜色
@@ -47,7 +47,7 @@ class AgentConfig:
47
47
  system: bool = False # 是否系统内置 Agent
48
48
  system_prompt: str = "" # 系统提示词
49
49
  model: str = "" # 模型覆盖
50
- parent: str = "" # 父 Agent 路径
50
+ parent: str = "" # 父 Agent 的数字 aid
51
51
  # 平台绑定
52
52
  platform: str = "" # 平台标识
53
53
  platform_token: str = "" # 平台 Token
@@ -99,7 +99,7 @@ class ContextBuilder:
99
99
  skill_registry: Optional["SkillRegistry"] = None,
100
100
  knowledge_base_dir: Optional[str] = None,
101
101
  max_dialog_chars: int = 20000,
102
- context_window: int = 128000,
102
+ context_window: int = 200000,
103
103
  ) -> None:
104
104
  self.memory_manager = memory_manager
105
105
  self.skill_registry = skill_registry
@@ -144,7 +144,7 @@ class ContextBuilder:
144
144
  用于 RAG 搜索知识库。为空时使用用户消息作为查询。
145
145
  recall: 上一轮 LLM 输出的 <recall> 内容,
146
146
  用于定向检索长期记忆。为空时仅用用户消息搜索。
147
- agent_path: Agent 路径(如 "default"),用于定位独立工作目录。
147
+ agent_path: Agent 的数字 aid(如 "1", "2"),用于定位独立工作目录。
148
148
 
149
149
  Returns:
150
150
  完整的 <context>...</context> XML 字符串
@@ -230,7 +230,7 @@ class ContextBuilder:
230
230
  agent_name: Agent 名称
231
231
  agent_description: Agent 描述
232
232
  agent_override_prompt: 可选的覆盖提示词
233
- agent_path: Agent 路径(用于定位独立工作目录)
233
+ agent_path: Agent 的数字 aid(用于定位独立工作目录)
234
234
 
235
235
  Returns:
236
236
  <whomi> XML 段落字符串
@@ -259,9 +259,9 @@ class ContextBuilder:
259
259
  def _get_workspace_dir(self, agent_path: Optional[str] = None) -> Optional[str]:
260
260
  """[v1.20.8] [v1.23.52] 获取工作目录路径
261
261
 
262
- 如果指定了 agent_path 且非默认 agent,则返回该 Agent 独立的工作目录:
263
- ~/.myagent/data/agents/{agent_path}/workspace/
264
- 否则返回全局工作目录:
262
+ 所有 Agent 均使用基于数字 aid 的独立工作目录:
263
+ ~/.myagent/data/agents/{aid}/workspace/
264
+ 无 agent_path 时返回全局工作目录:
265
265
  ~/.myagent/data/workspace/
266
266
  独立目录下自动创建 userfiles 子目录。
267
267
  """
@@ -269,15 +269,15 @@ class ContextBuilder:
269
269
  from config import ConfigManager
270
270
  import os
271
271
  cm = ConfigManager()
272
- if agent_path and agent_path != "default":
273
- # 使用 Agent 独立工作目录
272
+ if agent_path:
273
+ # 使用 Agent 独立工作目录(基于数字 aid)
274
274
  wd = cm.data_dir / "agents" / agent_path / "workspace"
275
275
  wd.mkdir(parents=True, exist_ok=True)
276
276
  userfiles = wd / "userfiles"
277
277
  userfiles.mkdir(parents=True, exist_ok=True)
278
278
  return str(wd)
279
279
  else:
280
- # 默认 agent 或无 agent_path 时使用全局工作目录
280
+ # agent_path 时使用全局工作目录
281
281
  wd = cm.data_dir / "workspace"
282
282
  wd.mkdir(parents=True, exist_ok=True)
283
283
  return str(wd)
@@ -47,8 +47,8 @@ class ContextBudget:
47
47
  @dataclass
48
48
  class ContextConfig:
49
49
  """上下文管理配置"""
50
- # 模型上下文窗口大小 (token数), 默认128K (大多数模型通用)
51
- model_context_window: int = 128000
50
+ # 模型上下文窗口大小 (token数), 默认200K
51
+ model_context_window: int = 200000
52
52
  # 预算分配
53
53
  budget: ContextBudget = field(default_factory=ContextBudget)
54
54
  # 近期消息保留条数 (原始消息, 不压缩)
package/core/llm.py CHANGED
@@ -132,13 +132,13 @@ class LLMClient:
132
132
  api_key: str = "",
133
133
  base_url: str = "",
134
134
  model: str = "gpt-4",
135
- temperature: float = 0.1,
136
- max_tokens: int = 30000,
135
+ temperature: float = 0.8,
136
+ max_tokens: int = 10240,
137
137
  timeout: int = 120,
138
138
  max_retries: int = 3,
139
139
  reasoning: bool = False,
140
140
  reasoning_effort: str = "medium",
141
- context_window: int = 128000,
141
+ context_window: int = 200000,
142
142
  **kwargs,
143
143
  ):
144
144
  self.provider = provider
@@ -86,7 +86,7 @@ class TaskPersistence:
86
86
  description: 任务描述(通常是用户消息内容)
87
87
  session_id: 会话 ID
88
88
  group_id: 群聊 ID(如果是群聊任务)
89
- agent_path: Agent 路径
89
+ agent_path: Agent 的数字 aid
90
90
  status: 任务状态 (pending|running|completed|failed)
91
91
  metadata: 附加元数据
92
92
  last_message: 最后一条消息内容
@@ -559,21 +559,21 @@ class ToolDispatcher:
559
559
  if stream_callback:
560
560
  await self._emit_sse("v2_web_control", {
561
561
  "action": "open",
562
- "session_id": session_id,
562
+ "sid": session_id,
563
563
  "url": url,
564
564
  "panel_url": f"/api/web_control/panel?sid={session_id}",
565
565
  }, stream_callback)
566
566
  return {
567
567
  "success": True,
568
568
  "output": f"已打开网页控制面板 (session: {session_id})" + (f",URL: {url}" if url else ""),
569
- "session_id": session_id,
569
+ "sid": session_id,
570
570
  }
571
571
 
572
572
  elif action == "close":
573
573
  wc_mgr.close_session(session_id)
574
574
  if stream_callback:
575
575
  await self._emit_sse("v2_web_control", {
576
- "action": "close", "session_id": session_id
576
+ "action": "close", "sid": session_id
577
577
  }, stream_callback)
578
578
  return {"success": True, "output": f"已关闭网页控制面板 (session: {session_id})"}
579
579
 
@@ -584,7 +584,7 @@ class ToolDispatcher:
584
584
  session.current_url = url
585
585
  if stream_callback:
586
586
  await self._emit_sse("v2_web_control", {
587
- "action": "navigate", "session_id": session_id, "url": url
587
+ "action": "navigate", "sid": session_id, "url": url
588
588
  }, stream_callback)
589
589
  return {"success": True, "output": f"正在导航到: {url}"}
590
590
 
@@ -631,7 +631,7 @@ class ToolDispatcher:
631
631
  if stream_callback:
632
632
  await self._emit_sse("v2_web_control", {
633
633
  "action": "human_interact",
634
- "session_id": session_id,
634
+ "sid": session_id,
635
635
  "prompt": prompt,
636
636
  "platform": platform,
637
637
  "timeout": timeout,
@@ -654,7 +654,7 @@ class ToolDispatcher:
654
654
  if stream_callback:
655
655
  await self._emit_sse("v2_web_control", {
656
656
  "action": "human_done",
657
- "session_id": session_id,
657
+ "sid": session_id,
658
658
  "timed_out": True,
659
659
  }, stream_callback)
660
660
  return {"success": False, "error": f"人机交互超时 ({timeout}s)"}
@@ -687,7 +687,7 @@ class ToolDispatcher:
687
687
  if stream_callback:
688
688
  await self._emit_sse("v2_web_control", {
689
689
  "action": "human_done",
690
- "session_id": session_id,
690
+ "sid": session_id,
691
691
  }, stream_callback)
692
692
 
693
693
  output_parts = [f"用户已完成人机交互操作"]
@@ -701,7 +701,7 @@ class ToolDispatcher:
701
701
  return {
702
702
  "success": True,
703
703
  "output": "\n".join(output_parts),
704
- "session_id": session_id,
704
+ "sid": session_id,
705
705
  "cookies_saved": bool(cookie_file) and not cookie_file.startswith("("),
706
706
  "cookie_file": cookie_file,
707
707
  "data": result_data,
@@ -747,7 +747,7 @@ class ToolDispatcher:
747
747
  if stream_callback:
748
748
  await self._emit_sse("v2_web_control", {
749
749
  "action": "login",
750
- "session_id": session_id,
750
+ "sid": session_id,
751
751
  "url": login_url,
752
752
  "panel_url": f"/api/web_control/panel?sid={session_id}",
753
753
  "platform": platform,
@@ -792,7 +792,7 @@ class ToolDispatcher:
792
792
  pass
793
793
  if stream_callback:
794
794
  await self._emit_sse("v2_web_control", {
795
- "action": "human_done", "session_id": session_id, "timed_out": True,
795
+ "action": "human_done", "sid": session_id, "timed_out": True,
796
796
  }, stream_callback)
797
797
  return {"success": False, "error": f"登录超时 ({timeout}s),请重试"}
798
798
 
@@ -839,7 +839,7 @@ class ToolDispatcher:
839
839
  if stream_callback:
840
840
  await self._emit_sse("v2_web_control", {
841
841
  "action": "login_done",
842
- "session_id": session_id,
842
+ "sid": session_id,
843
843
  "platform": platform,
844
844
  "login_success": login_success,
845
845
  }, stream_callback)
@@ -861,7 +861,7 @@ class ToolDispatcher:
861
861
  return {
862
862
  "success": True,
863
863
  "output": "\n".join(output_parts),
864
- "session_id": session_id,
864
+ "sid": session_id,
865
865
  "login_success": login_success,
866
866
  "platform": platform,
867
867
  "cookie_file": cookie_file,
@@ -94,7 +94,7 @@ CONTROL_SCRIPT = """
94
94
  notifyParent('ready', {
95
95
  url: window.location.href,
96
96
  title: document.title,
97
- session_id: window.__webControlSessionId
97
+ sid: window.__webControlSessionId
98
98
  });
99
99
  }
100
100
 
@@ -672,7 +672,7 @@ class WebControlManager:
672
672
  """客户端轮询 — 返回待执行命令"""
673
673
  session = self.get_session(session_id)
674
674
  if not session:
675
- return {"commands": [], "session_id": session_id, "error": "Session not found"}
675
+ return {"commands": [], "sid": session_id, "error": "Session not found"}
676
676
 
677
677
  session.is_panel_open = True
678
678
  session.touch()
@@ -684,7 +684,7 @@ class WebControlManager:
684
684
  except asyncio.QueueEmpty:
685
685
  break
686
686
 
687
- return {"commands": commands, "session_id": session_id}
687
+ return {"commands": commands, "sid": session_id}
688
688
 
689
689
  async def submit_result(self, session_id: str, cmd_id: str, result: Dict) -> bool:
690
690
  """客户端提交命令执行结果"""
package/groups/manager.py CHANGED
@@ -30,7 +30,7 @@ logger = logging.getLogger("myagent.groups")
30
30
  @dataclass
31
31
  class GroupMember:
32
32
  """群成员"""
33
- agent_path: str # Agent 路径,如 "default", "coder", "coder/python-expert"
33
+ agent_path: str # Agent 的数字 aid,如 "1", "2", "3"
34
34
  role: str = "member" # owner | admin | member
35
35
  joined_at: float = 0.0
36
36
  nickname: str = "" # 群内昵称(空=使用agent默认名)
@@ -61,13 +61,13 @@ class GroupMessage:
61
61
  """群消息"""
62
62
  id: str = ""
63
63
  group_id: str = ""
64
- sender: str = "" # "user" 或 agent_path
64
+ sender: str = "" # "user" 或 agent 的数字 aid
65
65
  sender_name: str = "" # 发送者显示名
66
66
  sender_avatar: str = "" # 发送者头像emoji
67
67
  content: str = ""
68
68
  msg_type: str = "text" # text | system
69
69
  timestamp: float = 0.0
70
- agent_path: str = "" # 消息关联的 agent(如果是agent回复)
70
+ agent_path: str = "" # 消息关联的 agent 的数字 aid
71
71
 
72
72
  def to_dict(self) -> dict:
73
73
  return {
@@ -466,7 +466,7 @@ class GroupManager:
466
466
 
467
467
  Args:
468
468
  group_id: 群ID
469
- agent_path: 要添加的 agent 路径
469
+ agent_path: 要添加的 agent 的数字 aid
470
470
  role: 成员角色 (member | admin)
471
471
  nickname: 群内昵称
472
472
  operator: 操作者 agent_path
@@ -519,7 +519,7 @@ class GroupManager:
519
519
 
520
520
  Args:
521
521
  group_id: 群ID
522
- agent_path: 要移除的 agent 路径
522
+ agent_path: 要移除的 agent 的数字 aid
523
523
  operator: 操作者 agent_path
524
524
 
525
525
  Returns:
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "myagent-ai",
3
- "version": "1.27.5",
3
+ "version": "1.27.7",
4
4
  "description": "本地桌面端执行型AI助手 - Open Interpreter 风格 | Local Desktop Execution-Oriented AI Assistant",
5
5
  "main": "main.py",
6
6
  "bin": {
@@ -43,4 +43,4 @@
43
43
  "python": ">=3.10",
44
44
  "node": ">=18"
45
45
  }
46
- }
46
+ }
package/web/api_server.py CHANGED
@@ -1322,7 +1322,7 @@ function tryDirectConnect() {{
1322
1322
  sessions = []
1323
1323
  for sid, session in mgr.sessions.items():
1324
1324
  sessions.append({
1325
- "session_id": sid,
1325
+ "sid": sid,
1326
1326
  "current_url": session.current_url,
1327
1327
  "is_panel_open": session.is_panel_open,
1328
1328
  "created_at": session.created_at,
@@ -1336,16 +1336,16 @@ function tryDirectConnect() {{
1336
1336
  session = mgr.create_session()
1337
1337
  return web.json_response({
1338
1338
  "success": True,
1339
- "session_id": session.session_id,
1339
+ "sid": session.session_id,
1340
1340
  "panel_url": f"/api/web_control/panel?sid={session.session_id}",
1341
1341
  })
1342
1342
 
1343
1343
  async def handle_wc_close_session(self, request):
1344
1344
  """POST /api/web_control/close - 关闭 Web Control 会话"""
1345
1345
  data = await request.json() if request.content_type == 'application/json' else {}
1346
- sid = data.get('session_id') or request.query.get('sid', '')
1346
+ sid = data.get('sid') or data.get('session_id') or request.query.get('sid', '')
1347
1347
  if not sid:
1348
- return web.json_response({"success": False, "error": "Missing session_id"}, status=400)
1348
+ return web.json_response({"success": False, "error": "Missing sid"}, status=400)
1349
1349
  self._get_wc_manager().close_session(sid)
1350
1350
  return web.json_response({"success": True})
1351
1351
 
@@ -1363,11 +1363,11 @@ function tryDirectConnect() {{
1363
1363
  data = await request.json()
1364
1364
  except:
1365
1365
  return web.json_response({"success": False, "error": "Invalid JSON"}, status=400)
1366
- sid = data.get('session_id', '')
1366
+ sid = data.get('sid') or data.get('session_id', '')
1367
1367
  cmd_id = data.get('cmd_id', '')
1368
1368
  result = data.get('result', {})
1369
1369
  if not sid or not cmd_id:
1370
- return web.json_response({"success": False, "error": "Missing session_id or cmd_id"}, status=400)
1370
+ return web.json_response({"success": False, "error": "Missing sid or cmd_id"}, status=400)
1371
1371
  ok = await self._get_wc_manager().submit_result(sid, cmd_id, result)
1372
1372
  return web.json_response({"success": ok})
1373
1373
 
@@ -1692,7 +1692,7 @@ function wcExecuteCommand(cmd) {{
1692
1692
  return;
1693
1693
  }}
1694
1694
  if (cmd.action === 'close') {{
1695
- window.parent.postMessage({{ __webControlPanel: true, action: 'close', session_id: WC_SESSION_ID }}, '*');
1695
+ window.parent.postMessage({{ __webControlPanel: true, action: 'close', sid: WC_SESSION_ID }}, '*');
1696
1696
  wcSubmitResult({{ cmdId: cmd.id, success: true, closed: true }});
1697
1697
  return;
1698
1698
  }}
@@ -1718,7 +1718,7 @@ async function wcSubmitResult(resultData) {{
1718
1718
  method: 'POST',
1719
1719
  headers: {{ 'Content-Type': 'application/json' }},
1720
1720
  body: JSON.stringify({{
1721
- session_id: WC_SESSION_ID,
1721
+ sid: WC_SESSION_ID,
1722
1722
  cmd_id: resultData.cmdId,
1723
1723
  result: resultData
1724
1724
  }})
@@ -1783,11 +1783,11 @@ if ('{initial_url}') {{
1783
1783
  }}
1784
1784
 
1785
1785
  // ── 通知父窗口面板已打开 ──
1786
- window.parent.postMessage({{ __webControlPanel: true, action: 'opened', session_id: WC_SESSION_ID }}, '*');
1786
+ window.parent.postMessage({{ __webControlPanel: true, action: 'opened', sid: WC_SESSION_ID }}, '*');
1787
1787
 
1788
1788
  // ── 页面卸载时清理 ──
1789
1789
  window.addEventListener('beforeunload', function() {{
1790
- window.parent.postMessage({{ __webControlPanel: true, action: 'closed', session_id: WC_SESSION_ID }}, '*');
1790
+ window.parent.postMessage({{ __webControlPanel: true, action: 'closed', sid: WC_SESSION_ID }}, '*');
1791
1791
  }});
1792
1792
  </script>
1793
1793
  </body>
@@ -1824,9 +1824,8 @@ window.addEventListener('beforeunload', function() {{
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)
1827
- # [v1.23.35] 直接使用前端传来的 session_id,不再拼接 agent_path 前缀
1828
- # 新格式(sess_uuid)和旧格式(agent_path_web_xxx)均兼容
1829
- session_id = data.get("session_id", "") or "web_default"
1827
+ # 统一使用 sid 作为会话标识(兼容旧字段 session_id
1828
+ session_id = data.get("sid", "") or data.get("session_id", "") or "web_default"
1830
1829
  chat_mode = data.get("mode", "") # "exec" = 执行模式
1831
1830
  escalated = data.get("escalated", False) # 临时提权到 local
1832
1831
 
@@ -1898,7 +1897,7 @@ window.addEventListener('beforeunload', function() {{
1898
1897
  except Exception as tp_err:
1899
1898
  logger.warning(f"任务列表更新失败: {tp_err}")
1900
1899
 
1901
- resp_data = {"response": response, "session_id": session_id, "agent_name": agent_path, "agent_path": agent_path}
1900
+ resp_data = {"response": response, "sid": session_id, "agent_name": agent_path, "agent_path": agent_path}
1902
1901
  if exec_events:
1903
1902
  resp_data["exec_events"] = exec_events
1904
1903
  return web.json_response(resp_data)
@@ -1985,8 +1984,8 @@ window.addEventListener('beforeunload', function() {{
1985
1984
  return web.Response(text="data: " + json.dumps({"error": "message is required"}) + "\n\n", content_type="text/event-stream")
1986
1985
 
1987
1986
  agent_path = data.get("agent_path", data.get("agent_name", "1")) or "1"
1988
- # [v1.23.35] 直接使用前端传来的 session_id,不再拼接 agent_path 前缀
1989
- session_id = data.get("session_id", "") or "web_default"
1987
+ # 统一使用 sid 作为会话标识(兼容旧字段 session_id
1988
+ session_id = data.get("sid", "") or data.get("session_id", "") or "web_default"
1990
1989
  chat_mode = data.get("mode", "")
1991
1990
  escalated = data.get("escalated", False)
1992
1991
  voice_text = data.get("voice_text", "").strip() # 语音转文字原始文本(用于 usersays_correct)
@@ -2015,16 +2014,16 @@ window.addEventListener('beforeunload', function() {{
2015
2014
  # 先发送已生成的内容
2016
2015
  existing_result = running_info.get("result", "")
2017
2016
  if existing_result:
2018
- await response.write(("data: " + json.dumps({"type": "resume", "session_id": session_id, "running": True, "started_at": running_info.get("started_at"), "result": existing_result}, ensure_ascii=False) + "\n\n").encode())
2017
+ await response.write(("data: " + json.dumps({"type": "resume", "sid": session_id, "running": True, "started_at": running_info.get("started_at"), "result": existing_result}, ensure_ascii=False) + "\n\n").encode())
2019
2018
  else:
2020
- await response.write(("data: " + json.dumps({"type": "resume", "session_id": session_id, "running": True, "started_at": running_info.get("started_at")}, ensure_ascii=False) + "\n\n").encode())
2019
+ await response.write(("data: " + json.dumps({"type": "resume", "sid": session_id, "running": True, "started_at": running_info.get("started_at")}, ensure_ascii=False) + "\n\n").encode())
2021
2020
 
2022
2021
  # 持续检查任务是否完成,完成后发送完成事件
2023
2022
  while not running_info.get("done"):
2024
2023
  await asyncio.sleep(0.5) # 每 500ms 检查一次
2025
2024
  running_info = self._running_sessions.get(session_id)
2026
2025
  if running_info and running_info.get("done"):
2027
- await response.write(("data: " + json.dumps({"type": "resume_complete", "session_id": session_id, "result": running_info.get("result", "")}, ensure_ascii=False) + "\n\n").encode())
2026
+ await response.write(("data: " + json.dumps({"type": "resume_complete", "sid": session_id, "result": running_info.get("result", "")}, ensure_ascii=False) + "\n\n").encode())
2028
2027
  break
2029
2028
 
2030
2029
  return response
@@ -2112,7 +2111,7 @@ window.addEventListener('beforeunload', function() {{
2112
2111
 
2113
2112
  # 发送 session 信息
2114
2113
  logger.info(f"[{session_id}] 准备发送 session 事件")
2115
- await safe_write({"type": "session", "session_id": session_id, "agent_path": agent_path})
2114
+ await safe_write({"type": "session", "sid": session_id, "agent_path": agent_path})
2116
2115
  logger.info(f"[{session_id}] session 事件已发送")
2117
2116
 
2118
2117
  # ── 定义后台流式处理任务(独立于 SSE 连接) ──
@@ -2196,7 +2195,7 @@ window.addEventListener('beforeunload', function() {{
2196
2195
  self._running_sessions[session_id]["completed_at"] = time.time()
2197
2196
 
2198
2197
  # 发送完成事件
2199
- await safe_write({"type": "done", "exec_events": exec_events, "session_id": session_id})
2198
+ await safe_write({"type": "done", "exec_events": exec_events, "sid": session_id})
2200
2199
 
2201
2200
  # ── 处理消息队列 ──
2202
2201
  while session_id in self._msg_queues and self._msg_queues[session_id]:
@@ -2205,7 +2204,7 @@ window.addEventListener('beforeunload', function() {{
2205
2204
  if not next_message:
2206
2205
  continue
2207
2206
  logger.info(f"[{session_id}] 处理队列消息: {next_message[:50]}...")
2208
- await safe_write({"type": "queue_start", "message": next_message, "session_id": session_id})
2207
+ await safe_write({"type": "queue_start", "message": next_message, "sid": session_id})
2209
2208
  clean_message_q, agent_system_prompt_q = self._build_agent_chat_context(agent_path, agent_cfg, next_message)
2210
2209
  if model_chain and self.core.llm:
2211
2210
  full_response = await self._try_model_chain_stream(
@@ -2227,7 +2226,7 @@ window.addEventListener('beforeunload', function() {{
2227
2226
  result_store["full_response"] = full_response or ""
2228
2227
  result_store["exec_events"] = exec_events_q
2229
2228
  result_store["done"] = True
2230
- await safe_write({"type": "done", "exec_events": exec_events_q, "session_id": session_id})
2229
+ await safe_write({"type": "done", "exec_events": exec_events_q, "sid": session_id})
2231
2230
 
2232
2231
  except asyncio.CancelledError:
2233
2232
  # [v1.23.38] 任务被取消(用户点击停止),清理资源
@@ -2235,7 +2234,7 @@ window.addEventListener('beforeunload', function() {{
2235
2234
  result_store["done"] = True
2236
2235
  result_store["cancelled"] = True
2237
2236
  try:
2238
- await safe_write({"type": "stopped", "session_id": session_id})
2237
+ await safe_write({"type": "stopped", "sid": session_id})
2239
2238
  except Exception:
2240
2239
  pass
2241
2240
  except Exception as e:
@@ -2327,9 +2326,9 @@ window.addEventListener('beforeunload', function() {{
2327
2326
  except Exception:
2328
2327
  return web.json_response({"error": "invalid JSON"}, status=400)
2329
2328
 
2330
- session_id = data.get("session_id", "")
2329
+ session_id = data.get("sid", "") or data.get("session_id", "")
2331
2330
  if not session_id:
2332
- return web.json_response({"ok": False, "error": "missing session_id"})
2331
+ return web.json_response({"ok": False, "error": "missing sid"})
2333
2332
 
2334
2333
  logger.info(f"[{session_id}] 收到停止执行请求")
2335
2334
 
@@ -2376,8 +2375,8 @@ window.addEventListener('beforeunload', function() {{
2376
2375
  return web.json_response({"error": "message is required"}, status=400)
2377
2376
 
2378
2377
  agent_path = data.get("agent_path", "1") or "1"
2379
- # [v1.23.35] 直接使用前端传来的 session_id,不再拼接 agent_path 前缀
2380
- session_id = data.get("session_id", "web_default")
2378
+ # 统一使用 sid 作为会话标识(兼容旧字段 session_id
2379
+ session_id = data.get("sid", "") or data.get("session_id", "web_default")
2381
2380
  choice = data.get("choice", "queue") # "continue" (插入后继续) 或 "queue" (排队)
2382
2381
 
2383
2382
  # 检查会话是否正在运行
@@ -2424,7 +2423,7 @@ window.addEventListener('beforeunload', function() {{
2424
2423
  return web.json_response({"error": "text is required"}, status=400)
2425
2424
 
2426
2425
  agent_path = data.get("agent_path", "1") or "1"
2427
- session_id = data.get("session_id", "")
2426
+ session_id = data.get("sid", "") or data.get("session_id", "")
2428
2427
  chat_mode = data.get("mode", "")
2429
2428
 
2430
2429
  # Build full session ID
@@ -2856,7 +2855,7 @@ window.addEventListener('beforeunload', function() {{
2856
2855
  for sid, info in self._running_sessions.items():
2857
2856
  if info.get("running") and not info.get("done"):
2858
2857
  running_agents.append({
2859
- "session_id": sid,
2858
+ "sid": sid,
2860
2859
  "agent_path": info.get("agent_path", ""),
2861
2860
  "message": info.get("message", ""),
2862
2861
  "started_at": info.get("started_at"),
@@ -4190,7 +4189,7 @@ window.addEventListener('beforeunload', function() {{
4190
4189
  for session_id, info in self._running_sessions.items():
4191
4190
  if info.get("running") and not info.get("done"):
4192
4191
  running.append({
4193
- "session_id": session_id,
4192
+ "sid": session_id,
4194
4193
  "running": True,
4195
4194
  "started_at": info.get("started_at"),
4196
4195
  "agent_path": info.get("agent_path"),
@@ -4561,7 +4560,7 @@ window.addEventListener('beforeunload', function() {{
4561
4560
  return web.json_response([{
4562
4561
  "id": e.id, "key": e.key, "content": e.content[:500],
4563
4562
  "category": e.category, "importance": e.importance,
4564
- "role": e.role, "session_id": e.session_id, "created_at": e.created_at,
4563
+ "role": e.role, "sid": e.session_id, "created_at": e.created_at,
4565
4564
  } for e in results])
4566
4565
 
4567
4566
  async def handle_memory_list(self, request):
@@ -4574,7 +4573,7 @@ window.addEventListener('beforeunload', function() {{
4574
4573
  "id": e.id, "key": e.key, "content": e.content[:500],
4575
4574
  "summary": e.summary, "importance": e.importance,
4576
4575
  "category": e.category, "role": e.role,
4577
- "session_id": e.session_id, "created_at": e.created_at,
4576
+ "sid": e.session_id, "created_at": e.created_at,
4578
4577
  } for e in entries])
4579
4578
 
4580
4579
  async def handle_delete_memory(self, request):
@@ -4698,7 +4697,7 @@ window.addEventListener('beforeunload', function() {{
4698
4697
  base_url = data.get("base_url", "")
4699
4698
  model = data.get("model", "")
4700
4699
  api_type = data.get("api_type", "")
4701
- temperature = data.get("temperature", 0.1)
4700
+ temperature = data.get("temperature", 0.8)
4702
4701
  provider = data.get("provider", "")
4703
4702
  input_modes = data.get("input_modes", ["text"])
4704
4703
 
@@ -4863,9 +4862,9 @@ window.addEventListener('beforeunload', function() {{
4863
4862
  model=data.get("model", model_id),
4864
4863
  base_url=data.get("base_url", ""),
4865
4864
  api_key=data.get("api_key", ""),
4866
- max_tokens=data.get("max_tokens", 4096),
4867
- temperature=data.get("temperature", 0.1),
4868
- context_window=data.get("context_window", 128000),
4865
+ max_tokens=data.get("max_tokens", 10240),
4866
+ temperature=data.get("temperature", 0.8),
4867
+ context_window=data.get("context_window", 200000),
4869
4868
  input_modes=data.get("input_modes", ["text"]),
4870
4869
  reasoning=data.get("reasoning", False),
4871
4870
  enabled=data.get("enabled", True),
@@ -5544,7 +5543,7 @@ window.addEventListener('beforeunload', function() {{
5544
5543
  "temperature": llm.temperature,
5545
5544
  "max_tokens": llm.max_tokens,
5546
5545
  "api_type": getattr(llm, 'api_type', ''),
5547
- "context_window": getattr(llm, 'context_window', 128000),
5546
+ "context_window": getattr(llm, 'context_window', 200000),
5548
5547
  }
5549
5548
 
5550
5549
  try:
@@ -5577,9 +5576,9 @@ window.addEventListener('beforeunload', function() {{
5577
5576
  if agent_system_prompt and self.core.main_agent:
5578
5577
  self.core.main_agent._agent_override_prompt = agent_system_prompt
5579
5578
  self.core.main_agent._agent_override_path = agent_path
5580
- # [v1.23.52] 为非默认 Agent 设置独立工作目录(executor 层面)
5579
+ # [v1.23.52] 为所有 Agent 设置独立工作目录(基于数字 aid,executor 层面)
5581
5580
  _original_exec_work_dir = None
5582
- if agent_path and agent_path != "1" and self.core.main_agent and self.core.main_agent.executor:
5581
+ if agent_path and self.core.main_agent and self.core.main_agent.executor:
5583
5582
  from config import ConfigManager
5584
5583
  _cm = ConfigManager()
5585
5584
  _agent_wd = _cm.data_dir / "agents" / agent_path / "workspace"
@@ -5698,7 +5697,7 @@ window.addEventListener('beforeunload', function() {{
5698
5697
  "provider": llm.provider, "model": llm.model, "base_url": llm.base_url,
5699
5698
  "api_key": llm.api_key, "temperature": llm.temperature, "max_tokens": llm.max_tokens,
5700
5699
  "api_type": getattr(llm, 'api_type', ''),
5701
- "context_window": getattr(llm, 'context_window', 128000),
5700
+ "context_window": getattr(llm, 'context_window', 200000),
5702
5701
  }
5703
5702
  try:
5704
5703
  if "provider" in mc: llm.provider = mc["provider"]
@@ -5907,8 +5906,8 @@ window.addEventListener('beforeunload', function() {{
5907
5906
  if _exec_mode:
5908
5907
  _original_exec_mode = agent.executor.execution_mode
5909
5908
  agent.executor.set_execution_mode(_exec_mode)
5910
- # [v1.23.52] 为非默认 Agent 设置独立工作目录
5911
- if agent_path and agent_path != "1" and agent.executor:
5909
+ # [v1.23.52] 为所有 Agent 设置独立工作目录(基于数字 aid)
5910
+ if agent_path and agent.executor:
5912
5911
  from config import ConfigManager
5913
5912
  cm = ConfigManager()
5914
5913
  agent_work_dir = cm.data_dir / "agents" / agent_path / "workspace"
@@ -7924,10 +7923,10 @@ window.addEventListener('beforeunload', function() {{
7924
7923
  - @某个Agent: 只有被@的Agent需要回复
7925
7924
  - @所有人 / @all: 所有成员都需要回复
7926
7925
  - 不@任何人(广播): 你自行判断是否需要回复
7927
- 2. **跨Agent私下沟通**: 你可以使用 `myagent-ai chat --agent <路径> --message "消息"` 命令向群内其他Agent发送私下消息。对方会在自己下次处理消息时收到。
7928
- - **⚠️ 必须使用 Agent 路径(ID),不能用名字!** 例如群成员列表中显示 `薇纸 [五香鸡/薇纸] (成员)`,则路径是 `五香鸡/薇纸`,不是 `薇纸`
7929
- - 从上方「群成员列表」中找到目标Agent的 `[方括号]` 内容就是它的路径
7930
- - 正确示例: `myagent-ai chat --agent 五香鸡/薇纸 --message "你好"`
7926
+ 2. **跨Agent私下沟通**: 你可以使用 `myagent-ai chat --agent <数字ID> --message "消息"` 命令向群内其他Agent发送私下消息。对方会在自己下次处理消息时收到。
7927
+ - **⚠️ 必须使用 Agent 的数字 ID,不能用名字!** 例如群成员列表中显示 `薇纸 [3] (成员)`,则 ID 是 `3`,不是 `薇纸`
7928
+ - 从上方「群成员列表」中找到目标Agent的 `[方括号]` 内容就是它的数字 ID
7929
+ - 正确示例: `myagent-ai chat --agent 3 --message "你好"`
7931
7930
  - 错误示例: `myagent-ai chat --agent 薇纸 --message "你好"`(名字可能重复或找不到)
7932
7931
  - 私下沟通的内容不会直接显示给用户,适合讨论细节、交换数据、协调方案
7933
7932
  - 当任务需要多个Agent协作时,应该先在群里讨论分工,然后私下沟通具体细节
@@ -12,7 +12,7 @@ async function renderMemory(){
12
12
  try{lt=await api('/api/memory/list?category='+encodeURIComponent(_memCategory))}catch(e){lt=[]}
13
13
  if(stats.error){$('content').innerHTML='<div class="empty" style="color:var(--danger)">记忆系统异常: '+escHtml(stats.error)+'</div>';return}
14
14
  // [v1.18.9] 按 agent 筛选
15
- if(_memAgentFilter){lt=lt.filter(e=>(e.agent_id||e.session_id||'').includes(_memAgentFilter));}
15
+ if(_memAgentFilter){lt=lt.filter(e=>(e.agent_id||e.sid||'').includes(_memAgentFilter));}
16
16
  const cats=[{k:'global',l:'全局记忆'},{k:'session',l:'会话记忆'}];
17
17
  let tabHtml='<div class="flex gap-8 mb-8" style="flex-wrap:wrap">';
18
18
  for(const c of cats){
@@ -40,7 +40,7 @@ async function renderMemory(){
40
40
  <div class="mem-meta">
41
41
  <span class="tag">${escHtml(e.role||'')}</span>
42
42
  ${!isSession&&e.importance!=null?'<span class="tag tag-imp">'+e.importance.toFixed(2)+'</span>':''}
43
- ${e.session_id?'<span class="mem-session" title="'+escHtml(e.session_id)+'">'+escHtml((e.session_id||'').split('_web_')[0])+'</span>':''}
43
+ ${e.sid?'<span class="mem-session" title="'+escHtml(e.sid)+'">'+escHtml((e.sid||'').split('_web_')[0])+'</span>':''}
44
44
  </div>
45
45
  </div>
46
46
  <div class="mem-content">${contentPreview}</div>
@@ -67,7 +67,7 @@ async function searchMemory(){
67
67
  <div class="mem-meta">
68
68
  <span class="tag">${e.category||''}</span>
69
69
  <span class="tag">${escHtml(e.role||'')}</span>
70
- <span class="mem-session">${escHtml((e.session_id||'').split('_web_')[0])}</span>
70
+ <span class="mem-session">${escHtml((e.sid||'').split('_web_')[0])}</span>
71
71
  </div>
72
72
  </div>
73
73
  <div class="mem-content">${escHtml(content)}</div>
@@ -1792,7 +1792,7 @@ window.addEventListener('message', function(event) {
1792
1792
  if (event.data && event.data.__webControlPanel) {
1793
1793
  var action = event.data.action;
1794
1794
  if (action === 'opened') {
1795
- wcCurrentSessionId = event.data.session_id || wcCurrentSessionId;
1795
+ wcCurrentSessionId = event.data.sid || wcCurrentSessionId;
1796
1796
  // 通知服务端面板已打开
1797
1797
  api('/api/web_control/poll?sid=' + wcCurrentSessionId).catch(function(){});
1798
1798
  } else if (action === 'close' || action === 'closed') {
@@ -3659,7 +3659,7 @@ window.buildMessageHtml = function(msg, idx, agent) {
3659
3659
  if (!wcEvents || wcEvents.length === 0) return '';
3660
3660
  let lastEvent = wcEvents[wcEvents.length - 1];
3661
3661
  let wcAction = lastEvent.action || 'open';
3662
- let wcSessionId = lastEvent.session_id || '';
3662
+ let wcSessionId = lastEvent.sid || '';
3663
3663
  let wcUrl = lastEvent.url || '';
3664
3664
  let wcTitle = 'Web Control';
3665
3665
  let wcIcon = '🌐';
@@ -226,7 +226,7 @@ async function sendChunkSequentially(chunks, idx) {
226
226
  method: 'POST',
227
227
  body: JSON.stringify({
228
228
  message: text,
229
- session_id: state.activeSessionId || ('split_' + Date.now()),
229
+ sid: state.activeSessionId || ('split_' + Date.now()),
230
230
  agent_name: state.activeAgent,
231
231
  agent_path: state.activeAgent,
232
232
  mode: state.chatMode,
@@ -1718,7 +1718,7 @@ async function sendMessage(opts) {
1718
1718
  headers: { 'Content-Type': 'application/json' },
1719
1719
  body: JSON.stringify({
1720
1720
  message: text,
1721
- session_id: sessionId,
1721
+ sid: sessionId,
1722
1722
  agent_name: state.activeAgent,
1723
1723
  agent_path: state.activeAgent,
1724
1724
  mode: state.chatMode,
@@ -1788,14 +1788,14 @@ async function sendMessage(opts) {
1788
1788
  const evt = JSON.parse(line.substring(6));
1789
1789
 
1790
1790
  if (evt.type === 'session') {
1791
- sessionIdReceived = evt.session_id;
1791
+ sessionIdReceived = evt.sid;
1792
1792
  // Sync the actual session ID (backend may prefix with agent_path)
1793
- state.activeSessionId = evt.session_id;
1793
+ state.activeSessionId = evt.sid;
1794
1794
  // [v1.23.24] 同步本地 sessions 列表中的 ID(前端生成的临时 ID → 后端 canonical ID)
1795
- if (sessionIdOriginal && sessionIdOriginal !== evt.session_id) {
1795
+ if (sessionIdOriginal && sessionIdOriginal !== evt.sid) {
1796
1796
  var _sesIdx = state.sessions.findIndex(function(s) { return s.id === sessionIdOriginal; });
1797
1797
  if (_sesIdx >= 0) {
1798
- state.sessions[_sesIdx].id = evt.session_id;
1798
+ state.sessions[_sesIdx].id = evt.sid;
1799
1799
  state.agentSessions[state.activeAgent] = [...state.sessions];
1800
1800
  renderSessions();
1801
1801
  }
@@ -1803,7 +1803,7 @@ async function sendMessage(opts) {
1803
1803
  // ── 更新 URL 参数(后端返回的 session ID 可能与前端不同) ──
1804
1804
  try {
1805
1805
  const _url = new URL(window.location.href);
1806
- _url.searchParams.set('s', UrlCodec.encode(evt.session_id));
1806
+ _url.searchParams.set('s', UrlCodec.encode(evt.sid));
1807
1807
  window.history.replaceState({}, '', _url.toString());
1808
1808
  } catch (_) {}
1809
1809
  } else if (evt.type === 'user_files') {
@@ -2189,7 +2189,7 @@ async function sendMessage(opts) {
2189
2189
  // [v1.21.0] Agent is opening/controlling web control panel
2190
2190
  if (evt.data) {
2191
2191
  var wcAction = evt.data.action;
2192
- var wcSessionId = evt.data.session_id || '';
2192
+ var wcSessionId = evt.data.sid || '';
2193
2193
  var wcUrl = evt.data.url || '';
2194
2194
  if (wcAction === 'open' || wcAction === 'navigate') {
2195
2195
  // 打开或导航 Web Control 面板
@@ -2210,7 +2210,7 @@ async function sendMessage(opts) {
2210
2210
  // [v1.15.8] 会话自动命名 — 后端通过 mainsubject 生成
2211
2211
  if (evt.data && evt.data.name) {
2212
2212
  var newName = evt.data.name;
2213
- var targetId = evt.data.session_id || sessionId;
2213
+ var targetId = evt.data.sid || sessionId;
2214
2214
  var _ses = state.sessions.find(function(s) { return s.id === targetId; });
2215
2215
  if (_ses) {
2216
2216
  _ses.name = newName;
@@ -2458,7 +2458,7 @@ function stopGenerating() {
2458
2458
  fetch('/api/chat/stop', {
2459
2459
  method: 'POST',
2460
2460
  headers: { 'Content-Type': 'application/json' },
2461
- body: JSON.stringify({ session_id: sid }),
2461
+ body: JSON.stringify({ sid: sid }),
2462
2462
  }).catch(function() {});
2463
2463
  }
2464
2464
  // 中断前端 SSE 连接
@@ -2508,7 +2508,7 @@ async function handleInjectChoice(choice) {
2508
2508
  headers: { 'Content-Type': 'application/json' },
2509
2509
  body: JSON.stringify({
2510
2510
  message: text,
2511
- session_id: rawSid,
2511
+ sid: rawSid,
2512
2512
  agent_path: state.activeAgent,
2513
2513
  choice: choice
2514
2514
  })
@@ -251,8 +251,8 @@ async function selectGroup(gid) {
251
251
  // [v1.23.81] 获取群聊 session ID 并写入 URL(纯数字,用于导航恢复)
252
252
  try {
253
253
  var sessionData = await api('/api/groups/' + encodeURIComponent(gid) + '/session');
254
- if (sessionData && sessionData.session_id) {
255
- var sessionId = sessionData.session_id;
254
+ if (sessionData && sessionData.sid) {
255
+ var sessionId = sessionData.sid;
256
256
  // 用群聊专用 ?g= 参数更新 URL(不刷新页面),纯数字 session ID
257
257
  var newUrl = '/ui/chat/chat_container.html?g=' + sessionId;
258
258
  if (typeof state !== 'undefined' && state.activeAgent) {