@modesto_ma/dsh-channels 0.5.0-beta.4 → 0.5.0-beta.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.
package/lib/index.js CHANGED
@@ -16221,7 +16221,7 @@ function resolveConfig(raw) {
16221
16221
  * Web 设置面板的线上契约:Host 半侧的路由/面板数据与 Browser 半侧的渲染共用。
16222
16222
  *
16223
16223
  * 本模块**没有运行时依赖**:Host 与 Client bundle 都直接内联它。因此这里只放
16224
- * 常量、字段清单与可序列化的 wire 类型,不 import zod / node / DSH 内部包。
16224
+ * 常量、字段清单、可序列化的 wire 类型与无依赖的纯文案函数,不 import zod / node / DSH 内部包。
16225
16225
  *
16226
16226
  * @module dsh-channels/settings/contract
16227
16227
  */
@@ -16269,43 +16269,50 @@ const PICK_DIRECTORY_ROUTE = "/dsh-channels/pick-directory";
16269
16269
  * `baseDir`(工作区根目录 = 模型/工具产生文件的落点)可覆盖,但面板只接受
16270
16270
  * **绝对路径**(`~` 会展开);已有 Session / 目录不迁移,只影响之后新建的
16271
16271
  * 会话。校验与保存时建目录见 `src/workspaces.ts`。
16272
+ *
16273
+ * 数组顺序就是面板里同一分组内字段的显示顺序。
16272
16274
  */
16273
16275
  const EDITABLE_KEYS = [
16274
- "baseDir",
16275
16276
  "dmMode",
16276
16277
  "requireMention",
16277
16278
  "threadFallback",
16279
+ "baseDir",
16280
+ "topicIsolation",
16281
+ "routeTtlMs",
16282
+ "approvalTimeoutMs",
16283
+ "questionTimeoutMs",
16284
+ "refreshMs",
16285
+ "statusRefreshMs",
16278
16286
  "welcomeOnboarding",
16279
16287
  "slashCommandPanel",
16280
16288
  "allowPermissionSwitch",
16281
- "analyzeListen",
16282
- "adminUserId",
16283
- "accessMode",
16284
- "authRequestTtlDays",
16289
+ "provider",
16290
+ "model",
16291
+ "reasoningEffort",
16292
+ "maxTokens",
16293
+ "agentPreset",
16285
16294
  "acceptAttachments",
16286
16295
  "attachmentStore",
16287
16296
  "prefetchImages",
16297
+ "historyBootstrapLimit",
16298
+ "feishuTools.attachmentFetch",
16299
+ "feishuTools.topicMessages",
16300
+ "feishuTools.sendFile",
16288
16301
  "prefetchTimeoutMs",
16289
16302
  "prefetchImageMaxBytes",
16290
16303
  "prefetchTotalMaxBytes",
16291
- "historyBootstrapLimit",
16292
- "feishuTools.attachmentFetch",
16293
16304
  "feishuTools.attachmentFetchMaxResources",
16294
16305
  "feishuTools.attachmentFetchMaxBytes",
16295
16306
  "feishuTools.attachmentFetchTimeoutMs",
16296
- "feishuTools.topicMessages",
16297
16307
  "feishuTools.topicMessagesTimeoutMs",
16298
- "feishuTools.sendFile",
16308
+ "promptContextTimeoutMs",
16309
+ "accessMode",
16310
+ "adminUserId",
16311
+ "authRequestTtlDays",
16299
16312
  "feishuTools.wikiRead",
16300
16313
  "feishuTools.wikiWrite",
16301
16314
  "wikiRoots",
16302
- "promptContextTimeoutMs",
16303
- "provider",
16304
- "model",
16305
- "reasoningEffort",
16306
- "agentPreset",
16307
- "refreshMs",
16308
- "statusRefreshMs",
16315
+ "analyzeListen",
16309
16316
  "loggerLevel"
16310
16317
  ];
16311
16318
  /**
@@ -16321,66 +16328,57 @@ const RESTART_KEYS = [
16321
16328
  "statusRefreshMs",
16322
16329
  "loggerLevel"
16323
16330
  ];
16331
+ /** `unit` of byte-count fields; the panel adds a MiB reading next to them. */
16332
+ const BYTES_UNIT = "字节";
16324
16333
  /** Display labels for the panel header/cards (kept on the wire so the client owns no copy). */
16325
16334
  const PANEL_COPY = {
16326
16335
  title: "飞书渠道",
16327
- description: "飞书长连接、应用凭据与渠道配置。凭据只写入 DSH 凭据库且不回显;标注「需重连」的项在连接建立时读取。",
16328
- statusCard: "连接状态",
16329
16336
  phaseUnconfigured: "待配置",
16330
16337
  phaseIdle: "未连接",
16331
16338
  phaseConnecting: "连接中",
16332
16339
  phaseConnected: "已连接",
16333
16340
  phaseError: "连接失败",
16334
- configuredBadge: "凭据已配置",
16335
- unconfiguredBadge: "凭据未配置",
16336
- statusSummaryConnected: "飞书长连接已建立,机器人可以收发消息。",
16337
- statusSummaryUnconfigured: "尚未配置飞书应用凭据:插件已加载,但不会连接飞书。填写凭据并保存后会自动连接。",
16338
- statusSummaryIdle: "飞书应用凭据已就绪,但当前没有建立长连接。",
16339
- statusSummaryConnecting: "正在连接飞书长连接…",
16340
- statusSummaryError: "最近一次连接飞书失败,请检查凭据与网络后重试。",
16341
+ statusSummaryConnected: "机器人在线,可以收发消息",
16342
+ statusSummaryUnconfigured: "还没有填写飞书应用凭据,插件不会连接飞书",
16343
+ statusSummaryIdle: "凭据已就绪,还没有建立连接",
16344
+ statusSummaryConnecting: "正在连接飞书…",
16345
+ statusSummaryError: "连接飞书失败,请检查凭据与网络后重试",
16346
+ uptimePrefix: "运行",
16341
16347
  lastError: "最近一次连接失败",
16342
- scopeCheckTitle: "权限自检",
16343
- scopeCheckOk: "已开通插件需要的全部飞书权限。",
16344
- scopeCheckMissing: "以下飞书权限未开通,开通后需在开发者后台发布新版本:",
16345
- scopeCheckOpenAll: "在开发者后台开通全部缺失权限",
16348
+ checksTitle: "自检",
16349
+ scopeCheckOk: "插件需要的飞书权限都已开通",
16350
+ scopeCheckMissing: "{n} 项权限未开通",
16351
+ scopeCheckMissingRequired: "{n} 项必需权限未开通,相关功能无法使用",
16352
+ scopeCheckMissingOptional: "不影响收发消息,只有相关功能不可用。开通后需在开发者后台发布新版本。",
16353
+ scopeCheckPublish: "开通后需在开发者后台发布新版本。",
16354
+ scopeCheckOpenAll: "全部开通",
16346
16355
  scopeCheckOpenOne: "去开通",
16347
- scopeCheckOptional: "可选",
16348
16356
  scopeCheckRequired: "必需",
16349
- scopeCheckError: "无法读取应用的权限授予状态:",
16357
+ scopeCheckError: "无法读取权限开通情况",
16350
16358
  slashCommandSyncTitle: "斜杠指令面板",
16351
- slashCommandSyncOk: "插件命令已同步到飞书原生斜杠指令面板,在聊天框输入 / 即可选择(飞书客户端约 5 分钟后刷新)。",
16352
- slashCommandSyncTotal: "命令数",
16353
- slashCommandSyncCreated: "本次新增",
16354
- slashCommandSyncUpdated: "本次更新",
16355
- slashCommandSyncRemoved: "本次删除",
16356
- slashCommandSyncError: "同步飞书原生斜杠指令面板失败(不影响直接输入命令):",
16359
+ slashCommandSyncOk: "已同步 {total} 条命令,飞书客户端约 5 分钟后刷新",
16360
+ slashCommandSyncError: "同步失败,直接输入命令不受影响",
16357
16361
  missingConfig: "缺少配置",
16358
- statusHintUnconfigured: "配置完成后插件会自动连接;也可以稍后在本页手动连接。",
16359
- connectionInfo: "连接信息",
16360
- connectionStateLabel: "飞书长连接",
16361
- botOpenId: "Bot open_id",
16362
- uptime: "运行时长",
16363
16362
  routeCount: "话题路由",
16364
16363
  liveAgentCount: "活动会话",
16365
16364
  inflightTurnCount: "在途回复",
16365
+ botOpenId: "Bot open_id",
16366
16366
  healthReasons: "健康判定",
16367
16367
  unknownValue: "—",
16368
16368
  connect: "连接飞书",
16369
16369
  connecting: "连接中…",
16370
16370
  onboardingTitle: "开始使用飞书渠道",
16371
- onboardingIntro: "只需三步:在飞书开放平台创建自建应用,把 App ID / App Secret 填入本页,保存后自动连接。",
16372
16371
  onboardingStep1Title: "创建飞书自建应用",
16373
- onboardingStep1Text: "在飞书开放平台创建企业自建应用,开启机器人能力;事件订阅选择「长连接」,订阅 im.message.receive_v1(接收消息)。",
16372
+ onboardingStep1Text: "在 open.feishu.cn/app 创建企业自建应用,开启机器人能力;事件订阅选「长连接」,订阅 im.message.receive_v1。",
16374
16373
  onboardingStep2Title: "填写应用凭据",
16375
- onboardingStep2Text: "把应用的 App ID(cli_ 开头)与 App Secret 填入下方「飞书应用凭据」,值会写入 DSH 凭据库。",
16376
- onboardingStep3Title: "保存并等待连接",
16377
- onboardingStep3Text: "两项凭据都保存后插件会自动连接;状态变为「已连接」即可在飞书里私聊机器人。",
16378
- onboardingDocsHint: "开放平台地址:open.feishu.cn/app;应用需要开通 im:message、im:message:send_as_bot 等消息权限。",
16379
- credentialsCard: "飞书应用凭据",
16380
- credentialsCardHelp: "凭据值经 DSH 凭据服务写入本机凭据库;面板只显示「已配置 / 未配置」,永不回显已存值。两项都配置后才会连接飞书。",
16381
- appIdLabel: "飞书 App ID",
16382
- appSecretLabel: "飞书 App Secret",
16383
- credentialsRef: "凭据引用",
16374
+ onboardingStep2Text: "把 App ID(cli_ 开头)和 App Secret 填到下方「应用凭据」。",
16375
+ onboardingStep3Title: "保存后自动连接",
16376
+ onboardingStep3Text: "两项都保存后插件会自动连接,状态变成「已连接」就能在飞书里私聊机器人。",
16377
+ credentialsTitle: "应用凭据",
16378
+ credentialsHint: "值只存在本机凭据库,面板不回显。",
16379
+ appIdLabel: "App ID",
16380
+ appSecretLabel: "App Secret",
16381
+ credentialStore: "凭据库",
16384
16382
  saveCredentials: "保存凭据",
16385
16383
  savingCredentials: "保存中…",
16386
16384
  credentialSaved: "凭据已保存",
@@ -16390,27 +16388,29 @@ const PANEL_COPY = {
16390
16388
  credentialAutoConnectFailed: "凭据已保存,但自动连接失败",
16391
16389
  credentialRemoved: "已移除存储的凭据",
16392
16390
  credentialRemovedPending: "已移除存储的凭据,重启飞书连接后生效",
16393
- removeCredential: "移除已存值",
16391
+ replaceCredential: "更换",
16392
+ setCredential: "设置",
16393
+ cancel: "取消",
16394
+ removeCredential: "移除",
16394
16395
  removingCredential: "移除中…",
16395
16396
  credentialConfigured: "已配置",
16396
16397
  credentialMissing: "未配置",
16397
16398
  credentialReadOnly: "当前凭据存储不可写",
16398
16399
  appIdPlaceholder: "输入 App ID(cli_…)",
16399
16400
  appSecretPlaceholder: "输入 App Secret",
16400
- credentialsPendingHint: "填写后点「保存凭据」;两项齐全时插件会自动连接飞书。",
16401
- connectionTabHelp: "连接状态与飞书应用凭据。凭据不完整时不会连接飞书。",
16402
- sessionsTabHelp: "私聊、群聊触发方式与入站内容:附件存储/预取、模型工具开关与读取预算;「需重连」项在下次连接时读取。",
16403
- modelTabHelp: "飞书会话使用的模型服务商、模型、推理档位与 Agent 预设;下拉选项来自宿主机实时目录,保存后对新会话生效。",
16404
- workspaceTabHelp: "每个用户一个工作区(模型/工具产生文件的落点),每个话题在其中拥有独立工作目录;只影响之后新建的话题。入站附件默认存于 DSH 原生附件库,不占用话题目录。插件不会自动删除工作区或话题目录;过期目录可手动删除,话题下次对话时会重建空目录。",
16405
- accessTabHelp: "准入采用 fail-closed:管理员不受白名单限制,非管理员私聊会被拒绝,群聊需要「群已授权 + 用户在白名单」两层同时命中。",
16406
- wikiTabHelp: "知识库工具以应用身份访问「知识库范围」内的文档、电子表格和多维表格。只有管理员或知识库白名单里的用户发起的话题能用;每次打开、新建、修改仍需话题发起人在授权卡上确认。",
16407
- advancedTabHelp: "流式刷新等低层参数、Web 覆盖文件与只读信息。",
16408
- save: "保存更改",
16401
+ credentialRemoveConfirm: "确定移除已存储的凭据值?移除后不会回显,需要时须重新填写。",
16402
+ save: "保存",
16409
16403
  saving: "保存中…",
16410
- saveHintDirty: "只保存改动过的字段;标注「需重连」的项在下次连接时生效。",
16411
- discardTab: "放弃本页更改",
16412
- saveHintClean: "没有未保存的更改。",
16413
- dirtyCount: "未保存项",
16404
+ discard: "放弃",
16405
+ dirtyCount: "{n} 项未保存",
16406
+ dirtyRestart: ",其中 {n} 项需要重连后生效",
16407
+ details: "详情",
16408
+ expand: "展开",
16409
+ collapse: "收起",
16410
+ collapsedCount: "{n} 项",
16411
+ collapsedClean: "一般不用改",
16412
+ collapsedChanged: "{n} 项已在面板修改",
16413
+ restartTag: "需重连",
16414
16414
  listAdd: "添加",
16415
16415
  listRemove: "移除",
16416
16416
  listEntry: "第 {n} 项",
@@ -16422,62 +16422,55 @@ const PANEL_COPY = {
16422
16422
  directoryPicked: "已选择目录",
16423
16423
  directoryPickFailed: "无法打开系统目录选择器",
16424
16424
  saved: "已保存",
16425
- cleared: "已清除 Web 覆盖,恢复为 profile 配置",
16426
- clear: "清除 Web 覆盖",
16427
- clearing: "清除中…",
16428
- noOverrides: "当前没有 Web 覆盖",
16429
- overridden: "Web 覆盖",
16430
- inherited: "继承 profile",
16431
- restartTag: "需重连",
16432
- restartBanner: "以下配置需重启飞书连接后生效:",
16433
- restartWarning: "重启会断开当前飞书长连接并中断进行中的回复,请确认空闲时操作。",
16434
- reconnect: "重启飞书连接",
16425
+ saveInvalid: "请先修正标红的配置项",
16426
+ numberInvalid: "请输入数字",
16427
+ numberMin: "不得小于 {n}",
16428
+ numberMax: "不得大于 {n}",
16429
+ modelFootnote: "对之后新建的会话生效。",
16430
+ catalogFailed: "模型目录加载失败,已退回手填。",
16431
+ catalogLoading: "正在读取宿主机选项…",
16432
+ catalogUnavailable: "宿主机未提供可选项,请手填。",
16433
+ restartBanner: "以下配置要重启飞书连接后生效:",
16434
+ restartWarning: "重启会断开当前飞书连接并中断进行中的回复,确定现在重启?",
16435
+ reconnect: "重启连接",
16435
16436
  reconnecting: "重连中…",
16436
- refresh: "刷新状态",
16437
+ refresh: "刷新",
16437
16438
  retry: "重试",
16438
16439
  pollFailed: "状态刷新失败",
16439
16440
  connectDone: "已连接飞书",
16440
16441
  reconnectDone: "已重启飞书连接",
16441
- saveInvalid: "请先修正标红的配置项",
16442
- enabled: "已启用",
16443
- disabled: "已关闭",
16444
- credentialRemoveConfirm: "确定移除已存储的凭据值?移除后不会回显,需要时须重新填写。",
16445
- analyzeTokenCard: "日志分析接口令牌",
16446
- analyzeTokenCardHelp: "日志平台调用分析接口时 Authorization: Bearer 后面的值。经 DSH 凭据服务写入本机凭据库,面板永不回显;保存或移除后下一次请求即生效,无需重连。未配置时接口对所有请求返回 503。",
16442
+ loading: "加载中…",
16443
+ loadFailed: "设置面板加载失败",
16447
16444
  analyzeTokenLabel: "访问令牌",
16445
+ analyzeTokenSummary: "请求头 Authorization: Bearer 的值,保存后立即生效;未配置时接口拒绝所有请求",
16448
16446
  analyzeTokenPlaceholder: "填写新令牌(建议 32 位以上随机串)",
16449
- saveAnalyzeToken: "保存令牌",
16450
16447
  analyzeTokenSaved: "令牌已保存,下一次请求生效",
16451
16448
  analyzeTokenRemoved: "令牌已移除,接口将拒绝所有请求",
16452
- accessNotLoaded: "飞书连接建立后加载授权列表",
16453
- loading: "加载中…",
16454
- loadFailed: "设置面板加载失败",
16455
- catalogFailed: "模型目录加载失败,已退回手填。",
16456
- catalogLoading: "正在读取宿主机选项…",
16457
- catalogUnavailable: "宿主机未提供可选项,请手填。",
16458
- version: "插件版本",
16449
+ overlayTitle: "Web 覆盖",
16459
16450
  overlayPath: "覆盖文件",
16460
- overlayPathHelp: "可以直接编辑该 JSON 文件;面板保存会整体重写它,「清除 Web 覆盖」会删除它并回落到 profile 配置。",
16461
- advancedCard: "只读与高级信息",
16462
- advancedHelp: "这些值来自 profile 配置,不能在面板里编辑。",
16463
- readOnlyCard: "部署级参数",
16464
- accessCard: "访问与授权",
16465
- accessCardHelp: "准入采用 fail-closed:管理员不受白名单限制(私聊、任意群聊都可直接对话);非管理员私聊会被拒绝,群聊需要「群已授权 + 用户在白名单」两层同时命中。管理员与准入模式在上方「准入与授权」中编辑;私聊机器人发送 /userid 获取自己的 user_id。",
16466
- accessModeOpenWarning: "当前准入模式为开放(open):应用可用范围内的任何人都能开启对话。该模式不安全,仅建议调试时使用。",
16467
- accessAdminMissingWarning: "当前准入=guarded 但未配置管理员,也无法自动使用应用所有者,所有对话都会被拒绝。请在上方「准入与授权」填写管理员 user_id(私聊机器人发送 /userid 获取;私聊模式关闭时 /userid 不可用,可在飞书管理后台的成员详情里查看用户 ID)。",
16468
- accessAdminOwnerNotice: "未配置管理员,已自动使用应用所有者作为管理员:",
16451
+ overlayCount: "{n} 项配置由面板覆盖",
16452
+ noOverrides: "当前没有面板覆盖的配置",
16453
+ overlayPathHelp: "面板保存的配置写在这个 JSON 文件里,优先级高于 profile。可以直接编辑;面板保存会整体重写它。",
16454
+ clear: "恢复 profile 配置",
16455
+ clearing: "恢复中…",
16456
+ clearConfirm: "确定删除所有面板覆盖,恢复为 profile 配置?",
16457
+ cleared: "已恢复为 profile 配置",
16458
+ debugModeWarning: "调试模式已打开:应用可用范围内的任何人都能和机器人对话。用完请在「访问授权」关闭。",
16459
+ accessAdminMissingWarning: "没有可用的管理员,所有对话都会被拒绝。请在下方填写管理员 user_id(私聊机器人发送 /userid 获取)。",
16460
+ accessAdminOwnerSummary: "未单独设置,正在使用应用所有者 {id}",
16461
+ accessNotLoaded: "飞书连接建立后加载授权列表",
16462
+ accessRequestsTitle: "待处理申请",
16469
16463
  accessGroupsTitle: "已授权群",
16470
- accessGroupsEmpty: "尚未授权任何群。机器人被拉进群后,管理员会收到带 chat_id 的群信息卡;也可在群内发送 /groupid 获取。",
16471
16464
  accessUsersTitle: "已授权用户",
16472
- accessUsersEmpty: "尚未授权任何用户。已授权用户可在所有已授权群里与机器人对话(私聊仍只开给管理员)。",
16473
- accessRequestsTitle: "待处理申请",
16474
- accessRequestsEmpty: "没有待处理的授权申请。",
16475
- accessGroupChatIdPlaceholder: "群 chat_id(oc_…)",
16465
+ accessGroupsEmpty: "还没有授权任何群",
16466
+ accessUsersEmpty: "还没有授权任何用户",
16467
+ accessGroupChatIdPlaceholder: "chat_id(oc_…,群里发 /groupid 获取)",
16476
16468
  accessGroupNamePlaceholder: "群名(可选)",
16477
- accessUserIdPlaceholder: "用户 user_id",
16469
+ accessUserIdPlaceholder: "user_id(私聊机器人发 /userid 获取)",
16478
16470
  accessUserNamePlaceholder: "昵称(可选)",
16479
16471
  accessAddGroup: "添加群",
16480
16472
  accessAddUser: "添加用户",
16473
+ accessAdd: "添加",
16481
16474
  accessRemove: "移除",
16482
16475
  accessAllow: "授权",
16483
16476
  accessDeny: "忽略",
@@ -16485,23 +16478,22 @@ const PANEL_COPY = {
16485
16478
  accessSourceCommand: "对话命令",
16486
16479
  accessSourceCard: "授权卡",
16487
16480
  accessSourcePanel: "设置面板",
16488
- accessRequestGroup: "群申请",
16489
- accessRequestUser: "用户申请",
16490
- accessRequestRequester: "申请人",
16491
- accessRequestExpires: "有效期至",
16481
+ accessRequestGroup: "申请授权群",
16482
+ accessRequestUser: "申请使用",
16483
+ accessRequestIn: "在「{group}」",
16484
+ accessRequestExpires: "{date} 前有效",
16492
16485
  accessGroupAdded: "已添加群授权",
16493
16486
  accessGroupRemoved: "已移除群授权",
16494
16487
  accessUserAdded: "已添加用户授权",
16495
16488
  accessUserRemoved: "已移除用户授权",
16496
16489
  accessRequestAllowed: "已授权",
16497
16490
  accessRequestDenied: "已忽略",
16498
- accessHints: "三种授权入口:群内 /auth 命令、入群与用户授权卡、本面板。撤销立即生效;白名单只约束非管理员(管理员在任何私聊/群聊都直接放行),非管理员需要群和用户两层同时命中。",
16499
- wikiUsersCard: "知识库白名单",
16500
- wikiUsersHelp: "与「访问授权」里的用户白名单相互独立:这里的用户(以及管理员)发起的话题可以使用知识库工具。也可以在飞书里发送 /auth wiki add @用户 或 /auth wiki remove @用户;移除立即生效。",
16501
- wikiUsersEmpty: "知识库白名单为空:目前只有管理员发起的话题能使用知识库工具。",
16491
+ wikiUsersTitle: "可使用的人",
16492
+ wikiUsersAdminPlus: "管理员 + {n}",
16493
+ wikiUsersEmpty: "目前只有管理员发起的话题能用知识库工具",
16494
+ wikiUsersHint: "也可以在飞书发 /auth wiki add @用户",
16502
16495
  wikiUserAdded: "已加入知识库白名单",
16503
- wikiUserRemoved: "已移出知识库白名单",
16504
- accessChatIdHint: "chat_id 可从入群群信息卡或群内 /groupid 获取;user_id 可私聊机器人发送 /userid 获取。"
16496
+ wikiUserRemoved: "已移出知识库白名单"
16505
16497
  };
16506
16498
  //#endregion
16507
16499
  //#region src/settings/overlay.ts
@@ -19735,12 +19727,13 @@ const CREDENTIAL_FIELDS = [
19735
19727
  "appSecret",
19736
19728
  "analyzeToken"
19737
19729
  ];
19738
- /** Optional text fields: an empty string in the panel clears the override. */
19730
+ /** Optional fields: an empty string in the panel clears the override. */
19739
19731
  const OPTIONAL_TEXT_KEYS = /* @__PURE__ */ new Set([
19740
19732
  "provider",
19741
19733
  "model",
19742
19734
  "reasoningEffort",
19743
19735
  "agentPreset",
19736
+ "maxTokens",
19744
19737
  "adminUserId",
19745
19738
  "analyzeListen"
19746
19739
  ]);
@@ -19829,26 +19822,47 @@ function normalizeStringList(key, raw, spec) {
19829
19822
  };
19830
19823
  }
19831
19824
  const SELECT_OPTIONS = {
19832
- attachmentStore: [{
19833
- value: "native",
19834
- label: "DSH 原生附件库(默认)"
19835
- }, {
19836
- value: "archive",
19837
- label: "工作区 attachments/(旧版)"
19838
- }],
19839
19825
  dmMode: [{
19840
19826
  value: "open",
19841
- label: "开放私聊"
19827
+ label: "开启"
19842
19828
  }, {
19843
19829
  value: "disabled",
19844
- label: "禁用私聊"
19830
+ label: "关闭"
19845
19831
  }],
19846
19832
  threadFallback: [{
19847
19833
  value: "degrade",
19848
- label: "话题被拒时降级为会话级"
19834
+ label: "降级为会话级"
19849
19835
  }, {
19850
19836
  value: "strict",
19851
- label: "话题被拒时直接失败"
19837
+ label: "直接失败"
19838
+ }],
19839
+ topicIsolation: [
19840
+ {
19841
+ value: "auto",
19842
+ label: "自动(推荐)"
19843
+ },
19844
+ {
19845
+ value: "subdir",
19846
+ label: "普通子目录"
19847
+ },
19848
+ {
19849
+ value: "worktree",
19850
+ label: "Git worktree"
19851
+ }
19852
+ ],
19853
+ attachmentStore: [{
19854
+ value: "native",
19855
+ label: "DSH 原生附件库"
19856
+ }, {
19857
+ value: "archive",
19858
+ label: "话题目录 attachments/"
19859
+ }],
19860
+ accessMode: [{
19861
+ value: "guarded",
19862
+ label: "关闭(管理员与白名单)"
19863
+ }, {
19864
+ value: "open",
19865
+ label: "打开(所有人可聊)"
19852
19866
  }],
19853
19867
  loggerLevel: [
19854
19868
  {
@@ -19867,260 +19881,341 @@ const SELECT_OPTIONS = {
19867
19881
  value: "error",
19868
19882
  label: "error"
19869
19883
  }
19870
- ],
19871
- accessMode: [{
19872
- value: "guarded",
19873
- label: "守卫模式(仅管理员与白名单)"
19874
- }, {
19875
- value: "open",
19876
- label: "开放(不安全,仅调试)"
19877
- }]
19884
+ ]
19878
19885
  };
19879
- /** Panel copy per editable key: label, help, and (for numbers) bounds. */
19886
+ /** Two-value selects rendered as switches: the stored value while on / off. */
19887
+ const TOGGLES = {
19888
+ dmMode: {
19889
+ on: "open",
19890
+ off: "disabled"
19891
+ },
19892
+ threadFallback: {
19893
+ on: "degrade",
19894
+ off: "strict"
19895
+ },
19896
+ attachmentStore: {
19897
+ on: "native",
19898
+ off: "archive"
19899
+ },
19900
+ accessMode: {
19901
+ on: "open",
19902
+ off: "guarded"
19903
+ }
19904
+ };
19905
+ const DAY_MS = 864e5;
19880
19906
  const FIELD_META = {
19907
+ dmMode: {
19908
+ label: "私聊",
19909
+ group: "trigger",
19910
+ summary: "关闭后私聊不再触发会话",
19911
+ help: "群聊和已绑定的话题不受影响。"
19912
+ },
19913
+ requireMention: {
19914
+ label: "普通群需要 @ 机器人",
19915
+ group: "trigger",
19916
+ summary: "话题内始终不需要 @",
19917
+ help: "关闭后普通群里的每条消息都会触发会话。"
19918
+ },
19919
+ threadFallback: {
19920
+ label: "话题被拒时降级为会话级",
19921
+ group: "trigger",
19922
+ summary: "飞书不允许建话题时改在会话里回复,关闭则直接报错"
19923
+ },
19881
19924
  baseDir: {
19882
- label: "工作区根目录(文件落点)",
19883
- help: "每个用户/群成员一个工作区:私聊 <baseDir>/p2p/<user_id>/,群聊 <baseDir>/groups/<chat_id>/<user_id>/;每个话题在其中拥有独立工作目录 <工作区>/topics/<话题>/(Git 仓库工作区可自动改用 worktree)。必须是绝对路径(~ 开头按家目录展开),保存时会创建该目录;只影响之后新建立的会话 —— 已有话题即使 /renew 也沿用原目录,旧文件不会迁移。",
19925
+ label: "工作区根目录",
19926
+ group: "workspace",
19927
+ summary: "模型和工具生成文件的位置",
19928
+ help: "每个用户一个工作区:私聊 <根目录>/p2p/<user_id>/,群聊 <根目录>/groups/<chat_id>/<user_id>/,每个话题在里面有独立目录。必须是绝对路径(~ 按家目录展开),保存时会创建该目录。只影响之后新建的话题,旧文件不迁移。",
19884
19929
  placeholder: "/Users/you/.dsh/dsh-channels/workspaces",
19885
19930
  wide: true
19886
19931
  },
19887
- dmMode: {
19888
- label: "私聊模式",
19889
- help: "禁用后私聊消息不再触发会话;群聊与已绑定话题不受影响。"
19932
+ topicIsolation: {
19933
+ label: "话题工作目录",
19934
+ group: "workspace",
19935
+ summary: "每个话题在工作区里怎么隔离",
19936
+ help: "自动:工作区是 Git 仓库时给每个话题建一个 worktree,否则用普通子目录。选 Git worktree 但宿主不支持时退回普通子目录。只影响之后新建的话题,已有话题保持原来的目录。"
19890
19937
  },
19891
- requireMention: {
19892
- label: "普通群需 @ 机器人",
19893
- help: "已绑定的主题内始终不需要 @;关闭后普通群的每条消息都会触发。"
19938
+ routeTtlMs: {
19939
+ label: "话题过期",
19940
+ group: "cards",
19941
+ summary: "闲置超过这么久的话题不再续聊,0 为永不过期",
19942
+ help: "过期话题里的新消息会被明确拒绝并提示新开话题,而不是悄悄开一个没有上下文的会话;Session 和工作区文件都保留。调小后,下一次清理(启动时和定期)就会让更多旧话题过期。",
19943
+ min: 0,
19944
+ step: DAY_MS,
19945
+ unit: "天",
19946
+ scale: DAY_MS
19894
19947
  },
19895
- threadFallback: {
19896
- label: "话题被拒时的兜底",
19897
- help: "degrade 降级为会话级路由;strict 直接让回复失败。"
19948
+ approvalTimeoutMs: {
19949
+ label: "审批卡片等待",
19950
+ group: "cards",
19951
+ summary: "超时自动拒绝,等待期间回复暂停",
19952
+ min: 1e4,
19953
+ max: 36e5,
19954
+ step: 1e3,
19955
+ unit: "秒",
19956
+ scale: 1e3
19957
+ },
19958
+ questionTimeoutMs: {
19959
+ label: "提问卡片等待",
19960
+ group: "cards",
19961
+ summary: "模型向用户提问时最多等多久",
19962
+ min: 1e4,
19963
+ max: 36e5,
19964
+ step: 1e3,
19965
+ unit: "秒",
19966
+ scale: 1e3
19967
+ },
19968
+ refreshMs: {
19969
+ label: "流式刷新间隔",
19970
+ group: "cards",
19971
+ summary: "回复卡片多久更新一次",
19972
+ min: 200,
19973
+ max: 1e4,
19974
+ step: 100,
19975
+ unit: "ms"
19976
+ },
19977
+ statusRefreshMs: {
19978
+ label: "状态行保活间隔",
19979
+ group: "cards",
19980
+ summary: "没有文字输出时,计时多久刷新一次",
19981
+ min: 1e3,
19982
+ max: 6e4,
19983
+ step: 500,
19984
+ unit: "ms"
19898
19985
  },
19899
19986
  welcomeOnboarding: {
19900
- label: "首次私聊引导卡",
19901
- help: "每个私聊会话第一次触达时发送一张命令与用法引导卡,只发一次。"
19987
+ label: "首次私聊发引导卡",
19988
+ group: "features",
19989
+ summary: "每个私聊只发一次"
19902
19990
  },
19903
19991
  slashCommandPanel: {
19904
- label: "同步飞书原生斜杠指令面板",
19905
- help: "连接时把插件命令同步到飞书输入 / 时弹出的面板;需开通 application:app_slash_command:read 与 write 权限,部分企业不允许应用添加斜杠指令。关闭时不读写面板,直接输入命令不受影响。"
19992
+ label: "同步斜杠指令面板",
19993
+ group: "features",
19994
+ summary: "在飞书输入 / 时列出插件命令",
19995
+ help: "需要 application:app_slash_command:read 和 application:app_slash_command:write 权限。部分企业不允许应用添加斜杠指令;关闭时不读写面板,直接输入命令不受影响。"
19906
19996
  },
19907
19997
  allowPermissionSwitch: {
19908
- label: "允许飞书侧切换权限预设",
19909
- help: "安全敏感:开启后话题所有者可用 /permissions 切换沙箱与审批预设。"
19998
+ label: "允许在飞书里切换权限预设",
19999
+ group: "features",
20000
+ summary: "话题所有者可以用 /permissions 改沙箱和审批"
19910
20001
  },
19911
- analyzeListen: {
19912
- label: "日志分析接口监听地址",
19913
- help: "日志平台调用 POST /dsh-channels/analyze 的独立端口,格式 host:port(如 0.0.0.0:3090);留空 = 关闭接口;需重连生效。请求需带 Authorization: Bearer <令牌>,令牌在本页下方「日志分析接口令牌」卡片填写。",
19914
- placeholder: "留空 = 关闭"
20002
+ provider: {
20003
+ label: "服务商",
20004
+ group: "model",
20005
+ summary: "留空使用部署默认",
20006
+ placeholder: "留空 = 部署默认"
19915
20007
  },
19916
- adminUserId: {
19917
- label: "管理员 user_id",
19918
- help: "唯一管理员。私聊机器人发送 /userid 获取(不是 ou_ 开头的 open_id,也不是邮箱);留空 = 清除 Web 覆盖。未配置时自动使用飞书应用所有者(需可选的「获取应用信息」权限,开不了就在这里手动填写);两者都没有时 guarded 模式会拒绝所有对话。",
19919
- placeholder: "user_id"
20008
+ model: {
20009
+ label: "模型",
20010
+ group: "model",
20011
+ summary: "留空使用部署默认",
20012
+ placeholder: "留空 = 部署默认"
19920
20013
  },
19921
- accessMode: {
19922
- label: "准入模式",
19923
- help: "guarded(默认):私聊仅管理员,群聊需群授权且发送者是管理员或已授权用户;open:应用可用范围内的任何人都能对话,不安全,仅调试。"
20014
+ reasoningEffort: {
20015
+ label: "推理档位",
20016
+ group: "model",
20017
+ summary: "模型声明的档位 id,留空使用适配器默认",
20018
+ placeholder: "留空 = 适配器默认"
19924
20019
  },
19925
- authRequestTtlDays: {
19926
- label: "授权申请有效期(天)",
19927
- help: "入群/用户授权申请卡的有效期,1–30 天;过期后卡片需重新触发申请(也可在本页下方「待处理申请」中处理)。",
20020
+ maxTokens: {
20021
+ label: "单次输出上限",
20022
+ group: "model",
20023
+ summary: "留空使用模型默认",
19928
20024
  min: 1,
19929
- max: 30,
19930
- step: 1
20025
+ step: 1,
20026
+ unit: "tokens",
20027
+ optional: true,
20028
+ placeholder: "模型默认"
20029
+ },
20030
+ agentPreset: {
20031
+ label: "Agent 预设",
20032
+ group: "model",
20033
+ summary: "留空使用 roster 默认",
20034
+ placeholder: "留空 = roster 默认"
19931
20035
  },
19932
20036
  acceptAttachments: {
19933
- label: "接收入站附件",
19934
- help: "接收飞书图片、文件与合并转发记录。native(默认)下入站附件存入 DSH 原生附件库:触发消息的图片预取进首轮、文件保持懒取,纯附件消息不回复、不落地,需要时请引用该消息(多个文件可合并转发后引用)再提问;archive 下按旧版行为下载到工作区 attachments/。关闭后附件消息不保存、不触发模型、也不列入清单。"
20037
+ label: "接收图片和文件",
20038
+ group: "attachments",
20039
+ summary: "关闭后附件消息不保存、不触发模型",
20040
+ help: "纯附件消息不回复;需要时引用该消息再提问,多个文件可以合并转发后引用。也接收合并转发的聊天记录。"
19935
20041
  },
19936
20042
  attachmentStore: {
19937
- label: "入站附件存储后端",
19938
- help: "native(默认):图片与文件存入 DSH 原生附件库(不可变、内容寻址去重、读取校验、随 Session 回放;不自动清理)。archive:旧版下载到话题工作区 attachments/(可清理但会阻塞会话)。宿主未挂载附件服务时 native 自动降级 archive。"
20043
+ label: "使用 DSH 原生附件库",
20044
+ group: "attachments",
20045
+ summary: "推荐开启;关闭则下载到话题目录 attachments/",
20046
+ help: "原生附件库:不可变、内容寻址去重、随 Session 回放,不自动清理。话题目录:旧版行为,可以手动清理,但下载会阻塞会话。宿主没有附件服务时自动退回话题目录。"
19939
20047
  },
19940
20048
  prefetchImages: {
19941
- label: "预取触发消息的图片",
19942
- help: "native 下把触发消息的图片预取为首轮 ImageBlock,会话/话题/卡片不等下载;失败、超限或超时的图片降级为清单中的懒取项。关闭后图片也需用 feishu_attachment_fetch 获取。"
20049
+ label: "预取触发消息里的图片",
20050
+ group: "attachments",
20051
+ summary: "首轮直接带图,失败的留给模型按需取"
20052
+ },
20053
+ historyBootstrapLimit: {
20054
+ label: "首轮带上话题历史",
20055
+ group: "attachments",
20056
+ summary: "新会话自动附带最近几条消息,0 为关闭",
20057
+ help: "更早的消息由模型用 feishu_topic_messages 工具翻页读取。缺权限或读取失败时静默省略。",
20058
+ min: 0,
20059
+ max: 20,
20060
+ step: 1,
20061
+ unit: "条"
20062
+ },
20063
+ "feishuTools.attachmentFetch": {
20064
+ label: "读取附件",
20065
+ group: "tools",
20066
+ summary: "按需下载已授权消息里的图片和文件",
20067
+ help: "工具名 feishu_attachment_fetch。关闭后文件无法按需读取,入站文件直接下载到话题目录。对新会话生效。"
20068
+ },
20069
+ "feishuTools.topicMessages": {
20070
+ label: "读取话题消息",
20071
+ group: "tools",
20072
+ summary: "翻看引用消息和话题里更早的内容",
20073
+ help: "工具名 feishu_topic_messages。只影响模型主动读取;引用摘录和首轮历史不受影响。"
20074
+ },
20075
+ "feishuTools.sendFile": {
20076
+ label: "发送文件",
20077
+ group: "tools",
20078
+ summary: "把生成的图片或文件发回会话,需 im:resource 权限",
20079
+ help: "工具名 feishu_send_file。图片不超过 10 MB,文件不超过 30 MB。对新会话生效。"
19943
20080
  },
19944
20081
  prefetchTimeoutMs: {
19945
- label: "图片预取整段超时(ms)",
19946
- help: "一次触发消息图片预取的总超时(默认 10000 ms,100–120000);到期后已取回的图片保留,其余降级为清单,不阻塞回合。",
20082
+ label: "图片预取超时",
20083
+ group: "limits",
19947
20084
  min: 100,
19948
20085
  max: 12e4,
19949
- step: 100
20086
+ step: 100,
20087
+ unit: "ms"
19950
20088
  },
19951
20089
  prefetchImageMaxBytes: {
19952
- label: "单张预取图片上限(字节)",
19953
- help: "单张图片超过该字节数即不入首轮图片、留在清单懒取(默认 20971520 = 20 MiB)。",
20090
+ label: "单张预取图片上限",
20091
+ group: "limits",
19954
20092
  min: 1,
19955
20093
  max: 200 * 1024 * 1024,
19956
- step: 1
20094
+ step: 1,
20095
+ unit: BYTES_UNIT
19957
20096
  },
19958
20097
  prefetchTotalMaxBytes: {
19959
- label: "单次预取总量上限(字节)",
19960
- help: "一次触发消息图片预取的总字节预算(默认 52428800 = 50 MiB);用尽后剩余图片降级为清单懒取。",
20098
+ label: "单次预取总量",
20099
+ group: "limits",
19961
20100
  min: 1,
19962
20101
  max: 1024 * 1024 * 1024,
19963
- step: 1
19964
- },
19965
- historyBootstrapLimit: {
19966
- label: "首轮话题历史条数",
19967
- help: "新 Session 首轮自动附带本话题最近 N 条消息摘要(0 = 关闭,上限 20);被动读取使用短预算,缺权限/失败时静默省略。更早的消息用 feishu_topic_messages 工具翻页。",
19968
- min: 0,
19969
- max: 20,
19970
- step: 1
19971
- },
19972
- promptContextTimeoutMs: {
19973
- label: "被动读取预算(ms)",
19974
- help: "引用摘录与首轮话题历史这类被动 prompt 增强的整段预算(默认 3000 ms,100–10000);超时即省略对应块、回合照跑。模型主动调用工具的读取超时另由 feishu_tools 超时控制。",
19975
- min: 100,
19976
- max: 1e4,
19977
- step: 100
19978
- },
19979
- "feishuTools.attachmentFetch": {
19980
- label: "启用 feishu_attachment_fetch 工具",
19981
- help: "让模型按 message_id/file_key 懒取已授权消息的图片/文件。关闭后文件无法懒取,插件整体回退 archive 后端(入站文件直接下载到工作区)。对新会话生效。"
20102
+ step: 1,
20103
+ unit: BYTES_UNIT
19982
20104
  },
19983
20105
  "feishuTools.attachmentFetchMaxResources": {
19984
- label: "单次取回资源数上限",
19985
- help: "一次工具调用最多取回的附件数量(默认 10,1–50);超出会返回可读原因,模型可按 file_key 拆分重试。",
20106
+ label: "读取附件:数量上限",
20107
+ group: "limits",
19986
20108
  min: 1,
19987
20109
  max: 50,
19988
- step: 1
20110
+ step: 1,
20111
+ unit: "个"
19989
20112
  },
19990
20113
  "feishuTools.attachmentFetchMaxBytes": {
19991
- label: "单次取回字节预算(字节)",
19992
- help: "一次工具调用的总下载字节预算(默认 104857600 = 100 MiB,不设上限);文件流式写入原生库,不整文件缓冲,几 GiB 的文件只占磁盘。",
20114
+ label: "读取附件:总字节",
20115
+ group: "limits",
19993
20116
  min: 1,
19994
- step: 1
20117
+ step: 1,
20118
+ unit: BYTES_UNIT
19995
20119
  },
19996
20120
  "feishuTools.attachmentFetchTimeoutMs": {
19997
- label: "单次取回超时(ms)",
19998
- help: "一次 feishu_attachment_fetch 的整段超时(默认 120000 ms,最小 1000,最大 2147483647 ≈ 24.8 天);到期取消下载并逐项报告可读原因。大文件请按带宽同步调大。",
20121
+ label: "读取附件:超时",
20122
+ group: "limits",
19999
20123
  min: 1e3,
20000
20124
  max: MAX_TIMER_DELAY_MS,
20001
- step: 1e3
20002
- },
20003
- "feishuTools.topicMessages": {
20004
- label: "启用 feishu_topic_messages 工具",
20005
- help: "让模型按需读取引用消息与话题内更早的消息/附件。关闭只影响模型工具;被动的引用摘录与首轮历史仍由 historyBootstrapLimit 控制。"
20125
+ step: 1e3,
20126
+ unit: "ms"
20006
20127
  },
20007
20128
  "feishuTools.topicMessagesTimeoutMs": {
20008
- label: "单次话题读取超时(ms)",
20009
- help: "一次 feishu_topic_messages 的整段超时(默认 20000 ms,1000–120000);被动摘录使用独立的短预算。",
20129
+ label: "读取话题消息:超时",
20130
+ group: "limits",
20010
20131
  min: 1e3,
20011
20132
  max: 12e4,
20012
- step: 1e3
20133
+ step: 1e3,
20134
+ unit: "ms"
20013
20135
  },
20014
- "feishuTools.sendFile": {
20015
- label: "启用 feishu_send_file 工具",
20016
- help: "让模型把当前话题工作目录里生成的图片/文件发回当前会话(图片 ≤10 MB,文件 ≤30 MB)。需开通 im:resource 权限。对新会话生效。"
20136
+ promptContextTimeoutMs: {
20137
+ label: "引用摘录与历史:超时",
20138
+ group: "limits",
20139
+ min: 100,
20140
+ max: 1e4,
20141
+ step: 100,
20142
+ unit: "ms"
20143
+ },
20144
+ accessMode: {
20145
+ label: "调试模式",
20146
+ group: "access",
20147
+ summary: "打开后所有人都能聊,不安全,只在调试时用",
20148
+ help: "关闭时(默认):管理员随时可用;非管理员私聊会被拒绝;群聊要同时满足群已授权、发言人在用户白名单里。授权入口有三个:群里 /auth 命令、授权卡、本页。撤销立即生效。"
20149
+ },
20150
+ adminUserId: {
20151
+ label: "管理员 user_id",
20152
+ group: "access",
20153
+ summary: "私聊机器人发送 /userid 获取;留空使用应用所有者",
20154
+ help: "不是 ou_ 开头的 open_id,也不是邮箱。私聊关闭时 /userid 不可用,可以在飞书管理后台的成员详情里查看。自动使用应用所有者需要可选的「获取应用信息」权限。",
20155
+ placeholder: "user_id"
20156
+ },
20157
+ authRequestTtlDays: {
20158
+ label: "申请有效期",
20159
+ group: "access",
20160
+ summary: "授权申请卡多久内可以处理",
20161
+ min: 1,
20162
+ max: 30,
20163
+ step: 1,
20164
+ unit: "天"
20017
20165
  },
20018
20166
  "feishuTools.wikiRead": {
20019
- label: "启用知识库读取工具",
20020
- help: "让模型浏览「知识库范围」内的知识库节点,并读取 docx 文档、电子表格和多维表格(feishu_wiki_list / feishu_wiki_read / feishu_wiki_sheet_read / feishu_wiki_base_read),以应用身份访问。需开通 wiki:wiki、docx:document(或对应的只读权限),电子表格需 sheets:spreadsheet:read,多维表格需 base:table:read、base:field:read、base:record:read(旧版 sheets:spreadsheet、bitable:app 不生效)。只有话题所有者是管理员或在知识库白名单(/auth wiki add @成员)中才能使用;打开文档前会在授权卡上征得话题所有者同意,每个话题一次。知识库范围为空时不挂载。对新会话生效。"
20167
+ label: "读取知识库",
20168
+ group: "wiki",
20169
+ summary: "浏览节点,读取文档、电子表格、多维表格",
20170
+ help: "以应用身份访问,工具 feishu_wiki_list / feishu_wiki_read / feishu_wiki_sheet_read / feishu_wiki_base_read。打开文档前在授权卡上征得话题发起人同意,每个话题一次。只有管理员或下方「可使用的人」发起的话题能用(/auth wiki add @成员)。需要权限 wiki:wiki、docx:document(或只读)、sheets:spreadsheet:read、base:table:read、base:field:read、base:record:read;旧版 sheets:spreadsheet、bitable:app 不生效。对新会话生效。"
20021
20171
  },
20022
20172
  "feishuTools.wikiWrite": {
20023
- label: "启用知识库写入工具",
20024
- help: "让模型在「知识库范围」内新建 docx 文档、电子表格和多维表格,编辑本应用拥有的文档和电子表格,增改删本应用拥有的多维表格记录、向其他多维表格新增记录(feishu_wiki_create / feishu_wiki_edit / feishu_wiki_sheet_edit / feishu_wiki_base_edit),以应用身份访问;每次新建或编辑都需话题所有者在审批卡上同意。需开通 wiki:wiki、docx:document、sheets:spreadsheet:write_only、base:record:create、base:record:update、base:record:delete 权限,以及读取工具的权限;使用条件同读取工具(管理员或知识库白名单)。知识库范围为空时不挂载。对新会话生效。"
20173
+ label: "编辑知识库",
20174
+ group: "wiki",
20175
+ summary: "新建和修改文档、表格,每次都需审批",
20176
+ help: "工具 feishu_wiki_create / feishu_wiki_edit / feishu_wiki_sheet_edit / feishu_wiki_base_edit。只能编辑本应用拥有的文档和表格;其他多维表格只能新增记录。需要读取工具的权限,以及 sheets:spreadsheet:write_only、base:record:create、base:record:update、base:record:delete。对新会话生效。"
20025
20177
  },
20026
20178
  wikiRoots: {
20027
- label: "知识库范围(wikiRoots)",
20028
- help: "知识库工具只能访问这些位置,每个输入框填一个链接:整个知识空间 https://<租户>.feishu.cn/wiki/space/<space_id>,或节点 https://<租户>.feishu.cn/wiki/<node_token>(该节点及其下所有节点);最多 20 项,空输入框保存时忽略。留空 = 不挂载任何知识库工具(即使上面的开关已开启)。对新会话生效。",
20179
+ label: "可访问范围",
20180
+ group: "wiki",
20181
+ summary: "每行一个知识空间或节点链接,为空时不挂载知识库工具",
20182
+ help: "整个知识空间 https://<租户>.feishu.cn/wiki/space/<space_id>,或节点 https://<租户>.feishu.cn/wiki/<node_token>(含其下所有节点)。最多 20 项,空行保存时忽略。对新会话生效。",
20029
20183
  placeholder: "https://<租户>.feishu.cn/wiki/space/<space_id>",
20030
20184
  wide: true
20031
20185
  },
20032
- provider: {
20033
- label: "模型服务商",
20034
- help: "留空 = 使用部署默认;例如 deepseek-official。",
20035
- placeholder: "留空 = 部署默认"
20036
- },
20037
- model: {
20038
- label: "模型 id",
20039
- help: "留空 = 使用部署默认;例如 deepseek-v4-flash。",
20040
- placeholder: "留空 = 部署默认"
20041
- },
20042
- reasoningEffort: {
20043
- label: "推理档位",
20044
- help: "模型声明的精确档位 id(如 high / max);留空 = 适配器默认。",
20045
- placeholder: "留空 = 适配器默认"
20046
- },
20047
- agentPreset: {
20048
- label: "Agent 预设",
20049
- help: "新会话使用的预设 id(如 standard);留空 = roster 默认。",
20050
- placeholder: "留空 = roster 默认"
20051
- },
20052
- refreshMs: {
20053
- label: "流式刷新间隔(ms)",
20054
- help: "流式卡片的 patch 节流间隔,200–10000;需重连生效。",
20055
- min: 200,
20056
- max: 1e4,
20057
- step: 100
20058
- },
20059
- statusRefreshMs: {
20060
- label: "状态行保活间隔(ms)",
20061
- help: "无文本输出时活动状态行的计时刷新间隔,1000–60000;需重连生效。",
20062
- min: 1e3,
20063
- max: 6e4,
20064
- step: 500
20186
+ analyzeListen: {
20187
+ label: "监听地址",
20188
+ group: "analyze",
20189
+ summary: "日志平台调用分析接口的 host:port,留空关闭",
20190
+ help: "接口路径 POST /dsh-channels/analyze,请求需带 Authorization: Bearer <访问令牌>。",
20191
+ placeholder: "例如 0.0.0.0:3090"
20065
20192
  },
20066
20193
  loggerLevel: {
20067
20194
  label: "SDK 日志级别",
20068
- help: "官方 SDK 的日志级别;需重连生效。"
20195
+ group: "logging"
20069
20196
  }
20070
20197
  };
20071
- const GROUP_OF = {
20072
- baseDir: "workspace",
20073
- dmMode: "behavior",
20074
- requireMention: "behavior",
20075
- threadFallback: "behavior",
20076
- welcomeOnboarding: "behavior",
20077
- slashCommandPanel: "behavior",
20078
- allowPermissionSwitch: "behavior",
20079
- analyzeListen: "behavior",
20080
- adminUserId: "access",
20081
- accessMode: "access",
20082
- authRequestTtlDays: "access",
20083
- acceptAttachments: "content",
20084
- attachmentStore: "content",
20085
- prefetchImages: "content",
20086
- prefetchTimeoutMs: "content",
20087
- prefetchImageMaxBytes: "content",
20088
- prefetchTotalMaxBytes: "content",
20089
- historyBootstrapLimit: "content",
20090
- promptContextTimeoutMs: "tools",
20091
- "feishuTools.attachmentFetch": "tools",
20092
- "feishuTools.attachmentFetchMaxResources": "tools",
20093
- "feishuTools.attachmentFetchMaxBytes": "tools",
20094
- "feishuTools.attachmentFetchTimeoutMs": "tools",
20095
- "feishuTools.topicMessages": "tools",
20096
- "feishuTools.topicMessagesTimeoutMs": "tools",
20097
- "feishuTools.sendFile": "tools",
20098
- "feishuTools.wikiRead": "wiki",
20099
- "feishuTools.wikiWrite": "wiki",
20100
- wikiRoots: "wiki",
20101
- provider: "model",
20102
- model: "model",
20103
- reasoningEffort: "model",
20104
- agentPreset: "model",
20105
- refreshMs: "streaming",
20106
- statusRefreshMs: "streaming",
20107
- loggerLevel: "streaming"
20108
- };
20109
20198
  /** One descriptor per editable key, in `EDITABLE_KEYS` order (Host-driven form). */
20110
20199
  const FIELD_DESCRIPTORS = EDITABLE_KEYS.map((key) => {
20111
20200
  const meta = FIELD_META[key];
20112
20201
  const options = SELECT_OPTIONS[key];
20202
+ const toggle = TOGGLES[key];
20113
20203
  const list = STRING_LIST_FIELDS[key];
20114
20204
  return {
20115
20205
  key,
20116
20206
  label: meta.label,
20117
20207
  kind: list !== void 0 ? "string-list" : BOOLEAN_KEYS.has(key) ? "boolean" : options !== void 0 ? "select" : meta.min !== void 0 ? "number" : "text",
20118
- group: GROUP_OF[key],
20119
- help: meta.help,
20208
+ group: meta.group,
20209
+ ...meta.summary === void 0 ? {} : { summary: meta.summary },
20210
+ ...meta.help === void 0 ? {} : { help: meta.help },
20120
20211
  ...options === void 0 ? {} : { options },
20212
+ ...toggle === void 0 ? {} : { toggle },
20121
20213
  ...meta.min === void 0 ? {} : { min: meta.min },
20122
20214
  ...meta.max === void 0 ? {} : { max: meta.max },
20123
20215
  ...meta.step === void 0 ? {} : { step: meta.step },
20216
+ ...meta.unit === void 0 ? {} : { unit: meta.unit },
20217
+ ...meta.scale === void 0 ? {} : { scale: meta.scale },
20218
+ ...meta.optional === void 0 ? {} : { optional: meta.optional },
20124
20219
  ...meta.placeholder === void 0 ? {} : { placeholder: meta.placeholder },
20125
20220
  ...list === void 0 ? {} : { maxItems: list.maxItems },
20126
20221
  ...list?.itemFormat === void 0 ? {} : { itemFormat: list.itemFormat },
@@ -20214,15 +20309,6 @@ function withDirectoryBrowse(fields, available) {
20214
20309
  function messageOf$1(error) {
20215
20310
  return error instanceof Error ? error.message : String(error);
20216
20311
  }
20217
- function formatDays(ms) {
20218
- return ms === 0 ? "关闭(不过期)" : `${Math.round(ms / 864e5)} 天`;
20219
- }
20220
- function formatSeconds(ms) {
20221
- return `${Math.round(ms / 1e3)} 秒`;
20222
- }
20223
- function formatOptional(value, suffix = "") {
20224
- return value === void 0 ? "未设置" : `${value}${suffix}`;
20225
- }
20226
20312
  /** Credential values are opaque strings; trim, cap length, reject control chars. */
20227
20313
  const MAX_CREDENTIAL_LENGTH = 512;
20228
20314
  function normalizeCredentialValue(raw) {
@@ -20308,39 +20394,6 @@ function normalizeAccessName(raw) {
20308
20394
  value
20309
20395
  };
20310
20396
  }
20311
- /** Build the read-only advanced card from the effective config. */
20312
- function readOnlyFields(config) {
20313
- return [
20314
- {
20315
- key: "topicIsolation",
20316
- label: "话题目录隔离",
20317
- value: config.topicIsolation === "auto" ? "自动(Git 仓库用 worktree,否则普通子目录)" : config.topicIsolation === "worktree" ? "Git worktree(失败回退子目录)" : "普通子目录",
20318
- help: "每个话题的独立工作目录形式;在 profile 配置里用 topicIsolation 设置(auto / subdir / worktree)。"
20319
- },
20320
- {
20321
- key: "routeTtlMs",
20322
- label: "话题路由过期",
20323
- value: formatDays(config.routeTtlMs),
20324
- help: "超期话题的后续消息会被明确拒绝,而不是新建 Context-free Session。"
20325
- },
20326
- {
20327
- key: "approvalTimeoutMs",
20328
- label: "审批卡片等待",
20329
- value: formatSeconds(config.approvalTimeoutMs)
20330
- },
20331
- {
20332
- key: "questionTimeoutMs",
20333
- label: "提问卡片等待",
20334
- value: formatSeconds(config.questionTimeoutMs)
20335
- },
20336
- {
20337
- key: "maxTokens",
20338
- label: "单次输出上限",
20339
- value: formatOptional(config.maxTokens, " tokens"),
20340
- help: "留空/未设置时使用模型适配器默认值。"
20341
- }
20342
- ];
20343
- }
20344
20397
  /**
20345
20398
  * Derive the panel phase from readiness + runtime facts. The order matters:
20346
20399
  * an incomplete configuration always wins (no connection is attempted), and a
@@ -20520,7 +20573,6 @@ var SettingsSurface = class {
20520
20573
  overriddenKeys,
20521
20574
  restartPendingKeys,
20522
20575
  fields,
20523
- readOnly: readOnlyFields(effective),
20524
20576
  credentials
20525
20577
  },
20526
20578
  access
@@ -21234,6 +21286,6 @@ function apply(ctx, config) {
21234
21286
  }, "dsh-channels");
21235
21287
  }
21236
21288
  //#endregion
21237
- export { AUTH_USER_TARGET_ERRORS, AccessController, AccessRequests, AccessStore, ApprovalAnswerer, CARD_MAX_BYTES, CARD_TARGET_BYTES, CATALOG_ROUTE, CHANNEL_COMMAND_NAMES, CONFIG_ROUTE, CREDENTIALS_ROUTE, Config, DM_DENY_TEXT, DM_UNCONFIGURED_TEXT, DSH_CHANNELS_VERSION, EDITABLE_KEYS, EMPTY_TOTALS, FIELD_DESCRIPTORS, FeishuService, HEALTH_DEPENDENCY_NAMES, INTERRUPTION_NOTICE, LOGICAL_EXPORT_FORMAT, LOGICAL_EXPORT_FORMAT_VERSION, MAX_QUESTION_OPTIONS, MAX_TABLES_PER_CARD, OverlayStore, PANEL_CHEVRON_TOKEN, PANEL_COPY, PANEL_ROUTE, PANEL_TITLES, PICK_DIRECTORY_ROUTE, QuestionAnswerer, REASONING_MAX_BYTES, RECONNECT_ROUTE, RESTART_KEYS, RouteOperationQueue, SESSION_HISTORY_DISPLAY_LIMIT, STATUS_ROUTE, SUPPORTED_COMMAND_NAMES, SettingsSurface, TRUNCATION_SUFFIX, TurnStreamer, accessGroupRecordSchema, accessRequestRecordSchema, accessUserRecordSchema, addUsage, appendSessionHistory, apply, applyCatalog, applyProjectionViews, armModelCommand, averageDecodeTokensPerSecond, averageTtftMs, buildApprovalCard, buildApprovalSettledCard, buildCard, buildCommandResultCard, buildCompactComparisonCard, buildGroupInfoCard, buildHealthCard, buildInterruptionCard, buildQuestionCard, buildQuestionSettledCard, buildRenewCard, buildRequestSettledCard, buildSessionHistoryCard, buildSessionStatusCard, buildUserRequestCard, buildWorkDirCard, cacheHitPct, cardJsonBytes, chatRouteKey, commandResultCardKind, compactFailureContext, countFiberStates, createHostCatalog, createLogicalSessionExport, createSettingsDirectoryPicker, decideAccess, defaultOverlayPath, emptyCatalog, ensureWorkspace, expiredRouteRecordSchema, feishuDomain, foldAll, foldEvent, foldHealthSnapshot, foldSessionStats, inflightSnapshotSchema, inject, isAdminUserId, isSameOriginRequest, isSupportedCommand, maskOpenIdTail, measureSessionContext, mergeOverlay, mountSettingsRoutes, name, normalizeCredentialValue, normalizeOverlay, normalizeRouteRecord, normalizeSessionHistory, parseOverlay, parseSlashCommand, pickEditable, processedRecordSchema, querySessionHistory, readOnlyFields, readProjectionViews, registerChannelCommands, registerModelCommand, registerSettingsRoutes, resolveAuthUserTarget, resolveDshHome, resolveWorkDir, routeRecordSchema, segmentCardContent, serializeLogicalSession, sessionDirOf, sessionHistoryEntrySchema, splitBodyForCard, stagingPathFor, stagingRoot, stripTables, supportedCommandHelp, supportedCommandList, tableBlocks, topicDirFor, topicTokenFor, usageFromBuckets, withDirectoryBrowse, workspacePathFor, workspaceTitleFor, worktreeBranchFor };
21289
+ export { AUTH_USER_TARGET_ERRORS, AccessController, AccessRequests, AccessStore, ApprovalAnswerer, CARD_MAX_BYTES, CARD_TARGET_BYTES, CATALOG_ROUTE, CHANNEL_COMMAND_NAMES, CONFIG_ROUTE, CREDENTIALS_ROUTE, Config, DM_DENY_TEXT, DM_UNCONFIGURED_TEXT, DSH_CHANNELS_VERSION, EDITABLE_KEYS, EMPTY_TOTALS, FIELD_DESCRIPTORS, FeishuService, HEALTH_DEPENDENCY_NAMES, INTERRUPTION_NOTICE, LOGICAL_EXPORT_FORMAT, LOGICAL_EXPORT_FORMAT_VERSION, MAX_QUESTION_OPTIONS, MAX_TABLES_PER_CARD, OverlayStore, PANEL_CHEVRON_TOKEN, PANEL_COPY, PANEL_ROUTE, PANEL_TITLES, PICK_DIRECTORY_ROUTE, QuestionAnswerer, REASONING_MAX_BYTES, RECONNECT_ROUTE, RESTART_KEYS, RouteOperationQueue, SESSION_HISTORY_DISPLAY_LIMIT, STATUS_ROUTE, SUPPORTED_COMMAND_NAMES, SettingsSurface, TRUNCATION_SUFFIX, TurnStreamer, accessGroupRecordSchema, accessRequestRecordSchema, accessUserRecordSchema, addUsage, appendSessionHistory, apply, applyCatalog, applyProjectionViews, armModelCommand, averageDecodeTokensPerSecond, averageTtftMs, buildApprovalCard, buildApprovalSettledCard, buildCard, buildCommandResultCard, buildCompactComparisonCard, buildGroupInfoCard, buildHealthCard, buildInterruptionCard, buildQuestionCard, buildQuestionSettledCard, buildRenewCard, buildRequestSettledCard, buildSessionHistoryCard, buildSessionStatusCard, buildUserRequestCard, buildWorkDirCard, cacheHitPct, cardJsonBytes, chatRouteKey, commandResultCardKind, compactFailureContext, countFiberStates, createHostCatalog, createLogicalSessionExport, createSettingsDirectoryPicker, decideAccess, defaultOverlayPath, emptyCatalog, ensureWorkspace, expiredRouteRecordSchema, feishuDomain, foldAll, foldEvent, foldHealthSnapshot, foldSessionStats, inflightSnapshotSchema, inject, isAdminUserId, isSameOriginRequest, isSupportedCommand, maskOpenIdTail, measureSessionContext, mergeOverlay, mountSettingsRoutes, name, normalizeCredentialValue, normalizeOverlay, normalizeRouteRecord, normalizeSessionHistory, parseOverlay, parseSlashCommand, pickEditable, processedRecordSchema, querySessionHistory, readProjectionViews, registerChannelCommands, registerModelCommand, registerSettingsRoutes, resolveAuthUserTarget, resolveDshHome, resolveWorkDir, routeRecordSchema, segmentCardContent, serializeLogicalSession, sessionDirOf, sessionHistoryEntrySchema, splitBodyForCard, stagingPathFor, stagingRoot, stripTables, supportedCommandHelp, supportedCommandList, tableBlocks, topicDirFor, topicTokenFor, usageFromBuckets, withDirectoryBrowse, workspacePathFor, workspaceTitleFor, worktreeBranchFor };
21238
21290
 
21239
21291
  //# sourceMappingURL=index.js.map