nextclaw 0.8.35 → 0.8.37

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. package/dist/cli/index.js +90 -17
  2. package/package.json +3 -3
  3. package/templates/USAGE.md +3 -0
  4. package/ui-dist/assets/{ChannelsList-AKnD2r1L.js → ChannelsList-C2h4dVWt.js} +1 -1
  5. package/ui-dist/assets/{ChatPage-DidO_pAN.js → ChatPage-B4xQTj78.js} +14 -14
  6. package/ui-dist/assets/{CronConfig-C1pm-oKA.js → CronConfig-CtiTohyP.js} +1 -1
  7. package/ui-dist/assets/{DocBrowser-BY90Lf6L.js → DocBrowser-BDOIcX3y.js} +1 -1
  8. package/ui-dist/assets/{MarketplacePage-BRtmhP3G.js → MarketplacePage-BPc8FmE5.js} +1 -1
  9. package/ui-dist/assets/{ModelConfig-Dga1Ko7_.js → ModelConfig-pX1wV-UJ.js} +1 -1
  10. package/ui-dist/assets/{ProvidersList-DvCoBTrT.js → ProvidersList-BJTtF6S5.js} +1 -1
  11. package/ui-dist/assets/{RuntimeConfig-2aqBJ6Xn.js → RuntimeConfig-BqN1F3nP.js} +1 -1
  12. package/ui-dist/assets/{SecretsConfig-wlnh__z0.js → SecretsConfig-CkqJq4s6.js} +2 -2
  13. package/ui-dist/assets/{SessionsConfig-CN2WymbH.js → SessionsConfig-ti41bz9T.js} +1 -1
  14. package/ui-dist/assets/{action-link-DLZDwUfD.js → action-link-C4fhtxYl.js} +1 -1
  15. package/ui-dist/assets/{card-D3dD-I5t.js → card-C0sHz144.js} +1 -1
  16. package/ui-dist/assets/chat-message-Jxa8JFA_.js +9 -0
  17. package/ui-dist/assets/{dialog-DZ0VC-RD.js → dialog-CJMXeCpK.js} +1 -1
  18. package/ui-dist/assets/index-BTE5dHqH.js +2 -0
  19. package/ui-dist/assets/{label-CJIvvG6o.js → label-DeI2vCVA.js} +1 -1
  20. package/ui-dist/assets/{page-layout-CLgr0qym.js → page-layout-C_pPVkYP.js} +1 -1
  21. package/ui-dist/assets/{switch-C-0Q8OH2.js → switch-_UxC2xoH.js} +1 -1
  22. package/ui-dist/assets/{tabs-custom-D4Gs3BGM.js → tabs-custom-DgryVfGt.js} +1 -1
  23. package/ui-dist/assets/useConfig-DDPQwvDe.js +6 -0
  24. package/ui-dist/assets/{useConfirmDialog-AMeSTA83.js → useConfirmDialog-DqTlJNqa.js} +1 -1
  25. package/ui-dist/index.html +1 -1
  26. package/ui-dist/assets/chat-message-DZV2Z5oc.js +0 -5
  27. package/ui-dist/assets/index-D_vv0E-O.js +0 -2
  28. package/ui-dist/assets/useConfig-R5uGhZtD.js +0 -1
package/dist/cli/index.js CHANGED
@@ -2717,7 +2717,8 @@ var GatewayAgentRuntimePool = class {
2717
2717
  sessionKey: route.sessionKey,
2718
2718
  channel: message.channel,
2719
2719
  chatId: message.chatId,
2720
- metadata: message.metadata
2720
+ metadata: message.metadata,
2721
+ onAssistantDelta: params.onAssistantDelta
2721
2722
  });
2722
2723
  }
