@xopcai/xopc 0.0.47 → 0.0.49

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. package/dist/extensions/dingtalk/src/accounts.js +1 -1
  2. package/dist/extensions/dingtalk/src/accounts.js.map +1 -1
  3. package/dist/extensions/dingtalk/src/merge-config.js +1 -1
  4. package/dist/extensions/dingtalk/src/merge-config.js.map +1 -1
  5. package/dist/extensions/dingtalk/src/plugin.js +1 -1
  6. package/dist/extensions/dingtalk/src/plugin.js.map +1 -1
  7. package/dist/extensions/feishu/src/adapters/cli-login.js +8 -8
  8. package/dist/extensions/feishu/src/adapters/cli-login.js.map +1 -1
  9. package/dist/extensions/feishu/src/adapters/onboard-cli.js +8 -8
  10. package/dist/extensions/feishu/src/adapters/onboard-cli.js.map +1 -1
  11. package/dist/extensions/feishu/src/plugin.js +1 -1
  12. package/dist/extensions/feishu/src/plugin.js.map +1 -1
  13. package/dist/extensions/feishu/src/schema/config-schema.js +2 -2
  14. package/dist/extensions/feishu/src/schema/config-schema.js.map +1 -1
  15. package/dist/extensions/feishu/src/state/accounts.js +1 -1
  16. package/dist/extensions/feishu/src/state/accounts.js.map +1 -1
  17. package/dist/extensions/feishu/src/streaming/streaming-adapter.js +82 -36
  18. package/dist/extensions/feishu/src/streaming/streaming-adapter.js.map +1 -1
  19. package/dist/extensions/telegram/src/command-handler.js +1 -1
  20. package/dist/extensions/telegram/src/command-handler.js.map +1 -1
  21. package/dist/extensions/telegram/xopc.extension.json +1 -1
  22. package/dist/extensions/weixin/src/auth/accounts.js +1 -1
  23. package/dist/extensions/weixin/src/auth/accounts.js.map +1 -1
  24. package/dist/extensions/weixin/src/config-schema.js +2 -2
  25. package/dist/extensions/weixin/src/config-schema.js.map +1 -1
  26. package/dist/extensions/weixin/src/config-surface.js +1 -1
  27. package/dist/extensions/weixin/src/config-surface.js.map +1 -1
  28. package/dist/extensions/weixin/src/messaging/process-message.js +2 -2
  29. package/dist/extensions/weixin/src/messaging/process-message.js.map +1 -1
  30. package/dist/extensions/weixin/src/plugin.js +1 -1
  31. package/dist/extensions/weixin/src/plugin.js.map +1 -1
  32. package/dist/gateway/static/root/assets/{agents-DdWPgyn-.js → agents-CQllyJhj.js} +2 -2
  33. package/dist/gateway/static/root/assets/{agents-DdWPgyn-.js.map → agents-CQllyJhj.js.map} +1 -1
  34. package/dist/gateway/static/root/assets/{apps-page-BTi_W1y1.js → apps-page-BWI3RVMh.js} +2 -2
  35. package/dist/gateway/static/root/assets/{apps-page-BTi_W1y1.js.map → apps-page-BWI3RVMh.js.map} +1 -1
  36. package/dist/gateway/static/root/assets/channels-settings-rfmhXfC4.js +2 -0
  37. package/dist/gateway/static/root/assets/channels-settings-rfmhXfC4.js.map +1 -0
  38. package/dist/gateway/static/root/assets/{cron-dreaming-jobs-DinMur-Z.js → cron-dreaming-jobs-BzCQy56Z.js} +2 -2
  39. package/dist/gateway/static/root/assets/{cron-dreaming-jobs-DinMur-Z.js.map → cron-dreaming-jobs-BzCQy56Z.js.map} +1 -1
  40. package/dist/gateway/static/root/assets/{cron-page-Bu05Z2oL.js → cron-page-CjTuH_av.js} +2 -2
  41. package/dist/gateway/static/root/assets/{cron-page-Bu05Z2oL.js.map → cron-page-CjTuH_av.js.map} +1 -1
  42. package/dist/gateway/static/root/assets/{dist-wDej8fSi.js → dist-DIeOihYP.js} +2 -2
  43. package/dist/gateway/static/root/assets/{dist-wDej8fSi.js.map → dist-DIeOihYP.js.map} +1 -1
  44. package/dist/gateway/static/root/assets/{extension-debug-page-CZBu7-zM.js → extension-debug-page-CR-4lZOn.js} +2 -2
  45. package/dist/gateway/static/root/assets/{extension-debug-page-CZBu7-zM.js.map → extension-debug-page-CR-4lZOn.js.map} +1 -1
  46. package/dist/gateway/static/root/assets/{extension-page-CnOyLPrh.js → extension-page-BNwcYj2Q.js} +2 -2
  47. package/dist/gateway/static/root/assets/{extension-page-CnOyLPrh.js.map → extension-page-BNwcYj2Q.js.map} +1 -1
  48. package/dist/gateway/static/root/assets/{extension-settings-page-BOHn3S1a.js → extension-settings-page-CDpiZPV4.js} +2 -2
  49. package/dist/gateway/static/root/assets/{extension-settings-page-BOHn3S1a.js.map → extension-settings-page-CDpiZPV4.js.map} +1 -1
  50. package/dist/gateway/static/root/assets/{heartbeat-config-api-OqFXdrMO.js → heartbeat-config-api-CSbqK-L_.js} +2 -2
  51. package/dist/gateway/static/root/assets/{heartbeat-config-api-OqFXdrMO.js.map → heartbeat-config-api-CSbqK-L_.js.map} +1 -1
  52. package/dist/gateway/static/root/assets/{index-DeELk--t.js → index-D3sMd_aw.js} +11 -11
  53. package/dist/gateway/static/root/assets/{index-DeELk--t.js.map → index-D3sMd_aw.js.map} +1 -1
  54. package/dist/gateway/static/root/assets/{logs-page-DiN42-yE.js → logs-page-DLcWAXU5.js} +2 -2
  55. package/dist/gateway/static/root/assets/{logs-page-DiN42-yE.js.map → logs-page-DLcWAXU5.js.map} +1 -1
  56. package/dist/gateway/static/root/assets/{sessions-page-B5oxRfRm.js → sessions-page-Ck3lS3N_.js} +2 -2
  57. package/dist/gateway/static/root/assets/{sessions-page-B5oxRfRm.js.map → sessions-page-Ck3lS3N_.js.map} +1 -1
  58. package/dist/gateway/static/root/assets/{settings-page-DaRY3XEp.js → settings-page-Dp_eFgub.js} +2 -2
  59. package/dist/gateway/static/root/assets/{settings-page-DaRY3XEp.js.map → settings-page-Dp_eFgub.js.map} +1 -1
  60. package/dist/gateway/static/root/assets/{skills-page-BGDLiQZ6.js → skills-page-ClRj9e6K.js} +2 -2
  61. package/dist/gateway/static/root/assets/{skills-page-BGDLiQZ6.js.map → skills-page-ClRj9e6K.js.map} +1 -1
  62. package/dist/gateway/static/root/assets/{use-image-provider-credentials-DcP2SYn3.js → use-image-provider-credentials-DAi5Iu8c.js} +2 -2
  63. package/dist/gateway/static/root/assets/{use-image-provider-credentials-DcP2SYn3.js.map → use-image-provider-credentials-DAi5Iu8c.js.map} +1 -1
  64. package/dist/gateway/static/root/index.html +1 -1
  65. package/dist/package.js +1 -1
  66. package/dist/src/agent/goals/checklist-judge.js +21 -17
  67. package/dist/src/agent/goals/checklist-judge.js.map +1 -1
  68. package/dist/src/agent/goals/evaluate-turn.js +6 -11
  69. package/dist/src/agent/goals/evaluate-turn.js.map +1 -1
  70. package/dist/src/agent/goals/judge.d.ts +16 -0
  71. package/dist/src/agent/goals/judge.js +61 -13
  72. package/dist/src/agent/goals/judge.js.map +1 -1
  73. package/dist/src/agent/goals/state.d.ts +7 -0
  74. package/dist/src/agent/goals/state.js +24 -1
  75. package/dist/src/agent/goals/state.js.map +1 -1
  76. package/dist/src/agent/service.js +2 -0
  77. package/dist/src/agent/service.js.map +1 -1
  78. package/dist/src/chat-commands/builtins/model.d.ts +2 -2
  79. package/dist/src/chat-commands/builtins/model.js +10 -8
  80. package/dist/src/chat-commands/builtins/model.js.map +1 -1
  81. package/dist/src/chat-commands/builtins/system.js +1 -1
  82. package/dist/src/chat-commands/builtins/system.js.map +1 -1
  83. package/dist/src/gateway/hono/routes/channels.js +2 -2
  84. package/dist/src/gateway/hono/routes/channels.js.map +1 -1
  85. package/dist/src/gateway/hono/routes/config.js +3 -3
  86. package/dist/src/gateway/hono/routes/config.js.map +1 -1
  87. package/dist/src/tui/backends/embedded-backend.d.ts +1 -1
  88. package/dist/src/tui/backends/embedded-backend.js +24 -3
  89. package/dist/src/tui/backends/embedded-backend.js.map +1 -1
  90. package/dist/src/tui/backends/gateway-sse-backend.js +36 -10
  91. package/dist/src/tui/backends/gateway-sse-backend.js.map +1 -1
  92. package/dist/src/tui/tui-commands.js +1 -1
  93. package/dist/src/tui/tui-commands.js.map +1 -1
  94. package/dist/src/tui/tui.js +12 -1
  95. package/dist/src/tui/tui.js.map +1 -1
  96. package/package.json +1 -1
  97. package/dist/gateway/static/root/assets/channels-settings-CjUmKQrC.js +0 -2
  98. package/dist/gateway/static/root/assets/channels-settings-CjUmKQrC.js.map +0 -1
