grix-connector 4.11.13 → 4.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -2
- package/dist/adapter/acp/acp-adapter.js +12 -12
- package/dist/adapter/claude/claude-bridge-server.js +1 -1
- package/dist/adapter/claude/claude-tools.js +1 -1
- package/dist/adapter/claude/claude-worker-client.js +1 -1
- package/dist/adapter/claude/mcp-http-launcher.js +2 -2
- package/dist/adapter/claude/result-timeout.js +1 -1
- package/dist/assets/dsh-bridge/grix-dsh-bridge-4.12.0.tgz +0 -0
- package/dist/assets/dsh-bridge/manifest.json +6 -6
- package/dist/bridge/acp-custom-toolbar.js +1 -0
- package/dist/bridge/bridge.js +2 -2
- package/dist/bridge/cwd-policy.js +1 -0
- package/dist/bridge/session-control-open.js +1 -1
- package/dist/bridge/text-command-session-control.js +1 -1
- package/dist/core/access/allowlist-store.js +1 -1
- package/dist/core/file-ops/list-files.js +1 -1
- package/dist/core/mcp/tools.js +1 -1
- package/dist/core/observability/sentry-worker.js +1 -0
- package/dist/core/observability/sentry.js +2 -1
- package/dist/grix.js +8 -8
- package/dist/log.js +2 -2
- package/dist/manager.js +1 -1
- package/dist/mcp/stream-http/config.js +1 -1
- package/dist/mcp/stream-http/connection-binding.js +1 -1
- package/dist/mcp/stream-http/tool-executor.js +1 -1
- package/dist/mcp/stream-http/tool-registry.js +1 -1
- package/dist/mcp/stream-http/tool-schemas.js +1 -1
- package/dist/service/service-manager.js +2 -2
- package/openclaw-plugin/index.js +57 -1
- package/package.json +1 -1
- package/dist/assets/dsh-bridge/grix-dsh-bridge-4.11.13.tgz +0 -0
package/dist/bridge/bridge.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import R from"node:path";import{tmpdir as F}from"node:os";import{createHash as x,randomUUID as k}from"node:crypto";import{ConnectionManager as U}from"../core/aibot/index.js";import{AUDIT_LOCAL_ACTION_TYPES as q}from"../core/aibot/types.js";import{ClaudeAdapter as L}from"../adapter/claude/index.js";import{CodexAdapter as M}from"../adapter/codex/index.js";import"../adapter/claude/session-history.js";import"../adapter/codex/session-history.js";import"../adapter/pi/session-history.js";import"../adapter/opencode/session-history.js";import"../adapter/codewhale/session-history.js";import"../adapter/deepseek-harness/session-history.js";import{PiAdapter as N}from"../adapter/pi/index.js";import{AcpAdapter as S}from"../adapter/acp/index.js";import{OpenHumanAdapter as W}from"../adapter/openhuman/index.js";import{CursorAdapter as G}from"../adapter/cursor/index.js";import{CodeWhaleAdapter as j}from"../adapter/codewhale/index.js";import{OpenCodeAdapter as T}from"../adapter/opencode/index.js";import{AgyAdapter as H}from"../adapter/agy/index.js";import{DshJsonRpcAdapter as K}from"../adapter/deepseek-harness/index.js";import{LOCAL_ACTION_TYPES as f,SESSION_CONTROL_ERROR_CODES as $,SESSION_CONTROL_VERBS as E,SESSION_MODE_IDS as z}from"../adapter/claude/protocol-contract.js";import{isAuditLocalActionType as J}from"../audit/query/audit-local-actions.js";import{shouldEnableRawApiCapture as D}from"../audit/raw-capture/types.js";import{buildWireSkills as Y}from"../core/skill-sync/sync-state.js";import{executeEventTool as V}from"../core/mcp/event-tool-executor.js";import{fetchAvailableModels as X}from"../adapter/claude/model-list.js";import{applyProxyEnv as Z,getProxyManager as ee}from"../core/proxy/index.js";import{getKiroRelaySpawnEnv as te}from"../core/proxy/kiro-relay.js";import{supportsKiroCwRelay as ne}from"../core/config/provider-env.js";import{buildProviderEnv as ie}from"../core/config/provider-env.js";import{isClaudeDirectEnv as se,stripGrixRelayEnv as oe}from"../core/config/claude-direct-env.js";import{sweepNativeProviderResidue as re}from"./native-provider-sweep.js";import{scanCodexSessions as ae}from"../adapter/codex/session-scanner.js";import{scanClaudeSessions as de}from"../adapter/claude/session-scanner.js";import{resolveAcpAgentTypes as le,scanAcpSessions as ce,scanReasonixSessionTitles as he}from"../adapter/acp/session-scanner.js";import{scanPiSessions as ue}from"../adapter/pi/session-scanner.js";import{scanCodeWhaleSessions as pe}from"../adapter/codewhale/session-scanner.js";import{scanCursorSessions as ge}from"../adapter/cursor/session-scanner.js";import{scanOpenCodeSessions as fe}from"../adapter/opencode/session-scanner.js";import{agentIdOf as me}from"../adapter/shared/native-provider-config.js";import{scanDshSessions as ve}from"../adapter/deepseek-harness/session-scanner.js";import{SessionScanCache as v,resolveCodexLeafDirs as _e,resolveClaudeLeafDirs as Se,resolveAcpLeafDirs as Ce,resolvePiLeafDirs as be,resolveCodeWhaleLeafDirs as Ae,resolveCursorLeafDirs as Ee,resolveOpenCodeLeafDirs as we,resolveDshLeafDirs as ye,resolveReasonixLeafDirs as Re}from"./session-scan-cache.js";import{log as h,ConversationLog as ke,AgentApiPacketLog as Te,BridgeEventLog as Pe,GRIX_PATHS as w}from"../core/log/index.js";import{routeSessionControlCommand as xe,routeSessionControlLocalAction as Le}from"./session-control-router.js";import{maybeOfferCliInstall as Me,handleCliInstallQuestionReply as He,handleCliInstallInteractionReply as $e,runConfirmedCliInstall as De}from"./cli-install-flow.js";import{handleEventCancel as Qe,waitForEventDone as Ie,handleAibotStop as Oe,killAndResumeStopSlot as Be,handleAibotRevoke as Fe}from"./event-stop.js";import{handleConfigureGatewayProvider as Ue,getAuditLocalActionHandler as qe,handleAuditLocalAction as Ne,handleConnectorRollback as We,getRelayStateSyncer as Ge,relayStateSyncOnConnect as je,reportRelayStateLocalChange as Ke,handleApplyRelayState as ze,fetchRelayCredential as Je,isSharedInstance as Ye}from"./connector-ops.js";import{CONNECTOR_ADMIN_ACTION_TYPE as Ve,handleConnectorAdminLocalAction as Xe}from"./remote-admin.js";import{unbindSession as Ze,handleUnbindTextCommand as et,handleUnbindLocalAction as tt,handleListSessionsTextCommand as nt,handleListSessionsLocalAction as it,handleSyncHistoryLocalAction as st}from"./session-list.js";import{handleCodexSessionControlOpen as ot,handleSessionControlForPool as rt,handleSessionControlLocalActionForPool as at,handleCodexSessionControlLocalActionOpen as dt,handleCursorSessionControlLocalActionOpen as lt,handlePiSessionControlOpen as ct,handlePiSessionControlRestart as ht,handlePiSessionControlRestartLocalAction as ut,syncOpenCodeBinding as pt,isWorkspaceFreeClient as gt,ensureDefaultBindingForWorkspaceFreeClient as ft,bindSessionForPool as mt,deferredCallbacks as vt,handleOpenHumanSessionControlOpen as _t,handleCodeWhaleSessionControlOpen as St,handleCodeWhaleSessionControlLocalActionOpen as Ct,handleDeepSeekSessionControlLocalActionOpen as bt}from"./session-control-open.js";import{handleGetSessionUsage as At,handleThreadCompact as Et}from"./session-usage.js";import{handleSkillDeleteLocalAction as wt,handleSkillUploadLocalAction as yt,handleSkillEnableLocalAction as Rt,handleSkillRefreshLocalAction as kt,handleSkillDisableLocalAction as Tt,computeSkillReport as Pt,reportSessionSkills as xt,skillsSyncGroupKey as Lt,forceRefreshSkills as Mt,adoptSkillsWireHashFromDisk as Ht,buildLibrarySkillsReport as $t,skillLookupEnv as Dt}from"./skill-actions.js";import{resolveToolbarSelection as Qt,persistToolbarSelection as Q}from"./toolbar-selection.js";import{normalizeClaudeModeId as It,handleExecCommandOptions as Ot,resolveSessionModelId as Bt,resolveSessionModeId as Ft,resolveCursorSessionModeId as Ut,resolveClaudeSessionEffort as qt,resolveClaudeSessionModeId as Nt,currentClaudeModeId as Wt,buildCursorToolbarMeta as Gt,buildAgyToolbarMeta as jt,buildAgyQuotaMeta as Kt,sendAgyBindingCard as zt,refreshAndPushAgyQuota as Jt,handleAgySetModel as Yt,buildClaudeToolbarMeta as Vt}from"./toolbar-meta.js";import{resolveProviderQuotaSource as Xt,maybeQueryProviderQuota as Zt,startProviderQuotaTimer as en,stopProviderQuotaTimer as tn,refreshAndPushProviderQuota as nn,pushProviderQuotaToBindings as sn,enrichProviderQuotaMeta as on,providerQuotaMetaPayload as rn,refreshProviderQuotaForSession as an,refreshQuotaAfterModelSwitch as dn,doRefreshQuotaAfterModelSwitch as ln}from"./provider-quota.js";import{handleGetRateLimits as cn,resolveRateLimitWakeSessionId as hn,wakeRateLimitSlot as un}from"./rate-limits.js";import{RevokeHandler as pn}from"./revoke-handler.js";import{AdapterPool as gn}from"./adapter-pool.js";import{parseSessionControlCommand as fn}from"./session-controller.js";import{isOpenSessionDirectiveMessage as mn,parseExecApprovalResolutionMessage as vn,parseAgentQuestionReplyMessage as _n}from"../core/protocol/interaction-parser.js";import{rejectUnusableAuditOptions as Sn}from"./inbound-audit-gate.js";import{interceptUnboundInboundEvent as Cn}from"./inbound-binding-gate.js";import{dispatchSessionControlTextCommand as bn}from"./text-command-session-control.js";import{dispatchSessionControlLocalAction as An}from"./local-action-session-control.js";import{handleCreateFolderLocalAction as En,handleFileListLocalAction as wn}from"./local-action-files.js";import{handleAcpToolbarLocalAction as yn,persistToolbarSelection as Rn}from"./local-action-toolbar.js";import{buildOpenedBindingResult as kn,ensureImportedAgentSession as Tn,hasDiskScanner as Pn,normalizePathForCompare as xn,providerKeyForAdapter as Ln,resolveAgentSessionId as Mn,resolveOrphanTitle as Hn,setResolvedAgentSessionId as $n}from"./session-identity.js";import{buildDshOpenedToolbarMeta as Dn,dshCatalogDataRoot as Qn}from"./dsh-toolbar.js";import{ensureSlotStarted as In,failSessionOpen as On,getClaudeWorkerStatus as Bn,refreshClaudeWorkerStatusCard as Fn,resolveCwdForBinding as Un}from"./session-open-helpers.js";import{handleAcpSetModel as qn,handleAcpSetMode as Nn,resolveAcpInitialDefaults as Wn}from"./acp-toolbar-persist.js";import{SessionBindingStore as Gn}from"../core/persistence/session-binding-store.js";import{serveLocalFile as jn}from"../core/files/index.js";import{uploadReplyFileToAgentMedia as Kn}from"../core/protocol/agent-api-media.js";import{attachmentHostFromWsUrl as zn,buildInboundAttachmentsJson as Jn,materializeInboundAttachments as Yn}from"../core/protocol/inbound-attachments.js";import{ActiveEventStore as Vn}from"../core/persistence/active-event-store.js";import{PendingEventCoordinator as Xn}from"./pending-event-coordinator.js";import{LifecycleBarrier as Zn}from"./lifecycle-barrier.js";import{QUEUE_COMPOSING_TTL_MS as ei}from"./event-queue.js";import{DEFAULT_CONNECTOR_RUNTIME_CONFIG as ti,applyConnectorRuntimeConfigPatch as ni,extractConnectorRuntimeConfigPatch as ii}from"./runtime-config.js";import{DEFAULT_QUOTE_TRIGGER_BY_ADAPTER as si,SendController as oi}from"./send-controller.js";import{providerQuotaToRateLimits as ri,providerQuotaToCodexRateLimits as ai}from"../core/provider-quota/index.js";import{buildToolUseCard as C,buildToolResultCard as b,buildDshOnlineToolCard as di,buildLocalGrixCardLink as I}from"./tool-card-utils.js";import{planRawEventDelivery as li,buildAuxiliaryDetailText as ci}from"./raw-event-delivery.js";import{DeferredEventManager as hi}from"./deferred-events.js";import{buildAgentProbeResult as ui,PROBE_CACHE_TTL_STATIC_MS as pi,PROBE_CACHE_TTL_FULL_MS as gi}from"./probe-helper.js";import{BridgeAuditController as fi}from"../audit/integration/bridge-audit-controller.js";import{isSettlableAuditProducer as mi,NoopAuditProducer as vi}from"../audit/producer/audit-producer.js";import{buildAuditStatePayload as O,AuditPreparationFailedError as _i,AuditTurnScopeUnsupportedError as Si}from"../audit/core/audit-state.js";import{extractAuditOptions as B,freezeAuditOptions as Ci,stripAuditOptions as bi}from"../audit/core/audit-options.js";import{AuditSessionOptionsError as Ai}from"../audit/core/audit-session-registry.js";import{waitForIdle as Ei,formatWaitDuration as wi}from"../core/upgrade/idle-wait.js";const yi=600*1e3,Ri=1800*1e3,ki=5*6e4,Ti=60*1e3,Pi=4e3;function xi(P,e,n){const r=x("sha256").update(P).update("\0").update(e).update("\0").update(n).digest("hex");return R.join(w.data,"audit-source","reasonix",`${r}.jsonl`)}const Li=new Set(["claude","codex","cursor","codewhale","opencode","pi","openhuman","agy","acp","deepseek-harness"]),y=3;class _o{config;name;aibotHandle;aibotConfig;pool;stopped=!1;startupAbortController=new AbortController;stopPromise=null;dropPendingEventsRequested=!1;pendingEventsDropped=!1;revokeHandler=new pn;sessionBindings=new Map;deferredMgr;sendCtrl=new oi(ti);bindingStore;globalConfigStore;upgradeTrigger=null;daemonShutdownRequester=null;lifecycleBusyChecker=null;lifecycleAdmissionCloser=null;lifecycleAdmissionRestorer=null;installAgentHandler=null;remoteAdminPorts=null;pendingCliInstalls=new Map;agentDeletedHandler=null;shareSetHandler=null;skillSyncHandler=null;providerConfigHandler=null;relayStateApplyPorts=null;relayStateSyncer=null;agentProfile={agentName:"",introduction:""};agentSystemPrompt="";activeEventStore;pendingEvents;pendingStartedEventIds=new Set;lifecycleBarrier=new Zn;cachedRateLimits=null;cachedRateLimitsSampledAtMs=null;cachedCodexContextWindow=null;cachedCodexTokenUsage=null;cachedCodexUsageSampledAtMs=null;cachedAcpContextWindow=null;cachedAcpContextWindowSampledAtMs=null;cachedClaudeRateLimitState=null;cachedProviderQuota=null;cachedProviderQuotaSampledAtMs=null;cachedProviderQuotaKey=null;sessionProviderHints=new Map;sessionProviderQuotas=new Map;sessionProviderMeta=new Map;lastModelSwitchQuotaRefresh=null;claudeWorkerStatus=new Map;lastReportedSkillsHash="";lastReportedSkillsWireHash="";conversationLog=null;packetLog=null;providerQuotaTimer=null;eventSessionIndex=new Map;inflightEvents=new Map;restartCount=new Map;selfDrivenSessions=new Set;selfDrivenLabels=new Map;probeCache=new Map;auditController;auditLocalActionHandler=null;sessionScanCache;reasonixTitleScan=null;isRateLimitsCacheFresh(e){if(!Number.isFinite(e))return!1;const n=Number(e);return n>0&&Date.now()-n<=Ti}resolveProviderQuotaSource(e){return Xt(this,e)}maybeQueryProviderQuota(e=!1,n){return Zt(this,e,n)}startProviderQuotaTimer(){en(this)}stopProviderQuotaTimer(){tn(this)}refreshAndPushProviderQuota(e=!1){return nn(this,e)}pushProviderQuotaToBindings(e,n=!1){sn(this,e,n)}enrichProviderQuotaMeta(e,n="standard",r=this.cachedProviderQuota,i=this.cachedProviderQuotaSampledAtMs){return on(this,e,n,r,i)}providerQuotaMetaPayload(e,n,r){return rn(this,e,n,r)}refreshProviderQuotaForSession(e,n,r){return an(this,e,n,r)}refreshQuotaAfterModelSwitch(e,n,r){dn(this,e,n,r)}doRefreshQuotaAfterModelSwitch(e,n,r){return ln(this,e,n,r)}getFreshClaudeRateLimitState(){const e=this.cachedClaudeRateLimitState;return e&&this.isRateLimitsCacheFresh(e.sampledAt)?e:null}getFreshCodexGlobalRateLimitCache(){const e=this.cachedRateLimits,n=this.cachedCodexContextWindow,r=this.cachedCodexTokenUsage;return{sampledAt:Math.max(this.cachedRateLimitsSampledAtMs??0,this.cachedCodexUsageSampledAtMs??0)||null,rateLimits:e,contextWindow:n,tokenUsage:r,hasData:!!(e||n||r)}}getStatus(){const e=this.pool?.getStatus()??{total:0,ready:0,busy:0};return{name:this.name,agentId:this.config.aibot.agentId,alive:!this.stopped,busy:e.busy>0,wsConnected:this.aibotHandle?.status==="ready",exhausted:this.pool?[...this.pool.getAllSlots()].some(n=>n.respawn.exhausted):!1,adapterType:this.config.adapterType??"acp",clientType:this.config.aibot.clientType,pool:e}}hasPendingWork(){return this.pool?.hasPendingWork()??!1}hasPendingOrBackgroundWork(){return this.lifecycleBarrier.hasActiveAdmissions()||(this.pool?.hasPendingOrBackgroundWork()??!1)}describePendingOrBackgroundWork(){const e=this.lifecycleBarrier.describeActiveAdmissions().map(({label:r,heldMs:i})=>({source:"admission",agent:this.name,label:r,...i>ki?{suspect:`admission held for ${wi(i)}`}:{}})),n=(this.pool?.describePendingOrBackgroundWork()??[]).map(r=>({...r,agent:this.name}));return[...e,...n]}async waitUntilLifecycleIdle(e){return Ei({describeBusy:()=>this.lifecycleBusyChecker?.()??this.describePendingOrBackgroundWork(),isStopped:()=>this.stopped,closeAdmission:()=>this.closeLifecycleAdmissionForRestart(),reopenAdmission:()=>this.reopenLifecycleAdmissionAfterAbort(),budgetMs:Ri,log:(n,r)=>{n==="warn"?h.warn(this.name,`${e}: ${r}`):h.info(this.name,`${e}: ${r}`)}})}reopenLifecycleAdmissionAfterAbort(){if(this.lifecycleAdmissionRestorer){this.lifecycleAdmissionRestorer();return}this.openLifecycleAdmission()}relayEnvStale=!1;relayEnvSettledHandler;async recycleAdaptersForRelayChange(){if(!this.pool)return this.relayEnvStale=!1,!0;if(this.hasPendingWork())return this.relayEnvStale=!0,h.info(this.name,"relay changed but agent is busy; adapters keep the old env until the next message (marked stale)"),!1;const e=[...this.pool.getAllSlots()];let n=0,r=!1;for(const i of e){if(this.hasPendingWork())return this.relayEnvStale=!0,h.info(this.name,"new work arrived while recycling; remaining adapters stay stale until the next message"),!1;let t=!1;await this.pool.removeSlot(i.sessionId).catch(s=>{r=!0,t=!0,h.warn(this.name,`failed to recycle adapter slot ${i.sessionId} after relay change: ${s}`)}),t||(n+=1)}return n>0&&h.info(this.name,`recycled ${n} adapter slot(s) so the new Grix relay env takes effect`),r?(this.relayEnvStale=!0,!1):(this.relayEnvStale=!1,this.relayEnvSettledHandler?.(),!0)}setRelayEnvSettledHandler(e){this.relayEnvSettledHandler=e}providerResolver;setProviderResolver(e){this.providerResolver=e}hasStaleRelayEnv(){return this.relayEnvStale}markRelayEnvStale(){this.relayEnvStale=!0}async probe(e={}){const n=e.conversation?"full":"static",r=e.conversation?gi:pi;if(!e.fresh){const a=this.probeCache.get(n);if(a&&Date.now()-a.sampledAt<r)return{...a.result,cached:!0}}const i=this.config.adapterType??"acp",t=this.createAdapter(i,"__probe__"),s=e.conversation&&i==="acp"?()=>this.runAcpConversationProbe(t,e.timeoutMs??1e4):void 0;let o;try{o=await ui({adapter:t,agentName:this.name,clientType:this.config.aibot.clientType,adapterType:i,providerBaseUrl:this.config.providerBaseUrl??null,opts:e,launchConversationProbe:s})}finally{t.stop().catch(()=>{})}return this.probeCache.set(n,{result:o,sampledAt:o.probed_at}),o}async runAcpConversationProbe(e,n){const r=Date.now(),i="__probe__",t=`probe-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,s=this.config.agent.cwd||F(),o=()=>Date.now()-r;try{await e.start()}catch(u){return{attempted:!0,ok:!1,latency_ms:o(),error:{code:"conversation_failed",message:`start failed: ${u instanceof Error?u.message:String(u)}`}}}if(!e.isAlive())return{attempted:!0,ok:!1,latency_ms:o(),error:{code:"process_not_started",message:"agent process not alive"}};if(e instanceof S)try{await e.bindSession(i,s)}catch{}let a=null;const l=new Promise(u=>{a=g=>{g===t&&u()},e.on("eventDone",a)});e.deliverInboundEvent({event_id:t,session_id:i,content:"ping",msg_id:t}),e.deliverStopEvent(t,i);let d=null;const c=await Promise.race([l.then(()=>!1),new Promise(u=>{d=setTimeout(()=>u(!0),n)})]);return d&&clearTimeout(d),a&&e.removeListener("eventDone",a),c?{attempted:!0,ok:!1,latency_ms:o(),error:{code:"conversation_timeout",message:`no eventDone within ${n}ms`}}:{attempted:!0,ok:!0,latency_ms:o()}}constructor(e,n,r=new vi){this.config=e,this.auditController=new fi(r,{onAuditState:t=>{try{this.aibotHandle.sendAuditState(O(t,Date.now()))}catch{}}}),mi(r)&&r.addJobSettledHandler((t,s)=>{this.auditController.handleJobSettled(t,s)}),this.name=e.name;const i=e.adapterType??"acp";if(this.sendCtrl.setDefaultQuoteTrigger(si[i]),this.aibotConfig={...e.aibot,...i==="claude"?{localActions:e.aibot.localActions??["session_control","claude_interaction_reply","get_session_usage","get_rate_limits","set_model","set_mode","set_reasoning_effort","thread_compact","get_agent_global_config",...q]}:{}},e.eventQueue&&(this.aibotConfig.concurrency={max_concurrent:e.eventQueue.maxConcurrent,max_queued:e.eventQueue.maxQueued,queue_timeout_ms:e.eventQueue.queueTimeoutMs,cancelable_queued:e.eventQueue.cancelableQueued,cancelable_running:e.eventQueue.cancelableRunning}),this.conversationLog=e.logDir?new ke(e.logDir):null,this.packetLog=e.logDir?new Te(e.logDir):null,this.bindingStore=new Gn(e.bindingsPath,e.legacyBindingsPath),this.bindingStore.load(),this.globalConfigStore=n??null,this.deferredMgr=new hi(this.name),this.activeEventStore=e.activeEventStorePath?new Vn(e.activeEventStorePath):null,this.pendingEvents=new Xn(e.pendingEventStorePath),i==="codex")this.sessionScanCache=new v(ae,_e);else if(i==="claude")this.sessionScanCache=new v(de,Se);else if(i==="pi"){const t=e.agent.env?.PI_CODING_AGENT_DIR;this.sessionScanCache=new v(()=>ue(void 0,t),()=>be(void 0,t))}else if(i==="codewhale")this.sessionScanCache=new v(pe,Ae);else if(i==="cursor")this.sessionScanCache=new v(ge,Ee);else if(i==="opencode"){const t=me(e.agent.command||"opencode")||"opencode";this.sessionScanCache=new v(()=>fe(void 0,t),()=>we(void 0,t))}else if(i==="deepseek-harness"){const t=typeof e.adapterOptions?.dshHome=="string"?e.adapterOptions.dshHome:e.agent.env?.DSH_HOME;this.sessionScanCache=new v(()=>ve(t),()=>ye(t))}else if(i==="agy")this.sessionScanCache=new v(()=>[],()=>[]);else{e.aibot.clientType?.trim().toLowerCase()==="reasonix"&&(this.reasonixTitleScan=new v(he,Re));const t=le(e.aibot.clientType);this.sessionScanCache=t?new v(()=>ce(void 0,t),()=>Ce(void 0,t)):new v(()=>[],()=>[])}}async start(){if(this.stopped)throw new Error("agent start aborted");if(await re({agentName:this.name,adapterType:this.config.adapterType??"acp",command:this.config.agent.command,piConfigDir:this.config.agent.env?.PI_CODING_AGENT_DIR,dshHome:typeof this.config.adapterOptions?.dshHome=="string"?this.config.adapterOptions.dshHome:this.config.agent.env?.DSH_HOME,hasProvider:!!this.config.agent.provider,boundCwds:[...this.bindingStore.entries()].map(([,t])=>String(t.cwd??""))}).then(t=>{t.length>0&&h.info(this.name,`restored native provider config after relay disable: ${t.join(", ")}`)}).catch(t=>{h.warn(this.name,`native provider residue sweep failed: ${t instanceof Error?t.message:String(t)}`)}),this.stopped)throw new Error("agent start aborted");if((this.config.adapterType??"acp")==="claude"){if(await X().catch(()=>{}),this.stopped)throw new Error("agent start aborted");this.maybeQueryProviderQuota().catch(()=>{})}if(this.stopped)throw new Error("agent start aborted");const e=!!(this.config.providerBaseUrl&&this.config.providerApiKey||this.config.agent.provider?.baseUrl&&this.config.agent.provider?.apiKey),n=(this.config.adapterType??"acp")==="pi",r=(this.config.adapterType??"acp")==="opencode";if(this.config.aibot.clientType==="kiro"||this.config.aibot.clientType==="kimi"||e?(this.maybeQueryProviderQuota().catch(()=>{}),this.startProviderQuotaTimer()):(n||r)&&this.startProviderQuotaTimer(),(this.config.adapterType??"acp")==="codex"&&this.maybeQueryProviderQuota().catch(()=>{}),(this.config.adapterType??"acp")==="opencode"&&this.maybeQueryProviderQuota().catch(()=>{}),this.stopped)throw new Error("agent start aborted");if(await this.connectAibot(),this.stopped)throw this.aibotHandle?.disconnect(),new Error("agent start aborted");this.sendCtrl.bind(this.aibotHandle);const i=this.config.adapterType??"acp";if(this.pool=new gn({maxPoolSize:this.config.poolMaxSize??20,idleTimeoutMs:this.config.poolIdleTimeoutMs??18e5,eventQueue:this.config.eventQueue},t=>{const s=this.createAdapter(i,t);return s instanceof S&&s.on("acpSessionReady",o=>{this.bindingStore.setAcpSessionId(t,o),this.sessionScanCache.invalidate()}),s},(t,s)=>{this.aibotHandle.sendEventAck({event_id:t,session_id:s,received_at:Date.now()})}),this.pool.setEventStateHandler((t,s,o,a)=>{if(h.info(this.name,`[queue-debug] send event_state session=${s} event=${t} state=${o} queue_pos=${a?.queue_position??""} queue_total=${a?.queue_total??""}`),this.aibotHandle.sendEventState({event_id:t,session_id:s,state:o,content_preview:a?.content_preview,content:a?.content,queue_position:a?.queue_position,queue_total:a?.queue_total,actions:a?.actions,reason:a?.reason,held:a?.held,held_reason:a?.held_reason,updated_at:Date.now()}),this.pushQueueSnapshotForSession(s),o==="running"&&(this.pendingStartedEventIds.add(t),this.pendingEvents.remove(t).catch(l=>{h.warn(this.name,`Failed to remove running event from pending store event=${t}: ${l instanceof Error?l.message:String(l)}`)})),o==="canceled"||o==="failed"){const l=o==="canceled"?"canceled":"failed";this.aibotHandle.sendEventResult({event_id:t,status:l,msg:a?.reason,updated_at:Date.now()}),this.auditController.closeWithoutAdapter(t,l,a?.reason,{queueTerminalState:o}),this.discardEventTrackingState(t),this.pendingEvents.remove(t).catch(d=>{h.warn(this.name,`Failed to remove queued terminal event from pending store event=${t}: ${d instanceof Error?d.message:String(d)}`)})}}),this.pool.setQueueComposingHandler((t,s,o)=>{this.aibotHandle.sendSessionActivitySet({session_id:t,kind:"composing",active:s,...s?{ttl_ms:ei,ref_event_id:o}:{}})}),this.pool.setInternalErrorHandler(t=>{this.handleSessionInternalError(t).catch(s=>{h.error(this.name,`[recovery] handleSessionInternalError failed event=${t.eventId} session=${t.sessionId}: ${s instanceof Error?s.message:String(s)}`)})}),this.pool.setEventStartedHandler((t,s)=>{if(this.reportSessionSkills(s),this.config.adapterType!=="claude")return;this.claudeWorkerStatus.set(s,"busy");const o=this.bindingStore.get(s);o?.cwd&&this.aibotHandle.sendUpdateBindingCard({session_id:s,worker_status:"busy",cwd:o.cwd,meta:this.buildClaudeToolbarMeta(s)})}),this.pool.setEventDoneHandler((t,s)=>{this.markAuditAdapterClosed(t,s);const o=this.config.adapterType??"acp";if(o==="claude"){this.claudeWorkerStatus.set(s,"ready");const a=this.bindingStore.get(s);a?.cwd&&this.aibotHandle.sendUpdateBindingCard({session_id:s,worker_status:"ready",cwd:a.cwd,meta:this.buildClaudeToolbarMeta(s)})}else if(o==="agy"){const a=this.bindingStore.get(s);if(a?.cwd){const l=this.buildAgyToolbarMeta(s),d=l?.available_models??[];h.info(this.name,`[agy-toolbar-diag] eventDone push binding card session=${s} model_id=${String(l?.model_id??"")} available_models=${d.length} meta_keys=${l?Object.keys(l).join(","):"<none>"}`),this.sendAgyBindingCard(s,a.cwd,l),this.refreshAndPushAgyQuota(s)}else h.info(this.name,`[agy-toolbar-diag] eventDone skip binding card: no binding cwd session=${s}`)}}),this.pool.setSessionActivityHandler((t,s,o)=>{const a=this.selfDrivenSessions.has(t),l=this.selfDrivenLabels.get(t);s?(this.selfDrivenSessions.add(t),o&&this.selfDrivenLabels.set(t,o),this.aibotHandle.sendSessionActivitySet({session_id:t,kind:"composing",active:!0,ttl_ms:9e4})):(this.selfDrivenSessions.delete(t),this.selfDrivenLabels.delete(t),a&&this.aibotHandle.sendSessionActivitySet({session_id:t,kind:"composing",active:!1})),(a!==s||s&&o!==void 0&&o!==l)&&this.pushQueueSnapshotForSession(t)}),await this.replayPendingEventsOnStartup(),this.stopped)throw new Error("agent start aborted");this.pool.startIdleSweep(),h.info(this.name,`Ready (adapter: ${i}, poolMax: ${this.config.poolMaxSize??20})`)}requestStop(){this.stopped=!0,this.lifecycleBarrier.close(),this.startupAbortController.abort(),this.pool?.stopIdleSweep(),this.stopProviderQuotaTimer(),this.pool?.pauseAllQueues("shutdown")}async stop(e){if(e?.dropPendingEvents&&(this.dropPendingEventsRequested=!0),this.requestStop(),!this.stopPromise){const n=this.stopOnce();this.stopPromise=n,n.catch(()=>{this.stopPromise===n&&(this.stopPromise=null)})}await this.stopPromise,this.dropPendingEventsRequested&&!this.pendingEventsDropped&&await this.dropPendingEventsBestEffort()}async stopOnce(){this.lifecycleBarrier.close(),this.pool?.stopIdleSweep(),this.stopProviderQuotaTimer(),this.pool?.pauseAllQueues("shutdown");const e=this.pool?.collectActiveEventIds()??[],n=new Map(e.map(o=>[o,this.eventSessionIndex.get(o)]));e.length>0&&this.activeEventStore&&await this.activeEventStore.save(e);for(const o of e)h.info(this.name,`Canceling active event on shutdown: ${o}`),this.sendEventResultWithCleanup(o,"canceled","process shutting down");e.length>0&&await new Promise(o=>setTimeout(o,100)),this.pool?.clearActiveEventsForShutdown();for(const o of e){const a=n.get(o),l=a?this.pool?.getSlot(a):void 0;this.auditController.markAdapterClosed(o,l?.adapter.takeAuditBoundary?.(o)??{processTerminated:!0})}const r=this.deferredMgr.getAllDeferredEntries(),i=this.pool?.drainAllQueuedEvents()??[],t=this.pendingEvents.dedupe([...this.pendingEvents.replaySnapshot(),...r.map(o=>({kind:"deferred",channel:o.channel,sessionId:o.sessionId,event:o.event})),...i.map(o=>({kind:"queued",event:o}))]);let s=!1;if(this.dropPendingEventsRequested)try{await this.pendingEvents.clear(),this.pendingEventsDropped=!0}catch(o){h.warn(this.name,`Failed to clear pending event store on removal: ${o instanceof Error?o.message:String(o)}`)}else try{s=await this.pendingEvents.mergeForShutdown(t)}catch(o){h.error(this.name,`Failed to persist pending events on shutdown: ${o instanceof Error?o.message:String(o)}`)}if(!s)for(const o of t){const a=o.event;h.info(this.name,`Failing pending event on shutdown: ${a.event_id}`),this.sendEventResultWithCleanup(a.event_id,"failed","process shutting down"),this.auditController.markAdapterClosed(a.event_id,{adapterNotStarted:!0,processTerminated:!0})}this.deferredMgr.clearAll(),await this.pool?.stop(),this.aibotHandle?.disconnect(),e.length>0&&this.activeEventStore&&await this.activeEventStore.save([]),this.eventSessionIndex.clear(),this.inflightEvents.clear(),this.restartCount.clear(),this.auditController.dispose()}async dropPendingEventsBestEffort(){try{await this.pendingEvents.clear(),this.pendingEventsDropped=!0}catch(e){h.warn(this.name,`Failed to clear pending event store on removal: ${e instanceof Error?e.message:String(e)}`)}}resolveSpawnEnv(){const e=this.providerResolver?this.providerResolver():this.config.agent.provider,n=ie(this.config.agent.clientType,e),r=this.config.agent.env;let i=Object.keys(n).length>0?{...n,...r}:r;if(se(n)){const t=ee()?.getRuntimeInfo(),s={...r??{},...n},o=oe(s,{proxyUrl:t?.proxyUrl,caCertPath:t?.caCertPath,caBundlePath:t?.caBundlePath});return delete o.ANTHROPIC_API_KEY,delete o.CLAUDE_CODE_OAUTH_TOKEN,o}if(ne(this.config.agent.clientType)){const t=te(this.name);t&&(i={...i??{},...t})}return Z(i,this.name,this.config.agent.clientType)}createAdapter(e,n){switch(e){case"claude":return this.createClaudeAdapter(n);case"codex":return this.createCodexAdapter(n);case"pi":return this.createPiAdapter(n);case"openhuman":return this.createOpenHumanAdapter(n);case"codewhale":return this.createCodeWhaleAdapter(n);case"cursor":return this.createCursorAdapter(n);case"opencode":return this.createOpenCodeAdapter(n);case"agy":return this.createAgyAdapter(n);case"deepseek-harness":return this.createDshAdapter(n);default:return this.createAcpAdapter(n)}}createDshAdapter(e){const n={sendStreamChunk:(t,s,o,a,l,d,c)=>{this.sendStreamChunkByRuntimeConfig(t,s,o,a,l,d,c)},sendFinalStreamChunkReliable:this.reliableFinalWiring("deepseek-harness",Pi),sendThinking:(t,s,o)=>this.sendThinkingByRuntimeConfig(t,s,o),sendEventResult:(t,s,o,a)=>{this.sendEventResultWithCleanup(t,s,o,void 0,a)},sendRawEventEnvelope:(t,s,o,a)=>{const l=di(o);if(l){this.sendToolExecutionCard(t,s,l);return}this.deliverRawEventEnvelope(t,s,o,"deepseek",a)},sendLocalActionResult:(t,s,o,a,l)=>{this.aibotHandle.sendLocalActionResult({action_id:t,status:s,...o!==void 0?{result:o}:{},...a?{error_code:a}:{},...l?{error_msg:l}:{}},e)},sendPermissionCard:t=>{this.sendGrixApprovalCard(t,"deepseek")},sendUpdateBindingCard:(t,s,o,a)=>{this.aibotHandle.sendUpdateBindingCard({session_id:t,worker_status:s,cwd:o,meta:a})},getAgentProfile:()=>({...this.agentProfile,systemPrompt:this.agentSystemPrompt}),getAgentId:()=>this.config.aibot.agentId,queryProviderQuota:t=>this.maybeQueryProviderQuota(t===!0,{providerId:"deepseek"}),agentInvoke:async(t,s,o)=>this.platformInvoke(t,s,o),eventToolInvoke:async(t,s)=>this.invokeDshEventTool(t,s)},r=x("sha256").update(this.config.aibot.agentId).digest("hex").slice(0,24),i=this.config.adapterOptions??{};return new K({command:this.config.agent.command,args:this.config.agent.args,env:this.resolveSpawnEnv(),options:i},n,{aibotSessionId:e,bindingStore:this.bindingStore,globalConfigStore:this.globalConfigStore,agentName:this.name,dataRoot:R.join(w.data,"deepseek-harness",r),...typeof i.cordisPath=="string"?{cordisPath:i.cordisPath}:{},...typeof i.defaultModel=="string"?{defaultModel:i.defaultModel}:{},...typeof i.maxTokens=="number"?{maxTokens:i.maxTokens}:{},...typeof i.maxLineBytes=="number"?{maxLineBytes:i.maxLineBytes}:{},...i.integrationMode==="embedded_jsonrpc"||i.integrationMode==="profile_bridge"?{integrationMode:i.integrationMode}:{},...typeof i.dshHome=="string"?{dshHome:i.dshHome}:{},...typeof i.dshProfile=="string"?{dshProfile:i.dshProfile}:{},...typeof i.autoInstallBridge=="boolean"?{autoInstallBridge:i.autoInstallBridge}:{},...typeof i.autoStartProfile=="boolean"?{autoStartProfile:i.autoStartProfile}:{},...this.config.agent.provider?{provider:this.config.agent.provider}:{},promptTimeoutMs:this.config.promptTimeoutMs})}createCursorAdapter(e){const n={...this.config.adapterOptions??{}};n.bindingStore=this.bindingStore,n.aibotSessionId=e;const r=this.bindingStore.get(e),i=this.resolveSessionModelId(e);i&&(n.model=i);const t=this.resolveCursorSessionModeId(e),s=t??"full_auto";t||this.bindingStore.setCursorModeId(e,s),n.mode=s,r?.cwd&&(n.workspace=r.cwd);const o={sendStreamChunk:(a,l,d,c,u,g,p)=>{this.sendStreamChunkByRuntimeConfig(a,l,d,c,u,g,p)},sendEventResult:(a,l,d)=>{this.sendEventResultWithCleanup(a,l,d)},sendEventAck:(a,l)=>{this.aibotHandle.sendEventAck({event_id:a,session_id:l,received_at:Date.now()})},sendRawEventEnvelope:(a,l,d)=>{this.deliverRawEventEnvelope(a,l,d,"cursor",this.buildCursorRawEventFallbackText(d))},sendAgentQuestionCard:(a,l,d)=>{const c=d.questions.map(g=>g.header).join(", "),u=I(`[Agent Question] ${d.request_id}`,"agent_question",d);this.aibotHandle.sendText({event_id:a,session_id:l,content:u,msg_type:1,extra:{card_type:"agent_question",summary_text:c}})},agentInvoke:async(a,l,d)=>this.platformInvoke(a,l,d),sendLocalActionResult:(a,l,d,c,u)=>{this.aibotHandle.sendLocalActionResult({action_id:a,status:l,...d!==void 0?{result:d}:{},...c?{error_code:c}:{},...u?{error_msg:u}:{}},e)},sendUpdateBindingCard:(a,l,d,c)=>{this.aibotHandle.sendUpdateBindingCard({session_id:a,worker_status:l,cwd:d,...c?{meta:c}:{}})},getAgentProfile:()=>this.agentProfile,getAgentId:()=>this.config.aibot.agentId};return new G({command:this.config.agent.command,args:this.config.agent.args,env:this.resolveSpawnEnv(),options:n},o)}createClaudeAdapter(e){const n={sendReply:(t,s,o,a,l)=>{this.sendReplyByRuntimeConfig(t,s,o,a,l)},sendStreamChunk:(t,s,o,a,l,d,c)=>{this.sendStreamChunkByRuntimeConfig(t,s,o,a,l,d,c)},sendMedia:(t,s,o,a,l,d,c)=>{this.aibotHandle.sendMedia({event_id:t,session_id:s,content:o,msg_type:2,quoted_message_id:l||void 0,client_msg_id:d||void 0,extra:c?{media_caption:a,...c}:{media_caption:a}})},sendEventResult:(t,s,o,a,l)=>{this.sendEventResultWithCleanup(t,s,o,a,l)},sendEventAck:(t,s)=>{this.aibotHandle.sendEventAck({event_id:t,session_id:s,received_at:Date.now()})},agentInvoke:async(t,s,o)=>this.platformInvoke(t,s,o),sendLocalActionResult:(t,s,o,a,l)=>{this.aibotHandle.sendLocalActionResult({action_id:t,status:s,...o!==void 0?{result:o}:{},...a?{error_code:a}:{},...l?{error_msg:l}:{}},e)},sendToolUse:(t,s,o,a)=>{this.sendToolExecutionCard(t,s,C(o,a))},sendToolResult:(t,s,o,a)=>{this.sendToolExecutionCard(t,s,b(o,a))},getWsUrl:()=>this.config.aibot.url,getAgentId:()=>this.config.aibot.agentId,getAgentProfile:()=>this.agentProfile,getApiKey:()=>this.config.aibot.apiKey,getActiveEventCount:()=>0,getPendingPermissionCount:()=>0,getPendingElicitationCount:()=>0,sendAgentQuestionCard:(t,s,o)=>{this.sendGrixAgentQuestionCard(t,s,o)},sendPermissionCard:t=>{this.sendGrixApprovalCard(t,"claude")},sendDirectMessage:t=>{this.aibotHandle.sendMsg({session_id:t.sessionId,msg_type:1,content:t.content,...t.clientMsgId?{client_msg_id:t.clientMsgId}:{},...t.quotedMessageId?{quoted_message_id:t.quotedMessageId}:{}})},onStatusLineUpdated:t=>{(t.rateLimits?.fiveHour||t.rateLimits?.sevenDay)&&(this.cachedClaudeRateLimitState=t);const s=this.bindingStore.get(e);s?.cwd&&this.aibotHandle.sendUpdateBindingCard({session_id:e,worker_status:this.claudeWorkerStatus.get(e)??"ready",cwd:s.cwd,meta:this.buildClaudeToolbarMeta(e)})},sendMcpFrame:t=>{this.aibotHandle.sendMcpFrame(e,t)}},r=this.config.adapterOptions??{},i={...r,sessionRuntimeResolver:()=>{const t=this.bindingStore.get(e),s=this.auditController.getSession(e);return{cwd:t?.cwd,modeId:this.resolveClaudeSessionModeId(e)??z.fullAuto,modelId:this.resolveSessionModelId(e),effort:this.resolveClaudeSessionEffort(e),pluginDir:r.pluginDir,claudeSessionId:t?.claudeSessionId,...s?{audit:{enabled:!0,profile:s.options.profile,capture:s.options.capture}}:{},onSessionIdAssigned:o=>{this.bindingStore.setClaudeSessionId(e,o),this.sessionScanCache.invalidate()}}}};return new L({command:this.config.agent.command,args:this.config.agent.args,env:this.resolveSpawnEnv(),options:i},n)}createCodexAdapter(e){let n=null;const r={sendEventResult:(o,a,l)=>{if(a!=="responded"){this.sendEventResultWithCleanup(o,a,l);return}this.sendCtrl.sendFinalStreamChunkReliable(o,e,`codex_terminal_fence_${o}`,5e3,!0,!0).then(()=>this.sendEventResultWithCleanup(o,a,l),d=>{const c=`codex output acceptance fence failed: ${d instanceof Error?d.message:String(d)}`;this.sendEventResultWithCleanup(o,a==="responded"?"failed":a,a==="responded"?c:l)})},sendEventAck:(o,a)=>this.aibotHandle.sendEventAck({event_id:o,session_id:a,received_at:Date.now()}),sendCodexEvent:o=>{this.shouldDropCodexDisplayEvent(o.event_id,o.codex_method)||(this.captureCodexAuditOutput(o),this.aibotHandle.sendCodexEvent(this.stampCodexEventQuote(o)),this.logCodexEventToConversation(o))},sendThinking:(o,a,l)=>{this.sendThinkingByRuntimeConfig(o,a,l)},sendRunError:(o,a,l)=>{this.sendRunErrorAsChunk(o,a,l)},sendUpdateBindingCard:(o,a,l,d)=>{const c={...d??{}};if(!c.rate_limits&&this.cachedProviderQuota?.success){this.isRateLimitsCacheFresh(this.cachedProviderQuotaSampledAtMs)||this.maybeQueryProviderQuota().catch(()=>{});const u=this.providerQuotaToCodexRateLimits(this.cachedProviderQuota);u&&(c.rate_limits=u.rateLimits,c.rate_limit_primary_percent=u.primaryPercent,c.rate_limit_secondary_percent=u.secondaryPercent,c.rate_limit_primary_window_min=u.primaryWindowMin,c.rate_limit_secondary_window_min=u.secondaryWindowMin)}!c.provider_quota&&this.cachedProviderQuota?.success&&(c.provider_quota=this.cachedProviderQuota),this.aibotHandle.sendUpdateBindingCard({session_id:o,worker_status:a,cwd:l,...Object.keys(c).length>0?{meta:c}:{}})},agentInvoke:async(o,a,l)=>this.platformInvoke(o,a,l),sendLocalActionResult:(o,a,l,d,c)=>this.aibotHandle.sendLocalActionResult({action_id:o,status:a,...l!==void 0?{result:l}:{},...d?{error_code:d}:{},...c?{error_msg:c}:{}},e),sendSessionActivitySet:(o,a,l,d)=>{this.aibotHandle.sendSessionActivitySet({session_id:o,kind:a,active:l,...d??{}})},getConversationLog:()=>this.conversationLog,getAgentProfile:()=>this.agentProfile,getAgentId:()=>this.config.aibot.agentId,onRateLimitsUpdated:o=>{this.cachedRateLimits=o,this.cachedRateLimitsSampledAtMs=Date.now(),this.isRateLimitsCacheFresh(this.cachedProviderQuotaSampledAtMs)||this.maybeQueryProviderQuota().catch(()=>{});const a=this.bindingStore.get(e);if(a?.cwd){const l=this.cachedRateLimitsSampledAtMs,d={rate_limits:{...o.primary.windowMinutes>0?{primary:o.primary}:{},...o.secondary.windowMinutes>0?{secondary:o.secondary}:{},sampledAt:l},rate_limit_primary_percent:o.primary.usedPercent,rate_limit_secondary_percent:o.secondary.usedPercent,rate_limit_primary_window_min:o.primary.windowMinutes,rate_limit_secondary_window_min:o.secondary.windowMinutes,credits:o.credits,...o.extras&&o.extras.length>0?{extra_limits:o.extras}:{},...n?.getEffortMeta()};this.cachedProviderQuota?.success&&(d.provider_quota=this.cachedProviderQuota),this.aibotHandle.sendUpdateBindingCard({session_id:e,worker_status:"ready",cwd:a.cwd,meta:d})}},onContextWindowUpdated:o=>{if(!o)return;this.cachedCodexContextWindow=o,this.cachedCodexUsageSampledAtMs=Date.now();const a=this.bindingStore.get(e);a?.cwd&&this.aibotHandle.sendUpdateBindingCard({session_id:e,worker_status:"ready",cwd:a.cwd,meta:{context_window:o,...n?.getEffortMeta()}})},onTokenUsageUpdated:o=>{o&&(this.cachedCodexTokenUsage=o,this.cachedCodexUsageSampledAtMs=Date.now())}},i=this.config.adapterOptions??{},t=this.auditController.getAdapterPreparation(e),s=o=>Qt(this,"codex",e,o);return n=new M({command:this.config.agent.command,args:this.config.agent.args,env:this.resolveSpawnEnv(),options:{...i,model:s("model")??i.model,collaborationMode:s("mode")??i.collaborationMode,reasoningEffort:s("reasoningEffort")??i.reasoningEffort,serviceTier:s("serviceTier")??i.serviceTier,sandboxMode:s("sandboxMode")??i.sandboxMode,aibotSessionId:e,bindingStore:this.bindingStore,...D(t?.options)?{rawApiCapture:{auditId:t.auditId,sessionId:e,spoolRootDir:R.join(w.data,"audit-replay","raw-spool")}}:{}}},r),n}createCodeWhaleAdapter(e){const n={sendEventResult:(i,t,s)=>{this.sendEventResultWithCleanup(i,t,s)},sendEventAck:(i,t)=>this.aibotHandle.sendEventAck({event_id:i,session_id:t,received_at:Date.now()}),sendStreamChunk:(i,t,s,o,a,l)=>{this.sendStreamChunkByRuntimeConfig(i,t,s,o,a,l)},sendUpdateBindingCard:(i,t,s,o)=>this.aibotHandle.sendUpdateBindingCard({session_id:i,worker_status:t,cwd:s,...this.providerQuotaMetaPayload(o,i,s)}),sendLocalActionResult:(i,t,s,o,a)=>this.aibotHandle.sendLocalActionResult({action_id:i,status:t,...s!==void 0?{result:s}:{},...o?{error_code:o}:{},...a?{error_msg:a}:{}},e),sendSessionActivitySet:(i,t,s,o)=>{this.aibotHandle.sendSessionActivitySet({session_id:i,kind:t,active:s,...o??{}})},sendToolUse:(i,t,s,o)=>{this.sendToolExecutionCard(i,t,C(s,o))},sendToolResult:(i,t,s,o)=>{this.sendToolExecutionCard(i,t,b(s,o))},agentInvoke:async(i,t,s)=>this.platformInvoke(i,t,s),getConversationLog:()=>this.conversationLog,getAgentProfile:()=>this.agentProfile,getAgentId:()=>this.config.aibot.agentId},r=this.config.adapterOptions??{};return new j({command:this.config.agent.command,args:this.config.agent.args,env:this.resolveSpawnEnv(),options:{...r,aibotSessionId:e,bindingStore:this.bindingStore,agentName:this.name,model:this.resolveSessionModelId(e)??r.model,...this.config.agent.provider?{provider:this.config.agent.provider}:{}}},n)}createPiAdapter(e){const n={sendEventResult:(i,t,s,o,a)=>{this.sendEventResultWithCleanup(i,t,s,o,a),h.info("bridge",`[pi] sendEventResult event=${i} status=${t}`)},sendEventAck:(i,t)=>this.aibotHandle.sendEventAck({event_id:i,session_id:t,received_at:Date.now()}),sendUpdateBindingCard:(i,t,s,o)=>this.aibotHandle.sendUpdateBindingCard({session_id:i,worker_status:t,cwd:s,...this.providerQuotaMetaPayload(o,i,s)}),agentInvoke:async(i,t,s)=>this.platformInvoke(i,t,s),sendLocalActionResult:(i,t,s,o,a)=>{this.aibotHandle.sendLocalActionResult({action_id:i,status:t,...s!==void 0?{result:s}:{},...o?{error_code:o}:{},...a?{error_msg:a}:{}},e)},sendSessionActivitySet:(i,t,s,o)=>{this.aibotHandle.sendSessionActivitySet({session_id:i,kind:t,active:s,...o??{}})},sendToolUse:(i,t,s,o)=>{this.sendToolExecutionCard(i,t,C(s,o))},sendToolResult:(i,t,s,o)=>{this.sendToolExecutionCard(i,t,b(s,o))},sendStreamChunk:(i,t,s,o,a,l)=>{this.sendStreamChunkByRuntimeConfig(i,t,s,o,a,l),a&&h.info("bridge",`[pi] sendFinalStreamChunk event=${i} seq=${o}`)},sendFinalStreamChunkReliable:this.reliableFinalWiring("pi"),sendThinking:(i,t,s)=>{this.sendThinkingByRuntimeConfig(i,t,s)},sendRunError:(i,t,s,o,a)=>{this.sendRunErrorAsChunk(i,t,s,o,a)},getAgentProfile:()=>this.agentProfile},r=this.config.adapterOptions??{};return new N({command:this.config.agent.command,args:this.config.agent.args,env:this.resolveSpawnEnv(),options:{...r,aibotSessionId:e,bindingStore:this.bindingStore,agentName:this.name,clientType:this.config.agent.clientType,...this.config.agent.provider?{provider:this.config.agent.provider}:{}}},n)}createOpenHumanAdapter(e){const n={sendStreamChunk:(i,t,s,o,a,l)=>{this.sendStreamChunkByRuntimeConfig(i,t,s,o,a,l)},sendFinalStreamChunkReliable:async(i,t,s,o)=>{try{await this.sendCtrl.sendFinalStreamChunkReliable(i,t,o)}catch(a){throw h.error("bridge",`[openhuman] sendFinalStreamChunkReliable ACK failed event=${i}: ${a}`),a}},sendEventResult:(i,t,s)=>{this.sendEventResultWithCleanup(i,t,s),h.info("bridge",`[openhuman] sendEventResult event=${i} status=${t}`)},sendEventAck:(i,t)=>this.aibotHandle.sendEventAck({event_id:i,session_id:t,received_at:Date.now()}),sendToolUse:(i,t,s,o)=>{this.sendToolExecutionCard(i,t,C(s,o))},sendToolResult:(i,t,s,o)=>{this.sendToolExecutionCard(i,t,b(s,o))},sendThinking:(i,t,s)=>{this.sendThinkingByRuntimeConfig(i,t,s)},sendRunError:(i,t,s)=>{this.sendRunErrorAsChunk(i,t,s,0)},sendUpdateBindingCard:(i,t,s,o)=>this.aibotHandle.sendUpdateBindingCard({session_id:i,worker_status:t,cwd:s,...this.providerQuotaMetaPayload(o,i,s)}),agentInvoke:async(i,t,s)=>this.platformInvoke(i,t,s),sendLocalActionResult:(i,t,s,o,a)=>{this.aibotHandle.sendLocalActionResult({action_id:i,status:t,...s!==void 0?{result:s}:{},...o?{error_code:o}:{},...a?{error_msg:a}:{}},e)},getAgentProfile:()=>this.agentProfile,getAgentId:()=>this.config.aibot.agentId},r=this.config.adapterOptions??{};return new W({command:this.config.agent.command,args:this.config.agent.args,env:this.resolveSpawnEnv(),options:r},n,{port:r.port,host:r.host,workspaceDir:r.workspace_dir,sessionToken:r.session_token,enableSessionBinding:!0,aibotSessionId:e})}createOpenCodeAdapter(e){const n={sendStreamChunk:(i,t,s,o,a,l)=>{this.sendStreamChunkByRuntimeConfig(i,t,s,o,a,l)},sendFinalStreamChunkReliable:this.reliableFinalWiring("opencode"),sendEventResult:(i,t,s,o,a)=>{this.sendEventResultWithCleanup(i,t,s,o,a),h.info("bridge",`[opencode] sendEventResult event=${i} status=${t}`)},sendEventAck:(i,t)=>this.aibotHandle.sendEventAck({event_id:i,session_id:t,received_at:Date.now()}),sendToolUse:(i,t,s,o)=>{this.sendToolExecutionCard(i,t,C(s,o))},sendToolResult:(i,t,s,o)=>{this.sendToolExecutionCard(i,t,b(s,o))},sendThinking:(i,t,s)=>{this.sendThinkingByRuntimeConfig(i,t,s)},sendRunError:(i,t,s)=>{this.sendRunErrorAsChunk(i,t,s)},sendUpdateBindingCard:(i,t,s,o)=>this.aibotHandle.sendUpdateBindingCard({session_id:i,worker_status:t,cwd:s,...this.providerQuotaMetaPayload(o,i,s)}),agentInvoke:async(i,t,s)=>this.platformInvoke(i,t,s),sendLocalActionResult:(i,t,s,o,a)=>{this.aibotHandle.sendLocalActionResult({action_id:i,status:t,...s!==void 0?{result:s}:{},...o?{error_code:o}:{},...a?{error_msg:a}:{}},e)},sendPermissionCard:i=>{this.sendGrixApprovalCard(i,"opencode")},sendAgentQuestionCard:(i,t,s)=>{this.sendGrixAgentQuestionCard(i,t,s)},getAgentProfile:()=>this.agentProfile,getAgentId:()=>this.config.aibot.agentId},r=this.config.adapterOptions??{};return new T({command:this.config.agent.command,args:this.config.agent.args,env:this.resolveSpawnEnv(),options:r},n,{port:r.port,hostname:r.hostname,model:r.model??this.resolveSessionModelId(e),agent:r.agent,permissionPolicy:r.permission_policy,enableSessionBinding:!0,aibotSessionId:e,bindingStore:this.bindingStore,...this.config.agent.provider?{provider:this.config.agent.provider}:{}})}createAgyAdapter(e){const n={sendStreamChunk:(i,t,s,o,a,l)=>{this.sendStreamChunkByRuntimeConfig(i,t,s,o,a,l)},sendEventResult:(i,t,s)=>{this.sendEventResultWithCleanup(i,t,s)},sendEventAck:(i,t)=>{this.aibotHandle.sendEventAck({event_id:i,session_id:t,received_at:Date.now()})},agentInvoke:async(i,t,s)=>this.platformInvoke(i,t,s),forceCompleteInternalEvent:(i,t)=>{this.pool.eventComplete(i,t),this.pushQueueSnapshotForSession(t)},persistConversationId:(i,t)=>{this.bindingStore.setAgyConversationId(i,t)},getAgentProfile:()=>this.agentProfile,getAgentId:()=>this.config.aibot.agentId},r=i=>{const t=this.bindingStore.get(i);return{cwd:t?.cwd,modelId:this.resolveSessionModelId(i),conversationId:t?.agyConversationId}};return new H({command:this.config.agent.command,args:this.config.agent.args,env:this.resolveSpawnEnv(),options:this.config.adapterOptions??{}},n,r)}createAcpAdapter(e){const n=this.isAcpRawTransportEnabled(),r={sendStreamChunk:(d,c,u,g,p,_,A)=>{this.sendStreamChunkByRuntimeConfig(d,c,u,g,p,_,A)},sendFinalStreamChunkReliable:this.reliableFinalWiring("acp",4e3),sendEventResult:(d,c,u,g,p)=>{this.sendEventResultWithCleanup(d,c,u,g,p)},sendEventAck:(d,c)=>{this.aibotHandle.sendEventAck({event_id:d,session_id:c,received_at:Date.now()})},agentInvoke:async(d,c,u)=>this.platformInvoke(d,c,u),sendLocalActionResult:(d,c,u,g,p)=>{this.aibotHandle.sendLocalActionResult({action_id:d,status:c,...u!==void 0?{result:u}:{},...g?{error_code:g}:{},...p?{error_msg:p}:{}},e)},sendRawEventEnvelope:(d,c,u)=>{this.sendAcpRawEventEnvelope(d,c,u)},sendToolUse:(d,c,u,g)=>{if(n){this.sendAcpRawEventEnvelope(d,c,{type:"tool_use",payload:{tool_name:u,tool_input:g??""}});return}this.sendToolExecutionCard(d,c,C(u,g))},sendToolResult:(d,c,u,g)=>{this.sendToolExecutionCard(d,c,b(u,g))},sendThinking:(d,c,u)=>{this.sendThinkingByRuntimeConfig(d,c,u)},sendRunError:(d,c,u)=>{this.sendRunErrorAsChunk(d,c,u)},sendAgentQuestionCard:(d,c,u)=>{this.sendGrixAgentQuestionCard(d,c,u)},sendPermissionCard:d=>{h.info("bridge","sendPermissionCard callback entered",{rawTransport:n,eventId:d.eventId,sessionId:d.sessionId,toolCallId:d.toolCallId,toolName:d.toolName,toolTitle:d.toolTitle});const c=d.toolInput&&d.toolTitle&&d.toolInput!==d.toolTitle?`${d.toolTitle}: ${d.toolInput}`:d.toolTitle||d.toolInput||d.toolName;if(n){this.sendAcpRawEventEnvelope(d.eventId,d.sessionId,{type:"permission_request",payload:{tool_call_id:d.toolCallId,tool_name:d.toolName,tool_title:d.toolTitle,...d.toolInput?{tool_input:d.toolInput}:{},options:d.options}}),h.info("bridge","sendPermissionCard: sent via rawEventEnvelope",{eventId:d.eventId,toolCallId:d.toolCallId});return}const u=`perm_${k()}`,g={event_id:d.eventId,session_id:d.sessionId,client_msg_id:u,msg_type:1,content:d.toolTitle?`Permission required: ${d.toolTitle}`:"Permission request",extra:{channel_data:{execApproval:{approvalId:d.toolCallId,approvalSlug:d.toolName},grix:{execApproval:{approval_command_id:d.toolCallId,approval_type:"permission",command:c,host:"acp"}}},agent_api_origin:!0}};h.info("bridge","sendPermissionCard: about to invoke aibotHandle.sendMsg",{eventId:d.eventId,sessionId:d.sessionId,clientMsgId:u,toolCallId:d.toolCallId,contentLength:g.content.length});try{this.aibotHandle.sendMsg(g),h.info("bridge","sendPermissionCard: aibotHandle.sendMsg returned",{eventId:d.eventId,clientMsgId:u})}catch(p){h.error("bridge","sendPermissionCard: aibotHandle.sendMsg threw",{eventId:d.eventId,clientMsgId:u,error:p instanceof Error?p.message:String(p)})}},sendAuthNotification:(d,c)=>{d&&this.aibotHandle.sendMsg({session_id:d,msg_type:1,content:c,extra:{biz_card:{version:1,type:"agent_error",payload:{error:{name:"AuthRequired",message:c}}}}})},sendAgentMessage:(d,c)=>{d&&c&&this.aibotHandle.sendMsg({session_id:d,msg_type:1,content:c})},sendUpdateBindingCard:(d,c,u,g)=>{const p={...g??{}};if(!p.rate_limits&&this.cachedProviderQuota?.success){this.isRateLimitsCacheFresh(this.cachedProviderQuotaSampledAtMs)||this.maybeQueryProviderQuota().catch(()=>{});const _=this.providerQuotaToRateLimits(this.cachedProviderQuota);_&&(p.rate_limits=_)}!p.provider_quota&&this.cachedProviderQuota?.success&&(p.provider_quota=this.cachedProviderQuota),this.aibotHandle.sendUpdateBindingCard({session_id:d,worker_status:c,cwd:u,...Object.keys(p).length>0?{meta:p}:{}})},onSkillsUpdate:(d,c)=>{try{this.aibotHandle.sendSkillsUpdate({skills:Y(d,w.skills),library_skills:this.buildLibrarySkillsReport(c)})}catch(u){}},onContextWindowUpdated:d=>{this.cachedAcpContextWindow=d,this.cachedAcpContextWindowSampledAtMs=Date.now();const c="usedPercentage"in d?d.usedPercentage.toFixed(1):(d.used/d.size*100).toFixed(1);h.info(this.name,`[acp] context_window updated: ${c}%`);const u=this.bindingStore.get(e);if(u?.cwd){const g="usedPercentage"in d?d.usedPercentage:Math.min(100,d.used/d.size*100),p={context_window:{..."usedPercentage"in d?{}:d,usedPercentage:g,remainingPercentage:100-g}};if((this.config.aibot.clientType==="kiro"||this.config.aibot.clientType==="kimi")&&this.cachedProviderQuota?.success){this.isRateLimitsCacheFresh(this.cachedProviderQuotaSampledAtMs)||this.maybeQueryProviderQuota().catch(()=>{}),p.provider_quota=this.cachedProviderQuota;const _=this.providerQuotaToRateLimits(this.cachedProviderQuota);_&&(p.rate_limits=_)}this.aibotHandle.sendUpdateBindingCard({session_id:e,worker_status:"ready",cwd:u.cwd,meta:p})}},sendMcpFrame:d=>{this.aibotHandle.sendMcpFrame(e,d)},getAgentProfile:()=>this.agentProfile,getAgentId:()=>this.config.aibot.agentId},i=e?this.bindingStore.get(e):void 0,t=e?this.auditController.getSession(e):void 0,s=this.config.aibot.clientType==="reasonix"&&t?xi(this.name,e,t.auditId):void 0,o=this.globalConfigStore?.get(this.name),{initialModel:a,initialMode:l}=Wn({sessionBinding:i,globalDefaults:o,configInitialMode:this.config.acpInitialMode});return e&&a&&!i?.acpModelId&&this.bindingStore.setAcpModelId(e,a),e&&l&&!i?.acpModeId&&this.bindingStore.setAcpModeId(e,l),(a||l)&&h.info(this.name,`[toolbar] hydrate from binding: session=${e} model=${a??"<none>"} mode=${l??"<none>"}`),new S({command:this.config.agent.command,args:this.config.agent.args,env:this.resolveSpawnEnv()},r,{acpAuthMethod:this.config.acpAuthMethod,acpInitialMode:l,acpInitialModel:a,acpMcpTools:this.config.acpMcpTools,rawTransport:n,eventResultsPath:this.config.eventResultsPath,approvalMode:this.config.approvalMode,bindingStore:this.config.enableSessionBinding?this.bindingStore:void 0,aibotSessionId:e,autoInjectArgs:this.config.autoInjectArgs,nativeProviderScope:this.name,bridgeLog:this.config.logDir?new Pe(this.config.logDir,`${this.name}-${e}`):null,reasonixAuditTranscriptPath:s,agentType:this.config.aibot.clientType,newSessionParams:this.config.adapterOptions?.newSessionParams&&typeof this.config.adapterOptions.newSessionParams=="object"&&!Array.isArray(this.config.adapterOptions.newSessionParams)?this.config.adapterOptions.newSessionParams:void 0})}async connectAibot(){const n=await new U().connect(this.aibotConfig,{aborted:()=>this.stopped,signal:this.startupAbortController.signal,label:this.name,packetLog:this.packetLog,maxRetries:this.config.connectMaxRetries});if(this.stopped)throw n.disconnect(),new Error("connection aborted");this.aibotHandle=n;const r=this.aibotHandle.authAck;if(this.applyAgentProfile(r?.agent_name,r?.introduction,{source:"auth_ack",respawnOnChange:!1},r?.system_prompt),this.aibotHandle.onEvent(i=>{this.handleAibotEvent(i).catch(t=>{h.error(this.name,`handleAibotEvent failed: ${t}`),this.aibotHandle.sendEventAck({event_id:i.event_id,session_id:i.session_id,received_at:Date.now()});const s=t instanceof Error?t.message:String(t);this.handleStaleCwdError(i,s)||this.aibotHandle.sendEventResult({event_id:i.event_id,status:"failed",msg:s,updated_at:Date.now()})})}),this.aibotHandle.onStop(i=>{try{this.handleAibotStop(i)}catch(t){h.error(this.name,`handleAibotStop failed: ${t}`)}}),this.aibotHandle.onAgentDeleted(i=>{h.warn(this.name,`agent deleted on platform (source=${i?.source??"unknown"}${i?.reason?` reason=${i.reason}`:""}), notifying manager to clean up`);try{this.agentDeletedHandler?.()}catch(t){h.error(this.name,`agentDeletedHandler failed: ${t}`)}}),this.aibotHandle.onShareSet(i=>{try{this.shareSetHandler?.(Array.isArray(i?.shared_to)?i.shared_to:[])}catch(t){h.error(this.name,`onShareSet failed: ${t}`)}}),this.aibotHandle.onProfilePush(i=>{try{this.applyAgentProfile(i?.agent_name,i?.introduction,{source:"profile_push",respawnOnChange:!0},i?.system_prompt)}catch(t){h.error(this.name,`onProfilePush failed: ${t}`)}}),this.aibotHandle.onSkillSync(i=>{if(!this.stopped)try{h.info(this.name,`skill_sync received owner=${i?.owner_id??""} name=${i?.name??""}`),this.skillSyncHandler?.()}catch(t){h.error(this.name,`onSkillSync failed: ${t}`)}}),this.aibotHandle.onRevoke(i=>{this.handleAibotRevoke(i).catch(t=>{h.error(this.name,`handleAibotRevoke failed: ${t}`)})}),this.aibotHandle.onLocalAction(i=>{this.handleAibotLocalAction(i).catch(t=>{h.error(this.name,`handleAibotLocalAction failed: ${t}`)})}),this.aibotHandle.onEventCancel(i=>{h.info(this.name,`recv event_cancel event_id=${i.event_id} session_id=${i.session_id}`),this.handleEventCancel(i).catch(t=>{h.error(this.name,`handleEventCancel failed: ${t}`)})}),this.aibotHandle.onMcpFrame((i,t)=>{const s=this.pool.getSlot(i)?.adapter;s?.deliverMcpFrameToAgent?s.deliverMcpFrameToAgent(t):h.warn(this.name,`mcp_frame: no adapter for session=${i}`)}),this.aibotHandle.onQueueClear(i=>{const t=this.pool.clearQueue(i.session_id);this.aibotHandle.sendQueueClearResult({session_id:i.session_id,canceled_event_ids:t}),this.pushQueueSnapshotForSession(i.session_id)}),typeof this.aibotHandle.onQueueReorder=="function"&&this.aibotHandle.onQueueReorder(i=>{const t=Array.isArray(i.ordered_event_ids)?i.ordered_event_ids.filter(o=>typeof o=="string"&&o.length>0):[],s=this.pool.reorderQueue(i.session_id,t);this.aibotHandle.sendQueueReorderResult({session_id:i.session_id,applied_event_ids:s}),this.pushQueueSnapshotForSession(i.session_id)}),typeof this.aibotHandle.onEventHold=="function"&&this.aibotHandle.onEventHold(i=>{const t=typeof i.session_id=="string"?i.session_id:"",s=typeof i.event_id=="string"?i.event_id:"",o=i.hold!==!1;if(h.info(this.name,`recv event_hold event_id=${s} session_id=${t} hold=${o} reason=${i.reason??""}`),!t||!s){this.aibotHandle.sendEventHoldResult({session_id:t,event_id:s,ok:!1,held:!1,error:"bad_request"});return}const a=typeof i.reason=="string"?i.reason:"",l=typeof i.ttl_ms=="number"?i.ttl_ms:void 0,d=this.pool.holdEvent(t,s,o,a,l),c=d==="ok";this.aibotHandle.sendEventHoldResult({session_id:t,event_id:s,ok:c,held:c?o:!1,...c?{}:{error:d}}),c&&this.pushQueueSnapshotForSession(t)}),typeof this.aibotHandle.onQueueEdit=="function"&&this.aibotHandle.onQueueEdit(i=>{const t=typeof i.session_id=="string"?i.session_id:"",s=typeof i.event_id=="string"?i.event_id:"";if(h.info(this.name,`recv queue_edit event_id=${s} session_id=${t}`),!t||!s){this.aibotHandle.sendQueueEditResult({session_id:t,event_id:s,ok:!1,error:"bad_request"});return}const o=typeof i.content=="string"?i.content:"",a=this.pool.editQueuedEvent(t,s,o),l=a==="ok";this.aibotHandle.sendQueueEditResult({session_id:t,event_id:s,ok:l,...l?{}:{error:a}}),l&&this.pushQueueSnapshotForSession(t)}),typeof this.aibotHandle.onQueueSnapshotQuery=="function"&&this.aibotHandle.onQueueSnapshotQuery(i=>{this.replyQueueSnapshotForSession(i.session_id)}),h.info(this.name,"Connected to aibot"),this.activeEventStore){const i=await this.activeEventStore.drain();if(i.length>0){h.warn(this.name,`Recovering ${i.length} stale event(s) from previous run`);for(const t of i)h.info(this.name,`Failing stale event on startup: ${t}`),this.aibotHandle.sendEventResult({event_id:t,status:"failed",msg:"process restarted, event lost",updated_at:Date.now()})}}this.pushQueueSnapshots(),this.relayStateSyncOnConnect(),this.aibotHandle.onReconnected(()=>{if(this.stopped)return;this.pushQueueSnapshots();const i=this.aibotHandle.authAck;this.applyAgentProfile(i?.agent_name,i?.introduction,{source:"reconnect",respawnOnChange:!0},i?.system_prompt),this.forceRefreshSkills(void 0,{force:!0}),this.skillSyncHandler?.(),this.relayStateSyncOnConnect()}),this.aibotHandle.onStreamRejected((i,t)=>{this.sendCtrl.markEventRejected(i)})}applyAgentProfile(e,n,r,i){const t=String(e??"").trim(),s=String(n??"").trim(),o=i===void 0?this.agentSystemPrompt:String(i),a=t!==this.agentProfile.agentName||s!==this.agentProfile.introduction||o!==this.agentSystemPrompt;this.agentProfile={agentName:t,introduction:s},this.agentSystemPrompt=o,t||s?h.info(this.name,`agent profile (${r.source}): GOT name="${t}" intro_len=${s.length} system_prompt_len=${o.length} changed=${a}`):h.warn(this.name,`agent profile (${r.source}): EMPTY \u2014 \u670D\u52A1\u7AEF\u672A\u4E0B\u53D1 agent_name/introduction\uFF08auth_ack \u5B57\u6BB5\u7F3A\u5931\u6216\u503C\u4E3A\u7A7A\uFF09`),a&&r.respawnOnChange&&this.applyProfileChangeToAdapters("agent_profile_changed")}applyProfileChangeToAdapters(e){if(!this.pool)return;const n=this.pool.getAllSlots();let r=0;for(const o of n)if(o.adapter.onAgentProfileChanged)try{o.adapter.onAgentProfileChanged(),r++}catch(a){h.warn(this.name,`onAgentProfileChanged failed for session=${o.sessionId}: ${a}`)}const i=n.filter(o=>o.adapter instanceof L),t=i.filter(o=>{if(o.state!=="ready")return!1;const a=o.adapter.getStatus();return!a.busy&&!a.backgroundBusy}),s=i.length-t.length;h.info(this.name,`${e}: notified ${r} adapter(s) via hook; respawning ${t.length} idle Claude slot(s), skipping ${s} busy`);for(const o of t)this.pool.removeSlot(o.sessionId).catch(a=>{h.warn(this.name,`removeSlot failed during ${e}: ${a}`)})}pushQueueSnapshots(){if(!(!this.config.eventQueue||!this.pool))for(const e of this.pool.getAllSlots())this.pushQueueSnapshotForSession(e.sessionId)}buildQueueSnapshotPayload(e){const n=this.pool?.getQueueSnapshot(e)??null,r=n?[...n.running]:[],i=n?n.running_items.map(s=>({event_id:s.event_id,...s.content_preview?{content_preview:s.content_preview}:{},...s.title?{title:s.title}:{},...s.summary?{summary:s.summary}:{},actions:[{type:"stop"}]})):[],t=n?n.queued.map(s=>({event_id:s.event_id,position:s.position,...s.content_preview?{content_preview:s.content_preview}:{},...typeof s.content=="string"?{content:s.content}:{},...s.title?{title:s.title}:{},...s.summary?{summary:s.summary}:{},held:s.held===!0,held_reason:s.held_reason??"",actions:[{type:"cancel"}]})):[];if(r.length===0&&this.selfDrivenSessions.has(e)&&this.pool?.getSlot(e)){const s=`selfdrive_${e}`,o=this.selfDrivenLabels.get(e)??"Background task in progress";r.push(s),i.push({event_id:s,content_preview:o,title:o,summary:o,actions:[]})}return{session_id:e,running:r,running_items:i,queued:t}}pushQueueSnapshotForSession(e){if(!this.config.eventQueue||!this.pool)return;const n=this.buildQueueSnapshotPayload(e);h.info(this.name,`[queue-debug] push snapshot session=${e} running=${n.running.length} queued=${n.queued.length} running_ids=[${n.running.join(",")}]`),this.aibotHandle.sendQueueSnapshot(n)}replyQueueSnapshotForSession(e){!this.config.eventQueue||!this.pool||this.aibotHandle.sendQueueSnapshot(this.buildQueueSnapshotPayload(e))}async platformInvoke(e,n,r){return e==="file_link"?jn(n):e==="file_upload"?this.uploadFileAndSendMedia(n):this.aibotHandle.agentInvoke(e,n,r)}invokeDshEventTool(e,n){const r=V(this.aibotHandle,e,n),i=r.content[0]?.text??"";if(r.isError)throw new Error(i||`grix event tool "${e}" failed`);try{return JSON.parse(i)}catch{return i}}async uploadFileAndSendMedia(e){const n=String(e.file_path??"").trim(),r=String(e.session_id??"").trim(),i=String(e.caption??"").trim(),t=String(e.reply_to_message_id??"").trim();if(!n)throw new Error("file_path is required");if(!r)throw new Error("session_id is required");const s=await Kn({wsURL:this.config.aibot.url,apiKey:this.config.aibot.apiKey,sessionID:r,filePath:n}),o=await this.aibotHandle.sendMedia({session_id:r,msg_type:2,content:i||`[${s.attachment_type}]`,client_msg_id:`file_upload_${k()}`,...t?{quoted_message_id:t}:{},extra:s.extra});if(o.cmd!=="send_ack"){const l=o.payload??{},d=String(l.msg??o.cmd);throw new Error(`media message send failed: ${d}`)}const a=o.payload??{};return{ok:!0,file_name:s.file_name,attachment_type:s.attachment_type,access_url:s.access_url,message_id:a.msg_id!=null?String(a.msg_id):null}}sendReplyByRuntimeConfig(e,n,r,i,t){const s=this.indexEventSession(e,n)??n;this.auditController.captureReply(e,r),this.sendCtrl.sendReply(e,s,r,i,t),r&&this.conversationLog?.logOutbound?.(s,e,"reply",r)}stampCodexEventQuote(e){if(e.quoted_message_id!=null){if(e.quoted_message_id)return e;const{quoted_message_id:s,...o}=e;return o}const n=e;if(n.codex_method!=="item/agentMessage/delta")return e;const i=n.codex_payload?.params?.phase;if(typeof i=="string"&&i.trim()&&i.trim().toLowerCase()!=="final_answer")return e;const t=this.sendCtrl.getDefaultQuotedMessageId(e.event_id);return t?{...e,quoted_message_id:t}:e}captureCodexAuditOutput(e){if(e.codex_method!=="item/agentMessage/delta")return;const n=e.codex_payload?.params,r=typeof n?.phase=="string"?n.phase.trim().toLowerCase():"";if(r&&r!=="final_answer")return;const i=n?.delta;typeof i!="string"||!i||this.auditController.captureUnsequencedStreamChunk(e.event_id,i)}discardEventTrackingState(e){this.inflightEvents.delete(e),this.restartCount.delete(e),this.eventSessionIndex.delete(e),this.pendingStartedEventIds.delete(e),this.sendCtrl.discardEventState(e)}reliableFinalWiring(e,n){return async(r,i,t)=>{try{await this.sendCtrl.sendFinalStreamChunkReliable(r,i,t,n)}catch(s){throw h.error("bridge",`[${e}] sendFinalStreamChunkReliable ACK failed event=${r}: ${s}`),s}h.info("bridge",`[${e}] sendFinalStreamChunkReliable done event=${r}`)}}sendStreamChunkByRuntimeConfig(e,n,r,i,t,s,o){const a=this.indexEventSession(e,n)??n;this.auditController.captureStreamChunk(e,i,r),this.sendCtrl.sendStreamChunk(e,a,r,i,t,s,o),(r||t)&&this.conversationLog?.logOutbound?.(a,e,t?"stream_chunk_finish":"stream_chunk",r)}surfacedRunErrorTexts=new Map;markRunErrorSurfaced(e,n){const r=n.trim();if(!r)return;const i=this.surfacedRunErrorTexts.get(e);i?i.add(r):this.surfacedRunErrorTexts.set(e,new Set([r]))}sendRunErrorAsChunk(e,n,r,i=1,t){this.surfacedRunErrorTexts.get(e)?.has(r.trim())||(this.markRunErrorSurfaced(e,r),this.sendStreamChunkByRuntimeConfig(e,n,`
|
|
1
|
+
import R from"node:path";import{tmpdir as F}from"node:os";import{createHash as L,randomUUID as k}from"node:crypto";import{ConnectionManager as U}from"../core/aibot/index.js";import{AUDIT_LOCAL_ACTION_TYPES as q}from"../core/aibot/types.js";import{ClaudeAdapter as M}from"../adapter/claude/index.js";import{CodexAdapter as H}from"../adapter/codex/index.js";import"../adapter/claude/session-history.js";import"../adapter/codex/session-history.js";import"../adapter/pi/session-history.js";import"../adapter/opencode/session-history.js";import"../adapter/codewhale/session-history.js";import"../adapter/deepseek-harness/session-history.js";import{PiAdapter as W}from"../adapter/pi/index.js";import{AcpAdapter as S}from"../adapter/acp/index.js";import{OpenHumanAdapter as N}from"../adapter/openhuman/index.js";import{CursorAdapter as G}from"../adapter/cursor/index.js";import{CodeWhaleAdapter as j}from"../adapter/codewhale/index.js";import{OpenCodeAdapter as T}from"../adapter/opencode/index.js";import{AgyAdapter as $}from"../adapter/agy/index.js";import{DshJsonRpcAdapter as K}from"../adapter/deepseek-harness/index.js";import{LOCAL_ACTION_TYPES as f,SESSION_CONTROL_ERROR_CODES as P,SESSION_CONTROL_VERBS as E,SESSION_MODE_IDS as z}from"../adapter/claude/protocol-contract.js";import{isAuditLocalActionType as J}from"../audit/query/audit-local-actions.js";import{shouldEnableRawApiCapture as D}from"../audit/raw-capture/types.js";import{buildWireSkills as Y}from"../core/skill-sync/sync-state.js";import{executeEventTool as V}from"../core/mcp/event-tool-executor.js";import{fetchAvailableModels as X}from"../adapter/claude/model-list.js";import{applyProxyEnv as Z,getProxyManager as ee}from"../core/proxy/index.js";import{getKiroRelaySpawnEnv as te}from"../core/proxy/kiro-relay.js";import{supportsKiroCwRelay as ne}from"../core/config/provider-env.js";import{buildProviderEnv as ie}from"../core/config/provider-env.js";import{isClaudeDirectEnv as se,stripGrixRelayEnv as oe}from"../core/config/claude-direct-env.js";import{sweepNativeProviderResidue as re}from"./native-provider-sweep.js";import{scanCodexSessions as ae}from"../adapter/codex/session-scanner.js";import{scanClaudeSessions as de}from"../adapter/claude/session-scanner.js";import{resolveAcpAgentTypes as le,scanAcpSessions as ce,scanReasonixSessionTitles as he}from"../adapter/acp/session-scanner.js";import{scanPiSessions as ue}from"../adapter/pi/session-scanner.js";import{scanCodeWhaleSessions as pe}from"../adapter/codewhale/session-scanner.js";import{scanCursorSessions as ge}from"../adapter/cursor/session-scanner.js";import{scanOpenCodeSessions as fe}from"../adapter/opencode/session-scanner.js";import{agentIdOf as me}from"../adapter/shared/native-provider-config.js";import{scanDshSessions as ve}from"../adapter/deepseek-harness/session-scanner.js";import{SessionScanCache as v,resolveCodexLeafDirs as _e,resolveClaudeLeafDirs as Se,resolveAcpLeafDirs as Ce,resolvePiLeafDirs as be,resolveCodeWhaleLeafDirs as Ae,resolveCursorLeafDirs as Ee,resolveOpenCodeLeafDirs as we,resolveDshLeafDirs as ye,resolveReasonixLeafDirs as Re}from"./session-scan-cache.js";import{log as h,ConversationLog as ke,AgentApiPacketLog as Te,BridgeEventLog as Pe,GRIX_PATHS as w}from"../core/log/index.js";import{routeSessionControlCommand as xe,routeSessionControlLocalAction as Le}from"./session-control-router.js";import{maybeOfferCliInstall as Me,handleCliInstallQuestionReply as He,handleCliInstallInteractionReply as $e,runConfirmedCliInstall as De}from"./cli-install-flow.js";import{handleEventCancel as Qe,waitForEventDone as Ie,handleAibotStop as Oe,killAndResumeStopSlot as Be,handleAibotRevoke as Fe}from"./event-stop.js";import{handleConfigureGatewayProvider as Ue,getAuditLocalActionHandler as qe,handleAuditLocalAction as We,handleConnectorRollback as Ne,getRelayStateSyncer as Ge,relayStateSyncOnConnect as je,reportRelayStateLocalChange as Ke,handleApplyRelayState as ze,fetchRelayCredential as Je,isSharedInstance as Ye}from"./connector-ops.js";import{CONNECTOR_ADMIN_ACTION_TYPE as Ve,handleConnectorAdminLocalAction as Xe}from"./remote-admin.js";import{unbindSession as Ze,handleUnbindTextCommand as et,handleUnbindLocalAction as tt,handleListSessionsTextCommand as nt,handleListSessionsLocalAction as it,handleSyncHistoryLocalAction as st}from"./session-list.js";import{handleCodexSessionControlOpen as ot,handleSessionControlForPool as rt,handleSessionControlLocalActionForPool as at,handleCodexSessionControlLocalActionOpen as dt,handleCursorSessionControlLocalActionOpen as lt,handlePiSessionControlOpen as ct,handlePiSessionControlRestart as ht,handlePiSessionControlRestartLocalAction as ut,syncOpenCodeBinding as pt,isWorkspaceFreeClient as gt,isCwdLockedClient as ft,ensureDefaultBindingForWorkspaceFreeClient as mt,bindSessionForPool as vt,deferredCallbacks as _t,handleOpenHumanSessionControlOpen as St,handleCodeWhaleSessionControlOpen as Ct,handleCodeWhaleSessionControlLocalActionOpen as bt,handleDeepSeekSessionControlLocalActionOpen as At}from"./session-control-open.js";import{CWD_LOCKED_REJECT_MSG as Et}from"./cwd-policy.js";import{normalizeCustomToolbarItems as wt}from"./acp-custom-toolbar.js";import{handleGetSessionUsage as yt,handleThreadCompact as Rt}from"./session-usage.js";import{handleSkillDeleteLocalAction as kt,handleSkillUploadLocalAction as Tt,handleSkillEnableLocalAction as Pt,handleSkillRefreshLocalAction as xt,handleSkillDisableLocalAction as Lt,computeSkillReport as Mt,reportSessionSkills as Ht,skillsSyncGroupKey as $t,forceRefreshSkills as Dt,adoptSkillsWireHashFromDisk as Qt,buildLibrarySkillsReport as It,skillLookupEnv as Ot}from"./skill-actions.js";import{resolveToolbarSelection as Bt,persistToolbarSelection as Q}from"./toolbar-selection.js";import{normalizeClaudeModeId as Ft,handleExecCommandOptions as Ut,resolveSessionModelId as qt,resolveSessionModeId as Wt,resolveCursorSessionModeId as Nt,resolveClaudeSessionEffort as Gt,resolveClaudeSessionModeId as jt,currentClaudeModeId as Kt,buildCursorToolbarMeta as zt,buildAgyToolbarMeta as Jt,buildAgyQuotaMeta as Yt,sendAgyBindingCard as Vt,refreshAndPushAgyQuota as Xt,handleAgySetModel as Zt,buildClaudeToolbarMeta as en}from"./toolbar-meta.js";import{resolveProviderQuotaSource as tn,maybeQueryProviderQuota as nn,startProviderQuotaTimer as sn,stopProviderQuotaTimer as on,refreshAndPushProviderQuota as rn,pushProviderQuotaToBindings as an,enrichProviderQuotaMeta as dn,providerQuotaMetaPayload as ln,refreshProviderQuotaForSession as cn,refreshQuotaAfterModelSwitch as hn,doRefreshQuotaAfterModelSwitch as un}from"./provider-quota.js";import{handleGetRateLimits as pn,resolveRateLimitWakeSessionId as gn,wakeRateLimitSlot as fn}from"./rate-limits.js";import{RevokeHandler as mn}from"./revoke-handler.js";import{AdapterPool as vn}from"./adapter-pool.js";import{parseSessionControlCommand as _n}from"./session-controller.js";import{isOpenSessionDirectiveMessage as Sn,parseExecApprovalResolutionMessage as Cn,parseAgentQuestionReplyMessage as bn}from"../core/protocol/interaction-parser.js";import{rejectUnusableAuditOptions as An}from"./inbound-audit-gate.js";import{interceptUnboundInboundEvent as En}from"./inbound-binding-gate.js";import{dispatchSessionControlTextCommand as wn}from"./text-command-session-control.js";import{dispatchSessionControlLocalAction as yn}from"./local-action-session-control.js";import{handleCreateFolderLocalAction as Rn,handleFileListLocalAction as kn}from"./local-action-files.js";import{handleAcpToolbarLocalAction as Tn,persistToolbarSelection as Pn}from"./local-action-toolbar.js";import{buildOpenedBindingResult as xn,ensureImportedAgentSession as Ln,hasDiskScanner as Mn,normalizePathForCompare as Hn,providerKeyForAdapter as $n,resolveAgentSessionId as Dn,resolveOrphanTitle as Qn,setResolvedAgentSessionId as In}from"./session-identity.js";import{buildDshOpenedToolbarMeta as On,dshCatalogDataRoot as Bn}from"./dsh-toolbar.js";import{ensureSlotStarted as Fn,failSessionOpen as Un,getClaudeWorkerStatus as qn,refreshClaudeWorkerStatusCard as Wn,resolveCwdForBinding as Nn}from"./session-open-helpers.js";import{handleAcpSetModel as Gn,handleAcpSetMode as jn,resolveAcpInitialDefaults as Kn}from"./acp-toolbar-persist.js";import{SessionBindingStore as zn}from"../core/persistence/session-binding-store.js";import{serveLocalFile as Jn}from"../core/files/index.js";import{uploadReplyFileToAgentMedia as Yn}from"../core/protocol/agent-api-media.js";import{attachmentHostFromWsUrl as Vn,buildInboundAttachmentsJson as Xn,materializeInboundAttachments as Zn}from"../core/protocol/inbound-attachments.js";import{ActiveEventStore as ei}from"../core/persistence/active-event-store.js";import{PendingEventCoordinator as ti}from"./pending-event-coordinator.js";import{LifecycleBarrier as ni}from"./lifecycle-barrier.js";import{QUEUE_COMPOSING_TTL_MS as ii}from"./event-queue.js";import{DEFAULT_CONNECTOR_RUNTIME_CONFIG as si,applyConnectorRuntimeConfigPatch as oi,extractConnectorRuntimeConfigPatch as ri}from"./runtime-config.js";import{DEFAULT_QUOTE_TRIGGER_BY_ADAPTER as ai,SendController as di}from"./send-controller.js";import{providerQuotaToRateLimits as li,providerQuotaToCodexRateLimits as ci}from"../core/provider-quota/index.js";import{buildToolUseCard as C,buildToolResultCard as b,buildDshOnlineToolCard as hi,buildLocalGrixCardLink as I}from"./tool-card-utils.js";import{planRawEventDelivery as ui,buildAuxiliaryDetailText as pi}from"./raw-event-delivery.js";import{DeferredEventManager as gi}from"./deferred-events.js";import{buildAgentProbeResult as fi,PROBE_CACHE_TTL_STATIC_MS as mi,PROBE_CACHE_TTL_FULL_MS as vi}from"./probe-helper.js";import{BridgeAuditController as _i}from"../audit/integration/bridge-audit-controller.js";import{isSettlableAuditProducer as Si,NoopAuditProducer as Ci}from"../audit/producer/audit-producer.js";import{buildAuditStatePayload as O,AuditPreparationFailedError as bi,AuditTurnScopeUnsupportedError as Ai}from"../audit/core/audit-state.js";import{extractAuditOptions as B,freezeAuditOptions as Ei,stripAuditOptions as wi}from"../audit/core/audit-options.js";import{AuditSessionOptionsError as yi}from"../audit/core/audit-session-registry.js";import{waitForIdle as Ri,formatWaitDuration as ki}from"../core/upgrade/idle-wait.js";const Ti=600*1e3,Pi=1800*1e3,xi=5*6e4,Li=60*1e3,Mi=4e3;function Hi(x,e,n){const r=L("sha256").update(x).update("\0").update(e).update("\0").update(n).digest("hex");return R.join(w.data,"audit-source","reasonix",`${r}.jsonl`)}const $i=new Set(["claude","codex","cursor","codewhale","opencode","pi","openhuman","agy","acp","deepseek-harness"]),y=3;class Eo{config;name;aibotHandle;aibotConfig;pool;stopped=!1;startupAbortController=new AbortController;stopPromise=null;dropPendingEventsRequested=!1;pendingEventsDropped=!1;revokeHandler=new mn;sessionBindings=new Map;customToolbars=new Map;deferredMgr;sendCtrl=new di(si);bindingStore;globalConfigStore;upgradeTrigger=null;daemonShutdownRequester=null;lifecycleBusyChecker=null;lifecycleAdmissionCloser=null;lifecycleAdmissionRestorer=null;installAgentHandler=null;remoteAdminPorts=null;pendingCliInstalls=new Map;agentDeletedHandler=null;shareSetHandler=null;skillSyncHandler=null;providerConfigHandler=null;relayStateApplyPorts=null;relayStateSyncer=null;agentProfile={agentName:"",introduction:""};agentSystemPrompt="";activeEventStore;pendingEvents;pendingStartedEventIds=new Set;lifecycleBarrier=new ni;cachedRateLimits=null;cachedRateLimitsSampledAtMs=null;cachedCodexContextWindow=null;cachedCodexTokenUsage=null;cachedCodexUsageSampledAtMs=null;cachedAcpContextWindow=null;cachedAcpContextWindowSampledAtMs=null;cachedClaudeRateLimitState=null;cachedProviderQuota=null;cachedProviderQuotaSampledAtMs=null;cachedProviderQuotaKey=null;sessionProviderHints=new Map;sessionProviderQuotas=new Map;sessionProviderMeta=new Map;lastModelSwitchQuotaRefresh=null;claudeWorkerStatus=new Map;lastReportedSkillsHash="";lastReportedSkillsWireHash="";conversationLog=null;packetLog=null;providerQuotaTimer=null;eventSessionIndex=new Map;inflightEvents=new Map;restartCount=new Map;selfDrivenSessions=new Set;selfDrivenLabels=new Map;probeCache=new Map;auditController;auditLocalActionHandler=null;sessionScanCache;reasonixTitleScan=null;isRateLimitsCacheFresh(e){if(!Number.isFinite(e))return!1;const n=Number(e);return n>0&&Date.now()-n<=Li}resolveProviderQuotaSource(e){return tn(this,e)}maybeQueryProviderQuota(e=!1,n){return nn(this,e,n)}startProviderQuotaTimer(){sn(this)}stopProviderQuotaTimer(){on(this)}refreshAndPushProviderQuota(e=!1){return rn(this,e)}pushProviderQuotaToBindings(e,n=!1){an(this,e,n)}enrichProviderQuotaMeta(e,n="standard",r=this.cachedProviderQuota,i=this.cachedProviderQuotaSampledAtMs){return dn(this,e,n,r,i)}providerQuotaMetaPayload(e,n,r){return ln(this,e,n,r)}refreshProviderQuotaForSession(e,n,r){return cn(this,e,n,r)}refreshQuotaAfterModelSwitch(e,n,r){hn(this,e,n,r)}doRefreshQuotaAfterModelSwitch(e,n,r){return un(this,e,n,r)}getFreshClaudeRateLimitState(){const e=this.cachedClaudeRateLimitState;return e&&this.isRateLimitsCacheFresh(e.sampledAt)?e:null}getFreshCodexGlobalRateLimitCache(){const e=this.cachedRateLimits,n=this.cachedCodexContextWindow,r=this.cachedCodexTokenUsage;return{sampledAt:Math.max(this.cachedRateLimitsSampledAtMs??0,this.cachedCodexUsageSampledAtMs??0)||null,rateLimits:e,contextWindow:n,tokenUsage:r,hasData:!!(e||n||r)}}getStatus(){const e=this.pool?.getStatus()??{total:0,ready:0,busy:0};return{name:this.name,agentId:this.config.aibot.agentId,alive:!this.stopped,busy:e.busy>0,wsConnected:this.aibotHandle?.status==="ready",exhausted:this.pool?[...this.pool.getAllSlots()].some(n=>n.respawn.exhausted):!1,adapterType:this.config.adapterType??"acp",clientType:this.config.aibot.clientType,pool:e}}hasPendingWork(){return this.pool?.hasPendingWork()??!1}hasPendingOrBackgroundWork(){return this.lifecycleBarrier.hasActiveAdmissions()||(this.pool?.hasPendingOrBackgroundWork()??!1)}describePendingOrBackgroundWork(){const e=this.lifecycleBarrier.describeActiveAdmissions().map(({label:r,heldMs:i})=>({source:"admission",agent:this.name,label:r,...i>xi?{suspect:`admission held for ${ki(i)}`}:{}})),n=(this.pool?.describePendingOrBackgroundWork()??[]).map(r=>({...r,agent:this.name}));return[...e,...n]}async waitUntilLifecycleIdle(e){return Ri({describeBusy:()=>this.lifecycleBusyChecker?.()??this.describePendingOrBackgroundWork(),isStopped:()=>this.stopped,closeAdmission:()=>this.closeLifecycleAdmissionForRestart(),reopenAdmission:()=>this.reopenLifecycleAdmissionAfterAbort(),budgetMs:Pi,log:(n,r)=>{n==="warn"?h.warn(this.name,`${e}: ${r}`):h.info(this.name,`${e}: ${r}`)}})}reopenLifecycleAdmissionAfterAbort(){if(this.lifecycleAdmissionRestorer){this.lifecycleAdmissionRestorer();return}this.openLifecycleAdmission()}relayEnvStale=!1;relayEnvSettledHandler;async recycleAdaptersForRelayChange(){if(!this.pool)return this.relayEnvStale=!1,!0;if(this.hasPendingWork())return this.relayEnvStale=!0,h.info(this.name,"relay changed but agent is busy; adapters keep the old env until the next message (marked stale)"),!1;const e=[...this.pool.getAllSlots()];let n=0,r=!1;for(const i of e){if(this.hasPendingWork())return this.relayEnvStale=!0,h.info(this.name,"new work arrived while recycling; remaining adapters stay stale until the next message"),!1;let t=!1;await this.pool.removeSlot(i.sessionId).catch(s=>{r=!0,t=!0,h.warn(this.name,`failed to recycle adapter slot ${i.sessionId} after relay change: ${s}`)}),t||(n+=1)}return n>0&&h.info(this.name,`recycled ${n} adapter slot(s) so the new Grix relay env takes effect`),r?(this.relayEnvStale=!0,!1):(this.relayEnvStale=!1,this.relayEnvSettledHandler?.(),!0)}setRelayEnvSettledHandler(e){this.relayEnvSettledHandler=e}providerResolver;setProviderResolver(e){this.providerResolver=e}hasStaleRelayEnv(){return this.relayEnvStale}markRelayEnvStale(){this.relayEnvStale=!0}async probe(e={}){const n=e.conversation?"full":"static",r=e.conversation?vi:mi;if(!e.fresh){const a=this.probeCache.get(n);if(a&&Date.now()-a.sampledAt<r)return{...a.result,cached:!0}}const i=this.config.adapterType??"acp",t=this.createAdapter(i,"__probe__"),s=e.conversation&&i==="acp"?()=>this.runAcpConversationProbe(t,e.timeoutMs??1e4):void 0;let o;try{o=await fi({adapter:t,agentName:this.name,clientType:this.config.aibot.clientType,adapterType:i,providerBaseUrl:this.config.providerBaseUrl??null,opts:e,launchConversationProbe:s})}finally{t.stop().catch(()=>{})}return this.probeCache.set(n,{result:o,sampledAt:o.probed_at}),o}async runAcpConversationProbe(e,n){const r=Date.now(),i="__probe__",t=`probe-${Date.now()}-${Math.random().toString(36).slice(2,8)}`,s=this.config.agent.cwd||F(),o=()=>Date.now()-r;try{await e.start()}catch(u){return{attempted:!0,ok:!1,latency_ms:o(),error:{code:"conversation_failed",message:`start failed: ${u instanceof Error?u.message:String(u)}`}}}if(!e.isAlive())return{attempted:!0,ok:!1,latency_ms:o(),error:{code:"process_not_started",message:"agent process not alive"}};if(e instanceof S)try{await e.bindSession(i,s)}catch{}let a=null;const l=new Promise(u=>{a=g=>{g===t&&u()},e.on("eventDone",a)});e.deliverInboundEvent({event_id:t,session_id:i,content:"ping",msg_id:t}),e.deliverStopEvent(t,i);let d=null;const c=await Promise.race([l.then(()=>!1),new Promise(u=>{d=setTimeout(()=>u(!0),n)})]);return d&&clearTimeout(d),a&&e.removeListener("eventDone",a),c?{attempted:!0,ok:!1,latency_ms:o(),error:{code:"conversation_timeout",message:`no eventDone within ${n}ms`}}:{attempted:!0,ok:!0,latency_ms:o()}}constructor(e,n,r=new Ci){this.config=e,this.auditController=new _i(r,{onAuditState:t=>{try{this.aibotHandle.sendAuditState(O(t,Date.now()))}catch{}}}),Si(r)&&r.addJobSettledHandler((t,s)=>{this.auditController.handleJobSettled(t,s)}),this.name=e.name;const i=e.adapterType??"acp";if(this.sendCtrl.setDefaultQuoteTrigger(ai[i]),this.aibotConfig={...e.aibot,...i==="claude"?{localActions:e.aibot.localActions??["session_control","claude_interaction_reply","get_session_usage","get_rate_limits","set_model","set_mode","set_reasoning_effort","thread_compact","get_agent_global_config",...q]}:{}},e.eventQueue&&(this.aibotConfig.concurrency={max_concurrent:e.eventQueue.maxConcurrent,max_queued:e.eventQueue.maxQueued,queue_timeout_ms:e.eventQueue.queueTimeoutMs,cancelable_queued:e.eventQueue.cancelableQueued,cancelable_running:e.eventQueue.cancelableRunning}),this.conversationLog=e.logDir?new ke(e.logDir):null,this.packetLog=e.logDir?new Te(e.logDir):null,this.bindingStore=new zn(e.bindingsPath,e.legacyBindingsPath),this.bindingStore.load(),this.globalConfigStore=n??null,this.deferredMgr=new gi(this.name),this.activeEventStore=e.activeEventStorePath?new ei(e.activeEventStorePath):null,this.pendingEvents=new ti(e.pendingEventStorePath),i==="codex")this.sessionScanCache=new v(ae,_e);else if(i==="claude")this.sessionScanCache=new v(de,Se);else if(i==="pi"){const t=e.agent.env?.PI_CODING_AGENT_DIR;this.sessionScanCache=new v(()=>ue(void 0,t),()=>be(void 0,t))}else if(i==="codewhale")this.sessionScanCache=new v(pe,Ae);else if(i==="cursor")this.sessionScanCache=new v(ge,Ee);else if(i==="opencode"){const t=me(e.agent.command||"opencode")||"opencode";this.sessionScanCache=new v(()=>fe(void 0,t),()=>we(void 0,t))}else if(i==="deepseek-harness"){const t=typeof e.adapterOptions?.dshHome=="string"?e.adapterOptions.dshHome:e.agent.env?.DSH_HOME;this.sessionScanCache=new v(()=>ve(t),()=>ye(t))}else if(i==="agy")this.sessionScanCache=new v(()=>[],()=>[]);else{e.aibot.clientType?.trim().toLowerCase()==="reasonix"&&(this.reasonixTitleScan=new v(he,Re));const t=le(e.aibot.clientType);this.sessionScanCache=t?new v(()=>ce(void 0,t),()=>Ce(void 0,t)):new v(()=>[],()=>[])}}async start(){if(this.stopped)throw new Error("agent start aborted");if(await re({agentName:this.name,adapterType:this.config.adapterType??"acp",command:this.config.agent.command,piConfigDir:this.config.agent.env?.PI_CODING_AGENT_DIR,dshHome:typeof this.config.adapterOptions?.dshHome=="string"?this.config.adapterOptions.dshHome:this.config.agent.env?.DSH_HOME,hasProvider:!!this.config.agent.provider,boundCwds:[...this.bindingStore.entries()].map(([,t])=>String(t.cwd??""))}).then(t=>{t.length>0&&h.info(this.name,`restored native provider config after relay disable: ${t.join(", ")}`)}).catch(t=>{h.warn(this.name,`native provider residue sweep failed: ${t instanceof Error?t.message:String(t)}`)}),this.stopped)throw new Error("agent start aborted");if((this.config.adapterType??"acp")==="claude"){if(await X().catch(()=>{}),this.stopped)throw new Error("agent start aborted");this.maybeQueryProviderQuota().catch(()=>{})}if(this.stopped)throw new Error("agent start aborted");const e=!!(this.config.providerBaseUrl&&this.config.providerApiKey||this.config.agent.provider?.baseUrl&&this.config.agent.provider?.apiKey),n=(this.config.adapterType??"acp")==="pi",r=(this.config.adapterType??"acp")==="opencode";if(this.config.aibot.clientType==="kiro"||this.config.aibot.clientType==="kimi"||e?(this.maybeQueryProviderQuota().catch(()=>{}),this.startProviderQuotaTimer()):(n||r)&&this.startProviderQuotaTimer(),(this.config.adapterType??"acp")==="codex"&&this.maybeQueryProviderQuota().catch(()=>{}),(this.config.adapterType??"acp")==="opencode"&&this.maybeQueryProviderQuota().catch(()=>{}),this.stopped)throw new Error("agent start aborted");if(await this.connectAibot(),this.stopped)throw this.aibotHandle?.disconnect(),new Error("agent start aborted");this.sendCtrl.bind(this.aibotHandle);const i=this.config.adapterType??"acp";if(this.pool=new vn({maxPoolSize:this.config.poolMaxSize??20,idleTimeoutMs:this.config.poolIdleTimeoutMs??18e5,eventQueue:this.config.eventQueue},t=>{const s=this.createAdapter(i,t);return s instanceof S&&s.on("acpSessionReady",o=>{this.bindingStore.setAcpSessionId(t,o),this.sessionScanCache.invalidate()}),s},(t,s)=>{this.aibotHandle.sendEventAck({event_id:t,session_id:s,received_at:Date.now()})}),this.pool.setEventStateHandler((t,s,o,a)=>{if(h.info(this.name,`[queue-debug] send event_state session=${s} event=${t} state=${o} queue_pos=${a?.queue_position??""} queue_total=${a?.queue_total??""}`),this.aibotHandle.sendEventState({event_id:t,session_id:s,state:o,content_preview:a?.content_preview,content:a?.content,queue_position:a?.queue_position,queue_total:a?.queue_total,actions:a?.actions,reason:a?.reason,held:a?.held,held_reason:a?.held_reason,updated_at:Date.now()}),this.pushQueueSnapshotForSession(s),o==="running"&&(this.pendingStartedEventIds.add(t),this.pendingEvents.remove(t).catch(l=>{h.warn(this.name,`Failed to remove running event from pending store event=${t}: ${l instanceof Error?l.message:String(l)}`)})),o==="canceled"||o==="failed"){const l=o==="canceled"?"canceled":"failed";this.aibotHandle.sendEventResult({event_id:t,status:l,msg:a?.reason,updated_at:Date.now()}),this.auditController.closeWithoutAdapter(t,l,a?.reason,{queueTerminalState:o}),this.discardEventTrackingState(t),this.pendingEvents.remove(t).catch(d=>{h.warn(this.name,`Failed to remove queued terminal event from pending store event=${t}: ${d instanceof Error?d.message:String(d)}`)})}}),this.pool.setQueueComposingHandler((t,s,o)=>{this.aibotHandle.sendSessionActivitySet({session_id:t,kind:"composing",active:s,...s?{ttl_ms:ii,ref_event_id:o}:{}})}),this.pool.setInternalErrorHandler(t=>{this.handleSessionInternalError(t).catch(s=>{h.error(this.name,`[recovery] handleSessionInternalError failed event=${t.eventId} session=${t.sessionId}: ${s instanceof Error?s.message:String(s)}`)})}),this.pool.setEventStartedHandler((t,s)=>{if(this.reportSessionSkills(s),this.config.adapterType!=="claude")return;this.claudeWorkerStatus.set(s,"busy");const o=this.bindingStore.get(s);o?.cwd&&this.aibotHandle.sendUpdateBindingCard({session_id:s,worker_status:"busy",cwd:o.cwd,meta:this.buildClaudeToolbarMeta(s)})}),this.pool.setEventDoneHandler((t,s)=>{this.markAuditAdapterClosed(t,s);const o=this.config.adapterType??"acp";if(o==="claude"){this.claudeWorkerStatus.set(s,"ready");const a=this.bindingStore.get(s);a?.cwd&&this.aibotHandle.sendUpdateBindingCard({session_id:s,worker_status:"ready",cwd:a.cwd,meta:this.buildClaudeToolbarMeta(s)})}else if(o==="agy"){const a=this.bindingStore.get(s);if(a?.cwd){const l=this.buildAgyToolbarMeta(s),d=l?.available_models??[];h.info(this.name,`[agy-toolbar-diag] eventDone push binding card session=${s} model_id=${String(l?.model_id??"")} available_models=${d.length} meta_keys=${l?Object.keys(l).join(","):"<none>"}`),this.sendAgyBindingCard(s,a.cwd,l),this.refreshAndPushAgyQuota(s)}else h.info(this.name,`[agy-toolbar-diag] eventDone skip binding card: no binding cwd session=${s}`)}}),this.pool.setSessionActivityHandler((t,s,o)=>{const a=this.selfDrivenSessions.has(t),l=this.selfDrivenLabels.get(t);s?(this.selfDrivenSessions.add(t),o&&this.selfDrivenLabels.set(t,o),this.aibotHandle.sendSessionActivitySet({session_id:t,kind:"composing",active:!0,ttl_ms:9e4})):(this.selfDrivenSessions.delete(t),this.selfDrivenLabels.delete(t),a&&this.aibotHandle.sendSessionActivitySet({session_id:t,kind:"composing",active:!1})),(a!==s||s&&o!==void 0&&o!==l)&&this.pushQueueSnapshotForSession(t)}),await this.replayPendingEventsOnStartup(),this.stopped)throw new Error("agent start aborted");this.pool.startIdleSweep(),h.info(this.name,`Ready (adapter: ${i}, poolMax: ${this.config.poolMaxSize??20})`)}requestStop(){this.stopped=!0,this.lifecycleBarrier.close(),this.startupAbortController.abort(),this.pool?.stopIdleSweep(),this.stopProviderQuotaTimer(),this.pool?.pauseAllQueues("shutdown")}async stop(e){if(e?.dropPendingEvents&&(this.dropPendingEventsRequested=!0),this.requestStop(),!this.stopPromise){const n=this.stopOnce();this.stopPromise=n,n.catch(()=>{this.stopPromise===n&&(this.stopPromise=null)})}await this.stopPromise,this.dropPendingEventsRequested&&!this.pendingEventsDropped&&await this.dropPendingEventsBestEffort()}async stopOnce(){this.lifecycleBarrier.close(),this.pool?.stopIdleSweep(),this.stopProviderQuotaTimer(),this.pool?.pauseAllQueues("shutdown");const e=this.pool?.collectActiveEventIds()??[],n=new Map(e.map(o=>[o,this.eventSessionIndex.get(o)]));e.length>0&&this.activeEventStore&&await this.activeEventStore.save(e);for(const o of e)h.info(this.name,`Canceling active event on shutdown: ${o}`),this.sendEventResultWithCleanup(o,"canceled","process shutting down");e.length>0&&await new Promise(o=>setTimeout(o,100)),this.pool?.clearActiveEventsForShutdown();for(const o of e){const a=n.get(o),l=a?this.pool?.getSlot(a):void 0;this.auditController.markAdapterClosed(o,l?.adapter.takeAuditBoundary?.(o)??{processTerminated:!0})}const r=this.deferredMgr.getAllDeferredEntries(),i=this.pool?.drainAllQueuedEvents()??[],t=this.pendingEvents.dedupe([...this.pendingEvents.replaySnapshot(),...r.map(o=>({kind:"deferred",channel:o.channel,sessionId:o.sessionId,event:o.event})),...i.map(o=>({kind:"queued",event:o}))]);let s=!1;if(this.dropPendingEventsRequested)try{await this.pendingEvents.clear(),this.pendingEventsDropped=!0}catch(o){h.warn(this.name,`Failed to clear pending event store on removal: ${o instanceof Error?o.message:String(o)}`)}else try{s=await this.pendingEvents.mergeForShutdown(t)}catch(o){h.error(this.name,`Failed to persist pending events on shutdown: ${o instanceof Error?o.message:String(o)}`)}if(!s)for(const o of t){const a=o.event;h.info(this.name,`Failing pending event on shutdown: ${a.event_id}`),this.sendEventResultWithCleanup(a.event_id,"failed","process shutting down"),this.auditController.markAdapterClosed(a.event_id,{adapterNotStarted:!0,processTerminated:!0})}this.deferredMgr.clearAll(),await this.pool?.stop(),this.aibotHandle?.disconnect(),e.length>0&&this.activeEventStore&&await this.activeEventStore.save([]),this.eventSessionIndex.clear(),this.inflightEvents.clear(),this.restartCount.clear(),this.auditController.dispose()}async dropPendingEventsBestEffort(){try{await this.pendingEvents.clear(),this.pendingEventsDropped=!0}catch(e){h.warn(this.name,`Failed to clear pending event store on removal: ${e instanceof Error?e.message:String(e)}`)}}resolveSpawnEnv(){const e=this.providerResolver?this.providerResolver():this.config.agent.provider,n=ie(this.config.agent.clientType,e),r=this.config.agent.env;let i=Object.keys(n).length>0?{...n,...r}:r;if(se(n)){const t=ee()?.getRuntimeInfo(),s={...r??{},...n},o=oe(s,{proxyUrl:t?.proxyUrl,caCertPath:t?.caCertPath,caBundlePath:t?.caBundlePath});return delete o.ANTHROPIC_API_KEY,delete o.CLAUDE_CODE_OAUTH_TOKEN,o}if(ne(this.config.agent.clientType)){const t=te(this.name);t&&(i={...i??{},...t})}return Z(i,this.name,this.config.agent.clientType)}createAdapter(e,n){switch(e){case"claude":return this.createClaudeAdapter(n);case"codex":return this.createCodexAdapter(n);case"pi":return this.createPiAdapter(n);case"openhuman":return this.createOpenHumanAdapter(n);case"codewhale":return this.createCodeWhaleAdapter(n);case"cursor":return this.createCursorAdapter(n);case"opencode":return this.createOpenCodeAdapter(n);case"agy":return this.createAgyAdapter(n);case"deepseek-harness":return this.createDshAdapter(n);default:return this.createAcpAdapter(n)}}createDshAdapter(e){const n={sendStreamChunk:(t,s,o,a,l,d,c)=>{this.sendStreamChunkByRuntimeConfig(t,s,o,a,l,d,c)},sendFinalStreamChunkReliable:this.reliableFinalWiring("deepseek-harness",Mi),sendThinking:(t,s,o)=>this.sendThinkingByRuntimeConfig(t,s,o),sendEventResult:(t,s,o,a)=>{this.sendEventResultWithCleanup(t,s,o,void 0,a)},sendRawEventEnvelope:(t,s,o,a)=>{const l=hi(o);if(l){this.sendToolExecutionCard(t,s,l);return}this.deliverRawEventEnvelope(t,s,o,"deepseek",a)},sendLocalActionResult:(t,s,o,a,l)=>{this.aibotHandle.sendLocalActionResult({action_id:t,status:s,...o!==void 0?{result:o}:{},...a?{error_code:a}:{},...l?{error_msg:l}:{}},e)},sendPermissionCard:t=>{this.sendGrixApprovalCard(t,"deepseek")},sendUpdateBindingCard:(t,s,o,a)=>{this.aibotHandle.sendUpdateBindingCard({session_id:t,worker_status:s,cwd:o,meta:a})},getAgentProfile:()=>({...this.agentProfile,systemPrompt:this.agentSystemPrompt}),getAgentId:()=>this.config.aibot.agentId,queryProviderQuota:t=>this.maybeQueryProviderQuota(t===!0,{providerId:"deepseek"}),agentInvoke:async(t,s,o)=>this.platformInvoke(t,s,o),eventToolInvoke:async(t,s)=>this.invokeDshEventTool(t,s)},r=L("sha256").update(this.config.aibot.agentId).digest("hex").slice(0,24),i=this.config.adapterOptions??{};return new K({command:this.config.agent.command,args:this.config.agent.args,env:this.resolveSpawnEnv(),options:i},n,{aibotSessionId:e,bindingStore:this.bindingStore,globalConfigStore:this.globalConfigStore,agentName:this.name,dataRoot:R.join(w.data,"deepseek-harness",r),...typeof i.cordisPath=="string"?{cordisPath:i.cordisPath}:{},...typeof i.defaultModel=="string"?{defaultModel:i.defaultModel}:{},...typeof i.maxTokens=="number"?{maxTokens:i.maxTokens}:{},...typeof i.maxLineBytes=="number"?{maxLineBytes:i.maxLineBytes}:{},...i.integrationMode==="embedded_jsonrpc"||i.integrationMode==="profile_bridge"?{integrationMode:i.integrationMode}:{},...typeof i.dshHome=="string"?{dshHome:i.dshHome}:{},...typeof i.dshProfile=="string"?{dshProfile:i.dshProfile}:{},...typeof i.autoInstallBridge=="boolean"?{autoInstallBridge:i.autoInstallBridge}:{},...typeof i.autoStartProfile=="boolean"?{autoStartProfile:i.autoStartProfile}:{},...this.config.agent.provider?{provider:this.config.agent.provider}:{},promptTimeoutMs:this.config.promptTimeoutMs})}createCursorAdapter(e){const n={...this.config.adapterOptions??{}};n.bindingStore=this.bindingStore,n.aibotSessionId=e;const r=this.bindingStore.get(e),i=this.resolveSessionModelId(e);i&&(n.model=i);const t=this.resolveCursorSessionModeId(e),s=t??"full_auto";t||this.bindingStore.setCursorModeId(e,s),n.mode=s,r?.cwd&&(n.workspace=r.cwd);const o={sendStreamChunk:(a,l,d,c,u,g,p)=>{this.sendStreamChunkByRuntimeConfig(a,l,d,c,u,g,p)},sendEventResult:(a,l,d)=>{this.sendEventResultWithCleanup(a,l,d)},sendEventAck:(a,l)=>{this.aibotHandle.sendEventAck({event_id:a,session_id:l,received_at:Date.now()})},sendRawEventEnvelope:(a,l,d)=>{this.deliverRawEventEnvelope(a,l,d,"cursor",this.buildCursorRawEventFallbackText(d))},sendAgentQuestionCard:(a,l,d)=>{const c=d.questions.map(g=>g.header).join(", "),u=I(`[Agent Question] ${d.request_id}`,"agent_question",d);this.aibotHandle.sendText({event_id:a,session_id:l,content:u,msg_type:1,extra:{card_type:"agent_question",summary_text:c}})},agentInvoke:async(a,l,d)=>this.platformInvoke(a,l,d),sendLocalActionResult:(a,l,d,c,u)=>{this.aibotHandle.sendLocalActionResult({action_id:a,status:l,...d!==void 0?{result:d}:{},...c?{error_code:c}:{},...u?{error_msg:u}:{}},e)},sendUpdateBindingCard:(a,l,d,c)=>{this.aibotHandle.sendUpdateBindingCard({session_id:a,worker_status:l,cwd:d,...c?{meta:c}:{}})},getAgentProfile:()=>this.agentProfile,getAgentId:()=>this.config.aibot.agentId};return new G({command:this.config.agent.command,args:this.config.agent.args,env:this.resolveSpawnEnv(),options:n},o)}createClaudeAdapter(e){const n={sendReply:(t,s,o,a,l)=>{this.sendReplyByRuntimeConfig(t,s,o,a,l)},sendStreamChunk:(t,s,o,a,l,d,c)=>{this.sendStreamChunkByRuntimeConfig(t,s,o,a,l,d,c)},sendMedia:(t,s,o,a,l,d,c)=>{this.aibotHandle.sendMedia({event_id:t,session_id:s,content:o,msg_type:2,quoted_message_id:l||void 0,client_msg_id:d||void 0,extra:c?{media_caption:a,...c}:{media_caption:a}})},sendEventResult:(t,s,o,a,l)=>{this.sendEventResultWithCleanup(t,s,o,a,l)},sendEventAck:(t,s)=>{this.aibotHandle.sendEventAck({event_id:t,session_id:s,received_at:Date.now()})},agentInvoke:async(t,s,o)=>this.platformInvoke(t,s,o),sendLocalActionResult:(t,s,o,a,l)=>{this.aibotHandle.sendLocalActionResult({action_id:t,status:s,...o!==void 0?{result:o}:{},...a?{error_code:a}:{},...l?{error_msg:l}:{}},e)},sendToolUse:(t,s,o,a)=>{this.sendToolExecutionCard(t,s,C(o,a))},sendToolResult:(t,s,o,a)=>{this.sendToolExecutionCard(t,s,b(o,a))},getWsUrl:()=>this.config.aibot.url,getAgentId:()=>this.config.aibot.agentId,getAgentProfile:()=>this.agentProfile,getApiKey:()=>this.config.aibot.apiKey,getActiveEventCount:()=>0,getPendingPermissionCount:()=>0,getPendingElicitationCount:()=>0,sendAgentQuestionCard:(t,s,o)=>{this.sendGrixAgentQuestionCard(t,s,o)},sendPermissionCard:t=>{this.sendGrixApprovalCard(t,"claude")},sendDirectMessage:t=>{this.aibotHandle.sendMsg({session_id:t.sessionId,msg_type:1,content:t.content,...t.clientMsgId?{client_msg_id:t.clientMsgId}:{},...t.quotedMessageId?{quoted_message_id:t.quotedMessageId}:{}})},onStatusLineUpdated:t=>{(t.rateLimits?.fiveHour||t.rateLimits?.sevenDay)&&(this.cachedClaudeRateLimitState=t);const s=this.bindingStore.get(e);s?.cwd&&this.aibotHandle.sendUpdateBindingCard({session_id:e,worker_status:this.claudeWorkerStatus.get(e)??"ready",cwd:s.cwd,meta:this.buildClaudeToolbarMeta(e)})},sendMcpFrame:t=>{this.aibotHandle.sendMcpFrame(e,t)}},r=this.config.adapterOptions??{},i={...r,sessionRuntimeResolver:()=>{const t=this.bindingStore.get(e),s=this.auditController.getSession(e);return{cwd:t?.cwd,modeId:this.resolveClaudeSessionModeId(e)??z.fullAuto,modelId:this.resolveSessionModelId(e),effort:this.resolveClaudeSessionEffort(e),pluginDir:r.pluginDir,claudeSessionId:t?.claudeSessionId,...s?{audit:{enabled:!0,profile:s.options.profile,capture:s.options.capture}}:{},onSessionIdAssigned:o=>{this.bindingStore.setClaudeSessionId(e,o),this.sessionScanCache.invalidate()}}}};return new M({command:this.config.agent.command,args:this.config.agent.args,env:this.resolveSpawnEnv(),options:i},n)}createCodexAdapter(e){let n=null;const r={sendEventResult:(o,a,l)=>{if(a!=="responded"){this.sendEventResultWithCleanup(o,a,l);return}this.sendCtrl.sendFinalStreamChunkReliable(o,e,`codex_terminal_fence_${o}`,5e3,!0,!0).then(()=>this.sendEventResultWithCleanup(o,a,l),d=>{const c=`codex output acceptance fence failed: ${d instanceof Error?d.message:String(d)}`;this.sendEventResultWithCleanup(o,a==="responded"?"failed":a,a==="responded"?c:l)})},sendEventAck:(o,a)=>this.aibotHandle.sendEventAck({event_id:o,session_id:a,received_at:Date.now()}),sendCodexEvent:o=>{this.shouldDropCodexDisplayEvent(o.event_id,o.codex_method)||(this.captureCodexAuditOutput(o),this.aibotHandle.sendCodexEvent(this.stampCodexEventQuote(o)),this.logCodexEventToConversation(o))},sendThinking:(o,a,l)=>{this.sendThinkingByRuntimeConfig(o,a,l)},sendRunError:(o,a,l)=>{this.sendRunErrorAsChunk(o,a,l)},sendUpdateBindingCard:(o,a,l,d)=>{const c={...d??{}};if(!c.rate_limits&&this.cachedProviderQuota?.success){this.isRateLimitsCacheFresh(this.cachedProviderQuotaSampledAtMs)||this.maybeQueryProviderQuota().catch(()=>{});const u=this.providerQuotaToCodexRateLimits(this.cachedProviderQuota);u&&(c.rate_limits=u.rateLimits,c.rate_limit_primary_percent=u.primaryPercent,c.rate_limit_secondary_percent=u.secondaryPercent,c.rate_limit_primary_window_min=u.primaryWindowMin,c.rate_limit_secondary_window_min=u.secondaryWindowMin)}!c.provider_quota&&this.cachedProviderQuota?.success&&(c.provider_quota=this.cachedProviderQuota),this.aibotHandle.sendUpdateBindingCard({session_id:o,worker_status:a,cwd:l,...Object.keys(c).length>0?{meta:c}:{}})},agentInvoke:async(o,a,l)=>this.platformInvoke(o,a,l),sendLocalActionResult:(o,a,l,d,c)=>this.aibotHandle.sendLocalActionResult({action_id:o,status:a,...l!==void 0?{result:l}:{},...d?{error_code:d}:{},...c?{error_msg:c}:{}},e),sendSessionActivitySet:(o,a,l,d)=>{this.aibotHandle.sendSessionActivitySet({session_id:o,kind:a,active:l,...d??{}})},getConversationLog:()=>this.conversationLog,getAgentProfile:()=>this.agentProfile,getAgentId:()=>this.config.aibot.agentId,onRateLimitsUpdated:o=>{this.cachedRateLimits=o,this.cachedRateLimitsSampledAtMs=Date.now(),this.isRateLimitsCacheFresh(this.cachedProviderQuotaSampledAtMs)||this.maybeQueryProviderQuota().catch(()=>{});const a=this.bindingStore.get(e);if(a?.cwd){const l=this.cachedRateLimitsSampledAtMs,d={rate_limits:{...o.primary.windowMinutes>0?{primary:o.primary}:{},...o.secondary.windowMinutes>0?{secondary:o.secondary}:{},sampledAt:l},rate_limit_primary_percent:o.primary.usedPercent,rate_limit_secondary_percent:o.secondary.usedPercent,rate_limit_primary_window_min:o.primary.windowMinutes,rate_limit_secondary_window_min:o.secondary.windowMinutes,credits:o.credits,...o.extras&&o.extras.length>0?{extra_limits:o.extras}:{},...n?.getEffortMeta()};this.cachedProviderQuota?.success&&(d.provider_quota=this.cachedProviderQuota),this.aibotHandle.sendUpdateBindingCard({session_id:e,worker_status:"ready",cwd:a.cwd,meta:d})}},onContextWindowUpdated:o=>{if(!o)return;this.cachedCodexContextWindow=o,this.cachedCodexUsageSampledAtMs=Date.now();const a=this.bindingStore.get(e);a?.cwd&&this.aibotHandle.sendUpdateBindingCard({session_id:e,worker_status:"ready",cwd:a.cwd,meta:{context_window:o,...n?.getEffortMeta()}})},onTokenUsageUpdated:o=>{o&&(this.cachedCodexTokenUsage=o,this.cachedCodexUsageSampledAtMs=Date.now())}},i=this.config.adapterOptions??{},t=this.auditController.getAdapterPreparation(e),s=o=>Bt(this,"codex",e,o);return n=new H({command:this.config.agent.command,args:this.config.agent.args,env:this.resolveSpawnEnv(),options:{...i,model:s("model")??i.model,collaborationMode:s("mode")??i.collaborationMode,reasoningEffort:s("reasoningEffort")??i.reasoningEffort,serviceTier:s("serviceTier")??i.serviceTier,sandboxMode:s("sandboxMode")??i.sandboxMode,aibotSessionId:e,bindingStore:this.bindingStore,...D(t?.options)?{rawApiCapture:{auditId:t.auditId,sessionId:e,spoolRootDir:R.join(w.data,"audit-replay","raw-spool")}}:{}}},r),n}createCodeWhaleAdapter(e){const n={sendEventResult:(i,t,s)=>{this.sendEventResultWithCleanup(i,t,s)},sendEventAck:(i,t)=>this.aibotHandle.sendEventAck({event_id:i,session_id:t,received_at:Date.now()}),sendStreamChunk:(i,t,s,o,a,l)=>{this.sendStreamChunkByRuntimeConfig(i,t,s,o,a,l)},sendUpdateBindingCard:(i,t,s,o)=>this.aibotHandle.sendUpdateBindingCard({session_id:i,worker_status:t,cwd:s,...this.providerQuotaMetaPayload(o,i,s)}),sendLocalActionResult:(i,t,s,o,a)=>this.aibotHandle.sendLocalActionResult({action_id:i,status:t,...s!==void 0?{result:s}:{},...o?{error_code:o}:{},...a?{error_msg:a}:{}},e),sendSessionActivitySet:(i,t,s,o)=>{this.aibotHandle.sendSessionActivitySet({session_id:i,kind:t,active:s,...o??{}})},sendToolUse:(i,t,s,o)=>{this.sendToolExecutionCard(i,t,C(s,o))},sendToolResult:(i,t,s,o)=>{this.sendToolExecutionCard(i,t,b(s,o))},agentInvoke:async(i,t,s)=>this.platformInvoke(i,t,s),getConversationLog:()=>this.conversationLog,getAgentProfile:()=>this.agentProfile,getAgentId:()=>this.config.aibot.agentId},r=this.config.adapterOptions??{};return new j({command:this.config.agent.command,args:this.config.agent.args,env:this.resolveSpawnEnv(),options:{...r,aibotSessionId:e,bindingStore:this.bindingStore,agentName:this.name,model:this.resolveSessionModelId(e)??r.model,...this.config.agent.provider?{provider:this.config.agent.provider}:{}}},n)}createPiAdapter(e){const n={sendEventResult:(i,t,s,o,a)=>{this.sendEventResultWithCleanup(i,t,s,o,a),h.info("bridge",`[pi] sendEventResult event=${i} status=${t}`)},sendEventAck:(i,t)=>this.aibotHandle.sendEventAck({event_id:i,session_id:t,received_at:Date.now()}),sendUpdateBindingCard:(i,t,s,o)=>this.aibotHandle.sendUpdateBindingCard({session_id:i,worker_status:t,cwd:s,...this.providerQuotaMetaPayload(o,i,s)}),agentInvoke:async(i,t,s)=>this.platformInvoke(i,t,s),sendLocalActionResult:(i,t,s,o,a)=>{this.aibotHandle.sendLocalActionResult({action_id:i,status:t,...s!==void 0?{result:s}:{},...o?{error_code:o}:{},...a?{error_msg:a}:{}},e)},sendSessionActivitySet:(i,t,s,o)=>{this.aibotHandle.sendSessionActivitySet({session_id:i,kind:t,active:s,...o??{}})},sendToolUse:(i,t,s,o)=>{this.sendToolExecutionCard(i,t,C(s,o))},sendToolResult:(i,t,s,o)=>{this.sendToolExecutionCard(i,t,b(s,o))},sendStreamChunk:(i,t,s,o,a,l)=>{this.sendStreamChunkByRuntimeConfig(i,t,s,o,a,l),a&&h.info("bridge",`[pi] sendFinalStreamChunk event=${i} seq=${o}`)},sendFinalStreamChunkReliable:this.reliableFinalWiring("pi"),sendThinking:(i,t,s)=>{this.sendThinkingByRuntimeConfig(i,t,s)},sendRunError:(i,t,s,o,a)=>{this.sendRunErrorAsChunk(i,t,s,o,a)},getAgentProfile:()=>this.agentProfile},r=this.config.adapterOptions??{};return new W({command:this.config.agent.command,args:this.config.agent.args,env:this.resolveSpawnEnv(),options:{...r,aibotSessionId:e,bindingStore:this.bindingStore,agentName:this.name,clientType:this.config.agent.clientType,...this.config.agent.provider?{provider:this.config.agent.provider}:{}}},n)}createOpenHumanAdapter(e){const n={sendStreamChunk:(i,t,s,o,a,l)=>{this.sendStreamChunkByRuntimeConfig(i,t,s,o,a,l)},sendFinalStreamChunkReliable:async(i,t,s,o)=>{try{await this.sendCtrl.sendFinalStreamChunkReliable(i,t,o)}catch(a){throw h.error("bridge",`[openhuman] sendFinalStreamChunkReliable ACK failed event=${i}: ${a}`),a}},sendEventResult:(i,t,s)=>{this.sendEventResultWithCleanup(i,t,s),h.info("bridge",`[openhuman] sendEventResult event=${i} status=${t}`)},sendEventAck:(i,t)=>this.aibotHandle.sendEventAck({event_id:i,session_id:t,received_at:Date.now()}),sendToolUse:(i,t,s,o)=>{this.sendToolExecutionCard(i,t,C(s,o))},sendToolResult:(i,t,s,o)=>{this.sendToolExecutionCard(i,t,b(s,o))},sendThinking:(i,t,s)=>{this.sendThinkingByRuntimeConfig(i,t,s)},sendRunError:(i,t,s)=>{this.sendRunErrorAsChunk(i,t,s,0)},sendUpdateBindingCard:(i,t,s,o)=>this.aibotHandle.sendUpdateBindingCard({session_id:i,worker_status:t,cwd:s,...this.providerQuotaMetaPayload(o,i,s)}),agentInvoke:async(i,t,s)=>this.platformInvoke(i,t,s),sendLocalActionResult:(i,t,s,o,a)=>{this.aibotHandle.sendLocalActionResult({action_id:i,status:t,...s!==void 0?{result:s}:{},...o?{error_code:o}:{},...a?{error_msg:a}:{}},e)},getAgentProfile:()=>this.agentProfile,getAgentId:()=>this.config.aibot.agentId},r=this.config.adapterOptions??{};return new N({command:this.config.agent.command,args:this.config.agent.args,env:this.resolveSpawnEnv(),options:r},n,{port:r.port,host:r.host,workspaceDir:r.workspace_dir,sessionToken:r.session_token,enableSessionBinding:!0,aibotSessionId:e})}createOpenCodeAdapter(e){const n={sendStreamChunk:(i,t,s,o,a,l)=>{this.sendStreamChunkByRuntimeConfig(i,t,s,o,a,l)},sendFinalStreamChunkReliable:this.reliableFinalWiring("opencode"),sendEventResult:(i,t,s,o,a)=>{this.sendEventResultWithCleanup(i,t,s,o,a),h.info("bridge",`[opencode] sendEventResult event=${i} status=${t}`)},sendEventAck:(i,t)=>this.aibotHandle.sendEventAck({event_id:i,session_id:t,received_at:Date.now()}),sendToolUse:(i,t,s,o)=>{this.sendToolExecutionCard(i,t,C(s,o))},sendToolResult:(i,t,s,o)=>{this.sendToolExecutionCard(i,t,b(s,o))},sendThinking:(i,t,s)=>{this.sendThinkingByRuntimeConfig(i,t,s)},sendRunError:(i,t,s)=>{this.sendRunErrorAsChunk(i,t,s)},sendUpdateBindingCard:(i,t,s,o)=>this.aibotHandle.sendUpdateBindingCard({session_id:i,worker_status:t,cwd:s,...this.providerQuotaMetaPayload(o,i,s)}),agentInvoke:async(i,t,s)=>this.platformInvoke(i,t,s),sendLocalActionResult:(i,t,s,o,a)=>{this.aibotHandle.sendLocalActionResult({action_id:i,status:t,...s!==void 0?{result:s}:{},...o?{error_code:o}:{},...a?{error_msg:a}:{}},e)},sendPermissionCard:i=>{this.sendGrixApprovalCard(i,"opencode")},sendAgentQuestionCard:(i,t,s)=>{this.sendGrixAgentQuestionCard(i,t,s)},getAgentProfile:()=>this.agentProfile,getAgentId:()=>this.config.aibot.agentId},r=this.config.adapterOptions??{};return new T({command:this.config.agent.command,args:this.config.agent.args,env:this.resolveSpawnEnv(),options:r},n,{port:r.port,hostname:r.hostname,model:r.model??this.resolveSessionModelId(e),agent:r.agent,permissionPolicy:r.permission_policy,enableSessionBinding:!0,aibotSessionId:e,bindingStore:this.bindingStore,...this.config.agent.provider?{provider:this.config.agent.provider}:{}})}createAgyAdapter(e){const n={sendStreamChunk:(i,t,s,o,a,l)=>{this.sendStreamChunkByRuntimeConfig(i,t,s,o,a,l)},sendEventResult:(i,t,s)=>{this.sendEventResultWithCleanup(i,t,s)},sendEventAck:(i,t)=>{this.aibotHandle.sendEventAck({event_id:i,session_id:t,received_at:Date.now()})},agentInvoke:async(i,t,s)=>this.platformInvoke(i,t,s),forceCompleteInternalEvent:(i,t)=>{this.pool.eventComplete(i,t),this.pushQueueSnapshotForSession(t)},persistConversationId:(i,t)=>{this.bindingStore.setAgyConversationId(i,t)},getAgentProfile:()=>this.agentProfile,getAgentId:()=>this.config.aibot.agentId},r=i=>{const t=this.bindingStore.get(i);return{cwd:t?.cwd,modelId:this.resolveSessionModelId(i),conversationId:t?.agyConversationId}};return new $({command:this.config.agent.command,args:this.config.agent.args,env:this.resolveSpawnEnv(),options:this.config.adapterOptions??{}},n,r)}createAcpAdapter(e){const n=this.isAcpRawTransportEnabled(),r={sendStreamChunk:(d,c,u,g,p,_,A)=>{this.sendStreamChunkByRuntimeConfig(d,c,u,g,p,_,A)},sendFinalStreamChunkReliable:this.reliableFinalWiring("acp",4e3),sendEventResult:(d,c,u,g,p)=>{this.sendEventResultWithCleanup(d,c,u,g,p)},sendEventAck:(d,c)=>{this.aibotHandle.sendEventAck({event_id:d,session_id:c,received_at:Date.now()})},agentInvoke:async(d,c,u)=>this.platformInvoke(d,c,u),sendLocalActionResult:(d,c,u,g,p)=>{this.aibotHandle.sendLocalActionResult({action_id:d,status:c,...u!==void 0?{result:u}:{},...g?{error_code:g}:{},...p?{error_msg:p}:{}},e)},sendRawEventEnvelope:(d,c,u)=>{this.sendAcpRawEventEnvelope(d,c,u)},sendToolUse:(d,c,u,g)=>{if(n){this.sendAcpRawEventEnvelope(d,c,{type:"tool_use",payload:{tool_name:u,tool_input:g??""}});return}this.sendToolExecutionCard(d,c,C(u,g))},sendToolResult:(d,c,u,g)=>{this.sendToolExecutionCard(d,c,b(u,g))},sendThinking:(d,c,u)=>{this.sendThinkingByRuntimeConfig(d,c,u)},sendRunError:(d,c,u)=>{this.sendRunErrorAsChunk(d,c,u)},sendAgentQuestionCard:(d,c,u)=>{this.sendGrixAgentQuestionCard(d,c,u)},sendPermissionCard:d=>{h.info("bridge","sendPermissionCard callback entered",{rawTransport:n,eventId:d.eventId,sessionId:d.sessionId,toolCallId:d.toolCallId,toolName:d.toolName,toolTitle:d.toolTitle});const c=d.toolInput&&d.toolTitle&&d.toolInput!==d.toolTitle?`${d.toolTitle}: ${d.toolInput}`:d.toolTitle||d.toolInput||d.toolName;if(n){this.sendAcpRawEventEnvelope(d.eventId,d.sessionId,{type:"permission_request",payload:{tool_call_id:d.toolCallId,tool_name:d.toolName,tool_title:d.toolTitle,...d.toolInput?{tool_input:d.toolInput}:{},options:d.options}}),h.info("bridge","sendPermissionCard: sent via rawEventEnvelope",{eventId:d.eventId,toolCallId:d.toolCallId});return}const u=`perm_${k()}`,g={event_id:d.eventId,session_id:d.sessionId,client_msg_id:u,msg_type:1,content:d.toolTitle?`Permission required: ${d.toolTitle}`:"Permission request",extra:{channel_data:{execApproval:{approvalId:d.toolCallId,approvalSlug:d.toolName},grix:{execApproval:{approval_command_id:d.toolCallId,approval_type:"permission",command:c,host:"acp"}}},agent_api_origin:!0}};h.info("bridge","sendPermissionCard: about to invoke aibotHandle.sendMsg",{eventId:d.eventId,sessionId:d.sessionId,clientMsgId:u,toolCallId:d.toolCallId,contentLength:g.content.length});try{this.aibotHandle.sendMsg(g),h.info("bridge","sendPermissionCard: aibotHandle.sendMsg returned",{eventId:d.eventId,clientMsgId:u})}catch(p){h.error("bridge","sendPermissionCard: aibotHandle.sendMsg threw",{eventId:d.eventId,clientMsgId:u,error:p instanceof Error?p.message:String(p)})}},sendAuthNotification:(d,c)=>{d&&this.aibotHandle.sendMsg({session_id:d,msg_type:1,content:c,extra:{biz_card:{version:1,type:"agent_error",payload:{error:{name:"AuthRequired",message:c}}}}})},sendAgentMessage:(d,c)=>{d&&c&&this.aibotHandle.sendMsg({session_id:d,msg_type:1,content:c})},sendUpdateBindingCard:(d,c,u,g)=>{const p={...g??{}};if(!p.rate_limits&&this.cachedProviderQuota?.success){this.isRateLimitsCacheFresh(this.cachedProviderQuotaSampledAtMs)||this.maybeQueryProviderQuota().catch(()=>{});const _=this.providerQuotaToRateLimits(this.cachedProviderQuota);_&&(p.rate_limits=_)}!p.provider_quota&&this.cachedProviderQuota?.success&&(p.provider_quota=this.cachedProviderQuota),this.aibotHandle.sendUpdateBindingCard({session_id:d,worker_status:c,cwd:u,...Object.keys(p).length>0?{meta:p}:{}})},onSkillsUpdate:(d,c)=>{try{this.aibotHandle.sendSkillsUpdate({skills:Y(d,w.skills),library_skills:this.buildLibrarySkillsReport(c)})}catch(u){}},onContextWindowUpdated:d=>{this.cachedAcpContextWindow=d,this.cachedAcpContextWindowSampledAtMs=Date.now();const c="usedPercentage"in d?d.usedPercentage.toFixed(1):(d.used/d.size*100).toFixed(1);h.info(this.name,`[acp] context_window updated: ${c}%`);const u=this.bindingStore.get(e);if(u?.cwd){const g="usedPercentage"in d?d.usedPercentage:Math.min(100,d.used/d.size*100),p={context_window:{..."usedPercentage"in d?{}:d,usedPercentage:g,remainingPercentage:100-g}};if((this.config.aibot.clientType==="kiro"||this.config.aibot.clientType==="kimi")&&this.cachedProviderQuota?.success){this.isRateLimitsCacheFresh(this.cachedProviderQuotaSampledAtMs)||this.maybeQueryProviderQuota().catch(()=>{}),p.provider_quota=this.cachedProviderQuota;const _=this.providerQuotaToRateLimits(this.cachedProviderQuota);_&&(p.rate_limits=_)}this.aibotHandle.sendUpdateBindingCard({session_id:e,worker_status:"ready",cwd:u.cwd,meta:p})}},sendMcpFrame:d=>{this.aibotHandle.sendMcpFrame(e,d)},getAgentProfile:()=>this.agentProfile,getAgentId:()=>this.config.aibot.agentId},i=e?this.bindingStore.get(e):void 0,t=e?this.auditController.getSession(e):void 0,s=this.config.aibot.clientType==="reasonix"&&t?Hi(this.name,e,t.auditId):void 0,o=this.globalConfigStore?.get(this.name),{initialModel:a,initialMode:l}=Kn({sessionBinding:i,globalDefaults:o,configInitialMode:this.config.acpInitialMode});return e&&a&&!i?.acpModelId&&this.bindingStore.setAcpModelId(e,a),e&&l&&!i?.acpModeId&&this.bindingStore.setAcpModeId(e,l),(a||l)&&h.info(this.name,`[toolbar] hydrate from binding: session=${e} model=${a??"<none>"} mode=${l??"<none>"}`),new S({command:this.config.agent.command,args:this.config.agent.args,env:this.resolveSpawnEnv()},r,{acpAuthMethod:this.config.acpAuthMethod,acpInitialMode:l,acpInitialModel:a,acpMcpTools:this.config.acpMcpTools,rawTransport:n,eventResultsPath:this.config.eventResultsPath,approvalMode:this.config.approvalMode,bindingStore:this.config.enableSessionBinding?this.bindingStore:void 0,aibotSessionId:e,autoInjectArgs:this.config.autoInjectArgs,nativeProviderScope:this.name,bridgeLog:this.config.logDir?new Pe(this.config.logDir,`${this.name}-${e}`):null,reasonixAuditTranscriptPath:s,agentType:this.config.aibot.clientType,newSessionParams:this.config.adapterOptions?.newSessionParams&&typeof this.config.adapterOptions.newSessionParams=="object"&&!Array.isArray(this.config.adapterOptions.newSessionParams)?this.config.adapterOptions.newSessionParams:void 0})}async connectAibot(){const n=await new U().connect(this.aibotConfig,{aborted:()=>this.stopped,signal:this.startupAbortController.signal,label:this.name,packetLog:this.packetLog,maxRetries:this.config.connectMaxRetries});if(this.stopped)throw n.disconnect(),new Error("connection aborted");this.aibotHandle=n;const r=this.aibotHandle.authAck;if(this.applyAgentProfile(r?.agent_name,r?.introduction,{source:"auth_ack",respawnOnChange:!1},r?.system_prompt),this.aibotHandle.onEvent(i=>{this.handleAibotEvent(i).catch(t=>{h.error(this.name,`handleAibotEvent failed: ${t}`),this.aibotHandle.sendEventAck({event_id:i.event_id,session_id:i.session_id,received_at:Date.now()});const s=t instanceof Error?t.message:String(t);this.handleStaleCwdError(i,s)||this.aibotHandle.sendEventResult({event_id:i.event_id,status:"failed",msg:s,updated_at:Date.now()})})}),this.aibotHandle.onStop(i=>{try{this.handleAibotStop(i)}catch(t){h.error(this.name,`handleAibotStop failed: ${t}`)}}),this.aibotHandle.onAgentDeleted(i=>{h.warn(this.name,`agent deleted on platform (source=${i?.source??"unknown"}${i?.reason?` reason=${i.reason}`:""}), notifying manager to clean up`);try{this.agentDeletedHandler?.()}catch(t){h.error(this.name,`agentDeletedHandler failed: ${t}`)}}),this.aibotHandle.onShareSet(i=>{try{this.shareSetHandler?.(Array.isArray(i?.shared_to)?i.shared_to:[])}catch(t){h.error(this.name,`onShareSet failed: ${t}`)}}),this.aibotHandle.onProfilePush(i=>{try{this.applyAgentProfile(i?.agent_name,i?.introduction,{source:"profile_push",respawnOnChange:!0},i?.system_prompt)}catch(t){h.error(this.name,`onProfilePush failed: ${t}`)}}),this.aibotHandle.onSkillSync(i=>{if(!this.stopped)try{h.info(this.name,`skill_sync received owner=${i?.owner_id??""} name=${i?.name??""}`),this.skillSyncHandler?.()}catch(t){h.error(this.name,`onSkillSync failed: ${t}`)}}),this.aibotHandle.onRevoke(i=>{this.handleAibotRevoke(i).catch(t=>{h.error(this.name,`handleAibotRevoke failed: ${t}`)})}),this.aibotHandle.onLocalAction(i=>{this.handleAibotLocalAction(i).catch(t=>{h.error(this.name,`handleAibotLocalAction failed: ${t}`)})}),this.aibotHandle.onEventCancel(i=>{h.info(this.name,`recv event_cancel event_id=${i.event_id} session_id=${i.session_id}`),this.handleEventCancel(i).catch(t=>{h.error(this.name,`handleEventCancel failed: ${t}`)})}),this.aibotHandle.onMcpFrame((i,t)=>{const s=this.pool.getSlot(i)?.adapter;s?.deliverMcpFrameToAgent?s.deliverMcpFrameToAgent(t):h.warn(this.name,`mcp_frame: no adapter for session=${i}`)}),this.aibotHandle.onQueueClear(i=>{const t=this.pool.clearQueue(i.session_id);this.aibotHandle.sendQueueClearResult({session_id:i.session_id,canceled_event_ids:t}),this.pushQueueSnapshotForSession(i.session_id)}),typeof this.aibotHandle.onQueueReorder=="function"&&this.aibotHandle.onQueueReorder(i=>{const t=Array.isArray(i.ordered_event_ids)?i.ordered_event_ids.filter(o=>typeof o=="string"&&o.length>0):[],s=this.pool.reorderQueue(i.session_id,t);this.aibotHandle.sendQueueReorderResult({session_id:i.session_id,applied_event_ids:s}),this.pushQueueSnapshotForSession(i.session_id)}),typeof this.aibotHandle.onEventHold=="function"&&this.aibotHandle.onEventHold(i=>{const t=typeof i.session_id=="string"?i.session_id:"",s=typeof i.event_id=="string"?i.event_id:"",o=i.hold!==!1;if(h.info(this.name,`recv event_hold event_id=${s} session_id=${t} hold=${o} reason=${i.reason??""}`),!t||!s){this.aibotHandle.sendEventHoldResult({session_id:t,event_id:s,ok:!1,held:!1,error:"bad_request"});return}const a=typeof i.reason=="string"?i.reason:"",l=typeof i.ttl_ms=="number"?i.ttl_ms:void 0,d=this.pool.holdEvent(t,s,o,a,l),c=d==="ok";this.aibotHandle.sendEventHoldResult({session_id:t,event_id:s,ok:c,held:c?o:!1,...c?{}:{error:d}}),c&&this.pushQueueSnapshotForSession(t)}),typeof this.aibotHandle.onQueueEdit=="function"&&this.aibotHandle.onQueueEdit(i=>{const t=typeof i.session_id=="string"?i.session_id:"",s=typeof i.event_id=="string"?i.event_id:"";if(h.info(this.name,`recv queue_edit event_id=${s} session_id=${t}`),!t||!s){this.aibotHandle.sendQueueEditResult({session_id:t,event_id:s,ok:!1,error:"bad_request"});return}const o=typeof i.content=="string"?i.content:"",a=this.pool.editQueuedEvent(t,s,o),l=a==="ok";this.aibotHandle.sendQueueEditResult({session_id:t,event_id:s,ok:l,...l?{}:{error:a}}),l&&this.pushQueueSnapshotForSession(t)}),typeof this.aibotHandle.onQueueSnapshotQuery=="function"&&this.aibotHandle.onQueueSnapshotQuery(i=>{this.replyQueueSnapshotForSession(i.session_id)}),h.info(this.name,"Connected to aibot"),this.activeEventStore){const i=await this.activeEventStore.drain();if(i.length>0){h.warn(this.name,`Recovering ${i.length} stale event(s) from previous run`);for(const t of i)h.info(this.name,`Failing stale event on startup: ${t}`),this.aibotHandle.sendEventResult({event_id:t,status:"failed",msg:"process restarted, event lost",updated_at:Date.now()})}}this.pushQueueSnapshots(),this.relayStateSyncOnConnect(),this.aibotHandle.onReconnected(()=>{if(this.stopped)return;this.pushQueueSnapshots();const i=this.aibotHandle.authAck;this.applyAgentProfile(i?.agent_name,i?.introduction,{source:"reconnect",respawnOnChange:!0},i?.system_prompt),this.forceRefreshSkills(void 0,{force:!0}),this.skillSyncHandler?.(),this.relayStateSyncOnConnect()}),this.aibotHandle.onStreamRejected((i,t)=>{this.sendCtrl.markEventRejected(i)})}applyAgentProfile(e,n,r,i){const t=String(e??"").trim(),s=String(n??"").trim(),o=i===void 0?this.agentSystemPrompt:String(i),a=t!==this.agentProfile.agentName||s!==this.agentProfile.introduction||o!==this.agentSystemPrompt;this.agentProfile={agentName:t,introduction:s},this.agentSystemPrompt=o,t||s?h.info(this.name,`agent profile (${r.source}): GOT name="${t}" intro_len=${s.length} system_prompt_len=${o.length} changed=${a}`):h.warn(this.name,`agent profile (${r.source}): EMPTY \u2014 \u670D\u52A1\u7AEF\u672A\u4E0B\u53D1 agent_name/introduction\uFF08auth_ack \u5B57\u6BB5\u7F3A\u5931\u6216\u503C\u4E3A\u7A7A\uFF09`),a&&r.respawnOnChange&&this.applyProfileChangeToAdapters("agent_profile_changed")}applyProfileChangeToAdapters(e){if(!this.pool)return;const n=this.pool.getAllSlots();let r=0;for(const o of n)if(o.adapter.onAgentProfileChanged)try{o.adapter.onAgentProfileChanged(),r++}catch(a){h.warn(this.name,`onAgentProfileChanged failed for session=${o.sessionId}: ${a}`)}const i=n.filter(o=>o.adapter instanceof M),t=i.filter(o=>{if(o.state!=="ready")return!1;const a=o.adapter.getStatus();return!a.busy&&!a.backgroundBusy}),s=i.length-t.length;h.info(this.name,`${e}: notified ${r} adapter(s) via hook; respawning ${t.length} idle Claude slot(s), skipping ${s} busy`);for(const o of t)this.pool.removeSlot(o.sessionId).catch(a=>{h.warn(this.name,`removeSlot failed during ${e}: ${a}`)})}pushQueueSnapshots(){if(!(!this.config.eventQueue||!this.pool))for(const e of this.pool.getAllSlots())this.pushQueueSnapshotForSession(e.sessionId)}buildQueueSnapshotPayload(e){const n=this.pool?.getQueueSnapshot(e)??null,r=n?[...n.running]:[],i=n?n.running_items.map(s=>({event_id:s.event_id,...s.content_preview?{content_preview:s.content_preview}:{},...s.title?{title:s.title}:{},...s.summary?{summary:s.summary}:{},actions:[{type:"stop"}]})):[],t=n?n.queued.map(s=>({event_id:s.event_id,position:s.position,...s.content_preview?{content_preview:s.content_preview}:{},...typeof s.content=="string"?{content:s.content}:{},...s.title?{title:s.title}:{},...s.summary?{summary:s.summary}:{},held:s.held===!0,held_reason:s.held_reason??"",actions:[{type:"cancel"}]})):[];if(r.length===0&&this.selfDrivenSessions.has(e)&&this.pool?.getSlot(e)){const s=`selfdrive_${e}`,o=this.selfDrivenLabels.get(e)??"Background task in progress";r.push(s),i.push({event_id:s,content_preview:o,title:o,summary:o,actions:[]})}return{session_id:e,running:r,running_items:i,queued:t}}pushQueueSnapshotForSession(e){if(!this.config.eventQueue||!this.pool)return;const n=this.buildQueueSnapshotPayload(e);h.info(this.name,`[queue-debug] push snapshot session=${e} running=${n.running.length} queued=${n.queued.length} running_ids=[${n.running.join(",")}]`),this.aibotHandle.sendQueueSnapshot(n)}replyQueueSnapshotForSession(e){!this.config.eventQueue||!this.pool||this.aibotHandle.sendQueueSnapshot(this.buildQueueSnapshotPayload(e))}async platformInvoke(e,n,r){return e==="file_link"?Jn(n):e==="file_upload"?this.uploadFileAndSendMedia(n):e==="toolbar_set"?this.setCustomToolbar(n):this.aibotHandle.agentInvoke(e,n,r)}async setCustomToolbar(e){const n=String(this.config.agent.clientType??this.config.aibot.clientType??"").trim().toLowerCase();if(n!=="acp")throw new Error(`grix_toolbar_set is only supported for client_type "acp" (this agent is "${n||"unknown"}")`);const r=String(e.session_id??"").trim();if(!r)throw new Error("grix_toolbar_set requires a session_id");const i=wt(e.items);return this.customToolbars.set(r,i),this.aibotHandle.sendUpdateBindingCard({session_id:r,metadata_only:!0,meta:{custom_toolbar:i}}),h.info(this.name,`[toolbar] custom toolbar published session=${r} items=${i.length}`),{ok:!0,items:i.length}}invokeDshEventTool(e,n){const r=V(this.aibotHandle,e,n),i=r.content[0]?.text??"";if(r.isError)throw new Error(i||`grix event tool "${e}" failed`);try{return JSON.parse(i)}catch{return i}}async uploadFileAndSendMedia(e){const n=String(e.file_path??"").trim(),r=String(e.session_id??"").trim(),i=String(e.caption??"").trim(),t=String(e.reply_to_message_id??"").trim();if(!n)throw new Error("file_path is required");if(!r)throw new Error("session_id is required");const s=await Yn({wsURL:this.config.aibot.url,apiKey:this.config.aibot.apiKey,sessionID:r,filePath:n}),o=await this.aibotHandle.sendMedia({session_id:r,msg_type:2,content:i||`[${s.attachment_type}]`,client_msg_id:`file_upload_${k()}`,...t?{quoted_message_id:t}:{},extra:s.extra});if(o.cmd!=="send_ack"){const l=o.payload??{},d=String(l.msg??o.cmd);throw new Error(`media message send failed: ${d}`)}const a=o.payload??{};return{ok:!0,file_name:s.file_name,attachment_type:s.attachment_type,access_url:s.access_url,message_id:a.msg_id!=null?String(a.msg_id):null}}sendReplyByRuntimeConfig(e,n,r,i,t){const s=this.indexEventSession(e,n)??n;this.auditController.captureReply(e,r),this.sendCtrl.sendReply(e,s,r,i,t),r&&this.conversationLog?.logOutbound?.(s,e,"reply",r)}stampCodexEventQuote(e){if(e.quoted_message_id!=null){if(e.quoted_message_id)return e;const{quoted_message_id:s,...o}=e;return o}const n=e;if(n.codex_method!=="item/agentMessage/delta")return e;const i=n.codex_payload?.params?.phase;if(typeof i=="string"&&i.trim()&&i.trim().toLowerCase()!=="final_answer")return e;const t=this.sendCtrl.getDefaultQuotedMessageId(e.event_id);return t?{...e,quoted_message_id:t}:e}captureCodexAuditOutput(e){if(e.codex_method!=="item/agentMessage/delta")return;const n=e.codex_payload?.params,r=typeof n?.phase=="string"?n.phase.trim().toLowerCase():"";if(r&&r!=="final_answer")return;const i=n?.delta;typeof i!="string"||!i||this.auditController.captureUnsequencedStreamChunk(e.event_id,i)}discardEventTrackingState(e){this.inflightEvents.delete(e),this.restartCount.delete(e),this.eventSessionIndex.delete(e),this.pendingStartedEventIds.delete(e),this.sendCtrl.discardEventState(e)}reliableFinalWiring(e,n){return async(r,i,t)=>{try{await this.sendCtrl.sendFinalStreamChunkReliable(r,i,t,n)}catch(s){throw h.error("bridge",`[${e}] sendFinalStreamChunkReliable ACK failed event=${r}: ${s}`),s}h.info("bridge",`[${e}] sendFinalStreamChunkReliable done event=${r}`)}}sendStreamChunkByRuntimeConfig(e,n,r,i,t,s,o){const a=this.indexEventSession(e,n)??n;this.auditController.captureStreamChunk(e,i,r),this.sendCtrl.sendStreamChunk(e,a,r,i,t,s,o),(r||t)&&this.conversationLog?.logOutbound?.(a,e,t?"stream_chunk_finish":"stream_chunk",r)}surfacedRunErrorTexts=new Map;markRunErrorSurfaced(e,n){const r=n.trim();if(!r)return;const i=this.surfacedRunErrorTexts.get(e);i?i.add(r):this.surfacedRunErrorTexts.set(e,new Set([r]))}sendRunErrorAsChunk(e,n,r,i=1,t){this.surfacedRunErrorTexts.get(e)?.has(r.trim())||(this.markRunErrorSurfaced(e,r),this.sendStreamChunkByRuntimeConfig(e,n,`
|
|
2
2
|
|
|
3
|
-
Error: ${r}`,i,!1,t))}sendEventResultWithCleanup(e,n,r,i,t=!1){const s=this.eventSessionIndex.get(e),o=r?.trim()??"";t&&this.markRunErrorSurfaced(e,o),n==="failed"&&s&&o&&this.sendRunErrorAsChunk(e,s,o);const a=n==="failed"&&o!==""&&(this.surfacedRunErrorTexts.get(e)?.has(o)??!1);this.auditController.markResponded(e,n,r),this.sendCtrl.finalizeOpenStreams(e),this.sendCtrl.sendEventResult(e,n,r,i,a),s&&(this.pool.eventComplete(e,s)===!1&&h.error(this.name,`Event terminal result could not release queue slot event=${e} session=${s} status=${n}`),this.pushQueueSnapshotForSession(s),this.conversationLog?.logResult?.(s,e,n,r),this.eventSessionIndex.delete(e)),this.inflightEvents.delete(e),this.restartCount.delete(e),this.surfacedRunErrorTexts.delete(e),this.pendingStartedEventIds.delete(e),this.pendingEvents.remove(e).catch(l=>{h.warn(this.name,`Failed to remove terminal event from pending store event=${e}: ${l instanceof Error?l.message:String(l)}`)}),n==="responded"&&(this.config.adapterType??"acp")!=="agy"&&(this.cachedProviderQuotaSampledAtMs=null,this.refreshAndPushProviderQuota(!0).catch(()=>{}))}async handleSessionInternalError(e){const{eventId:n,sessionId:r,errorMsg:i}=e;if(this.stopped)return;const t=this.inflightEvents.get(n);if(!t){h.warn(this.name,`[recovery] no inflight event for internalError event=${n} session=${r}; surface failure directly`),this.sendRunErrorAsChunk(n,r,i),this.sendEventResultWithCleanup(n,"failed",i,"agent_stop_failure");return}const s=(this.restartCount.get(n)??0)+1;this.restartCount.set(n,s);const o=this.config.adapterType??"acp";if(s>y){h.error(this.name,`[recovery] adapter=${o} session=${r} event=${n} restart=${s}/${y} outcome=give-up err=${i}`);const c=`${o} agent kept failing after ${y} automatic restarts: ${i}`;this.sendRunErrorAsChunk(n,r,c),this.sendEventResultWithCleanup(n,"failed",c,"agent_stop_failure");return}h.info(this.name,`[recovery] adapter=${o} session=${r} event=${n} restart=${s}/${y} outcome=restarting err=${i}`);const a=this.pool.drainQueuedForSession(r);a.length>0&&h.info(this.name,`[recovery] session=${r} preserved ${a.length} queued sibling event(s) across restart`);try{await this.pool.removeSlot(r)}catch(c){h.warn(this.name,`[recovery] removeSlot failed session=${r}: ${c instanceof Error?c.message:String(c)}`)}if(this.stopped)return;const l=e.replayOriginalContent?t.content:this.resolveRecoveryPrompt(o,t),d={...t,content:l};try{await this.pool.deliverInboundEvent(d)}catch(c){h.error(this.name,`[recovery] redeliver failed event=${n} session=${r}: ${c instanceof Error?c.message:String(c)}`),this.sendEventResultWithCleanup(n,"failed",c instanceof Error?c.message:String(c));return}for(const c of a){if(this.stopped)break;try{await this.pool.deliverInboundEvent(c)}catch(u){h.error(this.name,`[recovery] sibling redeliver failed event=${c.event_id} session=${r}: ${u instanceof Error?u.message:String(u)}`),this.sendEventResultWithCleanup(c.event_id,"failed",u instanceof Error?u.message:String(u))}}}resolveRecoveryPrompt(e,n){return e==="acp"?"continue":n.content}sendThinkingByRuntimeConfig(e,n,r){this.sendCtrl.sendThinking(e,n,r)}bufferStreamChunk(e,n,r,i,t){this.auditController.captureUnsequencedStreamChunk(e,r),this.sendCtrl.bufferOnly(e,n,r,i,t)}flushBufferedStreamText(e){}resolveEventRuntimeConfig(e){return this.sendCtrl.resolveEventRuntimeConfig(e)}captureEventRuntimeConfig(e){this.sendCtrl.captureEventRuntimeConfig(e),this.indexEventSession(e.event_id,e.session_id),this.auditController.markRecording(e.event_id),e.event_id&&!this.inflightEvents.has(e.event_id)&&this.inflightEvents.set(e.event_id,e)}async replayPendingEventsOnStartup(){const e=await this.pendingEvents.loadForReplay();if(e.length===0)return;const n=new Set(e.map(i=>i.event.event_id).filter(Boolean)),r=[];h.warn(this.name,`Replaying ${e.length} pending event(s) from previous run`);for(const i of e){if(this.stopped)break;const t=i.event;this.pendingEvents.startReplay(i);try{if(i.kind==="deferred"){const s=this.bindingStore.get(i.sessionId);s?.cwd?(await this.prepareBoundDeferredReplay(i,s.cwd),await this.deliverPendingReplayEvent(t),this.pendingStartedEventIds.has(t.event_id)||r.push(i)):(this.restorePendingReplayAuditTurn(t),this.deferredMgr.defer(i.channel,i.sessionId,t),r.push(i))}else await this.deliverPendingReplayEvent(t),this.pendingStartedEventIds.has(t.event_id)||r.push(i)}catch(s){const o=s instanceof Error?s.message:String(s);h.error(this.name,`Pending event replay failed event=${t.event_id}: ${o}`),this.sendEventResultWithCleanup(t.event_id,"failed",o),this.pendingEvents.markCanceled(t.event_id),await this.pendingEvents.remove(t.event_id).catch(()=>{})}finally{this.pendingEvents.finishReplay(i),await this.pendingEvents.checkpointReplay(n,[...r,...this.pendingEvents.replaySnapshot()])}if(this.stopped)break}this.stopped||(this.pendingEvents.finishAllReplay(),await this.pendingEvents.checkpointReplay(n,r))}failEventIfLifecycleDraining(e,n="connector is draining for restart; control command was not executed"){return this.lifecycleBarrier.isClosed()?(this.aibotHandle.sendEventAck({event_id:e.event_id,session_id:e.session_id,received_at:Date.now()}),this.aibotHandle.sendEventResult({event_id:e.event_id,status:"failed",code:"connector_lifecycle_draining",msg:n,updated_at:Date.now()}),!0):!1}sendCanceledPendingEventResult(e,n){this.restorePendingReplayAuditTurn(e),this.captureEventRuntimeConfig(e),this.sendEventResultWithCleanup(e.event_id,"canceled",n),this.auditController.markAdapterClosed(e.event_id,{adapterNotStarted:!0})}async deliverPendingReplayEvent(e){this.restorePendingReplayAuditTurn(e),this.captureEventRuntimeConfig(e),await this.pool.deliverInboundEvent(e)}async prepareBoundDeferredReplay(e,n){this.sessionBindings.set(e.sessionId,n),e.channel==="acp"?await this.bindSessionForPool(e.sessionId,n):e.channel==="opencode"&&await this.syncOpenCodeBinding(e.sessionId,n)}restorePendingReplayAuditTurn(e){const n=e.audit;if(!n?.enabled||!n.auditId||!n.capture||!n.profile||!n.scope)return;const r=Ci({enabled:!0,scope:n.scope,profile:n.profile,capture:n.capture,...n.retentionDays===void 0?{}:{retentionDays:n.retentionDays}});if(!r.enabled)return;const i=Object.freeze({auditId:n.auditId,businessSessionId:e.session_id,provider:this.resolveAuditProvider(),options:r,createdAt:new Date().toISOString()}),t=this.auditController.startTurn({session:i,eventId:e.event_id,userInput:e.content??"",...e.msg_id===void 0?{}:{originMsgId:e.msg_id},...Number.isFinite(Number(e.created_at))&&Number(e.created_at)>0?{startedAt:new Date(Number(e.created_at)).toISOString()}:{},boundary:{adapterType:this.config.adapterType??"acp"}});t&&(e.audit={...n,auditId:t.auditId,turnId:t.turnId,profile:i.options.profile,capture:{...i.options.capture},rawProviderBody:i.options.capture.rawProviderBody})}indexEventSession(e,n){if(!e||!n)return;const r=this.eventSessionIndex.get(e);return r?(r!==n&&h.warn(this.name,`Ignoring event session mismatch event=${e} indexed=${r} supplied=${n}`),r):(this.eventSessionIndex.set(e,n),n)}shouldDropToolDisplayEvent(e){return this.sendCtrl.shouldDropToolDisplayEvent(e)}shouldDropThinkingDisplayEvent(e){return this.sendCtrl.shouldDropThinkingDisplayEvent(e)}shouldDropCodexDisplayEvent(e,n){return this.sendCtrl.shouldDropCodexDisplayEvent(e,n)}logCodexEventToConversation(e){if(!this.conversationLog||e.codex_method!=="item/agentMessage/delta")return;const r=e.codex_payload?.params?.delta;if(!r)return;const i=this.eventSessionIndex.get(e.event_id)??e.session_id;this.conversationLog.append(i,{ts:Date.now(),dir:"outbound",event_id:e.event_id,kind:"codex_delta",text_len:r.length,content:r})}isAcpRawTransportEnabled(){return(this.config.adapterOptions??{}).raw_transport===!0}shouldDropAcpRawDisplayEvent(e,n){return this.sendCtrl.shouldDropAcpRawDisplayEvent(e,n)}sendAcpRawEventEnvelope(e,n,r){this.shouldDropAcpRawDisplayEvent(e,r.type)||this.deliverRawEventEnvelope(e,n,r,"acp",this.buildAcpRawEventFallbackText(r))}buildAcpRawEventFallbackText(e){const n=String(e.type??"").trim();if(!n)return"[acp] event";switch(n){case"permission_request":return`Permission required: ${String(e.payload?.tool_title??e.payload?.tool_name??"permission request")}`;case"tool_use":return`[tool] ${String(e.payload?.tool_name??"tool")}`;case"tool_result":return"[tool result]";case"thinking":return"[thinking]";case"error":return`[error] ${String(e.payload?.message??"agent error")}`;case"result":return"[result]";default:return`[acp] ${n}`}}rawDetailSeq=0;deliverRawEventEnvelope(e,n,r,i,t){const s=li({envelope:r,fallbackText:t,channelKey:i,allocateRefId:()=>`${e}_rawd_${++this.rawDetailSeq}`}),o=()=>{this.aibotHandle.sendMsg({event_id:e,session_id:n,msg_type:1,content:s.fallbackText,extra:{channel_data:{[i]:{raw_event:s.envelope}},agent_api_origin:!0}})};if(!s.sharded){o();return}h.info("bridge",`${i} raw_event oversized, sharded delivery: event=${e} fields=${s.oversizedFields.map(a=>a.field).join(",")}`),(async()=>{for(const a of s.oversizedFields)await this.sendCtrl.deliverAuxiliaryLargeText(e,n,ci({envelopeType:r.type,field:a.field,fullText:a.fullText}),a.refClientMsgId);o()})().catch(a=>{h.warn("bridge",`${i} raw_event sharded delivery failed event=${e}: ${a}`)})}buildCursorRawEventFallbackText(e){const n=String(e?.type??"").trim(),r=e?.payload&&typeof e.payload=="object"?e.payload:{};switch(n){case"permission_request":return`Permission required: ${String(r.tool_title??r.tool_name??"permission request")}`;case"tool_use":case"tool_call":case"tool_execution_start":return`[tool] ${String(r.tool_name??r.toolName??"tool")}`;case"tool_result":case"tool_execution_end":case"tool_execution_update":return"[tool result]";case"error":return`[error] ${String(r.message??"agent error")}`;default:return n?`[cursor] ${n}`:"[cursor] event"}}sendToolExecutionCard(e,n,r,i){this.sendCtrl.sendToolExecutionCard(e,n,r,i)}sendGrixApprovalCard(e,n){this.aibotHandle.sendMsg({event_id:e.eventId,session_id:e.sessionId,client_msg_id:`perm_${k()}`,msg_type:1,content:e.toolTitle?`Permission required: ${e.toolTitle}`:"Permission request",extra:{channel_data:{execApproval:{approvalId:e.approvalId,approvalSlug:e.toolName},grix:{execApproval:{approval_command_id:e.approvalId,command:e.toolTitle||e.toolName,host:n}}},agent_api_origin:!0}})}sendGrixAgentQuestionCard(e,n,r){const i=r.questions.map(s=>s.header).join(", "),t=I(`[Agent Question] ${r.request_id}`,"agent_question",r);this.aibotHandle.sendText({event_id:e,session_id:n,content:t,msg_type:1,extra:{card_type:"agent_question",summary_text:i}})}async handleAgentQuestionReplyEvent(e){const n=_n(String(e.content??""));if(!n)return!1;this.aibotHandle.sendEventAck({event_id:e.event_id,session_id:e.session_id,received_at:Date.now()});const i=this.pool.getSlot(e.session_id)?.adapter,t=i instanceof S?"acp":i instanceof T?"opencode":this.config.adapterType??"unknown",s=i instanceof T?i.handleQuestionReplyEvent(n):i instanceof S?await i.handleQuestionReplyEvent(n):{delivered:!1,errorCode:"interaction_request_not_pending",errorMsg:"The question is no longer pending; the reply was not delivered."};return s.delivered?(h.info(this.name,`[${t}] question reply delivered event=${e.event_id} session=${e.session_id} request=${n.request_id}`),this.aibotHandle.sendEventResult({event_id:e.event_id,status:"responded",updated_at:Date.now()})):(h.warn(this.name,`[${t}] question reply rejected event=${e.event_id} session=${e.session_id} request=${n.request_id} code=${s.errorCode??"interaction_reply_failed"}`),this.aibotHandle.sendEventResult({event_id:e.event_id,status:"failed",code:s.errorCode??"interaction_reply_failed",msg:s.errorMsg??"The question reply was not delivered.",updated_at:Date.now()})),!0}async handleExecApprovalResolutionEvent(e){const n=vn(String(e.content??""));if(!n)return!1;this.aibotHandle.sendEventAck({event_id:e.event_id,session_id:e.session_id,received_at:Date.now()});const i=this.pool.getSlot(e.session_id)?.adapter,t=n.params,s=String(t.tool_call_id??t.approval_command_id??t.approval_id??t.exec_context_id??""),o=i?.handleExecApprovalEvent?await i.handleExecApprovalEvent({...t,event_id:e.event_id,session_id:e.session_id}):{delivered:!1,errorCode:"approval_not_supported",errorMsg:"The current adapter does not support exec approval resolution events."};return o.delivered?(h.info(this.name,`[${this.config.adapterType??"unknown"}] exec approval resolution delivered event=${e.event_id} session=${e.session_id} approval=${s||"-"}`),this.aibotHandle.sendEventResult({event_id:e.event_id,status:"responded",updated_at:Date.now()})):(h.warn(this.name,`[${this.config.adapterType??"unknown"}] exec approval resolution rejected event=${e.event_id} session=${e.session_id} approval=${s||"-"} code=${o.errorCode}`),this.aibotHandle.sendEventResult({event_id:e.event_id,status:"failed",code:o.errorCode,msg:o.errorMsg,updated_at:Date.now()})),!0}async handleAibotEvent(e){if(this.relayEnvStale&&!this.hasPendingWork()&&await this.recycleAdaptersForRelayChange(),this.stopped){this.aibotHandle.sendEventAck({event_id:e.event_id,session_id:e.session_id,received_at:Date.now()}),this.aibotHandle.sendEventResult({event_id:e.event_id,status:"failed",msg:"agent shutting down",updated_at:Date.now()});return}this.logInboundConversation(e);const n=this.config.adapterType??"acp",r=fn(e);let i;if(r&&(i=this.lifecycleBarrier.tryEnter(`session-control:${r.verb}`)??void 0,!i)){this.failEventIfLifecycleDraining(e);return}try{if(await this.handleCliInstallQuestionReply(e)||(n==="opencode"||n==="acp")&&await this.handleAgentQuestionReplyEvent(e)||await this.handleExecApprovalResolutionEvent(e))return;const t=ii(e.extra);if(t.error){this.aibotHandle.sendEventAck({event_id:e.event_id,session_id:e.session_id,received_at:Date.now()}),this.aibotHandle.sendEventResult({event_id:e.event_id,status:"failed",code:"connector_config_invalid",msg:t.error,updated_at:Date.now()});return}const s=t.patch,o=B(e.extra);if(Sn(this,e,n,o))return;if(r){await bn(this,r,e,n,o);return}if(e.mirror_mode==="record_only"){this.aibotHandle.sendEventAck({event_id:e.event_id,session_id:e.session_id,received_at:Date.now()}),this.aibotHandle.sendEventResult({event_id:e.event_id,status:"responded",updated_at:Date.now()});return}if(this.isStaleEvent(e)){this.aibotHandle.sendEventAck({event_id:e.event_id,session_id:e.session_id,received_at:Date.now()}),this.aibotHandle.sendEventResult({event_id:e.event_id,status:"failed",code:"event_stale",msg:"event is stale and will not be processed",updated_at:Date.now()});return}let a;try{a=this.auditController.resolveSession({sessionId:e.session_id,provider:this.resolveAuditProvider(),extra:e.extra,eventId:e.event_id}).session}catch(c){this.sendAuditConfigurationError(e,c);return}if(await Cn(this,e,n,Li.has(n),s,a))return;if((this.config.adapterType??"acp")==="acp"){const u=String(e.content??"").trim().match(/^\/(\S+)\s*(.*)/);if(u){const[,g,p]=u,A=this.pool.getSlot(e.session_id)?.adapter;if(A?.execCommand&&(A.getSupportedCommands?.()??[]).some(m=>m.name===g||m.name===`/${g}`)){this.aibotHandle.sendEventAck({event_id:e.event_id,session_id:e.session_id,received_at:Date.now()});try{const m=await A.execCommand(g,p.trim(),e.session_id);m.status==="options"&&m.data&&this.handleExecCommandOptions(e.session_id,g,m.data),this.aibotHandle.sendEventResult({event_id:e.event_id,status:m.status==="failed"?"failed":"responded",msg:m.message,updated_at:Date.now()})}catch(m){this.aibotHandle.sendEventResult({event_id:e.event_id,status:"failed",msg:m instanceof Error?m.message:String(m),updated_at:Date.now()})}return}}}if(n==="codex"&&D(a?.options)){const c=this.pool.getSlot(e.session_id);if(c?.adapter instanceof M&&!c.adapter.hasRawApiCaptureRelay()){const u=c.eventQueue.snapshot(e.session_id);u.running.length===0&&u.queued.length===0?(h.info(this.name,`[audit-raw-capture] recreating idle Codex adapter before event=${e.event_id} session=${e.session_id}`),await this.pool.removeSlot(e.session_id)):h.warn(this.name,`[audit-raw-capture] Codex adapter lacks relay but is not idle event=${e.event_id} session=${e.session_id} running=${u.running.length} queued=${u.queued.length}`)}}const d=this.prepareAuditedInboundEvent(e,s,a);d.attachments_json=await Yn(d.attachments_json,{extraAllowedHosts:zn(this.aibotConfig.url),logTag:this.name});try{const c=await this.pendingEvents.append({kind:"queued",event:d});if(this.pendingEvents.isCanceled(e.event_id)){await this.pendingEvents.remove(e.event_id),this.aibotHandle.sendEventAck({event_id:e.event_id,session_id:e.session_id,received_at:Date.now()}),this.sendCanceledPendingEventResult(d,"canceled");return}if(this.lifecycleBarrier.isClosed()){if(!c)throw new Error("pending event store unavailable during lifecycle drain");this.aibotHandle.sendEventAck({event_id:e.event_id,session_id:e.session_id,received_at:Date.now()}),h.info(this.name,`Persisted inbound event during lifecycle drain: ${e.event_id}`);return}this.captureEventRuntimeConfig(d),await this.pool.deliverInboundEvent(d)}catch(c){await this.pendingEvents.remove(e.event_id).catch(u=>{h.warn(this.name,`Failed to remove undelivered pending event=${e.event_id}: ${u instanceof Error?u.message:String(u)}`)}),this.failUndeliveredInboundEvent(e,c)}}finally{i?.()}}handleStaleCwdError(e,n){if(!/CWD must be|Bound directory does not exist|Bound path is not a directory/i.test(n)||!e.session_id)return!1;this.bindingStore.delete(e.session_id),this.sessionBindings.delete(e.session_id),this.sessionProviderHints.delete(e.session_id),this.sessionProviderQuotas.delete(e.session_id),this.sessionProviderMeta.delete(e.session_id);const i=this.pool.getSlot(e.session_id);i?.adapter instanceof S&&i.adapter.getSessionBindings().delete(e.session_id);const t=this.config.adapterType??"acp",s=this.resolveBindingChannelKey(t);return this.aibotHandle.sendMsg({event_id:e.event_id,session_id:e.session_id,msg_type:1,content:n,extra:{channel_data:{[s]:{sessionBinding:{status:"missing",reason:"binding_stale",error_code:$.invalidCwd}}}},quoted_message_id:e.msg_id}),!0}failUndeliveredInboundEvent(e,n){const r=n instanceof Error?n.message:String(n);h.warn(this.name,`Inbound event undelivered event=${e.event_id} session=${e.session_id}: ${r}`),this.aibotHandle.sendEventAck({event_id:e.event_id,session_id:e.session_id,received_at:Date.now()}),this.auditController.closeWithoutAdapter(e.event_id,"failed",r,{deliveryFailed:!0}),this.discardEventTrackingState(e.event_id),!this.handleStaleCwdError(e,r)&&this.aibotHandle.sendEventResult({event_id:e.event_id,status:"failed",msg:r,updated_at:Date.now()})}handleCodexSessionControlOpen(e,n){return ot(this,e,n)}handleSessionControlForPool(e,n){return rt(this,e,n)}handleSessionControlLocalActionForPool(e){return at(this,e)}handleCodexSessionControlLocalActionOpen(e){return dt(this,e)}handleCursorSessionControlLocalActionOpen(e){return lt(this,e)}handlePiSessionControlOpen(e,n){return ct(this,e,n)}handlePiSessionControlRestart(e){return ht(this,e)}handlePiSessionControlRestartLocalAction(e){return ut(this,e)}syncOpenCodeBinding(e,n){return pt(this,e,n)}isWorkspaceFreeClient(){return gt(this)}ensureDefaultBindingForWorkspaceFreeClient(e,n){return ft(this,e,n)}bindSessionForPool(e,n){return mt(this,e,n)}deferredCallbacks(){return vt(this)}handleOpenHumanSessionControlOpen(e,n){return _t(this,e,n)}handleCodeWhaleSessionControlOpen(e,n){return St(this,e,n)}handleCodeWhaleSessionControlLocalActionOpen(e){return Ct(this,e)}handleDeepSeekSessionControlLocalActionOpen(e){return bt(this,e)}normalizeClaudeModeId(e){return It(this,e)}handleExecCommandOptions(e,n,r){Ot(this,e,n,r)}resolveSessionModelId(e){return Bt(this,e)}resolveSessionModeId(e){return Ft(this,e)}resolveCursorSessionModeId(e){return Ut(this,e)}resolveClaudeSessionEffort(e){return qt(this,e)}resolveClaudeSessionModeId(e){return Nt(this,e)}currentClaudeModeId(e){return Wt(this,e)}buildCursorToolbarMeta(e){return Gt(this,e)}buildAgyToolbarMeta(e,n){return jt(this,e,n)}buildAgyQuotaMeta(e){return Kt(this,e)}sendAgyBindingCard(e,n,r){return zt(this,e,n,r)}refreshAndPushAgyQuota(e,n=!1){return Jt(this,e,n)}handleAgySetModel(e,n){return Yt(this,e,n)}buildClaudeToolbarMeta(e){return Vt(this,e)}providerQuotaToCodexRateLimits(e){return ai(e,this.cachedProviderQuotaSampledAtMs??Date.now())}providerQuotaToRateLimits(e){return ri(e,this.cachedProviderQuotaSampledAtMs??Date.now())}async resolveCwdForBinding(e){return Un(e)}failSessionOpen(e,n){return On(this,e,n)}getClaudeWorkerStatus(e){return Bn(this,e)}refreshClaudeWorkerStatusCard(e,n){return Fn(this,e,n)}async ensureSlotStarted(e,n=6e4){return In(this,e,n)}maybeOfferCliInstall(e){Me(this,e)}handleCliInstallQuestionReply(e){return He(this,e)}handleCliInstallInteractionReply(e){return $e(this,e)}runConfirmedCliInstall(e,n){return De(this,e,n)}handleSkillDeleteLocalAction(e){return wt(this,e)}handleSkillUploadLocalAction(e){return yt(this,e)}handleSkillEnableLocalAction(e){return Rt(this,e)}handleSkillRefreshLocalAction(e){kt(this,e)}handleSkillDisableLocalAction(e){return Tt(this,e)}computeSkillReport(e){return Pt(this,e)}reportSessionSkills(e){xt(this,e)}skillsSyncGroupKey(){return Lt(this)}forceRefreshSkills(e,n){return Mt(this,e,n)}adoptSkillsWireHashFromDisk(){Ht(this)}buildLibrarySkillsReport(e){return $t(this,e)}skillLookupEnv(){return Dt(this)}resolveOrphanTitle(e){return Hn(this,e)}resolveAgentSessionId(e){return Mn(this,e)}providerKeyForAdapter(){return Ln(this)}setResolvedAgentSessionId(e,n){$n(this,e,n)}normalizePathForCompare(e){return xn(e)}ensureImportedAgentSession(e,n){Tn(this,e,n)}buildOpenedBindingResult(e,n,r="ready"){return kn(this,e,n,r)}buildDshOpenedToolbarMeta(e){return Dn(this,e)}dshCatalogDataRoot(){return Qn(this)}hasDiskScanner(){return Pn(this)}unbindSession(e){return Ze(this,e)}handleUnbindTextCommand(e){return et(this,e)}handleUnbindLocalAction(e){return tt(this,e)}handleListSessionsTextCommand(e){return nt(this,e)}handleListSessionsLocalAction(e){return it(this,e)}handleSyncHistoryLocalAction(e){return st(this,e)}handleSessionControlCommand(e,n){return xe(this,e,n)}handleSessionControlLocalAction(e){return Le(this,e)}handleEventCancel(e){return Qe(this,e)}waitForEventDone(e,n,r){return Ie(this,e,n,r)}handleAibotStop(e){Oe(this,e)}killAndResumeStopSlot(e,n){return Be(this,e,n)}handleAibotRevoke(e){return Fe(this,e)}handleConfigureGatewayProvider(e){return Ue(this,e)}getAuditLocalActionHandler(){return qe(this)}handleAuditLocalAction(e){return Ne(this,e)}handleConnectorRollback(e){return We(this,e)}getRelayStateSyncer(){return Ge(this)}relayStateSyncOnConnect(){je(this)}reportRelayStateLocalChange(){Ke(this)}handleApplyRelayState(e){return ze(this,e)}fetchRelayCredential(e){return Je(this,e)}handleConnectorAdminLocalAction(e){return Xe(this,e)}isSharedInstance(){return Ye(this)}async handleAibotLocalAction(e){if(this.stopped){this.aibotHandle.sendLocalActionResult({action_id:e.action_id,status:"failed",error_code:"connector_lifecycle_draining",error_msg:"connector is shutting down; local action was not executed"});return}const n=e.action_type??"",r=String((e.params??{}).session_id??""),i=String((e.params??{}).verb??"").trim().toLowerCase();h.debug(this.name,`local_action received action_type=${n} verb=${i||"-"} action_id=${e.action_id} session_id=${r}`);let t;if(n===f.sessionControl&&(t=this.lifecycleBarrier.tryEnter(`local-action:${i||n}`)??void 0,!t)){this.aibotHandle.sendLocalActionResult({action_id:e.action_id,status:"failed",error_code:"connector_lifecycle_draining",error_msg:"connector is draining for restart; session control was not executed"});return}try{if(n===f.interactionReply&&await this.handleCliInstallInteractionReply(e))return;if(J(n)){await this.handleAuditLocalAction(e);return}const s=(this.config.adapterType??"acp")==="claude";if(n===f.sessionControl&&i===E.exec&&await this.handleSessionControlLocalAction(e))return;if(n===f.sessionControl&&i===E.listSessions){await this.handleListSessionsLocalAction(e);return}if(n===f.sessionControl&&i===E.syncHistory){await this.handleSyncHistoryLocalAction(e);return}if(n===f.sessionControl&&i===E.unbind){await this.handleUnbindLocalAction(e);return}if(n==="skill_upload"){await this.handleSkillUploadLocalAction(e);return}if(n==="skill_delete"){await this.handleSkillDeleteLocalAction(e);return}if(n==="skill_enable"){await this.handleSkillEnableLocalAction(e);return}if(n==="skill_disable"){await this.handleSkillDisableLocalAction(e);return}if(n==="skill_refresh"){this.handleSkillRefreshLocalAction(e);return}const o=(this.config.adapterType??"acp")==="opencode";if((s&&(n===f.interactionReply||n==="exec_approve"||n==="exec_reject")||o&&n===f.interactionReply)&&(await this.pool.deliverLocalAction(e)).handled||s&&await this.handleSessionControlLocalAction(e))return;if(n===f.sessionControl){await An(this,e,r);return}if(n==="file_list"){await wn(this,e,r);return}if(n==="create_folder"){await En(this,e,r);return}if(n===f.setModel&&(this.config.adapterType??"acp")==="agy"){await this.handleAgySetModel(e,r);return}if(n===f.getSessionUsage){if((this.config.adapterType??"acp")==="deepseek-harness"&&(await this.pool.deliverLocalAction(e,{autoCreateSlot:!!r&&!!this.bindingStore.get(r)?.cwd})).handled)return;await this.handleGetSessionUsage(e,r);return}if(n===f.getRateLimits){if((this.config.adapterType??"acp")==="deepseek-harness"&&(await this.pool.deliverLocalAction(e,{autoCreateSlot:!!r&&!!this.bindingStore.get(r)?.cwd})).handled)return;await this.handleGetRateLimits(e,r);return}const a=(this.config.adapterType??"acp")==="acp",l=(this.config.adapterType??"acp")==="cursor";if((s||a||l)&&n===f.threadCompact){await this.handleThreadCompact(e,r);return}if(n==="connector_rollback"){await this.handleConnectorRollback(e);return}if(n==="connector_upgrade_push"){this.aibotHandle.sendLocalActionResult({action_id:e.action_id,status:"ok",result:{accepted:!0}}),this.upgradeTrigger?.();return}if(n===f.getAgentGlobalConfig){const p=this.globalConfigStore?.get(this.name);this.aibotHandle.sendLocalActionResult({action_id:e.action_id,status:"ok",result:{agentName:this.name,...p?{config:p}:{config:null}}});return}if(n===Ve){await this.handleConnectorAdminLocalAction(e);return}if(n==="configure_gateway_provider"){await this.handleConfigureGatewayProvider(e);return}if(n==="apply_relay_state"){await this.handleApplyRelayState(e);return}const d=this.config.adapterType??"acp",c=(d==="codex"||d==="cursor"||d==="pi"||d==="openhuman"||d==="opencode"||d==="deepseek-harness"||d==="acp")&&!!r&&!!this.bindingStore.get(r)?.cwd,u=await this.pool.deliverLocalAction(e,{autoCreateSlot:c});if(u.handled){Rn(this,e,r,d,u);return}if((d==="codex"||d==="cursor"||d==="pi"||d==="openhuman"||d==="opencode"||d==="deepseek-harness")&&r&&!this.bindingStore.get(r)?.cwd){this.aibotHandle.sendLocalActionResult({action_id:e.action_id,status:"failed",error_code:$.bindingMissing,error_msg:"Session binding missing. Open a workspace first."});return}if(d==="acp"&&(n==="set_mode"||n==="set_model")){await yn(this,e,r,n);return}const g=!!r&&!!this.pool.getSlot(r);this.aibotHandle.sendLocalActionResult({action_id:e.action_id,status:"failed",error_code:"unsupported_local_action",error_msg:g?`Action type "${n}" is not supported by the current agent process.`:`No active agent process for this session. The reply to action "${n}" could not be delivered \u2014 please resend it as a new message.`})}finally{t?.()}}handleGetSessionUsage(e,n){return At(this,e,n)}handleThreadCompact(e,n){return Et(this,e,n)}handleGetRateLimits(e,n){return cn(this,e,n)}resolveRateLimitWakeSessionId(e,n){return hn(this,e,n)}wakeRateLimitSlot(e,n){return un(this,e,n)}sessionControlCtx(e){const n=this.pool.getSlot(e),r=n?.adapter instanceof S?n.adapter:null,i=(this.config.adapterType??"acp")==="acp",t={bindingStore:this.bindingStore,acpAdapter:r,globalConfigStore:this.globalConfigStore,agentName:this.name,log:h};return{getCwd:()=>this.bindingStore.get(e)?.cwd??this.config.agent.cwd??process.cwd(),getSessionBindings:()=>{if(r)return r.getSessionBindings();const s=this.sessionBindings;if(e&&!s.has(e)){const o=this.bindingStore.get(e);o?.cwd&&s.set(e,o.cwd)}return s},getStatus:()=>this.getStatus(),isAcpAlive:!!r?.isAlive(),getAcpSessionOptions:()=>r?.acpSessionOptions??null,setMode:s=>r?r.setMode(s):Promise.resolve(!1),setModel:s=>r?r.setModel(s):Promise.resolve(!1),acpSetMode:i?(s,o)=>Nn(t,s,o):void 0,acpSetModel:i?(s,o)=>qn(t,s,o):void 0,getPendingApproval:s=>{const o=r?.pendingApprovalEntries.get(s);return o?{requestId:o}:void 0},deletePendingApproval:s=>r?.pendingApprovalEntries.delete(s)??!1,respondPermission:(s,o)=>(r&&r.respondToPermission(s,o),Promise.resolve()),onSessionBound:(s,o)=>{this.bindingStore.set(s,o)},onSessionUnbound:s=>{this.unbindSession(s).catch(o=>{h.warn(this.name,`session unbind cleanup failed: ${o instanceof Error?o.message:String(o)}`)})},cancelActiveRun:()=>(this.config.adapterType??"acp")==="agy"&&n?.adapter instanceof H?(n.adapter.cancelCurrentRun(),Promise.resolve()):n?.adapter?.cancel("")??Promise.resolve(),onModeSet:s=>{Q(this,this.config.adapterType??"acp",e,"mode",s)},onModelSet:s=>{Q(this,this.config.adapterType??"acp",e,"model",s),this.refreshQuotaAfterModelSwitch(e,s)}}}sessionControlSenders(e){return{sendEventAck:(n,r)=>this.aibotHandle.sendEventAck({event_id:n,session_id:r,received_at:Date.now()}),sendEventResult:(n,r,i)=>this.aibotHandle.sendEventResult({event_id:n,status:r,...i?.msg?{msg:i.msg}:{},...i?.code?{code:i.code}:{},updated_at:Date.now()}),sendLocalActionResult:(n,r,i,t,s)=>this.aibotHandle.sendLocalActionResult({action_id:n,status:r,...i?{result:i}:{},...t?{error_code:t}:{},...s?{error_msg:s}:{}},e)}}resolveBindingChannelKey(e){switch(e){case"claude":return"grix-claude";case"codex":return"codex";case"cursor":return"cursor";case"pi":return"pi";case"openhuman":return"openhuman";case"codewhale":return"codewhale";case"opencode":return"opencode";case"agy":return"acp";case"deepseek-harness":return"deepseek";case"acp":return this.config.aibot.clientType==="qwen"?"qwen":"acp";default:return e}}finalizeThinking(e,n){this.sendCtrl.finalizeThinking(e,n)}logInboundConversation(e){const n=String(e.session_id??"").trim();n&&this.conversationLog?.logInbound(n,{event_id:e.event_id,msg_id:e.msg_id,sender_id:e.sender_id,msg_type:e.msg_type,content:e.content??""})}resolveAuditProvider(){const e=this.config.adapterType??"acp";return e==="claude"||e==="codex"||e==="cursor"||e==="opencode"||e==="pi"||e==="codewhale"||e==="deepseek-harness"||e==="agy"?e:"acp"}sendAuditConfigurationError(e,n){const r=n instanceof Error?n.message:String(n),i=(()=>{const a=B(e.extra);return a.options?.enabled===!0&&a.options.scope==="turn"})(),t=n instanceof Si||n instanceof _i,s=n instanceof Ai&&i,o=s?"audit_config_invalid":t?n.code:"audit_config_conflict";if(this.aibotHandle.sendEventAck({event_id:e.event_id,session_id:e.session_id,received_at:Date.now()}),this.aibotHandle.sendEventResult({event_id:e.event_id,status:"failed",code:o,msg:r,updated_at:Date.now()}),t||s)try{this.aibotHandle.sendAuditState(O({state:"failed",eventId:e.event_id,sessionId:e.session_id,...e.msg_id===void 0?{}:{msgId:e.msg_id},errorCode:o,errorMessage:r},Date.now()))}catch{}}markAuditAdapterClosed(e,n){const i=this.pool.getSlot(n)?.adapter.takeAuditBoundary?.(e);this.auditController.markAdapterClosed(e,i)}prepareAuditedInboundEvent(e,n,r){const i=this.buildInboundEvent(e,n),t=this.bindingStore.get(e.session_id),s=t?this.resolveAgentSessionId(t):void 0,o=Number(e.created_at),a=Number.isFinite(o)&&o>0?new Date(o).toISOString():void 0,l=this.auditController.startTurn({session:r,eventId:e.event_id,userInput:e.content??"",...e.msg_id===void 0?{}:{originMsgId:e.msg_id},...a===void 0?{}:{startedAt:a},boundary:{adapterType:this.config.adapterType??"acp",...s?{providerSessionId:s}:{}}});return l&&(i.audit={enabled:!0,auditId:l.auditId,turnId:l.turnId,...r?{scope:r.options.scope,profile:r.options.profile,...r.options.retentionDays===void 0?{}:{retentionDays:r.options.retentionDays},capture:{...r.options.capture}}:{},rawProviderBody:r?.options.capture.rawProviderBody===!0}),i}buildInboundEvent(e,n){const r=ni(this.sendCtrl.getGlobalRuntimeConfig(),n),i=bi(e.extra);return{event_id:e.event_id,session_id:e.session_id,thread_id:e.thread_id,sender_id:e.sender_id,msg_id:e.msg_id,msg_type:e.msg_type,content:e.content??"",quoted_message_id:e.quoted_message_id,context_messages_json:this.buildContextMessagesJson(e.context_messages),extra_json:i===void 0?void 0:JSON.stringify(i),attachments_json:Jn(e.attachments),connector_runtime_config:{response_delivery:r.responseDelivery,tool_events:r.toolEvents,thinking_events:r.thinkingEvents},session_type:e.session_type,created_at:e.created_at}}buildContextMessagesJson(e){if(!e)return;const n=e.filter(r=>!mn(String(r?.content??"")));if(n.length!==0)return JSON.stringify(n)}isStaleEvent(e){const n=Number(e.created_at);return!Number.isFinite(n)||n<=0?!1:Date.now()-n>yi}setUpgradeTrigger(e){this.upgradeTrigger=e}setDaemonShutdownRequester(e){this.daemonShutdownRequester=e}setLifecycleBusyChecker(e){this.lifecycleBusyChecker=e}setLifecycleAdmissionCloser(e){this.lifecycleAdmissionCloser=e}setLifecycleAdmissionRestorer(e){this.lifecycleAdmissionRestorer=e}closeLifecycleAdmission(){this.lifecycleBarrier.setAutoOpenHandler(e=>{h.warn(this.name,`Lifecycle admission auto-reopened after ${Math.round(e/1e3)}s: a restart was expected but never happened. Admission is open again and events flow; the pending restart or upgrade did not complete.`)}),this.lifecycleBarrier.close()}openLifecycleAdmission(){this.lifecycleBarrier.open()}closeLifecycleAdmissionForRestart(){this.lifecycleAdmissionCloser?this.lifecycleAdmissionCloser():this.closeLifecycleAdmission()}setInstallAgentHandler(e){this.installAgentHandler=e}setRemoteAdminPorts(e){this.remoteAdminPorts=e}setAgentDeletedHandler(e){this.agentDeletedHandler=e}setSkillSyncHandler(e){this.skillSyncHandler=e}setShareSetHandler(e){this.shareSetHandler=e}setProviderConfigHandler(e){this.providerConfigHandler=e}setRelayStateApplyPorts(e){this.relayStateApplyPorts=e}}export{_o as AgentInstance};
|
|
3
|
+
Error: ${r}`,i,!1,t))}sendEventResultWithCleanup(e,n,r,i,t=!1){const s=this.eventSessionIndex.get(e),o=r?.trim()??"";t&&this.markRunErrorSurfaced(e,o),n==="failed"&&s&&o&&this.sendRunErrorAsChunk(e,s,o);const a=n==="failed"&&o!==""&&(this.surfacedRunErrorTexts.get(e)?.has(o)??!1);this.auditController.markResponded(e,n,r),this.sendCtrl.finalizeOpenStreams(e),this.sendCtrl.sendEventResult(e,n,r,i,a),s&&(this.pool.eventComplete(e,s)===!1&&h.error(this.name,`Event terminal result could not release queue slot event=${e} session=${s} status=${n}`),this.pushQueueSnapshotForSession(s),this.conversationLog?.logResult?.(s,e,n,r),this.eventSessionIndex.delete(e)),this.inflightEvents.delete(e),this.restartCount.delete(e),this.surfacedRunErrorTexts.delete(e),this.pendingStartedEventIds.delete(e),this.pendingEvents.remove(e).catch(l=>{h.warn(this.name,`Failed to remove terminal event from pending store event=${e}: ${l instanceof Error?l.message:String(l)}`)}),n==="responded"&&(this.config.adapterType??"acp")!=="agy"&&(this.cachedProviderQuotaSampledAtMs=null,this.refreshAndPushProviderQuota(!0).catch(()=>{}))}async handleSessionInternalError(e){const{eventId:n,sessionId:r,errorMsg:i}=e;if(this.stopped)return;const t=this.inflightEvents.get(n);if(!t){h.warn(this.name,`[recovery] no inflight event for internalError event=${n} session=${r}; surface failure directly`),this.sendRunErrorAsChunk(n,r,i),this.sendEventResultWithCleanup(n,"failed",i,"agent_stop_failure");return}const s=(this.restartCount.get(n)??0)+1;this.restartCount.set(n,s);const o=this.config.adapterType??"acp";if(s>y){h.error(this.name,`[recovery] adapter=${o} session=${r} event=${n} restart=${s}/${y} outcome=give-up err=${i}`);const c=`${o} agent kept failing after ${y} automatic restarts: ${i}`;this.sendRunErrorAsChunk(n,r,c),this.sendEventResultWithCleanup(n,"failed",c,"agent_stop_failure");return}h.info(this.name,`[recovery] adapter=${o} session=${r} event=${n} restart=${s}/${y} outcome=restarting err=${i}`);const a=this.pool.drainQueuedForSession(r);a.length>0&&h.info(this.name,`[recovery] session=${r} preserved ${a.length} queued sibling event(s) across restart`);try{await this.pool.removeSlot(r)}catch(c){h.warn(this.name,`[recovery] removeSlot failed session=${r}: ${c instanceof Error?c.message:String(c)}`)}if(this.stopped)return;const l=e.replayOriginalContent?t.content:this.resolveRecoveryPrompt(o,t),d={...t,content:l};try{await this.pool.deliverInboundEvent(d)}catch(c){h.error(this.name,`[recovery] redeliver failed event=${n} session=${r}: ${c instanceof Error?c.message:String(c)}`),this.sendEventResultWithCleanup(n,"failed",c instanceof Error?c.message:String(c));return}for(const c of a){if(this.stopped)break;try{await this.pool.deliverInboundEvent(c)}catch(u){h.error(this.name,`[recovery] sibling redeliver failed event=${c.event_id} session=${r}: ${u instanceof Error?u.message:String(u)}`),this.sendEventResultWithCleanup(c.event_id,"failed",u instanceof Error?u.message:String(u))}}}resolveRecoveryPrompt(e,n){return e==="acp"?"continue":n.content}sendThinkingByRuntimeConfig(e,n,r){this.sendCtrl.sendThinking(e,n,r)}bufferStreamChunk(e,n,r,i,t){this.auditController.captureUnsequencedStreamChunk(e,r),this.sendCtrl.bufferOnly(e,n,r,i,t)}flushBufferedStreamText(e){}resolveEventRuntimeConfig(e){return this.sendCtrl.resolveEventRuntimeConfig(e)}captureEventRuntimeConfig(e){this.sendCtrl.captureEventRuntimeConfig(e),this.indexEventSession(e.event_id,e.session_id),this.auditController.markRecording(e.event_id),e.event_id&&!this.inflightEvents.has(e.event_id)&&this.inflightEvents.set(e.event_id,e)}async replayPendingEventsOnStartup(){const e=await this.pendingEvents.loadForReplay();if(e.length===0)return;const n=new Set(e.map(i=>i.event.event_id).filter(Boolean)),r=[];h.warn(this.name,`Replaying ${e.length} pending event(s) from previous run`);for(const i of e){if(this.stopped)break;const t=i.event;this.pendingEvents.startReplay(i);try{if(i.kind==="deferred"){const s=this.bindingStore.get(i.sessionId);s?.cwd?(await this.prepareBoundDeferredReplay(i,s.cwd),await this.deliverPendingReplayEvent(t),this.pendingStartedEventIds.has(t.event_id)||r.push(i)):(this.restorePendingReplayAuditTurn(t),this.deferredMgr.defer(i.channel,i.sessionId,t),r.push(i))}else await this.deliverPendingReplayEvent(t),this.pendingStartedEventIds.has(t.event_id)||r.push(i)}catch(s){const o=s instanceof Error?s.message:String(s);h.error(this.name,`Pending event replay failed event=${t.event_id}: ${o}`),this.sendEventResultWithCleanup(t.event_id,"failed",o),this.pendingEvents.markCanceled(t.event_id),await this.pendingEvents.remove(t.event_id).catch(()=>{})}finally{this.pendingEvents.finishReplay(i),await this.pendingEvents.checkpointReplay(n,[...r,...this.pendingEvents.replaySnapshot()])}if(this.stopped)break}this.stopped||(this.pendingEvents.finishAllReplay(),await this.pendingEvents.checkpointReplay(n,r))}failEventIfLifecycleDraining(e,n="connector is draining for restart; control command was not executed"){return this.lifecycleBarrier.isClosed()?(this.aibotHandle.sendEventAck({event_id:e.event_id,session_id:e.session_id,received_at:Date.now()}),this.aibotHandle.sendEventResult({event_id:e.event_id,status:"failed",code:"connector_lifecycle_draining",msg:n,updated_at:Date.now()}),!0):!1}sendCanceledPendingEventResult(e,n){this.restorePendingReplayAuditTurn(e),this.captureEventRuntimeConfig(e),this.sendEventResultWithCleanup(e.event_id,"canceled",n),this.auditController.markAdapterClosed(e.event_id,{adapterNotStarted:!0})}async deliverPendingReplayEvent(e){this.restorePendingReplayAuditTurn(e),this.captureEventRuntimeConfig(e),await this.pool.deliverInboundEvent(e)}async prepareBoundDeferredReplay(e,n){this.sessionBindings.set(e.sessionId,n),e.channel==="acp"?await this.bindSessionForPool(e.sessionId,n):e.channel==="opencode"&&await this.syncOpenCodeBinding(e.sessionId,n)}restorePendingReplayAuditTurn(e){const n=e.audit;if(!n?.enabled||!n.auditId||!n.capture||!n.profile||!n.scope)return;const r=Ei({enabled:!0,scope:n.scope,profile:n.profile,capture:n.capture,...n.retentionDays===void 0?{}:{retentionDays:n.retentionDays}});if(!r.enabled)return;const i=Object.freeze({auditId:n.auditId,businessSessionId:e.session_id,provider:this.resolveAuditProvider(),options:r,createdAt:new Date().toISOString()}),t=this.auditController.startTurn({session:i,eventId:e.event_id,userInput:e.content??"",...e.msg_id===void 0?{}:{originMsgId:e.msg_id},...Number.isFinite(Number(e.created_at))&&Number(e.created_at)>0?{startedAt:new Date(Number(e.created_at)).toISOString()}:{},boundary:{adapterType:this.config.adapterType??"acp"}});t&&(e.audit={...n,auditId:t.auditId,turnId:t.turnId,profile:i.options.profile,capture:{...i.options.capture},rawProviderBody:i.options.capture.rawProviderBody})}indexEventSession(e,n){if(!e||!n)return;const r=this.eventSessionIndex.get(e);return r?(r!==n&&h.warn(this.name,`Ignoring event session mismatch event=${e} indexed=${r} supplied=${n}`),r):(this.eventSessionIndex.set(e,n),n)}shouldDropToolDisplayEvent(e){return this.sendCtrl.shouldDropToolDisplayEvent(e)}shouldDropThinkingDisplayEvent(e){return this.sendCtrl.shouldDropThinkingDisplayEvent(e)}shouldDropCodexDisplayEvent(e,n){return this.sendCtrl.shouldDropCodexDisplayEvent(e,n)}logCodexEventToConversation(e){if(!this.conversationLog||e.codex_method!=="item/agentMessage/delta")return;const r=e.codex_payload?.params?.delta;if(!r)return;const i=this.eventSessionIndex.get(e.event_id)??e.session_id;this.conversationLog.append(i,{ts:Date.now(),dir:"outbound",event_id:e.event_id,kind:"codex_delta",text_len:r.length,content:r})}isAcpRawTransportEnabled(){return(this.config.adapterOptions??{}).raw_transport===!0}shouldDropAcpRawDisplayEvent(e,n){return this.sendCtrl.shouldDropAcpRawDisplayEvent(e,n)}sendAcpRawEventEnvelope(e,n,r){this.shouldDropAcpRawDisplayEvent(e,r.type)||this.deliverRawEventEnvelope(e,n,r,"acp",this.buildAcpRawEventFallbackText(r))}buildAcpRawEventFallbackText(e){const n=String(e.type??"").trim();if(!n)return"[acp] event";switch(n){case"permission_request":return`Permission required: ${String(e.payload?.tool_title??e.payload?.tool_name??"permission request")}`;case"tool_use":return`[tool] ${String(e.payload?.tool_name??"tool")}`;case"tool_result":return"[tool result]";case"thinking":return"[thinking]";case"error":return`[error] ${String(e.payload?.message??"agent error")}`;case"result":return"[result]";default:return`[acp] ${n}`}}rawDetailSeq=0;deliverRawEventEnvelope(e,n,r,i,t){const s=ui({envelope:r,fallbackText:t,channelKey:i,allocateRefId:()=>`${e}_rawd_${++this.rawDetailSeq}`}),o=()=>{this.aibotHandle.sendMsg({event_id:e,session_id:n,msg_type:1,content:s.fallbackText,extra:{channel_data:{[i]:{raw_event:s.envelope}},agent_api_origin:!0}})};if(!s.sharded){o();return}h.info("bridge",`${i} raw_event oversized, sharded delivery: event=${e} fields=${s.oversizedFields.map(a=>a.field).join(",")}`),(async()=>{for(const a of s.oversizedFields)await this.sendCtrl.deliverAuxiliaryLargeText(e,n,pi({envelopeType:r.type,field:a.field,fullText:a.fullText}),a.refClientMsgId);o()})().catch(a=>{h.warn("bridge",`${i} raw_event sharded delivery failed event=${e}: ${a}`)})}buildCursorRawEventFallbackText(e){const n=String(e?.type??"").trim(),r=e?.payload&&typeof e.payload=="object"?e.payload:{};switch(n){case"permission_request":return`Permission required: ${String(r.tool_title??r.tool_name??"permission request")}`;case"tool_use":case"tool_call":case"tool_execution_start":return`[tool] ${String(r.tool_name??r.toolName??"tool")}`;case"tool_result":case"tool_execution_end":case"tool_execution_update":return"[tool result]";case"error":return`[error] ${String(r.message??"agent error")}`;default:return n?`[cursor] ${n}`:"[cursor] event"}}sendToolExecutionCard(e,n,r,i){this.sendCtrl.sendToolExecutionCard(e,n,r,i)}sendGrixApprovalCard(e,n){this.aibotHandle.sendMsg({event_id:e.eventId,session_id:e.sessionId,client_msg_id:`perm_${k()}`,msg_type:1,content:e.toolTitle?`Permission required: ${e.toolTitle}`:"Permission request",extra:{channel_data:{execApproval:{approvalId:e.approvalId,approvalSlug:e.toolName},grix:{execApproval:{approval_command_id:e.approvalId,command:e.toolTitle||e.toolName,host:n}}},agent_api_origin:!0}})}sendGrixAgentQuestionCard(e,n,r){const i=r.questions.map(s=>s.header).join(", "),t=I(`[Agent Question] ${r.request_id}`,"agent_question",r);this.aibotHandle.sendText({event_id:e,session_id:n,content:t,msg_type:1,extra:{card_type:"agent_question",summary_text:i}})}async handleAgentQuestionReplyEvent(e){const n=bn(String(e.content??""));if(!n)return!1;this.aibotHandle.sendEventAck({event_id:e.event_id,session_id:e.session_id,received_at:Date.now()});const i=this.pool.getSlot(e.session_id)?.adapter,t=i instanceof S?"acp":i instanceof T?"opencode":this.config.adapterType??"unknown",s=i instanceof T?i.handleQuestionReplyEvent(n):i instanceof S?await i.handleQuestionReplyEvent(n):{delivered:!1,errorCode:"interaction_request_not_pending",errorMsg:"The question is no longer pending; the reply was not delivered."};return s.delivered?(h.info(this.name,`[${t}] question reply delivered event=${e.event_id} session=${e.session_id} request=${n.request_id}`),this.aibotHandle.sendEventResult({event_id:e.event_id,status:"responded",updated_at:Date.now()})):(h.warn(this.name,`[${t}] question reply rejected event=${e.event_id} session=${e.session_id} request=${n.request_id} code=${s.errorCode??"interaction_reply_failed"}`),this.aibotHandle.sendEventResult({event_id:e.event_id,status:"failed",code:s.errorCode??"interaction_reply_failed",msg:s.errorMsg??"The question reply was not delivered.",updated_at:Date.now()})),!0}async handleExecApprovalResolutionEvent(e){const n=Cn(String(e.content??""));if(!n)return!1;this.aibotHandle.sendEventAck({event_id:e.event_id,session_id:e.session_id,received_at:Date.now()});const i=this.pool.getSlot(e.session_id)?.adapter,t=n.params,s=String(t.tool_call_id??t.approval_command_id??t.approval_id??t.exec_context_id??""),o=i?.handleExecApprovalEvent?await i.handleExecApprovalEvent({...t,event_id:e.event_id,session_id:e.session_id}):{delivered:!1,errorCode:"approval_not_supported",errorMsg:"The current adapter does not support exec approval resolution events."};return o.delivered?(h.info(this.name,`[${this.config.adapterType??"unknown"}] exec approval resolution delivered event=${e.event_id} session=${e.session_id} approval=${s||"-"}`),this.aibotHandle.sendEventResult({event_id:e.event_id,status:"responded",updated_at:Date.now()})):(h.warn(this.name,`[${this.config.adapterType??"unknown"}] exec approval resolution rejected event=${e.event_id} session=${e.session_id} approval=${s||"-"} code=${o.errorCode}`),this.aibotHandle.sendEventResult({event_id:e.event_id,status:"failed",code:o.errorCode,msg:o.errorMsg,updated_at:Date.now()})),!0}async handleAibotEvent(e){if(this.relayEnvStale&&!this.hasPendingWork()&&await this.recycleAdaptersForRelayChange(),this.stopped){this.aibotHandle.sendEventAck({event_id:e.event_id,session_id:e.session_id,received_at:Date.now()}),this.aibotHandle.sendEventResult({event_id:e.event_id,status:"failed",msg:"agent shutting down",updated_at:Date.now()});return}this.logInboundConversation(e);const n=this.config.adapterType??"acp",r=_n(e);let i;if(r&&(i=this.lifecycleBarrier.tryEnter(`session-control:${r.verb}`)??void 0,!i)){this.failEventIfLifecycleDraining(e);return}try{if(await this.handleCliInstallQuestionReply(e)||(n==="opencode"||n==="acp")&&await this.handleAgentQuestionReplyEvent(e)||await this.handleExecApprovalResolutionEvent(e))return;const t=ri(e.extra);if(t.error){this.aibotHandle.sendEventAck({event_id:e.event_id,session_id:e.session_id,received_at:Date.now()}),this.aibotHandle.sendEventResult({event_id:e.event_id,status:"failed",code:"connector_config_invalid",msg:t.error,updated_at:Date.now()});return}const s=t.patch,o=B(e.extra);if(An(this,e,n,o))return;if(r){await wn(this,r,e,n,o,this.config.agent.clientType??this.config.aibot.clientType);return}if(e.mirror_mode==="record_only"){this.aibotHandle.sendEventAck({event_id:e.event_id,session_id:e.session_id,received_at:Date.now()}),this.aibotHandle.sendEventResult({event_id:e.event_id,status:"responded",updated_at:Date.now()});return}if(this.isStaleEvent(e)){this.aibotHandle.sendEventAck({event_id:e.event_id,session_id:e.session_id,received_at:Date.now()}),this.aibotHandle.sendEventResult({event_id:e.event_id,status:"failed",code:"event_stale",msg:"event is stale and will not be processed",updated_at:Date.now()});return}let a;try{a=this.auditController.resolveSession({sessionId:e.session_id,provider:this.resolveAuditProvider(),extra:e.extra,eventId:e.event_id}).session}catch(c){this.sendAuditConfigurationError(e,c);return}if(await En(this,e,n,$i.has(n),s,a))return;if((this.config.adapterType??"acp")==="acp"){const u=String(e.content??"").trim().match(/^\/(\S+)\s*(.*)/);if(u){const[,g,p]=u,A=this.pool.getSlot(e.session_id)?.adapter;if(A?.execCommand&&(A.getSupportedCommands?.()??[]).some(m=>m.name===g||m.name===`/${g}`)){this.aibotHandle.sendEventAck({event_id:e.event_id,session_id:e.session_id,received_at:Date.now()});try{const m=await A.execCommand(g,p.trim(),e.session_id);m.status==="options"&&m.data&&this.handleExecCommandOptions(e.session_id,g,m.data),this.aibotHandle.sendEventResult({event_id:e.event_id,status:m.status==="failed"?"failed":"responded",msg:m.message,updated_at:Date.now()})}catch(m){this.aibotHandle.sendEventResult({event_id:e.event_id,status:"failed",msg:m instanceof Error?m.message:String(m),updated_at:Date.now()})}return}}}if(n==="codex"&&D(a?.options)){const c=this.pool.getSlot(e.session_id);if(c?.adapter instanceof H&&!c.adapter.hasRawApiCaptureRelay()){const u=c.eventQueue.snapshot(e.session_id);u.running.length===0&&u.queued.length===0?(h.info(this.name,`[audit-raw-capture] recreating idle Codex adapter before event=${e.event_id} session=${e.session_id}`),await this.pool.removeSlot(e.session_id)):h.warn(this.name,`[audit-raw-capture] Codex adapter lacks relay but is not idle event=${e.event_id} session=${e.session_id} running=${u.running.length} queued=${u.queued.length}`)}}const d=this.prepareAuditedInboundEvent(e,s,a);d.attachments_json=await Zn(d.attachments_json,{extraAllowedHosts:Vn(this.aibotConfig.url),logTag:this.name});try{const c=await this.pendingEvents.append({kind:"queued",event:d});if(this.pendingEvents.isCanceled(e.event_id)){await this.pendingEvents.remove(e.event_id),this.aibotHandle.sendEventAck({event_id:e.event_id,session_id:e.session_id,received_at:Date.now()}),this.sendCanceledPendingEventResult(d,"canceled");return}if(this.lifecycleBarrier.isClosed()){if(!c)throw new Error("pending event store unavailable during lifecycle drain");this.aibotHandle.sendEventAck({event_id:e.event_id,session_id:e.session_id,received_at:Date.now()}),h.info(this.name,`Persisted inbound event during lifecycle drain: ${e.event_id}`);return}this.captureEventRuntimeConfig(d),await this.pool.deliverInboundEvent(d)}catch(c){await this.pendingEvents.remove(e.event_id).catch(u=>{h.warn(this.name,`Failed to remove undelivered pending event=${e.event_id}: ${u instanceof Error?u.message:String(u)}`)}),this.failUndeliveredInboundEvent(e,c)}}finally{i?.()}}handleStaleCwdError(e,n){if(!/CWD must be|Bound directory does not exist|Bound path is not a directory/i.test(n)||!e.session_id)return!1;this.bindingStore.delete(e.session_id),this.sessionBindings.delete(e.session_id),this.sessionProviderHints.delete(e.session_id),this.sessionProviderQuotas.delete(e.session_id),this.sessionProviderMeta.delete(e.session_id);const i=this.pool.getSlot(e.session_id);i?.adapter instanceof S&&i.adapter.getSessionBindings().delete(e.session_id);const t=this.config.adapterType??"acp",s=this.resolveBindingChannelKey(t);return this.aibotHandle.sendMsg({event_id:e.event_id,session_id:e.session_id,msg_type:1,content:n,extra:{channel_data:{[s]:{sessionBinding:{status:"missing",reason:"binding_stale",error_code:P.invalidCwd}}}},quoted_message_id:e.msg_id}),!0}failUndeliveredInboundEvent(e,n){const r=n instanceof Error?n.message:String(n);h.warn(this.name,`Inbound event undelivered event=${e.event_id} session=${e.session_id}: ${r}`),this.aibotHandle.sendEventAck({event_id:e.event_id,session_id:e.session_id,received_at:Date.now()}),this.auditController.closeWithoutAdapter(e.event_id,"failed",r,{deliveryFailed:!0}),this.discardEventTrackingState(e.event_id),!this.handleStaleCwdError(e,r)&&this.aibotHandle.sendEventResult({event_id:e.event_id,status:"failed",msg:r,updated_at:Date.now()})}handleCodexSessionControlOpen(e,n){return ot(this,e,n)}handleSessionControlForPool(e,n){return rt(this,e,n)}handleSessionControlLocalActionForPool(e){return at(this,e)}handleCodexSessionControlLocalActionOpen(e){return dt(this,e)}handleCursorSessionControlLocalActionOpen(e){return lt(this,e)}handlePiSessionControlOpen(e,n){return ct(this,e,n)}handlePiSessionControlRestart(e){return ht(this,e)}handlePiSessionControlRestartLocalAction(e){return ut(this,e)}syncOpenCodeBinding(e,n){return pt(this,e,n)}isWorkspaceFreeClient(){return gt(this)}isCwdLockedClient(){return ft(this)}ensureDefaultBindingForWorkspaceFreeClient(e,n){return mt(this,e,n)}bindSessionForPool(e,n){return vt(this,e,n)}deferredCallbacks(){return _t(this)}handleOpenHumanSessionControlOpen(e,n){return St(this,e,n)}handleCodeWhaleSessionControlOpen(e,n){return Ct(this,e,n)}handleCodeWhaleSessionControlLocalActionOpen(e){return bt(this,e)}handleDeepSeekSessionControlLocalActionOpen(e){return At(this,e)}normalizeClaudeModeId(e){return Ft(this,e)}handleExecCommandOptions(e,n,r){Ut(this,e,n,r)}resolveSessionModelId(e){return qt(this,e)}resolveSessionModeId(e){return Wt(this,e)}resolveCursorSessionModeId(e){return Nt(this,e)}resolveClaudeSessionEffort(e){return Gt(this,e)}resolveClaudeSessionModeId(e){return jt(this,e)}currentClaudeModeId(e){return Kt(this,e)}buildCursorToolbarMeta(e){return zt(this,e)}buildAgyToolbarMeta(e,n){return Jt(this,e,n)}buildAgyQuotaMeta(e){return Yt(this,e)}sendAgyBindingCard(e,n,r){return Vt(this,e,n,r)}refreshAndPushAgyQuota(e,n=!1){return Xt(this,e,n)}handleAgySetModel(e,n){return Zt(this,e,n)}buildClaudeToolbarMeta(e){return en(this,e)}providerQuotaToCodexRateLimits(e){return ci(e,this.cachedProviderQuotaSampledAtMs??Date.now())}providerQuotaToRateLimits(e){return li(e,this.cachedProviderQuotaSampledAtMs??Date.now())}async resolveCwdForBinding(e){return Nn(e)}failSessionOpen(e,n){return Un(this,e,n)}getClaudeWorkerStatus(e){return qn(this,e)}refreshClaudeWorkerStatusCard(e,n){return Wn(this,e,n)}async ensureSlotStarted(e,n=6e4){return Fn(this,e,n)}maybeOfferCliInstall(e){Me(this,e)}handleCliInstallQuestionReply(e){return He(this,e)}handleCliInstallInteractionReply(e){return $e(this,e)}runConfirmedCliInstall(e,n){return De(this,e,n)}handleSkillDeleteLocalAction(e){return kt(this,e)}handleSkillUploadLocalAction(e){return Tt(this,e)}handleSkillEnableLocalAction(e){return Pt(this,e)}handleSkillRefreshLocalAction(e){xt(this,e)}handleSkillDisableLocalAction(e){return Lt(this,e)}computeSkillReport(e){return Mt(this,e)}reportSessionSkills(e){Ht(this,e)}skillsSyncGroupKey(){return $t(this)}forceRefreshSkills(e,n){return Dt(this,e,n)}adoptSkillsWireHashFromDisk(){Qt(this)}buildLibrarySkillsReport(e){return It(this,e)}skillLookupEnv(){return Ot(this)}resolveOrphanTitle(e){return Qn(this,e)}resolveAgentSessionId(e){return Dn(this,e)}providerKeyForAdapter(){return $n(this)}setResolvedAgentSessionId(e,n){In(this,e,n)}normalizePathForCompare(e){return Hn(e)}ensureImportedAgentSession(e,n){Ln(this,e,n)}buildOpenedBindingResult(e,n,r="ready"){return xn(this,e,n,r)}buildDshOpenedToolbarMeta(e){return On(this,e)}dshCatalogDataRoot(){return Bn(this)}hasDiskScanner(){return Mn(this)}unbindSession(e){return Ze(this,e)}handleUnbindTextCommand(e){return et(this,e)}handleUnbindLocalAction(e){return tt(this,e)}handleListSessionsTextCommand(e){return nt(this,e)}handleListSessionsLocalAction(e){return it(this,e)}handleSyncHistoryLocalAction(e){return st(this,e)}handleSessionControlCommand(e,n){return xe(this,e,n)}handleSessionControlLocalAction(e){return Le(this,e)}handleEventCancel(e){return Qe(this,e)}waitForEventDone(e,n,r){return Ie(this,e,n,r)}handleAibotStop(e){Oe(this,e)}killAndResumeStopSlot(e,n){return Be(this,e,n)}handleAibotRevoke(e){return Fe(this,e)}handleConfigureGatewayProvider(e){return Ue(this,e)}getAuditLocalActionHandler(){return qe(this)}handleAuditLocalAction(e){return We(this,e)}handleConnectorRollback(e){return Ne(this,e)}getRelayStateSyncer(){return Ge(this)}relayStateSyncOnConnect(){je(this)}reportRelayStateLocalChange(){Ke(this)}handleApplyRelayState(e){return ze(this,e)}fetchRelayCredential(e){return Je(this,e)}handleConnectorAdminLocalAction(e){return Xe(this,e)}isSharedInstance(){return Ye(this)}async handleAibotLocalAction(e){if(this.stopped){this.aibotHandle.sendLocalActionResult({action_id:e.action_id,status:"failed",error_code:"connector_lifecycle_draining",error_msg:"connector is shutting down; local action was not executed"});return}const n=e.action_type??"",r=String((e.params??{}).session_id??""),i=String((e.params??{}).verb??"").trim().toLowerCase();h.debug(this.name,`local_action received action_type=${n} verb=${i||"-"} action_id=${e.action_id} session_id=${r}`);let t;if(n===f.sessionControl&&(t=this.lifecycleBarrier.tryEnter(`local-action:${i||n}`)??void 0,!t)){this.aibotHandle.sendLocalActionResult({action_id:e.action_id,status:"failed",error_code:"connector_lifecycle_draining",error_msg:"connector is draining for restart; session control was not executed"});return}try{if(n===f.interactionReply&&await this.handleCliInstallInteractionReply(e))return;if(J(n)){await this.handleAuditLocalAction(e);return}const s=(this.config.adapterType??"acp")==="claude";if(n===f.sessionControl&&i===E.exec&&await this.handleSessionControlLocalAction(e))return;if(n===f.sessionControl&&i===E.listSessions){await this.handleListSessionsLocalAction(e);return}if(n===f.sessionControl&&i===E.syncHistory){await this.handleSyncHistoryLocalAction(e);return}if(n===f.sessionControl&&i===E.unbind){if(this.isCwdLockedClient()){this.aibotHandle.sendLocalActionResult({action_id:e.action_id,status:"failed",error_code:P.verbInvalid,error_msg:Et});return}await this.handleUnbindLocalAction(e);return}if(n==="skill_upload"){await this.handleSkillUploadLocalAction(e);return}if(n==="skill_delete"){await this.handleSkillDeleteLocalAction(e);return}if(n==="skill_enable"){await this.handleSkillEnableLocalAction(e);return}if(n==="skill_disable"){await this.handleSkillDisableLocalAction(e);return}if(n==="skill_refresh"){this.handleSkillRefreshLocalAction(e);return}const o=(this.config.adapterType??"acp")==="opencode";if((s&&(n===f.interactionReply||n==="exec_approve"||n==="exec_reject")||o&&n===f.interactionReply)&&(await this.pool.deliverLocalAction(e)).handled||s&&await this.handleSessionControlLocalAction(e))return;if(n===f.sessionControl){await yn(this,e,r);return}if(n==="file_list"){await kn(this,e,r);return}if(n==="create_folder"){await Rn(this,e,r);return}if(n===f.setModel&&(this.config.adapterType??"acp")==="agy"){await this.handleAgySetModel(e,r);return}if(n===f.getSessionUsage){if((this.config.adapterType??"acp")==="deepseek-harness"&&(await this.pool.deliverLocalAction(e,{autoCreateSlot:!!r&&!!this.bindingStore.get(r)?.cwd})).handled)return;await this.handleGetSessionUsage(e,r);return}if(n===f.getRateLimits){if((this.config.adapterType??"acp")==="deepseek-harness"&&(await this.pool.deliverLocalAction(e,{autoCreateSlot:!!r&&!!this.bindingStore.get(r)?.cwd})).handled)return;await this.handleGetRateLimits(e,r);return}const a=(this.config.adapterType??"acp")==="acp",l=(this.config.adapterType??"acp")==="cursor";if((s||a||l)&&n===f.threadCompact){await this.handleThreadCompact(e,r);return}if(n==="connector_rollback"){await this.handleConnectorRollback(e);return}if(n==="connector_upgrade_push"){this.aibotHandle.sendLocalActionResult({action_id:e.action_id,status:"ok",result:{accepted:!0}}),this.upgradeTrigger?.();return}if(n===f.getAgentGlobalConfig){const p=this.globalConfigStore?.get(this.name);this.aibotHandle.sendLocalActionResult({action_id:e.action_id,status:"ok",result:{agentName:this.name,...p?{config:p}:{config:null}}});return}if(n===Ve){await this.handleConnectorAdminLocalAction(e);return}if(n==="configure_gateway_provider"){await this.handleConfigureGatewayProvider(e);return}if(n==="apply_relay_state"){await this.handleApplyRelayState(e);return}const d=this.config.adapterType??"acp",c=(d==="codex"||d==="cursor"||d==="pi"||d==="openhuman"||d==="opencode"||d==="deepseek-harness"||d==="acp")&&!!r&&!!this.bindingStore.get(r)?.cwd,u=await this.pool.deliverLocalAction(e,{autoCreateSlot:c});if(u.handled){Pn(this,e,r,d,u);return}if((d==="codex"||d==="cursor"||d==="pi"||d==="openhuman"||d==="opencode"||d==="deepseek-harness")&&r&&!this.bindingStore.get(r)?.cwd){this.aibotHandle.sendLocalActionResult({action_id:e.action_id,status:"failed",error_code:P.bindingMissing,error_msg:"Session binding missing. Open a workspace first."});return}if(d==="acp"&&(n==="set_mode"||n==="set_model")){await Tn(this,e,r,n);return}const g=!!r&&!!this.pool.getSlot(r);this.aibotHandle.sendLocalActionResult({action_id:e.action_id,status:"failed",error_code:"unsupported_local_action",error_msg:g?`Action type "${n}" is not supported by the current agent process.`:`No active agent process for this session. The reply to action "${n}" could not be delivered \u2014 please resend it as a new message.`})}finally{t?.()}}handleGetSessionUsage(e,n){return yt(this,e,n)}handleThreadCompact(e,n){return Rt(this,e,n)}handleGetRateLimits(e,n){return pn(this,e,n)}resolveRateLimitWakeSessionId(e,n){return gn(this,e,n)}wakeRateLimitSlot(e,n){return fn(this,e,n)}sessionControlCtx(e){const n=this.pool.getSlot(e),r=n?.adapter instanceof S?n.adapter:null,i=(this.config.adapterType??"acp")==="acp",t={bindingStore:this.bindingStore,acpAdapter:r,globalConfigStore:this.globalConfigStore,agentName:this.name,log:h};return{getCwd:()=>this.bindingStore.get(e)?.cwd??this.config.agent.cwd??process.cwd(),getSessionBindings:()=>{if(r)return r.getSessionBindings();const s=this.sessionBindings;if(e&&!s.has(e)){const o=this.bindingStore.get(e);o?.cwd&&s.set(e,o.cwd)}return s},getStatus:()=>this.getStatus(),isAcpAlive:!!r?.isAlive(),getAcpSessionOptions:()=>r?.acpSessionOptions??null,setMode:s=>r?r.setMode(s):Promise.resolve(!1),setModel:s=>r?r.setModel(s):Promise.resolve(!1),acpSetMode:i?(s,o)=>jn(t,s,o):void 0,acpSetModel:i?(s,o)=>Gn(t,s,o):void 0,getPendingApproval:s=>{const o=r?.pendingApprovalEntries.get(s);return o?{requestId:o}:void 0},deletePendingApproval:s=>r?.pendingApprovalEntries.delete(s)??!1,respondPermission:(s,o)=>(r&&r.respondToPermission(s,o),Promise.resolve()),onSessionBound:(s,o)=>{this.bindingStore.set(s,o)},onSessionUnbound:s=>{this.unbindSession(s).catch(o=>{h.warn(this.name,`session unbind cleanup failed: ${o instanceof Error?o.message:String(o)}`)})},cancelActiveRun:()=>(this.config.adapterType??"acp")==="agy"&&n?.adapter instanceof $?(n.adapter.cancelCurrentRun(),Promise.resolve()):n?.adapter?.cancel("")??Promise.resolve(),onModeSet:s=>{Q(this,this.config.adapterType??"acp",e,"mode",s)},onModelSet:s=>{Q(this,this.config.adapterType??"acp",e,"model",s),this.refreshQuotaAfterModelSwitch(e,s)}}}sessionControlSenders(e){return{sendEventAck:(n,r)=>this.aibotHandle.sendEventAck({event_id:n,session_id:r,received_at:Date.now()}),sendEventResult:(n,r,i)=>this.aibotHandle.sendEventResult({event_id:n,status:r,...i?.msg?{msg:i.msg}:{},...i?.code?{code:i.code}:{},updated_at:Date.now()}),sendLocalActionResult:(n,r,i,t,s)=>this.aibotHandle.sendLocalActionResult({action_id:n,status:r,...i?{result:i}:{},...t?{error_code:t}:{},...s?{error_msg:s}:{}},e)}}resolveBindingChannelKey(e){switch(e){case"claude":return"grix-claude";case"codex":return"codex";case"cursor":return"cursor";case"pi":return"pi";case"openhuman":return"openhuman";case"codewhale":return"codewhale";case"opencode":return"opencode";case"agy":return"acp";case"deepseek-harness":return"deepseek";case"acp":return this.config.aibot.clientType==="qwen"?"qwen":"acp";default:return e}}finalizeThinking(e,n){this.sendCtrl.finalizeThinking(e,n)}logInboundConversation(e){const n=String(e.session_id??"").trim();n&&this.conversationLog?.logInbound(n,{event_id:e.event_id,msg_id:e.msg_id,sender_id:e.sender_id,msg_type:e.msg_type,content:e.content??""})}resolveAuditProvider(){const e=this.config.adapterType??"acp";return e==="claude"||e==="codex"||e==="cursor"||e==="opencode"||e==="pi"||e==="codewhale"||e==="deepseek-harness"||e==="agy"?e:"acp"}sendAuditConfigurationError(e,n){const r=n instanceof Error?n.message:String(n),i=(()=>{const a=B(e.extra);return a.options?.enabled===!0&&a.options.scope==="turn"})(),t=n instanceof Ai||n instanceof bi,s=n instanceof yi&&i,o=s?"audit_config_invalid":t?n.code:"audit_config_conflict";if(this.aibotHandle.sendEventAck({event_id:e.event_id,session_id:e.session_id,received_at:Date.now()}),this.aibotHandle.sendEventResult({event_id:e.event_id,status:"failed",code:o,msg:r,updated_at:Date.now()}),t||s)try{this.aibotHandle.sendAuditState(O({state:"failed",eventId:e.event_id,sessionId:e.session_id,...e.msg_id===void 0?{}:{msgId:e.msg_id},errorCode:o,errorMessage:r},Date.now()))}catch{}}markAuditAdapterClosed(e,n){const i=this.pool.getSlot(n)?.adapter.takeAuditBoundary?.(e);this.auditController.markAdapterClosed(e,i)}prepareAuditedInboundEvent(e,n,r){const i=this.buildInboundEvent(e,n),t=this.bindingStore.get(e.session_id),s=t?this.resolveAgentSessionId(t):void 0,o=Number(e.created_at),a=Number.isFinite(o)&&o>0?new Date(o).toISOString():void 0,l=this.auditController.startTurn({session:r,eventId:e.event_id,userInput:e.content??"",...e.msg_id===void 0?{}:{originMsgId:e.msg_id},...a===void 0?{}:{startedAt:a},boundary:{adapterType:this.config.adapterType??"acp",...s?{providerSessionId:s}:{}}});return l&&(i.audit={enabled:!0,auditId:l.auditId,turnId:l.turnId,...r?{scope:r.options.scope,profile:r.options.profile,...r.options.retentionDays===void 0?{}:{retentionDays:r.options.retentionDays},capture:{...r.options.capture}}:{},rawProviderBody:r?.options.capture.rawProviderBody===!0}),i}buildInboundEvent(e,n){const r=oi(this.sendCtrl.getGlobalRuntimeConfig(),n),i=wi(e.extra);return{event_id:e.event_id,session_id:e.session_id,thread_id:e.thread_id,sender_id:e.sender_id,msg_id:e.msg_id,msg_type:e.msg_type,content:e.content??"",quoted_message_id:e.quoted_message_id,context_messages_json:this.buildContextMessagesJson(e.context_messages),extra_json:i===void 0?void 0:JSON.stringify(i),attachments_json:Xn(e.attachments),connector_runtime_config:{response_delivery:r.responseDelivery,tool_events:r.toolEvents,thinking_events:r.thinkingEvents},session_type:e.session_type,created_at:e.created_at}}buildContextMessagesJson(e){if(!e)return;const n=e.filter(r=>!Sn(String(r?.content??"")));if(n.length!==0)return JSON.stringify(n)}isStaleEvent(e){const n=Number(e.created_at);return!Number.isFinite(n)||n<=0?!1:Date.now()-n>Ti}setUpgradeTrigger(e){this.upgradeTrigger=e}setDaemonShutdownRequester(e){this.daemonShutdownRequester=e}setLifecycleBusyChecker(e){this.lifecycleBusyChecker=e}setLifecycleAdmissionCloser(e){this.lifecycleAdmissionCloser=e}setLifecycleAdmissionRestorer(e){this.lifecycleAdmissionRestorer=e}closeLifecycleAdmission(){this.lifecycleBarrier.setAutoOpenHandler(e=>{h.warn(this.name,`Lifecycle admission auto-reopened after ${Math.round(e/1e3)}s: a restart was expected but never happened. Admission is open again and events flow; the pending restart or upgrade did not complete.`)}),this.lifecycleBarrier.close()}openLifecycleAdmission(){this.lifecycleBarrier.open()}closeLifecycleAdmissionForRestart(){this.lifecycleAdmissionCloser?this.lifecycleAdmissionCloser():this.closeLifecycleAdmission()}setInstallAgentHandler(e){this.installAgentHandler=e}setRemoteAdminPorts(e){this.remoteAdminPorts=e}setAgentDeletedHandler(e){this.agentDeletedHandler=e}setSkillSyncHandler(e){this.skillSyncHandler=e}setShareSetHandler(e){this.shareSetHandler=e}setProviderConfigHandler(e){this.providerConfigHandler=e}setRelayStateApplyPorts(e){this.relayStateApplyPorts=e}}export{Eo as AgentInstance};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{homedir as n}from"node:os";const r=new Set(["hermes","acp"]),o=new Set(["acp"]);function t(e){return String(e??"").trim().toLowerCase()}function s(e){return r.has(t(e))}function a(e){return o.has(t(e))}function d(e){return String(e??"").trim()||n()}const C=`This agent's working directory is fixed by its connector config and cannot be changed from chat. Edit the agent's "cwd" field in the grix-connector agent config and restart the connector instead.`;export{C as CWD_LOCKED_REJECT_MSG,a as isCwdLockedClientType,s as isWorkspaceFreeClientType,t as normalizeClientType,d as resolveStaticCwd};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{homedir as w}from"node:os";import{LOCAL_ACTION_TYPES as b,SESSION_CONTROL_ERROR_CODES as g,SESSION_CONTROL_VERBS as f}from"../adapter/claude/protocol-contract.js";import{AcpAdapter as S}from"../adapter/acp/index.js";import{OpenCodeAdapter as _}from"../adapter/opencode/index.js";import{handleSessionControlCommand as p}from"./session-controller.js";import{isCliMissingError as m}from"./cli-install-offer.js";import{log as u}from"../core/log/index.js";const C=new Set(["hermes"]),E=["buildCursorToolbarMeta","buildDshOpenedToolbarMeta","buildOpenedBindingResult","captureEventRuntimeConfig","ensureImportedAgentSession","ensureSlotStarted","failSessionOpen","forceRefreshSkills","resolveCwdForBinding","resolveSessionModeId","resolveSessionModelId","sendEventResultWithCleanup","sessionControlCtx","sessionControlSenders","setResolvedAgentSessionId","bindSessionForPool","deferredCallbacks","handleSessionControlForPool","isWorkspaceFreeClient","syncOpenCodeBinding"],A=["name","config","aibotHandle","pool","bindingStore","sessionBindings","sessionScanCache","pendingEvents","deferredMgr"];async function y(e,s,d){const n=d.session_id,o=s.args.trim(),c=()=>e.aibotHandle.sendEventAck({event_id:d.event_id,session_id:n,received_at:Date.now()}),a=(i,r)=>e.aibotHandle.sendEventResult({event_id:d.event_id,status:i,...r,updated_at:Date.now()});if(!o){c(),a("failed",{msg:"Usage: /grix open <working-directory>",code:g.cwdRequired});return}try{const i=await e.resolveCwdForBinding(o),r=e.bindingStore.get(n);if(r?.cwd){let t=!1;try{const l=await e.resolveCwdForBinding(r.cwd);if(l===i){c(),e.sessionBindings.set(n,l),e.deferredMgr.sendCodexDeferredReplayComposing(n,e.deferredCallbacks()),await e.bindSessionForPool(n,l),await e.deferredMgr.release(n,e.deferredCallbacks(),{announceComposing:!1}),a("responded",{msg:`Session already bound to ${r.cwd}`});return}}catch{t=!0,u.info("bridge",`Stale codex binding for session ${n}: ${r.cwd} no longer exists, allowing rebind`)}if(!t){c(),a("failed",{msg:`Session already bound to ${r.cwd}. Rebinding is not allowed.`,code:g.rebindForbidden});return}}e.bindingStore.set(n,i),e.sessionBindings.set(n,i),e.deferredMgr.sendCodexDeferredReplayComposing(n,e.deferredCallbacks()),await e.bindSessionForPool(n,i),await e.deferredMgr.release(n,e.deferredCallbacks(),{announceComposing:!1}),e.aibotHandle.sendUpdateBindingCard({session_id:n,worker_status:"ready",cwd:i}),c(),a("responded",{msg:`Session bound to ${i}`})}catch(i){c(),e.failSessionOpen(i,{sessionId:n,eventId:d.event_id,quotedMessageId:d.msg_id,cwd:e.bindingStore.get(n)?.cwd||o,send:(r,t)=>a("failed",{code:r,msg:t})})}}async function I(e,s,d){s.verb===f.open&&await e.bindSessionForPool(d.session_id,s.args.trim())}async function $(e,s){if(String(s.action_type??"")!==b.sessionControl)return;const d=s.params??{};if(String(d.verb??"").trim().toLowerCase()!==f.open)return;const o=String(d.session_id??"").trim(),c=String(d.cwd??"").trim();!o||!c||await e.bindSessionForPool(o,c)}async function H(e,s){const d=s.params??{},n=String(d.session_id??"").trim(),o=String(d.cwd??"").trim(),c=String(d.agent_session_id??"").trim(),a=(i,r,t,l)=>{e.aibotHandle.sendLocalActionResult({action_id:s.action_id,status:i,...r!==void 0?{result:r}:{},...t?{error_code:t}:{},...l?{error_msg:l}:{}})};if(!n||!o){a("failed",void 0,g.cwdRequired,"session cwd is required");return}try{const i=await e.resolveCwdForBinding(o);e.ensureImportedAgentSession(c,i);const r=e.bindingStore.get(n);if(r?.cwd){let t=!1;try{const l=await e.resolveCwdForBinding(r.cwd);if(l===i){e.setResolvedAgentSessionId(n,c),e.sessionBindings.set(n,l),e.deferredMgr.sendCodexDeferredReplayComposing(n,e.deferredCallbacks()),await e.bindSessionForPool(n,l),await e.deferredMgr.release(n,e.deferredCallbacks(),{announceComposing:!1}),a("ok",{outcome:"opened",binding:e.buildOpenedBindingResult(n,l)});return}}catch{t=!0,u.info("bridge",`Stale codex binding for session ${n}: ${r.cwd} no longer exists, allowing rebind`)}if(!t){a("failed",void 0,g.rebindForbidden,`Session already bound to ${r.cwd}`);return}}e.bindingStore.set(n,i),e.setResolvedAgentSessionId(n,c),e.sessionBindings.set(n,i),e.deferredMgr.sendCodexDeferredReplayComposing(n,e.deferredCallbacks()),await e.bindSessionForPool(n,i),await e.deferredMgr.release(n,e.deferredCallbacks(),{announceComposing:!1}),a("ok",{outcome:"opened",binding:e.buildOpenedBindingResult(n,i)})}catch(i){e.failSessionOpen(i,{sessionId:n,eventId:s.action_id,cwd:e.bindingStore.get(n)?.cwd||o,send:(r,t)=>a("failed",void 0,r,t)})}}async function M(e,s){const d=s.params??{},n=String(d.session_id??"").trim(),o=String(d.cwd??"").trim(),c=String(d.agent_session_id??"").trim(),a=(i,r,t,l)=>{e.aibotHandle.sendLocalActionResult({action_id:s.action_id,status:i,...r!==void 0?{result:r}:{},...t?{error_code:t}:{},...l?{error_msg:l}:{}})};if(!n||!o){a("failed",void 0,g.cwdRequired,"session cwd is required");return}try{const i=await e.resolveCwdForBinding(o);e.ensureImportedAgentSession(c,i);const r=e.bindingStore.get(n);if(r?.cwd){let t=!1;try{const l=await e.resolveCwdForBinding(r.cwd);if(l===i){e.setResolvedAgentSessionId(n,c),e.sessionBindings.set(n,l),await e.bindSessionForPool(n,l),e.aibotHandle.sendUpdateBindingCard({session_id:n,worker_status:"ready",cwd:l,meta:e.buildCursorToolbarMeta(n)}),a("ok",{outcome:"opened",binding:e.buildOpenedBindingResult(n,l)});return}}catch{t=!0,u.info("bridge",`Stale cursor binding for session ${n}: ${r.cwd} no longer exists, allowing rebind`)}if(!t){a("failed",void 0,g.rebindForbidden,`Session already bound to ${r.cwd}`);return}}e.bindingStore.set(n,i),e.setResolvedAgentSessionId(n,c),e.sessionBindings.set(n,i),e.deferredMgr.sendCursorDeferredReplayComposing(n,e.deferredCallbacks()),await e.bindSessionForPool(n,i),await e.deferredMgr.release(n,e.deferredCallbacks(),{announceComposing:!1}),e.aibotHandle.sendUpdateBindingCard({session_id:n,worker_status:"ready",cwd:i,meta:e.buildCursorToolbarMeta(n)}),a("ok",{outcome:"opened",binding:e.buildOpenedBindingResult(n,i)})}catch(i){e.failSessionOpen(i,{sessionId:n,eventId:s.action_id,cwd:e.bindingStore.get(n)?.cwd||o,send:(r,t)=>a("failed",void 0,r,t)})}}async function P(e,s,d){const n=d.session_id,o=s.args.trim(),c=()=>e.aibotHandle.sendEventAck({event_id:d.event_id,session_id:n,received_at:Date.now()}),a=(i,r)=>e.aibotHandle.sendEventResult({event_id:d.event_id,status:i,...r,updated_at:Date.now()});if(!o){c(),a("failed",{msg:"Usage: /grix open <working-directory>",code:g.cwdRequired});return}try{const i=await e.resolveCwdForBinding(o),r=e.bindingStore.get(n);if(r?.cwd){let t=!1;try{const l=await e.resolveCwdForBinding(r.cwd);if(l===i){e.sessionBindings.set(n,l),await e.ensureSlotStarted(n),c(),a("responded",{msg:`Session already bound to ${r.cwd}`}),e.aibotHandle.sendMsg({event_id:d.event_id,session_id:n,msg_type:1,content:`\u2705 Session already bound to \`${r.cwd}\``,quoted_message_id:d.msg_id});return}}catch{t=!0,u.info("bridge",`Stale pi binding for session ${n}: ${r.cwd} no longer exists, allowing rebind`)}if(!t){c(),a("failed",{msg:`Session already bound to ${r.cwd}. Rebinding is not allowed.`,code:g.rebindForbidden});return}}e.bindingStore.set(n,i),e.sessionBindings.set(n,i),await e.ensureSlotStarted(n).catch(t=>{if(m(t))throw t;u.warn("bridge",`pi ensureSlotStarted on bind failed (non-fatal): ${t instanceof Error?t.message:String(t)}`)}),await e.deferredMgr.release(n,e.deferredCallbacks()),e.aibotHandle.sendUpdateBindingCard({session_id:n,worker_status:"ready",cwd:i}),c(),a("responded",{msg:`Session bound to ${i}`}),e.aibotHandle.sendMsg({event_id:d.event_id,session_id:n,msg_type:1,content:`\u2705 Working directory bound: \`${i}\``,quoted_message_id:d.msg_id})}catch(i){c(),e.failSessionOpen(i,{sessionId:n,eventId:d.event_id,quotedMessageId:d.msg_id,cwd:e.bindingStore.get(n)?.cwd||o,send:(r,t)=>a("failed",{code:r,msg:t})})}}async function D(e,s){const d=s.session_id,n=()=>e.aibotHandle.sendEventAck({event_id:s.event_id,session_id:d,received_at:Date.now()}),o=(i,r)=>e.aibotHandle.sendEventResult({event_id:s.event_id,status:i,...r,updated_at:Date.now()}),a=e.bindingStore.get(d)?.cwd??"";if(!a){n(),o("failed",{msg:"session binding was not found",code:g.bindingMissing});return}n(),await e.pool.removeSlot(d).catch(()=>{}),e.aibotHandle.sendUpdateBindingCard({session_id:d,worker_status:"ready",cwd:a}),o("responded",{msg:`Session worker restarted for ${a}`})}async function L(e,s){const d=s.params??{},n=String(d.session_id??"").trim(),c=(n?e.bindingStore.get(n):void 0)?.cwd??"",a=(i,r,t,l)=>{e.aibotHandle.sendLocalActionResult({action_id:s.action_id,status:i,...r!==void 0?{result:r}:{},...t?{error_code:t}:{},...l?{error_msg:l}:{}})};if(!n){a("failed",void 0,"session_id_required","session_id is required for restart");return}if(!c){a("failed",void 0,g.bindingMissing,"Session binding missing. Open a workspace first.");return}await e.pool.removeSlot(n).catch(()=>{}),e.aibotHandle.sendUpdateBindingCard({session_id:n,worker_status:"ready",cwd:c}),a("ok",{outcome:"restarted",binding:{aibotSessionId:n,cwd:c,workerStatus:"ready"}})}async function T(e,s,d){if(!s||!d)return;try{e.resolveSessionModelId(s),e.resolveSessionModeId(s)}catch(o){u.warn(e.name,`[opencode] resolve global toolbar default failed: ${o instanceof Error?o.message:String(o)}`)}let n=e.pool.getSlot(s);n?.stopping&&(await e.pool.waitForSlotRemoval(s),n=e.pool.getSlot(s)),!n&&(e.config.adapterType??"acp")==="opencode"&&(await e.ensureSlotStarted(s),n=e.pool.getSlot(s)),n?.startPromise&&await n.startPromise,n?.adapter instanceof _&&await n.adapter.bindSession(s,d)}function q(e){const s=String(e.config.agent.clientType??e.config.aibot.clientType??"").trim().toLowerCase();return C.has(s)}async function U(e,s,d){if(!s||!e.isWorkspaceFreeClient()||e.bindingStore.get(s)?.cwd)return;let n;try{n=await e.resolveCwdForBinding(w())}catch(o){u.warn(e.name,`[${d}] default cwd unavailable, falling back to binding prompt session=${s}: ${o instanceof Error?o.message:String(o)}`);return}e.bindingStore.set(s,n),e.sessionBindings.set(s,n),u.info(e.name,`[${d}] auto-bound workspace-free client session=${s} cwd=${n}`)}async function N(e,s,d){const n=String(d??"").trim();if(!s||!n)return;const o=await e.pool.getOrCreateSlot(s);if(!o||(o.startPromise&&await o.startPromise,!o.adapter))return;const c=o.adapter instanceof S?o.adapter:null;if(!c?.hasSessionBinding)return;const a=await e.resolveCwdForBinding(n);c.announceDeferredComposing(s),await c.bindSession(s,a),e.sessionBindings.set(s,a),e.sessionScanCache.invalidate(),c.replayDeferredEvents(s),e.forceRefreshSkills(s)}function W(e){return{captureEventRuntimeConfig:s=>e.captureEventRuntimeConfig(s),deliverInboundEvent:async s=>{await e.pool.deliverInboundEvent(s)},sendEventResult:(s,d,n)=>{e.sendEventResultWithCleanup(s,d,n),e.pendingEvents.remove(s).catch(o=>{u.warn(e.name,`Failed to remove terminal deferred event from pending store event=${s}: ${o instanceof Error?o.message:String(o)}`)})},sendSessionComposing:(s,d,n)=>{const o={};d&&(o.ttl_ms=n?.ttlMs??3e4,n?.activity&&(o.activity=n.activity)),e.aibotHandle.sendSessionActivitySet({session_id:s,kind:"composing",active:d,...o})}}}async function Y(e,s,d){const n=()=>e.aibotHandle.sendEventAck({event_id:d.event_id,session_id:d.session_id,received_at:Date.now()});try{const o=await e.resolveCwdForBinding(s.args.trim());await e.handleSessionControlForPool(s,d),await e.syncOpenCodeBinding(d.session_id,o),p(s,d,e.sessionControlCtx(d.session_id),e.sessionControlSenders(d.session_id)),await e.deferredMgr.release(d.session_id,e.deferredCallbacks())}catch(o){n(),e.failSessionOpen(o,{sessionId:d.session_id,eventId:d.event_id,quotedMessageId:d.msg_id,cwd:e.bindingStore.get(d.session_id)?.cwd||s.args.trim(),send:(c,a)=>e.aibotHandle.sendEventResult({event_id:d.event_id,status:"failed",code:c,msg:a,updated_at:Date.now()})})}}async function K(e,s,d){const n=d.session_id,o=s.args.trim(),c=()=>e.aibotHandle.sendEventAck({event_id:d.event_id,session_id:n,received_at:Date.now()}),a=(i,r)=>e.aibotHandle.sendEventResult({event_id:d.event_id,status:i,...r,updated_at:Date.now()});if(!o){c(),a("failed",{msg:"Usage: /grix open <working-directory>",code:g.cwdRequired});return}try{const i=await e.resolveCwdForBinding(o),r=e.bindingStore.get(n);if(r?.cwd){if(await e.resolveCwdForBinding(r.cwd)!==i){c(),a("failed",{msg:`Session already bound to ${r.cwd}. Rebinding is not allowed.`,code:g.rebindForbidden});return}c(),a("responded",{msg:`Session already bound to ${r.cwd}`});return}e.bindingStore.set(n,i),e.sessionBindings.set(n,i),await e.bindSessionForPool(n,i),await e.deferredMgr.release(n,e.deferredCallbacks(),{announceComposing:!1}),e.aibotHandle.sendUpdateBindingCard({session_id:n,worker_status:"ready",cwd:i}),c(),a("responded",{msg:`Session bound to ${i}`})}catch(i){c(),e.failSessionOpen(i,{sessionId:n,eventId:d.event_id,quotedMessageId:d.msg_id,cwd:e.bindingStore.get(n)?.cwd||o,send:(r,t)=>a("failed",{code:r,msg:t})})}}async function V(e,s){const d=s.params??{},n=String(d.session_id??"").trim(),o=String(d.cwd??"").trim(),c=String(d.agent_session_id??"").trim(),a=(i,r,t,l)=>{e.aibotHandle.sendLocalActionResult({action_id:s.action_id,status:i,...r!==void 0?{result:r}:{},...t?{error_code:t}:{},...l?{error_msg:l}:{}})};if(!n||!o){a("failed",void 0,g.cwdRequired,"session cwd is required");return}try{const i=await e.resolveCwdForBinding(o);e.ensureImportedAgentSession(c,i);const r=e.bindingStore.get(n);if(r?.cwd){const t=await e.resolveCwdForBinding(r.cwd);if(t!==i){a("failed",void 0,g.rebindForbidden,`Session already bound to ${r.cwd}`);return}e.setResolvedAgentSessionId(n,c),a("ok",{outcome:"opened",binding:e.buildOpenedBindingResult(n,t)});return}e.bindingStore.set(n,i),e.setResolvedAgentSessionId(n,c),e.sessionBindings.set(n,i),await e.bindSessionForPool(n,i),await e.deferredMgr.release(n,e.deferredCallbacks(),{announceComposing:!1}),e.aibotHandle.sendUpdateBindingCard({session_id:n,worker_status:"ready",cwd:i}),a("ok",{outcome:"opened",binding:e.buildOpenedBindingResult(n,i)})}catch(i){e.failSessionOpen(i,{sessionId:n,eventId:s.action_id,cwd:e.bindingStore.get(n)?.cwd||o,send:(r,t)=>a("failed",void 0,r,t)})}}async function j(e,s){const d=s.params??{},n=String(d.session_id??"").trim(),o=String(d.cwd??"").trim(),c=String(d.agent_session_id??"").trim(),a=(i,r,t,l)=>{e.aibotHandle.sendLocalActionResult({action_id:s.action_id,status:i,...r!==void 0?{result:r}:{},...t?{error_code:t}:{},...l?{error_msg:l}:{}})};if(!n||!o){a("failed",void 0,g.cwdRequired,"session cwd is required");return}try{const i=await e.resolveCwdForBinding(o);e.ensureImportedAgentSession(c,i);const r=e.bindingStore.get(n);if(r?.cwd){const t=await e.resolveCwdForBinding(r.cwd);if(t!==i){a("failed",void 0,g.rebindForbidden,`Session already bound to ${r.cwd}`);return}e.setResolvedAgentSessionId(n,c),e.sessionBindings.set(n,t),await e.deferredMgr.release(n,e.deferredCallbacks()),e.aibotHandle.sendUpdateBindingCard({session_id:n,worker_status:"ready",cwd:t,meta:e.buildDshOpenedToolbarMeta(n)}),a("ok",{outcome:"opened",binding:e.buildOpenedBindingResult(n,t)});return}e.bindingStore.set(n,i),e.setResolvedAgentSessionId(n,c),e.sessionBindings.set(n,i),await e.deferredMgr.release(n,e.deferredCallbacks()),e.aibotHandle.sendUpdateBindingCard({session_id:n,worker_status:"ready",cwd:i,meta:e.buildDshOpenedToolbarMeta(n)}),a("ok",{outcome:"opened",binding:e.buildOpenedBindingResult(n,i)})}catch(i){e.failSessionOpen(i,{sessionId:n,eventId:s.action_id,cwd:e.bindingStore.get(n)?.cwd||o,send:(r,t)=>a("failed",void 0,r,t)})}}export{A as SESSION_CONTROL_OPEN_HOST_FIELDS,E as SESSION_CONTROL_OPEN_HOST_METHODS,N as bindSessionForPool,W as deferredCallbacks,U as ensureDefaultBindingForWorkspaceFreeClient,V as handleCodeWhaleSessionControlLocalActionOpen,K as handleCodeWhaleSessionControlOpen,H as handleCodexSessionControlLocalActionOpen,y as handleCodexSessionControlOpen,M as handleCursorSessionControlLocalActionOpen,j as handleDeepSeekSessionControlLocalActionOpen,Y as handleOpenHumanSessionControlOpen,P as handlePiSessionControlOpen,D as handlePiSessionControlRestart,L as handlePiSessionControlRestartLocalAction,I as handleSessionControlForPool,$ as handleSessionControlLocalActionForPool,q as isWorkspaceFreeClient,T as syncOpenCodeBinding};
|
|
1
|
+
import{homedir as f}from"node:os";import{LOCAL_ACTION_TYPES as S,SESSION_CONTROL_ERROR_CODES as g,SESSION_CONTROL_VERBS as w}from"../adapter/claude/protocol-contract.js";import{AcpAdapter as _}from"../adapter/acp/index.js";import{OpenCodeAdapter as C}from"../adapter/opencode/index.js";import{handleSessionControlCommand as m}from"./session-controller.js";import{isCliMissingError as p}from"./cli-install-offer.js";import{isCwdLockedClientType as v,isWorkspaceFreeClientType as R,resolveStaticCwd as k}from"./cwd-policy.js";import{log as u}from"../core/log/index.js";const H=["buildCursorToolbarMeta","buildDshOpenedToolbarMeta","buildOpenedBindingResult","captureEventRuntimeConfig","ensureImportedAgentSession","ensureSlotStarted","failSessionOpen","forceRefreshSkills","resolveCwdForBinding","resolveSessionModeId","resolveSessionModelId","sendEventResultWithCleanup","sessionControlCtx","sessionControlSenders","setResolvedAgentSessionId","bindSessionForPool","deferredCallbacks","handleSessionControlForPool","isWorkspaceFreeClient","isCwdLockedClient","syncOpenCodeBinding"],M=["name","config","aibotHandle","pool","bindingStore","sessionBindings","sessionScanCache","pendingEvents","deferredMgr"];async function I(e,s,d){const n=d.session_id,t=s.args.trim(),c=()=>e.aibotHandle.sendEventAck({event_id:d.event_id,session_id:n,received_at:Date.now()}),o=(i,r)=>e.aibotHandle.sendEventResult({event_id:d.event_id,status:i,...r,updated_at:Date.now()});if(!t){c(),o("failed",{msg:"Usage: /grix open <working-directory>",code:g.cwdRequired});return}try{const i=await e.resolveCwdForBinding(t),r=e.bindingStore.get(n);if(r?.cwd){let a=!1;try{const l=await e.resolveCwdForBinding(r.cwd);if(l===i){c(),e.sessionBindings.set(n,l),e.deferredMgr.sendCodexDeferredReplayComposing(n,e.deferredCallbacks()),await e.bindSessionForPool(n,l),await e.deferredMgr.release(n,e.deferredCallbacks(),{announceComposing:!1}),o("responded",{msg:`Session already bound to ${r.cwd}`});return}}catch{a=!0,u.info("bridge",`Stale codex binding for session ${n}: ${r.cwd} no longer exists, allowing rebind`)}if(!a){c(),o("failed",{msg:`Session already bound to ${r.cwd}. Rebinding is not allowed.`,code:g.rebindForbidden});return}}e.bindingStore.set(n,i),e.sessionBindings.set(n,i),e.deferredMgr.sendCodexDeferredReplayComposing(n,e.deferredCallbacks()),await e.bindSessionForPool(n,i),await e.deferredMgr.release(n,e.deferredCallbacks(),{announceComposing:!1}),e.aibotHandle.sendUpdateBindingCard({session_id:n,worker_status:"ready",cwd:i}),c(),o("responded",{msg:`Session bound to ${i}`})}catch(i){c(),e.failSessionOpen(i,{sessionId:n,eventId:d.event_id,quotedMessageId:d.msg_id,cwd:e.bindingStore.get(n)?.cwd||t,send:(r,a)=>o("failed",{code:r,msg:a})})}}async function P(e,s,d){s.verb===w.open&&await e.bindSessionForPool(d.session_id,s.args.trim())}async function D(e,s){if(String(s.action_type??"")!==S.sessionControl)return;const d=s.params??{};if(String(d.verb??"").trim().toLowerCase()!==w.open)return;const t=String(d.session_id??"").trim(),c=String(d.cwd??"").trim();!t||!c||await e.bindSessionForPool(t,c)}async function L(e,s){const d=s.params??{},n=String(d.session_id??"").trim(),t=String(d.cwd??"").trim(),c=String(d.agent_session_id??"").trim(),o=(i,r,a,l)=>{e.aibotHandle.sendLocalActionResult({action_id:s.action_id,status:i,...r!==void 0?{result:r}:{},...a?{error_code:a}:{},...l?{error_msg:l}:{}})};if(!n||!t){o("failed",void 0,g.cwdRequired,"session cwd is required");return}try{const i=await e.resolveCwdForBinding(t);e.ensureImportedAgentSession(c,i);const r=e.bindingStore.get(n);if(r?.cwd){let a=!1;try{const l=await e.resolveCwdForBinding(r.cwd);if(l===i){e.setResolvedAgentSessionId(n,c),e.sessionBindings.set(n,l),e.deferredMgr.sendCodexDeferredReplayComposing(n,e.deferredCallbacks()),await e.bindSessionForPool(n,l),await e.deferredMgr.release(n,e.deferredCallbacks(),{announceComposing:!1}),o("ok",{outcome:"opened",binding:e.buildOpenedBindingResult(n,l)});return}}catch{a=!0,u.info("bridge",`Stale codex binding for session ${n}: ${r.cwd} no longer exists, allowing rebind`)}if(!a){o("failed",void 0,g.rebindForbidden,`Session already bound to ${r.cwd}`);return}}e.bindingStore.set(n,i),e.setResolvedAgentSessionId(n,c),e.sessionBindings.set(n,i),e.deferredMgr.sendCodexDeferredReplayComposing(n,e.deferredCallbacks()),await e.bindSessionForPool(n,i),await e.deferredMgr.release(n,e.deferredCallbacks(),{announceComposing:!1}),o("ok",{outcome:"opened",binding:e.buildOpenedBindingResult(n,i)})}catch(i){e.failSessionOpen(i,{sessionId:n,eventId:s.action_id,cwd:e.bindingStore.get(n)?.cwd||t,send:(r,a)=>o("failed",void 0,r,a)})}}async function q(e,s){const d=s.params??{},n=String(d.session_id??"").trim(),t=String(d.cwd??"").trim(),c=String(d.agent_session_id??"").trim(),o=(i,r,a,l)=>{e.aibotHandle.sendLocalActionResult({action_id:s.action_id,status:i,...r!==void 0?{result:r}:{},...a?{error_code:a}:{},...l?{error_msg:l}:{}})};if(!n||!t){o("failed",void 0,g.cwdRequired,"session cwd is required");return}try{const i=await e.resolveCwdForBinding(t);e.ensureImportedAgentSession(c,i);const r=e.bindingStore.get(n);if(r?.cwd){let a=!1;try{const l=await e.resolveCwdForBinding(r.cwd);if(l===i){e.setResolvedAgentSessionId(n,c),e.sessionBindings.set(n,l),await e.bindSessionForPool(n,l),e.aibotHandle.sendUpdateBindingCard({session_id:n,worker_status:"ready",cwd:l,meta:e.buildCursorToolbarMeta(n)}),o("ok",{outcome:"opened",binding:e.buildOpenedBindingResult(n,l)});return}}catch{a=!0,u.info("bridge",`Stale cursor binding for session ${n}: ${r.cwd} no longer exists, allowing rebind`)}if(!a){o("failed",void 0,g.rebindForbidden,`Session already bound to ${r.cwd}`);return}}e.bindingStore.set(n,i),e.setResolvedAgentSessionId(n,c),e.sessionBindings.set(n,i),e.deferredMgr.sendCursorDeferredReplayComposing(n,e.deferredCallbacks()),await e.bindSessionForPool(n,i),await e.deferredMgr.release(n,e.deferredCallbacks(),{announceComposing:!1}),e.aibotHandle.sendUpdateBindingCard({session_id:n,worker_status:"ready",cwd:i,meta:e.buildCursorToolbarMeta(n)}),o("ok",{outcome:"opened",binding:e.buildOpenedBindingResult(n,i)})}catch(i){e.failSessionOpen(i,{sessionId:n,eventId:s.action_id,cwd:e.bindingStore.get(n)?.cwd||t,send:(r,a)=>o("failed",void 0,r,a)})}}async function T(e,s,d){const n=d.session_id,t=s.args.trim(),c=()=>e.aibotHandle.sendEventAck({event_id:d.event_id,session_id:n,received_at:Date.now()}),o=(i,r)=>e.aibotHandle.sendEventResult({event_id:d.event_id,status:i,...r,updated_at:Date.now()});if(!t){c(),o("failed",{msg:"Usage: /grix open <working-directory>",code:g.cwdRequired});return}try{const i=await e.resolveCwdForBinding(t),r=e.bindingStore.get(n);if(r?.cwd){let a=!1;try{const l=await e.resolveCwdForBinding(r.cwd);if(l===i){e.sessionBindings.set(n,l),await e.ensureSlotStarted(n),c(),o("responded",{msg:`Session already bound to ${r.cwd}`}),e.aibotHandle.sendMsg({event_id:d.event_id,session_id:n,msg_type:1,content:`\u2705 Session already bound to \`${r.cwd}\``,quoted_message_id:d.msg_id});return}}catch{a=!0,u.info("bridge",`Stale pi binding for session ${n}: ${r.cwd} no longer exists, allowing rebind`)}if(!a){c(),o("failed",{msg:`Session already bound to ${r.cwd}. Rebinding is not allowed.`,code:g.rebindForbidden});return}}e.bindingStore.set(n,i),e.sessionBindings.set(n,i),await e.ensureSlotStarted(n).catch(a=>{if(p(a))throw a;u.warn("bridge",`pi ensureSlotStarted on bind failed (non-fatal): ${a instanceof Error?a.message:String(a)}`)}),await e.deferredMgr.release(n,e.deferredCallbacks()),e.aibotHandle.sendUpdateBindingCard({session_id:n,worker_status:"ready",cwd:i}),c(),o("responded",{msg:`Session bound to ${i}`}),e.aibotHandle.sendMsg({event_id:d.event_id,session_id:n,msg_type:1,content:`\u2705 Working directory bound: \`${i}\``,quoted_message_id:d.msg_id})}catch(i){c(),e.failSessionOpen(i,{sessionId:n,eventId:d.event_id,quotedMessageId:d.msg_id,cwd:e.bindingStore.get(n)?.cwd||t,send:(r,a)=>o("failed",{code:r,msg:a})})}}async function U(e,s){const d=s.session_id,n=()=>e.aibotHandle.sendEventAck({event_id:s.event_id,session_id:d,received_at:Date.now()}),t=(i,r)=>e.aibotHandle.sendEventResult({event_id:s.event_id,status:i,...r,updated_at:Date.now()}),o=e.bindingStore.get(d)?.cwd??"";if(!o){n(),t("failed",{msg:"session binding was not found",code:g.bindingMissing});return}n(),await e.pool.removeSlot(d).catch(()=>{}),e.aibotHandle.sendUpdateBindingCard({session_id:d,worker_status:"ready",cwd:o}),t("responded",{msg:`Session worker restarted for ${o}`})}async function N(e,s){const d=s.params??{},n=String(d.session_id??"").trim(),c=(n?e.bindingStore.get(n):void 0)?.cwd??"",o=(i,r,a,l)=>{e.aibotHandle.sendLocalActionResult({action_id:s.action_id,status:i,...r!==void 0?{result:r}:{},...a?{error_code:a}:{},...l?{error_msg:l}:{}})};if(!n){o("failed",void 0,"session_id_required","session_id is required for restart");return}if(!c){o("failed",void 0,g.bindingMissing,"Session binding missing. Open a workspace first.");return}await e.pool.removeSlot(n).catch(()=>{}),e.aibotHandle.sendUpdateBindingCard({session_id:n,worker_status:"ready",cwd:c}),o("ok",{outcome:"restarted",binding:{aibotSessionId:n,cwd:c,workerStatus:"ready"}})}async function W(e,s,d){if(!s||!d)return;try{e.resolveSessionModelId(s),e.resolveSessionModeId(s)}catch(t){u.warn(e.name,`[opencode] resolve global toolbar default failed: ${t instanceof Error?t.message:String(t)}`)}let n=e.pool.getSlot(s);n?.stopping&&(await e.pool.waitForSlotRemoval(s),n=e.pool.getSlot(s)),!n&&(e.config.adapterType??"acp")==="opencode"&&(await e.ensureSlotStarted(s),n=e.pool.getSlot(s)),n?.startPromise&&await n.startPromise,n?.adapter instanceof C&&await n.adapter.bindSession(s,d)}function b(e){return String(e.config.agent.clientType??e.config.aibot.clientType??"")}function V(e){return R(b(e))}function Y(e){return v(b(e))}async function j(e,s,d){if(!s||!e.isWorkspaceFreeClient())return;const n=e.isCwdLockedClient(),t=e.bindingStore.get(s)?.cwd;if(t&&!n)return;const c=n?k(e.config.staticCwd):f();let o;try{o=await e.resolveCwdForBinding(c)}catch(i){const r=i instanceof Error?i.message:String(i);if(n&&c!==f()){u.error(e.name,`[${d}] configured cwd unusable (${c}): ${r}; falling back to the home directory`);try{o=await e.resolveCwdForBinding(f())}catch(a){u.warn(e.name,`[${d}] default cwd unavailable, falling back to binding prompt session=${s}: ${a instanceof Error?a.message:String(a)}`);return}}else{u.warn(e.name,`[${d}] default cwd unavailable, falling back to binding prompt session=${s}: ${r}`);return}}t!==o&&(e.bindingStore.set(s,o),e.sessionBindings.set(s,o),u.info(e.name,`[${d}] auto-bound workspace-free client session=${s} cwd=${o}`))}async function z(e,s,d){const n=String(d??"").trim();if(!s||!n)return;const t=await e.pool.getOrCreateSlot(s);if(!t||(t.startPromise&&await t.startPromise,!t.adapter))return;const c=t.adapter instanceof _?t.adapter:null;if(!c?.hasSessionBinding)return;const o=await e.resolveCwdForBinding(n);c.announceDeferredComposing(s),await c.bindSession(s,o),e.sessionBindings.set(s,o),e.sessionScanCache.invalidate(),c.replayDeferredEvents(s),e.forceRefreshSkills(s)}function G(e){return{captureEventRuntimeConfig:s=>e.captureEventRuntimeConfig(s),deliverInboundEvent:async s=>{await e.pool.deliverInboundEvent(s)},sendEventResult:(s,d,n)=>{e.sendEventResultWithCleanup(s,d,n),e.pendingEvents.remove(s).catch(t=>{u.warn(e.name,`Failed to remove terminal deferred event from pending store event=${s}: ${t instanceof Error?t.message:String(t)}`)})},sendSessionComposing:(s,d,n)=>{const t={};d&&(t.ttl_ms=n?.ttlMs??3e4,n?.activity&&(t.activity=n.activity)),e.aibotHandle.sendSessionActivitySet({session_id:s,kind:"composing",active:d,...t})}}}async function J(e,s,d){const n=()=>e.aibotHandle.sendEventAck({event_id:d.event_id,session_id:d.session_id,received_at:Date.now()});try{const t=await e.resolveCwdForBinding(s.args.trim());await e.handleSessionControlForPool(s,d),await e.syncOpenCodeBinding(d.session_id,t),m(s,d,e.sessionControlCtx(d.session_id),e.sessionControlSenders(d.session_id)),await e.deferredMgr.release(d.session_id,e.deferredCallbacks())}catch(t){n(),e.failSessionOpen(t,{sessionId:d.session_id,eventId:d.event_id,quotedMessageId:d.msg_id,cwd:e.bindingStore.get(d.session_id)?.cwd||s.args.trim(),send:(c,o)=>e.aibotHandle.sendEventResult({event_id:d.event_id,status:"failed",code:c,msg:o,updated_at:Date.now()})})}}async function K(e,s,d){const n=d.session_id,t=s.args.trim(),c=()=>e.aibotHandle.sendEventAck({event_id:d.event_id,session_id:n,received_at:Date.now()}),o=(i,r)=>e.aibotHandle.sendEventResult({event_id:d.event_id,status:i,...r,updated_at:Date.now()});if(!t){c(),o("failed",{msg:"Usage: /grix open <working-directory>",code:g.cwdRequired});return}try{const i=await e.resolveCwdForBinding(t),r=e.bindingStore.get(n);if(r?.cwd){if(await e.resolveCwdForBinding(r.cwd)!==i){c(),o("failed",{msg:`Session already bound to ${r.cwd}. Rebinding is not allowed.`,code:g.rebindForbidden});return}c(),o("responded",{msg:`Session already bound to ${r.cwd}`});return}e.bindingStore.set(n,i),e.sessionBindings.set(n,i),await e.bindSessionForPool(n,i),await e.deferredMgr.release(n,e.deferredCallbacks(),{announceComposing:!1}),e.aibotHandle.sendUpdateBindingCard({session_id:n,worker_status:"ready",cwd:i}),c(),o("responded",{msg:`Session bound to ${i}`})}catch(i){c(),e.failSessionOpen(i,{sessionId:n,eventId:d.event_id,quotedMessageId:d.msg_id,cwd:e.bindingStore.get(n)?.cwd||t,send:(r,a)=>o("failed",{code:r,msg:a})})}}async function Q(e,s){const d=s.params??{},n=String(d.session_id??"").trim(),t=String(d.cwd??"").trim(),c=String(d.agent_session_id??"").trim(),o=(i,r,a,l)=>{e.aibotHandle.sendLocalActionResult({action_id:s.action_id,status:i,...r!==void 0?{result:r}:{},...a?{error_code:a}:{},...l?{error_msg:l}:{}})};if(!n||!t){o("failed",void 0,g.cwdRequired,"session cwd is required");return}try{const i=await e.resolveCwdForBinding(t);e.ensureImportedAgentSession(c,i);const r=e.bindingStore.get(n);if(r?.cwd){const a=await e.resolveCwdForBinding(r.cwd);if(a!==i){o("failed",void 0,g.rebindForbidden,`Session already bound to ${r.cwd}`);return}e.setResolvedAgentSessionId(n,c),o("ok",{outcome:"opened",binding:e.buildOpenedBindingResult(n,a)});return}e.bindingStore.set(n,i),e.setResolvedAgentSessionId(n,c),e.sessionBindings.set(n,i),await e.bindSessionForPool(n,i),await e.deferredMgr.release(n,e.deferredCallbacks(),{announceComposing:!1}),e.aibotHandle.sendUpdateBindingCard({session_id:n,worker_status:"ready",cwd:i}),o("ok",{outcome:"opened",binding:e.buildOpenedBindingResult(n,i)})}catch(i){e.failSessionOpen(i,{sessionId:n,eventId:s.action_id,cwd:e.bindingStore.get(n)?.cwd||t,send:(r,a)=>o("failed",void 0,r,a)})}}async function X(e,s){const d=s.params??{},n=String(d.session_id??"").trim(),t=String(d.cwd??"").trim(),c=String(d.agent_session_id??"").trim(),o=(i,r,a,l)=>{e.aibotHandle.sendLocalActionResult({action_id:s.action_id,status:i,...r!==void 0?{result:r}:{},...a?{error_code:a}:{},...l?{error_msg:l}:{}})};if(!n||!t){o("failed",void 0,g.cwdRequired,"session cwd is required");return}try{const i=await e.resolveCwdForBinding(t);e.ensureImportedAgentSession(c,i);const r=e.bindingStore.get(n);if(r?.cwd){const a=await e.resolveCwdForBinding(r.cwd);if(a!==i){o("failed",void 0,g.rebindForbidden,`Session already bound to ${r.cwd}`);return}e.setResolvedAgentSessionId(n,c),e.sessionBindings.set(n,a),await e.deferredMgr.release(n,e.deferredCallbacks()),e.aibotHandle.sendUpdateBindingCard({session_id:n,worker_status:"ready",cwd:a,meta:e.buildDshOpenedToolbarMeta(n)}),o("ok",{outcome:"opened",binding:e.buildOpenedBindingResult(n,a)});return}e.bindingStore.set(n,i),e.setResolvedAgentSessionId(n,c),e.sessionBindings.set(n,i),await e.deferredMgr.release(n,e.deferredCallbacks()),e.aibotHandle.sendUpdateBindingCard({session_id:n,worker_status:"ready",cwd:i,meta:e.buildDshOpenedToolbarMeta(n)}),o("ok",{outcome:"opened",binding:e.buildOpenedBindingResult(n,i)})}catch(i){e.failSessionOpen(i,{sessionId:n,eventId:s.action_id,cwd:e.bindingStore.get(n)?.cwd||t,send:(r,a)=>o("failed",void 0,r,a)})}}export{M as SESSION_CONTROL_OPEN_HOST_FIELDS,H as SESSION_CONTROL_OPEN_HOST_METHODS,z as bindSessionForPool,G as deferredCallbacks,j as ensureDefaultBindingForWorkspaceFreeClient,Q as handleCodeWhaleSessionControlLocalActionOpen,K as handleCodeWhaleSessionControlOpen,L as handleCodexSessionControlLocalActionOpen,I as handleCodexSessionControlOpen,q as handleCursorSessionControlLocalActionOpen,X as handleDeepSeekSessionControlLocalActionOpen,J as handleOpenHumanSessionControlOpen,T as handlePiSessionControlOpen,U as handlePiSessionControlRestart,N as handlePiSessionControlRestartLocalAction,P as handleSessionControlForPool,D as handleSessionControlLocalActionForPool,Y as isCwdLockedClient,V as isWorkspaceFreeClient,W as syncOpenCodeBinding};
|