2723
2724
  async run() {
@@ -3397,6 +3398,29 @@ var ServiceCommands = class {
3397
3398
  if (!uiConfig.enabled) {
3398
3399
  return;
3399
3400
  }
3401
+ const resolveChatTurnParams = (params) => {
3402
+ const sessionKey = typeof params.sessionKey === "string" && params.sessionKey.trim().length > 0 ? params.sessionKey.trim() : `ui:${Date.now().toString(36)}:${Math.random().toString(36).slice(2, 8)}`;
3403
+ const inferredAgentId = typeof params.agentId === "string" && params.agentId.trim().length > 0 ? params.agentId.trim() : parseAgentScopedSessionKey2(sessionKey)?.agentId;
3404
+ const model = typeof params.model === "string" && params.model.trim().length > 0 ? params.model.trim() : void 0;
3405
+ const metadata = params.metadata && typeof params.metadata === "object" && !Array.isArray(params.metadata) ? { ...params.metadata } : {};
3406
+ if (model) {
3407
+ metadata.model = model;
3408
+ }
3409
+ return {
3410
+ sessionKey,
3411
+ inferredAgentId,
3412
+ model,
3413
+ metadata,
3414
+ channel: typeof params.channel === "string" && params.channel.trim().length > 0 ? params.channel : "ui",
3415
+ chatId: typeof params.chatId === "string" && params.chatId.trim().length > 0 ? params.chatId : "web-ui"
3416
+ };
3417
+ };
3418
+ const buildTurnResult = (params) => ({
3419
+ reply: params.reply,
3420
+ sessionKey: params.sessionKey,
3421
+ ...params.inferredAgentId ? { agentId: params.inferredAgentId } : {},
3422
+ ...params.model ? { model: params.model } : {}
3423
+ });
3400
3424
  const uiServer = startUiServer({
3401
3425
  host: uiConfig.host,
3402
3426
  port: uiConfig.port,
@@ -3416,27 +3440,76 @@ var ServiceCommands = class {
3416
3440
  },
3417
3441
  chatRuntime: {
3418
3442
  processTurn: async (params) => {
3419
- const sessionKey = typeof params.sessionKey === "string" && params.sessionKey.trim().length > 0 ? params.sessionKey.trim() : `ui:${Date.now().toString(36)}:${Math.random().toString(36).slice(2, 8)}`;
3420
- const inferredAgentId = typeof params.agentId === "string" && params.agentId.trim().length > 0 ? params.agentId.trim() : parseAgentScopedSessionKey2(sessionKey)?.agentId;
3421
- const model = typeof params.model === "string" && params.model.trim().length > 0 ? params.model.trim() : void 0;
3422
- const metadata = params.metadata && typeof params.metadata === "object" && !Array.isArray(params.metadata) ? { ...params.metadata } : {};
3423
- if (model) {
3424
- metadata.model = model;
3425
- }
3443
+ const resolved = resolveChatTurnParams(params);
3426
3444
  const reply = await runtimePool.processDirect({
3427
3445
  content: params.message,
3428
- sessionKey,
3429
- channel: typeof params.channel === "string" && params.channel.trim().length > 0 ? params.channel : "ui",
3430
- chatId: typeof params.chatId === "string" && params.chatId.trim().length > 0 ? params.chatId : "web-ui",
3431
- agentId: inferredAgentId,
3432
- metadata
3446
+ sessionKey: resolved.sessionKey,
3447
+ channel: resolved.channel,
3448
+ chatId: resolved.chatId,
3449
+ agentId: resolved.inferredAgentId,
3450
+ metadata: resolved.metadata
3433
3451
  });
3434
- return {
3452
+ return buildTurnResult({
3435
3453
  reply,
3436
- sessionKey,
3437
- ...inferredAgentId ? { agentId: inferredAgentId } : {},
3438
- ...model ? { model } : {}
3454
+ sessionKey: resolved.sessionKey,
3455
+ inferredAgentId: resolved.inferredAgentId,
3456
+ model: resolved.model
3457
+ });
3458
+ },
3459
+ processTurnStream: async function* (params) {
3460
+ const resolved = resolveChatTurnParams(params);
3461
+ const queue = [];
3462
+ let waiter = null;
3463
+ const push = (event) => {
3464
+ queue.push(event);
3465
+ const currentWaiter = waiter;
3466
+ waiter = null;
3467
+ currentWaiter?.();
3439
3468
  };
3469
+ const run = runtimePool.processDirect({
3470
+ content: params.message,
3471
+ sessionKey: resolved.sessionKey,
3472
+ channel: resolved.channel,
3473
+ chatId: resolved.chatId,
3474
+ agentId: resolved.inferredAgentId,
3475
+ metadata: resolved.metadata,
3476
+ onAssistantDelta: (delta) => {
3477
+ if (typeof delta !== "string" || delta.length === 0) {
3478
+ return;
3479
+ }
3480
+ push({ type: "delta", delta });
3481
+ }
3482
+ }).then((reply) => {
3483
+ push({
3484
+ type: "final",
3485
+ result: buildTurnResult({
3486
+ reply,
3487
+ sessionKey: resolved.sessionKey,
3488
+ inferredAgentId: resolved.inferredAgentId,
3489
+ model: resolved.model
3490
+ })
3491
+ });
3492
+ }).catch((error) => {
3493
+ push({ type: "error", error: String(error) });
3494
+ });
3495
+ while (true) {
3496
+ if (queue.length === 0) {
3497
+ await new Promise((resolve10) => {
3498
+ waiter = resolve10;
3499
+ });
3500
+ }
3501
+ while (queue.length > 0) {
3502
+ const event = queue.shift();
3503
+ if (!event) {
3504
+ continue;
3505
+ }
3506
+ yield event;
3507
+ if (event.type !== "delta") {
3508
+ await run;
3509
+ return;
3510
+ }
3511
+ }
3512
+ }
3440
3513
  }
3441
3514
  }
3442
3515
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nextclaw",
3
- "version": "0.8.35",
3
+ "version": "0.8.37",
4
4
  "description": "Lightweight personal AI assistant with CLI, multi-provider routing, and channel integrations.",
5
5
  "private": false,
6
6
  "type": "module",
@@ -38,8 +38,8 @@
38
38
  "dependencies": {
39
39
  "chokidar": "^3.6.0",
40
40
  "commander": "^12.1.0",
41
- "@nextclaw/core": "^0.6.35",
42
- "@nextclaw/server": "^0.5.18",
41
+ "@nextclaw/core": "^0.6.36",
42
+ "@nextclaw/server": "^0.5.19",
43
43
  "@nextclaw/openclaw-compat": "^0.1.28"
44
44
  },
45
45
  "devDependencies": {
@@ -361,9 +361,12 @@ NextClaw UI includes a first-class **Chat** tab so you can talk to your agent di
361
361
  - choose target agent before sending message
362
362
  - send messages with Enter (Shift+Enter for newline)
363
363
  - keep using the same session for multi-turn context
364
+ - stream assistant output in real time via UI SSE API (`POST /api/chat/turn/stream`)
364
365
  - render assistant replies as Markdown (tables/code blocks/links)
365
366
  - show tool calls/results as structured tool cards
367
+ - merge tool result and its immediate assistant follow-up explanation into one card
366
368
  - merge consecutive same-role messages into grouped chat blocks for better readability
369
+ - keep input editable while AI is streaming, and queue additional sends during busy turns
367
370
 
368
371
  Notes:
369
372
 
@@ -1 +1 @@
1
- import{r as v,j as a,ac as ae,M as S,ad as M,ae as N,K as te,a0 as ne,ab as le,af as se,ag as oe,n as H,ah as re,ai as ce,aj as ie}from"./vendor-H2M3a_4Z.js";import{u as K,a as _,i as me,j as pe,I as D,g as de}from"./useConfig-R5uGhZtD.js";import{t as e,c as q,u as G,S as be,b as ue,d as ge,e as ye,g as xe}from"./index-D_vv0E-O.js";import{D as he,a as fe,b as we,c as je,d as ve,e as ke}from"./dialog-DZ0VC-RD.js";import{B as F,P as Ce,a as Pe}from"./page-layout-CLgr0qym.js";import{L as Ne}from"./label-CJIvvG6o.js";import{S as Se}from"./switch-C-0Q8OH2.js";import{h as T}from"./config-hints-CApS3K_7.js";import{T as Ie}from"./tabs-custom-D4Gs3BGM.js";import{C as De,a as Fe,L as Te,d as Me,S as Ae,b as Le,c as Ue,A as Ee}from"./action-link-DLZDwUfD.js";function Be({value:n,onChange:d,className:i,placeholder:m=""}){const[c,y]=v.useState(""),b=u=>{u.key==="Enter"&&c.trim()?(u.preventDefault(),d([...n,c.trim()]),y("")):u.key==="Backspace"&&!c&&n.length>0&&d(n.slice(0,-1))},f=u=>{d(n.filter((r,g)=>g!==u))};return a.jsxs("div",{className:q("flex flex-wrap gap-2 p-2 border rounded-md min-h-[42px]",i),children:[n.map((u,r)=>a.jsxs("span",{className:"inline-flex items-center gap-1 px-2 py-1 bg-primary text-primary-foreground rounded text-sm",children:[u,a.jsx("button",{type:"button",onClick:()=>f(r),className:"hover:text-red-300 transition-colors",children:a.jsx(ae,{className:"h-3 w-3"})})]},r)),a.jsx("input",{type:"text",value:c,onChange:u=>y(u.target.value),onKeyDown:b,className:"flex-1 outline-none min-w-[100px] bg-transparent text-sm",placeholder:m||e("enterTag")})]})}const U=[{value:"pairing",label:"pairing"},{value:"allowlist",label:"allowlist"},{value:"open",label:"open"},{value:"disabled",label:"disabled"}],E=[{value:"open",label:"open"},{value:"allowlist",label:"allowlist"},{value:"disabled",label:"disabled"}],Oe=[{value:"off",label:"off"},{value:"partial",label:"partial"},{value:"block",label:"block"},{value:"progress",label:"progress"}],$e=n=>n.includes("token")||n.includes("secret")||n.includes("password")?a.jsx(te,{className:"h-3.5 w-3.5 text-gray-500"}):n.includes("url")||n.includes("host")?a.jsx(ne,{className:"h-3.5 w-3.5 text-gray-500"}):n.includes("email")||n.includes("mail")?a.jsx(M,{className:"h-3.5 w-3.5 text-gray-500"}):n.includes("id")||n.includes("from")?a.jsx(le,{className:"h-3.5 w-3.5 text-gray-500"}):n==="enabled"||n==="consentGranted"?a.jsx(se,{className:"h-3.5 w-3.5 text-gray-500"}):a.jsx(oe,{className:"h-3.5 w-3.5 text-gray-500"});function B(){return{telegram:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"token",type:"password",label:e("botToken")},{name:"allowFrom",type:"tags",label:e("allowFrom")},{name:"proxy",type:"text",label:e("proxy")},{name:"accountId",type:"text",label:e("accountId")},{name:"dmPolicy",type:"select",label:e("dmPolicy"),options:U},{name:"groupPolicy",type:"select",label:e("groupPolicy"),options:E},{name:"groupAllowFrom",type:"tags",label:e("groupAllowFrom")},{name:"requireMention",type:"boolean",label:e("requireMention")},{name:"mentionPatterns",type:"tags",label:e("mentionPatterns")},{name:"groups",type:"json",label:e("groupRulesJson")}],discord:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"token",type:"password",label:e("botToken")},{name:"allowBots",type:"boolean",label:e("allowBotMessages")},{name:"allowFrom",type:"tags",label:e("allowFrom")},{name:"gatewayUrl",type:"text",label:e("gatewayUrl")},{name:"intents",type:"number",label:e("intents")},{name:"proxy",type:"text",label:e("proxy")},{name:"mediaMaxMb",type:"number",label:e("attachmentMaxSizeMb")},{name:"streaming",type:"select",label:e("streamingMode"),options:Oe},{name:"draftChunk",type:"json",label:e("draftChunkingJson")},{name:"textChunkLimit",type:"number",label:e("textChunkLimit")},{name:"accountId",type:"text",label:e("accountId")},{name:"dmPolicy",type:"select",label:e("dmPolicy"),options:U},{name:"groupPolicy",type:"select",label:e("groupPolicy"),options:E},{name:"groupAllowFrom",type:"tags",label:e("groupAllowFrom")},{name:"requireMention",type:"boolean",label:e("requireMention")},{name:"mentionPatterns",type:"tags",label:e("mentionPatterns")},{name:"groups",type:"json",label:e("groupRulesJson")}],whatsapp:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"bridgeUrl",type:"text",label:e("bridgeUrl")},{name:"allowFrom",type:"tags",label:e("allowFrom")}],feishu:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"appId",type:"text",label:e("appId")},{name:"appSecret",type:"password",label:e("appSecret")},{name:"encryptKey",type:"password",label:e("encryptKey")},{name:"verificationToken",type:"password",label:e("verificationToken")},{name:"allowFrom",type:"tags",label:e("allowFrom")}],dingtalk:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"clientId",type:"text",label:e("clientId")},{name:"clientSecret",type:"password",label:e("clientSecret")},{name:"allowFrom",type:"tags",label:e("allowFrom")}],wecom:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"corpId",type:"text",label:e("corpId")},{name:"agentId",type:"text",label:e("agentId")},{name:"secret",type:"password",label:e("secret")},{name:"token",type:"password",label:e("token")},{name:"callbackPort",type:"number",label:e("callbackPort")},{name:"callbackPath",type:"text",label:e("callbackPath")},{name:"allowFrom",type:"tags",label:e("allowFrom")}],slack:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"mode",type:"text",label:e("mode")},{name:"webhookPath",type:"text",label:e("webhookPath")},{name:"allowBots",type:"boolean",label:e("allowBotMessages")},{name:"botToken",type:"password",label:e("botToken")},{name:"appToken",type:"password",label:e("appToken")}],email:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"consentGranted",type:"boolean",label:e("consentGranted")},{name:"imapHost",type:"text",label:e("imapHost")},{name:"imapPort",type:"number",label:e("imapPort")},{name:"imapUsername",type:"text",label:e("imapUsername")},{name:"imapPassword",type:"password",label:e("imapPassword")},{name:"fromAddress",type:"email",label:e("fromAddress")}],mochat:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"baseUrl",type:"text",label:e("baseUrl")},{name:"clawToken",type:"password",label:e("clawToken")},{name:"agentUserId",type:"text",label:e("agentUserId")},{name:"allowFrom",type:"tags",label:e("allowFrom")}],qq:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"appId",type:"text",label:e("appId")},{name:"secret",type:"password",label:e("appSecret")},{name:"markdownSupport",type:"boolean",label:e("markdownSupport")},{name:"allowFrom",type:"tags",label:e("allowFrom")}]}}const O={telegram:S,slack:S,email:M,default:S},$={telegram:"from-primary-300 to-primary-600",slack:"from-primary-200 to-primary-500",email:"from-primary-100 to-primary-400",default:"from-gray-300 to-gray-500"};function I(n){return typeof n=="object"&&n!==null&&!Array.isArray(n)}function J(n,d){const i={...n};for(const[m,c]of Object.entries(d)){const y=i[m];if(I(y)&&I(c)){i[m]=J(y,c);continue}i[m]=c}return i}function Re(n,d){const i=n.split("."),m={};let c=m;for(let y=0;y<i.length-1;y+=1){const b=i[y];c[b]={},c=c[b]}return c[i[i.length-1]]=d,m}function He(){var A,L;const{channelModal:n,closeChannelModal:d}=G(),{data:i}=K(),{data:m}=_(),c=me(),y=pe(),[b,f]=v.useState({}),[u,r]=v.useState({}),[g,h]=v.useState(null),o=n.channel,w=o?i==null?void 0:i.channels[o]:null,k=o?B()[o]??[]:[],C=m==null?void 0:m.uiHints,P=o?`channels.${o}`:null,z=((A=m==null?void 0:m.actions)==null?void 0:A.filter(t=>t.scope===P))??[],V=o&&(((L=T(`channels.${o}`,C))==null?void 0:L.label)??o);v.useEffect(()=>{if(w){f({...w});const t={};(o?B()[o]??[]:[]).filter(s=>s.type==="json").forEach(s=>{const x=w[s.name];t[s.name]=JSON.stringify(x??{},null,2)}),r(t)}else f({}),r({})},[w,o]);const j=(t,l)=>{f(s=>({...s,[t]:l}))},Y=t=>{if(t.preventDefault(),!o)return;const l={...b};for(const s of k){if(s.type!=="password")continue;const x=l[s.name];(typeof x!="string"||x.length===0)&&delete l[s.name]}for(const s of k){if(s.type!=="json")continue;const x=u[s.name]??"";try{l[s.name]=x.trim()?JSON.parse(x):{}}catch{N.error(`${e("invalidJson")}: ${s.name}`);return}}c.mutate({channel:o,data:l},{onSuccess:()=>d()})},W=t=>{if(!t||!o)return;const l=t.channels;if(!I(l))return;const s=l[o];I(s)&&f(x=>J(x,s))},X=async t=>{if(!(!o||!P)){h(t.id);try{let l={...b};t.saveBeforeRun&&(l={...l,...t.savePatch??{}},f(l),await c.mutateAsync({channel:o,data:l}));const s=await y.mutateAsync({actionId:t.id,data:{scope:P,draftConfig:Re(P,l)}});W(s.patch),s.ok?N.success(s.message||e("success")):N.error(s.message||e("error"))}catch(l){const s=l instanceof Error?l.message:String(l);N.error(`${e("error")}: ${s}`)}finally{h(null)}}},Q=O[o||""]||O.default,Z=$[o||""]||$.default;return a.jsx(he,{open:n.open,onOpenChange:d,children:a.jsxs(fe,{className:"sm:max-w-[550px] max-h-[85vh] overflow-hidden flex flex-col",children:[a.jsx(we,{children:a.jsxs("div",{className:"flex items-center gap-3",children:[a.jsx("div",{className:`h-10 w-10 rounded-xl bg-gradient-to-br ${Z} flex items-center justify-center`,children:a.jsx(Q,{className:"h-5 w-5 text-white"})}),a.jsxs("div",{children:[a.jsx(je,{className:"capitalize",children:V}),a.jsx(ve,{children:e("configureMessageChannelParameters")})]})]})}),a.jsxs("form",{onSubmit:Y,className:"flex flex-col flex-1 overflow-hidden",children:[a.jsx("div",{className:"flex-1 overflow-y-auto custom-scrollbar py-2 pr-2 space-y-5",children:k.map(t=>{const l=o?T(`channels.${o}.${t.name}`,C):void 0,s=(l==null?void 0:l.label)??t.label,x=l==null?void 0:l.placeholder;return a.jsxs("div",{className:"space-y-2.5",children:[a.jsxs(Ne,{htmlFor:t.name,className:"text-sm font-medium text-gray-900 flex items-center gap-2",children:[$e(t.name),s]}),t.type==="boolean"&&a.jsxs("div",{className:"flex items-center justify-between p-3 rounded-xl bg-gray-50",children:[a.jsx("span",{className:"text-sm text-gray-500",children:b[t.name]?e("enabled"):e("disabled")}),a.jsx(Se,{id:t.name,checked:b[t.name]||!1,onCheckedChange:p=>j(t.name,p),className:"data-[state=checked]:bg-emerald-500"})]}),(t.type==="text"||t.type==="email")&&a.jsx(D,{id:t.name,type:t.type,value:b[t.name]||"",onChange:p=>j(t.name,p.target.value),placeholder:x,className:"rounded-xl"}),t.type==="password"&&a.jsx(D,{id:t.name,type:"password",value:b[t.name]||"",onChange:p=>j(t.name,p.target.value),placeholder:x??e("leaveBlankToKeepUnchanged"),className:"rounded-xl"}),t.type==="number"&&a.jsx(D,{id:t.name,type:"number",value:b[t.name]||0,onChange:p=>j(t.name,parseInt(p.target.value)||0),placeholder:x,className:"rounded-xl"}),t.type==="tags"&&a.jsx(Be,{value:b[t.name]||[],onChange:p=>j(t.name,p)}),t.type==="select"&&a.jsxs(be,{value:b[t.name]||"",onValueChange:p=>j(t.name,p),children:[a.jsx(ue,{className:"rounded-xl",children:a.jsx(ge,{})}),a.jsx(ye,{children:(t.options??[]).map(p=>a.jsx(xe,{value:p.value,children:p.label},p.value))})]}),t.type==="json"&&a.jsx("textarea",{id:t.name,value:u[t.name]??"{}",onChange:p=>r(ee=>({...ee,[t.name]:p.target.value})),className:"min-h-[120px] w-full rounded-lg border border-gray-200 bg-white px-3 py-2 text-xs font-mono"})]},t.name)})}),a.jsxs(ke,{className:"pt-4 flex-shrink-0",children:[a.jsx(F,{type:"button",variant:"outline",onClick:d,children:e("cancel")}),a.jsx(F,{type:"submit",disabled:c.isPending||!!g,children:c.isPending?e("saving"):e("save")}),z.filter(t=>t.trigger==="manual").map(t=>a.jsx(F,{type:"button",onClick:()=>X(t),disabled:c.isPending||!!g,variant:"secondary",children:g===t.id?e("connecting"):t.title},t.id))]})]})]})})}const R={telegram:S,slack:ce,email:M,webhook:re,default:H},Ke={telegram:"channelDescTelegram",slack:"channelDescSlack",email:"channelDescEmail",webhook:"channelDescWebhook",discord:"channelDescDiscord",feishu:"channelDescFeishu"};function Ze(){const{data:n}=K(),{data:d}=de(),{data:i}=_(),{openChannelModal:m}=G(),[c,y]=v.useState("active"),b=i==null?void 0:i.uiHints;if(!n||!d)return a.jsx("div",{className:"p-8 text-gray-400",children:e("channelsLoading")});const f=[{id:"active",label:e("channelsTabEnabled"),count:d.channels.filter(r=>{var g;return(g=n.channels[r.name])==null?void 0:g.enabled}).length},{id:"all",label:e("channelsTabAll"),count:d.channels.length}],u=d.channels.filter(r=>{var h;const g=((h=n.channels[r.name])==null?void 0:h.enabled)||!1;return c==="all"||g});return a.jsxs(Ce,{children:[a.jsx(Pe,{title:e("channelsPageTitle")}),a.jsx(Ie,{tabs:f,activeTab:c,onChange:y}),a.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4",children:u.map(r=>{const g=n.channels[r.name],h=(g==null?void 0:g.enabled)||!1,o=R[r.name]||R.default,w=T(`channels.${r.name}`,b),k=(w==null?void 0:w.help)||e(Ke[r.name]||"channelDescriptionDefault");return a.jsxs(De,{onClick:()=>m(r.name),children:[a.jsxs(Fe,{children:[a.jsx(Te,{name:r.name,src:Me(r.name),className:q("h-11 w-11 rounded-xl border transition-all",h?"bg-white border-primary/30":"bg-white border-gray-200/60 group-hover:border-gray-300"),imgClassName:"h-5 w-5",fallback:a.jsx(o,{className:"h-5 w-5"})}),a.jsx(Ae,{status:h?"active":"inactive",label:h?e("statusActive"):e("statusInactive")})]}),a.jsx(Le,{title:r.displayName||r.name,description:k}),a.jsxs(Ue,{children:[a.jsx(Ee,{label:h?e("actionConfigure"):e("actionEnable")}),r.tutorialUrl&&a.jsx("a",{href:r.tutorialUrl,target:"_blank",rel:"noreferrer",onClick:C=>C.stopPropagation(),className:"flex items-center justify-center h-6 w-6 rounded-md text-gray-300 hover:text-gray-500 hover:bg-gray-100/60 transition-colors",title:e("channelsGuideTitle"),children:a.jsx(ie,{className:"h-3.5 w-3.5"})})]})]},r.name)})}),u.length===0&&a.jsxs("div",{className:"flex flex-col items-center justify-center py-16 text-center",children:[a.jsx("div",{className:"h-14 w-14 flex items-center justify-center rounded-xl bg-gray-100/80 mb-4",children:a.jsx(H,{className:"h-6 w-6 text-gray-300"})}),a.jsx("h3",{className:"text-[14px] font-semibold text-gray-900 mb-1.5",children:e("channelsEmptyTitle")}),a.jsx("p",{className:"text-[13px] text-gray-400 max-w-sm",children:e("channelsEmptyDescription")})]}),a.jsx(He,{})]})}export{Ze as ChannelsList};
1
+ import{r as v,j as a,ac as ae,M as S,ad as M,ae as N,K as te,a0 as ne,ab as le,af as se,ag as oe,n as H,ah as re,ai as ce,aj as ie}from"./vendor-H2M3a_4Z.js";import{u as K,a as _,h as me,i as pe,I as D,f as de}from"./useConfig-DDPQwvDe.js";import{t as e,c as q,u as G,S as be,b as ue,d as ye,e as ge,g as xe}from"./index-BTE5dHqH.js";import{D as he,a as fe,b as we,c as je,d as ve,e as ke}from"./dialog-CJMXeCpK.js";import{B as F,P as Ce,a as Pe}from"./page-layout-C_pPVkYP.js";import{L as Ne}from"./label-DeI2vCVA.js";import{S as Se}from"./switch-_UxC2xoH.js";import{h as T}from"./config-hints-CApS3K_7.js";import{T as Ie}from"./tabs-custom-DgryVfGt.js";import{C as De,a as Fe,L as Te,d as Me,S as Ae,b as Le,c as Ue,A as Ee}from"./action-link-C4fhtxYl.js";function Be({value:n,onChange:d,className:i,placeholder:m=""}){const[c,g]=v.useState(""),b=u=>{u.key==="Enter"&&c.trim()?(u.preventDefault(),d([...n,c.trim()]),g("")):u.key==="Backspace"&&!c&&n.length>0&&d(n.slice(0,-1))},f=u=>{d(n.filter((r,y)=>y!==u))};return a.jsxs("div",{className:q("flex flex-wrap gap-2 p-2 border rounded-md min-h-[42px]",i),children:[n.map((u,r)=>a.jsxs("span",{className:"inline-flex items-center gap-1 px-2 py-1 bg-primary text-primary-foreground rounded text-sm",children:[u,a.jsx("button",{type:"button",onClick:()=>f(r),className:"hover:text-red-300 transition-colors",children:a.jsx(ae,{className:"h-3 w-3"})})]},r)),a.jsx("input",{type:"text",value:c,onChange:u=>g(u.target.value),onKeyDown:b,className:"flex-1 outline-none min-w-[100px] bg-transparent text-sm",placeholder:m||e("enterTag")})]})}const U=[{value:"pairing",label:"pairing"},{value:"allowlist",label:"allowlist"},{value:"open",label:"open"},{value:"disabled",label:"disabled"}],E=[{value:"open",label:"open"},{value:"allowlist",label:"allowlist"},{value:"disabled",label:"disabled"}],Oe=[{value:"off",label:"off"},{value:"partial",label:"partial"},{value:"block",label:"block"},{value:"progress",label:"progress"}],$e=n=>n.includes("token")||n.includes("secret")||n.includes("password")?a.jsx(te,{className:"h-3.5 w-3.5 text-gray-500"}):n.includes("url")||n.includes("host")?a.jsx(ne,{className:"h-3.5 w-3.5 text-gray-500"}):n.includes("email")||n.includes("mail")?a.jsx(M,{className:"h-3.5 w-3.5 text-gray-500"}):n.includes("id")||n.includes("from")?a.jsx(le,{className:"h-3.5 w-3.5 text-gray-500"}):n==="enabled"||n==="consentGranted"?a.jsx(se,{className:"h-3.5 w-3.5 text-gray-500"}):a.jsx(oe,{className:"h-3.5 w-3.5 text-gray-500"});function B(){return{telegram:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"token",type:"password",label:e("botToken")},{name:"allowFrom",type:"tags",label:e("allowFrom")},{name:"proxy",type:"text",label:e("proxy")},{name:"accountId",type:"text",label:e("accountId")},{name:"dmPolicy",type:"select",label:e("dmPolicy"),options:U},{name:"groupPolicy",type:"select",label:e("groupPolicy"),options:E},{name:"groupAllowFrom",type:"tags",label:e("groupAllowFrom")},{name:"requireMention",type:"boolean",label:e("requireMention")},{name:"mentionPatterns",type:"tags",label:e("mentionPatterns")},{name:"groups",type:"json",label:e("groupRulesJson")}],discord:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"token",type:"password",label:e("botToken")},{name:"allowBots",type:"boolean",label:e("allowBotMessages")},{name:"allowFrom",type:"tags",label:e("allowFrom")},{name:"gatewayUrl",type:"text",label:e("gatewayUrl")},{name:"intents",type:"number",label:e("intents")},{name:"proxy",type:"text",label:e("proxy")},{name:"mediaMaxMb",type:"number",label:e("attachmentMaxSizeMb")},{name:"streaming",type:"select",label:e("streamingMode"),options:Oe},{name:"draftChunk",type:"json",label:e("draftChunkingJson")},{name:"textChunkLimit",type:"number",label:e("textChunkLimit")},{name:"accountId",type:"text",label:e("accountId")},{name:"dmPolicy",type:"select",label:e("dmPolicy"),options:U},{name:"groupPolicy",type:"select",label:e("groupPolicy"),options:E},{name:"groupAllowFrom",type:"tags",label:e("groupAllowFrom")},{name:"requireMention",type:"boolean",label:e("requireMention")},{name:"mentionPatterns",type:"tags",label:e("mentionPatterns")},{name:"groups",type:"json",label:e("groupRulesJson")}],whatsapp:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"bridgeUrl",type:"text",label:e("bridgeUrl")},{name:"allowFrom",type:"tags",label:e("allowFrom")}],feishu:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"appId",type:"text",label:e("appId")},{name:"appSecret",type:"password",label:e("appSecret")},{name:"encryptKey",type:"password",label:e("encryptKey")},{name:"verificationToken",type:"password",label:e("verificationToken")},{name:"allowFrom",type:"tags",label:e("allowFrom")}],dingtalk:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"clientId",type:"text",label:e("clientId")},{name:"clientSecret",type:"password",label:e("clientSecret")},{name:"allowFrom",type:"tags",label:e("allowFrom")}],wecom:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"corpId",type:"text",label:e("corpId")},{name:"agentId",type:"text",label:e("agentId")},{name:"secret",type:"password",label:e("secret")},{name:"token",type:"password",label:e("token")},{name:"callbackPort",type:"number",label:e("callbackPort")},{name:"callbackPath",type:"text",label:e("callbackPath")},{name:"allowFrom",type:"tags",label:e("allowFrom")}],slack:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"mode",type:"text",label:e("mode")},{name:"webhookPath",type:"text",label:e("webhookPath")},{name:"allowBots",type:"boolean",label:e("allowBotMessages")},{name:"botToken",type:"password",label:e("botToken")},{name:"appToken",type:"password",label:e("appToken")}],email:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"consentGranted",type:"boolean",label:e("consentGranted")},{name:"imapHost",type:"text",label:e("imapHost")},{name:"imapPort",type:"number",label:e("imapPort")},{name:"imapUsername",type:"text",label:e("imapUsername")},{name:"imapPassword",type:"password",label:e("imapPassword")},{name:"fromAddress",type:"email",label:e("fromAddress")}],mochat:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"baseUrl",type:"text",label:e("baseUrl")},{name:"clawToken",type:"password",label:e("clawToken")},{name:"agentUserId",type:"text",label:e("agentUserId")},{name:"allowFrom",type:"tags",label:e("allowFrom")}],qq:[{name:"enabled",type:"boolean",label:e("enabled")},{name:"appId",type:"text",label:e("appId")},{name:"secret",type:"password",label:e("appSecret")},{name:"markdownSupport",type:"boolean",label:e("markdownSupport")},{name:"allowFrom",type:"tags",label:e("allowFrom")}]}}const O={telegram:S,slack:S,email:M,default:S},$={telegram:"from-primary-300 to-primary-600",slack:"from-primary-200 to-primary-500",email:"from-primary-100 to-primary-400",default:"from-gray-300 to-gray-500"};function I(n){return typeof n=="object"&&n!==null&&!Array.isArray(n)}function J(n,d){const i={...n};for(const[m,c]of Object.entries(d)){const g=i[m];if(I(g)&&I(c)){i[m]=J(g,c);continue}i[m]=c}return i}function Re(n,d){const i=n.split("."),m={};let c=m;for(let g=0;g<i.length-1;g+=1){const b=i[g];c[b]={},c=c[b]}return c[i[i.length-1]]=d,m}function He(){var A,L;const{channelModal:n,closeChannelModal:d}=G(),{data:i}=K(),{data:m}=_(),c=me(),g=pe(),[b,f]=v.useState({}),[u,r]=v.useState({}),[y,h]=v.useState(null),o=n.channel,w=o?i==null?void 0:i.channels[o]:null,k=o?B()[o]??[]:[],C=m==null?void 0:m.uiHints,P=o?`channels.${o}`:null,z=((A=m==null?void 0:m.actions)==null?void 0:A.filter(t=>t.scope===P))??[],V=o&&(((L=T(`channels.${o}`,C))==null?void 0:L.label)??o);v.useEffect(()=>{if(w){f({...w});const t={};(o?B()[o]??[]:[]).filter(s=>s.type==="json").forEach(s=>{const x=w[s.name];t[s.name]=JSON.stringify(x??{},null,2)}),r(t)}else f({}),r({})},[w,o]);const j=(t,l)=>{f(s=>({...s,[t]:l}))},Y=t=>{if(t.preventDefault(),!o)return;const l={...b};for(const s of k){if(s.type!=="password")continue;const x=l[s.name];(typeof x!="string"||x.length===0)&&delete l[s.name]}for(const s of k){if(s.type!=="json")continue;const x=u[s.name]??"";try{l[s.name]=x.trim()?JSON.parse(x):{}}catch{N.error(`${e("invalidJson")}: ${s.name}`);return}}c.mutate({channel:o,data:l},{onSuccess:()=>d()})},W=t=>{if(!t||!o)return;const l=t.channels;if(!I(l))return;const s=l[o];I(s)&&f(x=>J(x,s))},X=async t=>{if(!(!o||!P)){h(t.id);try{let l={...b};t.saveBeforeRun&&(l={...l,...t.savePatch??{}},f(l),await c.mutateAsync({channel:o,data:l}));const s=await g.mutateAsync({actionId:t.id,data:{scope:P,draftConfig:Re(P,l)}});W(s.patch),s.ok?N.success(s.message||e("success")):N.error(s.message||e("error"))}catch(l){const s=l instanceof Error?l.message:String(l);N.error(`${e("error")}: ${s}`)}finally{h(null)}}},Q=O[o||""]||O.default,Z=$[o||""]||$.default;return a.jsx(he,{open:n.open,onOpenChange:d,children:a.jsxs(fe,{className:"sm:max-w-[550px] max-h-[85vh] overflow-hidden flex flex-col",children:[a.jsx(we,{children:a.jsxs("div",{className:"flex items-center gap-3",children:[a.jsx("div",{className:`h-10 w-10 rounded-xl bg-gradient-to-br ${Z} flex items-center justify-center`,children:a.jsx(Q,{className:"h-5 w-5 text-white"})}),a.jsxs("div",{children:[a.jsx(je,{className:"capitalize",children:V}),a.jsx(ve,{children:e("configureMessageChannelParameters")})]})]})}),a.jsxs("form",{onSubmit:Y,className:"flex flex-col flex-1 overflow-hidden",children:[a.jsx("div",{className:"flex-1 overflow-y-auto custom-scrollbar py-2 pr-2 space-y-5",children:k.map(t=>{const l=o?T(`channels.${o}.${t.name}`,C):void 0,s=(l==null?void 0:l.label)??t.label,x=l==null?void 0:l.placeholder;return a.jsxs("div",{className:"space-y-2.5",children:[a.jsxs(Ne,{htmlFor:t.name,className:"text-sm font-medium text-gray-900 flex items-center gap-2",children:[$e(t.name),s]}),t.type==="boolean"&&a.jsxs("div",{className:"flex items-center justify-between p-3 rounded-xl bg-gray-50",children:[a.jsx("span",{className:"text-sm text-gray-500",children:b[t.name]?e("enabled"):e("disabled")}),a.jsx(Se,{id:t.name,checked:b[t.name]||!1,onCheckedChange:p=>j(t.name,p),className:"data-[state=checked]:bg-emerald-500"})]}),(t.type==="text"||t.type==="email")&&a.jsx(D,{id:t.name,type:t.type,value:b[t.name]||"",onChange:p=>j(t.name,p.target.value),placeholder:x,className:"rounded-xl"}),t.type==="password"&&a.jsx(D,{id:t.name,type:"password",value:b[t.name]||"",onChange:p=>j(t.name,p.target.value),placeholder:x??e("leaveBlankToKeepUnchanged"),className:"rounded-xl"}),t.type==="number"&&a.jsx(D,{id:t.name,type:"number",value:b[t.name]||0,onChange:p=>j(t.name,parseInt(p.target.value)||0),placeholder:x,className:"rounded-xl"}),t.type==="tags"&&a.jsx(Be,{value:b[t.name]||[],onChange:p=>j(t.name,p)}),t.type==="select"&&a.jsxs(be,{value:b[t.name]||"",onValueChange:p=>j(t.name,p),children:[a.jsx(ue,{className:"rounded-xl",children:a.jsx(ye,{})}),a.jsx(ge,{children:(t.options??[]).map(p=>a.jsx(xe,{value:p.value,children:p.label},p.value))})]}),t.type==="json"&&a.jsx("textarea",{id:t.name,value:u[t.name]??"{}",onChange:p=>r(ee=>({...ee,[t.name]:p.target.value})),className:"min-h-[120px] w-full rounded-lg border border-gray-200 bg-white px-3 py-2 text-xs font-mono"})]},t.name)})}),a.jsxs(ke,{className:"pt-4 flex-shrink-0",children:[a.jsx(F,{type:"button",variant:"outline",onClick:d,children:e("cancel")}),a.jsx(F,{type:"submit",disabled:c.isPending||!!y,children:c.isPending?e("saving"):e("save")}),z.filter(t=>t.trigger==="manual").map(t=>a.jsx(F,{type:"button",onClick:()=>X(t),disabled:c.isPending||!!y,variant:"secondary",children:y===t.id?e("connecting"):t.title},t.id))]})]})]})})}const R={telegram:S,slack:ce,email:M,webhook:re,default:H},Ke={telegram:"channelDescTelegram",slack:"channelDescSlack",email:"channelDescEmail",webhook:"channelDescWebhook",discord:"channelDescDiscord",feishu:"channelDescFeishu"};function Ze(){const{data:n}=K(),{data:d}=de(),{data:i}=_(),{openChannelModal:m}=G(),[c,g]=v.useState("active"),b=i==null?void 0:i.uiHints;if(!n||!d)return a.jsx("div",{className:"p-8 text-gray-400",children:e("channelsLoading")});const f=[{id:"active",label:e("channelsTabEnabled"),count:d.channels.filter(r=>{var y;return(y=n.channels[r.name])==null?void 0:y.enabled}).length},{id:"all",label:e("channelsTabAll"),count:d.channels.length}],u=d.channels.filter(r=>{var h;const y=((h=n.channels[r.name])==null?void 0:h.enabled)||!1;return c==="all"||y});return a.jsxs(Ce,{children:[a.jsx(Pe,{title:e("channelsPageTitle")}),a.jsx(Ie,{tabs:f,activeTab:c,onChange:g}),a.jsx("div",{className:"grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4",children:u.map(r=>{const y=n.channels[r.name],h=(y==null?void 0:y.enabled)||!1,o=R[r.name]||R.default,w=T(`channels.${r.name}`,b),k=(w==null?void 0:w.help)||e(Ke[r.name]||"channelDescriptionDefault");return a.jsxs(De,{onClick:()=>m(r.name),children:[a.jsxs(Fe,{children:[a.jsx(Te,{name:r.name,src:Me(r.name),className:q("h-11 w-11 rounded-xl border transition-all",h?"bg-white border-primary/30":"bg-white border-gray-200/60 group-hover:border-gray-300"),imgClassName:"h-5 w-5",fallback:a.jsx(o,{className:"h-5 w-5"})}),a.jsx(Ae,{status:h?"active":"inactive",label:h?e("statusActive"):e("statusInactive")})]}),a.jsx(Le,{title:r.displayName||r.name,description:k}),a.jsxs(Ue,{children:[a.jsx(Ee,{label:h?e("actionConfigure"):e("actionEnable")}),r.tutorialUrl&&a.jsx("a",{href:r.tutorialUrl,target:"_blank",rel:"noreferrer",onClick:C=>C.stopPropagation(),className:"flex items-center justify-center h-6 w-6 rounded-md text-gray-300 hover:text-gray-500 hover:bg-gray-100/60 transition-colors",title:e("channelsGuideTitle"),children:a.jsx(ie,{className:"h-3.5 w-3.5"})})]})]},r.name)})}),u.length===0&&a.jsxs("div",{className:"flex flex-col items-center justify-center py-16 text-center",children:[a.jsx("div",{className:"h-14 w-14 flex items-center justify-center rounded-xl bg-gray-100/80 mb-4",children:a.jsx(H,{className:"h-6 w-6 text-gray-300"})}),a.jsx("h3",{className:"text-[14px] font-semibold text-gray-900 mb-1.5",children:e("channelsEmptyTitle")}),a.jsx("p",{className:"text-[13px] text-gray-400 max-w-sm",children:e("channelsEmptyDescription")})]}),a.jsx(He,{})]})}export{Ze as ChannelsList};