@@ -23,7 +23,7 @@ async function startDingtalkSetupPolling(sessionKey, service) {
23
23
  const raw = readFileSync(configPath, "utf8");
24
24
  const config = JSON.parse(raw);
25
25
  const existing = config.channels?.dingtalk ?? {};
26
- const dmPolicy = typeof existing.dmPolicy === "string" && existing.dmPolicy.trim() ? existing.dmPolicy : "pairing";
26
+ const dmPolicy = typeof existing.dmPolicy === "string" && existing.dmPolicy.trim() ? existing.dmPolicy : "open";
27
27
  const allowFrom = Array.isArray(existing.allowFrom) ? existing.allowFrom : [];
28
28
  config.channels = {
29
29
  ...config.channels,
@@ -64,7 +64,7 @@ async function startFeishuSetupPolling(sessionKey, service) {
64
64
  const raw = readFileSync(configPath, "utf8");
65
65
  const config = JSON.parse(raw);
66
66
  const existingFeishu = config.channels?.feishu ?? {};
67
- const dmPolicy = typeof existingFeishu.dmPolicy === "string" && existingFeishu.dmPolicy.trim() ? existingFeishu.dmPolicy : "pairing";
67
+ const dmPolicy = typeof existingFeishu.dmPolicy === "string" && existingFeishu.dmPolicy.trim() ? existingFeishu.dmPolicy : "open";
68
68
  const preseedOpenId = outcome.result.openId?.trim();
69
69
  const allowFrom = mergeDistinctSenderIds(existingFeishu.allowFrom, preseedOpenId ? [preseedOpenId] : []);
70
70
  config.channels = {
@@ -1 +1 @@
1
- {"version":3,"file":"channels.js","names":[],"sources":["../../../../../src/gateway/hono/routes/channels.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\n\nimport type { Hono } from 'hono';\n\nimport { mergeDistinctSenderIds } from '../../../channels/pairing/index.js';\nimport { writeTextAtomic } from '../../../infra/write-file-atomic.js';\nimport type { GatewayService } from '../../service.js';\nimport type { AuthenticatedRouteDeps } from './deps.js';\n\ntype FeishuSetupDomain = 'feishu' | 'lark';\n\ninterface FeishuSetupSession {\n deviceCode: string;\n domain: FeishuSetupDomain;\n intervalSec: number;\n expireInSec: number;\n createdAt: number;\n phase: 'idle' | 'polling' | 'scanned' | 'done' | 'error';\n result?: {\n appId: string;\n appSecret: string;\n domain: FeishuSetupDomain;\n openId?: string;\n };\n error?: string;\n}\n\nconst feishuSetupSessions = new Map<string, FeishuSetupSession>();\n\ninterface DingtalkSetupSession {\n deviceCode: string;\n intervalSec: number;\n expireInSec: number;\n createdAt: number;\n phase: 'idle' | 'polling' | 'done' | 'error';\n result?: { clientId: string; clientSecret: string };\n error?: string;\n}\n\nconst dingtalkSetupSessions = new Map<string, DingtalkSetupSession>();\n\nasync function startDingtalkSetupPolling(sessionKey: string, service: GatewayService): Promise<void> {\n const session = dingtalkSetupSessions.get(sessionKey);\n if (!session) return;\n\n const { waitForDingtalkRegistrationSuccess } = await import(\n '../../../../extensions/dingtalk/src/auth/device-auth.js'\n );\n\n session.phase = 'polling';\n\n try {\n const creds = await waitForDingtalkRegistrationSuccess({\n deviceCode: session.deviceCode,\n intervalSeconds: session.intervalSec,\n expiresInSeconds: session.expireInSec,\n });\n session.phase = 'done';\n session.result = creds;\n try {\n const configPath = service.getHealth().configPath;\n const raw = readFileSync(configPath, 'utf8');\n const config = JSON.parse(raw) as {\n channels?: Record<string, unknown>;\n };\n const existing = (config.channels?.dingtalk ?? {}) as Record<string, unknown>;\n const dmPolicy =\n typeof existing.dmPolicy === 'string' && existing.dmPolicy.trim() ? existing.dmPolicy : 'pairing';\n const allowFrom = Array.isArray(existing.allowFrom) ? existing.allowFrom : [];\n\n config.channels = {\n ...config.channels,\n dingtalk: {\n ...existing,\n enabled: true,\n clientId: creds.clientId,\n clientSecret: creds.clientSecret,\n dmPolicy,\n allowFrom,\n },\n };\n\n await writeTextAtomic(configPath, `${JSON.stringify(config, null, 2)}\\n`);\n await service.afterDingtalkCredentialsPersisted();\n } catch {\n /* non-blocking */\n }\n } catch (err) {\n session.phase = 'error';\n session.error = err instanceof Error ? err.message : String(err);\n }\n\n setTimeout(() => dingtalkSetupSessions.delete(sessionKey), 30_000);\n}\n\nasync function startFeishuSetupPolling(sessionKey: string, service: GatewayService): Promise<void> {\n const session = feishuSetupSessions.get(sessionKey);\n if (!session) return;\n\n const { pollAppRegistration } = await import(\n '../../../../extensions/feishu/src/auth/app-registration.js'\n );\n\n session.phase = 'polling';\n\n const outcome = await pollAppRegistration({\n deviceCode: session.deviceCode,\n intervalSec: session.intervalSec,\n expireInSec: session.expireInSec,\n initialDomain: session.domain,\n });\n\n if (outcome.status === 'success') {\n session.phase = 'done';\n session.result = outcome.result;\n try {\n const configPath = service.getHealth().configPath;\n const raw = readFileSync(configPath, 'utf8');\n const config = JSON.parse(raw) as {\n channels?: Record<string, unknown>;\n };\n const existingFeishu = (config.channels?.feishu ?? {}) as Record<string, unknown>;\n const dmPolicy =\n typeof existingFeishu.dmPolicy === 'string' && existingFeishu.dmPolicy.trim()\n ? existingFeishu.dmPolicy\n : 'pairing';\n const preseedOpenId = outcome.result.openId?.trim();\n const allowFrom = mergeDistinctSenderIds(existingFeishu.allowFrom, preseedOpenId ? [preseedOpenId] : []);\n\n config.channels = {\n ...config.channels,\n feishu: {\n ...existingFeishu,\n enabled: true,\n appId: outcome.result.appId,\n appSecret: outcome.result.appSecret,\n domain: outcome.result.domain,\n connectionMode: (existingFeishu.connectionMode as string) || 'websocket',\n dmPolicy,\n allowFrom,\n },\n };\n\n await writeTextAtomic(configPath, `${JSON.stringify(config, null, 2)}\\n`);\n await service.afterFeishuCredentialsPersisted();\n } catch {\n // Config write / reload failure is non-blocking; session still carries credentials for debugging.\n }\n } else {\n session.phase = 'error';\n session.error =\n outcome.status === 'access_denied'\n ? 'User denied authorization.'\n : outcome.status === 'expired'\n ? 'Session expired.'\n : outcome.status === 'timeout'\n ? 'Scan timed out.'\n : 'message' in outcome\n ? outcome.message\n : 'Unknown error.';\n }\n\n setTimeout(() => feishuSetupSessions.delete(sessionKey), 30_000);\n}\n\nexport function registerChannelRoutes(authenticated: Hono, deps: AuthenticatedRouteDeps): void {\n const { service, strictRateLimitMiddleware } = deps;\n\n authenticated.get('/api/channels/status', (c) => {\n const channels = service.getChannelsStatus();\n return c.json({ ok: true, payload: { channels } });\n });\n\n authenticated.post('/api/channels/weixin/login/start', strictRateLimitMiddleware, async (c) => {\n const body = await c.req.json().catch(() => ({}));\n const account =\n body && typeof body === 'object' && typeof (body as { account?: unknown }).account === 'string'\n ? (body as { account: string }).account.trim() || undefined\n : undefined;\n const rawTimeout =\n body && typeof body === 'object' ? (body as { timeoutMs?: unknown }).timeoutMs : undefined;\n const timeoutMs =\n typeof rawTimeout === 'number' && Number.isFinite(rawTimeout) ? Math.max(60_000, rawTimeout) : undefined;\n\n const { startWeixinGatewayQrLogin } = await import('../../../channels/weixin/index.js');\n const result = await startWeixinGatewayQrLogin({\n configPath: service.getHealth().configPath,\n account,\n timeoutMs,\n onPersisted: async (r) => {\n if (r.ok) {\n await service.afterWeixinCredentialsPersisted();\n }\n },\n });\n\n if (result.ok === false) {\n return c.json(\n { ok: false, error: { code: 'WEIXIN_LOGIN_FAILED', message: result.message } },\n 400,\n );\n }\n return c.json({\n ok: true,\n payload: { sessionKey: result.sessionKey, qrcodeUrl: result.qrcodeUrl },\n });\n });\n\n authenticated.get('/api/channels/weixin/login/:sessionKey', async (c) => {\n const sessionKey = c.req.param('sessionKey')?.trim() ?? '';\n if (!sessionKey) {\n return c.json({ ok: false, error: { code: 'BAD_REQUEST', message: 'Missing sessionKey' } }, 400);\n }\n const { getWeixinGatewayQrLoginStatus } = await import('../../../channels/weixin/index.js');\n const status = getWeixinGatewayQrLoginStatus(sessionKey);\n return c.json({ ok: true, payload: { status } });\n });\n\n authenticated.post('/api/channels/feishu/setup/start', strictRateLimitMiddleware, async (c) => {\n const body = await c.req.json().catch(() => ({}));\n const rawDomain =\n body && typeof body === 'object' && typeof (body as { domain?: unknown }).domain === 'string'\n ? (body as { domain: string }).domain.trim().toLowerCase()\n : '';\n const domain: FeishuSetupDomain = rawDomain === 'lark' ? 'lark' : 'feishu';\n\n const { initAppRegistration, beginAppRegistration } = await import(\n '../../../../extensions/feishu/src/auth/app-registration.js'\n );\n\n const supported = await initAppRegistration(domain);\n if (!supported) {\n return c.json(\n {\n ok: false,\n error: { code: 'FEISHU_SCAN_NOT_SUPPORTED', message: 'Scan-to-create is not available.' },\n },\n 400,\n );\n }\n\n const begin = await beginAppRegistration(domain);\n\n const sessionKey = `feishu-setup-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n\n feishuSetupSessions.set(sessionKey, {\n deviceCode: begin.deviceCode,\n domain,\n intervalSec: begin.intervalSec,\n expireInSec: begin.expireInSec,\n createdAt: Date.now(),\n phase: 'idle',\n });\n\n void startFeishuSetupPolling(sessionKey, service);\n\n return c.json({\n ok: true,\n payload: { sessionKey, qrUrl: begin.qrUrl },\n });\n });\n\n authenticated.get('/api/channels/feishu/setup/:sessionKey', async (c) => {\n const sessionKey = c.req.param('sessionKey')?.trim() ?? '';\n if (!sessionKey) {\n return c.json({ ok: false, error: { code: 'BAD_REQUEST', message: 'Missing sessionKey' } }, 400);\n }\n\n const session = feishuSetupSessions.get(sessionKey);\n if (!session) {\n return c.json({\n ok: true,\n payload: {\n status: { phase: 'unknown' as const, message: 'Session not found or expired.' },\n },\n });\n }\n\n if (session.phase === 'done' && session.result) {\n return c.json({\n ok: true,\n payload: {\n status: {\n phase: 'done' as const,\n ok: true,\n appId: session.result.appId,\n domain: session.result.domain,\n openId: session.result.openId,\n },\n },\n });\n }\n\n if (session.phase === 'error') {\n return c.json({\n ok: true,\n payload: {\n status: {\n phase: 'done' as const,\n ok: false,\n message: session.error ?? 'Setup failed.',\n },\n },\n });\n }\n\n return c.json({\n ok: true,\n payload: {\n status: { phase: 'polling' as const },\n },\n });\n });\n\n authenticated.post('/api/channels/dingtalk/setup/start', strictRateLimitMiddleware, async (c) => {\n const { beginDingtalkRegistration } = await import('../../../../extensions/dingtalk/src/auth/device-auth.js');\n\n let begin;\n try {\n begin = await beginDingtalkRegistration();\n } catch (err) {\n const message = err instanceof Error ? err.message : 'DingTalk registration start failed';\n return c.json({ ok: false, error: { code: 'DINGTALK_SETUP_START_FAILED', message } }, 400);\n }\n\n const sessionKey = `dingtalk-setup-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n\n dingtalkSetupSessions.set(sessionKey, {\n deviceCode: begin.deviceCode,\n intervalSec: begin.intervalSeconds,\n expireInSec: begin.expiresInSeconds,\n createdAt: Date.now(),\n phase: 'idle',\n });\n\n void startDingtalkSetupPolling(sessionKey, service);\n\n return c.json({\n ok: true,\n payload: { sessionKey, qrUrl: begin.verificationUriComplete },\n });\n });\n\n authenticated.get('/api/channels/dingtalk/setup/:sessionKey', async (c) => {\n const sessionKey = c.req.param('sessionKey')?.trim() ?? '';\n if (!sessionKey) {\n return c.json({ ok: false, error: { code: 'BAD_REQUEST', message: 'Missing sessionKey' } }, 400);\n }\n\n const session = dingtalkSetupSessions.get(sessionKey);\n if (!session) {\n return c.json({\n ok: true,\n payload: {\n status: { phase: 'unknown' as const, message: 'Session not found or expired.' },\n },\n });\n }\n\n if (session.phase === 'done' && session.result) {\n return c.json({\n ok: true,\n payload: {\n status: {\n phase: 'done' as const,\n ok: true,\n clientId: session.result.clientId,\n },\n },\n });\n }\n\n if (session.phase === 'error') {\n return c.json({\n ok: true,\n payload: {\n status: {\n phase: 'done' as const,\n ok: false,\n message: session.error ?? 'Setup failed.',\n },\n },\n });\n }\n\n return c.json({\n ok: true,\n payload: {\n status: { phase: 'polling' as const },\n },\n });\n });\n}\n"],"mappings":";;;;wBAKsE;AAsBtE,MAAM,sCAAsB,IAAI,KAAiC;AAYjE,MAAM,wCAAwB,IAAI,KAAmC;AAErE,eAAe,0BAA0B,YAAoB,SAAwC;CACnG,MAAM,UAAU,sBAAsB,IAAI,WAAW;AACrD,KAAI,CAAC,QAAS;CAEd,MAAM,EAAE,uCAAuC,MAAM,OACnD;AAGF,SAAQ,QAAQ;AAEhB,KAAI;EACF,MAAM,QAAQ,MAAM,mCAAmC;GACrD,YAAY,QAAQ;GACpB,iBAAiB,QAAQ;GACzB,kBAAkB,QAAQ;GAC3B,CAAC;AACF,UAAQ,QAAQ;AAChB,UAAQ,SAAS;AACjB,MAAI;GACF,MAAM,aAAa,QAAQ,WAAW,CAAC;GACvC,MAAM,MAAM,aAAa,YAAY,OAAO;GAC5C,MAAM,SAAS,KAAK,MAAM,IAAI;GAG9B,MAAM,WAAY,OAAO,UAAU,YAAY,EAAE;GACjD,MAAM,WACJ,OAAO,SAAS,aAAa,YAAY,SAAS,SAAS,MAAM,GAAG,SAAS,WAAW;GAC1F,MAAM,YAAY,MAAM,QAAQ,SAAS,UAAU,GAAG,SAAS,YAAY,EAAE;AAE7E,UAAO,WAAW;IAChB,GAAG,OAAO;IACV,UAAU;KACR,GAAG;KACH,SAAS;KACT,UAAU,MAAM;KAChB,cAAc,MAAM;KACpB;KACA;KACD;IACF;AAED,SAAM,gBAAgB,YAAY,GAAG,KAAK,UAAU,QAAQ,MAAM,EAAE,CAAC,IAAI;AACzE,SAAM,QAAQ,mCAAmC;UAC3C;UAGD,KAAK;AACZ,UAAQ,QAAQ;AAChB,UAAQ,QAAQ,eAAe,QAAQ,IAAI,UAAU,OAAO,IAAI;;AAGlE,kBAAiB,sBAAsB,OAAO,WAAW,EAAE,IAAO;;AAGpE,eAAe,wBAAwB,YAAoB,SAAwC;CACjG,MAAM,UAAU,oBAAoB,IAAI,WAAW;AACnD,KAAI,CAAC,QAAS;CAEd,MAAM,EAAE,wBAAwB,MAAM,OACpC;AAGF,SAAQ,QAAQ;CAEhB,MAAM,UAAU,MAAM,oBAAoB;EACxC,YAAY,QAAQ;EACpB,aAAa,QAAQ;EACrB,aAAa,QAAQ;EACrB,eAAe,QAAQ;EACxB,CAAC;AAEF,KAAI,QAAQ,WAAW,WAAW;AAChC,UAAQ,QAAQ;AAChB,UAAQ,SAAS,QAAQ;AACzB,MAAI;GACF,MAAM,aAAa,QAAQ,WAAW,CAAC;GACvC,MAAM,MAAM,aAAa,YAAY,OAAO;GAC5C,MAAM,SAAS,KAAK,MAAM,IAAI;GAG9B,MAAM,iBAAkB,OAAO,UAAU,UAAU,EAAE;GACrD,MAAM,WACJ,OAAO,eAAe,aAAa,YAAY,eAAe,SAAS,MAAM,GACzE,eAAe,WACf;GACN,MAAM,gBAAgB,QAAQ,OAAO,QAAQ,MAAM;GACnD,MAAM,YAAY,uBAAuB,eAAe,WAAW,gBAAgB,CAAC,cAAc,GAAG,EAAE,CAAC;AAExG,UAAO,WAAW;IAChB,GAAG,OAAO;IACV,QAAQ;KACN,GAAG;KACH,SAAS;KACT,OAAO,QAAQ,OAAO;KACtB,WAAW,QAAQ,OAAO;KAC1B,QAAQ,QAAQ,OAAO;KACvB,gBAAiB,eAAe,kBAA6B;KAC7D;KACA;KACD;IACF;AAED,SAAM,gBAAgB,YAAY,GAAG,KAAK,UAAU,QAAQ,MAAM,EAAE,CAAC,IAAI;AACzE,SAAM,QAAQ,iCAAiC;UACzC;QAGH;AACL,UAAQ,QAAQ;AAChB,UAAQ,QACN,QAAQ,WAAW,kBACf,+BACA,QAAQ,WAAW,YACjB,qBACA,QAAQ,WAAW,YACjB,oBACA,aAAa,UACX,QAAQ,UACR;;AAGd,kBAAiB,oBAAoB,OAAO,WAAW,EAAE,IAAO;;AAGlE,SAAgB,sBAAsB,eAAqB,MAAoC;CAC7F,MAAM,EAAE,SAAS,8BAA8B;AAE/C,eAAc,IAAI,yBAAyB,MAAM;EAC/C,MAAM,WAAW,QAAQ,mBAAmB;AAC5C,SAAO,EAAE,KAAK;GAAE,IAAI;GAAM,SAAS,EAAE,UAAU;GAAE,CAAC;GAClD;AAEF,eAAc,KAAK,oCAAoC,2BAA2B,OAAO,MAAM;EAC7F,MAAM,OAAO,MAAM,EAAE,IAAI,MAAM,CAAC,aAAa,EAAE,EAAE;EACjD,MAAM,UACJ,QAAQ,OAAO,SAAS,YAAY,OAAQ,KAA+B,YAAY,WAClF,KAA6B,QAAQ,MAAM,IAAI,KAAA,IAChD,KAAA;EACN,MAAM,aACJ,QAAQ,OAAO,SAAS,WAAY,KAAiC,YAAY,KAAA;EACnF,MAAM,YACJ,OAAO,eAAe,YAAY,OAAO,SAAS,WAAW,GAAG,KAAK,IAAI,KAAQ,WAAW,GAAG,KAAA;EAEjG,MAAM,EAAE,8BAA8B,MAAM,OAAO;EACnD,MAAM,SAAS,MAAM,0BAA0B;GAC7C,YAAY,QAAQ,WAAW,CAAC;GAChC;GACA;GACA,aAAa,OAAO,MAAM;AACxB,QAAI,EAAE,GACJ,OAAM,QAAQ,iCAAiC;;GAGpD,CAAC;AAEF,MAAI,OAAO,OAAO,MAChB,QAAO,EAAE,KACP;GAAE,IAAI;GAAO,OAAO;IAAE,MAAM;IAAuB,SAAS,OAAO;IAAS;GAAE,EAC9E,IACD;AAEH,SAAO,EAAE,KAAK;GACZ,IAAI;GACJ,SAAS;IAAE,YAAY,OAAO;IAAY,WAAW,OAAO;IAAW;GACxE,CAAC;GACF;AAEF,eAAc,IAAI,0CAA0C,OAAO,MAAM;EACvE,MAAM,aAAa,EAAE,IAAI,MAAM,aAAa,EAAE,MAAM,IAAI;AACxD,MAAI,CAAC,WACH,QAAO,EAAE,KAAK;GAAE,IAAI;GAAO,OAAO;IAAE,MAAM;IAAe,SAAS;IAAsB;GAAE,EAAE,IAAI;EAElG,MAAM,EAAE,kCAAkC,MAAM,OAAO;EACvD,MAAM,SAAS,8BAA8B,WAAW;AACxD,SAAO,EAAE,KAAK;GAAE,IAAI;GAAM,SAAS,EAAE,QAAQ;GAAE,CAAC;GAChD;AAEF,eAAc,KAAK,oCAAoC,2BAA2B,OAAO,MAAM;EAC7F,MAAM,OAAO,MAAM,EAAE,IAAI,MAAM,CAAC,aAAa,EAAE,EAAE;EAKjD,MAAM,UAHJ,QAAQ,OAAO,SAAS,YAAY,OAAQ,KAA8B,WAAW,WAChF,KAA4B,OAAO,MAAM,CAAC,aAAa,GACxD,QAC0C,SAAS,SAAS;EAElE,MAAM,EAAE,qBAAqB,yBAAyB,MAAM,OAC1D;AAIF,MAAI,CAAC,MADmB,oBAAoB,OAAO,CAEjD,QAAO,EAAE,KACP;GACE,IAAI;GACJ,OAAO;IAAE,MAAM;IAA6B,SAAS;IAAoC;GAC1F,EACD,IACD;EAGH,MAAM,QAAQ,MAAM,qBAAqB,OAAO;EAEhD,MAAM,aAAa,gBAAgB,KAAK,KAAK,CAAC,GAAG,KAAK,QAAQ,CAAC,SAAS,GAAG,CAAC,MAAM,GAAG,EAAE;AAEvF,sBAAoB,IAAI,YAAY;GAClC,YAAY,MAAM;GAClB;GACA,aAAa,MAAM;GACnB,aAAa,MAAM;GACnB,WAAW,KAAK,KAAK;GACrB,OAAO;GACR,CAAC;AAEG,0BAAwB,YAAY,QAAQ;AAEjD,SAAO,EAAE,KAAK;GACZ,IAAI;GACJ,SAAS;IAAE;IAAY,OAAO,MAAM;IAAO;GAC5C,CAAC;GACF;AAEF,eAAc,IAAI,0CAA0C,OAAO,MAAM;EACvE,MAAM,aAAa,EAAE,IAAI,MAAM,aAAa,EAAE,MAAM,IAAI;AACxD,MAAI,CAAC,WACH,QAAO,EAAE,KAAK;GAAE,IAAI;GAAO,OAAO;IAAE,MAAM;IAAe,SAAS;IAAsB;GAAE,EAAE,IAAI;EAGlG,MAAM,UAAU,oBAAoB,IAAI,WAAW;AACnD,MAAI,CAAC,QACH,QAAO,EAAE,KAAK;GACZ,IAAI;GACJ,SAAS,EACP,QAAQ;IAAE,OAAO;IAAoB,SAAS;IAAiC,EAChF;GACF,CAAC;AAGJ,MAAI,QAAQ,UAAU,UAAU,QAAQ,OACtC,QAAO,EAAE,KAAK;GACZ,IAAI;GACJ,SAAS,EACP,QAAQ;IACN,OAAO;IACP,IAAI;IACJ,OAAO,QAAQ,OAAO;IACtB,QAAQ,QAAQ,OAAO;IACvB,QAAQ,QAAQ,OAAO;IACxB,EACF;GACF,CAAC;AAGJ,MAAI,QAAQ,UAAU,QACpB,QAAO,EAAE,KAAK;GACZ,IAAI;GACJ,SAAS,EACP,QAAQ;IACN,OAAO;IACP,IAAI;IACJ,SAAS,QAAQ,SAAS;IAC3B,EACF;GACF,CAAC;AAGJ,SAAO,EAAE,KAAK;GACZ,IAAI;GACJ,SAAS,EACP,QAAQ,EAAE,OAAO,WAAoB,EACtC;GACF,CAAC;GACF;AAEF,eAAc,KAAK,sCAAsC,2BAA2B,OAAO,MAAM;EAC/F,MAAM,EAAE,8BAA8B,MAAM,OAAO;EAEnD,IAAI;AACJ,MAAI;AACF,WAAQ,MAAM,2BAA2B;WAClC,KAAK;GACZ,MAAM,UAAU,eAAe,QAAQ,IAAI,UAAU;AACrD,UAAO,EAAE,KAAK;IAAE,IAAI;IAAO,OAAO;KAAE,MAAM;KAA+B;KAAS;IAAE,EAAE,IAAI;;EAG5F,MAAM,aAAa,kBAAkB,KAAK,KAAK,CAAC,GAAG,KAAK,QAAQ,CAAC,SAAS,GAAG,CAAC,MAAM,GAAG,EAAE;AAEzF,wBAAsB,IAAI,YAAY;GACpC,YAAY,MAAM;GAClB,aAAa,MAAM;GACnB,aAAa,MAAM;GACnB,WAAW,KAAK,KAAK;GACrB,OAAO;GACR,CAAC;AAEG,4BAA0B,YAAY,QAAQ;AAEnD,SAAO,EAAE,KAAK;GACZ,IAAI;GACJ,SAAS;IAAE;IAAY,OAAO,MAAM;IAAyB;GAC9D,CAAC;GACF;AAEF,eAAc,IAAI,4CAA4C,OAAO,MAAM;EACzE,MAAM,aAAa,EAAE,IAAI,MAAM,aAAa,EAAE,MAAM,IAAI;AACxD,MAAI,CAAC,WACH,QAAO,EAAE,KAAK;GAAE,IAAI;GAAO,OAAO;IAAE,MAAM;IAAe,SAAS;IAAsB;GAAE,EAAE,IAAI;EAGlG,MAAM,UAAU,sBAAsB,IAAI,WAAW;AACrD,MAAI,CAAC,QACH,QAAO,EAAE,KAAK;GACZ,IAAI;GACJ,SAAS,EACP,QAAQ;IAAE,OAAO;IAAoB,SAAS;IAAiC,EAChF;GACF,CAAC;AAGJ,MAAI,QAAQ,UAAU,UAAU,QAAQ,OACtC,QAAO,EAAE,KAAK;GACZ,IAAI;GACJ,SAAS,EACP,QAAQ;IACN,OAAO;IACP,IAAI;IACJ,UAAU,QAAQ,OAAO;IAC1B,EACF;GACF,CAAC;AAGJ,MAAI,QAAQ,UAAU,QACpB,QAAO,EAAE,KAAK;GACZ,IAAI;GACJ,SAAS,EACP,QAAQ;IACN,OAAO;IACP,IAAI;IACJ,SAAS,QAAQ,SAAS;IAC3B,EACF;GACF,CAAC;AAGJ,SAAO,EAAE,KAAK;GACZ,IAAI;GACJ,SAAS,EACP,QAAQ,EAAE,OAAO,WAAoB,EACtC;GACF,CAAC;GACF"}
1
+ {"version":3,"file":"channels.js","names":[],"sources":["../../../../../src/gateway/hono/routes/channels.ts"],"sourcesContent":["import { readFileSync } from 'node:fs';\n\nimport type { Hono } from 'hono';\n\nimport { mergeDistinctSenderIds } from '../../../channels/pairing/index.js';\nimport { writeTextAtomic } from '../../../infra/write-file-atomic.js';\nimport type { GatewayService } from '../../service.js';\nimport type { AuthenticatedRouteDeps } from './deps.js';\n\ntype FeishuSetupDomain = 'feishu' | 'lark';\n\ninterface FeishuSetupSession {\n deviceCode: string;\n domain: FeishuSetupDomain;\n intervalSec: number;\n expireInSec: number;\n createdAt: number;\n phase: 'idle' | 'polling' | 'scanned' | 'done' | 'error';\n result?: {\n appId: string;\n appSecret: string;\n domain: FeishuSetupDomain;\n openId?: string;\n };\n error?: string;\n}\n\nconst feishuSetupSessions = new Map<string, FeishuSetupSession>();\n\ninterface DingtalkSetupSession {\n deviceCode: string;\n intervalSec: number;\n expireInSec: number;\n createdAt: number;\n phase: 'idle' | 'polling' | 'done' | 'error';\n result?: { clientId: string; clientSecret: string };\n error?: string;\n}\n\nconst dingtalkSetupSessions = new Map<string, DingtalkSetupSession>();\n\nasync function startDingtalkSetupPolling(sessionKey: string, service: GatewayService): Promise<void> {\n const session = dingtalkSetupSessions.get(sessionKey);\n if (!session) return;\n\n const { waitForDingtalkRegistrationSuccess } = await import(\n '../../../../extensions/dingtalk/src/auth/device-auth.js'\n );\n\n session.phase = 'polling';\n\n try {\n const creds = await waitForDingtalkRegistrationSuccess({\n deviceCode: session.deviceCode,\n intervalSeconds: session.intervalSec,\n expiresInSeconds: session.expireInSec,\n });\n session.phase = 'done';\n session.result = creds;\n try {\n const configPath = service.getHealth().configPath;\n const raw = readFileSync(configPath, 'utf8');\n const config = JSON.parse(raw) as {\n channels?: Record<string, unknown>;\n };\n const existing = (config.channels?.dingtalk ?? {}) as Record<string, unknown>;\n const dmPolicy =\n typeof existing.dmPolicy === 'string' && existing.dmPolicy.trim() ? existing.dmPolicy : 'open';\n const allowFrom = Array.isArray(existing.allowFrom) ? existing.allowFrom : [];\n\n config.channels = {\n ...config.channels,\n dingtalk: {\n ...existing,\n enabled: true,\n clientId: creds.clientId,\n clientSecret: creds.clientSecret,\n dmPolicy,\n allowFrom,\n },\n };\n\n await writeTextAtomic(configPath, `${JSON.stringify(config, null, 2)}\\n`);\n await service.afterDingtalkCredentialsPersisted();\n } catch {\n /* non-blocking */\n }\n } catch (err) {\n session.phase = 'error';\n session.error = err instanceof Error ? err.message : String(err);\n }\n\n setTimeout(() => dingtalkSetupSessions.delete(sessionKey), 30_000);\n}\n\nasync function startFeishuSetupPolling(sessionKey: string, service: GatewayService): Promise<void> {\n const session = feishuSetupSessions.get(sessionKey);\n if (!session) return;\n\n const { pollAppRegistration } = await import(\n '../../../../extensions/feishu/src/auth/app-registration.js'\n );\n\n session.phase = 'polling';\n\n const outcome = await pollAppRegistration({\n deviceCode: session.deviceCode,\n intervalSec: session.intervalSec,\n expireInSec: session.expireInSec,\n initialDomain: session.domain,\n });\n\n if (outcome.status === 'success') {\n session.phase = 'done';\n session.result = outcome.result;\n try {\n const configPath = service.getHealth().configPath;\n const raw = readFileSync(configPath, 'utf8');\n const config = JSON.parse(raw) as {\n channels?: Record<string, unknown>;\n };\n const existingFeishu = (config.channels?.feishu ?? {}) as Record<string, unknown>;\n const dmPolicy =\n typeof existingFeishu.dmPolicy === 'string' && existingFeishu.dmPolicy.trim()\n ? existingFeishu.dmPolicy\n : 'open';\n const preseedOpenId = outcome.result.openId?.trim();\n const allowFrom = mergeDistinctSenderIds(existingFeishu.allowFrom, preseedOpenId ? [preseedOpenId] : []);\n\n config.channels = {\n ...config.channels,\n feishu: {\n ...existingFeishu,\n enabled: true,\n appId: outcome.result.appId,\n appSecret: outcome.result.appSecret,\n domain: outcome.result.domain,\n connectionMode: (existingFeishu.connectionMode as string) || 'websocket',\n dmPolicy,\n allowFrom,\n },\n };\n\n await writeTextAtomic(configPath, `${JSON.stringify(config, null, 2)}\\n`);\n await service.afterFeishuCredentialsPersisted();\n } catch {\n // Config write / reload failure is non-blocking; session still carries credentials for debugging.\n }\n } else {\n session.phase = 'error';\n session.error =\n outcome.status === 'access_denied'\n ? 'User denied authorization.'\n : outcome.status === 'expired'\n ? 'Session expired.'\n : outcome.status === 'timeout'\n ? 'Scan timed out.'\n : 'message' in outcome\n ? outcome.message\n : 'Unknown error.';\n }\n\n setTimeout(() => feishuSetupSessions.delete(sessionKey), 30_000);\n}\n\nexport function registerChannelRoutes(authenticated: Hono, deps: AuthenticatedRouteDeps): void {\n const { service, strictRateLimitMiddleware } = deps;\n\n authenticated.get('/api/channels/status', (c) => {\n const channels = service.getChannelsStatus();\n return c.json({ ok: true, payload: { channels } });\n });\n\n authenticated.post('/api/channels/weixin/login/start', strictRateLimitMiddleware, async (c) => {\n const body = await c.req.json().catch(() => ({}));\n const account =\n body && typeof body === 'object' && typeof (body as { account?: unknown }).account === 'string'\n ? (body as { account: string }).account.trim() || undefined\n : undefined;\n const rawTimeout =\n body && typeof body === 'object' ? (body as { timeoutMs?: unknown }).timeoutMs : undefined;\n const timeoutMs =\n typeof rawTimeout === 'number' && Number.isFinite(rawTimeout) ? Math.max(60_000, rawTimeout) : undefined;\n\n const { startWeixinGatewayQrLogin } = await import('../../../channels/weixin/index.js');\n const result = await startWeixinGatewayQrLogin({\n configPath: service.getHealth().configPath,\n account,\n timeoutMs,\n onPersisted: async (r) => {\n if (r.ok) {\n await service.afterWeixinCredentialsPersisted();\n }\n },\n });\n\n if (result.ok === false) {\n return c.json(\n { ok: false, error: { code: 'WEIXIN_LOGIN_FAILED', message: result.message } },\n 400,\n );\n }\n return c.json({\n ok: true,\n payload: { sessionKey: result.sessionKey, qrcodeUrl: result.qrcodeUrl },\n });\n });\n\n authenticated.get('/api/channels/weixin/login/:sessionKey', async (c) => {\n const sessionKey = c.req.param('sessionKey')?.trim() ?? '';\n if (!sessionKey) {\n return c.json({ ok: false, error: { code: 'BAD_REQUEST', message: 'Missing sessionKey' } }, 400);\n }\n const { getWeixinGatewayQrLoginStatus } = await import('../../../channels/weixin/index.js');\n const status = getWeixinGatewayQrLoginStatus(sessionKey);\n return c.json({ ok: true, payload: { status } });\n });\n\n authenticated.post('/api/channels/feishu/setup/start', strictRateLimitMiddleware, async (c) => {\n const body = await c.req.json().catch(() => ({}));\n const rawDomain =\n body && typeof body === 'object' && typeof (body as { domain?: unknown }).domain === 'string'\n ? (body as { domain: string }).domain.trim().toLowerCase()\n : '';\n const domain: FeishuSetupDomain = rawDomain === 'lark' ? 'lark' : 'feishu';\n\n const { initAppRegistration, beginAppRegistration } = await import(\n '../../../../extensions/feishu/src/auth/app-registration.js'\n );\n\n const supported = await initAppRegistration(domain);\n if (!supported) {\n return c.json(\n {\n ok: false,\n error: { code: 'FEISHU_SCAN_NOT_SUPPORTED', message: 'Scan-to-create is not available.' },\n },\n 400,\n );\n }\n\n const begin = await beginAppRegistration(domain);\n\n const sessionKey = `feishu-setup-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n\n feishuSetupSessions.set(sessionKey, {\n deviceCode: begin.deviceCode,\n domain,\n intervalSec: begin.intervalSec,\n expireInSec: begin.expireInSec,\n createdAt: Date.now(),\n phase: 'idle',\n });\n\n void startFeishuSetupPolling(sessionKey, service);\n\n return c.json({\n ok: true,\n payload: { sessionKey, qrUrl: begin.qrUrl },\n });\n });\n\n authenticated.get('/api/channels/feishu/setup/:sessionKey', async (c) => {\n const sessionKey = c.req.param('sessionKey')?.trim() ?? '';\n if (!sessionKey) {\n return c.json({ ok: false, error: { code: 'BAD_REQUEST', message: 'Missing sessionKey' } }, 400);\n }\n\n const session = feishuSetupSessions.get(sessionKey);\n if (!session) {\n return c.json({\n ok: true,\n payload: {\n status: { phase: 'unknown' as const, message: 'Session not found or expired.' },\n },\n });\n }\n\n if (session.phase === 'done' && session.result) {\n return c.json({\n ok: true,\n payload: {\n status: {\n phase: 'done' as const,\n ok: true,\n appId: session.result.appId,\n domain: session.result.domain,\n openId: session.result.openId,\n },\n },\n });\n }\n\n if (session.phase === 'error') {\n return c.json({\n ok: true,\n payload: {\n status: {\n phase: 'done' as const,\n ok: false,\n message: session.error ?? 'Setup failed.',\n },\n },\n });\n }\n\n return c.json({\n ok: true,\n payload: {\n status: { phase: 'polling' as const },\n },\n });\n });\n\n authenticated.post('/api/channels/dingtalk/setup/start', strictRateLimitMiddleware, async (c) => {\n const { beginDingtalkRegistration } = await import('../../../../extensions/dingtalk/src/auth/device-auth.js');\n\n let begin;\n try {\n begin = await beginDingtalkRegistration();\n } catch (err) {\n const message = err instanceof Error ? err.message : 'DingTalk registration start failed';\n return c.json({ ok: false, error: { code: 'DINGTALK_SETUP_START_FAILED', message } }, 400);\n }\n\n const sessionKey = `dingtalk-setup-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;\n\n dingtalkSetupSessions.set(sessionKey, {\n deviceCode: begin.deviceCode,\n intervalSec: begin.intervalSeconds,\n expireInSec: begin.expiresInSeconds,\n createdAt: Date.now(),\n phase: 'idle',\n });\n\n void startDingtalkSetupPolling(sessionKey, service);\n\n return c.json({\n ok: true,\n payload: { sessionKey, qrUrl: begin.verificationUriComplete },\n });\n });\n\n authenticated.get('/api/channels/dingtalk/setup/:sessionKey', async (c) => {\n const sessionKey = c.req.param('sessionKey')?.trim() ?? '';\n if (!sessionKey) {\n return c.json({ ok: false, error: { code: 'BAD_REQUEST', message: 'Missing sessionKey' } }, 400);\n }\n\n const session = dingtalkSetupSessions.get(sessionKey);\n if (!session) {\n return c.json({\n ok: true,\n payload: {\n status: { phase: 'unknown' as const, message: 'Session not found or expired.' },\n },\n });\n }\n\n if (session.phase === 'done' && session.result) {\n return c.json({\n ok: true,\n payload: {\n status: {\n phase: 'done' as const,\n ok: true,\n clientId: session.result.clientId,\n },\n },\n });\n }\n\n if (session.phase === 'error') {\n return c.json({\n ok: true,\n payload: {\n status: {\n phase: 'done' as const,\n ok: false,\n message: session.error ?? 'Setup failed.',\n },\n },\n });\n }\n\n return c.json({\n ok: true,\n payload: {\n status: { phase: 'polling' as const },\n },\n });\n });\n}\n"],"mappings":"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"}
@@ -426,7 +426,7 @@ function registerConfigRoutes(authenticated, deps) {
426
426
  if (!config.channels) config.channels = {};
427
427
  if (!config.channels.weixin) config.channels.weixin = {
428
428
  enabled: false,
429
- dmPolicy: "pairing",
429
+ dmPolicy: "open",
430
430
  allowFrom: [],
431
431
  debug: false,
432
432
  historyLimit: 50,
@@ -461,7 +461,7 @@ function registerConfigRoutes(authenticated, deps) {
461
461
  appSecret: "",
462
462
  domain: "feishu",
463
463
  connectionMode: "websocket",
464
- dmPolicy: "pairing",
464
+ dmPolicy: "open",
465
465
  groupPolicy: "allowlist",
466
466
  allowFrom: [],
467
467
  groupAllowFrom: [],
@@ -532,7 +532,7 @@ function registerConfigRoutes(authenticated, deps) {
532
532
  enabled: false,
533
533
  clientId: "",
534
534
  clientSecret: "",
535
- dmPolicy: "pairing",
535
+ dmPolicy: "open",
536
536
  groupPolicy: "open",
537
537
  allowFrom: [],
538
538
  groupAllowFrom: [],
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","names":[],"sources":["../../../../../src/gateway/hono/routes/config.ts"],"sourcesContent":["import type { Hono } from 'hono';\n\nimport { type Config, BindingsConfigSchema } from '../../../config/schema.js';\nimport { CredentialResolver } from '../../../auth/credentials.js';\nimport { applyToolsWebPatch } from '../../config-tools-web.js';\nimport { buildSafeWebConfigPayload } from '../lib/config-payload.js';\nimport {\n normalizePatchAgentImageGenerationModel,\n normalizePatchAgentModel,\n} from '../lib/agent-model.js';\nimport type { AuthenticatedRouteDeps } from './deps.js';\n\nexport function registerConfigRoutes(authenticated: Hono, deps: AuthenticatedRouteDeps): void {\n const { service, strictRateLimitMiddleware } = deps;\n\n authenticated.post('/api/config/reload', strictRateLimitMiddleware, async (c) => {\n const result = await service.reloadConfig();\n return c.json({ ok: true, payload: result });\n });\n\n authenticated.post('/api/heartbeat/trigger', strictRateLimitMiddleware, async (c) => {\n let reason = 'manual';\n try {\n const body = await c.req.json();\n if (body && typeof body === 'object' && typeof (body as { reason?: unknown }).reason === 'string') {\n const r = (body as { reason: string }).reason.trim();\n if (r) reason = r.slice(0, 120);\n }\n } catch {\n /* empty or invalid body */\n }\n service.requestHeartbeatNow({ reason });\n return c.json({ ok: true, payload: { scheduled: true } });\n });\n\n authenticated.get('/api/config', async (c) => {\n const safeConfig = await buildSafeWebConfigPayload(service);\n return c.json({ ok: true, payload: { config: safeConfig } });\n });\n\n authenticated.patch('/api/config', strictRateLimitMiddleware, async (c) => {\n const body = await c.req.json();\n \n // Merge updates into current config\n const config: Config = service.currentConfig as Config;\n \n // Update agent defaults\n if (body.agents?.defaults) {\n if (!config.agents) config.agents = { defaults: { workspace: '~/.xopc/workspace', model: 'anthropic/claude-sonnet-4-5', maxTokens: 8192, temperature: 0.7, maxToolIterations: 20, maxRequestsPerTurn: 50, maxToolFailuresPerTurn: 3, thinkingDefault: 'medium', reasoningDefault: 'stream', verboseDefault: 'full' } };\n if (!config.agents.defaults) config.agents.defaults = {} as any;\n \n if (body.agents.defaults.model !== undefined) {\n config.agents.defaults.model = normalizePatchAgentModel(body.agents.defaults.model) as Config['agents']['defaults']['model'];\n }\n if (body.agents.defaults.maxTokens !== undefined) {\n config.agents.defaults.maxTokens = body.agents.defaults.maxTokens;\n }\n if (body.agents.defaults.temperature !== undefined) {\n config.agents.defaults.temperature = body.agents.defaults.temperature;\n }\n if (body.agents.defaults.maxToolIterations !== undefined) {\n config.agents.defaults.maxToolIterations = body.agents.defaults.maxToolIterations;\n }\n if (body.agents.defaults.workspace !== undefined) {\n config.agents.defaults.workspace = body.agents.defaults.workspace;\n }\n if (body.agents.defaults.thinkingDefault !== undefined) {\n config.agents.defaults.thinkingDefault = body.agents.defaults.thinkingDefault;\n }\n if (body.agents.defaults.reasoningDefault !== undefined) {\n config.agents.defaults.reasoningDefault = body.agents.defaults.reasoningDefault;\n }\n if (body.agents.defaults.verboseDefault !== undefined) {\n config.agents.defaults.verboseDefault = body.agents.defaults.verboseDefault;\n }\n if (body.agents.defaults.imageModel !== undefined) {\n const v = body.agents.defaults.imageModel;\n if (v === '' || v === null) {\n delete (config.agents.defaults as Record<string, unknown>).imageModel;\n } else {\n config.agents.defaults.imageModel = normalizePatchAgentModel(v) as Config['agents']['defaults']['imageModel'];\n }\n }\n if (body.agents.defaults.imageGenerationModel !== undefined) {\n const v = body.agents.defaults.imageGenerationModel;\n if (v === '' || v === null) {\n delete (config.agents.defaults as Record<string, unknown>).imageGenerationModel;\n } else {\n const normalized = normalizePatchAgentImageGenerationModel(v);\n if (normalized === undefined) {\n delete (config.agents.defaults as Record<string, unknown>).imageGenerationModel;\n } else {\n config.agents.defaults.imageGenerationModel =\n normalized as Config['agents']['defaults']['imageGenerationModel'];\n }\n }\n }\n if (body.agents.defaults.mediaMaxMb !== undefined) {\n const v = body.agents.defaults.mediaMaxMb;\n if (v === null) {\n delete (config.agents.defaults as Record<string, unknown>).mediaMaxMb;\n } else {\n const n = typeof v === 'number' ? v : Number(v);\n if (!Number.isNaN(n) && n > 0) {\n config.agents.defaults.mediaMaxMb = n;\n }\n }\n }\n if (body.agents.defaults.browser !== undefined) {\n const b = body.agents.defaults.browser;\n if (b === null) {\n delete (config.agents.defaults as Record<string, unknown>).browser;\n } else if (typeof b === 'object' && !Array.isArray(b)) {\n const br = b as Record<string, unknown>;\n if (!config.agents.defaults.browser) {\n config.agents.defaults.browser = { enabled: false, headless: true };\n }\n const target = config.agents.defaults.browser;\n if (br.enabled !== undefined) {\n target.enabled = Boolean(br.enabled);\n }\n if (br.headless !== undefined) {\n target.headless = Boolean(br.headless);\n }\n }\n }\n\n const dPatch = body.agents.defaults as Record<string, unknown>;\n const def = config.agents.defaults as Record<string, unknown>;\n\n if (dPatch.maxTaskDurationMs !== undefined) {\n const v = dPatch.maxTaskDurationMs;\n if (v === null) {\n delete def.maxTaskDurationMs;\n } else if (typeof v === 'number' && Number.isFinite(v)) {\n const ms = Math.floor(v);\n if (ms >= 60_000 && ms <= 14_400_000) {\n def.maxTaskDurationMs = ms;\n }\n }\n }\n if (dPatch.maxRequestsPerTurn !== undefined) {\n const v = dPatch.maxRequestsPerTurn;\n if (v === null) {\n delete def.maxRequestsPerTurn;\n } else if (typeof v === 'number' && Number.isFinite(v)) {\n const n = Math.floor(v);\n if (n >= 10 && n <= 200) {\n def.maxRequestsPerTurn = n;\n }\n }\n }\n if (dPatch.maxToolFailuresPerTurn !== undefined) {\n const v = dPatch.maxToolFailuresPerTurn;\n if (v === null) {\n delete def.maxToolFailuresPerTurn;\n } else if (typeof v === 'number' && Number.isFinite(v)) {\n const n = Math.floor(v);\n if (n >= 1 && n <= 20) {\n def.maxToolFailuresPerTurn = n;\n }\n }\n }\n\n if (dPatch.compaction !== undefined) {\n const c = dPatch.compaction;\n if (c === null) {\n delete def.compaction;\n } else if (typeof c === 'object' && !Array.isArray(c)) {\n const p = c as Record<string, unknown>;\n if (!def.compaction || typeof def.compaction !== 'object') {\n def.compaction = {};\n }\n const t = def.compaction as Record<string, unknown>;\n if (p.enabled !== undefined) t.enabled = Boolean(p.enabled);\n if (p.mode === 'default' || p.mode === 'safeguard') t.mode = p.mode;\n if (typeof p.reserveTokens === 'number' && Number.isFinite(p.reserveTokens)) {\n t.reserveTokens = Math.floor(p.reserveTokens);\n }\n if (typeof p.triggerThreshold === 'number' && Number.isFinite(p.triggerThreshold)) {\n const x = p.triggerThreshold;\n if (x >= 0.5 && x <= 0.95) t.triggerThreshold = x;\n }\n if (typeof p.minMessagesBeforeCompact === 'number' && Number.isFinite(p.minMessagesBeforeCompact)) {\n t.minMessagesBeforeCompact = Math.floor(p.minMessagesBeforeCompact);\n }\n if (typeof p.keepRecentMessages === 'number' && Number.isFinite(p.keepRecentMessages)) {\n t.keepRecentMessages = Math.floor(p.keepRecentMessages);\n }\n if (typeof p.evictionWindow === 'number' && Number.isFinite(p.evictionWindow)) {\n const x = p.evictionWindow;\n if (x >= 0.1 && x <= 0.5) t.evictionWindow = x;\n }\n if (typeof p.retentionWindow === 'number' && Number.isFinite(p.retentionWindow)) {\n const n = Math.floor(p.retentionWindow);\n if (n >= 3 && n <= 20) t.retentionWindow = n;\n }\n }\n }\n\n if (dPatch.pruning !== undefined) {\n const c = dPatch.pruning;\n if (c === null) {\n delete def.pruning;\n } else if (typeof c === 'object' && !Array.isArray(c)) {\n const p = c as Record<string, unknown>;\n if (!def.pruning || typeof def.pruning !== 'object') {\n def.pruning = {};\n }\n const t = def.pruning as Record<string, unknown>;\n if (p.enabled !== undefined) t.enabled = Boolean(p.enabled);\n if (typeof p.maxToolResultChars === 'number' && Number.isFinite(p.maxToolResultChars)) {\n t.maxToolResultChars = Math.floor(p.maxToolResultChars);\n }\n if (typeof p.headKeepRatio === 'number' && Number.isFinite(p.headKeepRatio)) {\n t.headKeepRatio = p.headKeepRatio;\n }\n if (typeof p.tailKeepRatio === 'number' && Number.isFinite(p.tailKeepRatio)) {\n t.tailKeepRatio = p.tailKeepRatio;\n }\n }\n }\n\n if (dPatch.memory !== undefined) {\n const c = dPatch.memory;\n if (c === null) {\n delete def.memory;\n } else if (typeof c === 'object' && !Array.isArray(c)) {\n const p = c as Record<string, unknown>;\n if (!def.memory || typeof def.memory !== 'object') {\n def.memory = {};\n }\n const t = def.memory as Record<string, unknown>;\n if (p.enabled !== undefined) {\n if (p.enabled === null) delete t.enabled;\n else t.enabled = Boolean(p.enabled);\n }\n if (p.useEnhancedSystem !== undefined) {\n if (p.useEnhancedSystem === null) delete t.useEnhancedSystem;\n else t.useEnhancedSystem = Boolean(p.useEnhancedSystem);\n }\n if (p.userProfileEnabled !== undefined) {\n if (p.userProfileEnabled === null) delete t.userProfileEnabled;\n else t.userProfileEnabled = Boolean(p.userProfileEnabled);\n }\n if (p.memoryCharLimit !== undefined) {\n if (p.memoryCharLimit === null) delete t.memoryCharLimit;\n else if (typeof p.memoryCharLimit === 'number' && p.memoryCharLimit > 0) {\n t.memoryCharLimit = Math.floor(p.memoryCharLimit);\n }\n }\n if (p.userCharLimit !== undefined) {\n if (p.userCharLimit === null) delete t.userCharLimit;\n else if (typeof p.userCharLimit === 'number' && p.userCharLimit > 0) {\n t.userCharLimit = Math.floor(p.userCharLimit);\n }\n }\n if (p.provider === 'none' || p.provider === 'stub') {\n t.provider = p.provider;\n } else if (p.provider === null) {\n delete t.provider;\n }\n if (p.injectionFrequency === 'every-turn' || p.injectionFrequency === 'first-turn') {\n t.injectionFrequency = p.injectionFrequency;\n } else if (p.injectionFrequency === null) {\n delete t.injectionFrequency;\n }\n if (p.contextCadence !== undefined) {\n if (p.contextCadence === null) delete t.contextCadence;\n else if (typeof p.contextCadence === 'number' && p.contextCadence >= 1) {\n t.contextCadence = Math.floor(p.contextCadence);\n }\n }\n if (p.dialecticCadence !== undefined) {\n if (p.dialecticCadence === null) delete t.dialecticCadence;\n else if (typeof p.dialecticCadence === 'number' && p.dialecticCadence >= 1) {\n t.dialecticCadence = Math.floor(p.dialecticCadence);\n }\n }\n\n // Dreaming (schemaless patch): agents.defaults.memory.dreaming\n if (p.dreaming !== undefined) {\n const d0 = p.dreaming;\n if (d0 === null) {\n delete (t as { dreaming?: unknown }).dreaming;\n } else if (typeof d0 === 'object' && d0 !== null && !Array.isArray(d0)) {\n if (!('dreaming' in t) || typeof (t as { dreaming?: unknown }).dreaming !== 'object') {\n (t as { dreaming?: Record<string, unknown> }).dreaming = {};\n }\n const dt = (t as { dreaming: Record<string, unknown> }).dreaming;\n const dp = d0 as Record<string, unknown>;\n\n if (dp.enabled !== undefined) {\n if (dp.enabled === null) delete dt.enabled;\n else dt.enabled = Boolean(dp.enabled);\n }\n if (dp.frequency !== undefined) {\n const v = dp.frequency;\n if (v === null || v === '') delete dt.frequency;\n else if (typeof v === 'string') dt.frequency = v;\n }\n if (dp.timezone !== undefined) {\n const v = dp.timezone;\n if (v === null || v === '') delete dt.timezone;\n else if (typeof v === 'string') dt.timezone = v;\n }\n\n // Accept either `phases.deep` or `deep`.\n if (dp.phases !== undefined || dp.deep !== undefined) {\n if (!('phases' in dt) || typeof (dt as { phases?: unknown }).phases !== 'object' || (dt as { phases?: unknown }).phases === null) {\n dt.phases = {};\n }\n const phases = (dt as { phases: Record<string, unknown> }).phases;\n if (!('deep' in phases) || typeof phases.deep !== 'object' || phases.deep === null) {\n phases.deep = {};\n }\n const deep = phases.deep as Record<string, unknown>;\n\n const deepPatchRaw =\n typeof dp.phases === 'object' && dp.phases !== null && !Array.isArray(dp.phases)\n ? (dp.phases as Record<string, unknown>).deep\n : dp.deep;\n const deepPatch =\n typeof deepPatchRaw === 'object' && deepPatchRaw !== null && !Array.isArray(deepPatchRaw)\n ? (deepPatchRaw as Record<string, unknown>)\n : null;\n\n if (deepPatch) {\n if (deepPatch.enabled !== undefined) {\n if (deepPatch.enabled === null) delete deep.enabled;\n else deep.enabled = Boolean(deepPatch.enabled);\n }\n if (deepPatch.minScore !== undefined) {\n const v = deepPatch.minScore;\n if (v === null) delete deep.minScore;\n else if (typeof v === 'number' && Number.isFinite(v)) deep.minScore = v;\n }\n if (deepPatch.minRecallCount !== undefined) {\n const v = deepPatch.minRecallCount;\n if (v === null) delete deep.minRecallCount;\n else if (typeof v === 'number' && Number.isFinite(v)) deep.minRecallCount = Math.floor(v);\n }\n if (deepPatch.limit !== undefined) {\n const v = deepPatch.limit;\n if (v === null) delete deep.limit;\n else if (typeof v === 'number' && Number.isFinite(v)) deep.limit = Math.floor(v);\n }\n }\n }\n }\n }\n }\n }\n\n if (dPatch.sessionSearch !== undefined) {\n const c = dPatch.sessionSearch;\n if (c === null) {\n delete def.sessionSearch;\n } else if (typeof c === 'object' && !Array.isArray(c)) {\n const p = c as Record<string, unknown>;\n if (!def.sessionSearch || typeof def.sessionSearch !== 'object') {\n def.sessionSearch = {};\n }\n const t = def.sessionSearch as Record<string, unknown>;\n if (p.summaryModel !== undefined) {\n if (p.summaryModel === null || p.summaryModel === '') {\n delete t.summaryModel;\n } else if (typeof p.summaryModel === 'string') {\n t.summaryModel = p.summaryModel;\n }\n }\n }\n }\n\n if (dPatch.backgroundReview !== undefined) {\n const c = dPatch.backgroundReview;\n if (c === null) {\n delete def.backgroundReview;\n } else if (typeof c === 'object' && !Array.isArray(c)) {\n const p = c as Record<string, unknown>;\n if (!def.backgroundReview || typeof def.backgroundReview !== 'object') {\n def.backgroundReview = {};\n }\n const t = def.backgroundReview as Record<string, unknown>;\n if (p.enabled !== undefined) {\n if (p.enabled === null) delete t.enabled;\n else t.enabled = Boolean(p.enabled);\n }\n if (p.memoryNudgeInterval !== undefined) {\n if (p.memoryNudgeInterval === null) delete t.memoryNudgeInterval;\n else if (typeof p.memoryNudgeInterval === 'number' && p.memoryNudgeInterval >= 0) {\n t.memoryNudgeInterval = Math.floor(p.memoryNudgeInterval);\n }\n }\n if (p.skillNudgeInterval !== undefined) {\n if (p.skillNudgeInterval === null) delete t.skillNudgeInterval;\n else if (typeof p.skillNudgeInterval === 'number' && p.skillNudgeInterval >= 0) {\n t.skillNudgeInterval = Math.floor(p.skillNudgeInterval);\n }\n }\n if (p.maxToolRounds !== undefined) {\n if (p.maxToolRounds === null) delete t.maxToolRounds;\n else if (typeof p.maxToolRounds === 'number' && p.maxToolRounds >= 1 && p.maxToolRounds <= 32) {\n t.maxToolRounds = Math.floor(p.maxToolRounds);\n }\n }\n if (p.maxHistoryMessages !== undefined) {\n if (p.maxHistoryMessages === null) delete t.maxHistoryMessages;\n else if (typeof p.maxHistoryMessages === 'number' && p.maxHistoryMessages >= 10 && p.maxHistoryMessages <= 200) {\n t.maxHistoryMessages = Math.floor(p.maxHistoryMessages);\n }\n }\n if (p.maxDurationMs !== undefined) {\n if (p.maxDurationMs === null) delete t.maxDurationMs;\n else if (typeof p.maxDurationMs === 'number' && p.maxDurationMs >= 30_000 && p.maxDurationMs <= 600_000) {\n t.maxDurationMs = Math.floor(p.maxDurationMs);\n }\n }\n }\n }\n\n if (dPatch.webExtract !== undefined) {\n const c = dPatch.webExtract;\n if (c === null) {\n delete def.webExtract;\n } else if (typeof c === 'object' && !Array.isArray(c)) {\n const p = c as Record<string, unknown>;\n if (!def.webExtract || typeof def.webExtract !== 'object') {\n def.webExtract = {};\n }\n const t = def.webExtract as Record<string, unknown>;\n if (p.model !== undefined) {\n if (p.model === null || p.model === '') {\n delete t.model;\n } else if (typeof p.model === 'string') {\n t.model = p.model;\n }\n }\n if (p.maxLength !== undefined) {\n if (p.maxLength === null) delete t.maxLength;\n else if (typeof p.maxLength === 'number' && p.maxLength > 0) {\n t.maxLength = p.maxLength;\n }\n }\n }\n }\n\n if (dPatch.delegate !== undefined) {\n const c = dPatch.delegate;\n if (c === null) {\n delete def.delegate;\n } else if (typeof c === 'object' && !Array.isArray(c)) {\n const p = c as Record<string, unknown>;\n if (!def.delegate || typeof def.delegate !== 'object') {\n def.delegate = {};\n }\n const t = def.delegate as Record<string, unknown>;\n if (p.enabled !== undefined) {\n if (p.enabled === null) delete t.enabled;\n else t.enabled = Boolean(p.enabled);\n }\n }\n }\n\n if (dPatch.executeCode !== undefined) {\n const c = dPatch.executeCode;\n if (c === null) {\n delete def.executeCode;\n } else if (typeof c === 'object' && !Array.isArray(c)) {\n const p = c as Record<string, unknown>;\n if (!def.executeCode || typeof def.executeCode !== 'object') {\n def.executeCode = {};\n }\n const t = def.executeCode as Record<string, unknown>;\n if (p.enabled !== undefined) {\n if (p.enabled === null) delete t.enabled;\n else t.enabled = Boolean(p.enabled);\n }\n }\n }\n\n if (dPatch.systemPromptOverride !== undefined) {\n const v = dPatch.systemPromptOverride;\n if (v === null || v === '') {\n delete def.systemPromptOverride;\n } else if (typeof v === 'string') {\n def.systemPromptOverride = v;\n }\n }\n\n if (dPatch.skills !== undefined) {\n const v = dPatch.skills;\n if (v === null) {\n delete def.skills;\n } else if (Array.isArray(v) && v.every((x) => typeof x === 'string')) {\n def.skills = v;\n }\n }\n\n if (dPatch.tools !== undefined) {\n const t0 = dPatch.tools;\n if (t0 === null) {\n delete def.tools;\n } else if (typeof t0 === 'object' && !Array.isArray(t0)) {\n const p = t0 as { disable?: unknown };\n if (!def.tools || typeof def.tools !== 'object') {\n def.tools = {};\n }\n const t = def.tools as { disable?: string[] };\n if (p.disable !== undefined) {\n if (p.disable === null || (Array.isArray(p.disable) && p.disable.length === 0)) {\n delete t.disable;\n } else if (Array.isArray(p.disable) && p.disable.every((x) => typeof x === 'string')) {\n t.disable = p.disable;\n }\n }\n }\n }\n\n if (dPatch.params !== undefined) {\n const v = dPatch.params;\n if (v === null) {\n delete def.params;\n } else if (typeof v === 'object' && !Array.isArray(v) && v !== null) {\n def.params = v as Record<string, unknown>;\n }\n }\n }\n \n // Update channels — use `in` / null so `weixin: null` removes the block; avoid `if (ch.weixin)` missing null.\n const patchChannels = body.channels;\n if (patchChannels != null && typeof patchChannels === 'object' && !Array.isArray(patchChannels)) {\n if ('telegram' in patchChannels) {\n const tgRaw = patchChannels.telegram;\n if (tgRaw === null) {\n if (config.channels) delete config.channels.telegram;\n } else if (typeof tgRaw === 'object' && !Array.isArray(tgRaw)) {\n const bodyTg = tgRaw as Record<string, unknown>;\n if (!config.channels) {\n config.channels = {\n telegram: {\n enabled: false,\n allowFrom: [],\n groupAllowFrom: [],\n debug: false,\n accounts: {\n default: {\n accountId: 'default',\n enabled: true,\n botToken: '',\n allowFrom: [],\n dmPolicy: 'pairing' as const,\n groupPolicy: 'open' as const,\n replyToMode: 'off' as const,\n historyLimit: 50,\n textChunkLimit: 4000,\n streamMode: 'partial' as const,\n },\n },\n dmPolicy: 'pairing' as const,\n groupPolicy: 'open' as const,\n replyToMode: 'off' as const,\n historyLimit: 50,\n textChunkLimit: 4000,\n },\n };\n }\n if (!config.channels.telegram) config.channels.telegram = {} as any;\n const tg = config.channels.telegram as Record<string, unknown>;\n\n if (bodyTg.enabled !== undefined) {\n tg.enabled = bodyTg.enabled;\n }\n if (bodyTg.botToken !== undefined) {\n const accRaw = tg.accounts;\n const acc =\n accRaw && typeof accRaw === 'object' && !Array.isArray(accRaw)\n ? { ...(accRaw as Record<string, unknown>) }\n : {};\n const defRaw = acc.default;\n const def =\n defRaw && typeof defRaw === 'object' && !Array.isArray(defRaw)\n ? { ...(defRaw as Record<string, unknown>) }\n : {};\n acc.default = {\n ...def,\n accountId: 'default',\n botToken: bodyTg.botToken,\n };\n tg.accounts = acc;\n }\n if (bodyTg.allowFrom !== undefined) {\n tg.allowFrom = bodyTg.allowFrom;\n }\n if (bodyTg.apiRoot !== undefined) {\n tg.apiRoot = bodyTg.apiRoot;\n }\n if (bodyTg.debug !== undefined) {\n tg.debug = bodyTg.debug;\n }\n if (bodyTg.streamMode !== undefined) {\n tg.streamMode = bodyTg.streamMode;\n }\n if (bodyTg.groupAllowFrom !== undefined) {\n tg.groupAllowFrom = bodyTg.groupAllowFrom;\n }\n if (bodyTg.dmPolicy !== undefined) {\n tg.dmPolicy = bodyTg.dmPolicy;\n }\n if (bodyTg.groupPolicy !== undefined) {\n tg.groupPolicy = bodyTg.groupPolicy;\n }\n if (bodyTg.replyToMode !== undefined) {\n tg.replyToMode = bodyTg.replyToMode;\n }\n if (bodyTg.historyLimit !== undefined) {\n tg.historyLimit = bodyTg.historyLimit;\n }\n if (bodyTg.textChunkLimit !== undefined) {\n tg.textChunkLimit = bodyTg.textChunkLimit;\n }\n if (bodyTg.proxy !== undefined) {\n tg.proxy = bodyTg.proxy;\n }\n if (bodyTg.accounts !== undefined) {\n tg.accounts = bodyTg.accounts;\n }\n }\n }\n\n if ('weixin' in patchChannels) {\n const wxRaw = patchChannels.weixin;\n if (wxRaw === null) {\n if (config.channels) delete config.channels.weixin;\n } else if (typeof wxRaw === 'object' && !Array.isArray(wxRaw)) {\n const wx = wxRaw as Record<string, unknown>;\n if (!config.channels) config.channels = {} as any;\n if (!config.channels.weixin) {\n config.channels.weixin = {\n enabled: false,\n dmPolicy: 'pairing',\n allowFrom: [],\n debug: false,\n historyLimit: 50,\n textChunkLimit: 4000,\n };\n }\n const wxTarget = config.channels.weixin as Record<string, unknown>;\n if (wx.enabled !== undefined) wxTarget.enabled = wx.enabled;\n if (wx.dmPolicy !== undefined) wxTarget.dmPolicy = wx.dmPolicy;\n if (wx.allowFrom !== undefined) wxTarget.allowFrom = wx.allowFrom;\n if (wx.debug !== undefined) wxTarget.debug = wx.debug;\n if (wx.streamMode !== undefined) wxTarget.streamMode = wx.streamMode;\n if (wx.historyLimit !== undefined) wxTarget.historyLimit = wx.historyLimit;\n if (wx.textChunkLimit !== undefined) wxTarget.textChunkLimit = wx.textChunkLimit;\n if ('routeTag' in wx) {\n const rt = wx.routeTag;\n if (rt === null || rt === undefined || rt === '') {\n delete wxTarget.routeTag;\n } else {\n wxTarget.routeTag = rt as string | number;\n }\n }\n if (wx.accounts !== undefined) wxTarget.accounts = wx.accounts;\n }\n }\n\n if ('feishu' in patchChannels) {\n const fsRaw = patchChannels.feishu;\n if (fsRaw === null) {\n if (config.channels) delete config.channels.feishu;\n } else if (typeof fsRaw === 'object' && !Array.isArray(fsRaw)) {\n const fs = fsRaw as Record<string, unknown>;\n if (!config.channels) config.channels = {} as any;\n if (!config.channels.feishu) {\n config.channels.feishu = {\n enabled: false,\n appId: '',\n appSecret: '',\n domain: 'feishu',\n connectionMode: 'websocket',\n dmPolicy: 'pairing',\n groupPolicy: 'allowlist',\n allowFrom: [],\n groupAllowFrom: [],\n requireMention: true,\n historyLimit: 50,\n textChunkLimit: 4000,\n accounts: {},\n };\n }\n const fsTarget = config.channels.feishu as Record<string, unknown>;\n\n if (fs.enabled !== undefined) fsTarget.enabled = fs.enabled;\n if (fs.defaultAccount !== undefined) {\n const da = fs.defaultAccount;\n if (da === null || da === '') delete fsTarget.defaultAccount;\n else fsTarget.defaultAccount = String(da);\n }\n if (fs.appId !== undefined) fsTarget.appId = fs.appId;\n if (fs.appSecret !== undefined) fsTarget.appSecret = fs.appSecret;\n if (fs.domain !== undefined) fsTarget.domain = fs.domain;\n if (fs.connectionMode !== undefined) fsTarget.connectionMode = fs.connectionMode;\n if (fs.verificationToken !== undefined) {\n const v = fs.verificationToken;\n if (v === null || (typeof v === 'string' && !String(v).trim())) delete fsTarget.verificationToken;\n else fsTarget.verificationToken = v;\n }\n if (fs.encryptKey !== undefined) {\n const v = fs.encryptKey;\n if (v === null || (typeof v === 'string' && !String(v).trim())) delete fsTarget.encryptKey;\n else fsTarget.encryptKey = v;\n }\n if (fs.webhookHost !== undefined) {\n const v = fs.webhookHost;\n if (v === null || (typeof v === 'string' && !String(v).trim())) delete fsTarget.webhookHost;\n else fsTarget.webhookHost = v;\n }\n if (fs.webhookPort !== undefined) fsTarget.webhookPort = fs.webhookPort;\n if (fs.webhookPath !== undefined) {\n const v = fs.webhookPath;\n if (v === null || (typeof v === 'string' && !String(v).trim())) delete fsTarget.webhookPath;\n else fsTarget.webhookPath = v;\n }\n if (fs.dmPolicy !== undefined) fsTarget.dmPolicy = fs.dmPolicy;\n if (fs.groupPolicy !== undefined) fsTarget.groupPolicy = fs.groupPolicy;\n if (fs.allowFrom !== undefined) fsTarget.allowFrom = fs.allowFrom;\n if (fs.groupAllowFrom !== undefined) {\n const ga = fs.groupAllowFrom;\n if (ga === null || (Array.isArray(ga) && ga.length === 0)) delete fsTarget.groupAllowFrom;\n else fsTarget.groupAllowFrom = ga;\n }\n if (fs.requireMention !== undefined) fsTarget.requireMention = fs.requireMention;\n if (fs.historyLimit !== undefined) fsTarget.historyLimit = fs.historyLimit;\n if (fs.textChunkLimit !== undefined) fsTarget.textChunkLimit = fs.textChunkLimit;\n if (fs.renderMode !== undefined) fsTarget.renderMode = fs.renderMode;\n if (fs.streaming !== undefined) fsTarget.streaming = fs.streaming;\n if (fs.reactionNotifications !== undefined) {\n fsTarget.reactionNotifications = fs.reactionNotifications;\n }\n if (fs.tools !== undefined) fsTarget.tools = fs.tools;\n if (fs.actions !== undefined) fsTarget.actions = fs.actions;\n if (fs.accounts !== undefined) fsTarget.accounts = fs.accounts;\n }\n }\n\n if ('dingtalk' in patchChannels) {\n const dtRaw = patchChannels.dingtalk;\n if (dtRaw === null) {\n if (config.channels) delete config.channels.dingtalk;\n } else if (typeof dtRaw === 'object' && !Array.isArray(dtRaw)) {\n const dt = dtRaw as Record<string, unknown>;\n if (!config.channels) config.channels = {} as any;\n if (!config.channels.dingtalk) {\n config.channels.dingtalk = {\n enabled: false,\n clientId: '',\n clientSecret: '',\n dmPolicy: 'pairing',\n groupPolicy: 'open',\n allowFrom: [],\n groupAllowFrom: [],\n requireMention: false,\n historyLimit: 50,\n textChunkLimit: 4000,\n accounts: {},\n };\n }\n const dtTarget = config.channels.dingtalk as Record<string, unknown>;\n if (dt.enabled !== undefined) dtTarget.enabled = dt.enabled;\n if (dt.defaultAccount !== undefined) {\n const da = dt.defaultAccount;\n if (da === null || da === '') delete dtTarget.defaultAccount;\n else dtTarget.defaultAccount = String(da);\n }\n if (dt.clientId !== undefined) dtTarget.clientId = dt.clientId;\n if (dt.clientSecret !== undefined) dtTarget.clientSecret = dt.clientSecret;\n if (dt.dmPolicy !== undefined) dtTarget.dmPolicy = dt.dmPolicy;\n if (dt.groupPolicy !== undefined) dtTarget.groupPolicy = dt.groupPolicy;\n if (dt.allowFrom !== undefined) dtTarget.allowFrom = dt.allowFrom;\n if (dt.groupAllowFrom !== undefined) {\n const ga = dt.groupAllowFrom;\n if (ga === null || (Array.isArray(ga) && ga.length === 0)) delete dtTarget.groupAllowFrom;\n else dtTarget.groupAllowFrom = ga;\n }\n if (dt.requireMention !== undefined) dtTarget.requireMention = dt.requireMention;\n if (dt.debug !== undefined) dtTarget.debug = dt.debug;\n if (dt.endpoint !== undefined) dtTarget.endpoint = dt.endpoint;\n if (dt.historyLimit !== undefined) dtTarget.historyLimit = dt.historyLimit;\n if (dt.textChunkLimit !== undefined) dtTarget.textChunkLimit = dt.textChunkLimit;\n if (dt.accounts !== undefined) dtTarget.accounts = dt.accounts;\n }\n }\n }\n \n // Update gateway heartbeat (partial merge)\n if (body.gateway?.heartbeat !== undefined && typeof body.gateway.heartbeat === 'object') {\n if (!config.gateway) {\n config.gateway = {\n host: '0.0.0.0',\n port: 18790,\n heartbeat: { enabled: true, intervalMs: 1_800_000, includeSystemPromptSection: false },\n maxSseConnections: 100,\n corsOrigins: ['*'],\n };\n }\n if (!config.gateway.heartbeat) {\n config.gateway.heartbeat = { enabled: true, intervalMs: 1_800_000, includeSystemPromptSection: false };\n }\n const h = config.gateway.heartbeat;\n const p = body.gateway.heartbeat as Record<string, unknown>;\n if (p.enabled !== undefined) h.enabled = Boolean(p.enabled);\n if (p.intervalMs !== undefined && typeof p.intervalMs === 'number' && Number.isFinite(p.intervalMs)) {\n h.intervalMs = p.intervalMs;\n }\n if (p.includeSystemPromptSection !== undefined) {\n h.includeSystemPromptSection = Boolean(p.includeSystemPromptSection);\n }\n if (p.target !== undefined) {\n if (p.target === null || p.target === '') delete (h as { target?: string }).target;\n else (h as { target?: string }).target = String(p.target);\n }\n if (p.targetChatId !== undefined) {\n if (p.targetChatId === null || p.targetChatId === '') delete (h as { targetChatId?: string }).targetChatId;\n else (h as { targetChatId?: string }).targetChatId = String(p.targetChatId);\n }\n if (p.prompt !== undefined) {\n if (p.prompt === null || p.prompt === '') delete (h as { prompt?: string }).prompt;\n else (h as { prompt?: string }).prompt = String(p.prompt);\n }\n if (p.ackMaxChars !== undefined) {\n if (p.ackMaxChars === null || p.ackMaxChars === '') delete (h as { ackMaxChars?: number }).ackMaxChars;\n else if (typeof p.ackMaxChars === 'number' && Number.isFinite(p.ackMaxChars)) {\n (h as { ackMaxChars?: number }).ackMaxChars = p.ackMaxChars;\n }\n }\n if (p.isolatedSession !== undefined) {\n if (p.isolatedSession === null || p.isolatedSession === false) {\n delete (h as { isolatedSession?: boolean }).isolatedSession;\n } else {\n (h as { isolatedSession?: boolean }).isolatedSession = Boolean(p.isolatedSession);\n }\n }\n if (p.activeHours !== undefined) {\n if (p.activeHours === null) {\n delete (h as { activeHours?: unknown }).activeHours;\n } else if (typeof p.activeHours === 'object' && p.activeHours !== null) {\n const ah = p.activeHours as Record<string, unknown>;\n const start = typeof ah.start === 'string' ? ah.start : '';\n const end = typeof ah.end === 'string' ? ah.end : '';\n if (start && end) {\n (h as { activeHours?: { start: string; end: string; timezone?: string } }).activeHours = {\n start,\n end,\n ...(typeof ah.timezone === 'string' && ah.timezone.trim() ? { timezone: ah.timezone } : {}),\n };\n } else {\n delete (h as { activeHours?: unknown }).activeHours;\n }\n }\n }\n }\n if (body.gateway?.auth !== undefined) {\n if (!config.gateway) {\n config.gateway = {\n host: '0.0.0.0',\n port: 18790,\n heartbeat: { enabled: true, intervalMs: 1_800_000, includeSystemPromptSection: false },\n maxSseConnections: 100,\n corsOrigins: ['*'],\n };\n }\n if (!config.gateway.auth) config.gateway.auth = { mode: 'token' };\n const a = body.gateway.auth;\n if (a.mode !== undefined) {\n config.gateway.auth.mode = a.mode;\n }\n if (a.token !== undefined) {\n config.gateway.auth.token = a.token;\n }\n }\n\n if (body.update !== undefined && typeof body.update === 'object' && body.update !== null) {\n const p = body.update as Record<string, unknown>;\n if (p.channel === 'stable' || p.channel === 'beta' || p.channel === 'dev') {\n if (!config.update) {\n config.update = { checkOnStart: true, channel: p.channel };\n } else {\n config.update.channel = p.channel;\n }\n }\n }\n\n // Update providers config - save to credential system instead of config\n if (body.providers) {\n const resolver = new CredentialResolver();\n for (const [key, apiKey] of Object.entries(body.providers)) {\n if (\n apiKey !== undefined &&\n typeof apiKey === 'string' &&\n apiKey.trim() &&\n apiKey !== '***' &&\n apiKey !== '••••••••••••'\n ) {\n await resolver.saveApiKey(key, apiKey, { profileName: 'default' });\n }\n }\n }\n\n // Structured per-vendor provider config (cfg.providers.<id>) for capability\n // providers (image / audio / video). Distinct from `body.providers` above\n // which targets the LLM-side credential resolver.\n if (body.providersConfig && typeof body.providersConfig === 'object' && !Array.isArray(body.providersConfig)) {\n const cfgProviders = (config as { providers?: Record<string, Record<string, unknown>> }).providers ?? {};\n for (const [vendorId, raw] of Object.entries(body.providersConfig as Record<string, unknown>)) {\n if (!vendorId || typeof vendorId !== 'string') continue;\n if (raw === null) {\n delete cfgProviders[vendorId];\n continue;\n }\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) continue;\n const next = (cfgProviders[vendorId] ?? {}) as Record<string, unknown>;\n const patch = raw as Record<string, unknown>;\n for (const field of ['apiKey', 'baseUrl', 'region', 'imageBaseUrl'] as const) {\n if (patch[field] === null || patch[field] === '') {\n delete next[field];\n } else if (typeof patch[field] === 'string') {\n next[field] = (patch[field] as string).trim();\n }\n }\n if (patch.azure === null) {\n delete next.azure;\n } else if (patch.azure && typeof patch.azure === 'object' && !Array.isArray(patch.azure)) {\n next.azure = { ...(next.azure as Record<string, unknown> ?? {}), ...(patch.azure as Record<string, unknown>) };\n }\n if (patch.request === null) {\n delete next.request;\n } else if (patch.request && typeof patch.request === 'object' && !Array.isArray(patch.request)) {\n next.request = { ...(next.request as Record<string, unknown> ?? {}), ...(patch.request as Record<string, unknown>) };\n }\n cfgProviders[vendorId] = next;\n }\n (config as { providers?: Record<string, Record<string, unknown>> }).providers = cfgProviders;\n }\n\n // PATCH `stt` writes to tools.media.audio; PATCH `tts` writes to messages.tts.\n if (body.stt !== undefined) {\n config.tools = config.tools ?? {};\n config.tools.media = config.tools.media ?? {};\n (config.tools.media as Record<string, unknown>).audio = body.stt;\n }\n if (body.tts !== undefined) {\n config.messages = config.messages ?? {};\n (config.messages as Record<string, unknown>).tts = body.tts;\n }\n\n const toolsPatchErr = applyToolsWebPatch(config, body as Record<string, unknown>);\n if (toolsPatchErr) {\n return c.json({ ok: false, error: { message: toolsPatchErr } }, 400);\n }\n\n if (body.bindings !== undefined) {\n if (!Array.isArray(body.bindings)) {\n return c.json({ ok: false, error: { message: 'bindings must be an array' } }, 400);\n }\n const parsed = BindingsConfigSchema.safeParse(body.bindings);\n if (!parsed.success) {\n return c.json(\n { ok: false, error: { message: parsed.error.issues.map((i) => i.message).join('; ') } },\n 400,\n );\n }\n config.bindings = parsed.data;\n }\n\n // Save config\n const result = await service.saveConfig(config);\n if (!result.saved) {\n return c.json({ ok: false, error: result.error }, 500);\n }\n\n if (body.gateway?.heartbeat !== undefined && typeof body.gateway.heartbeat === 'object') {\n service.reloadHeartbeatFromCurrentConfig();\n }\n\n const safeConfig = await buildSafeWebConfigPayload(service);\n return c.json({ ok: true, payload: { config: safeConfig } });\n });\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"config.js","names":[],"sources":["../../../../../src/gateway/hono/routes/config.ts"],"sourcesContent":["import type { Hono } from 'hono';\n\nimport { type Config, BindingsConfigSchema } from '../../../config/schema.js';\nimport { CredentialResolver } from '../../../auth/credentials.js';\nimport { applyToolsWebPatch } from '../../config-tools-web.js';\nimport { buildSafeWebConfigPayload } from '../lib/config-payload.js';\nimport {\n normalizePatchAgentImageGenerationModel,\n normalizePatchAgentModel,\n} from '../lib/agent-model.js';\nimport type { AuthenticatedRouteDeps } from './deps.js';\n\nexport function registerConfigRoutes(authenticated: Hono, deps: AuthenticatedRouteDeps): void {\n const { service, strictRateLimitMiddleware } = deps;\n\n authenticated.post('/api/config/reload', strictRateLimitMiddleware, async (c) => {\n const result = await service.reloadConfig();\n return c.json({ ok: true, payload: result });\n });\n\n authenticated.post('/api/heartbeat/trigger', strictRateLimitMiddleware, async (c) => {\n let reason = 'manual';\n try {\n const body = await c.req.json();\n if (body && typeof body === 'object' && typeof (body as { reason?: unknown }).reason === 'string') {\n const r = (body as { reason: string }).reason.trim();\n if (r) reason = r.slice(0, 120);\n }\n } catch {\n /* empty or invalid body */\n }\n service.requestHeartbeatNow({ reason });\n return c.json({ ok: true, payload: { scheduled: true } });\n });\n\n authenticated.get('/api/config', async (c) => {\n const safeConfig = await buildSafeWebConfigPayload(service);\n return c.json({ ok: true, payload: { config: safeConfig } });\n });\n\n authenticated.patch('/api/config', strictRateLimitMiddleware, async (c) => {\n const body = await c.req.json();\n \n // Merge updates into current config\n const config: Config = service.currentConfig as Config;\n \n // Update agent defaults\n if (body.agents?.defaults) {\n if (!config.agents) config.agents = { defaults: { workspace: '~/.xopc/workspace', model: 'anthropic/claude-sonnet-4-5', maxTokens: 8192, temperature: 0.7, maxToolIterations: 20, maxRequestsPerTurn: 50, maxToolFailuresPerTurn: 3, thinkingDefault: 'medium', reasoningDefault: 'stream', verboseDefault: 'full' } };\n if (!config.agents.defaults) config.agents.defaults = {} as any;\n \n if (body.agents.defaults.model !== undefined) {\n config.agents.defaults.model = normalizePatchAgentModel(body.agents.defaults.model) as Config['agents']['defaults']['model'];\n }\n if (body.agents.defaults.maxTokens !== undefined) {\n config.agents.defaults.maxTokens = body.agents.defaults.maxTokens;\n }\n if (body.agents.defaults.temperature !== undefined) {\n config.agents.defaults.temperature = body.agents.defaults.temperature;\n }\n if (body.agents.defaults.maxToolIterations !== undefined) {\n config.agents.defaults.maxToolIterations = body.agents.defaults.maxToolIterations;\n }\n if (body.agents.defaults.workspace !== undefined) {\n config.agents.defaults.workspace = body.agents.defaults.workspace;\n }\n if (body.agents.defaults.thinkingDefault !== undefined) {\n config.agents.defaults.thinkingDefault = body.agents.defaults.thinkingDefault;\n }\n if (body.agents.defaults.reasoningDefault !== undefined) {\n config.agents.defaults.reasoningDefault = body.agents.defaults.reasoningDefault;\n }\n if (body.agents.defaults.verboseDefault !== undefined) {\n config.agents.defaults.verboseDefault = body.agents.defaults.verboseDefault;\n }\n if (body.agents.defaults.imageModel !== undefined) {\n const v = body.agents.defaults.imageModel;\n if (v === '' || v === null) {\n delete (config.agents.defaults as Record<string, unknown>).imageModel;\n } else {\n config.agents.defaults.imageModel = normalizePatchAgentModel(v) as Config['agents']['defaults']['imageModel'];\n }\n }\n if (body.agents.defaults.imageGenerationModel !== undefined) {\n const v = body.agents.defaults.imageGenerationModel;\n if (v === '' || v === null) {\n delete (config.agents.defaults as Record<string, unknown>).imageGenerationModel;\n } else {\n const normalized = normalizePatchAgentImageGenerationModel(v);\n if (normalized === undefined) {\n delete (config.agents.defaults as Record<string, unknown>).imageGenerationModel;\n } else {\n config.agents.defaults.imageGenerationModel =\n normalized as Config['agents']['defaults']['imageGenerationModel'];\n }\n }\n }\n if (body.agents.defaults.mediaMaxMb !== undefined) {\n const v = body.agents.defaults.mediaMaxMb;\n if (v === null) {\n delete (config.agents.defaults as Record<string, unknown>).mediaMaxMb;\n } else {\n const n = typeof v === 'number' ? v : Number(v);\n if (!Number.isNaN(n) && n > 0) {\n config.agents.defaults.mediaMaxMb = n;\n }\n }\n }\n if (body.agents.defaults.browser !== undefined) {\n const b = body.agents.defaults.browser;\n if (b === null) {\n delete (config.agents.defaults as Record<string, unknown>).browser;\n } else if (typeof b === 'object' && !Array.isArray(b)) {\n const br = b as Record<string, unknown>;\n if (!config.agents.defaults.browser) {\n config.agents.defaults.browser = { enabled: false, headless: true };\n }\n const target = config.agents.defaults.browser;\n if (br.enabled !== undefined) {\n target.enabled = Boolean(br.enabled);\n }\n if (br.headless !== undefined) {\n target.headless = Boolean(br.headless);\n }\n }\n }\n\n const dPatch = body.agents.defaults as Record<string, unknown>;\n const def = config.agents.defaults as Record<string, unknown>;\n\n if (dPatch.maxTaskDurationMs !== undefined) {\n const v = dPatch.maxTaskDurationMs;\n if (v === null) {\n delete def.maxTaskDurationMs;\n } else if (typeof v === 'number' && Number.isFinite(v)) {\n const ms = Math.floor(v);\n if (ms >= 60_000 && ms <= 14_400_000) {\n def.maxTaskDurationMs = ms;\n }\n }\n }\n if (dPatch.maxRequestsPerTurn !== undefined) {\n const v = dPatch.maxRequestsPerTurn;\n if (v === null) {\n delete def.maxRequestsPerTurn;\n } else if (typeof v === 'number' && Number.isFinite(v)) {\n const n = Math.floor(v);\n if (n >= 10 && n <= 200) {\n def.maxRequestsPerTurn = n;\n }\n }\n }\n if (dPatch.maxToolFailuresPerTurn !== undefined) {\n const v = dPatch.maxToolFailuresPerTurn;\n if (v === null) {\n delete def.maxToolFailuresPerTurn;\n } else if (typeof v === 'number' && Number.isFinite(v)) {\n const n = Math.floor(v);\n if (n >= 1 && n <= 20) {\n def.maxToolFailuresPerTurn = n;\n }\n }\n }\n\n if (dPatch.compaction !== undefined) {\n const c = dPatch.compaction;\n if (c === null) {\n delete def.compaction;\n } else if (typeof c === 'object' && !Array.isArray(c)) {\n const p = c as Record<string, unknown>;\n if (!def.compaction || typeof def.compaction !== 'object') {\n def.compaction = {};\n }\n const t = def.compaction as Record<string, unknown>;\n if (p.enabled !== undefined) t.enabled = Boolean(p.enabled);\n if (p.mode === 'default' || p.mode === 'safeguard') t.mode = p.mode;\n if (typeof p.reserveTokens === 'number' && Number.isFinite(p.reserveTokens)) {\n t.reserveTokens = Math.floor(p.reserveTokens);\n }\n if (typeof p.triggerThreshold === 'number' && Number.isFinite(p.triggerThreshold)) {\n const x = p.triggerThreshold;\n if (x >= 0.5 && x <= 0.95) t.triggerThreshold = x;\n }\n if (typeof p.minMessagesBeforeCompact === 'number' && Number.isFinite(p.minMessagesBeforeCompact)) {\n t.minMessagesBeforeCompact = Math.floor(p.minMessagesBeforeCompact);\n }\n if (typeof p.keepRecentMessages === 'number' && Number.isFinite(p.keepRecentMessages)) {\n t.keepRecentMessages = Math.floor(p.keepRecentMessages);\n }\n if (typeof p.evictionWindow === 'number' && Number.isFinite(p.evictionWindow)) {\n const x = p.evictionWindow;\n if (x >= 0.1 && x <= 0.5) t.evictionWindow = x;\n }\n if (typeof p.retentionWindow === 'number' && Number.isFinite(p.retentionWindow)) {\n const n = Math.floor(p.retentionWindow);\n if (n >= 3 && n <= 20) t.retentionWindow = n;\n }\n }\n }\n\n if (dPatch.pruning !== undefined) {\n const c = dPatch.pruning;\n if (c === null) {\n delete def.pruning;\n } else if (typeof c === 'object' && !Array.isArray(c)) {\n const p = c as Record<string, unknown>;\n if (!def.pruning || typeof def.pruning !== 'object') {\n def.pruning = {};\n }\n const t = def.pruning as Record<string, unknown>;\n if (p.enabled !== undefined) t.enabled = Boolean(p.enabled);\n if (typeof p.maxToolResultChars === 'number' && Number.isFinite(p.maxToolResultChars)) {\n t.maxToolResultChars = Math.floor(p.maxToolResultChars);\n }\n if (typeof p.headKeepRatio === 'number' && Number.isFinite(p.headKeepRatio)) {\n t.headKeepRatio = p.headKeepRatio;\n }\n if (typeof p.tailKeepRatio === 'number' && Number.isFinite(p.tailKeepRatio)) {\n t.tailKeepRatio = p.tailKeepRatio;\n }\n }\n }\n\n if (dPatch.memory !== undefined) {\n const c = dPatch.memory;\n if (c === null) {\n delete def.memory;\n } else if (typeof c === 'object' && !Array.isArray(c)) {\n const p = c as Record<string, unknown>;\n if (!def.memory || typeof def.memory !== 'object') {\n def.memory = {};\n }\n const t = def.memory as Record<string, unknown>;\n if (p.enabled !== undefined) {\n if (p.enabled === null) delete t.enabled;\n else t.enabled = Boolean(p.enabled);\n }\n if (p.useEnhancedSystem !== undefined) {\n if (p.useEnhancedSystem === null) delete t.useEnhancedSystem;\n else t.useEnhancedSystem = Boolean(p.useEnhancedSystem);\n }\n if (p.userProfileEnabled !== undefined) {\n if (p.userProfileEnabled === null) delete t.userProfileEnabled;\n else t.userProfileEnabled = Boolean(p.userProfileEnabled);\n }\n if (p.memoryCharLimit !== undefined) {\n if (p.memoryCharLimit === null) delete t.memoryCharLimit;\n else if (typeof p.memoryCharLimit === 'number' && p.memoryCharLimit > 0) {\n t.memoryCharLimit = Math.floor(p.memoryCharLimit);\n }\n }\n if (p.userCharLimit !== undefined) {\n if (p.userCharLimit === null) delete t.userCharLimit;\n else if (typeof p.userCharLimit === 'number' && p.userCharLimit > 0) {\n t.userCharLimit = Math.floor(p.userCharLimit);\n }\n }\n if (p.provider === 'none' || p.provider === 'stub') {\n t.provider = p.provider;\n } else if (p.provider === null) {\n delete t.provider;\n }\n if (p.injectionFrequency === 'every-turn' || p.injectionFrequency === 'first-turn') {\n t.injectionFrequency = p.injectionFrequency;\n } else if (p.injectionFrequency === null) {\n delete t.injectionFrequency;\n }\n if (p.contextCadence !== undefined) {\n if (p.contextCadence === null) delete t.contextCadence;\n else if (typeof p.contextCadence === 'number' && p.contextCadence >= 1) {\n t.contextCadence = Math.floor(p.contextCadence);\n }\n }\n if (p.dialecticCadence !== undefined) {\n if (p.dialecticCadence === null) delete t.dialecticCadence;\n else if (typeof p.dialecticCadence === 'number' && p.dialecticCadence >= 1) {\n t.dialecticCadence = Math.floor(p.dialecticCadence);\n }\n }\n\n // Dreaming (schemaless patch): agents.defaults.memory.dreaming\n if (p.dreaming !== undefined) {\n const d0 = p.dreaming;\n if (d0 === null) {\n delete (t as { dreaming?: unknown }).dreaming;\n } else if (typeof d0 === 'object' && d0 !== null && !Array.isArray(d0)) {\n if (!('dreaming' in t) || typeof (t as { dreaming?: unknown }).dreaming !== 'object') {\n (t as { dreaming?: Record<string, unknown> }).dreaming = {};\n }\n const dt = (t as { dreaming: Record<string, unknown> }).dreaming;\n const dp = d0 as Record<string, unknown>;\n\n if (dp.enabled !== undefined) {\n if (dp.enabled === null) delete dt.enabled;\n else dt.enabled = Boolean(dp.enabled);\n }\n if (dp.frequency !== undefined) {\n const v = dp.frequency;\n if (v === null || v === '') delete dt.frequency;\n else if (typeof v === 'string') dt.frequency = v;\n }\n if (dp.timezone !== undefined) {\n const v = dp.timezone;\n if (v === null || v === '') delete dt.timezone;\n else if (typeof v === 'string') dt.timezone = v;\n }\n\n // Accept either `phases.deep` or `deep`.\n if (dp.phases !== undefined || dp.deep !== undefined) {\n if (!('phases' in dt) || typeof (dt as { phases?: unknown }).phases !== 'object' || (dt as { phases?: unknown }).phases === null) {\n dt.phases = {};\n }\n const phases = (dt as { phases: Record<string, unknown> }).phases;\n if (!('deep' in phases) || typeof phases.deep !== 'object' || phases.deep === null) {\n phases.deep = {};\n }\n const deep = phases.deep as Record<string, unknown>;\n\n const deepPatchRaw =\n typeof dp.phases === 'object' && dp.phases !== null && !Array.isArray(dp.phases)\n ? (dp.phases as Record<string, unknown>).deep\n : dp.deep;\n const deepPatch =\n typeof deepPatchRaw === 'object' && deepPatchRaw !== null && !Array.isArray(deepPatchRaw)\n ? (deepPatchRaw as Record<string, unknown>)\n : null;\n\n if (deepPatch) {\n if (deepPatch.enabled !== undefined) {\n if (deepPatch.enabled === null) delete deep.enabled;\n else deep.enabled = Boolean(deepPatch.enabled);\n }\n if (deepPatch.minScore !== undefined) {\n const v = deepPatch.minScore;\n if (v === null) delete deep.minScore;\n else if (typeof v === 'number' && Number.isFinite(v)) deep.minScore = v;\n }\n if (deepPatch.minRecallCount !== undefined) {\n const v = deepPatch.minRecallCount;\n if (v === null) delete deep.minRecallCount;\n else if (typeof v === 'number' && Number.isFinite(v)) deep.minRecallCount = Math.floor(v);\n }\n if (deepPatch.limit !== undefined) {\n const v = deepPatch.limit;\n if (v === null) delete deep.limit;\n else if (typeof v === 'number' && Number.isFinite(v)) deep.limit = Math.floor(v);\n }\n }\n }\n }\n }\n }\n }\n\n if (dPatch.sessionSearch !== undefined) {\n const c = dPatch.sessionSearch;\n if (c === null) {\n delete def.sessionSearch;\n } else if (typeof c === 'object' && !Array.isArray(c)) {\n const p = c as Record<string, unknown>;\n if (!def.sessionSearch || typeof def.sessionSearch !== 'object') {\n def.sessionSearch = {};\n }\n const t = def.sessionSearch as Record<string, unknown>;\n if (p.summaryModel !== undefined) {\n if (p.summaryModel === null || p.summaryModel === '') {\n delete t.summaryModel;\n } else if (typeof p.summaryModel === 'string') {\n t.summaryModel = p.summaryModel;\n }\n }\n }\n }\n\n if (dPatch.backgroundReview !== undefined) {\n const c = dPatch.backgroundReview;\n if (c === null) {\n delete def.backgroundReview;\n } else if (typeof c === 'object' && !Array.isArray(c)) {\n const p = c as Record<string, unknown>;\n if (!def.backgroundReview || typeof def.backgroundReview !== 'object') {\n def.backgroundReview = {};\n }\n const t = def.backgroundReview as Record<string, unknown>;\n if (p.enabled !== undefined) {\n if (p.enabled === null) delete t.enabled;\n else t.enabled = Boolean(p.enabled);\n }\n if (p.memoryNudgeInterval !== undefined) {\n if (p.memoryNudgeInterval === null) delete t.memoryNudgeInterval;\n else if (typeof p.memoryNudgeInterval === 'number' && p.memoryNudgeInterval >= 0) {\n t.memoryNudgeInterval = Math.floor(p.memoryNudgeInterval);\n }\n }\n if (p.skillNudgeInterval !== undefined) {\n if (p.skillNudgeInterval === null) delete t.skillNudgeInterval;\n else if (typeof p.skillNudgeInterval === 'number' && p.skillNudgeInterval >= 0) {\n t.skillNudgeInterval = Math.floor(p.skillNudgeInterval);\n }\n }\n if (p.maxToolRounds !== undefined) {\n if (p.maxToolRounds === null) delete t.maxToolRounds;\n else if (typeof p.maxToolRounds === 'number' && p.maxToolRounds >= 1 && p.maxToolRounds <= 32) {\n t.maxToolRounds = Math.floor(p.maxToolRounds);\n }\n }\n if (p.maxHistoryMessages !== undefined) {\n if (p.maxHistoryMessages === null) delete t.maxHistoryMessages;\n else if (typeof p.maxHistoryMessages === 'number' && p.maxHistoryMessages >= 10 && p.maxHistoryMessages <= 200) {\n t.maxHistoryMessages = Math.floor(p.maxHistoryMessages);\n }\n }\n if (p.maxDurationMs !== undefined) {\n if (p.maxDurationMs === null) delete t.maxDurationMs;\n else if (typeof p.maxDurationMs === 'number' && p.maxDurationMs >= 30_000 && p.maxDurationMs <= 600_000) {\n t.maxDurationMs = Math.floor(p.maxDurationMs);\n }\n }\n }\n }\n\n if (dPatch.webExtract !== undefined) {\n const c = dPatch.webExtract;\n if (c === null) {\n delete def.webExtract;\n } else if (typeof c === 'object' && !Array.isArray(c)) {\n const p = c as Record<string, unknown>;\n if (!def.webExtract || typeof def.webExtract !== 'object') {\n def.webExtract = {};\n }\n const t = def.webExtract as Record<string, unknown>;\n if (p.model !== undefined) {\n if (p.model === null || p.model === '') {\n delete t.model;\n } else if (typeof p.model === 'string') {\n t.model = p.model;\n }\n }\n if (p.maxLength !== undefined) {\n if (p.maxLength === null) delete t.maxLength;\n else if (typeof p.maxLength === 'number' && p.maxLength > 0) {\n t.maxLength = p.maxLength;\n }\n }\n }\n }\n\n if (dPatch.delegate !== undefined) {\n const c = dPatch.delegate;\n if (c === null) {\n delete def.delegate;\n } else if (typeof c === 'object' && !Array.isArray(c)) {\n const p = c as Record<string, unknown>;\n if (!def.delegate || typeof def.delegate !== 'object') {\n def.delegate = {};\n }\n const t = def.delegate as Record<string, unknown>;\n if (p.enabled !== undefined) {\n if (p.enabled === null) delete t.enabled;\n else t.enabled = Boolean(p.enabled);\n }\n }\n }\n\n if (dPatch.executeCode !== undefined) {\n const c = dPatch.executeCode;\n if (c === null) {\n delete def.executeCode;\n } else if (typeof c === 'object' && !Array.isArray(c)) {\n const p = c as Record<string, unknown>;\n if (!def.executeCode || typeof def.executeCode !== 'object') {\n def.executeCode = {};\n }\n const t = def.executeCode as Record<string, unknown>;\n if (p.enabled !== undefined) {\n if (p.enabled === null) delete t.enabled;\n else t.enabled = Boolean(p.enabled);\n }\n }\n }\n\n if (dPatch.systemPromptOverride !== undefined) {\n const v = dPatch.systemPromptOverride;\n if (v === null || v === '') {\n delete def.systemPromptOverride;\n } else if (typeof v === 'string') {\n def.systemPromptOverride = v;\n }\n }\n\n if (dPatch.skills !== undefined) {\n const v = dPatch.skills;\n if (v === null) {\n delete def.skills;\n } else if (Array.isArray(v) && v.every((x) => typeof x === 'string')) {\n def.skills = v;\n }\n }\n\n if (dPatch.tools !== undefined) {\n const t0 = dPatch.tools;\n if (t0 === null) {\n delete def.tools;\n } else if (typeof t0 === 'object' && !Array.isArray(t0)) {\n const p = t0 as { disable?: unknown };\n if (!def.tools || typeof def.tools !== 'object') {\n def.tools = {};\n }\n const t = def.tools as { disable?: string[] };\n if (p.disable !== undefined) {\n if (p.disable === null || (Array.isArray(p.disable) && p.disable.length === 0)) {\n delete t.disable;\n } else if (Array.isArray(p.disable) && p.disable.every((x) => typeof x === 'string')) {\n t.disable = p.disable;\n }\n }\n }\n }\n\n if (dPatch.params !== undefined) {\n const v = dPatch.params;\n if (v === null) {\n delete def.params;\n } else if (typeof v === 'object' && !Array.isArray(v) && v !== null) {\n def.params = v as Record<string, unknown>;\n }\n }\n }\n \n // Update channels — use `in` / null so `weixin: null` removes the block; avoid `if (ch.weixin)` missing null.\n const patchChannels = body.channels;\n if (patchChannels != null && typeof patchChannels === 'object' && !Array.isArray(patchChannels)) {\n if ('telegram' in patchChannels) {\n const tgRaw = patchChannels.telegram;\n if (tgRaw === null) {\n if (config.channels) delete config.channels.telegram;\n } else if (typeof tgRaw === 'object' && !Array.isArray(tgRaw)) {\n const bodyTg = tgRaw as Record<string, unknown>;\n if (!config.channels) {\n config.channels = {\n telegram: {\n enabled: false,\n allowFrom: [],\n groupAllowFrom: [],\n debug: false,\n accounts: {\n default: {\n accountId: 'default',\n enabled: true,\n botToken: '',\n allowFrom: [],\n dmPolicy: 'pairing' as const,\n groupPolicy: 'open' as const,\n replyToMode: 'off' as const,\n historyLimit: 50,\n textChunkLimit: 4000,\n streamMode: 'partial' as const,\n },\n },\n dmPolicy: 'pairing' as const,\n groupPolicy: 'open' as const,\n replyToMode: 'off' as const,\n historyLimit: 50,\n textChunkLimit: 4000,\n },\n };\n }\n if (!config.channels.telegram) config.channels.telegram = {} as any;\n const tg = config.channels.telegram as Record<string, unknown>;\n\n if (bodyTg.enabled !== undefined) {\n tg.enabled = bodyTg.enabled;\n }\n if (bodyTg.botToken !== undefined) {\n const accRaw = tg.accounts;\n const acc =\n accRaw && typeof accRaw === 'object' && !Array.isArray(accRaw)\n ? { ...(accRaw as Record<string, unknown>) }\n : {};\n const defRaw = acc.default;\n const def =\n defRaw && typeof defRaw === 'object' && !Array.isArray(defRaw)\n ? { ...(defRaw as Record<string, unknown>) }\n : {};\n acc.default = {\n ...def,\n accountId: 'default',\n botToken: bodyTg.botToken,\n };\n tg.accounts = acc;\n }\n if (bodyTg.allowFrom !== undefined) {\n tg.allowFrom = bodyTg.allowFrom;\n }\n if (bodyTg.apiRoot !== undefined) {\n tg.apiRoot = bodyTg.apiRoot;\n }\n if (bodyTg.debug !== undefined) {\n tg.debug = bodyTg.debug;\n }\n if (bodyTg.streamMode !== undefined) {\n tg.streamMode = bodyTg.streamMode;\n }\n if (bodyTg.groupAllowFrom !== undefined) {\n tg.groupAllowFrom = bodyTg.groupAllowFrom;\n }\n if (bodyTg.dmPolicy !== undefined) {\n tg.dmPolicy = bodyTg.dmPolicy;\n }\n if (bodyTg.groupPolicy !== undefined) {\n tg.groupPolicy = bodyTg.groupPolicy;\n }\n if (bodyTg.replyToMode !== undefined) {\n tg.replyToMode = bodyTg.replyToMode;\n }\n if (bodyTg.historyLimit !== undefined) {\n tg.historyLimit = bodyTg.historyLimit;\n }\n if (bodyTg.textChunkLimit !== undefined) {\n tg.textChunkLimit = bodyTg.textChunkLimit;\n }\n if (bodyTg.proxy !== undefined) {\n tg.proxy = bodyTg.proxy;\n }\n if (bodyTg.accounts !== undefined) {\n tg.accounts = bodyTg.accounts;\n }\n }\n }\n\n if ('weixin' in patchChannels) {\n const wxRaw = patchChannels.weixin;\n if (wxRaw === null) {\n if (config.channels) delete config.channels.weixin;\n } else if (typeof wxRaw === 'object' && !Array.isArray(wxRaw)) {\n const wx = wxRaw as Record<string, unknown>;\n if (!config.channels) config.channels = {} as any;\n if (!config.channels.weixin) {\n config.channels.weixin = {\n enabled: false,\n dmPolicy: 'open',\n allowFrom: [],\n debug: false,\n historyLimit: 50,\n textChunkLimit: 4000,\n };\n }\n const wxTarget = config.channels.weixin as Record<string, unknown>;\n if (wx.enabled !== undefined) wxTarget.enabled = wx.enabled;\n if (wx.dmPolicy !== undefined) wxTarget.dmPolicy = wx.dmPolicy;\n if (wx.allowFrom !== undefined) wxTarget.allowFrom = wx.allowFrom;\n if (wx.debug !== undefined) wxTarget.debug = wx.debug;\n if (wx.streamMode !== undefined) wxTarget.streamMode = wx.streamMode;\n if (wx.historyLimit !== undefined) wxTarget.historyLimit = wx.historyLimit;\n if (wx.textChunkLimit !== undefined) wxTarget.textChunkLimit = wx.textChunkLimit;\n if ('routeTag' in wx) {\n const rt = wx.routeTag;\n if (rt === null || rt === undefined || rt === '') {\n delete wxTarget.routeTag;\n } else {\n wxTarget.routeTag = rt as string | number;\n }\n }\n if (wx.accounts !== undefined) wxTarget.accounts = wx.accounts;\n }\n }\n\n if ('feishu' in patchChannels) {\n const fsRaw = patchChannels.feishu;\n if (fsRaw === null) {\n if (config.channels) delete config.channels.feishu;\n } else if (typeof fsRaw === 'object' && !Array.isArray(fsRaw)) {\n const fs = fsRaw as Record<string, unknown>;\n if (!config.channels) config.channels = {} as any;\n if (!config.channels.feishu) {\n config.channels.feishu = {\n enabled: false,\n appId: '',\n appSecret: '',\n domain: 'feishu',\n connectionMode: 'websocket',\n dmPolicy: 'open',\n groupPolicy: 'allowlist',\n allowFrom: [],\n groupAllowFrom: [],\n requireMention: true,\n historyLimit: 50,\n textChunkLimit: 4000,\n accounts: {},\n };\n }\n const fsTarget = config.channels.feishu as Record<string, unknown>;\n\n if (fs.enabled !== undefined) fsTarget.enabled = fs.enabled;\n if (fs.defaultAccount !== undefined) {\n const da = fs.defaultAccount;\n if (da === null || da === '') delete fsTarget.defaultAccount;\n else fsTarget.defaultAccount = String(da);\n }\n if (fs.appId !== undefined) fsTarget.appId = fs.appId;\n if (fs.appSecret !== undefined) fsTarget.appSecret = fs.appSecret;\n if (fs.domain !== undefined) fsTarget.domain = fs.domain;\n if (fs.connectionMode !== undefined) fsTarget.connectionMode = fs.connectionMode;\n if (fs.verificationToken !== undefined) {\n const v = fs.verificationToken;\n if (v === null || (typeof v === 'string' && !String(v).trim())) delete fsTarget.verificationToken;\n else fsTarget.verificationToken = v;\n }\n if (fs.encryptKey !== undefined) {\n const v = fs.encryptKey;\n if (v === null || (typeof v === 'string' && !String(v).trim())) delete fsTarget.encryptKey;\n else fsTarget.encryptKey = v;\n }\n if (fs.webhookHost !== undefined) {\n const v = fs.webhookHost;\n if (v === null || (typeof v === 'string' && !String(v).trim())) delete fsTarget.webhookHost;\n else fsTarget.webhookHost = v;\n }\n if (fs.webhookPort !== undefined) fsTarget.webhookPort = fs.webhookPort;\n if (fs.webhookPath !== undefined) {\n const v = fs.webhookPath;\n if (v === null || (typeof v === 'string' && !String(v).trim())) delete fsTarget.webhookPath;\n else fsTarget.webhookPath = v;\n }\n if (fs.dmPolicy !== undefined) fsTarget.dmPolicy = fs.dmPolicy;\n if (fs.groupPolicy !== undefined) fsTarget.groupPolicy = fs.groupPolicy;\n if (fs.allowFrom !== undefined) fsTarget.allowFrom = fs.allowFrom;\n if (fs.groupAllowFrom !== undefined) {\n const ga = fs.groupAllowFrom;\n if (ga === null || (Array.isArray(ga) && ga.length === 0)) delete fsTarget.groupAllowFrom;\n else fsTarget.groupAllowFrom = ga;\n }\n if (fs.requireMention !== undefined) fsTarget.requireMention = fs.requireMention;\n if (fs.historyLimit !== undefined) fsTarget.historyLimit = fs.historyLimit;\n if (fs.textChunkLimit !== undefined) fsTarget.textChunkLimit = fs.textChunkLimit;\n if (fs.renderMode !== undefined) fsTarget.renderMode = fs.renderMode;\n if (fs.streaming !== undefined) fsTarget.streaming = fs.streaming;\n if (fs.reactionNotifications !== undefined) {\n fsTarget.reactionNotifications = fs.reactionNotifications;\n }\n if (fs.tools !== undefined) fsTarget.tools = fs.tools;\n if (fs.actions !== undefined) fsTarget.actions = fs.actions;\n if (fs.accounts !== undefined) fsTarget.accounts = fs.accounts;\n }\n }\n\n if ('dingtalk' in patchChannels) {\n const dtRaw = patchChannels.dingtalk;\n if (dtRaw === null) {\n if (config.channels) delete config.channels.dingtalk;\n } else if (typeof dtRaw === 'object' && !Array.isArray(dtRaw)) {\n const dt = dtRaw as Record<string, unknown>;\n if (!config.channels) config.channels = {} as any;\n if (!config.channels.dingtalk) {\n config.channels.dingtalk = {\n enabled: false,\n clientId: '',\n clientSecret: '',\n dmPolicy: 'open',\n groupPolicy: 'open',\n allowFrom: [],\n groupAllowFrom: [],\n requireMention: false,\n historyLimit: 50,\n textChunkLimit: 4000,\n accounts: {},\n };\n }\n const dtTarget = config.channels.dingtalk as Record<string, unknown>;\n if (dt.enabled !== undefined) dtTarget.enabled = dt.enabled;\n if (dt.defaultAccount !== undefined) {\n const da = dt.defaultAccount;\n if (da === null || da === '') delete dtTarget.defaultAccount;\n else dtTarget.defaultAccount = String(da);\n }\n if (dt.clientId !== undefined) dtTarget.clientId = dt.clientId;\n if (dt.clientSecret !== undefined) dtTarget.clientSecret = dt.clientSecret;\n if (dt.dmPolicy !== undefined) dtTarget.dmPolicy = dt.dmPolicy;\n if (dt.groupPolicy !== undefined) dtTarget.groupPolicy = dt.groupPolicy;\n if (dt.allowFrom !== undefined) dtTarget.allowFrom = dt.allowFrom;\n if (dt.groupAllowFrom !== undefined) {\n const ga = dt.groupAllowFrom;\n if (ga === null || (Array.isArray(ga) && ga.length === 0)) delete dtTarget.groupAllowFrom;\n else dtTarget.groupAllowFrom = ga;\n }\n if (dt.requireMention !== undefined) dtTarget.requireMention = dt.requireMention;\n if (dt.debug !== undefined) dtTarget.debug = dt.debug;\n if (dt.endpoint !== undefined) dtTarget.endpoint = dt.endpoint;\n if (dt.historyLimit !== undefined) dtTarget.historyLimit = dt.historyLimit;\n if (dt.textChunkLimit !== undefined) dtTarget.textChunkLimit = dt.textChunkLimit;\n if (dt.accounts !== undefined) dtTarget.accounts = dt.accounts;\n }\n }\n }\n \n // Update gateway heartbeat (partial merge)\n if (body.gateway?.heartbeat !== undefined && typeof body.gateway.heartbeat === 'object') {\n if (!config.gateway) {\n config.gateway = {\n host: '0.0.0.0',\n port: 18790,\n heartbeat: { enabled: true, intervalMs: 1_800_000, includeSystemPromptSection: false },\n maxSseConnections: 100,\n corsOrigins: ['*'],\n };\n }\n if (!config.gateway.heartbeat) {\n config.gateway.heartbeat = { enabled: true, intervalMs: 1_800_000, includeSystemPromptSection: false };\n }\n const h = config.gateway.heartbeat;\n const p = body.gateway.heartbeat as Record<string, unknown>;\n if (p.enabled !== undefined) h.enabled = Boolean(p.enabled);\n if (p.intervalMs !== undefined && typeof p.intervalMs === 'number' && Number.isFinite(p.intervalMs)) {\n h.intervalMs = p.intervalMs;\n }\n if (p.includeSystemPromptSection !== undefined) {\n h.includeSystemPromptSection = Boolean(p.includeSystemPromptSection);\n }\n if (p.target !== undefined) {\n if (p.target === null || p.target === '') delete (h as { target?: string }).target;\n else (h as { target?: string }).target = String(p.target);\n }\n if (p.targetChatId !== undefined) {\n if (p.targetChatId === null || p.targetChatId === '') delete (h as { targetChatId?: string }).targetChatId;\n else (h as { targetChatId?: string }).targetChatId = String(p.targetChatId);\n }\n if (p.prompt !== undefined) {\n if (p.prompt === null || p.prompt === '') delete (h as { prompt?: string }).prompt;\n else (h as { prompt?: string }).prompt = String(p.prompt);\n }\n if (p.ackMaxChars !== undefined) {\n if (p.ackMaxChars === null || p.ackMaxChars === '') delete (h as { ackMaxChars?: number }).ackMaxChars;\n else if (typeof p.ackMaxChars === 'number' && Number.isFinite(p.ackMaxChars)) {\n (h as { ackMaxChars?: number }).ackMaxChars = p.ackMaxChars;\n }\n }\n if (p.isolatedSession !== undefined) {\n if (p.isolatedSession === null || p.isolatedSession === false) {\n delete (h as { isolatedSession?: boolean }).isolatedSession;\n } else {\n (h as { isolatedSession?: boolean }).isolatedSession = Boolean(p.isolatedSession);\n }\n }\n if (p.activeHours !== undefined) {\n if (p.activeHours === null) {\n delete (h as { activeHours?: unknown }).activeHours;\n } else if (typeof p.activeHours === 'object' && p.activeHours !== null) {\n const ah = p.activeHours as Record<string, unknown>;\n const start = typeof ah.start === 'string' ? ah.start : '';\n const end = typeof ah.end === 'string' ? ah.end : '';\n if (start && end) {\n (h as { activeHours?: { start: string; end: string; timezone?: string } }).activeHours = {\n start,\n end,\n ...(typeof ah.timezone === 'string' && ah.timezone.trim() ? { timezone: ah.timezone } : {}),\n };\n } else {\n delete (h as { activeHours?: unknown }).activeHours;\n }\n }\n }\n }\n if (body.gateway?.auth !== undefined) {\n if (!config.gateway) {\n config.gateway = {\n host: '0.0.0.0',\n port: 18790,\n heartbeat: { enabled: true, intervalMs: 1_800_000, includeSystemPromptSection: false },\n maxSseConnections: 100,\n corsOrigins: ['*'],\n };\n }\n if (!config.gateway.auth) config.gateway.auth = { mode: 'token' };\n const a = body.gateway.auth;\n if (a.mode !== undefined) {\n config.gateway.auth.mode = a.mode;\n }\n if (a.token !== undefined) {\n config.gateway.auth.token = a.token;\n }\n }\n\n if (body.update !== undefined && typeof body.update === 'object' && body.update !== null) {\n const p = body.update as Record<string, unknown>;\n if (p.channel === 'stable' || p.channel === 'beta' || p.channel === 'dev') {\n if (!config.update) {\n config.update = { checkOnStart: true, channel: p.channel };\n } else {\n config.update.channel = p.channel;\n }\n }\n }\n\n // Update providers config - save to credential system instead of config\n if (body.providers) {\n const resolver = new CredentialResolver();\n for (const [key, apiKey] of Object.entries(body.providers)) {\n if (\n apiKey !== undefined &&\n typeof apiKey === 'string' &&\n apiKey.trim() &&\n apiKey !== '***' &&\n apiKey !== '••••••••••••'\n ) {\n await resolver.saveApiKey(key, apiKey, { profileName: 'default' });\n }\n }\n }\n\n // Structured per-vendor provider config (cfg.providers.<id>) for capability\n // providers (image / audio / video). Distinct from `body.providers` above\n // which targets the LLM-side credential resolver.\n if (body.providersConfig && typeof body.providersConfig === 'object' && !Array.isArray(body.providersConfig)) {\n const cfgProviders = (config as { providers?: Record<string, Record<string, unknown>> }).providers ?? {};\n for (const [vendorId, raw] of Object.entries(body.providersConfig as Record<string, unknown>)) {\n if (!vendorId || typeof vendorId !== 'string') continue;\n if (raw === null) {\n delete cfgProviders[vendorId];\n continue;\n }\n if (!raw || typeof raw !== 'object' || Array.isArray(raw)) continue;\n const next = (cfgProviders[vendorId] ?? {}) as Record<string, unknown>;\n const patch = raw as Record<string, unknown>;\n for (const field of ['apiKey', 'baseUrl', 'region', 'imageBaseUrl'] as const) {\n if (patch[field] === null || patch[field] === '') {\n delete next[field];\n } else if (typeof patch[field] === 'string') {\n next[field] = (patch[field] as string).trim();\n }\n }\n if (patch.azure === null) {\n delete next.azure;\n } else if (patch.azure && typeof patch.azure === 'object' && !Array.isArray(patch.azure)) {\n next.azure = { ...(next.azure as Record<string, unknown> ?? {}), ...(patch.azure as Record<string, unknown>) };\n }\n if (patch.request === null) {\n delete next.request;\n } else if (patch.request && typeof patch.request === 'object' && !Array.isArray(patch.request)) {\n next.request = { ...(next.request as Record<string, unknown> ?? {}), ...(patch.request as Record<string, unknown>) };\n }\n cfgProviders[vendorId] = next;\n }\n (config as { providers?: Record<string, Record<string, unknown>> }).providers = cfgProviders;\n }\n\n // PATCH `stt` writes to tools.media.audio; PATCH `tts` writes to messages.tts.\n if (body.stt !== undefined) {\n config.tools = config.tools ?? {};\n config.tools.media = config.tools.media ?? {};\n (config.tools.media as Record<string, unknown>).audio = body.stt;\n }\n if (body.tts !== undefined) {\n config.messages = config.messages ?? {};\n (config.messages as Record<string, unknown>).tts = body.tts;\n }\n\n const toolsPatchErr = applyToolsWebPatch(config, body as Record<string, unknown>);\n if (toolsPatchErr) {\n return c.json({ ok: false, error: { message: toolsPatchErr } }, 400);\n }\n\n if (body.bindings !== undefined) {\n if (!Array.isArray(body.bindings)) {\n return c.json({ ok: false, error: { message: 'bindings must be an array' } }, 400);\n }\n const parsed = BindingsConfigSchema.safeParse(body.bindings);\n if (!parsed.success) {\n return c.json(\n { ok: false, error: { message: parsed.error.issues.map((i) => i.message).join('; ') } },\n 400,\n );\n }\n config.bindings = parsed.data;\n }\n\n // Save config\n const result = await service.saveConfig(config);\n if (!result.saved) {\n return c.json({ ok: false, error: result.error }, 500);\n }\n\n if (body.gateway?.heartbeat !== undefined && typeof body.gateway.heartbeat === 'object') {\n service.reloadHeartbeatFromCurrentConfig();\n }\n\n const safeConfig = await buildSafeWebConfigPayload(service);\n return c.json({ ok: true, payload: { config: safeConfig } });\n });\n}\n"],"mappings":"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"}
@@ -34,7 +34,7 @@ export declare class EmbeddedBackend implements TuiBackend {
34
34
  messages: HistoryMessage[];
35
35
  }>;
36
36
  listSessions(): Promise<TuiSessionItem[]>;
37
- getSessionInfo(_sessionKey: string): Promise<SessionInfo>;
37
+ getSessionInfo(sessionKey: string): Promise<SessionInfo>;
38
38
  listModels(): Promise<TuiModelChoice[]>;
39
39
  resetSession(_sessionKey: string): Promise<void>;
40
40
  patchSession(_sessionKey: string, _patch: Record<string, unknown>): Promise<void>;
@@ -7,6 +7,7 @@ import { MessageBus, MessageBusShutdownError } from "../../infra/bus/queue.js";
7
7
  import "../../infra/bus/index.js";
8
8
  import { prependEnvelopeTimestamp } from "../../channels/envelope-timestamp.js";
9
9
  import { messagesToClientHistory } from "../../session/client-history.js";
10
+ import { parseModelRef } from "../../agent/models/selection.js";
10
11
  import { AgentService } from "../../agent/service.js";
11
12
  import "../../agent/index.js";
12
13
  import "../../config/index.js";
@@ -128,9 +129,29 @@ var EmbeddedBackend = class {
128
129
  async listSessions() {
129
130
  return [];
130
131
  }
131
- async getSessionInfo(_sessionKey) {
132
- const modelConfig = loadConfig().agents?.defaults?.model;
133
- return { model: (typeof modelConfig === "string" ? modelConfig : modelConfig?.primary) ?? void 0 };
132
+ async getSessionInfo(sessionKey) {
133
+ if (!this.agent) {
134
+ const modelConfig = loadConfig().agents?.defaults?.model;
135
+ return { model: (typeof modelConfig === "string" ? modelConfig : modelConfig?.primary) ?? void 0 };
136
+ }
137
+ try {
138
+ const cfg = await this.agent.getSessionAgentConfig(sessionKey);
139
+ const parsed = parseModelRef(cfg.model);
140
+ return {
141
+ model: parsed?.model ?? cfg.model,
142
+ modelProvider: parsed?.provider,
143
+ thinkingLevel: cfg.thinkingLevel
144
+ };
145
+ } catch (err) {
146
+ const errorMessage = err instanceof Error ? err.message : String(err);
147
+ log.warn({
148
+ err,
149
+ sessionKey,
150
+ errorMessage
151
+ }, `getSessionInfo failed: ${errorMessage}`);
152
+ const modelConfig = loadConfig().agents?.defaults?.model;
153
+ return { model: (typeof modelConfig === "string" ? modelConfig : modelConfig?.primary) ?? void 0 };
154
+ }
134
155
  }
135
156
  async listModels() {
136
157
  const choices = [];
@@ -1 +1 @@
1
- {"version":3,"file":"embedded-backend.js","names":[],"sources":["../../../../src/tui/backends/embedded-backend.ts"],"sourcesContent":["import { AgentService } from '../../agent/index.js';\nimport { messagesToClientHistory } from '../../session/client-history.js';\nimport { prependEnvelopeTimestamp } from '../../channels/envelope-timestamp.js';\nimport { loadConfig, getWorkspacePath } from '../../config/index.js';\nimport { MessageBus, MessageBusShutdownError } from '../../infra/bus/index.js';\nimport { getAllProviders, getModelsByProvider } from '../../providers/index.js';\nimport { createLogger } from '../../utils/logger.js';\nimport type {\n ChatSendOptions,\n HistoryMessage,\n TuiBackend,\n TuiEvent,\n TuiModelChoice,\n TuiSessionItem,\n} from '../tui-backend.js';\nimport type { SessionInfo } from '../tui-types.js';\n\nconst log = createLogger('TUI:Embedded');\n\n/**\n * TUI backend that runs the agent in-process (no gateway required).\n *\n * Wraps `AgentService` directly and emits TuiEvents by observing the\n * `MessageBus` output stream.\n */\nexport class EmbeddedBackend implements TuiBackend {\n private bus: MessageBus;\n private agent: AgentService | null = null;\n private running = false;\n private chatAbort: AbortController | null = null;\n\n onEvent?: (evt: TuiEvent) => void;\n onConnected?: () => void;\n onDisconnected?: (reason: string) => void;\n\n constructor() {\n this.bus = new MessageBus();\n }\n\n get connectionLabel(): string {\n return 'local embedded';\n }\n\n start(): void {\n if (this.running) return;\n this.running = true;\n\n const config = loadConfig();\n const workspace = getWorkspacePath(config);\n const modelConfig = config.agents?.defaults?.model;\n const modelId = typeof modelConfig === 'string' ? modelConfig : modelConfig?.primary;\n\n this.agent = new AgentService(this.bus, {\n workspace: workspace ?? process.cwd(),\n model: modelId,\n config,\n });\n\n this.agent.start().catch((err) => {\n const errorMessage = err instanceof Error ? err.message : String(err);\n log.error({ err, errorMessage }, `Embedded agent failed: ${errorMessage}`);\n this.onDisconnected?.(errorMessage);\n });\n\n // Process outbound messages in background\n this.processOutbound();\n\n // Signal ready\n queueMicrotask(() => this.onConnected?.());\n }\n\n stop(): void {\n this.running = false;\n this.bus.shutdown();\n void this.agent?.stop();\n this.agent = null;\n }\n\n async sendChat(opts: ChatSendOptions): Promise<{ runId: string }> {\n if (!this.agent) throw new Error('Agent not started');\n\n const runId = crypto.randomUUID();\n this.chatAbort?.abort();\n this.chatAbort = new AbortController();\n const signal = this.chatAbort.signal;\n\n this.onEvent?.({ event: 'status', data: { status: 'started', runId } });\n\n // Run the stream in background so the TUI event loop stays responsive.\n void (async () => {\n try {\n // Prepend envelope timestamp so the model knows the current date/time,\n // matching the behavior of channel pipelines (Telegram, Weixin, etc.).\n // Skip for slash commands — parseSlashCommand requires lines starting with '/'.\n const messageForAgent = opts.message.trimStart().startsWith('/')\n ? opts.message\n : prependEnvelopeTimestamp(opts.message);\n\n const stream = this.agent!.processDirectStreaming(\n messageForAgent,\n opts.sessionKey,\n undefined,\n opts.thinking,\n { signal },\n );\n\n for await (const event of stream) {\n if (signal.aborted) break;\n this.onEvent?.({ event: event.type, data: event });\n }\n\n if (!signal.aborted) {\n this.onEvent?.({\n event: 'result',\n data: { ok: true },\n });\n }\n } catch (error) {\n if (signal.aborted) return;\n const errorMessage = error instanceof Error ? error.message : String(error);\n this.onEvent?.({ event: 'error', data: { content: errorMessage } });\n }\n })();\n\n return { runId };\n }\n\n async abortChat(_opts: { sessionKey: string; runId: string }): Promise<{ ok: boolean }> {\n if (this.chatAbort) {\n this.chatAbort.abort();\n this.chatAbort = null;\n return { ok: true };\n }\n return { ok: false };\n }\n\n async loadHistory(opts: {\n sessionKey: string;\n limit?: number;\n }): Promise<{ messages: HistoryMessage[] }> {\n if (!this.agent) {\n return { messages: [] };\n }\n try {\n const detail = await this.agent.loadSessionDetail(opts.sessionKey);\n if (!detail) {\n return { messages: [] };\n }\n return {\n messages: messagesToClientHistory(detail.messages, { limit: opts.limit }),\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, errorMessage }, `Embedded loadHistory failed: ${errorMessage}`);\n return { messages: [] };\n }\n }\n\n async listSessions(): Promise<TuiSessionItem[]> {\n return [];\n }\n\n async getSessionInfo(_sessionKey: string): Promise<SessionInfo> {\n const config = loadConfig();\n const modelConfig = config.agents?.defaults?.model;\n const model = typeof modelConfig === 'string' ? modelConfig : modelConfig?.primary;\n return { model: model ?? undefined };\n }\n\n async listModels(): Promise<TuiModelChoice[]> {\n const choices: TuiModelChoice[] = [];\n for (const provider of getAllProviders()) {\n for (const model of getModelsByProvider(provider)) {\n choices.push({\n id: model.id,\n name: model.name ?? model.id,\n provider,\n });\n }\n }\n return choices;\n }\n\n async resetSession(_sessionKey: string): Promise<void> {\n // Restart agent for a clean session\n this.stop();\n this.bus = new MessageBus();\n this.start();\n }\n\n async patchSession(\n _sessionKey: string,\n _patch: Record<string, unknown>,\n ): Promise<void> {\n // Not supported in embedded mode\n }\n\n private processOutbound(): void {\n void (async () => {\n while (this.running) {\n try {\n const msg = await this.bus.consumeOutbound();\n log.debug({ channel: msg.channel, chatId: msg.chat_id }, 'Outbound message');\n } catch (error) {\n if (error instanceof MessageBusShutdownError) break;\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, errorMessage }, `Outbound processor failed: ${errorMessage}`);\n await new Promise((resolve) => setTimeout(resolve, 1000));\n }\n }\n })();\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"embedded-backend.js","names":[],"sources":["../../../../src/tui/backends/embedded-backend.ts"],"sourcesContent":["import { AgentService } from '../../agent/index.js';\nimport { parseModelRef } from '../../agent/models/selection.js';\nimport { messagesToClientHistory } from '../../session/client-history.js';\nimport { prependEnvelopeTimestamp } from '../../channels/envelope-timestamp.js';\nimport { loadConfig, getWorkspacePath } from '../../config/index.js';\nimport { MessageBus, MessageBusShutdownError } from '../../infra/bus/index.js';\nimport { getAllProviders, getModelsByProvider } from '../../providers/index.js';\nimport { createLogger } from '../../utils/logger.js';\nimport type {\n ChatSendOptions,\n HistoryMessage,\n TuiBackend,\n TuiEvent,\n TuiModelChoice,\n TuiSessionItem,\n} from '../tui-backend.js';\nimport type { SessionInfo } from '../tui-types.js';\n\nconst log = createLogger('TUI:Embedded');\n\n/**\n * TUI backend that runs the agent in-process (no gateway required).\n *\n * Wraps `AgentService` directly and emits TuiEvents by observing the\n * `MessageBus` output stream.\n */\nexport class EmbeddedBackend implements TuiBackend {\n private bus: MessageBus;\n private agent: AgentService | null = null;\n private running = false;\n private chatAbort: AbortController | null = null;\n\n onEvent?: (evt: TuiEvent) => void;\n onConnected?: () => void;\n onDisconnected?: (reason: string) => void;\n\n constructor() {\n this.bus = new MessageBus();\n }\n\n get connectionLabel(): string {\n return 'local embedded';\n }\n\n start(): void {\n if (this.running) return;\n this.running = true;\n\n const config = loadConfig();\n const workspace = getWorkspacePath(config);\n const modelConfig = config.agents?.defaults?.model;\n const modelId = typeof modelConfig === 'string' ? modelConfig : modelConfig?.primary;\n\n this.agent = new AgentService(this.bus, {\n workspace: workspace ?? process.cwd(),\n model: modelId,\n config,\n });\n\n this.agent.start().catch((err) => {\n const errorMessage = err instanceof Error ? err.message : String(err);\n log.error({ err, errorMessage }, `Embedded agent failed: ${errorMessage}`);\n this.onDisconnected?.(errorMessage);\n });\n\n // Process outbound messages in background\n this.processOutbound();\n\n // Signal ready\n queueMicrotask(() => this.onConnected?.());\n }\n\n stop(): void {\n this.running = false;\n this.bus.shutdown();\n void this.agent?.stop();\n this.agent = null;\n }\n\n async sendChat(opts: ChatSendOptions): Promise<{ runId: string }> {\n if (!this.agent) throw new Error('Agent not started');\n\n const runId = crypto.randomUUID();\n this.chatAbort?.abort();\n this.chatAbort = new AbortController();\n const signal = this.chatAbort.signal;\n\n this.onEvent?.({ event: 'status', data: { status: 'started', runId } });\n\n // Run the stream in background so the TUI event loop stays responsive.\n void (async () => {\n try {\n // Prepend envelope timestamp so the model knows the current date/time,\n // matching the behavior of channel pipelines (Telegram, Weixin, etc.).\n // Skip for slash commands — parseSlashCommand requires lines starting with '/'.\n const messageForAgent = opts.message.trimStart().startsWith('/')\n ? opts.message\n : prependEnvelopeTimestamp(opts.message);\n\n const stream = this.agent!.processDirectStreaming(\n messageForAgent,\n opts.sessionKey,\n undefined,\n opts.thinking,\n { signal },\n );\n\n for await (const event of stream) {\n if (signal.aborted) break;\n this.onEvent?.({ event: event.type, data: event });\n }\n\n if (!signal.aborted) {\n this.onEvent?.({\n event: 'result',\n data: { ok: true },\n });\n }\n } catch (error) {\n if (signal.aborted) return;\n const errorMessage = error instanceof Error ? error.message : String(error);\n this.onEvent?.({ event: 'error', data: { content: errorMessage } });\n }\n })();\n\n return { runId };\n }\n\n async abortChat(_opts: { sessionKey: string; runId: string }): Promise<{ ok: boolean }> {\n if (this.chatAbort) {\n this.chatAbort.abort();\n this.chatAbort = null;\n return { ok: true };\n }\n return { ok: false };\n }\n\n async loadHistory(opts: {\n sessionKey: string;\n limit?: number;\n }): Promise<{ messages: HistoryMessage[] }> {\n if (!this.agent) {\n return { messages: [] };\n }\n try {\n const detail = await this.agent.loadSessionDetail(opts.sessionKey);\n if (!detail) {\n return { messages: [] };\n }\n return {\n messages: messagesToClientHistory(detail.messages, { limit: opts.limit }),\n };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, errorMessage }, `Embedded loadHistory failed: ${errorMessage}`);\n return { messages: [] };\n }\n }\n\n async listSessions(): Promise<TuiSessionItem[]> {\n return [];\n }\n\n async getSessionInfo(sessionKey: string): Promise<SessionInfo> {\n if (!this.agent) {\n const config = loadConfig();\n const modelConfig = config.agents?.defaults?.model;\n const model = typeof modelConfig === 'string' ? modelConfig : modelConfig?.primary;\n return { model: model ?? undefined };\n }\n try {\n const cfg = await this.agent.getSessionAgentConfig(sessionKey);\n const parsed = parseModelRef(cfg.model);\n return {\n model: parsed?.model ?? cfg.model,\n modelProvider: parsed?.provider,\n thinkingLevel: cfg.thinkingLevel,\n };\n } catch (err) {\n const errorMessage = err instanceof Error ? err.message : String(err);\n log.warn({ err, sessionKey, errorMessage }, `getSessionInfo failed: ${errorMessage}`);\n const config = loadConfig();\n const modelConfig = config.agents?.defaults?.model;\n const model = typeof modelConfig === 'string' ? modelConfig : modelConfig?.primary;\n return { model: model ?? undefined };\n }\n }\n\n async listModels(): Promise<TuiModelChoice[]> {\n const choices: TuiModelChoice[] = [];\n for (const provider of getAllProviders()) {\n for (const model of getModelsByProvider(provider)) {\n choices.push({\n id: model.id,\n name: model.name ?? model.id,\n provider,\n });\n }\n }\n return choices;\n }\n\n async resetSession(_sessionKey: string): Promise<void> {\n // Restart agent for a clean session\n this.stop();\n this.bus = new MessageBus();\n this.start();\n }\n\n async patchSession(\n _sessionKey: string,\n _patch: Record<string, unknown>,\n ): Promise<void> {\n // Not supported in embedded mode\n }\n\n private processOutbound(): void {\n void (async () => {\n while (this.running) {\n try {\n const msg = await this.bus.consumeOutbound();\n log.debug({ channel: msg.channel, chatId: msg.chat_id }, 'Outbound message');\n } catch (error) {\n if (error instanceof MessageBusShutdownError) break;\n const errorMessage = error instanceof Error ? error.message : String(error);\n log.warn({ err: error, errorMessage }, `Outbound processor failed: ${errorMessage}`);\n await new Promise((resolve) => setTimeout(resolve, 1000));\n }\n }\n })();\n }\n}\n"],"mappings":"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"}