ai_co_discuss 0.2.35 → 0.2.37

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.
package/README.md CHANGED
@@ -113,7 +113,7 @@ codiscuss local connect https://你的站点
113
113
 
114
114
  下次打开会保留原讨论,已暂停的房间需在进度看板明确重启。网页已连接或创建成功不代表 AI 已回答,应核对实际执行进展与讨论记录。独立服务管理、停止归属及故障排查见 [接入说明](docs/runner.md#常驻讨论服务);私有配置需保留在原位置。
115
115
 
116
- 软件失败时先查看暂停原因,登录和权限问题在对应软件中处理。本机网站的已登记房间,可从进度看板 Codex 旁的“…”菜单直接选择“切换 App / CLI”,在弹窗内暂停并保存;软件路径在“接入 → 修正本场软件连接”修改。原会话与讨论进度保留,待服务确认采用后重启;线上连接暂不提供此修正入口。切到 App 后模型和文件权限按 App 设置,切回 CLI 前须让 App 释放原聊天。本场修改不影响后续讨论的默认配置,详见 [配置修正](docs/runner.md#已启动后的配置修正)。
116
+ 软件失败时先查看暂停原因,登录和权限问题在对应软件中处理。仍保留当前发言安排时,可点“跳过”,取消这次发言并恢复讨论,由主持人安排后续;“重启”则重试原安排。本机网站的已登记房间,可从进度看板 Codex 旁的“…”菜单直接选择“切换 App / CLI”,在弹窗内暂停并保存;软件路径在“接入 → 修正本场软件连接”修改。原会话与讨论进度保留,待服务确认采用后重启;线上连接暂不提供此修正入口。切到 App 后模型和文件权限按 App 设置,切回 CLI 前须让 App 释放原聊天。本场修改不影响后续讨论的默认配置,详见 [配置修正](docs/runner.md#已启动后的配置修正)。
117
117
 
118
118
  **手动接入与网页 AI:** 手动接入可用于“自由协作”和“讨论”的专家(讨论的主持人必须由本机唤醒),在成员卡片正面的“自动 / 手动 / 网页”切换里选择。手动成员从成员菜单下载自己的凭据文件,或复制同样内容的凭证文本(设为环境变量 `DISCUSS_ACCESS`),连同参与说明私下交给对应 AI 会话,由人工或软件原生定时触发;讨论里的手动专家只在被安排发言时参与,没有及时回答时消息区显示等待发言卡片,可在进度看板点“跳过”本次发言,交给主持人继续安排;网页 AI 仍只用于自由协作,网页 AI 只能阅读房间,回答由你代发;它从自己的服务器读取阅读链接,只在本机运行的网站(`127.0.0.1`)它读不到,需由你粘贴材料。只有手动和网页成员时建房无需本机接入服务。详见 [自由协作房间](docs/workflow.md#自由协作房间)。
119
119
 
@@ -106,10 +106,20 @@ def runtime_view(connection, room_id):
106
106
  event = connection.execute("SELECT id,participant,role,status,result FROM discussion_events WHERE room_id=? ORDER BY id DESC LIMIT 1", (room_id,)).fetchone()
107
107
  result["latest_execution"] = dict(event) if event else None
108
108
  result["participants"] = participant_executions(connection, room_id)
109
+ result["failures"] = failed_executions(connection, room_id)
109
110
  result["timings"] = execution_timings(connection, room_id, row["run_id"])
110
111
  return result
111
112
 
112
113
 
114
+ def failed_executions(connection, room_id):
115
+ """Keep failed attempts readable after a retry, without exposing execution credentials."""
116
+ return [dict(row) for row in connection.execute("""SELECT e.id,e.participant,e.role,e.turn_id,
117
+ e.result,e.created_at,CASE WHEN t.dispatched_at>0 AND t.finished_at>0
118
+ THEN MAX(0,t.finished_at-t.dispatched_at) END AS elapsed_seconds
119
+ FROM discussion_events AS e LEFT JOIN event_timings AS t ON t.event_id=e.id
120
+ WHERE e.room_id=? AND e.status='failed' ORDER BY e.id""", (room_id,))]
121
+
122
+
113
123
  def execution_timings(connection, room_id, run_id):
114
124
  """Summarize stage durations of the current run so slow stages are visible."""
115
125
  now = int(time.time())
package/backend/server.py CHANGED
@@ -1610,6 +1610,10 @@ class DiscussionHandler(BaseHTTPRequestHandler):
1610
1610
  raise LookupError("地址不存在")
1611
1611
  room_id = parts[2]
1612
1612
  token = self.headers.get("X-Discussion-Token", "")
1613
+ if self.headers.get("X-Discussion-Session"):
1614
+ record_reported_session(connection, room_id, token, {"session_id": self.headers.get("X-Discussion-Session"),
1615
+ "session_client": self.headers.get("X-Discussion-Session-Client")})
1616
+ connection.commit()
1613
1617
  free = room_mode(connection, room_id) == "free"
1614
1618
  if free and parts[3:4] in (["inbox"], ["executions"], ["members"], ["suggestions"], ["recommendations"]):
1615
1619
  return self.handle_free_api(connection, parts, method)
@@ -181,11 +181,11 @@ Python 在一个只读事务快照中查询;D1 使用同一个 batch 事务读
181
181
 
182
182
  浮层(菜单、预览、消息工具条、抽屉与弹窗)在深色频道使用毛玻璃:半透明上亮下暗渐变底配合 24px 背景模糊与增艳,边缘只用顶部内侧亮线、底部内侧暗线和向下投影,不加外侧白色辉光。浅色频道的控件本体保持不透明白色,只学习材质边界:蓝灰细描边、内侧顶部高光、内侧底部浅蓝灰暗边和蓝灰多层投影,按控件、面板、浮层三级加强。外观设置的「视觉效果」可切换为精简,写入根节点 `data-effects="reduced"` 并随布局偏好保存在浏览器;精简模式全局关闭背景模糊,深色浮层改为实色,深浅阴影各退为单层,用于保证低配设备的流畅度。浅色频道的发言快速导航不加底板,刻度改为发言者实色、固定 2px 粗细(覆盖脚本动画的内联高度,长度与透明度仍由脚本驱动),轮次号与轮次分隔比辅助文字深一级。
183
183
 
184
- 选中状态用填色、文字和勾选表达,键盘焦点使用中性边缘,不增加蓝色外框;卡片、模型选择、强度滑杆、模式、时长及编辑区遵循同一规则。加载图标在各处统一为每 3 秒匀速旋转一圈;系统开启“减少动态效果”时保留静态图标,不再旋转。
184
+ 选中状态用填色、文字和勾选表达,键盘焦点使用中性边缘,不增加蓝色外框;卡片、模型选择、强度滑杆、模式、时长及编辑区遵循同一规则。加载图标在各处统一为每 3 秒匀速旋转一圈;系统开启“减少动态效果”时仍保留缓慢旋转,以表示请求正在进行,其余动效继续遵循减弱设置。
185
185
 
186
186
  接入页分别交付本地成员的私有配置文件和不含 token 的参与说明,在线成员只给阅读说明;前端快照仅含成员接入方式与文件可用状态。手动创建、邀请、请回直接请求网站,自动成员才经本机启动器。创建与成员变更在请求前保存原编号和凭据,结果不明时沿用;复制说明不代表已送达或接入。项目、工作目录、讨论上限和错误按需展开。暂停后的本场软件连接修正使用独立卡片,页面不推断本机服务在线状态,选择模式或下载配置不会启动讨论。
187
187
 
188
- 消息区显示议题、原文和主持简报;议题卡的参与配置使用与头像一致的 20px 行高,姓名与主持 / CLI 标签保留字号层级并垂直居中。全自动执行期间,消息流末尾按有效执行显示等待状态:专家复用发言卡片的头像、姓名、轮次与样式,显示“正在唤醒…”或“正在准备回复…”;主持执行使用同宽、更矮、弱化底色和边框的“主持工作”卡,显示头像、姓名及右上角耗时,按交付与进入状态显示“正在唤醒主持人…”或“正在安排下一步…”,不推测内部操作。卡片类型按本次执行职责区分,主持人作为专家回答时仍使用专家等待卡;正式主持发言保留普通消息卡。手动接入专家轮到发言时,即使没有自动执行,也按当前安排显示“等待发言”卡片,提示到该 AI 会话发送启动指令;标注“手动接入”,不显示执行动画或耗时。输入区的“复制启动指令”使用无底色、无描边的复制图标文字按钮,复制成功后原位显示“已复制”。自动成员仅有待处理安排、执行过期、暂停或归档时不显示等待卡片。卡片不计入消息记录,没有消息编号、回复或引用操作;执行结束、手动安排已回答或取消后移除;下一位自动专家实际交付、手动专家轮到发言时显示对应卡片。右侧进度看板的“跳过”取消当前专家本次安排及有效执行,保留排队安排并交给主持人继续安排,不暂停讨论。搜索与提及筛选时隐藏,状态更新仅在用户原本位于底部时跟随滚动。标题栏、窄屏标签栏与主持简报合为同一块顶部面板,简报展开内容留在面板内,与收起状态共用背景、边线与投影,不再另起浮层。消息视图中该面板浮在消息列表之上,使用与深色浮层同款的毛玻璃(半透明渐变底、24px 背景模糊与增艳;浅色为白色半透明),滚动经过的卡片在其下模糊可见;消息列表顶部留白、导航与筛选条下移量、跳转与当前消息判定都按收起时的面板高度计算,展开简报只覆盖消息,不推动消息与输入区。其他视图中面板按普通流式布局排列。精简视觉效果下面板改为实色。已存档房间在独立弹窗管理,不改变当前房间和草稿。存档房间仍可阅读、恢复与导出;批量删除作用于当前搜索和筛选结果,执行前确认。
188
+ 消息区显示议题、原文和主持简报;议题卡的参与配置使用与头像一致的 20px 行高,姓名与主持 / CLI 标签保留字号层级并垂直居中。全自动执行期间,消息流末尾按有效执行显示等待状态:专家复用发言卡片的头像、姓名、轮次与样式,显示“正在唤醒…”或“正在准备回复…”;主持执行使用同宽、更矮、弱化底色和边框的“主持工作”卡,显示头像、姓名及右上角耗时,按交付与进入状态显示“正在唤醒主持人…”或“正在安排下一步…”,不推测内部操作。卡片类型按本次执行职责区分,主持人作为专家回答时仍使用专家等待卡;正式主持发言保留普通消息卡。手动接入专家轮到发言时,即使没有自动执行,也按当前安排显示“等待发言”卡片,提示到该 AI 会话发送启动指令;标注“手动接入”,不显示执行动画或耗时。输入区的“复制启动指令”使用无底色、无描边的复制图标文字按钮,复制成功后原位显示“已复制”。自动成员仅有待处理安排、执行过期、暂停或归档时不显示等待卡片。卡片不计入消息记录,没有消息编号、回复或引用操作;执行成功或取消、手动安排已回答或取消后移除;失败执行保留为时间顺序中的卡片,显示失败原因、执行编号及已记录耗时,刷新、重试和收束后仍可查看。拥有控制凭据的浏览器可在当前失败卡片上点“重试”,沿用保留的安排创建新的执行;旧失败卡不消失,也不会作为 AI 原文计数,历史安排已变化时不提供重试;下一位自动专家实际交付、手动专家轮到发言时显示对应卡片。右侧进度看板的“跳过”取消当前专家本次安排及有效执行,保留排队安排并交给主持人继续安排,不暂停讨论。操作按钮保持单行排列。因执行失败或用户操作而暂停、且仍保留当前安排时,仍可点“跳过”:先取消该安排,再按当前运行版本恢复讨论,唤醒主持人而不重试被跳过的专家;恢复失败时说明安排已跳过,可核对后用“重启”继续。搜索与提及筛选时隐藏,状态更新仅在用户原本位于底部时跟随滚动。标题栏、窄屏标签栏与主持简报合为同一块顶部面板,简报展开内容留在面板内,与收起状态共用背景、边线与投影,不再另起浮层。消息视图中该面板浮在消息列表之上,使用与深色浮层同款的毛玻璃(半透明渐变底、24px 背景模糊与增艳;浅色为白色半透明),滚动经过的卡片在其下模糊可见;消息列表顶部留白、导航与筛选条下移量、跳转与当前消息判定都按收起时的面板高度计算,展开简报只覆盖消息,不推动消息与输入区。其他视图中面板按普通流式布局排列。精简视觉效果下面板改为实色。已存档房间在独立弹窗管理,不改变当前房间和草稿。存档房间仍可阅读、恢复与导出;批量删除作用于当前搜索和筛选结果,执行前确认。
189
189
 
190
190
  所有发言卡片右上角显示耗时。等待卡片使用同一执行的 `runtime.timings` 唤醒与执行秒数之和,从交付唤醒起累计,不计之前排队;本地每秒更新,服务器计时变化时校准,状态结束或切换房间后停止。正式发言的 `elapsed_seconds` 在保存消息的同一事务内按有效执行凭据与原作者关联计算,保存在 `message_timings`,此后翻页、重试和运行结束均不改变。主持发言同样计到各自保存时刻;不接受客户端提供的耗时。用户留言、手动或代发内容及缺少记录的旧消息显示“耗时 —”。升级仅为有精确 `message:ID` 完成结果与计时记录的历史专家发言回填,不按时间邻近推测关联,不覆盖已有耗时。
191
191
 
@@ -237,7 +237,7 @@ running 状态即使只有 pending 事件,也必须先暂停才能重新启动
237
237
 
238
238
  两种房间的用户写入、运行控制及成员管理都必须携带建房时的房主控制凭据;`actor`、`author`、`submitted_by` 只是声明。`room_modes` 为所有新房间保存控制哈希,`room_members` 保存每个实例的独立成员哈希、能力和主持职责。讨论房间的手动本地成员用自己的持久成员凭证;在线成员不能自行写入,由房主或获授主持职责的本地成员代发。成员主持可维护资料、摘要、阶段和安排,不能改名单、授予主持权限、控制自动运行或删除房间。房主凭据不能冒充本地成员提交观点。自动讨论里本机唤醒的成员仍要求本次有效执行凭据,持久成员凭证不能替代执行租约;手动接入的专家(`access=manual`、`adapter=manual`,主持人除外)用自己的成员凭证回答安排,其待派发事件由接入程序跳过,回答保存后由触发器完成事件并唤醒主持人。
239
239
 
240
- 房间响应的 `runtime.timings` 汇总当前运行各执行的阶段耗时:排队(事件产生到 reserve)、唤醒(reserve 到 AI enter)、执行(enter 到完成、撤销或失败),未结束的阶段计到当前时间;返回最近 20 条与全部合计,进度看板据此展示。升级前的执行没有计时记录,不计入。
240
+ 房间响应的 `runtime.timings` 汇总当前运行各执行的阶段耗时:排队(事件产生到 reserve)、唤醒(reserve 到 AI enter)、执行(enter 到完成、撤销或失败),未结束的阶段计到当前时间;返回最近 20 条与全部合计,进度看板据此展示。升级前的执行没有计时记录,不计入。 `runtime.failures` 单独返回本房间全部失败执行的公开字段(编号、参与者、职责、安排、原因、创建时间与交付到失败的固定耗时),不随新执行覆盖,也不受最近 20 条计时截断影响;旧执行没有计时数据时耗时为 null。前端重试前重读房间,核对最新失败执行与当前保留的安排,再使用现有 runtime start 和 revision 校验恢复;无需新增表或更改执行重试协议。
241
241
 
242
242
  每房间最多一个 dispatched/started 执行;写入同时校验运行代次、期限、身份及职责。租约 120 秒,通知程序每 30 秒续租,单步采用 discussion_limits.execution_minutes,新建默认 0(不限),非零值为 1–60 分钟;设置了整场截止时取更早期限。不限单步时长仍要求有效的租约、运行代次和身份,续租不设隐含执行截止。schema 重建建房触发器并显式写入 0,使旧表默认值为 20 的数据库中新建房间也默认不限,已有房间的配置保持不变。通知受理未必开始,开始未必完成。运行和最新执行状态对网页可见,控制哈希与执行哈希不公开。备份保持原有讨论数据范围,不导出运行凭据或本机绑定。
243
243
 
@@ -248,7 +248,7 @@ running 状态即使只有 pending 事件,也必须先暂停才能重新启动
248
248
  自由房间(`room_modes.mode='free'`)与讨论房间共用房间、成员登记、消息、附件与目录,没有发言权、安排、阶段推进和轮次。没有控制凭据登记的旧房间只供阅读,不支持通过首次运行配置认领;本次不迁移历史房间。
249
249
 
250
250
  - **凭据**:建房时由客户端提供房间控制凭据和每位成员的成员凭证,服务端只存哈希。用户身份的房间写入(发言、附件、存档、恢复、删除、打断)都须控制凭据;房间排序和归入文件夹只改共享目录,与站点级文件夹操作一样不需要凭据;无凭据、错误凭据、成员凭证或他房凭据一律只读。成员凭证只能以该成员身份发言或上传附件。声明字段(`author`、`source`、localhost)不代替凭据。
251
- - **成员**:`room_members` 以 `id` 为稳定主键,`access` 为 `runner`(接入程序投递)、`manual`(成员自行读写)或 `online`(只读、原文代发),`session_mode` 标记是否借用用户正在使用的会话。房主用控制凭据 `POST members` 运行中加入成员,`POST members/ID {action}` 让成员离开(`away`,作废其进行中执行与未投递请求)、请回(`active`,必须提供不同于原凭证的新凭证,旧凭证副本不再有效)或移除(`remove`,保留历史发言)。同一成员凭证不能复用于其他成员或房主;相同凭证与配置的邀请、请回重试返回已有结果。会话续接由本机接入程序负责,服务端不保存会话绑定;唯一例外是手动成员上报的会话:`message post` 可带 `session_id` 与 `session_client`(CLI 读取 `CLAUDE_CODE_SESSION_ID` 或 `CODEX_THREAD_ID`,取值 `claude` / `codex`),服务端在 `member_sessions` 保存该手动成员最近上报的会话,成员视图以 `reported_session` 暴露。房主用 `POST members/ID {action:"adopt", adapter:"claude", session_id}`(须与上报一致、仅全自动讨论中在场的手动成员)把成员改为 `runner`、`borrowed` 并清除上报,本机接入程序据此接管。两套后端行为一致。
251
+ - **成员**:`room_members` 以 `id` 为稳定主键,`access` 为 `runner`(接入程序投递)、`manual`(成员自行读写)或 `online`(只读、原文代发),`session_mode` 标记是否借用用户正在使用的会话。房主用控制凭据 `POST members` 运行中加入成员,`POST members/ID {action}` 让成员离开(`away`,作废其进行中执行与未投递请求)、请回(`active`,必须提供不同于原凭证的新凭证,旧凭证副本不再有效)或移除(`remove`,保留历史发言)。同一成员凭证不能复用于其他成员或房主;相同凭证与配置的邀请、请回重试返回已有结果。会话续接由本机接入程序负责,服务端不保存会话绑定;唯一例外是手动成员上报的会话:带凭据的请求可带请求头 `X-Discussion-Session` 与 `X-Discussion-Session-Client`,`message post` 也可在正文带 `session_id` 与 `session_client`(CLI 读取 `CLAUDE_CODE_SESSION_ID` 或 `CODEX_THREAD_ID`,取值 `claude` / `codex`),服务端在 `member_sessions` 保存该手动成员最近上报的会话,成员视图以 `reported_session` 暴露。房主用 `POST members/ID {action:"adopt", adapter:"claude", session_id}`(须与上报一致、仅全自动讨论中在场的手动成员)把成员改为 `runner`、`borrowed` 并清除上报,本机接入程序据此接管。两套后端行为一致。
252
252
  - **请求**:用户消息按结构化接收者 `to`(成员名)为每位成员生成一条请求;省略且仅有一位在场成员时默认点名该成员,多位成员时交给主持人(`route`),只有在线成员而没有主持人时只作留言,不广播。网页只从正文中代码与引用之外的 `@成员` 生成 `to`,没有 @ 时省略 `to`。请求状态为 `pending`(待投递)→ `delivering`(处理中)→ `completed` / `cancelled` / `failed`。
253
253
  - **执行**:`member_executions` 每位成员最多一个 `dispatched/started`(部分唯一索引),不同成员可并行。接入程序用控制凭据 `GET inbox`、`POST executions {member_id, client_id}`(同一 `client_id` 返回同一执行)把成员的全部待投递请求打包;`POST executions/ID {action}` 支持 `renew`(租约 120 秒,不超过单次执行时限,默认 20 分钟)、`fail`(请求标记失败)和 `release`(仅确认未送达时退回队列)。租约过期的执行在下次读取或领取时标记失败,不自动重发。
254
254
  - **主持人与任务链**:用户是需求方,不担任主持人。只要有在场的非在线成员,房间就保持恰好一位主持人:成员变动时,离开或移出的主持人失去角色,由第一位在场的 runner 成员(没有则手动成员)接任;建房和每条房主消息前也做同样的补位,因此旧房间在下一条消息时自动获得主持人。房主用 `POST members/ID {action:"role", role:"host"}` 更换主持人(在线成员不能担任),把现任主持人改为 `member` 会被拒绝。多位成员时未点名的房主消息生成给主持人的 `route` 请求。主持人的回答可带 `to` 点名其他成员(不能点名自己),这些请求组成一个批次(`free_batches`);批次内全部进入终态后,只要有一个完成就给主持人生成一次 `handoff` 请求,全部失败则停下该任务链。每条房主消息开启一条任务链(`chain_id` 为该消息编号),链上 AI 发起的请求(派活与回交)最多 8 次,超出即停下(`free_chains`,原因 `budget` / `all_failed`),房主发新消息开启新链。Worker 用同一批次内的集合 SQL 完成回交,回交请求按(派活消息,主持人)唯一,重复执行不会重复唤醒。
package/docs/cli.md CHANGED
@@ -35,7 +35,7 @@ Bash 对应 `export DISCUSS_URL=http://127.0.0.1:8765`,CMD 对应 `set DISCUSS
35
35
 
36
36
  建房与更新资料支持 `--user-request` / `--user-request-file`,将用户原文与 `--background` 分开保存,各限 4000 字。`room brief` 返回两者,概要和通知不自动展开原文。
37
37
 
38
- `room create` 必须指定 `--access-file 私有文件`,CLI 在请求前原子保存建房编号、房主和各成员凭据,确认房间后另写各本地成员的独立文件,回执只返回 `member_access_files` 路径。结果不明时沿用同一文件、编号和创建参数;不能换文件重建。后续每次写入使用对应身份的文件,不能拿房主文件冒充成员;自动讨论使用本次任务文件中的执行凭据。文件含 `site`、`room`、`token`,CLI 检查站点与房间匹配。同样内容的单行 JSON 文本可放入环境变量 `DISCUSS_ACCESS`(或 `--access-file -` 从标准输入读取),未传 `--access-file` 时使用;成员菜单的“复制凭证文本”复制的就是这段文本,含 token,只交给该成员,不要写进命令行参数或回显。`--dry-run` 不生成或写入凭据,预览会隐藏凭据字段。`message post` 在 Claude Code 会话中运行时自动附带 `session_id` 与 `session_client: "claude"`(取自 `CLAUDE_CODE_SESSION_ID`;Codex 为 `session_client: "codex"`,取自 `CODEX_THREAD_ID`),服务端仅对手动成员保存,供本机服务转为托管;其他情况忽略。
38
+ `room create` 必须指定 `--access-file 私有文件`,CLI 在请求前原子保存建房编号、房主和各成员凭据,确认房间后另写各本地成员的独立文件,回执只返回 `member_access_files` 路径。结果不明时沿用同一文件、编号和创建参数;不能换文件重建。后续每次写入使用对应身份的文件,不能拿房主文件冒充成员;自动讨论使用本次任务文件中的执行凭据。文件含 `site`、`room`、`token`,CLI 检查站点与房间匹配。同样内容的单行 JSON 文本可放入环境变量 `DISCUSS_ACCESS`(或 `--access-file -` 从标准输入读取),未传 `--access-file` 时使用;成员菜单的“复制凭证文本”复制的就是这段文本,含 token,只交给该成员,不要写进命令行参数或回显。`--dry-run` 不生成或写入凭据,预览会隐藏凭据字段。CLI 在 Claude Code / Codex 会话中运行时,所有带凭据的请求自动附带请求头 `X-Discussion-Session` 与 `X-Discussion-Session-Client`,`message post` 另在正文带 `session_id` 与 `session_client`(`claude` 取自 `CLAUDE_CODE_SESSION_ID`,`codex` 取自 `CODEX_THREAD_ID`),服务端仅对手动成员保存,供本机服务转为托管;其他情况忽略。
39
39
 
40
40
  接入程序新启动的 CLI 使用 `DISCUSS_ACCESS_FILE` 绑定本次凭据文件,日常读写可省略 `--access-file`;文件每次重新读取,保留会话绑定与房间、站点检查。优先级为显式 `--access-file` → `DISCUSS_ACCESS_FILE` 文件 → `DISCUSS_ACCESS` JSON;已指定文件损坏或缺失时直接报错,不回退其他身份。首次接入已有会话和 App 仍使用交付的文件路径。建房仍须显式指定新凭据的保存路径。
41
41