shennian 0.5.4 → 0.5.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -511,8 +511,8 @@
|
|
|
511
511
|
},
|
|
512
512
|
{
|
|
513
513
|
"file": "src/daemon-ipc/control.js",
|
|
514
|
-
"beforeBytes":
|
|
515
|
-
"afterBytes":
|
|
514
|
+
"beforeBytes": 4433,
|
|
515
|
+
"afterBytes": 2484
|
|
516
516
|
},
|
|
517
517
|
{
|
|
518
518
|
"file": "src/daemon-ipc/json.js",
|
|
@@ -576,8 +576,8 @@
|
|
|
576
576
|
},
|
|
577
577
|
{
|
|
578
578
|
"file": "src/index.js",
|
|
579
|
-
"beforeBytes":
|
|
580
|
-
"afterBytes":
|
|
579
|
+
"beforeBytes": 43017,
|
|
580
|
+
"afterBytes": 21364
|
|
581
581
|
},
|
|
582
582
|
{
|
|
583
583
|
"file": "src/log-redaction.js",
|
|
@@ -1021,8 +1021,8 @@
|
|
|
1021
1021
|
},
|
|
1022
1022
|
{
|
|
1023
1023
|
"file": "src/session/handlers/room-managed.js",
|
|
1024
|
-
"beforeBytes":
|
|
1025
|
-
"afterBytes":
|
|
1024
|
+
"beforeBytes": 5106,
|
|
1025
|
+
"afterBytes": 2698
|
|
1026
1026
|
},
|
|
1027
1027
|
{
|
|
1028
1028
|
"file": "src/session/handlers/session-refresh.js",
|
|
@@ -1061,8 +1061,8 @@
|
|
|
1061
1061
|
},
|
|
1062
1062
|
{
|
|
1063
1063
|
"file": "src/session/manager.js",
|
|
1064
|
-
"beforeBytes":
|
|
1065
|
-
"afterBytes":
|
|
1064
|
+
"beforeBytes": 41108,
|
|
1065
|
+
"afterBytes": 21675
|
|
1066
1066
|
},
|
|
1067
1067
|
{
|
|
1068
1068
|
"file": "src/session/native-cleanup-outbox.js",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import o from"node:fs";import{getAcpLocalMetrics as
|
|
1
|
+
import o from"node:fs";import{getAcpLocalMetrics as g}from"../agents/acp/metrics.js";const u=["protocol.info","daemon.status","agent.list","agent.discover","agent.check","room.agent.bind-managed","agent.auth.completed","log.read","upgrade.start","upgrade.prepare-external","upgrade.cancel-external"],m=32*1024,y=64*1024;function _(t){return{"protocol.info":()=>{const e=t.getStatus();return{daemonVersion:t.daemonVersion,protocolVersion:t.protocolVersion,launcher:e.launcher,capabilities:[...u]}},"daemon.status":()=>t.getStatus(),"agent.list":()=>({agents:t.getAgents().map(e=>({type:e.type,...e.version?{version:e.version}:{},...e.runtimePlatform?{runtimePlatform:e.runtimePlatform}:{},...e.runtimeIsWsl!==void 0?{runtimeIsWsl:e.runtimeIsWsl}:{}})),acpMetrics:g()}),"agent.auth.completed":async e=>{const n=e&&typeof e=="object"&&!Array.isArray(e)&&typeof e.agentType=="string"?e.agentType:"";if(!/^acp:[a-z0-9][a-z0-9._-]{0,63}$/.test(n))throw new Error("invalid_acp_agent");return{resumed:await t.completeAgentAuthentication?.(n)??!1}},"room.agent.bind-managed":async e=>{if(!e||typeof e!="object"||Array.isArray(e))throw new Error("invalid_managed_room_binding");if(!t.bindManagedRoom)throw new Error("managed_room_binding_unavailable");return t.bindManagedRoom(e)},"log.read":e=>p(t.getStatus().logFile,e),"upgrade.start":async e=>{if(!t.startUpgrade)throw new Error("upgrade_unavailable");return t.startUpgrade(e)},"upgrade.prepare-external":async e=>{if(!t.prepareExternalUpgrade)throw new Error("external_upgrade_unavailable");return t.prepareExternalUpgrade(e)},"upgrade.cancel-external":async()=>{if(!t.cancelExternalUpgrade)throw new Error("external_upgrade_unavailable");return t.cancelExternalUpgrade()}}}function p(t,e){const n=e&&typeof e=="object"&&!Array.isArray(e)?e:{},c=typeof n.limitBytes=="number"&&Number.isFinite(n.limitBytes)?n.limitBytes:m,d=Math.max(1,Math.min(Math.floor(c),y));let l=0;try{l=o.statSync(t).size}catch{return{text:"",start:0,end:0,nextBefore:null,eof:!0}}const f=typeof n.before=="number"&&Number.isFinite(n.before)?Math.floor(n.before):l,a=Math.max(0,Math.min(f,l)),r=Math.max(0,a-d);if(a===r)return{text:"",start:r,end:a,nextBefore:r>0?r:null,eof:r===0};const i=Buffer.allocUnsafe(a-r),s=o.openSync(t,"r");try{o.readSync(s,i,0,i.length,r)}finally{o.closeSync(s)}return{text:i.toString("utf8"),start:r,end:a,nextBefore:r>0?r:null,eof:r===0}}export{u as DAEMON_CONTROL_CAPABILITIES,_ as createDaemonControlHandlers,p as readDaemonLogPage};
|
package/dist/src/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
import{registerScheduleCommand as Se}from"./commands/schedule.js";import{resolvePersonalScheduleContext as ye}from"./schedules/personal-context.js";import{executeServerSchedule as oe,deliverServerSchedule as we}from"./schedules/server-client.js";import{Command as Ce}from"commander";import E from"chalk";import Re from"node:os";import G from"node:fs";import{loadConfig as p,saveConfig as be,getConfigPath as ke,getShennianDir as Pe,resolveShennianPath as W,normalizeAutoUpgradePolicy as Ae}from"./config/index.js";import{CliRelayClient as Ee}from"./relay/client.js";import{collectKnownLogSecrets as ne,installCliLogRedaction as Te,sanitizeCliLogValue as De}from"./log-redaction.js";import{registerPairCommand as Ue,runSmartStart as Me}from"./commands/pair.js";import{registerLogoutCommand as _e}from"./commands/logout.js";import{clearDaemonPidIfOwner as te,createDaemonInstanceId as Ne,clearDaemonLauncher as re,findRunningDaemonProcessIds as xe,isRemoteAccessDisabled as ae,prepareRemoteAccessPause as Oe,stopPreparedRemoteAccessService as $e,isIsolatedDaemonE2eInstance as Ve,getDaemonStatus as ie,registerDaemonCommand as Le,writeDaemonPid as se,writeDaemonLauncher as ce}from"./commands/daemon.js";import{registerRuntimeCommand as je}from"./commands/runtime.js";import{registerAdapterCommand as He}from"./commands/adapter.js";import{registerAgentCommand as Be}from"./commands/agent.js";import{registerManagerCommand as Fe}from"./commands/manager.js";import{registerWorkerCommand as Ge}from"./commands/worker.js";import{handleUpgradeStart as We,registerUpgradeCommand as ze}from"./commands/upgrade.js";import{registerToolsCommand as Je}from"./commands/tools.js";import{registerQueueCommand as Ke}from"./commands/queue.js";import{registerIntegrationCommand as qe}from"./commands/integration.js";import{registerRoomCommand as Qe}from"./commands/room.js";import{registerSupportCommand as Ye}from"./commands/support.js";import{SessionManager as Ze}from"./session/manager.js";import{createTrustedProjectFsRequestResolver as Xe}from"./session/handlers/project-fs.js";import{SERVERS as z,regionToUrl as eo,urlToRegion as oo}from"./region.js";import{clearUpgradeAttempt as no,getCurrentVersion as de,handleStartupCrashCheck as to,readUpgradeAttempt as ro}from"./upgrade/engine.js";import{AutoUpgradeScheduler as ao}from"./upgrade/scheduler.js";import{ensureUpdaterInstalled as io}from"./upgrade/updater-bootstrap.js";import{launchUpdater as so,markUpdaterHealthy as co}from"./upgrade/updater-launcher.js";import{detectAgents as lo}from"./agents/detect.js";import{augmentProcessPath as le}from"./env-path.js";import{acquireDaemonInstanceLock as mo}from"./commands/daemon-instance-lock.js";le();const O=de();import{getCachedAgentInfos as $,resolveAgentInfos as po}from"./agents/model-registry.js";import{initCliLogReporter as go,reportLog as T,reportUpgradeAggregateMetric as uo}from"./log-reporter.js";import{isNativeFusionEnabled as fo}from"./native-fusion/config.js";import{NativeSessionFusionService as ho}from"./native-fusion/service.js";import{startDaemonLogRetention as vo}from"./daemon-log.js";import{startDaemonIpcServer as me}from"./daemon-ipc/server.js";import{resolveDaemonIpcPaths as Io,resolveManagedRoomIpcPaths as So}from"./daemon-ipc/paths.js";import{createDaemonControlHandlers as yo}from"./daemon-ipc/control.js";import{createAgentReadinessHandlers as wo}from"./daemon-ipc/agent-readiness.js";import{scanMachineAgents as Co}from"./session/handlers/agents.js";import{validateAgentWorkspaceConfiguration as Ro}from"./session/handlers/agent-workspace-validation.js";import{DAEMON_IPC_VERSION as bo}from"./daemon-ipc/protocol.js";import{RoomSessionRegistry as ko}from"./room/session-registry.js";import{HttpRoomBindingClient as Po}from"./room/room-binding-client.js";import{TrustedManagedRoomBinder as Ao}from"./room/managed-room-binding.js";import{RoomHostSessionObservationStore as Eo}from"./room/host-session-observations.js";import{RoomMirrorSyncService as To}from"./room/mirror-sync-service.js";import{handleLiveRoomDelivery as Do}from"./room/live-delivery.js";import{NativeSourceDeletionStore as Uo}from"./native-fusion/native-source-deletions.js";import{matchesRoomOwner as Mo,isCurrentRegistration as _o}from"./room/registration-authority.js";import{RoomActivationService as No,resolveManagedAgentPolicy as xo}from"./room/activation-service.js";import{RoomActivationAudit as Oo}from"./room/activation-audit.js";import{RoomAttachmentCache as $o}from"./room/attachment-cache.js";import{RoomAttachmentUploader as Vo}from"./room/attachment-upload.js";import{ManagedRoomContextAuthority as Lo}from"./room/managed-context.js";import{createManagedRoomExecutor as jo}from"./room/managed-room-ipc.js";import{SESSION_SYNC_PROTOCOL_VERSION as pe,SESSION_SYNC_ADVERTISED_CAPABILITIES as ge}from"@shennian/wire";import{getDaemonInstallationId as Ho}from"./session/store.js";import{OWNER_DIRECT_TURN_OPTIONS as Bo}from"./session/queue-helpers.js";import{synchronizeMachinePersonalAuthority as Fo}from"./personal-sync/machine-authority.js";import{CLI_SESSION_SYNC_DATA_EPOCH as ue,ensurePersonalDataEpoch as Go}from"./personal-sync/epoch.js";import{DeletionSyncRetryWaitError as Wo,DeletionSyncTerminalError as zo}from"./session/deletion-sync-state.js";const fe=Pe(),Jo=W("daemon.pid"),Ko=W("daemon.instance.lock");function qo(){try{const a=G.readFileSync(Jo,"utf-8").trim();if(a.startsWith("{")){const g=JSON.parse(a),c=Number(g.pid);return Number.isInteger(c)&&c>0?c:null}const s=parseInt(a,10);return Number.isInteger(s)&&s>0?s:null}catch{return null}}function Qo(a){return a.replace(/^https:\/\//,"wss://").replace(/^http:\/\//,"ws://")}function J(){process.stdout.write(`${JSON.stringify({ok:!1,error:"integration_command_retired",message:"Room MCP and Hooks were retired. Use the Shennian Skill and CLI.",nextAction:{type:"open_install_guide",url:"https://shennian.net/install.md"}})}
|
|
2
|
-
`),process.exitCode=1}function Yo(a){const s=[`trigger=${a.trigger??"unknown"}`,`phase=${a.phase}`,`code=${a.code??"unknown"}`,`attempt=${a.reconnectAttempt}`];return a.reason&&s.push(`reason=${a.reason}`),a.error&&s.push(`error=${a.error}`),s.join(" ")}const i=new Ce;i.name("shennian").description("Shennian \u2014 AI Agent Control Plane").version(O),i.enablePositionalOptions(),qe(i),Qe(i),Ye(i),Se(i),i.option("--api <url>","Server URL override").option("--name <name>","Machine name",Re.hostname()).action(async a=>{const s=p(),g=a.api??process.env.SHENNIAN_DESKTOP_SERVER_URL??s.serverUrl??void 0;await Me(g,a.name)}),i.command("run-service",{hidden:!0}).description("(internal) Connect to relay server, called by the background service").option("--api <url>","Server URL override").action(async a=>{const s=W("env.json");try{const e=JSON.parse(G.readFileSync(s,"utf-8"));for(const[n,o]of Object.entries(e))process.env[n]||(process.env[n]=o);le()}catch{}Te(ne(process.env,p()));const g=vo();ae()&&(console.log(`[${new Date().toISOString()}] remote access disabled, service start skipped`),clearInterval(g),process.exit(0));const c=Ne(),w=mo({lockPath:Ko,instanceId:c});w.acquired||(console.log(`[${new Date().toISOString()}] daemon already running`+(w.ownerPid?` (PID ${w.ownerPid})`:"")+", skipping duplicate start"),clearInterval(g),process.exit(0));try{const e=qo();if(e&&e!==process.pid)try{process.kill(e,0),console.log(`[${new Date().toISOString()}] daemon already running (PID ${e}), skipping duplicate start`),w.release(),process.exit(0)}catch{}}catch{}const K=Ve(process.env,fe)?[]:xe(process.pid);K.length>0&&(console.log(`[${new Date().toISOString()}] daemon already running (PID ${K[0]}), skipping duplicate start`),w.release(),process.exit(0)),se(process.pid,c,{version:O}),ce(process.pid,void 0,c),process.on("exit",()=>{te(process.pid,c),re(c)}),process.on("exit",w.release);let V=null;try{V=io()}catch(e){console.error(`[upgrade] updater bootstrap unavailable: ${e instanceof Error?e.message:String(e)}`)}const D=await to();if(D){V||(console.error("[upgrade] Crash-loop rollback blocked: updater bootstrap unavailable"),process.exit(1));try{so({fromVersion:O,targetVersion:D.from,oldDaemonPid:process.pid,operation:"rollback",rollbackJobId:D.jobId},{readiness:V}),console.error(`[upgrade] New version crashed ${D.attemptCount} times; external rollback scheduled.`),process.stdin.resume();return}catch(e){console.error(`[upgrade] Crash-loop rollback could not start: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}}try{Go()}catch(e){console.error(`[personal-sync] data epoch initialization failed: ${e instanceof Error?e.message:String(e)}`),process.exitCode=1;return}const m=p(),u=a.api??process.env.SHENNIAN_DESKTOP_SERVER_URL??m.serverUrl??z.cn.url,h=de(),l=await lo({serverUrl:u,authToken:m.machineToken??m.accessToken}),C=l.map(e=>e.type),L=$(l),f=new ko,U=new Eo,R=new Lo(f),S=new Po(u),ve=new $o({actionClient:S}),Ie=new Vo({actionClient:S});let y=null,r;const q=jo({authority:R,actionClient:S,attachmentCache:ve,attachmentUploader:Ie,observations:U,getMachineCredentials:()=>({machineToken:p().machineToken}),managerExecutor:e=>r.executeManagedManagerAction(e),onSendOutcome:e=>r.noteManagedRoomSendOutcome(e),getActiveRunId:(e,n)=>r.getManagedRoomActiveRunId(e,n),scheduleExecutor:(e,n,o)=>oe({serverUrl:u,machineToken:p().machineToken,sessionId:e,action:n,args:o}),onPaused:({registryKey:e,sessionId:n})=>{const t=f.getByRegistryKey(e)?.binding;t&&f.setBinding({registryKey:e,bindingId:t.bindingId,roomId:t.roomId,agentIdentityId:t.agentIdentityId,agentMembershipId:t.agentMembershipId,status:"paused",activationMode:"paused"}),R.revokeSession(e),r?.discardPendingManagedRoomMessages(n)}});let j=null,H=null,B=null;const b=await me({paths:Io(),handlers:{...yo({daemonVersion:h,protocolVersion:bo,getStatus:()=>ie(),getAgents:()=>l,completeAgentAuthentication:e=>r.resumePendingAcpAuthentication(e),startUpgrade:async e=>{if(!j)throw new Error("upgrade_unavailable");return j(e)},prepareExternalUpgrade:e=>{if(!H)throw new Error("external_upgrade_unavailable");return H(e)},cancelExternalUpgrade:()=>{if(!B)throw new Error("external_upgrade_unavailable");return B()}}),...wo({getStatus:()=>ie(),getSnapshot:()=>$(l).map(e=>{const n=l.find(o=>o.type===e.type);return{...e,runtimePlatform:n?.runtimePlatform,runtimeIsWsl:n?.runtimeIsWsl}}),discover:async e=>{if(!r)throw new Error("daemon_starting");const n=await Co(!0,e);if(e){const t=l.filter(I=>I.type!==e);l.splice(0,l.length,...t,...n.detectedAgents)}else l.splice(0,l.length,...n.detectedAgents);const o=$(l);return d.sendEvent({type:"event",event:"machine.agents",payload:{agentList:l.map(t=>t.type),agents:o}}),n.agents.map(t=>{const I=n.detectedAgents.find(F=>F.type===t.type);return{...t,runtimePlatform:I?.runtimePlatform,runtimeIsWsl:I?.runtimeIsWsl}})},validate:async e=>{if(!r)throw new Error("daemon_starting");return Ro(e,{ignoreNativeSession:(n,o)=>P?.ignoreNativeSource(n,o)})}})}});let k;try{k=await me({paths:So(),handlers:{"managed-room.execute":e=>q(e),"schedule.personal":async e=>{const n=e,o=ye(n?.context);if(f.getByNianSessionId(o)?.binding)throw new Error("schedule_personal_context_required");return await oe({serverUrl:u,machineToken:p().machineToken,sessionId:o,action:n.operation,args:n})}}})}catch(e){throw await b.close(),e}let Q=!1;const M=()=>{Q||(Q=!0,Promise.allSettled([b.close(),k.close()]).finally(()=>process.exit(0)))};if(process.once("SIGINT",M),process.once("SIGTERM",M),!m.machineToken){console.error('Shennian CLI is not paired. Run "shennian pair --browser" or "shennian pair --token" first.'),await Promise.allSettled([b.close(),k.close()]),process.exitCode=1;return}process.removeListener("SIGINT",M),process.removeListener("SIGTERM",M);const Y=`${Qo(u)}/relay/machine`,_=m.machineToken;if(!_)return;try{await Fo({serverUrl:u,machineToken:_,machineId:m.machineId})}catch(e){console.error(`[personal-sync] machine authority verification failed: ${e instanceof Error?e.message:String(e)}`),await Promise.allSettled([b.close(),k.close()]),process.exit(1)}m.machineId&&go(u,m.machineId),console.log(`[${new Date().toISOString()}] Connecting to ${Y}... (v${h}) agents: ${C.join(",")}`),T({level:"info",wsEvent:"daemon.start",metadata:{version:h,agents:C}});let P=null,A=null,N=0,v=ro();const Z=Ae(m.autoUpgrade),d=new Ee({serverUrl:Y,machineToken:_,cliVersion:h,agentList:C,autoUpgradePolicy:Z,sessionSyncProtocolVersion:pe,sessionSyncCapabilities:ge,daemonInstallationId:Ho(),dataEpoch:ue,updaterProtocolVersion:1,onConnected:()=>{console.log(`[${new Date().toISOString()}] \u2713 Connected`),T({level:"info",wsEvent:"daemon.connected"}),L.some(o=>o.models.length>0)&&d.sendEvent({type:"event",event:"machine.agents",payload:{agentList:C,agents:L}}),po(l,{serverUrl:m.serverUrl??u,authToken:m.machineToken??m.accessToken}).then(o=>{JSON.stringify(o)!==JSON.stringify(L)&&d.sendEvent({type:"event",event:"machine.agents",payload:{agentList:C,agents:o}})}).catch(()=>{}),v&&d.sendEvent({type:"event",event:"upgrade",payload:{state:"recovering",machineId:"self",from:v.from,to:v.to,...v.jobId?{jobId:v.jobId}:{},activeRunCount:r.getPendingRecoveryCount()}}),x.start(),A?.start();const e=++N,n=async()=>{try{if(await r.synchronizeSessionDeletions(),await r.recoverInterruptedRuns(),v){const o=v;v=null,o.jobId&&co(o.jobId,o.to),no(),console.log(`[${new Date().toISOString()}] [upgrade] ${o.operation==="rollback"?"Rolled back":"Healthy"}: ${o.from} \u2192 ${o.to}`),uo({kind:"upgrade",result:o.operation==="rollback"?"rolled_back":"healthy",stage:"terminal"}),d.sendEvent({type:"event",event:"upgrade",payload:{state:o.operation==="rollback"?"rolled_back":"healthy",machineId:"self",from:o.from,to:o.to,...o.jobId?{jobId:o.jobId}:{}}}),o.operation!=="rollback"&&d.sendEvent({type:"event",event:"upgrade",payload:{state:"success",machineId:"self",from:o.from,to:o.to}})}e===N&&d.getState()==="connected"&&P?.handleConnected()}catch(o){if(console.error("[session.deletions] startup catch-up failed",o),e===N&&d.getState()==="connected"){if(o instanceof zo)return;const t=o instanceof Wo?Math.max(1e3,o.retryAfterMs):5e3;setTimeout(()=>{n()},t).unref?.()}}};n()},onDisconnected:e=>{N+=1,r?.revokeProjectFsHandles(),A?.stop(),console.log(`[${new Date().toISOString()}] \u26A0 Disconnected, reconnecting... ${Yo(e)}`),T({level:"warn",wsEvent:"daemon.disconnected",metadata:{code:e.code,reason:e.reason,error:e.error,phase:e.phase,trigger:e.trigger,reconnectAttempt:e.reconnectAttempt}})},onProjectFsCapabilityChanged:e=>{e||r?.revokeProjectFsHandles()},onReq:e=>{if(console.log(`[${new Date().toISOString()}] [req] ${e.method}`),T({level:"info",type:"ws",wsEvent:e.method,wsDirection:"in",traceId:e.traceId}),e.method==="room.message.deliver"){Do(d,A,e);return}r.handleReq(e)}});P=fo()?new ho(d):null,A=new To({registry:f,observations:U,actionClient:S,getMachineCredentials:()=>({machineToken:p().machineToken}),isSessionDeleted:e=>new Uo().hasSession(e),onMessages:async(e,n,o,t)=>{await y?.processMessages(e,n,o,t)},onBindingPaused:e=>{e.lifecycleState==="closed"?(R.revokeSession(e.registryKey),r?.retireManagedRoomSession(e.nianSessionId).catch(()=>{console.warn("[room.sync] retired session cleanup failed")})):r?.discardPendingManagedRoomMessages(e.nianSessionId)}});const x=new ao({currentVersion:h,machineId:m.machineId??"unknown-machine",serverUrl:m.serverUrl??u,getIdleState:()=>r.getUpgradeIdleState(),sessionSyncProtocolVersion:pe,dataEpoch:ue,advertisedCapabilities:ge,updaterProtocolVersion:1,startUpgrade:async(e,n)=>{const{handleUpgradeStart:o}=await import("./commands/upgrade.js");await o(d,"auto-upgrade",e,{currentVersion:h,prepareForUpgrade:t=>r.prepareForUpgrade(t),cancelUpgradePreparation:()=>r.cancelUpgradePreparation(),shutdownAfterHandoff:()=>{setTimeout(()=>process.kill(process.pid,"SIGTERM"),100).unref?.()},suppressResponse:!0,waitForCompletion:!0,canHandoff:n?void 0:()=>r.getUpgradeIdleState().idle})}});x.setPolicy(Z),r=new Ze(d,P,h,x,new Ao({registry:f,observations:U,bindingClient:S,getMachineCredentials:()=>{const e=p();return{machineId:e.machineId,machineToken:e.machineToken}},hostProcessIdentity:()=>`daemon:${c}`}),{prepare:()=>Oe(),isDisabled:()=>ae(),shutdownAfterResponse:()=>{setTimeout(()=>{$e(),process.kill(process.pid,"SIGTERM")},100).unref?.()}},e=>R.revokeToken(e),q,null,Xe(_),()=>$(l)),j=async e=>{const n=e&&typeof e=="object"&&!Array.isArray(e)?e:{},o=typeof n.targetVersion=="string"?n.targetVersion:void 0,t=n.confirmedMajor===!0;return await We(d,`local-upgrade-${Date.now()}`,o,{currentVersion:h,confirmedMajor:t,prepareForUpgrade:F=>r.prepareForUpgrade(F),cancelUpgradePreparation:()=>r.cancelUpgradePreparation(),shutdownAfterHandoff:()=>{setTimeout(()=>process.kill(process.pid,"SIGTERM"),100).unref?.()},suppressResponse:!0})},H=e=>{const n=e&&typeof e=="object"&&!Array.isArray(e)?e:{},t=`desktop-${(typeof n.targetVersion=="string"?n.targetVersion:"unknown").replace(/[^A-Za-z0-9._-]/g,"_")}-${Date.now()}`;return{jobId:t,...r.prepareForUpgrade(t)}},B=()=>(r.cancelUpgradePreparation(),{cancelled:!0}),y=new No({registry:f,observations:U,enqueueConversationBatch:e=>r.enqueueManagedRoomBatch(e),loadContext:async e=>{const n=p().machineToken?.trim(),o=e.binding;if(!n||!o)throw new Error("managed_room_context_unavailable");const t=await S.status({machineToken:n,roomId:o.roomId,bindingId:o.bindingId});if(!_o(f,e)||!Mo(e,t))throw new Error("managed_room_binding_unavailable");return{roomName:t.room.name,memberCount:t.room.memberCount,members:t.room.members,agentsByIdentityId:t.agent?{[t.agentIdentityId]:t.agent}:{},effectiveModelsBySessionId:t.effectiveModelId!==void 0?{[e.nianSessionId]:t.effectiveModelId}:void 0,agentSystemPromptsByIdentityId:t.agent?{[t.agentIdentityId]:t.agent.systemPrompt??""}:{}}},issueManagedRoomContext:(e,n,o,t)=>{const I=p().machineToken;if(!I)throw new Error("machine_not_authorized");return R.issue({registryKey:e,machineCredential:I,activationCauseMessageId:n,allowedActions:o,propagateWorkerRoomOrigin:t})},audit:new Oo,resolveManagedAgentPolicy:e=>xo({...e,runtime:l.find(n=>n.type===e.registration.runtimeAdapter)})}),r.scheduleHandler=e=>we({serverUrl:u,machineToken:p().machineToken,req:e,client:d,queue:r.getScheduleQueue(),registry:f}),r.getScheduleQueue().validateScheduledTarget=async e=>{if(!e.bindingId||!e.roomId)return"ready";if(f.getByNianSessionId(e.sessionId)?.binding?.bindingId!==e.bindingId)return"ended";const o=await S.status({machineToken:p().machineToken,roomId:e.roomId,bindingId:e.bindingId});return o.status==="active"&&o.room.status==="active"?"ready":"ended"},r.setManagedRoomTurnPreparer(e=>y.prepareConversationTurn(e)),r.setManagedAgentDirectTurnPreparer((e,n)=>y.prepareDirectConversationTurn(e,n)),r.setManagedRecoveryPreparer(async e=>e.source==="managed_direct"?y.prepareDirectConversationTurn(e.sessionId,Bo):e.source==="manager_event"?y.prepareDirectConversationTurn(e.sessionId,{allowedRoomActions:[],managerEvent:!0}):e.source!=="managed_room"||!e.roomContextRegistryKey||!e.activationCauseMessageId||!e.rootCauseMessageId||!e.activationSequence||e.activationHopCount===null?null:y.prepareConversationTurn([{registryKey:e.roomContextRegistryKey,causeMessageId:e.activationCauseMessageId,rootCauseMessageId:e.rootCauseMessageId,sequence:e.activationSequence,hopCount:e.activationHopCount}])),G.mkdirSync(fe,{recursive:!0}),se(process.pid,c,{version:h}),ce(process.pid,void 0,c),d.connect(),process.stdin.resume();let X=!1;const ee=async()=>{if(!X){X=!0,console.log(E.gray(`
|
|
2
|
+
`),process.exitCode=1}function Yo(a){const s=[`trigger=${a.trigger??"unknown"}`,`phase=${a.phase}`,`code=${a.code??"unknown"}`,`attempt=${a.reconnectAttempt}`];return a.reason&&s.push(`reason=${a.reason}`),a.error&&s.push(`error=${a.error}`),s.join(" ")}const i=new Ce;i.name("shennian").description("Shennian \u2014 AI Agent Control Plane").version(O),i.enablePositionalOptions(),qe(i),Qe(i),Ye(i),Se(i),i.option("--api <url>","Server URL override").option("--name <name>","Machine name",Re.hostname()).action(async a=>{const s=p(),g=a.api??process.env.SHENNIAN_DESKTOP_SERVER_URL??s.serverUrl??void 0;await Me(g,a.name)}),i.command("run-service",{hidden:!0}).description("(internal) Connect to relay server, called by the background service").option("--api <url>","Server URL override").action(async a=>{const s=W("env.json");try{const e=JSON.parse(G.readFileSync(s,"utf-8"));for(const[n,o]of Object.entries(e))process.env[n]||(process.env[n]=o);le()}catch{}Te(ne(process.env,p()));const g=vo();ae()&&(console.log(`[${new Date().toISOString()}] remote access disabled, service start skipped`),clearInterval(g),process.exit(0));const c=Ne(),w=mo({lockPath:Ko,instanceId:c});w.acquired||(console.log(`[${new Date().toISOString()}] daemon already running`+(w.ownerPid?` (PID ${w.ownerPid})`:"")+", skipping duplicate start"),clearInterval(g),process.exit(0));try{const e=qo();if(e&&e!==process.pid)try{process.kill(e,0),console.log(`[${new Date().toISOString()}] daemon already running (PID ${e}), skipping duplicate start`),w.release(),process.exit(0)}catch{}}catch{}const K=Ve(process.env,fe)?[]:xe(process.pid);K.length>0&&(console.log(`[${new Date().toISOString()}] daemon already running (PID ${K[0]}), skipping duplicate start`),w.release(),process.exit(0)),se(process.pid,c,{version:O}),ce(process.pid,void 0,c),process.on("exit",()=>{te(process.pid,c),re(c)}),process.on("exit",w.release);let V=null;try{V=io()}catch(e){console.error(`[upgrade] updater bootstrap unavailable: ${e instanceof Error?e.message:String(e)}`)}const D=await to();if(D){V||(console.error("[upgrade] Crash-loop rollback blocked: updater bootstrap unavailable"),process.exit(1));try{so({fromVersion:O,targetVersion:D.from,oldDaemonPid:process.pid,operation:"rollback",rollbackJobId:D.jobId},{readiness:V}),console.error(`[upgrade] New version crashed ${D.attemptCount} times; external rollback scheduled.`),process.stdin.resume();return}catch(e){console.error(`[upgrade] Crash-loop rollback could not start: ${e instanceof Error?e.message:String(e)}`),process.exit(1)}}try{Go()}catch(e){console.error(`[personal-sync] data epoch initialization failed: ${e instanceof Error?e.message:String(e)}`),process.exitCode=1;return}const m=p(),u=a.api??process.env.SHENNIAN_DESKTOP_SERVER_URL??m.serverUrl??z.cn.url,h=de(),l=await lo({serverUrl:u,authToken:m.machineToken??m.accessToken}),C=l.map(e=>e.type),L=$(l),f=new ko,U=new Eo,R=new Lo(f),S=new Po(u),ve=new $o({actionClient:S}),Ie=new Vo({actionClient:S});let y=null,r;const q=jo({authority:R,actionClient:S,attachmentCache:ve,attachmentUploader:Ie,observations:U,getMachineCredentials:()=>({machineToken:p().machineToken}),managerExecutor:e=>r.executeManagedManagerAction(e),onSendOutcome:e=>r.noteManagedRoomSendOutcome(e),getActiveRunId:(e,n)=>r.getManagedRoomActiveRunId(e,n),scheduleExecutor:(e,n,o)=>oe({serverUrl:u,machineToken:p().machineToken,sessionId:e,action:n,args:o}),onPaused:({registryKey:e,sessionId:n})=>{const t=f.getByRegistryKey(e)?.binding;t&&f.setBinding({registryKey:e,bindingId:t.bindingId,roomId:t.roomId,agentIdentityId:t.agentIdentityId,agentMembershipId:t.agentMembershipId,status:"paused",activationMode:"paused"}),R.revokeSession(e),r?.discardPendingManagedRoomMessages(n)}});let j=null,H=null,B=null;const b=await me({paths:Io(),handlers:{...yo({daemonVersion:h,protocolVersion:bo,getStatus:()=>ie(),getAgents:()=>l,completeAgentAuthentication:e=>r.resumePendingAcpAuthentication(e),bindManagedRoom:e=>r.bindManagedRoomFromLocal(e),startUpgrade:async e=>{if(!j)throw new Error("upgrade_unavailable");return j(e)},prepareExternalUpgrade:e=>{if(!H)throw new Error("external_upgrade_unavailable");return H(e)},cancelExternalUpgrade:()=>{if(!B)throw new Error("external_upgrade_unavailable");return B()}}),...wo({getStatus:()=>ie(),getSnapshot:()=>$(l).map(e=>{const n=l.find(o=>o.type===e.type);return{...e,runtimePlatform:n?.runtimePlatform,runtimeIsWsl:n?.runtimeIsWsl}}),discover:async e=>{if(!r)throw new Error("daemon_starting");const n=await Co(!0,e);if(e){const t=l.filter(I=>I.type!==e);l.splice(0,l.length,...t,...n.detectedAgents)}else l.splice(0,l.length,...n.detectedAgents);const o=$(l);return d.sendEvent({type:"event",event:"machine.agents",payload:{agentList:l.map(t=>t.type),agents:o}}),n.agents.map(t=>{const I=n.detectedAgents.find(F=>F.type===t.type);return{...t,runtimePlatform:I?.runtimePlatform,runtimeIsWsl:I?.runtimeIsWsl}})},validate:async e=>{if(!r)throw new Error("daemon_starting");return Ro(e,{ignoreNativeSession:(n,o)=>P?.ignoreNativeSource(n,o)})}})}});let k;try{k=await me({paths:So(),handlers:{"managed-room.execute":e=>q(e),"schedule.personal":async e=>{const n=e,o=ye(n?.context);if(f.getByNianSessionId(o)?.binding)throw new Error("schedule_personal_context_required");return await oe({serverUrl:u,machineToken:p().machineToken,sessionId:o,action:n.operation,args:n})}}})}catch(e){throw await b.close(),e}let Q=!1;const M=()=>{Q||(Q=!0,Promise.allSettled([b.close(),k.close()]).finally(()=>process.exit(0)))};if(process.once("SIGINT",M),process.once("SIGTERM",M),!m.machineToken){console.error('Shennian CLI is not paired. Run "shennian pair --browser" or "shennian pair --token" first.'),await Promise.allSettled([b.close(),k.close()]),process.exitCode=1;return}process.removeListener("SIGINT",M),process.removeListener("SIGTERM",M);const Y=`${Qo(u)}/relay/machine`,_=m.machineToken;if(!_)return;try{await Fo({serverUrl:u,machineToken:_,machineId:m.machineId})}catch(e){console.error(`[personal-sync] machine authority verification failed: ${e instanceof Error?e.message:String(e)}`),await Promise.allSettled([b.close(),k.close()]),process.exit(1)}m.machineId&&go(u,m.machineId),console.log(`[${new Date().toISOString()}] Connecting to ${Y}... (v${h}) agents: ${C.join(",")}`),T({level:"info",wsEvent:"daemon.start",metadata:{version:h,agents:C}});let P=null,A=null,N=0,v=ro();const Z=Ae(m.autoUpgrade),d=new Ee({serverUrl:Y,machineToken:_,cliVersion:h,agentList:C,autoUpgradePolicy:Z,sessionSyncProtocolVersion:pe,sessionSyncCapabilities:ge,daemonInstallationId:Ho(),dataEpoch:ue,updaterProtocolVersion:1,onConnected:()=>{console.log(`[${new Date().toISOString()}] \u2713 Connected`),T({level:"info",wsEvent:"daemon.connected"}),L.some(o=>o.models.length>0)&&d.sendEvent({type:"event",event:"machine.agents",payload:{agentList:C,agents:L}}),po(l,{serverUrl:m.serverUrl??u,authToken:m.machineToken??m.accessToken}).then(o=>{JSON.stringify(o)!==JSON.stringify(L)&&d.sendEvent({type:"event",event:"machine.agents",payload:{agentList:C,agents:o}})}).catch(()=>{}),v&&d.sendEvent({type:"event",event:"upgrade",payload:{state:"recovering",machineId:"self",from:v.from,to:v.to,...v.jobId?{jobId:v.jobId}:{},activeRunCount:r.getPendingRecoveryCount()}}),x.start(),A?.start();const e=++N,n=async()=>{try{if(await r.synchronizeSessionDeletions(),await r.recoverInterruptedRuns(),v){const o=v;v=null,o.jobId&&co(o.jobId,o.to),no(),console.log(`[${new Date().toISOString()}] [upgrade] ${o.operation==="rollback"?"Rolled back":"Healthy"}: ${o.from} \u2192 ${o.to}`),uo({kind:"upgrade",result:o.operation==="rollback"?"rolled_back":"healthy",stage:"terminal"}),d.sendEvent({type:"event",event:"upgrade",payload:{state:o.operation==="rollback"?"rolled_back":"healthy",machineId:"self",from:o.from,to:o.to,...o.jobId?{jobId:o.jobId}:{}}}),o.operation!=="rollback"&&d.sendEvent({type:"event",event:"upgrade",payload:{state:"success",machineId:"self",from:o.from,to:o.to}})}e===N&&d.getState()==="connected"&&P?.handleConnected()}catch(o){if(console.error("[session.deletions] startup catch-up failed",o),e===N&&d.getState()==="connected"){if(o instanceof zo)return;const t=o instanceof Wo?Math.max(1e3,o.retryAfterMs):5e3;setTimeout(()=>{n()},t).unref?.()}}};n()},onDisconnected:e=>{N+=1,r?.revokeProjectFsHandles(),A?.stop(),console.log(`[${new Date().toISOString()}] \u26A0 Disconnected, reconnecting... ${Yo(e)}`),T({level:"warn",wsEvent:"daemon.disconnected",metadata:{code:e.code,reason:e.reason,error:e.error,phase:e.phase,trigger:e.trigger,reconnectAttempt:e.reconnectAttempt}})},onProjectFsCapabilityChanged:e=>{e||r?.revokeProjectFsHandles()},onReq:e=>{if(console.log(`[${new Date().toISOString()}] [req] ${e.method}`),T({level:"info",type:"ws",wsEvent:e.method,wsDirection:"in",traceId:e.traceId}),e.method==="room.message.deliver"){Do(d,A,e);return}r.handleReq(e)}});P=fo()?new ho(d):null,A=new To({registry:f,observations:U,actionClient:S,getMachineCredentials:()=>({machineToken:p().machineToken}),isSessionDeleted:e=>new Uo().hasSession(e),onMessages:async(e,n,o,t)=>{await y?.processMessages(e,n,o,t)},onBindingPaused:e=>{e.lifecycleState==="closed"?(R.revokeSession(e.registryKey),r?.retireManagedRoomSession(e.nianSessionId).catch(()=>{console.warn("[room.sync] retired session cleanup failed")})):r?.discardPendingManagedRoomMessages(e.nianSessionId)}});const x=new ao({currentVersion:h,machineId:m.machineId??"unknown-machine",serverUrl:m.serverUrl??u,getIdleState:()=>r.getUpgradeIdleState(),sessionSyncProtocolVersion:pe,dataEpoch:ue,advertisedCapabilities:ge,updaterProtocolVersion:1,startUpgrade:async(e,n)=>{const{handleUpgradeStart:o}=await import("./commands/upgrade.js");await o(d,"auto-upgrade",e,{currentVersion:h,prepareForUpgrade:t=>r.prepareForUpgrade(t),cancelUpgradePreparation:()=>r.cancelUpgradePreparation(),shutdownAfterHandoff:()=>{setTimeout(()=>process.kill(process.pid,"SIGTERM"),100).unref?.()},suppressResponse:!0,waitForCompletion:!0,canHandoff:n?void 0:()=>r.getUpgradeIdleState().idle})}});x.setPolicy(Z),r=new Ze(d,P,h,x,new Ao({registry:f,observations:U,bindingClient:S,getMachineCredentials:()=>{const e=p();return{machineId:e.machineId,machineToken:e.machineToken}},hostProcessIdentity:()=>`daemon:${c}`}),{prepare:()=>Oe(),isDisabled:()=>ae(),shutdownAfterResponse:()=>{setTimeout(()=>{$e(),process.kill(process.pid,"SIGTERM")},100).unref?.()}},e=>R.revokeToken(e),q,null,Xe(_),()=>$(l)),j=async e=>{const n=e&&typeof e=="object"&&!Array.isArray(e)?e:{},o=typeof n.targetVersion=="string"?n.targetVersion:void 0,t=n.confirmedMajor===!0;return await We(d,`local-upgrade-${Date.now()}`,o,{currentVersion:h,confirmedMajor:t,prepareForUpgrade:F=>r.prepareForUpgrade(F),cancelUpgradePreparation:()=>r.cancelUpgradePreparation(),shutdownAfterHandoff:()=>{setTimeout(()=>process.kill(process.pid,"SIGTERM"),100).unref?.()},suppressResponse:!0})},H=e=>{const n=e&&typeof e=="object"&&!Array.isArray(e)?e:{},t=`desktop-${(typeof n.targetVersion=="string"?n.targetVersion:"unknown").replace(/[^A-Za-z0-9._-]/g,"_")}-${Date.now()}`;return{jobId:t,...r.prepareForUpgrade(t)}},B=()=>(r.cancelUpgradePreparation(),{cancelled:!0}),y=new No({registry:f,observations:U,enqueueConversationBatch:e=>r.enqueueManagedRoomBatch(e),loadContext:async e=>{const n=p().machineToken?.trim(),o=e.binding;if(!n||!o)throw new Error("managed_room_context_unavailable");const t=await S.status({machineToken:n,roomId:o.roomId,bindingId:o.bindingId});if(!_o(f,e)||!Mo(e,t))throw new Error("managed_room_binding_unavailable");return{roomName:t.room.name,memberCount:t.room.memberCount,members:t.room.members,agentsByIdentityId:t.agent?{[t.agentIdentityId]:t.agent}:{},effectiveModelsBySessionId:t.effectiveModelId!==void 0?{[e.nianSessionId]:t.effectiveModelId}:void 0,agentSystemPromptsByIdentityId:t.agent?{[t.agentIdentityId]:t.agent.systemPrompt??""}:{}}},issueManagedRoomContext:(e,n,o,t)=>{const I=p().machineToken;if(!I)throw new Error("machine_not_authorized");return R.issue({registryKey:e,machineCredential:I,activationCauseMessageId:n,allowedActions:o,propagateWorkerRoomOrigin:t})},audit:new Oo,resolveManagedAgentPolicy:e=>xo({...e,runtime:l.find(n=>n.type===e.registration.runtimeAdapter)})}),r.scheduleHandler=e=>we({serverUrl:u,machineToken:p().machineToken,req:e,client:d,queue:r.getScheduleQueue(),registry:f}),r.getScheduleQueue().validateScheduledTarget=async e=>{if(!e.bindingId||!e.roomId)return"ready";if(f.getByNianSessionId(e.sessionId)?.binding?.bindingId!==e.bindingId)return"ended";const o=await S.status({machineToken:p().machineToken,roomId:e.roomId,bindingId:e.bindingId});return o.status==="active"&&o.room.status==="active"?"ready":"ended"},r.setManagedRoomTurnPreparer(e=>y.prepareConversationTurn(e)),r.setManagedAgentDirectTurnPreparer((e,n)=>y.prepareDirectConversationTurn(e,n)),r.setManagedRecoveryPreparer(async e=>e.source==="managed_direct"?y.prepareDirectConversationTurn(e.sessionId,Bo):e.source==="manager_event"?y.prepareDirectConversationTurn(e.sessionId,{allowedRoomActions:[],managerEvent:!0}):e.source!=="managed_room"||!e.roomContextRegistryKey||!e.activationCauseMessageId||!e.rootCauseMessageId||!e.activationSequence||e.activationHopCount===null?null:y.prepareConversationTurn([{registryKey:e.roomContextRegistryKey,causeMessageId:e.activationCauseMessageId,rootCauseMessageId:e.rootCauseMessageId,sequence:e.activationSequence,hopCount:e.activationHopCount}])),G.mkdirSync(fe,{recursive:!0}),se(process.pid,c,{version:h}),ce(process.pid,void 0,c),d.connect(),process.stdin.resume();let X=!1;const ee=async()=>{if(!X){X=!0,console.log(E.gray(`
|
|
3
3
|
Disconnecting...`)),T({level:"info",wsEvent:"daemon.stop"}),clearInterval(g);try{await r.cleanup(),x.stop(),P?.stop(),A?.stop(),d.disconnect(),await Promise.allSettled([b.close(),k.close()]),te(process.pid,c),re(c)}finally{process.exit(0)}}};process.on("SIGINT",()=>{ee()}),process.on("SIGTERM",()=>{ee()})}),i.command("workbuddy-session-hook",{hidden:!0}).description("(retired) WorkBuddy Room Hook").allowUnknownOption(!0).action(()=>J()),i.command("room-session-hook",{hidden:!0}).description("(internal) Authorize the official Room tool for one trusted Agent Session").argument("<runtime>","Trusted runtime adapter").allowUnknownOption(!0).action(()=>J()),i.command("room-tool-server",{hidden:!0}).description("(internal) Run the official Shennian Room MCP tool").allowUnknownOption(!0).action(()=>J());const he=i.command("config").description("View or modify configuration");he.command("show",{isDefault:!0}).description("Show current configuration").action(()=>{console.log(`Config file: ${ke()}`);const a=p(),s=De(a,ne(process.env,a));if(a.serverUrl){const g=oo(a.serverUrl);console.log(`Region: ${g} (${z[g].label})`)}console.log(JSON.stringify(s,null,2))}),he.command("set").description("Update a config value").argument("<key>",'Config key (e.g. "server")').argument("<value>",'Config value (e.g. "cn" or "global")').action((a,s)=>{const g=p();if(a==="server"){s!=="cn"&&s!=="global"&&(console.error(E.red('\u2717 Value must be "cn" or "global"')),process.exit(1));const c=s;g.serverUrl=eo(c),be(g),console.log(E.green(`\u2713 Server set to ${z[c].label}`)),console.log(E.yellow(" Restart the background service for this to take effect: shennian stop && shennian start"));return}console.error(E.red(`\u2717 Unknown config key: ${a}. Supported: server`)),process.exit(1)}),Ue(i),_e(i),Le(i),je(i),He(i,{clientVersion:O}),Be(i),Fe(i),Ge(i),ze(i),Je(i),Ke(i),i.parse();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isAvailableAgentType as w}from"@shennian/wire";const f=/^[A-Za-z0-9_.:@/-]{1,191}$/,S=new Set(["roomId","agentIdentityId","nianSessionId","assignmentIntentId","agentType","activationMode"]),l=new Set(["roomId","bindingId","agentIdentityId","previousNianSessionId","nianSessionId","assignmentIntentId","agentType"]);async function
|
|
1
|
+
import{isAvailableAgentType as w}from"@shennian/wire";const f=/^[A-Za-z0-9_.:@/-]{1,191}$/,S=new Set(["roomId","agentIdentityId","nianSessionId","assignmentIntentId","agentType","activationMode"]),l=new Set(["roomId","bindingId","agentIdentityId","previousNianSessionId","nianSessionId","assignmentIntentId","agentType"]);async function b(n,t,e){const s=await R(n,t,e.params);n.client.sendRes({type:"res",id:e.id,ok:!0,payload:s})}async function R(n,t,e){if(!t)throw new Error("Managed Room binding is unavailable.");if(Object.keys(e).some(g=>!S.has(g)))throw new Error("Managed Room binding contains unsupported parameters.");const s=o(e.roomId,"roomId"),d=o(e.agentIdentityId,"agentIdentityId"),i=o(e.nianSessionId,"nianSessionId"),a=o(e.assignmentIntentId,"assignmentIntentId"),r=m(e.agentType),I=M(e.activationMode);return await c(n,i),t.bind({roomId:s,agentIdentityId:d,nianSessionId:i,assignmentIntentId:a,sourceSessionKey:p(i),agentType:r,activationMode:I})}async function h(n,t,e){if(!t)throw new Error("Managed Room binding is unavailable.");if(Object.keys(e.params).some(u=>!l.has(u)))throw new Error("Managed Room restart contains unsupported parameters.");const s=o(e.params.roomId,"roomId"),d=o(e.params.bindingId,"bindingId"),i=o(e.params.agentIdentityId,"agentIdentityId"),a=o(e.params.previousNianSessionId,"previousNianSessionId"),r=o(e.params.nianSessionId,"nianSessionId"),I=o(e.params.assignmentIntentId,"assignmentIntentId"),g=m(e.params.agentType);await n.managerRuntime?.retireManagerAndWorkers(a),await c(n,a),n.chatQueue?.purgeSession(a),await c(n,r);const y=await t.restart({roomId:s,bindingId:d,agentIdentityId:i,previousNianSessionId:a,nianSessionId:r,assignmentIntentId:I,sourceSessionKey:p(r),agentType:g});n.client.sendRes({type:"res",id:e.id,ok:!0,payload:y})}function o(n,t){if(typeof n!="string"||!f.test(n))throw new Error(`Invalid ${t}.`);return n}function m(n){if(typeof n!="string"||!w(n)||n==="manager"||n==="pi"||n==="openclaw")throw new Error("managed_agent_runtime_unsupported");return n}function M(n){if(n===void 0)return"auto_follow";if(n==="auto_follow"||n==="mention_only"||n==="paused")return n;throw new Error("Invalid activationMode.")}function p(n){return`managed:${n}`}async function c(n,t){n.runJournal?.markSessionAborted(t),n.recoveryBarrier?.end(t);const e=n.sessions.get(t);e&&(n.sessions.delete(t),e.managedRoomContextToken&&(n.revokeManagedRoomContextToken?.(e.managedRoomContextToken),e.managedRoomContextToken=null),e.heartbeatTimer&&clearInterval(e.heartbeatTimer),e.adapter.removeAllListeners(),await e.adapter.stop())}export{R as bindManagedRoom,c as discardPreBindingSession,b as handleManagedRoomBind,h as handleManagedRoomRestart};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import b from"node:crypto";import{getRegisteredAgents as S,unregisterAgent as k}from"../agents/adapter.js";import{resetCommandSpecCache as w}from"../agents/command-spec.js";import{loadConfig as A}from"../config/index.js";import{handleUpgradeStart as I,handleUpgradeStatus as T}from"../commands/upgrade.js";import{handleAgentsRefresh as P,handleModelsRefresh as C,refreshMachineAgents as M}from"./handlers/agents.js";import{AcpDiscoveryWatcher as x}from"../agents/acp/watcher.js";import{handleAgentCapabilitiesList as D}from"./handlers/agent-capabilities.js";import{handleAgentConfigClear as F,handleAgentConfigGet as E,handleAgentConfigTest as Q,handleAgentConfigUpsert as j}from"./handlers/agent-config.js";import{handleChatAbort as z,handleChatSend as O}from"./handlers/chat.js";import{recoverJournaledRun as B}from"./handlers/chat-recovery.js";import{handleSessionRefresh as W}from"./handlers/session-refresh.js";import{handleSessionToolDetail as _}from"./handlers/tool-detail.js";import{handleSessionTitleSet as H}from"./handlers/title.js";import{handleSessionMessageStatus as U}from"./handlers/message-status.js";import{handleAgentWorkspaceValidation as J}from"./handlers/agent-workspace-validation.js";import{handleVoiceSessionBodyWindow as $}from"./handlers/voice-window.js";import{handleRemoteAccessPause as V}from"./handlers/remote-access.js";import{cleanupPendingTransfers as N,handleFsLs as L,handleFsRead as G,handleFsRename as K,handleFsWrite as X,handleFsTransferAbort as Z,handleFsTransferChunk as Y,handleFsTransferFinish as q,handleFsTransferStart as ee,handleFsExportMarkdownPdf as se,handleFsExportMarkdownPdfSetup as te,handleFsArchiveZip as ae}from"./handlers/fs.js";import{handleRegionProbe as re,handleRegionSwitch as ne,handleUpgradeSetPolicy as ie}from"./handlers/control.js";import{ManagerRuntimeService as oe,setManagerRuntimeService as h}from"../manager/runtime.js";import{ChatQueueManager as ce}from"./queue.js";import{createAuthorizedFsRoot as le,createAuthorizedFsRootAsync as ue,resolveAuthorizedPath as he,resolveAuthorizedPathAsync as de,resolveSessionWorkDir as me}from"../fs/boundary.js";import"../agents/claude.js";import"../agents/codex.js";import"../agents/workbuddy.js";import"../agents/gemini.js";import"../agents/cursor.js";import"../agents/opencode.js";import"../agents/pi-coding-agent.js";import"../agents/manager.js";import{registerCustomAgent as pe}from"../agents/custom.js";import{listNodeAdapters as ge}from"../adapter-kit/registry.js";import{syncNodeAdapterAgents as fe}from"../agents/node-adapter.js";import{handleManagedRoomBind as ve,handleManagedRoomRestart as ye,discardPreBindingSession as Re}from"./handlers/room-managed.js";import{getDaemonInstallationId as d,listSessionRecords as u,purgeCanonicalSession as be,purgeSessionRecord as Se,recordSession as ke,upsertMessage as we}from"./store.js";import{requestSessionIndexPublish as m}from"./index-publisher.js";import{checkRunStalls as Ae}from"./run-stall.js";import{reportUpgradeAggregateMetric as Ie}from"../log-reporter.js";import{PersonalHistorySubscriptions as Te}from"./history-subscriptions.js";import{sweepAttachmentTransfers as Pe}from"./attachment-transfer-store.js";import{NativeSourceDeletionStore as Ce}from"../native-fusion/native-source-deletions.js";import{collectLocalNativeSources as Me}from"../native-fusion/session-native-sources.js";import{purgeToolDetails as xe}from"./tool-detail-store.js";import{NativeSessionCleanupOutbox as De}from"./native-cleanup-outbox.js";import{assertPersonalSyncIdentity as o}from"../personal-sync/epoch.js";import{ActiveRunJournal as Fe}from"./run-recovery/journal.js";import{RunRecoveryBarrier as Ee}from"./run-recovery/barrier.js";import{RunRecoveryCoordinator as Qe}from"./run-recovery/coordinator.js";import{ProjectFsHandleStore as je}from"./project-fs-store.js";import{handleProjectFsRequest as ze}from"./handlers/project-fs.js";import{handleAgentPermissionResponse as Oe,handleAcpAgentRequest as Be}from"./handlers/agent-control.js";import{SessionDeletionSynchronizer as We}from"./deletion-synchronizer.js";import{dispatchManagedChat as _e,dispatchQueuedChat as He,interruptQueuedChat as Ue}from"./queued-chat-dispatch.js";const Je=50;import{resolveSessionWorkDir as Ks}from"../fs/boundary.js";function $e(){return"\u795E\u5FF5\u5347\u7EA7\u4E2D\u65AD\u4E86\u672C\u6B21\u8FD0\u884C\u3002\u5DF2\u5B8C\u6210\u7684\u56DE\u590D\u6216\u64CD\u4F5C\u4ECD\u7136\u6709\u6548\uFF0C\u672A\u5B8C\u6210\u90E8\u5206\u53EF\u91CD\u8BD5\u3002\u539F\u4F1A\u8BDD\u5DF2\u4FDD\u7559\u3002"}class Ns{client;nativeFusion;cliVersion;upgradePolicyController;managedRoomBinder;remoteAccessPauseController;managedRoomContextRevoker;managedRoomExecutor;trustedProjectFsRequestResolver;getAgentSnapshot;scheduleHandler;getScheduleQueue(){return this.chatQueue}sessions=new Map;processedReqIds=new Set;runTextAcc=new Map;pendingTransfers=new Map;managerRuntime;chatQueue;historySubscriptions;nativeCleanupOutbox;activityProbeTimer=null;attachmentCleanupTimer=null;activeRequests=0;acpDiscoveryWatcher;runJournal;recoveryBarrier=new Ee;recoveryCoordinator;recoveryPass=null;prepareManagedRecovery;projectFsHandleStore=new je;deletionSynchronizer;constructor(e,t=null,s,n=null,r=null,l=null,p=null,g=null,f=null,v=null,y=null){this.client=e,this.nativeFusion=t,this.cliVersion=s,this.upgradePolicyController=n,this.managedRoomBinder=r,this.remoteAccessPauseController=l,this.managedRoomContextRevoker=p,this.managedRoomExecutor=g,this.trustedProjectFsRequestResolver=v,this.getAgentSnapshot=y,this.runJournal=f??new Fe(d());for(const a of this.runJournal.loadPendingReconciliation().records)this.recoveryBarrier.begin(a.sessionId);this.recoveryCoordinator=new Qe({journal:this.runJournal,barrier:this.recoveryBarrier,recover:(a,i)=>B(this.getRuntime(),a,i),commitTerminal:(a,i)=>this.commitRecoveryTerminal(a,i),isCanonicalTerminal:a=>{const i=u().find(R=>R.sessionId===a.sessionId),c=`terminal:${b.createHash("sha256").update(`${a.runId}\0`).digest("hex")}`;return i?.lastAttentionId===c},onOutcome:a=>Ie({kind:"recovery",adapterType:a.adapterType,result:a.result,stage:a.result==="continued"?"continue":a.result==="reattached"?"reattach":a.result==="resumed"?"resume":a.result==="terminal_reconciled"?"inspect":"terminal",durationMs:a.durationMs,retries:Math.max(0,a.attempts-1),...a.reason?{errorCode:a.reason}:{}})}),this.managerRuntime=new oe({getRuntime:()=>this.getRuntime(),getAgentSnapshot:this.getAgentSnapshot??void 0,dispatchReq:a=>this.handleReq(a,{propagateErrors:!0})}),this.chatQueue=new ce({getRuntime:()=>this.getRuntime(),dispatchReq:a=>this.handleReq(a),dispatchManagedReq:(a,i)=>_e(this.getRuntime(),a,i),dispatchQueuedReq:(a,i)=>He(this.getRuntime(),a,i),interruptQueuedSession:a=>Ue(this.getRuntime(),a)}),this.deletionSynchronizer=new We(e,a=>this.applySessionDeletion(a)),this.historySubscriptions=new Te(this.client),this.nativeCleanupOutbox=new De({logger:console.info}),this.acpDiscoveryWatcher=new x(async()=>{w(),await M(this.getRuntime())}),this.nativeFusion?.setExternalTerminalHandler?.(a=>{this.handleExternalTerminal(a)}),this.nativeFusion?.setExternalClaimHandler?.((a,i)=>{this.chatQueue.noteExternalClaim(a,i)}),this.nativeCleanupOutbox.start(),h(this.managerRuntime),this.managerRuntime.start(),this.reloadCustomAgents();try{this.acpDiscoveryWatcher.start()}catch(a){console.warn(`[acp.discovery] watcher unavailable: ${a instanceof Error?a.message:String(a)}`)}this.activityProbeTimer=setInterval(()=>{Ae(this.sessions.entries(),()=>m(this.client)),this.publishManagedActivitySnapshots().catch(a=>{console.error("[session.activity] managed probe failed",a)})},15e3),this.activityProbeTimer.unref?.(),this.attachmentCleanupTimer=setInterval(()=>{const a=new Set([...u().map(i=>i.workDir),...Array.from(this.pendingTransfers.values()).map(i=>i.rootPath)]);for(const i of a)try{Pe(this.resolvePath(i))}catch(c){console.error("[attachment.cleanup] failed",c instanceof Error?c.message:String(c))}},6e4),this.attachmentCleanupTimer.unref?.()}executeManagedManagerAction(e){return this.managerRuntime.executeScopedWorkerAction(e.managerSessionId,e.action,e.params,e.roomOrigin)}noteManagedRoomSendOutcome(e){for(const t of this.sessions.values()){if(t.managedRoomContextToken!==e.token)continue;const s=t.roomSendOutcome??(t.roomSendOutcome={successes:0,failureCodes:[]});e.ok?s.successes+=1:s.failureCodes.length<20&&s.failureCodes.push(e.errorCode??"managed_room_action_failed");return}}getManagedRoomActiveRunId(e,t){const s=this.sessions.get(t);if(s?.currentRunId)return s.currentRunId;for(const n of this.sessions.values())if(n.managedRoomContextToken===e)return n.currentRunId??null;return null}getRuntime(){return{client:this.client,pendingTransfers:this.pendingTransfers,processedReqIds:this.processedReqIds,reloadCustomAgents:()=>this.reloadCustomAgents(),getAgentSnapshot:this.getAgentSnapshot??void 0,resolvePath:e=>this.resolvePath(e),resolveAuthorizedPath:(e,t)=>this.resolveAuthorizedPath(e,t),resolveAuthorizedPathAsync:(e,t)=>this.resolveAuthorizedPathAsync(e,t),runTextAcc:this.runTextAcc,sessions:this.sessions,evictIdleSessions:()=>this.evictIdleSessions(),nativeFusion:this.nativeFusion,managerRuntime:this.managerRuntime,chatQueue:this.chatQueue,activityPublisher:{publish:(e,t)=>this.publishSessionActivity(e,t)},upgradePolicyController:this.upgradePolicyController,revokeManagedRoomContextToken:this.managedRoomContextRevoker,managedRoomExecutor:this.managedRoomExecutor,runJournal:this.runJournal,recoveryBarrier:this.recoveryBarrier,prepareManagedRecovery:this.prepareManagedRecovery}}async resumePendingAcpAuthentication(e){const t=[...this.sessions.values()].find(s=>s.agentType===e&&s.adapter.hasPendingAuthenticationRetry?.());return t?.adapter.resumeAfterExternalAuthentication?(await t.adapter.resumeAfterExternalAuthentication(),!0):!1}getUpgradeIdleState(){const e=[];return[...this.sessions.values()].some(t=>t.currentRunId!==null)&&e.push("active-agent-turn"),this.pendingTransfers.size>0&&e.push("file-transfer"),this.activeRequests>0&&e.push("active-daemon-request"),{idle:e.length===0,reasons:e}}prepareForUpgrade(e){this.recoveryBarrier.freezeDispatch();const t=this.runJournal.markPlannedUpgrade(e);return this.runJournal.sync(),{activeRunCount:t}}cancelUpgradePreparation(){this.recoveryBarrier.unfreezeDispatch()}async recoverInterruptedRuns(){this.recoveryPass??=this.recoveryCoordinator.recoverAll(),await this.recoveryPass}getPendingRecoveryCount(){return this.runJournal.loadPendingReconciliation().records.length}revokeProjectFsHandles(){this.projectFsHandleStore.revokeAll()}async commitRecoveryTerminal(e,t){const s=this.sessions.get(e.sessionId);s&&(s.currentRunId=null,s.currentRunPhase=null,s.journalRunId=null,s.heartbeatTimer&&(clearInterval(s.heartbeatTimer),s.heartbeatTimer=null)),this.runTextAcc.delete(`${e.sessionId}:${e.providerRunId??e.runId}`),this.publishSessionActivity(e.sessionId,null);const n=$e();we(e.sessionId,{id:`upgrade-recovery-terminal-${e.runId}`,sessionId:e.sessionId,role:"agent",ts:Date.now(),payload:JSON.stringify({v:1,type:"error",content:n,error:!0,recoveryState:t.result,recoveryReason:t.reason})}),ke({sessionId:e.sessionId,agentType:e.agentType,sessionMode:e.sessionMode,workDir:e.workDir,agentSessionId:e.agentSessionId,modelId:e.modelId,status:"failed",attentionId:`upgrade-recovery:${e.runId}`,lastActivityAt:new Date().toISOString()}),this.managerRuntime.noteAgentEvent(e.sessionId,{state:"error",runId:e.providerRunId??e.runId,seq:e.lastObservedEventSeq+1,message:n}),m(this.client);const r=e.lastObservedEventSeq+1;this.client.sendAgentEvent({type:"event",event:"agent",payload:t.result==="interrupted_by_upgrade"?{state:"interrupted_by_upgrade",sessionId:e.sessionId,runId:e.providerRunId??e.runId,seq:r,reason:t.reason}:{state:"recovery_failed",sessionId:e.sessionId,runId:e.providerRunId??e.runId,seq:r,reason:t.reason,...t.message?{message:t.message}:{}},seq:r,id:`agent-recovery-terminal-${e.runId}`}),this.chatQueue.noteTerminal(e.sessionId)}setManagedRoomTurnPreparer(e){this.chatQueue.setManagedRoomTurnPreparer(e)}setManagedAgentDirectTurnPreparer(e){this.chatQueue.setManagedAgentDirectTurnPreparer(e)}setManagedRecoveryPreparer(e){this.prepareManagedRecovery=e}async enqueueManagedRoomBatch(e){const t=e.map(s=>{const n=u().find(r=>r.sessionId===s.params.sessionId);return{context:s.context,params:{...s.params,modelId:n?.modelId??s.params.modelId,sessionMode:n?.sessionMode??s.params.sessionMode,managerConfig:n?.managerConfig??s.params.managerConfig,managerDefaultWorkerAgentType:n?.managerDefaultWorkerAgentType??s.params.managerDefaultWorkerAgentType,managerDefaultWorkerModelId:n?.managerDefaultWorkerModelId??s.params.managerDefaultWorkerModelId}}});await this.chatQueue.enqueueManagedRoomBatch(t)}async retireManagedRoomSession(e){this.chatQueue.purgeSession(e),await Re(this.getRuntime(),e)}discardPendingManagedRoomMessages(e){return this.chatQueue.discardPendingManagedRoomMessages(e)}async synchronizeSessionDeletions(){await this.deletionSynchronizer.synchronize()}async applySessionDeletion(e){const t=new Ce({daemonInstallationId:d()});let s=[];try{s=Me(e.sessionId,{records:u()})}catch(r){console.warn("[session.deletions] local native source lookup failed",{error:r instanceof Error?r.message:String(r)})}t.recordSession(e);for(const r of[...e.sources,...s]){const l=t.find(r.agentType,r.sourceSessionKey);l&&l.sessionId!==e.sessionId||t.record({...e,...r})}this.runJournal.markSessionAborted(e.sessionId),this.recoveryBarrier.end(e.sessionId);const n=this.sessions.get(e.sessionId);if(n){this.revokeManagedRoomToken(n);try{await n.adapter.stop()}catch{}this.sessions.delete(e.sessionId)}this.historySubscriptions.closeSession(e.sessionId),this.nativeFusion?.handleSessionDeleted(e.sessionId),this.chatQueue.purgeSession(e.sessionId),xe(e.sessionId),be(e.sessionId),Se(e.sessionId),this.runTextAcc.delete(e.sessionId),this.publishSessionActivity(e.sessionId,null),this.nativeCleanupOutbox.enqueue(e),this.nativeCleanupOutbox.kick()}publishSessionActivity(e,t){this.client.sendEvent({type:"event",event:"session.activity",payload:{sessionId:e,activity:t}})}async handleExternalTerminal(e){const t=this.sessions.get(e);t&&(t.journalRunId&&(this.recoveryCoordinator.completeFromProvider(e,t.journalRunId),t.journalRunId=null),this.sessions.delete(e),this.revokeManagedRoomToken(t),t.heartbeatTimer&&clearInterval(t.heartbeatTimer),t.adapter.removeAllListeners(),await t.adapter.stop().catch(()=>{})),this.chatQueue.noteTerminal(e)}async publishManagedActivitySnapshots(){for(const[e,t]of this.sessions.entries()){if(t.heartbeatTimer||!t.currentRunId||!t.adapter.getStatus)continue;const s=await t.adapter.getStatus().catch(()=>null);if(!s?.active||!s.runPhase)continue;const n=new Date().toISOString();this.publishSessionActivity(e,{sessionId:e,runId:s.runId||t.currentRunId,runPhase:s.runPhase,startedAt:new Date(t.lastActiveAt).toISOString(),updatedAt:n,canStop:s.canStop??!0});const r=t.heartbeatSeq++;this.client.sendAgentEvent({type:"event",event:"agent",payload:{state:"heartbeat",sessionId:e,runId:s.runId||t.currentRunId,seq:r,runPhase:s.runPhase,canStop:s.canStop??!0},seq:r,id:`agent-status-${s.runId||t.currentRunId}-${Date.now()}`})}}reloadCustomAgents(){for(const t of S())t.startsWith("custom:")&&k(t);const e=A();for(const[t,s]of Object.entries(e.customAgents??{}))pe(t,s);fe(ge(),new Set(Object.keys(e.customAgents??{})))}async handleReq(e,t={}){const s=this.getRuntime();let n;this.activeRequests++;try{switch(e.method){case"schedule.deliver":if(!this.scheduleHandler)throw new Error("schedules_unavailable");await this.scheduleHandler(e);break;case"chat.send":if(e.params.scheduledDelivery)throw new Error("schedule_source_untrusted");o(e.params),this.recoveryBarrier.isDispatchFrozen()||this.recoveryBarrier.isRecovering(String(e.params.sessionId??""))?n={durableQueueHandoff:await this.chatQueue.handleEnqueue({...e,method:"chat.enqueue"})}:await O(s,e);break;case"chat.enqueue":o(e.params),n={durableQueueHandoff:await this.chatQueue.handleEnqueue(e)};break;case"chat.queue.get":o(e.params),await this.chatQueue.handleGet(e);break;case"chat.queue.edit":o(e.params),await this.chatQueue.handleEdit(e);break;case"chat.queue.delete":o(e.params),await this.chatQueue.handleDelete(e);break;case"chat.queue.promote":o(e.params),await this.chatQueue.handlePromote(e);break;case"chat.abort":o(e.params),await z(s,e);break;case"session.refresh":o(e.params),await W(s,e);break;case"session.history.open":this.historySubscriptions.handleOpen(e);break;case"session.history.sync":this.historySubscriptions.handleSync(e);break;case"session.history.page":this.historySubscriptions.handlePage(e);break;case"session.history.close":this.historySubscriptions.handleClose(e);break;case"session.body.replica.subscribe":this.historySubscriptions.handleReplicaSubscribe(e);break;case"session.body.replica.unsubscribe":this.historySubscriptions.handleReplicaUnsubscribe(e);break;case"session.history":this.client.sendRes({type:"res",id:e.id,ok:!1,error:"upgrade_required"});break;case"session.message.status":U(s,e);break;case"session.tool.detail":await _(s,e);break;case"voice.session.body.window":$(s,e);break;case"session.title.set":await H(s,e);break;case"room.agent.bind-managed":await ve(s,this.managedRoomBinder,e);break;case"room.agent.restart-managed":await ye(s,this.managedRoomBinder,e);break;case"fs.ls":await L(s,e);break;case"project.fs.open":case"project.fs.list":case"project.fs.read":case"project.fs.close":await ze(this.client,this.projectFsHandleStore,e,this.trustedProjectFsRequestResolver);break;case"fs.read":await G(s,e);break;case"fs.write":await X(s,e);break;case"fs.export.markdown-pdf":await se(s,e);break;case"fs.export.markdown-pdf.setup":await te(s,e);break;case"fs.archive.zip":await ae(s,e);break;case"fs.rename":await K(s,e);break;case"fs.transfer.start":await ee(s,e);break;case"fs.transfer.chunk":await Y(s,e);break;case"fs.transfer.finish":await q(s,e);break;case"fs.transfer.abort":await Z(s,e);break;case"region.probe":await re(s,e);break;case"region.switch":await ne(s,e);break;case"upgrade.start":await I(this.client,e.id,e.params.version,{currentVersion:this.cliVersion,confirmedMajor:e.params.confirmedMajor===!0,prepareForUpgrade:r=>this.prepareForUpgrade(r),cancelUpgradePreparation:()=>this.cancelUpgradePreparation(),shutdownAfterHandoff:()=>{setTimeout(()=>process.kill(process.pid,"SIGTERM"),100).unref?.()}});break;case"upgrade.status":await T(this.client,e.id,{currentVersion:this.cliVersion});break;case"upgrade.set-policy":await ie(s,e);break;case"machine.remote-access.pause":await V(this.client,this.remoteAccessPauseController,e);break;case"agents.refresh":await P(s,e);break;case"agent.permission.respond":await Oe(s,e);break;case"agent.auth.start":case"agent.auth.logout":case"agent.session-options.get":case"agent.external-sessions.list":case"agent.external-sessions.import":case"agent.external-sessions.close":case"agent.external-sessions.delete":await Be(s,e);break;case"models.refresh":await C(s,e);break;case"agent.config.get":await E(s,e);break;case"agent.config.upsert":await j(s,e);break;case"agent.config.clear":await F(s,e);break;case"agent.config.test":await Q(s,e);break;case"agent.workspace.validate":await J(s,e);break;case"agent.capabilities.list":await D(s,e);break;case"skill.list":case"skill.install":case"skill.doctor":case"skill.setup":case"skill.use":this.client.sendRes({type:"res",id:e.id,ok:!1,error:"feature_retired"});break;case"session.wechat-rpa.channel.get":case"session.wechat-rpa.channel.upsert":case"session.wechat-rpa.channel.sync":case"manager.wechat-rpa.channel.get":case"manager.wechat-rpa.channel.upsert":case"manager.wechat-rpa.channel.sync":this.client.sendRes({type:"res",id:e.id,ok:!1,error:"feature_retired"});break;default:this.client.sendRes({type:"res",id:e.id,ok:!1,error:`Unknown method: ${e.method}`})}}catch(r){if(t.propagateErrors)throw r;this.client.sendRes({type:"res",id:e.id,ok:!1,error:r instanceof Error?r.message:String(r)})}finally{this.activeRequests--}return n}evictIdleSessions(){if(this.sessions.size<Je)return;let e=null;for(const[t,s]of this.sessions)(!e||s.lastActiveAt<e.session.lastActiveAt)&&(e={key:t,session:s});e&&(this.revokeManagedRoomToken(e.session),e.session.heartbeatTimer&&(clearInterval(e.session.heartbeatTimer),e.session.heartbeatTimer=null),e.session.adapter.removeAllListeners(),e.session.adapter.stop().catch(()=>{}),this.sessions.delete(e.key))}resolvePath(e){return me(e)}resolveAuthorizedPath(e,t){return he(e,le(t))}async resolveAuthorizedPathAsync(e,t){return de(e,await ue(t))}async cleanup(){this.chatQueue.stop(),this.projectFsHandleStore.revokeAll(),this.acpDiscoveryWatcher.stop(),this.nativeFusion?.setExternalTerminalHandler?.(null),this.nativeCleanupOutbox.stop(),this.historySubscriptions.closeAll(),this.activityProbeTimer&&(clearInterval(this.activityProbeTimer),this.activityProbeTimer=null),this.attachmentCleanupTimer&&(clearInterval(this.attachmentCleanupTimer),this.attachmentCleanupTimer=null);for(const[,e]of this.sessions)this.revokeManagedRoomToken(e),e.heartbeatTimer&&(clearInterval(e.heartbeatTimer),e.heartbeatTimer=null),e.adapter.removeAllListeners(),await e.adapter.stop().catch(()=>{});this.sessions.clear(),this.runTextAcc.clear(),N(this.getRuntime()),await this.managerRuntime.stop(),h(null)}revokeManagedRoomToken(e){const t=e.managedRoomContextToken;e.managedRoomContextToken=null,t&&this.managedRoomContextRevoker?.(t)}}export{Ns as SessionManager,Ks as resolveSessionWorkDir,$e as upgradeRecoveryVisibleMessage};
|
|
1
|
+
import b from"node:crypto";import{getRegisteredAgents as S,unregisterAgent as k}from"../agents/adapter.js";import{resetCommandSpecCache as w}from"../agents/command-spec.js";import{loadConfig as A}from"../config/index.js";import{handleUpgradeStart as I,handleUpgradeStatus as T}from"../commands/upgrade.js";import{handleAgentsRefresh as P,handleModelsRefresh as C,refreshMachineAgents as M}from"./handlers/agents.js";import{AcpDiscoveryWatcher as x}from"../agents/acp/watcher.js";import{handleAgentCapabilitiesList as D}from"./handlers/agent-capabilities.js";import{handleAgentConfigClear as F,handleAgentConfigGet as E,handleAgentConfigTest as Q,handleAgentConfigUpsert as j}from"./handlers/agent-config.js";import{handleChatAbort as z,handleChatSend as O}from"./handlers/chat.js";import{recoverJournaledRun as B}from"./handlers/chat-recovery.js";import{handleSessionRefresh as W}from"./handlers/session-refresh.js";import{handleSessionToolDetail as _}from"./handlers/tool-detail.js";import{handleSessionTitleSet as H}from"./handlers/title.js";import{handleSessionMessageStatus as U}from"./handlers/message-status.js";import{handleAgentWorkspaceValidation as J}from"./handlers/agent-workspace-validation.js";import{handleVoiceSessionBodyWindow as $}from"./handlers/voice-window.js";import{handleRemoteAccessPause as V}from"./handlers/remote-access.js";import{cleanupPendingTransfers as L,handleFsLs as N,handleFsRead as G,handleFsRename as K,handleFsWrite as X,handleFsTransferAbort as Z,handleFsTransferChunk as Y,handleFsTransferFinish as q,handleFsTransferStart as ee,handleFsExportMarkdownPdf as se,handleFsExportMarkdownPdfSetup as te,handleFsArchiveZip as ae}from"./handlers/fs.js";import{handleRegionProbe as re,handleRegionSwitch as ne,handleUpgradeSetPolicy as ie}from"./handlers/control.js";import{ManagerRuntimeService as oe,setManagerRuntimeService as h}from"../manager/runtime.js";import{ChatQueueManager as ce}from"./queue.js";import{createAuthorizedFsRoot as le,createAuthorizedFsRootAsync as ue,resolveAuthorizedPath as he,resolveAuthorizedPathAsync as de,resolveSessionWorkDir as me}from"../fs/boundary.js";import"../agents/claude.js";import"../agents/codex.js";import"../agents/workbuddy.js";import"../agents/gemini.js";import"../agents/cursor.js";import"../agents/opencode.js";import"../agents/pi-coding-agent.js";import"../agents/manager.js";import{registerCustomAgent as pe}from"../agents/custom.js";import{listNodeAdapters as ge}from"../adapter-kit/registry.js";import{syncNodeAdapterAgents as fe}from"../agents/node-adapter.js";import{bindManagedRoom as ve,handleManagedRoomBind as ye,handleManagedRoomRestart as Re,discardPreBindingSession as be}from"./handlers/room-managed.js";import{getDaemonInstallationId as d,listSessionRecords as u,purgeCanonicalSession as Se,purgeSessionRecord as ke,recordSession as we,upsertMessage as Ae}from"./store.js";import{requestSessionIndexPublish as m}from"./index-publisher.js";import{checkRunStalls as Ie}from"./run-stall.js";import{reportUpgradeAggregateMetric as Te}from"../log-reporter.js";import{PersonalHistorySubscriptions as Pe}from"./history-subscriptions.js";import{sweepAttachmentTransfers as Ce}from"./attachment-transfer-store.js";import{NativeSourceDeletionStore as Me}from"../native-fusion/native-source-deletions.js";import{collectLocalNativeSources as xe}from"../native-fusion/session-native-sources.js";import{purgeToolDetails as De}from"./tool-detail-store.js";import{NativeSessionCleanupOutbox as Fe}from"./native-cleanup-outbox.js";import{assertPersonalSyncIdentity as o}from"../personal-sync/epoch.js";import{ActiveRunJournal as Ee}from"./run-recovery/journal.js";import{RunRecoveryBarrier as Qe}from"./run-recovery/barrier.js";import{RunRecoveryCoordinator as je}from"./run-recovery/coordinator.js";import{ProjectFsHandleStore as ze}from"./project-fs-store.js";import{handleProjectFsRequest as Oe}from"./handlers/project-fs.js";import{handleAgentPermissionResponse as Be,handleAcpAgentRequest as We}from"./handlers/agent-control.js";import{SessionDeletionSynchronizer as _e}from"./deletion-synchronizer.js";import{dispatchManagedChat as He,dispatchQueuedChat as Ue,interruptQueuedChat as Je}from"./queued-chat-dispatch.js";const $e=50;import{resolveSessionWorkDir as Xs}from"../fs/boundary.js";function Ve(){return"\u795E\u5FF5\u5347\u7EA7\u4E2D\u65AD\u4E86\u672C\u6B21\u8FD0\u884C\u3002\u5DF2\u5B8C\u6210\u7684\u56DE\u590D\u6216\u64CD\u4F5C\u4ECD\u7136\u6709\u6548\uFF0C\u672A\u5B8C\u6210\u90E8\u5206\u53EF\u91CD\u8BD5\u3002\u539F\u4F1A\u8BDD\u5DF2\u4FDD\u7559\u3002"}class Ns{client;nativeFusion;cliVersion;upgradePolicyController;managedRoomBinder;remoteAccessPauseController;managedRoomContextRevoker;managedRoomExecutor;trustedProjectFsRequestResolver;getAgentSnapshot;scheduleHandler;getScheduleQueue(){return this.chatQueue}sessions=new Map;processedReqIds=new Set;runTextAcc=new Map;pendingTransfers=new Map;managerRuntime;chatQueue;historySubscriptions;nativeCleanupOutbox;activityProbeTimer=null;attachmentCleanupTimer=null;activeRequests=0;acpDiscoveryWatcher;runJournal;recoveryBarrier=new Qe;recoveryCoordinator;recoveryPass=null;prepareManagedRecovery;projectFsHandleStore=new ze;deletionSynchronizer;constructor(e,t=null,s,n=null,r=null,l=null,p=null,g=null,f=null,v=null,y=null){this.client=e,this.nativeFusion=t,this.cliVersion=s,this.upgradePolicyController=n,this.managedRoomBinder=r,this.remoteAccessPauseController=l,this.managedRoomContextRevoker=p,this.managedRoomExecutor=g,this.trustedProjectFsRequestResolver=v,this.getAgentSnapshot=y,this.runJournal=f??new Ee(d());for(const a of this.runJournal.loadPendingReconciliation().records)this.recoveryBarrier.begin(a.sessionId);this.recoveryCoordinator=new je({journal:this.runJournal,barrier:this.recoveryBarrier,recover:(a,i)=>B(this.getRuntime(),a,i),commitTerminal:(a,i)=>this.commitRecoveryTerminal(a,i),isCanonicalTerminal:a=>{const i=u().find(R=>R.sessionId===a.sessionId),c=`terminal:${b.createHash("sha256").update(`${a.runId}\0`).digest("hex")}`;return i?.lastAttentionId===c},onOutcome:a=>Te({kind:"recovery",adapterType:a.adapterType,result:a.result,stage:a.result==="continued"?"continue":a.result==="reattached"?"reattach":a.result==="resumed"?"resume":a.result==="terminal_reconciled"?"inspect":"terminal",durationMs:a.durationMs,retries:Math.max(0,a.attempts-1),...a.reason?{errorCode:a.reason}:{}})}),this.managerRuntime=new oe({getRuntime:()=>this.getRuntime(),getAgentSnapshot:this.getAgentSnapshot??void 0,dispatchReq:a=>this.handleReq(a,{propagateErrors:!0})}),this.chatQueue=new ce({getRuntime:()=>this.getRuntime(),dispatchReq:a=>this.handleReq(a),dispatchManagedReq:(a,i)=>He(this.getRuntime(),a,i),dispatchQueuedReq:(a,i)=>Ue(this.getRuntime(),a,i),interruptQueuedSession:a=>Je(this.getRuntime(),a)}),this.deletionSynchronizer=new _e(e,a=>this.applySessionDeletion(a)),this.historySubscriptions=new Pe(this.client),this.nativeCleanupOutbox=new Fe({logger:console.info}),this.acpDiscoveryWatcher=new x(async()=>{w(),await M(this.getRuntime())}),this.nativeFusion?.setExternalTerminalHandler?.(a=>{this.handleExternalTerminal(a)}),this.nativeFusion?.setExternalClaimHandler?.((a,i)=>{this.chatQueue.noteExternalClaim(a,i)}),this.nativeCleanupOutbox.start(),h(this.managerRuntime),this.managerRuntime.start(),this.reloadCustomAgents();try{this.acpDiscoveryWatcher.start()}catch(a){console.warn(`[acp.discovery] watcher unavailable: ${a instanceof Error?a.message:String(a)}`)}this.activityProbeTimer=setInterval(()=>{Ie(this.sessions.entries(),()=>m(this.client)),this.publishManagedActivitySnapshots().catch(a=>{console.error("[session.activity] managed probe failed",a)})},15e3),this.activityProbeTimer.unref?.(),this.attachmentCleanupTimer=setInterval(()=>{const a=new Set([...u().map(i=>i.workDir),...Array.from(this.pendingTransfers.values()).map(i=>i.rootPath)]);for(const i of a)try{Ce(this.resolvePath(i))}catch(c){console.error("[attachment.cleanup] failed",c instanceof Error?c.message:String(c))}},6e4),this.attachmentCleanupTimer.unref?.()}executeManagedManagerAction(e){return this.managerRuntime.executeScopedWorkerAction(e.managerSessionId,e.action,e.params,e.roomOrigin)}noteManagedRoomSendOutcome(e){for(const t of this.sessions.values()){if(t.managedRoomContextToken!==e.token)continue;const s=t.roomSendOutcome??(t.roomSendOutcome={successes:0,failureCodes:[]});e.ok?s.successes+=1:s.failureCodes.length<20&&s.failureCodes.push(e.errorCode??"managed_room_action_failed");return}}getManagedRoomActiveRunId(e,t){const s=this.sessions.get(t);if(s?.currentRunId)return s.currentRunId;for(const n of this.sessions.values())if(n.managedRoomContextToken===e)return n.currentRunId??null;return null}getRuntime(){return{client:this.client,pendingTransfers:this.pendingTransfers,processedReqIds:this.processedReqIds,reloadCustomAgents:()=>this.reloadCustomAgents(),getAgentSnapshot:this.getAgentSnapshot??void 0,resolvePath:e=>this.resolvePath(e),resolveAuthorizedPath:(e,t)=>this.resolveAuthorizedPath(e,t),resolveAuthorizedPathAsync:(e,t)=>this.resolveAuthorizedPathAsync(e,t),runTextAcc:this.runTextAcc,sessions:this.sessions,evictIdleSessions:()=>this.evictIdleSessions(),nativeFusion:this.nativeFusion,managerRuntime:this.managerRuntime,chatQueue:this.chatQueue,activityPublisher:{publish:(e,t)=>this.publishSessionActivity(e,t)},upgradePolicyController:this.upgradePolicyController,revokeManagedRoomContextToken:this.managedRoomContextRevoker,managedRoomExecutor:this.managedRoomExecutor,runJournal:this.runJournal,recoveryBarrier:this.recoveryBarrier,prepareManagedRecovery:this.prepareManagedRecovery}}async resumePendingAcpAuthentication(e){const t=[...this.sessions.values()].find(s=>s.agentType===e&&s.adapter.hasPendingAuthenticationRetry?.());return t?.adapter.resumeAfterExternalAuthentication?(await t.adapter.resumeAfterExternalAuthentication(),!0):!1}getUpgradeIdleState(){const e=[];return[...this.sessions.values()].some(t=>t.currentRunId!==null)&&e.push("active-agent-turn"),this.pendingTransfers.size>0&&e.push("file-transfer"),this.activeRequests>0&&e.push("active-daemon-request"),{idle:e.length===0,reasons:e}}bindManagedRoomFromLocal(e){return ve(this.getRuntime(),this.managedRoomBinder,e)}prepareForUpgrade(e){this.recoveryBarrier.freezeDispatch();const t=this.runJournal.markPlannedUpgrade(e);return this.runJournal.sync(),{activeRunCount:t}}cancelUpgradePreparation(){this.recoveryBarrier.unfreezeDispatch()}async recoverInterruptedRuns(){this.recoveryPass??=this.recoveryCoordinator.recoverAll(),await this.recoveryPass}getPendingRecoveryCount(){return this.runJournal.loadPendingReconciliation().records.length}revokeProjectFsHandles(){this.projectFsHandleStore.revokeAll()}async commitRecoveryTerminal(e,t){const s=this.sessions.get(e.sessionId);s&&(s.currentRunId=null,s.currentRunPhase=null,s.journalRunId=null,s.heartbeatTimer&&(clearInterval(s.heartbeatTimer),s.heartbeatTimer=null)),this.runTextAcc.delete(`${e.sessionId}:${e.providerRunId??e.runId}`),this.publishSessionActivity(e.sessionId,null);const n=Ve();Ae(e.sessionId,{id:`upgrade-recovery-terminal-${e.runId}`,sessionId:e.sessionId,role:"agent",ts:Date.now(),payload:JSON.stringify({v:1,type:"error",content:n,error:!0,recoveryState:t.result,recoveryReason:t.reason})}),we({sessionId:e.sessionId,agentType:e.agentType,sessionMode:e.sessionMode,workDir:e.workDir,agentSessionId:e.agentSessionId,modelId:e.modelId,status:"failed",attentionId:`upgrade-recovery:${e.runId}`,lastActivityAt:new Date().toISOString()}),this.managerRuntime.noteAgentEvent(e.sessionId,{state:"error",runId:e.providerRunId??e.runId,seq:e.lastObservedEventSeq+1,message:n}),m(this.client);const r=e.lastObservedEventSeq+1;this.client.sendAgentEvent({type:"event",event:"agent",payload:t.result==="interrupted_by_upgrade"?{state:"interrupted_by_upgrade",sessionId:e.sessionId,runId:e.providerRunId??e.runId,seq:r,reason:t.reason}:{state:"recovery_failed",sessionId:e.sessionId,runId:e.providerRunId??e.runId,seq:r,reason:t.reason,...t.message?{message:t.message}:{}},seq:r,id:`agent-recovery-terminal-${e.runId}`}),this.chatQueue.noteTerminal(e.sessionId)}setManagedRoomTurnPreparer(e){this.chatQueue.setManagedRoomTurnPreparer(e)}setManagedAgentDirectTurnPreparer(e){this.chatQueue.setManagedAgentDirectTurnPreparer(e)}setManagedRecoveryPreparer(e){this.prepareManagedRecovery=e}async enqueueManagedRoomBatch(e){const t=e.map(s=>{const n=u().find(r=>r.sessionId===s.params.sessionId);return{context:s.context,params:{...s.params,modelId:n?.modelId??s.params.modelId,sessionMode:n?.sessionMode??s.params.sessionMode,managerConfig:n?.managerConfig??s.params.managerConfig,managerDefaultWorkerAgentType:n?.managerDefaultWorkerAgentType??s.params.managerDefaultWorkerAgentType,managerDefaultWorkerModelId:n?.managerDefaultWorkerModelId??s.params.managerDefaultWorkerModelId}}});await this.chatQueue.enqueueManagedRoomBatch(t)}async retireManagedRoomSession(e){this.chatQueue.purgeSession(e),await be(this.getRuntime(),e)}discardPendingManagedRoomMessages(e){return this.chatQueue.discardPendingManagedRoomMessages(e)}async synchronizeSessionDeletions(){await this.deletionSynchronizer.synchronize()}async applySessionDeletion(e){const t=new Me({daemonInstallationId:d()});let s=[];try{s=xe(e.sessionId,{records:u()})}catch(r){console.warn("[session.deletions] local native source lookup failed",{error:r instanceof Error?r.message:String(r)})}t.recordSession(e);for(const r of[...e.sources,...s]){const l=t.find(r.agentType,r.sourceSessionKey);l&&l.sessionId!==e.sessionId||t.record({...e,...r})}this.runJournal.markSessionAborted(e.sessionId),this.recoveryBarrier.end(e.sessionId);const n=this.sessions.get(e.sessionId);if(n){this.revokeManagedRoomToken(n);try{await n.adapter.stop()}catch{}this.sessions.delete(e.sessionId)}this.historySubscriptions.closeSession(e.sessionId),this.nativeFusion?.handleSessionDeleted(e.sessionId),this.chatQueue.purgeSession(e.sessionId),De(e.sessionId),Se(e.sessionId),ke(e.sessionId),this.runTextAcc.delete(e.sessionId),this.publishSessionActivity(e.sessionId,null),this.nativeCleanupOutbox.enqueue(e),this.nativeCleanupOutbox.kick()}publishSessionActivity(e,t){this.client.sendEvent({type:"event",event:"session.activity",payload:{sessionId:e,activity:t}})}async handleExternalTerminal(e){const t=this.sessions.get(e);t&&(t.journalRunId&&(this.recoveryCoordinator.completeFromProvider(e,t.journalRunId),t.journalRunId=null),this.sessions.delete(e),this.revokeManagedRoomToken(t),t.heartbeatTimer&&clearInterval(t.heartbeatTimer),t.adapter.removeAllListeners(),await t.adapter.stop().catch(()=>{})),this.chatQueue.noteTerminal(e)}async publishManagedActivitySnapshots(){for(const[e,t]of this.sessions.entries()){if(t.heartbeatTimer||!t.currentRunId||!t.adapter.getStatus)continue;const s=await t.adapter.getStatus().catch(()=>null);if(!s?.active||!s.runPhase)continue;const n=new Date().toISOString();this.publishSessionActivity(e,{sessionId:e,runId:s.runId||t.currentRunId,runPhase:s.runPhase,startedAt:new Date(t.lastActiveAt).toISOString(),updatedAt:n,canStop:s.canStop??!0});const r=t.heartbeatSeq++;this.client.sendAgentEvent({type:"event",event:"agent",payload:{state:"heartbeat",sessionId:e,runId:s.runId||t.currentRunId,seq:r,runPhase:s.runPhase,canStop:s.canStop??!0},seq:r,id:`agent-status-${s.runId||t.currentRunId}-${Date.now()}`})}}reloadCustomAgents(){for(const t of S())t.startsWith("custom:")&&k(t);const e=A();for(const[t,s]of Object.entries(e.customAgents??{}))pe(t,s);fe(ge(),new Set(Object.keys(e.customAgents??{})))}async handleReq(e,t={}){const s=this.getRuntime();let n;this.activeRequests++;try{switch(e.method){case"schedule.deliver":if(!this.scheduleHandler)throw new Error("schedules_unavailable");await this.scheduleHandler(e);break;case"chat.send":if(e.params.scheduledDelivery)throw new Error("schedule_source_untrusted");o(e.params),this.recoveryBarrier.isDispatchFrozen()||this.recoveryBarrier.isRecovering(String(e.params.sessionId??""))?n={durableQueueHandoff:await this.chatQueue.handleEnqueue({...e,method:"chat.enqueue"})}:await O(s,e);break;case"chat.enqueue":o(e.params),n={durableQueueHandoff:await this.chatQueue.handleEnqueue(e)};break;case"chat.queue.get":o(e.params),await this.chatQueue.handleGet(e);break;case"chat.queue.edit":o(e.params),await this.chatQueue.handleEdit(e);break;case"chat.queue.delete":o(e.params),await this.chatQueue.handleDelete(e);break;case"chat.queue.promote":o(e.params),await this.chatQueue.handlePromote(e);break;case"chat.abort":o(e.params),await z(s,e);break;case"session.refresh":o(e.params),await W(s,e);break;case"session.history.open":this.historySubscriptions.handleOpen(e);break;case"session.history.sync":this.historySubscriptions.handleSync(e);break;case"session.history.page":this.historySubscriptions.handlePage(e);break;case"session.history.close":this.historySubscriptions.handleClose(e);break;case"session.body.replica.subscribe":this.historySubscriptions.handleReplicaSubscribe(e);break;case"session.body.replica.unsubscribe":this.historySubscriptions.handleReplicaUnsubscribe(e);break;case"session.history":this.client.sendRes({type:"res",id:e.id,ok:!1,error:"upgrade_required"});break;case"session.message.status":U(s,e);break;case"session.tool.detail":await _(s,e);break;case"voice.session.body.window":$(s,e);break;case"session.title.set":await H(s,e);break;case"room.agent.bind-managed":await ye(s,this.managedRoomBinder,e);break;case"room.agent.restart-managed":await Re(s,this.managedRoomBinder,e);break;case"fs.ls":await N(s,e);break;case"project.fs.open":case"project.fs.list":case"project.fs.read":case"project.fs.close":await Oe(this.client,this.projectFsHandleStore,e,this.trustedProjectFsRequestResolver);break;case"fs.read":await G(s,e);break;case"fs.write":await X(s,e);break;case"fs.export.markdown-pdf":await se(s,e);break;case"fs.export.markdown-pdf.setup":await te(s,e);break;case"fs.archive.zip":await ae(s,e);break;case"fs.rename":await K(s,e);break;case"fs.transfer.start":await ee(s,e);break;case"fs.transfer.chunk":await Y(s,e);break;case"fs.transfer.finish":await q(s,e);break;case"fs.transfer.abort":await Z(s,e);break;case"region.probe":await re(s,e);break;case"region.switch":await ne(s,e);break;case"upgrade.start":await I(this.client,e.id,e.params.version,{currentVersion:this.cliVersion,confirmedMajor:e.params.confirmedMajor===!0,prepareForUpgrade:r=>this.prepareForUpgrade(r),cancelUpgradePreparation:()=>this.cancelUpgradePreparation(),shutdownAfterHandoff:()=>{setTimeout(()=>process.kill(process.pid,"SIGTERM"),100).unref?.()}});break;case"upgrade.status":await T(this.client,e.id,{currentVersion:this.cliVersion});break;case"upgrade.set-policy":await ie(s,e);break;case"machine.remote-access.pause":await V(this.client,this.remoteAccessPauseController,e);break;case"agents.refresh":await P(s,e);break;case"agent.permission.respond":await Be(s,e);break;case"agent.auth.start":case"agent.auth.logout":case"agent.session-options.get":case"agent.external-sessions.list":case"agent.external-sessions.import":case"agent.external-sessions.close":case"agent.external-sessions.delete":await We(s,e);break;case"models.refresh":await C(s,e);break;case"agent.config.get":await E(s,e);break;case"agent.config.upsert":await j(s,e);break;case"agent.config.clear":await F(s,e);break;case"agent.config.test":await Q(s,e);break;case"agent.workspace.validate":await J(s,e);break;case"agent.capabilities.list":await D(s,e);break;case"skill.list":case"skill.install":case"skill.doctor":case"skill.setup":case"skill.use":this.client.sendRes({type:"res",id:e.id,ok:!1,error:"feature_retired"});break;case"session.wechat-rpa.channel.get":case"session.wechat-rpa.channel.upsert":case"session.wechat-rpa.channel.sync":case"manager.wechat-rpa.channel.get":case"manager.wechat-rpa.channel.upsert":case"manager.wechat-rpa.channel.sync":this.client.sendRes({type:"res",id:e.id,ok:!1,error:"feature_retired"});break;default:this.client.sendRes({type:"res",id:e.id,ok:!1,error:`Unknown method: ${e.method}`})}}catch(r){if(t.propagateErrors)throw r;this.client.sendRes({type:"res",id:e.id,ok:!1,error:r instanceof Error?r.message:String(r)})}finally{this.activeRequests--}return n}evictIdleSessions(){if(this.sessions.size<$e)return;let e=null;for(const[t,s]of this.sessions)(!e||s.lastActiveAt<e.session.lastActiveAt)&&(e={key:t,session:s});e&&(this.revokeManagedRoomToken(e.session),e.session.heartbeatTimer&&(clearInterval(e.session.heartbeatTimer),e.session.heartbeatTimer=null),e.session.adapter.removeAllListeners(),e.session.adapter.stop().catch(()=>{}),this.sessions.delete(e.key))}resolvePath(e){return me(e)}resolveAuthorizedPath(e,t){return he(e,le(t))}async resolveAuthorizedPathAsync(e,t){return de(e,await ue(t))}async cleanup(){this.chatQueue.stop(),this.projectFsHandleStore.revokeAll(),this.acpDiscoveryWatcher.stop(),this.nativeFusion?.setExternalTerminalHandler?.(null),this.nativeCleanupOutbox.stop(),this.historySubscriptions.closeAll(),this.activityProbeTimer&&(clearInterval(this.activityProbeTimer),this.activityProbeTimer=null),this.attachmentCleanupTimer&&(clearInterval(this.attachmentCleanupTimer),this.attachmentCleanupTimer=null);for(const[,e]of this.sessions)this.revokeManagedRoomToken(e),e.heartbeatTimer&&(clearInterval(e.heartbeatTimer),e.heartbeatTimer=null),e.adapter.removeAllListeners(),await e.adapter.stop().catch(()=>{});this.sessions.clear(),this.runTextAcc.clear(),L(this.getRuntime()),await this.managerRuntime.stop(),h(null)}revokeManagedRoomToken(e){const t=e.managedRoomContextToken;e.managedRoomContextToken=null,t&&this.managedRoomContextRevoker?.(t)}}export{Ns as SessionManager,Xs as resolveSessionWorkDir,Ve as upgradeRecoveryVisibleMessage};
|