grix-connector 4.12.2 → 4.13.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.
Files changed (33) hide show
  1. package/dist/adapter/agy/agy-adapter.js +12 -12
  2. package/dist/adapter/agy/stream-parser.js +2 -0
  3. package/dist/adapter/codex/codex-bridge.js +10 -10
  4. package/dist/assets/dsh-bridge/grix-dsh-bridge-4.13.0.tgz +0 -0
  5. package/dist/assets/dsh-bridge/manifest.json +5 -5
  6. package/dist/bridge/bridge.js +2 -2
  7. package/dist/bridge/tool-card-utils.js +1 -1
  8. package/dist/core/config/claude-direct-env.js +1 -1
  9. package/dist/core/proxy/index.js +1 -1
  10. package/dist/default-skills/grix-access-control/SKILL.md +1 -1
  11. package/dist/default-skills/grix-admin/SKILL.md +1 -1
  12. package/dist/default-skills/grix-agent-dispatch/SKILL.md +1 -1
  13. package/dist/default-skills/grix-audit-data/SKILL.md +1 -1
  14. package/dist/default-skills/grix-chat-state/SKILL.md +1 -1
  15. package/dist/default-skills/grix-egg/SKILL.md +1 -1
  16. package/dist/default-skills/grix-group/SKILL.md +1 -1
  17. package/dist/default-skills/grix-owner-relay/SKILL.md +1 -1
  18. package/dist/default-skills/grix-query/SKILL.md +1 -1
  19. package/dist/default-skills/grix-scheduled-trigger/SKILL.md +1 -1
  20. package/dist/default-skills/grix-skill-library/SKILL.md +1 -1
  21. package/dist/default-skills/grix-task-flow/SKILL.md +12 -524
  22. package/dist/default-skills/grix-task-flow/references/planning-and-flowcharts.md +173 -0
  23. package/dist/default-skills/grix-task-flow/references/receipts-and-watchdogs.md +171 -0
  24. package/dist/default-skills/grix-task-flow/references/recursion-and-examples.md +192 -0
  25. package/dist/default-skills/grix-widget-visitor-ban/SKILL.md +1 -1
  26. package/dist/default-skills/index.js +1 -1
  27. package/dist/default-skills/message-edit/SKILL.md +1 -1
  28. package/dist/default-skills/message-send/SKILL.md +1 -1
  29. package/dist/default-skills/message-unsend/SKILL.md +1 -1
  30. package/dist/default-skills/tailnet-file-share/SKILL.md +1 -1
  31. package/dist/mcp/stream-http/security.js +1 -1
  32. package/package.json +1 -1
  33. package/dist/assets/dsh-bridge/grix-dsh-bridge-4.12.2.tgz +0 -0
@@ -1,3 +1,3 @@
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 c=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 l=await Promise.race([c.then(()=>!1),new Promise(u=>{d=setTimeout(()=>u(!0),n)})]);return d&&clearTimeout(d),a&&e.removeListener("eventDone",a),l?{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(c=>{h.warn(this.name,`Failed to remove running event from pending store event=${t}: ${c instanceof Error?c.message:String(c)}`)})),o==="canceled"||o==="failed"){const c=o==="canceled"?"canceled":"failed";this.aibotHandle.sendEventResult({event_id:t,status:c,msg:a?.reason,updated_at:Date.now()}),this.auditController.closeWithoutAdapter(t,c,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 c=this.buildAgyToolbarMeta(s),d=c?.available_models??[];h.info(this.name,`[agy-toolbar-diag] eventDone push binding card session=${s} model_id=${String(c?.model_id??"")} available_models=${d.length} meta_keys=${c?Object.keys(c).join(","):"<none>"}`),this.sendAgyBindingCard(s,a.cwd,c),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),c=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!==c)&&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),c=a?this.pool?.getSlot(a):void 0;this.auditController.markAdapterClosed(o,c?.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,c,d,l)=>{this.sendStreamChunkByRuntimeConfig(t,s,o,a,c,d,l)},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 c=hi(o);if(c){this.sendToolExecutionCard(t,s,c);return}this.deliverRawEventEnvelope(t,s,o,"deepseek",a)},sendLocalActionResult:(t,s,o,a,c)=>{this.aibotHandle.sendLocalActionResult({action_id:t,status:s,...o!==void 0?{result:o}:{},...a?{error_code:a}:{},...c?{error_msg:c}:{}},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,c,d,l,u,g,p)=>{this.sendStreamChunkByRuntimeConfig(a,c,d,l,u,g,p)},sendEventResult:(a,c,d)=>{this.sendEventResultWithCleanup(a,c,d)},sendEventAck:(a,c)=>{this.aibotHandle.sendEventAck({event_id:a,session_id:c,received_at:Date.now()})},sendRawEventEnvelope:(a,c,d)=>{this.deliverRawEventEnvelope(a,c,d,"cursor",this.buildCursorRawEventFallbackText(d))},sendAgentQuestionCard:(a,c,d)=>{const l=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:c,content:u,msg_type:1,extra:{card_type:"agent_question",summary_text:l}})},agentInvoke:async(a,c,d)=>this.platformInvoke(a,c,d),sendLocalActionResult:(a,c,d,l,u)=>{this.aibotHandle.sendLocalActionResult({action_id:a,status:c,...d!==void 0?{result:d}:{},...l?{error_code:l}:{},...u?{error_msg:u}:{}},e)},sendUpdateBindingCard:(a,c,d,l)=>{this.aibotHandle.sendUpdateBindingCard({session_id:a,worker_status:c,cwd:d,...l?{meta:l}:{}})},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,c)=>{this.sendReplyByRuntimeConfig(t,s,o,a,c)},sendStreamChunk:(t,s,o,a,c,d,l)=>{this.sendStreamChunkByRuntimeConfig(t,s,o,a,c,d,l)},sendMedia:(t,s,o,a,c,d,l)=>{this.aibotHandle.sendMedia({event_id:t,session_id:s,content:o,msg_type:2,quoted_message_id:c||void 0,client_msg_id:d||void 0,extra:l?{media_caption:a,...l}:{media_caption:a}})},sendEventResult:(t,s,o,a,c)=>{this.sendEventResultWithCleanup(t,s,o,a,c)},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,c)=>{this.aibotHandle.sendLocalActionResult({action_id:t,status:s,...o!==void 0?{result:o}:{},...a?{error_code:a}:{},...c?{error_msg:c}:{}},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,c)=>{if(a!=="responded"){this.sendEventResultWithCleanup(o,a,c);return}this.sendCtrl.sendFinalStreamChunkReliable(o,e,`codex_terminal_fence_${o}`,5e3,!0,!0).then(()=>this.sendEventResultWithCleanup(o,a,c),d=>{const l=`codex output acceptance fence failed: ${d instanceof Error?d.message:String(d)}`;this.sendEventResultWithCleanup(o,a==="responded"?"failed":a,a==="responded"?l:c)})},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,c)=>{this.sendThinkingByRuntimeConfig(o,a,c)},sendRunError:(o,a,c)=>{this.sendRunErrorAsChunk(o,a,c)},sendUpdateBindingCard:(o,a,c,d)=>{const l={...d??{}};if(!l.rate_limits&&this.cachedProviderQuota?.success){this.isRateLimitsCacheFresh(this.cachedProviderQuotaSampledAtMs)||this.maybeQueryProviderQuota().catch(()=>{});const u=this.providerQuotaToCodexRateLimits(this.cachedProviderQuota);u&&(l.rate_limits=u.rateLimits,l.rate_limit_primary_percent=u.primaryPercent,l.rate_limit_secondary_percent=u.secondaryPercent,l.rate_limit_primary_window_min=u.primaryWindowMin,l.rate_limit_secondary_window_min=u.secondaryWindowMin)}!l.provider_quota&&this.cachedProviderQuota?.success&&(l.provider_quota=this.cachedProviderQuota),this.aibotHandle.sendUpdateBindingCard({session_id:o,worker_status:a,cwd:c,...Object.keys(l).length>0?{meta:l}:{}})},agentInvoke:async(o,a,c)=>this.platformInvoke(o,a,c),sendLocalActionResult:(o,a,c,d,l)=>this.aibotHandle.sendLocalActionResult({action_id:o,status:a,...c!==void 0?{result:c}:{},...d?{error_code:d}:{},...l?{error_msg:l}:{}},e),sendSessionActivitySet:(o,a,c,d)=>{this.aibotHandle.sendSessionActivitySet({session_id:o,kind:a,active:c,...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 c=this.cachedRateLimitsSampledAtMs,d={rate_limits:{...o.primary.windowMinutes>0?{primary:o.primary}:{},...o.secondary.windowMinutes>0?{secondary:o.secondary}:{},sampledAt:c},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,c)=>{this.sendStreamChunkByRuntimeConfig(i,t,s,o,a,c)},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,c)=>{this.sendStreamChunkByRuntimeConfig(i,t,s,o,a,c),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,c)=>{this.sendStreamChunkByRuntimeConfig(i,t,s,o,a,c)},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,c)=>{this.sendStreamChunkByRuntimeConfig(i,t,s,o,a,c)},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,c)=>{this.sendStreamChunkByRuntimeConfig(i,t,s,o,a,c)},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,l,u,g,p,_,A)=>{this.sendStreamChunkByRuntimeConfig(d,l,u,g,p,_,A)},sendFinalStreamChunkReliable:this.reliableFinalWiring("acp",4e3),sendEventResult:(d,l,u,g,p)=>{this.sendEventResultWithCleanup(d,l,u,g,p)},sendEventAck:(d,l)=>{this.aibotHandle.sendEventAck({event_id:d,session_id:l,received_at:Date.now()})},agentInvoke:async(d,l,u)=>this.platformInvoke(d,l,u),sendLocalActionResult:(d,l,u,g,p)=>{this.aibotHandle.sendLocalActionResult({action_id:d,status:l,...u!==void 0?{result:u}:{},...g?{error_code:g}:{},...p?{error_msg:p}:{}},e)},sendRawEventEnvelope:(d,l,u)=>{this.sendAcpRawEventEnvelope(d,l,u)},sendToolUse:(d,l,u,g)=>{if(n){this.sendAcpRawEventEnvelope(d,l,{type:"tool_use",payload:{tool_name:u,tool_input:g??""}});return}this.sendToolExecutionCard(d,l,C(u,g))},sendToolResult:(d,l,u,g)=>{this.sendToolExecutionCard(d,l,b(u,g))},sendThinking:(d,l,u)=>{this.sendThinkingByRuntimeConfig(d,l,u)},sendRunError:(d,l,u)=>{this.sendRunErrorAsChunk(d,l,u)},sendAgentQuestionCard:(d,l,u)=>{this.sendGrixAgentQuestionCard(d,l,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 l=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:l,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,l)=>{d&&this.aibotHandle.sendMsg({session_id:d,msg_type:1,content:l,extra:{biz_card:{version:1,type:"agent_error",payload:{error:{name:"AuthRequired",message:l}}}}})},sendAgentMessage:(d,l)=>{d&&l&&this.aibotHandle.sendMsg({session_id:d,msg_type:1,content:l})},sendUpdateBindingCard:(d,l,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:l,cwd:u,...Object.keys(p).length>0?{meta:p}:{}})},onSkillsUpdate:(d,l)=>{try{this.aibotHandle.sendSkillsUpdate({skills:Y(d,w.skills),library_skills:this.buildLibrarySkillsReport(l)})}catch(u){}},onContextWindowUpdated:d=>{this.cachedAcpContextWindow=d,this.cachedAcpContextWindowSampledAtMs=Date.now();const l="usedPercentage"in d?d.usedPercentage.toFixed(1):(d.used/d.size*100).toFixed(1);h.info(this.name,`[acp] context_window updated: ${l}%`);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:c}=Kn({sessionBinding:i,globalDefaults:o,configInitialMode:this.config.acpInitialMode});return e&&a&&!i?.acpModelId&&this.bindingStore.setAcpModelId(e,a),e&&c&&!i?.acpModeId&&this.bindingStore.setAcpModeId(e,c),(a||c)&&h.info(this.name,`[toolbar] hydrate from binding: session=${e} model=${a??"<none>"} mode=${c??"<none>"}`),new S({command:this.config.agent.command,args:this.config.agent.args,env:this.resolveSpawnEnv()},r,{acpAuthMethod:this.config.acpAuthMethod,acpInitialMode:c,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:"",c=typeof i.ttl_ms=="number"?i.ttl_ms:void 0,d=this.pool.holdEvent(t,s,o,a,c),l=d==="ok";this.aibotHandle.sendEventHoldResult({session_id:t,event_id:s,ok:l,held:l?o:!1,...l?{}:{error:d}}),l&&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),c=a==="ok";this.aibotHandle.sendQueueEditResult({session_id:t,event_id:s,ok:c,...c?{}:{error:a}}),c&&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 c=o.payload??{},d=String(c.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,i){const r=L("sha256").update(x).update("\0").update(e).update("\0").update(i).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 i=Number(e);return i>0&&Date.now()-i<=Li}resolveProviderQuotaSource(e){return tn(this,e)}maybeQueryProviderQuota(e=!1,i){return nn(this,e,i)}startProviderQuotaTimer(){sn(this)}stopProviderQuotaTimer(){on(this)}refreshAndPushProviderQuota(e=!1){return rn(this,e)}pushProviderQuotaToBindings(e,i=!1){an(this,e,i)}enrichProviderQuotaMeta(e,i="standard",r=this.cachedProviderQuota,n=this.cachedProviderQuotaSampledAtMs){return dn(this,e,i,r,n)}providerQuotaMetaPayload(e,i,r){return ln(this,e,i,r)}refreshProviderQuotaForSession(e,i,r){return cn(this,e,i,r)}refreshQuotaAfterModelSwitch(e,i,r){hn(this,e,i,r)}doRefreshQuotaAfterModelSwitch(e,i,r){return un(this,e,i,r)}getFreshClaudeRateLimitState(){const e=this.cachedClaudeRateLimitState;return e&&this.isRateLimitsCacheFresh(e.sampledAt)?e:null}getFreshCodexGlobalRateLimitCache(){const e=this.cachedRateLimits,i=this.cachedCodexContextWindow,r=this.cachedCodexTokenUsage;return{sampledAt:Math.max(this.cachedRateLimitsSampledAtMs??0,this.cachedCodexUsageSampledAtMs??0)||null,rateLimits:e,contextWindow:i,tokenUsage:r,hasData:!!(e||i||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(i=>i.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:n})=>({source:"admission",agent:this.name,label:r,...n>xi?{suspect:`admission held for ${ki(n)}`}:{}})),i=(this.pool?.describePendingOrBackgroundWork()??[]).map(r=>({...r,agent:this.name}));return[...e,...i]}async waitUntilLifecycleIdle(e){return Ri({describeBusy:()=>this.lifecycleBusyChecker?.()??this.describePendingOrBackgroundWork(),isStopped:()=>this.stopped,closeAdmission:()=>this.closeLifecycleAdmissionForRestart(),reopenAdmission:()=>this.reopenLifecycleAdmissionAfterAbort(),budgetMs:Pi,log:(i,r)=>{i==="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 i=0,r=!1;for(const n 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(n.sessionId).catch(s=>{r=!0,t=!0,h.warn(this.name,`failed to recycle adapter slot ${n.sessionId} after relay change: ${s}`)}),t||(i+=1)}return i>0&&h.info(this.name,`recycled ${i} 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 i=e.conversation?"full":"static",r=e.conversation?vi:mi;if(!e.fresh){const a=this.probeCache.get(i);if(a&&Date.now()-a.sampledAt<r)return{...a.result,cached:!0}}const n=this.config.adapterType??"acp",t=this.createAdapter(n,"__probe__"),s=e.conversation&&n==="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:n,providerBaseUrl:this.config.providerBaseUrl??null,opts:e,launchConversationProbe:s})}finally{t.stop().catch(()=>{})}return this.probeCache.set(i,{result:o,sampledAt:o.probed_at}),o}async runAcpConversationProbe(e,i){const r=Date.now(),n="__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(n,s)}catch{}let a=null;const c=new Promise(u=>{a=g=>{g===t&&u()},e.on("eventDone",a)});e.deliverInboundEvent({event_id:t,session_id:n,content:"ping",msg_id:t}),e.deliverStopEvent(t,n);let d=null;const l=await Promise.race([c.then(()=>!1),new Promise(u=>{d=setTimeout(()=>u(!0),i)})]);return d&&clearTimeout(d),a&&e.removeListener("eventDone",a),l?{attempted:!0,ok:!1,latency_ms:o(),error:{code:"conversation_timeout",message:`no eventDone within ${i}ms`}}:{attempted:!0,ok:!0,latency_ms:o()}}constructor(e,i,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 n=e.adapterType??"acp";if(this.sendCtrl.setDefaultQuoteTrigger(ai[n]),this.aibotConfig={...e.aibot,...n==="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=i??null,this.deferredMgr=new gi(this.name),this.activeEventStore=e.activeEventStorePath?new ei(e.activeEventStorePath):null,this.pendingEvents=new ti(e.pendingEventStorePath),n==="codex")this.sessionScanCache=new v(ae,_e);else if(n==="claude")this.sessionScanCache=new v(de,Se);else if(n==="pi"){const t=e.agent.env?.PI_CODING_AGENT_DIR;this.sessionScanCache=new v(()=>ue(void 0,t),()=>be(void 0,t))}else if(n==="codewhale")this.sessionScanCache=new v(pe,Ae);else if(n==="cursor")this.sessionScanCache=new v(ge,Ee);else if(n==="opencode"){const t=me(e.agent.command||"opencode")||"opencode";this.sessionScanCache=new v(()=>fe(void 0,t),()=>we(void 0,t))}else if(n==="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(n==="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),i=(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()):(i||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 n=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(n,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(c=>{h.warn(this.name,`Failed to remove running event from pending store event=${t}: ${c instanceof Error?c.message:String(c)}`)})),o==="canceled"||o==="failed"){const c=o==="canceled"?"canceled":"failed";this.aibotHandle.sendEventResult({event_id:t,status:c,msg:a?.reason,updated_at:Date.now()}),this.auditController.closeWithoutAdapter(t,c,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 c=this.buildAgyToolbarMeta(s),d=c?.available_models??[];h.info(this.name,`[agy-toolbar-diag] eventDone push binding card session=${s} model_id=${String(c?.model_id??"")} available_models=${d.length} meta_keys=${c?Object.keys(c).join(","):"<none>"}`),this.sendAgyBindingCard(s,a.cwd,c),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),c=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!==c)&&this.pushQueueSnapshotForSession(t)}),await this.replayPendingEventsOnStartup(),this.stopped)throw new Error("agent start aborted");this.pool.startIdleSweep(),h.info(this.name,`Ready (adapter: ${n}, 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 i=this.stopOnce();this.stopPromise=i,i.catch(()=>{this.stopPromise===i&&(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()??[],i=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=i.get(o),c=a?this.pool?.getSlot(a):void 0;this.auditController.markAdapterClosed(o,c?.adapter.takeAuditBoundary?.(o)??{processTerminated:!0})}const r=this.deferredMgr.getAllDeferredEntries(),n=this.pool?.drainAllQueuedEvents()??[],t=this.pendingEvents.dedupe([...this.pendingEvents.replaySnapshot(),...r.map(o=>({kind:"deferred",channel:o.channel,sessionId:o.sessionId,event:o.event})),...n.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,i=ie(this.config.agent.clientType,e),r=this.config.agent.env;let n=Object.keys(i).length>0?{...i,...r}:r;if(se(i)){const t=ee()?.getRuntimeInfo(),s={...r??{},...i},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&&(n={...n??{},...t})}return Z(n,this.name,this.config.agent.clientType)}createAdapter(e,i){switch(e){case"claude":return this.createClaudeAdapter(i);case"codex":return this.createCodexAdapter(i);case"pi":return this.createPiAdapter(i);case"openhuman":return this.createOpenHumanAdapter(i);case"codewhale":return this.createCodeWhaleAdapter(i);case"cursor":return this.createCursorAdapter(i);case"opencode":return this.createOpenCodeAdapter(i);case"agy":return this.createAgyAdapter(i);case"deepseek-harness":return this.createDshAdapter(i);default:return this.createAcpAdapter(i)}}createDshAdapter(e){const i={sendStreamChunk:(t,s,o,a,c,d,l)=>{this.sendStreamChunkByRuntimeConfig(t,s,o,a,c,d,l)},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 c=hi(o);if(c){this.sendToolExecutionCard(t,s,c);return}this.deliverRawEventEnvelope(t,s,o,"deepseek",a)},sendLocalActionResult:(t,s,o,a,c)=>{this.aibotHandle.sendLocalActionResult({action_id:t,status:s,...o!==void 0?{result:o}:{},...a?{error_code:a}:{},...c?{error_msg:c}:{}},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),n=this.config.adapterOptions??{};return new K({command:this.config.agent.command,args:this.config.agent.args,env:this.resolveSpawnEnv(),options:n},i,{aibotSessionId:e,bindingStore:this.bindingStore,globalConfigStore:this.globalConfigStore,agentName:this.name,dataRoot:R.join(w.data,"deepseek-harness",r),...typeof n.cordisPath=="string"?{cordisPath:n.cordisPath}:{},...typeof n.defaultModel=="string"?{defaultModel:n.defaultModel}:{},...typeof n.maxTokens=="number"?{maxTokens:n.maxTokens}:{},...typeof n.maxLineBytes=="number"?{maxLineBytes:n.maxLineBytes}:{},...n.integrationMode==="embedded_jsonrpc"||n.integrationMode==="profile_bridge"?{integrationMode:n.integrationMode}:{},...typeof n.dshHome=="string"?{dshHome:n.dshHome}:{},...typeof n.dshProfile=="string"?{dshProfile:n.dshProfile}:{},...typeof n.autoInstallBridge=="boolean"?{autoInstallBridge:n.autoInstallBridge}:{},...typeof n.autoStartProfile=="boolean"?{autoStartProfile:n.autoStartProfile}:{},...this.config.agent.provider?{provider:this.config.agent.provider}:{},promptTimeoutMs:this.config.promptTimeoutMs})}createCursorAdapter(e){const i={...this.config.adapterOptions??{}};i.bindingStore=this.bindingStore,i.aibotSessionId=e;const r=this.bindingStore.get(e),n=this.resolveSessionModelId(e);n&&(i.model=n);const t=this.resolveCursorSessionModeId(e),s=t??"full_auto";t||this.bindingStore.setCursorModeId(e,s),i.mode=s,r?.cwd&&(i.workspace=r.cwd);const o={sendStreamChunk:(a,c,d,l,u,g,p)=>{this.sendStreamChunkByRuntimeConfig(a,c,d,l,u,g,p)},sendEventResult:(a,c,d)=>{this.sendEventResultWithCleanup(a,c,d)},sendEventAck:(a,c)=>{this.aibotHandle.sendEventAck({event_id:a,session_id:c,received_at:Date.now()})},sendRawEventEnvelope:(a,c,d)=>{this.deliverRawEventEnvelope(a,c,d,"cursor",this.buildCursorRawEventFallbackText(d))},sendAgentQuestionCard:(a,c,d)=>{const l=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:c,content:u,msg_type:1,extra:{card_type:"agent_question",summary_text:l}})},agentInvoke:async(a,c,d)=>this.platformInvoke(a,c,d),sendLocalActionResult:(a,c,d,l,u)=>{this.aibotHandle.sendLocalActionResult({action_id:a,status:c,...d!==void 0?{result:d}:{},...l?{error_code:l}:{},...u?{error_msg:u}:{}},e)},sendUpdateBindingCard:(a,c,d,l)=>{this.aibotHandle.sendUpdateBindingCard({session_id:a,worker_status:c,cwd:d,...l?{meta:l}:{}})},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:i},o)}createClaudeAdapter(e){const i={sendReply:(t,s,o,a,c)=>{this.sendReplyByRuntimeConfig(t,s,o,a,c)},sendStreamChunk:(t,s,o,a,c,d,l)=>{this.sendStreamChunkByRuntimeConfig(t,s,o,a,c,d,l)},sendMedia:(t,s,o,a,c,d,l)=>{this.aibotHandle.sendMedia({event_id:t,session_id:s,content:o,msg_type:2,quoted_message_id:c||void 0,client_msg_id:d||void 0,extra:l?{media_caption:a,...l}:{media_caption:a}})},sendEventResult:(t,s,o,a,c)=>{this.sendEventResultWithCleanup(t,s,o,a,c)},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,c)=>{this.aibotHandle.sendLocalActionResult({action_id:t,status:s,...o!==void 0?{result:o}:{},...a?{error_code:a}:{},...c?{error_msg:c}:{}},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??{},n={...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:n},i)}createCodexAdapter(e){let i=null;const r={sendEventResult:(o,a,c)=>{if(a!=="responded"){this.sendEventResultWithCleanup(o,a,c);return}this.sendCtrl.sendFinalStreamChunkReliable(o,e,`codex_terminal_fence_${o}`,5e3,!0,!0).then(()=>this.sendEventResultWithCleanup(o,a,c),d=>{const l=`codex output acceptance fence failed: ${d instanceof Error?d.message:String(d)}`;this.sendEventResultWithCleanup(o,a==="responded"?"failed":a,a==="responded"?l:c)})},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,c)=>{this.sendThinkingByRuntimeConfig(o,a,c)},sendRunError:(o,a,c)=>{this.sendRunErrorAsChunk(o,a,c)},sendUpdateBindingCard:(o,a,c,d)=>{const l={...d??{}};if(!l.rate_limits&&this.cachedProviderQuota?.success){this.isRateLimitsCacheFresh(this.cachedProviderQuotaSampledAtMs)||this.maybeQueryProviderQuota().catch(()=>{});const u=this.providerQuotaToCodexRateLimits(this.cachedProviderQuota);u&&(l.rate_limits=u.rateLimits,l.rate_limit_primary_percent=u.primaryPercent,l.rate_limit_secondary_percent=u.secondaryPercent,l.rate_limit_primary_window_min=u.primaryWindowMin,l.rate_limit_secondary_window_min=u.secondaryWindowMin)}!l.provider_quota&&this.cachedProviderQuota?.success&&(l.provider_quota=this.cachedProviderQuota),this.aibotHandle.sendUpdateBindingCard({session_id:o,worker_status:a,cwd:c,...Object.keys(l).length>0?{meta:l}:{}})},agentInvoke:async(o,a,c)=>this.platformInvoke(o,a,c),sendLocalActionResult:(o,a,c,d,l)=>this.aibotHandle.sendLocalActionResult({action_id:o,status:a,...c!==void 0?{result:c}:{},...d?{error_code:d}:{},...l?{error_msg:l}:{}},e),sendSessionActivitySet:(o,a,c,d)=>{this.aibotHandle.sendSessionActivitySet({session_id:o,kind:a,active:c,...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 c=this.cachedRateLimitsSampledAtMs,d={rate_limits:{...o.primary.windowMinutes>0?{primary:o.primary}:{},...o.secondary.windowMinutes>0?{secondary:o.secondary}:{},sampledAt:c},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}:{},...i?.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,...i?.getEffortMeta()}})},onTokenUsageUpdated:o=>{o&&(this.cachedCodexTokenUsage=o,this.cachedCodexUsageSampledAtMs=Date.now())}},n=this.config.adapterOptions??{},t=this.auditController.getAdapterPreparation(e),s=o=>Bt(this,"codex",e,o);return i=new H({command:this.config.agent.command,args:this.config.agent.args,env:this.resolveSpawnEnv(),options:{...n,model:s("model")??n.model,collaborationMode:s("mode")??n.collaborationMode,reasoningEffort:s("reasoningEffort")??n.reasoningEffort,serviceTier:s("serviceTier")??n.serviceTier,sandboxMode:s("sandboxMode")??n.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),i}createCodeWhaleAdapter(e){const i={sendEventResult:(n,t,s)=>{this.sendEventResultWithCleanup(n,t,s)},sendEventAck:(n,t)=>this.aibotHandle.sendEventAck({event_id:n,session_id:t,received_at:Date.now()}),sendStreamChunk:(n,t,s,o,a,c)=>{this.sendStreamChunkByRuntimeConfig(n,t,s,o,a,c)},sendUpdateBindingCard:(n,t,s,o)=>this.aibotHandle.sendUpdateBindingCard({session_id:n,worker_status:t,cwd:s,...this.providerQuotaMetaPayload(o,n,s)}),sendLocalActionResult:(n,t,s,o,a)=>this.aibotHandle.sendLocalActionResult({action_id:n,status:t,...s!==void 0?{result:s}:{},...o?{error_code:o}:{},...a?{error_msg:a}:{}},e),sendSessionActivitySet:(n,t,s,o)=>{this.aibotHandle.sendSessionActivitySet({session_id:n,kind:t,active:s,...o??{}})},sendToolUse:(n,t,s,o)=>{this.sendToolExecutionCard(n,t,C(s,o))},sendToolResult:(n,t,s,o)=>{this.sendToolExecutionCard(n,t,b(s,o))},agentInvoke:async(n,t,s)=>this.platformInvoke(n,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}:{}}},i)}createPiAdapter(e){const i={sendEventResult:(n,t,s,o,a)=>{this.sendEventResultWithCleanup(n,t,s,o,a),h.info("bridge",`[pi] sendEventResult event=${n} status=${t}`)},sendEventAck:(n,t)=>this.aibotHandle.sendEventAck({event_id:n,session_id:t,received_at:Date.now()}),sendUpdateBindingCard:(n,t,s,o)=>this.aibotHandle.sendUpdateBindingCard({session_id:n,worker_status:t,cwd:s,...this.providerQuotaMetaPayload(o,n,s)}),agentInvoke:async(n,t,s)=>this.platformInvoke(n,t,s),sendLocalActionResult:(n,t,s,o,a)=>{this.aibotHandle.sendLocalActionResult({action_id:n,status:t,...s!==void 0?{result:s}:{},...o?{error_code:o}:{},...a?{error_msg:a}:{}},e)},sendSessionActivitySet:(n,t,s,o)=>{this.aibotHandle.sendSessionActivitySet({session_id:n,kind:t,active:s,...o??{}})},sendToolUse:(n,t,s,o)=>{this.sendToolExecutionCard(n,t,C(s,o))},sendToolResult:(n,t,s,o)=>{this.sendToolExecutionCard(n,t,b(s,o))},sendStreamChunk:(n,t,s,o,a,c)=>{this.sendStreamChunkByRuntimeConfig(n,t,s,o,a,c),a&&h.info("bridge",`[pi] sendFinalStreamChunk event=${n} seq=${o}`)},sendFinalStreamChunkReliable:this.reliableFinalWiring("pi"),sendThinking:(n,t,s)=>{this.sendThinkingByRuntimeConfig(n,t,s)},sendRunError:(n,t,s,o,a)=>{this.sendRunErrorAsChunk(n,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}:{}}},i)}createOpenHumanAdapter(e){const i={sendStreamChunk:(n,t,s,o,a,c)=>{this.sendStreamChunkByRuntimeConfig(n,t,s,o,a,c)},sendFinalStreamChunkReliable:async(n,t,s,o)=>{try{await this.sendCtrl.sendFinalStreamChunkReliable(n,t,o)}catch(a){throw h.error("bridge",`[openhuman] sendFinalStreamChunkReliable ACK failed event=${n}: ${a}`),a}},sendEventResult:(n,t,s)=>{this.sendEventResultWithCleanup(n,t,s),h.info("bridge",`[openhuman] sendEventResult event=${n} status=${t}`)},sendEventAck:(n,t)=>this.aibotHandle.sendEventAck({event_id:n,session_id:t,received_at:Date.now()}),sendToolUse:(n,t,s,o)=>{this.sendToolExecutionCard(n,t,C(s,o))},sendToolResult:(n,t,s,o)=>{this.sendToolExecutionCard(n,t,b(s,o))},sendThinking:(n,t,s)=>{this.sendThinkingByRuntimeConfig(n,t,s)},sendRunError:(n,t,s)=>{this.sendRunErrorAsChunk(n,t,s,0)},sendUpdateBindingCard:(n,t,s,o)=>this.aibotHandle.sendUpdateBindingCard({session_id:n,worker_status:t,cwd:s,...this.providerQuotaMetaPayload(o,n,s)}),agentInvoke:async(n,t,s)=>this.platformInvoke(n,t,s),sendLocalActionResult:(n,t,s,o,a)=>{this.aibotHandle.sendLocalActionResult({action_id:n,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},i,{port:r.port,host:r.host,workspaceDir:r.workspace_dir,sessionToken:r.session_token,enableSessionBinding:!0,aibotSessionId:e})}createOpenCodeAdapter(e){const i={sendStreamChunk:(n,t,s,o,a,c)=>{this.sendStreamChunkByRuntimeConfig(n,t,s,o,a,c)},sendFinalStreamChunkReliable:this.reliableFinalWiring("opencode"),sendEventResult:(n,t,s,o,a)=>{this.sendEventResultWithCleanup(n,t,s,o,a),h.info("bridge",`[opencode] sendEventResult event=${n} status=${t}`)},sendEventAck:(n,t)=>this.aibotHandle.sendEventAck({event_id:n,session_id:t,received_at:Date.now()}),sendToolUse:(n,t,s,o)=>{this.sendToolExecutionCard(n,t,C(s,o))},sendToolResult:(n,t,s,o)=>{this.sendToolExecutionCard(n,t,b(s,o))},sendThinking:(n,t,s)=>{this.sendThinkingByRuntimeConfig(n,t,s)},sendRunError:(n,t,s)=>{this.sendRunErrorAsChunk(n,t,s)},sendUpdateBindingCard:(n,t,s,o)=>this.aibotHandle.sendUpdateBindingCard({session_id:n,worker_status:t,cwd:s,...this.providerQuotaMetaPayload(o,n,s)}),agentInvoke:async(n,t,s)=>this.platformInvoke(n,t,s),sendLocalActionResult:(n,t,s,o,a)=>{this.aibotHandle.sendLocalActionResult({action_id:n,status:t,...s!==void 0?{result:s}:{},...o?{error_code:o}:{},...a?{error_msg:a}:{}},e)},sendPermissionCard:n=>{this.sendGrixApprovalCard(n,"opencode")},sendAgentQuestionCard:(n,t,s)=>{this.sendGrixAgentQuestionCard(n,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},i,{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 i={sendStreamChunk:(n,t,s,o,a,c)=>{this.sendStreamChunkByRuntimeConfig(n,t,s,o,a,c)},sendEventResult:(n,t,s)=>{this.sendEventResultWithCleanup(n,t,s)},sendEventAck:(n,t)=>{this.aibotHandle.sendEventAck({event_id:n,session_id:t,received_at:Date.now()})},agentInvoke:async(n,t,s)=>this.platformInvoke(n,t,s),forceCompleteInternalEvent:(n,t)=>{this.pool.eventComplete(n,t),this.pushQueueSnapshotForSession(t)},persistConversationId:(n,t)=>{this.bindingStore.setAgyConversationId(n,t)},sendToolUse:(n,t,s,o)=>{this.sendToolExecutionCard(n,t,C(s,o))},sendToolResult:(n,t,s,o)=>{this.sendToolExecutionCard(n,t,b(s,o))},getAgentProfile:()=>this.agentProfile,getAgentId:()=>this.config.aibot.agentId},r=n=>{const t=this.bindingStore.get(n);return{cwd:t?.cwd,modelId:this.resolveSessionModelId(n),conversationId:t?.agyConversationId}};return new $({command:this.config.agent.command,args:this.config.agent.args,env:this.resolveSpawnEnv(),options:this.config.adapterOptions??{}},i,r)}createAcpAdapter(e){const i=this.isAcpRawTransportEnabled(),r={sendStreamChunk:(d,l,u,g,p,_,A)=>{this.sendStreamChunkByRuntimeConfig(d,l,u,g,p,_,A)},sendFinalStreamChunkReliable:this.reliableFinalWiring("acp",4e3),sendEventResult:(d,l,u,g,p)=>{this.sendEventResultWithCleanup(d,l,u,g,p)},sendEventAck:(d,l)=>{this.aibotHandle.sendEventAck({event_id:d,session_id:l,received_at:Date.now()})},agentInvoke:async(d,l,u)=>this.platformInvoke(d,l,u),sendLocalActionResult:(d,l,u,g,p)=>{this.aibotHandle.sendLocalActionResult({action_id:d,status:l,...u!==void 0?{result:u}:{},...g?{error_code:g}:{},...p?{error_msg:p}:{}},e)},sendRawEventEnvelope:(d,l,u)=>{this.sendAcpRawEventEnvelope(d,l,u)},sendToolUse:(d,l,u,g)=>{if(i){this.sendAcpRawEventEnvelope(d,l,{type:"tool_use",payload:{tool_name:u,tool_input:g??""}});return}this.sendToolExecutionCard(d,l,C(u,g))},sendToolResult:(d,l,u,g)=>{this.sendToolExecutionCard(d,l,b(u,g))},sendThinking:(d,l,u)=>{this.sendThinkingByRuntimeConfig(d,l,u)},sendRunError:(d,l,u)=>{this.sendRunErrorAsChunk(d,l,u)},sendAgentQuestionCard:(d,l,u)=>{this.sendGrixAgentQuestionCard(d,l,u)},sendPermissionCard:d=>{h.info("bridge","sendPermissionCard callback entered",{rawTransport:i,eventId:d.eventId,sessionId:d.sessionId,toolCallId:d.toolCallId,toolName:d.toolName,toolTitle:d.toolTitle});const l=d.toolInput&&d.toolTitle&&d.toolInput!==d.toolTitle?`${d.toolTitle}: ${d.toolInput}`:d.toolTitle||d.toolInput||d.toolName;if(i){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:l,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,l)=>{d&&this.aibotHandle.sendMsg({session_id:d,msg_type:1,content:l,extra:{biz_card:{version:1,type:"agent_error",payload:{error:{name:"AuthRequired",message:l}}}}})},sendAgentMessage:(d,l)=>{d&&l&&this.aibotHandle.sendMsg({session_id:d,msg_type:1,content:l})},sendUpdateBindingCard:(d,l,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:l,cwd:u,...Object.keys(p).length>0?{meta:p}:{}})},onSkillsUpdate:(d,l)=>{try{this.aibotHandle.sendSkillsUpdate({skills:Y(d,w.skills),library_skills:this.buildLibrarySkillsReport(l)})}catch(u){}},onContextWindowUpdated:d=>{this.cachedAcpContextWindow=d,this.cachedAcpContextWindowSampledAtMs=Date.now();const l="usedPercentage"in d?d.usedPercentage.toFixed(1):(d.used/d.size*100).toFixed(1);h.info(this.name,`[acp] context_window updated: ${l}%`);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},n=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:c}=Kn({sessionBinding:n,globalDefaults:o,configInitialMode:this.config.acpInitialMode});return e&&a&&!n?.acpModelId&&this.bindingStore.setAcpModelId(e,a),e&&c&&!n?.acpModeId&&this.bindingStore.setAcpModeId(e,c),(a||c)&&h.info(this.name,`[toolbar] hydrate from binding: session=${e} model=${a??"<none>"} mode=${c??"<none>"}`),new S({command:this.config.agent.command,args:this.config.agent.args,env:this.resolveSpawnEnv()},r,{acpAuthMethod:this.config.acpAuthMethod,acpInitialMode:c,acpInitialModel:a,acpMcpTools:this.config.acpMcpTools,rawTransport:i,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 i=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 i.disconnect(),new Error("connection aborted");this.aibotHandle=i;const r=this.aibotHandle.authAck;if(this.applyAgentProfile(r?.agent_name,r?.introduction,{source:"auth_ack",respawnOnChange:!1},r?.system_prompt),this.aibotHandle.onEvent(n=>{this.handleAibotEvent(n).catch(t=>{h.error(this.name,`handleAibotEvent failed: ${t}`),this.aibotHandle.sendEventAck({event_id:n.event_id,session_id:n.session_id,received_at:Date.now()});const s=t instanceof Error?t.message:String(t);this.handleStaleCwdError(n,s)||this.aibotHandle.sendEventResult({event_id:n.event_id,status:"failed",msg:s,updated_at:Date.now()})})}),this.aibotHandle.onStop(n=>{try{this.handleAibotStop(n)}catch(t){h.error(this.name,`handleAibotStop failed: ${t}`)}}),this.aibotHandle.onAgentDeleted(n=>{h.warn(this.name,`agent deleted on platform (source=${n?.source??"unknown"}${n?.reason?` reason=${n.reason}`:""}), notifying manager to clean up`);try{this.agentDeletedHandler?.()}catch(t){h.error(this.name,`agentDeletedHandler failed: ${t}`)}}),this.aibotHandle.onShareSet(n=>{try{this.shareSetHandler?.(Array.isArray(n?.shared_to)?n.shared_to:[])}catch(t){h.error(this.name,`onShareSet failed: ${t}`)}}),this.aibotHandle.onProfilePush(n=>{try{this.applyAgentProfile(n?.agent_name,n?.introduction,{source:"profile_push",respawnOnChange:!0},n?.system_prompt)}catch(t){h.error(this.name,`onProfilePush failed: ${t}`)}}),this.aibotHandle.onSkillSync(n=>{if(!this.stopped)try{h.info(this.name,`skill_sync received owner=${n?.owner_id??""} name=${n?.name??""}`),this.skillSyncHandler?.()}catch(t){h.error(this.name,`onSkillSync failed: ${t}`)}}),this.aibotHandle.onRevoke(n=>{this.handleAibotRevoke(n).catch(t=>{h.error(this.name,`handleAibotRevoke failed: ${t}`)})}),this.aibotHandle.onLocalAction(n=>{this.handleAibotLocalAction(n).catch(t=>{h.error(this.name,`handleAibotLocalAction failed: ${t}`)})}),this.aibotHandle.onEventCancel(n=>{h.info(this.name,`recv event_cancel event_id=${n.event_id} session_id=${n.session_id}`),this.handleEventCancel(n).catch(t=>{h.error(this.name,`handleEventCancel failed: ${t}`)})}),this.aibotHandle.onMcpFrame((n,t)=>{const s=this.pool.getSlot(n)?.adapter;s?.deliverMcpFrameToAgent?s.deliverMcpFrameToAgent(t):h.warn(this.name,`mcp_frame: no adapter for session=${n}`)}),this.aibotHandle.onQueueClear(n=>{const t=this.pool.clearQueue(n.session_id);this.aibotHandle.sendQueueClearResult({session_id:n.session_id,canceled_event_ids:t}),this.pushQueueSnapshotForSession(n.session_id)}),typeof this.aibotHandle.onQueueReorder=="function"&&this.aibotHandle.onQueueReorder(n=>{const t=Array.isArray(n.ordered_event_ids)?n.ordered_event_ids.filter(o=>typeof o=="string"&&o.length>0):[],s=this.pool.reorderQueue(n.session_id,t);this.aibotHandle.sendQueueReorderResult({session_id:n.session_id,applied_event_ids:s}),this.pushQueueSnapshotForSession(n.session_id)}),typeof this.aibotHandle.onEventHold=="function"&&this.aibotHandle.onEventHold(n=>{const t=typeof n.session_id=="string"?n.session_id:"",s=typeof n.event_id=="string"?n.event_id:"",o=n.hold!==!1;if(h.info(this.name,`recv event_hold event_id=${s} session_id=${t} hold=${o} reason=${n.reason??""}`),!t||!s){this.aibotHandle.sendEventHoldResult({session_id:t,event_id:s,ok:!1,held:!1,error:"bad_request"});return}const a=typeof n.reason=="string"?n.reason:"",c=typeof n.ttl_ms=="number"?n.ttl_ms:void 0,d=this.pool.holdEvent(t,s,o,a,c),l=d==="ok";this.aibotHandle.sendEventHoldResult({session_id:t,event_id:s,ok:l,held:l?o:!1,...l?{}:{error:d}}),l&&this.pushQueueSnapshotForSession(t)}),typeof this.aibotHandle.onQueueEdit=="function"&&this.aibotHandle.onQueueEdit(n=>{const t=typeof n.session_id=="string"?n.session_id:"",s=typeof n.event_id=="string"?n.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 n.content=="string"?n.content:"",a=this.pool.editQueuedEvent(t,s,o),c=a==="ok";this.aibotHandle.sendQueueEditResult({session_id:t,event_id:s,ok:c,...c?{}:{error:a}}),c&&this.pushQueueSnapshotForSession(t)}),typeof this.aibotHandle.onQueueSnapshotQuery=="function"&&this.aibotHandle.onQueueSnapshotQuery(n=>{this.replyQueueSnapshotForSession(n.session_id)}),h.info(this.name,"Connected to aibot"),this.activeEventStore){const n=await this.activeEventStore.drain();if(n.length>0){h.warn(this.name,`Recovering ${n.length} stale event(s) from previous run`);for(const t of n)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 n=this.aibotHandle.authAck;this.applyAgentProfile(n?.agent_name,n?.introduction,{source:"reconnect",respawnOnChange:!0},n?.system_prompt),this.forceRefreshSkills(void 0,{force:!0}),this.skillSyncHandler?.(),this.relayStateSyncOnConnect()}),this.aibotHandle.onStreamRejected((n,t)=>{this.sendCtrl.markEventRejected(n)})}applyAgentProfile(e,i,r,n){const t=String(e??"").trim(),s=String(i??"").trim(),o=n===void 0?this.agentSystemPrompt:String(n),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 i=this.pool.getAllSlots();let r=0;for(const o of i)if(o.adapter.onAgentProfileChanged)try{o.adapter.onAgentProfileChanged(),r++}catch(a){h.warn(this.name,`onAgentProfileChanged failed for session=${o.sessionId}: ${a}`)}const n=i.filter(o=>o.adapter instanceof M),t=n.filter(o=>{if(o.state!=="ready")return!1;const a=o.adapter.getStatus();return!a.busy&&!a.backgroundBusy}),s=n.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 i=this.pool?.getQueueSnapshot(e)??null,r=i?[...i.running]:[],n=i?i.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=i?i.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),n.push({event_id:s,content_preview:o,title:o,summary:o,actions:[]})}return{session_id:e,running:r,running_items:n,queued:t}}pushQueueSnapshotForSession(e){if(!this.config.eventQueue||!this.pool)return;const i=this.buildQueueSnapshotPayload(e);h.info(this.name,`[queue-debug] push snapshot session=${e} running=${i.running.length} queued=${i.queued.length} running_ids=[${i.running.join(",")}]`),this.aibotHandle.sendQueueSnapshot(i)}replyQueueSnapshotForSession(e){!this.config.eventQueue||!this.pool||this.aibotHandle.sendQueueSnapshot(this.buildQueueSnapshotPayload(e))}async platformInvoke(e,i,r){return e==="file_link"?Jn(i):e==="file_upload"?this.uploadFileAndSendMedia(i):e==="toolbar_set"?this.setCustomToolbar(i):this.aibotHandle.agentInvoke(e,i,r)}async setCustomToolbar(e){const i=String(this.config.agent.clientType??this.config.aibot.clientType??"").trim().toLowerCase();if(i!=="acp")throw new Error(`grix_toolbar_set is only supported for client_type "acp" (this agent is "${i||"unknown"}")`);const r=String(e.session_id??"").trim();if(!r)throw new Error("grix_toolbar_set requires a session_id");const n=wt(e.items);return this.customToolbars.set(r,n),this.aibotHandle.sendUpdateBindingCard({session_id:r,metadata_only:!0,meta:{custom_toolbar:n}}),h.info(this.name,`[toolbar] custom toolbar published session=${r} items=${n.length}`),{ok:!0,items:n.length}}invokeDshEventTool(e,i){const r=V(this.aibotHandle,e,i),n=r.content[0]?.text??"";if(r.isError)throw new Error(n||`grix event tool "${e}" failed`);try{return JSON.parse(n)}catch{return n}}async uploadFileAndSendMedia(e){const i=String(e.file_path??"").trim(),r=String(e.session_id??"").trim(),n=String(e.caption??"").trim(),t=String(e.reply_to_message_id??"").trim();if(!i)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:i}),o=await this.aibotHandle.sendMedia({session_id:r,msg_type:2,content:n||`[${s.attachment_type}]`,client_msg_id:`file_upload_${k()}`,...t?{quoted_message_id:t}:{},extra:s.extra});if(o.cmd!=="send_ack"){const c=o.payload??{},d=String(c.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,i,r,n,t){const s=this.indexEventSession(e,i)??i;this.auditController.captureReply(e,r),this.sendCtrl.sendReply(e,s,r,n,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 i=e;if(i.codex_method!=="item/agentMessage/delta")return e;const n=i.codex_payload?.params?.phase;if(typeof n=="string"&&n.trim()&&n.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 i=e.codex_payload?.params,r=typeof i?.phase=="string"?i.phase.trim().toLowerCase():"";if(r&&r!=="final_answer")return;const n=i?.delta;typeof n!="string"||!n||this.auditController.captureUnsequencedStreamChunk(e.event_id,n)}discardEventTrackingState(e){this.inflightEvents.delete(e),this.restartCount.delete(e),this.eventSessionIndex.delete(e),this.pendingStartedEventIds.delete(e),this.sendCtrl.discardEventState(e)}reliableFinalWiring(e,i){return async(r,n,t)=>{try{await this.sendCtrl.sendFinalStreamChunkReliable(r,n,t,i)}catch(s){throw h.error("bridge",`[${e}] sendFinalStreamChunkReliable ACK failed event=${r}: ${s}`),s}h.info("bridge",`[${e}] sendFinalStreamChunkReliable done event=${r}`)}}sendStreamChunkByRuntimeConfig(e,i,r,n,t,s,o){const a=this.indexEventSession(e,i)??i;this.auditController.captureStreamChunk(e,n,r),this.sendCtrl.sendStreamChunk(e,a,r,n,t,s,o),(r||t)&&this.conversationLog?.logOutbound?.(a,e,t?"stream_chunk_finish":"stream_chunk",r)}surfacedRunErrorTexts=new Map;markRunErrorSurfaced(e,i){const r=i.trim();if(!r)return;const n=this.surfacedRunErrorTexts.get(e);n?n.add(r):this.surfacedRunErrorTexts.set(e,new Set([r]))}sendRunErrorAsChunk(e,i,r,n=1,t){this.surfacedRunErrorTexts.get(e)?.has(r.trim())||(this.markRunErrorSurfaced(e,r),this.sendStreamChunkByRuntimeConfig(e,i,`
2
2
 
3
- Error: ${r}`,i,!1,t))}sendEventResultWithCleanup(e,n,r,i,t=!1){const s=this.pool.getEventSessionId(e)??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),this.pool.cleanupEvent(e,s)===!1&&h.error(this.name,`Event terminal result could not release queue slot event=${e} session=${s??"-"} status=${n}`),s&&(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(d=>{h.warn(this.name,`Failed to remove terminal event from pending store event=${e}: ${d instanceof Error?d.message:String(d)}`)}),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 l=`${o} agent kept failing after ${y} automatic restarts: ${i}`;this.sendRunErrorAsChunk(n,r,l),this.sendEventResultWithCleanup(n,"failed",l,"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(l){h.warn(this.name,`[recovery] removeSlot failed session=${r}: ${l instanceof Error?l.message:String(l)}`)}if(this.stopped)return;const c=e.replayOriginalContent?t.content:this.resolveRecoveryPrompt(o,t),d={...t,content:c};try{await this.pool.deliverInboundEvent(d)}catch(l){h.error(this.name,`[recovery] redeliver failed event=${n} session=${r}: ${l instanceof Error?l.message:String(l)}`),this.sendEventResultWithCleanup(n,"failed",l instanceof Error?l.message:String(l));return}for(const l of a){if(this.stopped)break;try{await this.pool.deliverInboundEvent(l)}catch(u){h.error(this.name,`[recovery] sibling redeliver failed event=${l.event_id} session=${r}: ${u instanceof Error?u.message:String(u)}`),this.sendEventResultWithCleanup(l.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(l){this.sendAuditConfigurationError(e,l);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 l=this.pool.getSlot(e.session_id);if(l?.adapter instanceof H&&!l.adapter.hasRawApiCaptureRelay()){const u=l.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 l=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(!l)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(l){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,l)}}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",c=(this.config.adapterType??"acp")==="cursor";if((s||a||c)&&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",l=(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:l});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,c=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 c&&(i.audit={enabled:!0,auditId:c.auditId,turnId:c.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};
3
+ Error: ${r}`,n,!1,t))}sendEventResultWithCleanup(e,i,r,n,t=!1){const s=this.pool.getEventSessionId(e)??this.eventSessionIndex.get(e),o=r?.trim()??"";t&&this.markRunErrorSurfaced(e,o),i==="failed"&&s&&o&&this.sendRunErrorAsChunk(e,s,o);const a=i==="failed"&&o!==""&&(this.surfacedRunErrorTexts.get(e)?.has(o)??!1);this.auditController.markResponded(e,i,r),this.sendCtrl.finalizeOpenStreams(e),this.sendCtrl.sendEventResult(e,i,r,n,a),this.pool.cleanupEvent(e,s)===!1&&h.error(this.name,`Event terminal result could not release queue slot event=${e} session=${s??"-"} status=${i}`),s&&(this.pushQueueSnapshotForSession(s),this.conversationLog?.logResult?.(s,e,i,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(d=>{h.warn(this.name,`Failed to remove terminal event from pending store event=${e}: ${d instanceof Error?d.message:String(d)}`)}),i==="responded"&&(this.config.adapterType??"acp")!=="agy"&&(this.cachedProviderQuotaSampledAtMs=null,this.refreshAndPushProviderQuota(!0).catch(()=>{}))}async handleSessionInternalError(e){const{eventId:i,sessionId:r,errorMsg:n}=e;if(this.stopped)return;const t=this.inflightEvents.get(i);if(!t){h.warn(this.name,`[recovery] no inflight event for internalError event=${i} session=${r}; surface failure directly`),this.sendRunErrorAsChunk(i,r,n),this.sendEventResultWithCleanup(i,"failed",n,"agent_stop_failure");return}const s=(this.restartCount.get(i)??0)+1;this.restartCount.set(i,s);const o=this.config.adapterType??"acp";if(s>y){h.error(this.name,`[recovery] adapter=${o} session=${r} event=${i} restart=${s}/${y} outcome=give-up err=${n}`);const l=`${o} agent kept failing after ${y} automatic restarts: ${n}`;this.sendRunErrorAsChunk(i,r,l),this.sendEventResultWithCleanup(i,"failed",l,"agent_stop_failure");return}h.info(this.name,`[recovery] adapter=${o} session=${r} event=${i} restart=${s}/${y} outcome=restarting err=${n}`);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(l){h.warn(this.name,`[recovery] removeSlot failed session=${r}: ${l instanceof Error?l.message:String(l)}`)}if(this.stopped)return;const c=e.replayOriginalContent?t.content:this.resolveRecoveryPrompt(o,t),d={...t,content:c};try{await this.pool.deliverInboundEvent(d)}catch(l){h.error(this.name,`[recovery] redeliver failed event=${i} session=${r}: ${l instanceof Error?l.message:String(l)}`),this.sendEventResultWithCleanup(i,"failed",l instanceof Error?l.message:String(l));return}for(const l of a){if(this.stopped)break;try{await this.pool.deliverInboundEvent(l)}catch(u){h.error(this.name,`[recovery] sibling redeliver failed event=${l.event_id} session=${r}: ${u instanceof Error?u.message:String(u)}`),this.sendEventResultWithCleanup(l.event_id,"failed",u instanceof Error?u.message:String(u))}}}resolveRecoveryPrompt(e,i){return e==="acp"?"continue":i.content}sendThinkingByRuntimeConfig(e,i,r){this.sendCtrl.sendThinking(e,i,r)}bufferStreamChunk(e,i,r,n,t){this.auditController.captureUnsequencedStreamChunk(e,r),this.sendCtrl.bufferOnly(e,i,r,n,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 i=new Set(e.map(n=>n.event.event_id).filter(Boolean)),r=[];h.warn(this.name,`Replaying ${e.length} pending event(s) from previous run`);for(const n of e){if(this.stopped)break;const t=n.event;this.pendingEvents.startReplay(n);try{if(n.kind==="deferred"){const s=this.bindingStore.get(n.sessionId);s?.cwd?(await this.prepareBoundDeferredReplay(n,s.cwd),await this.deliverPendingReplayEvent(t),this.pendingStartedEventIds.has(t.event_id)||r.push(n)):(this.restorePendingReplayAuditTurn(t),this.deferredMgr.defer(n.channel,n.sessionId,t),r.push(n))}else await this.deliverPendingReplayEvent(t),this.pendingStartedEventIds.has(t.event_id)||r.push(n)}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(n),await this.pendingEvents.checkpointReplay(i,[...r,...this.pendingEvents.replaySnapshot()])}if(this.stopped)break}this.stopped||(this.pendingEvents.finishAllReplay(),await this.pendingEvents.checkpointReplay(i,r))}failEventIfLifecycleDraining(e,i="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:i,updated_at:Date.now()}),!0):!1}sendCanceledPendingEventResult(e,i){this.restorePendingReplayAuditTurn(e),this.captureEventRuntimeConfig(e),this.sendEventResultWithCleanup(e.event_id,"canceled",i),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,i){this.sessionBindings.set(e.sessionId,i),e.channel==="acp"?await this.bindSessionForPool(e.sessionId,i):e.channel==="opencode"&&await this.syncOpenCodeBinding(e.sessionId,i)}restorePendingReplayAuditTurn(e){const i=e.audit;if(!i?.enabled||!i.auditId||!i.capture||!i.profile||!i.scope)return;const r=Ei({enabled:!0,scope:i.scope,profile:i.profile,capture:i.capture,...i.retentionDays===void 0?{}:{retentionDays:i.retentionDays}});if(!r.enabled)return;const n=Object.freeze({auditId:i.auditId,businessSessionId:e.session_id,provider:this.resolveAuditProvider(),options:r,createdAt:new Date().toISOString()}),t=this.auditController.startTurn({session:n,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={...i,auditId:t.auditId,turnId:t.turnId,profile:n.options.profile,capture:{...n.options.capture},rawProviderBody:n.options.capture.rawProviderBody})}indexEventSession(e,i){if(!e||!i)return;const r=this.eventSessionIndex.get(e);return r?(r!==i&&h.warn(this.name,`Ignoring event session mismatch event=${e} indexed=${r} supplied=${i}`),r):(this.eventSessionIndex.set(e,i),i)}shouldDropToolDisplayEvent(e){return this.sendCtrl.shouldDropToolDisplayEvent(e)}shouldDropThinkingDisplayEvent(e){return this.sendCtrl.shouldDropThinkingDisplayEvent(e)}shouldDropCodexDisplayEvent(e,i){return this.sendCtrl.shouldDropCodexDisplayEvent(e,i)}logCodexEventToConversation(e){if(!this.conversationLog||e.codex_method!=="item/agentMessage/delta")return;const r=e.codex_payload?.params?.delta;if(!r)return;const n=this.eventSessionIndex.get(e.event_id)??e.session_id;this.conversationLog.append(n,{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,i){return this.sendCtrl.shouldDropAcpRawDisplayEvent(e,i)}sendAcpRawEventEnvelope(e,i,r){this.shouldDropAcpRawDisplayEvent(e,r.type)||this.deliverRawEventEnvelope(e,i,r,"acp",this.buildAcpRawEventFallbackText(r))}buildAcpRawEventFallbackText(e){const i=String(e.type??"").trim();if(!i)return"[acp] event";switch(i){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] ${i}`}}rawDetailSeq=0;deliverRawEventEnvelope(e,i,r,n,t){const s=ui({envelope:r,fallbackText:t,channelKey:n,allocateRefId:()=>`${e}_rawd_${++this.rawDetailSeq}`}),o=()=>{this.aibotHandle.sendMsg({event_id:e,session_id:i,msg_type:1,content:s.fallbackText,extra:{channel_data:{[n]:{raw_event:s.envelope}},agent_api_origin:!0}})};if(!s.sharded){o();return}h.info("bridge",`${n} 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,i,pi({envelopeType:r.type,field:a.field,fullText:a.fullText}),a.refClientMsgId);o()})().catch(a=>{h.warn("bridge",`${n} raw_event sharded delivery failed event=${e}: ${a}`)})}buildCursorRawEventFallbackText(e){const i=String(e?.type??"").trim(),r=e?.payload&&typeof e.payload=="object"?e.payload:{};switch(i){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 i?`[cursor] ${i}`:"[cursor] event"}}sendToolExecutionCard(e,i,r,n){this.sendCtrl.sendToolExecutionCard(e,i,r,n)}sendGrixApprovalCard(e,i){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:i}}},agent_api_origin:!0}})}sendGrixAgentQuestionCard(e,i,r){const n=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:i,content:t,msg_type:1,extra:{card_type:"agent_question",summary_text:n}})}async handleAgentQuestionReplyEvent(e){const i=bn(String(e.content??""));if(!i)return!1;this.aibotHandle.sendEventAck({event_id:e.event_id,session_id:e.session_id,received_at:Date.now()});const n=this.pool.getSlot(e.session_id)?.adapter,t=n instanceof S?"acp":n instanceof T?"opencode":this.config.adapterType??"unknown",s=n instanceof T?n.handleQuestionReplyEvent(i):n instanceof S?await n.handleQuestionReplyEvent(i):{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=${i.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=${i.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 i=Cn(String(e.content??""));if(!i)return!1;this.aibotHandle.sendEventAck({event_id:e.event_id,session_id:e.session_id,received_at:Date.now()});const n=this.pool.getSlot(e.session_id)?.adapter,t=i.params,s=String(t.tool_call_id??t.approval_command_id??t.approval_id??t.exec_context_id??""),o=n?.handleExecApprovalEvent?await n.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 i=this.config.adapterType??"acp",r=_n(e);let n;if(r&&(n=this.lifecycleBarrier.tryEnter(`session-control:${r.verb}`)??void 0,!n)){this.failEventIfLifecycleDraining(e);return}try{if(await this.handleCliInstallQuestionReply(e)||(i==="opencode"||i==="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,i,o))return;if(r){await wn(this,r,e,i,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(l){this.sendAuditConfigurationError(e,l);return}if(await En(this,e,i,$i.has(i),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(i==="codex"&&D(a?.options)){const l=this.pool.getSlot(e.session_id);if(l?.adapter instanceof H&&!l.adapter.hasRawApiCaptureRelay()){const u=l.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 l=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(!l)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(l){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,l)}}finally{n?.()}}handleStaleCwdError(e,i){if(!/CWD must be|Bound directory does not exist|Bound path is not a directory/i.test(i)||!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 n=this.pool.getSlot(e.session_id);n?.adapter instanceof S&&n.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:i,extra:{channel_data:{[s]:{sessionBinding:{status:"missing",reason:"binding_stale",error_code:P.invalidCwd}}}},quoted_message_id:e.msg_id}),!0}failUndeliveredInboundEvent(e,i){const r=i instanceof Error?i.message:String(i);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,i){return ot(this,e,i)}handleSessionControlForPool(e,i){return rt(this,e,i)}handleSessionControlLocalActionForPool(e){return at(this,e)}handleCodexSessionControlLocalActionOpen(e){return dt(this,e)}handleCursorSessionControlLocalActionOpen(e){return lt(this,e)}handlePiSessionControlOpen(e,i){return ct(this,e,i)}handlePiSessionControlRestart(e){return ht(this,e)}handlePiSessionControlRestartLocalAction(e){return ut(this,e)}syncOpenCodeBinding(e,i){return pt(this,e,i)}isWorkspaceFreeClient(){return gt(this)}isCwdLockedClient(){return ft(this)}ensureDefaultBindingForWorkspaceFreeClient(e,i){return mt(this,e,i)}bindSessionForPool(e,i){return vt(this,e,i)}deferredCallbacks(){return _t(this)}handleOpenHumanSessionControlOpen(e,i){return St(this,e,i)}handleCodeWhaleSessionControlOpen(e,i){return Ct(this,e,i)}handleCodeWhaleSessionControlLocalActionOpen(e){return bt(this,e)}handleDeepSeekSessionControlLocalActionOpen(e){return At(this,e)}normalizeClaudeModeId(e){return Ft(this,e)}handleExecCommandOptions(e,i,r){Ut(this,e,i,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,i){return Jt(this,e,i)}buildAgyQuotaMeta(e){return Yt(this,e)}sendAgyBindingCard(e,i,r){return Vt(this,e,i,r)}refreshAndPushAgyQuota(e,i=!1){return Xt(this,e,i)}handleAgySetModel(e,i){return Zt(this,e,i)}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,i){return Un(this,e,i)}getClaudeWorkerStatus(e){return qn(this,e)}refreshClaudeWorkerStatusCard(e,i){return Wn(this,e,i)}async ensureSlotStarted(e,i=6e4){return Fn(this,e,i)}maybeOfferCliInstall(e){Me(this,e)}handleCliInstallQuestionReply(e){return He(this,e)}handleCliInstallInteractionReply(e){return $e(this,e)}runConfirmedCliInstall(e,i){return De(this,e,i)}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,i){return Dt(this,e,i)}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,i){In(this,e,i)}normalizePathForCompare(e){return Hn(e)}ensureImportedAgentSession(e,i){Ln(this,e,i)}buildOpenedBindingResult(e,i,r="ready"){return xn(this,e,i,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,i){return xe(this,e,i)}handleSessionControlLocalAction(e){return Le(this,e)}handleEventCancel(e){return Qe(this,e)}waitForEventDone(e,i,r){return Ie(this,e,i,r)}handleAibotStop(e){Oe(this,e)}killAndResumeStopSlot(e,i){return Be(this,e,i)}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 i=e.action_type??"",r=String((e.params??{}).session_id??""),n=String((e.params??{}).verb??"").trim().toLowerCase();h.debug(this.name,`local_action received action_type=${i} verb=${n||"-"} action_id=${e.action_id} session_id=${r}`);let t;if(i===f.sessionControl&&(t=this.lifecycleBarrier.tryEnter(`local-action:${n||i}`)??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(i===f.interactionReply&&await this.handleCliInstallInteractionReply(e))return;if(J(i)){await this.handleAuditLocalAction(e);return}const s=(this.config.adapterType??"acp")==="claude";if(i===f.sessionControl&&n===E.exec&&await this.handleSessionControlLocalAction(e))return;if(i===f.sessionControl&&n===E.listSessions){await this.handleListSessionsLocalAction(e);return}if(i===f.sessionControl&&n===E.syncHistory){await this.handleSyncHistoryLocalAction(e);return}if(i===f.sessionControl&&n===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(i==="skill_upload"){await this.handleSkillUploadLocalAction(e);return}if(i==="skill_delete"){await this.handleSkillDeleteLocalAction(e);return}if(i==="skill_enable"){await this.handleSkillEnableLocalAction(e);return}if(i==="skill_disable"){await this.handleSkillDisableLocalAction(e);return}if(i==="skill_refresh"){this.handleSkillRefreshLocalAction(e);return}const o=(this.config.adapterType??"acp")==="opencode";if((s&&(i===f.interactionReply||i==="exec_approve"||i==="exec_reject")||o&&i===f.interactionReply)&&(await this.pool.deliverLocalAction(e)).handled||s&&await this.handleSessionControlLocalAction(e))return;if(i===f.sessionControl){await yn(this,e,r);return}if(i==="file_list"){await kn(this,e,r);return}if(i==="create_folder"){await Rn(this,e,r);return}if(i===f.setModel&&(this.config.adapterType??"acp")==="agy"){await this.handleAgySetModel(e,r);return}if(i===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(i===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",c=(this.config.adapterType??"acp")==="cursor";if((s||a||c)&&i===f.threadCompact){await this.handleThreadCompact(e,r);return}if(i==="connector_rollback"){await this.handleConnectorRollback(e);return}if(i==="connector_upgrade_push"){this.aibotHandle.sendLocalActionResult({action_id:e.action_id,status:"ok",result:{accepted:!0}}),this.upgradeTrigger?.();return}if(i===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(i===Ve){await this.handleConnectorAdminLocalAction(e);return}if(i==="configure_gateway_provider"){await this.handleConfigureGatewayProvider(e);return}if(i==="apply_relay_state"){await this.handleApplyRelayState(e);return}const d=this.config.adapterType??"acp",l=(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:l});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"&&(i==="set_mode"||i==="set_model")){await Tn(this,e,r,i);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 "${i}" is not supported by the current agent process.`:`No active agent process for this session. The reply to action "${i}" could not be delivered \u2014 please resend it as a new message.`})}finally{t?.()}}handleGetSessionUsage(e,i){return yt(this,e,i)}handleThreadCompact(e,i){return Rt(this,e,i)}handleGetRateLimits(e,i){return pn(this,e,i)}resolveRateLimitWakeSessionId(e,i){return gn(this,e,i)}wakeRateLimitSlot(e,i){return fn(this,e,i)}sessionControlCtx(e){const i=this.pool.getSlot(e),r=i?.adapter instanceof S?i.adapter:null,n=(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:n?(s,o)=>jn(t,s,o):void 0,acpSetModel:n?(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"&&i?.adapter instanceof $?(i.adapter.cancelCurrentRun(),Promise.resolve()):i?.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:(i,r)=>this.aibotHandle.sendEventAck({event_id:i,session_id:r,received_at:Date.now()}),sendEventResult:(i,r,n)=>this.aibotHandle.sendEventResult({event_id:i,status:r,...n?.msg?{msg:n.msg}:{},...n?.code?{code:n.code}:{},updated_at:Date.now()}),sendLocalActionResult:(i,r,n,t,s)=>this.aibotHandle.sendLocalActionResult({action_id:i,status:r,...n?{result:n}:{},...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,i){this.sendCtrl.finalizeThinking(e,i)}logInboundConversation(e){const i=String(e.session_id??"").trim();i&&this.conversationLog?.logInbound(i,{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,i){const r=i instanceof Error?i.message:String(i),n=(()=>{const a=B(e.extra);return a.options?.enabled===!0&&a.options.scope==="turn"})(),t=i instanceof Ai||i instanceof bi,s=i instanceof yi&&n,o=s?"audit_config_invalid":t?i.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,i){const n=this.pool.getSlot(i)?.adapter.takeAuditBoundary?.(e);this.auditController.markAdapterClosed(e,n)}prepareAuditedInboundEvent(e,i,r){const n=this.buildInboundEvent(e,i),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,c=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 c&&(n.audit={enabled:!0,auditId:c.auditId,turnId:c.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}),n}buildInboundEvent(e,i){const r=oi(this.sendCtrl.getGlobalRuntimeConfig(),i),n=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:n===void 0?void 0:JSON.stringify(n),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 i=e.filter(r=>!Sn(String(r?.content??"")));if(i.length!==0)return JSON.stringify(i)}isStaleEvent(e){const i=Number(e.created_at);return!Number.isFinite(i)||i<=0?!1:Date.now()-i>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};
@@ -1 +1 @@
1
- const _=500,y=140;function i(t){return typeof t=="string"?t.trim().replace(/\s+/g," "):t==null?"":typeof t=="number"||typeof t=="boolean"?String(t):""}function n(t,o){const r=i(t);return r.length<=o?r:o<=3?r.slice(0,o):`${r.slice(0,o-3)}...`}function T(t){const o=i(t);if(!o)return"";try{const r=JSON.parse(o),e=s(r);if(e)return e}catch{}return o}function u(t){const o=i(t);if(!o)return"";try{return s(JSON.parse(o))}catch{return""}}function s(t){if(!t||typeof t!="object"||Array.isArray(t))return"";const o=t;for(const r of["command","file_path","path","pattern","query","description","url","text"]){const e=i(o[r]);if(e)return e}return""}function d(t,o){const r=i(t)||"tool",e=T(o);return{summaryText:e?`${r}: ${n(e,140)}`:r,...e?{detailText:n(e,500)}:{}}}function p(t,o){const r=i(o);if(r==="(failed)")return{summaryText:"(failed)"};if(r.startsWith("(failed) ")){const f=r.slice(9),l=u(f);return{summaryText:l?`${n(l,140)} (failed)`:"(failed)",...l?{detailText:n(l,500)}:{}}}const e=u(r);if(e)return{summaryText:n(e,140),detailText:n(e,500)};const c=n(r,500);return{summaryText:t||"result",...c?{detailText:c}:{}}}function a(t){if(typeof t=="string")return t;if(t==null)return"";try{return JSON.stringify(t)}catch{return String(t)}}function m(t){const o=String(t.type??""),r=t.payload&&typeof t.payload=="object"?t.payload:{};return o==="tool_call"||o==="tool_use"?d(String(r.tool_name??r.toolName??"tool"),a(r.tool_input??r.input)):o==="tool_result"?p(String(r.tool_name??r.toolName??"result"),a(r.result??r.content??r.output)):null}function I(t,o,r){const e=new URLSearchParams;return e.set("d",JSON.stringify(r)),`[${t}](grix://card/${o}?${e.toString()})`}export{m as buildDshOnlineToolCard,I as buildLocalGrixCardLink,p as buildToolResultCard,d as buildToolUseCard,n as compactToolCardText,i as normalizeToolCardText,a as stringifyToolField};
1
+ const _=500,y=140;function i(t){return typeof t=="string"?t.trim().replace(/\s+/g," "):t==null?"":typeof t=="number"||typeof t=="boolean"?String(t):""}function e(t,o){const r=i(t);return r.length<=o?r:o<=3?r.slice(0,o):`${r.slice(0,o-3)}...`}function T(t){const o=i(t);if(!o)return"";try{const r=JSON.parse(o),n=a(r);if(n)return n}catch{}return o}function u(t){const o=i(t);if(!o)return"";try{return a(JSON.parse(o))}catch{return""}}function a(t){if(!t||typeof t!="object"||Array.isArray(t))return"";const o=t;for(const r of["command","CommandLine","file_path","AbsolutePath","path","pattern","query","description","toolSummary","toolAction","url","text"]){const n=i(o[r]);if(n)return n}return""}function d(t,o){const r=i(t)||"tool",n=T(o);return{summaryText:n?`${r}: ${e(n,140)}`:r,...n?{detailText:e(n,500)}:{}}}function p(t,o){const r=i(o);if(r==="(failed)")return{summaryText:"(failed)"};if(r.startsWith("(failed) ")){const f=r.slice(9),l=u(f);return{summaryText:l?`${e(l,140)} (failed)`:"(failed)",...l?{detailText:e(l,500)}:{}}}const n=u(r);if(n)return{summaryText:e(n,140),detailText:e(n,500)};const c=e(r,500);return{summaryText:t||"result",...c?{detailText:c}:{}}}function s(t){if(typeof t=="string")return t;if(t==null)return"";try{return JSON.stringify(t)}catch{return String(t)}}function m(t){const o=String(t.type??""),r=t.payload&&typeof t.payload=="object"?t.payload:{};return o==="tool_call"||o==="tool_use"?d(String(r.tool_name??r.toolName??"tool"),s(r.tool_input??r.input)):o==="tool_result"?p(String(r.tool_name??r.toolName??"result"),s(r.result??r.content??r.output)):null}function L(t,o,r){const n=new URLSearchParams;return n.set("d",JSON.stringify(r)),`[${t}](grix://card/${o}?${n.toString()})`}export{m as buildDshOnlineToolCard,L as buildLocalGrixCardLink,p as buildToolResultCard,d as buildToolUseCard,e as compactToolCardText,i as normalizeToolCardText,s as stringifyToolField};
@@ -1 +1 @@
1
- const L=1,d=["low","medium","high","xhigh","max","auto"],c=["low","medium","high","xhigh","max"],T=d,O=c,A={"x-high":"xhigh",x_high:"xhigh",default:"auto","model-default":"auto",model_default:"auto"};function s(t){const o=typeof t=="string"?t.trim().toLowerCase():String(t??"").trim().toLowerCase();if(!o)return;const e=A[o]??o;return d.includes(e)?e:void 0}function C(t){const o=s(t);return o&&o!=="auto"?o:void 0}function E(t){return typeof t!="string"?void 0:t.trim()||void 0}function R(t){if(!t||typeof t!="object")return null;const o=t;if(o.version!==1)return null;const e=o.claude;if(!e||typeof e!="object"||e.supported!==!0)return null;const n=E(e.base_url);if(!n)return null;try{const i=new URL(n);if(i.protocol!=="https:"&&i.protocol!=="http:")return null}catch{return null}const r=E(e.primary_model);if(!r)return null;const _=E(e.fast_model),l=E(e.effort),u=s(l);if(l&&!u)return null;const f=u==="auto"?void 0:u;return{baseUrl:n,primaryModel:r,..._?{fastModel:_}:{},...f?{effort:f}:{}}}function p(t,o){const e=t.fastModel??t.primaryModel,n={ANTHROPIC_BASE_URL:t.baseUrl,ANTHROPIC_AUTH_TOKEN:o,ANTHROPIC_MODEL:t.primaryModel,ANTHROPIC_DEFAULT_OPUS_MODEL:t.primaryModel,ANTHROPIC_DEFAULT_SONNET_MODEL:t.primaryModel,ANTHROPIC_DEFAULT_HAIKU_MODEL:e,CLAUDE_CODE_SUBAGENT_MODEL:e},r=C(t.effort);return r&&(n.CLAUDE_CODE_EFFORT_LEVEL=r),n}function I(t){return!!(t.ANTHROPIC_BASE_URL&&t.ANTHROPIC_AUTH_TOKEN)}const a="grix-relay-placeholder";function m(t,o){const e={...t},n=new Set([o.caCertPath,o.caBundlePath].filter(r=>!!r));for(const r of["HTTPS_PROXY","https_proxy","HTTP_PROXY","http_proxy"])o.proxyUrl&&e[r]===o.proxyUrl&&delete e[r];for(const r of["NODE_EXTRA_CA_CERTS","SSL_CERT_FILE"]){const _=e[r];_&&n.has(_)&&delete e[r]}return delete e.GRIX_RELAY_PROXY,e.ANTHROPIC_API_KEY===a&&delete e.ANTHROPIC_API_KEY,e}export{L as CLAUDE_DIRECT_CAPABILITY_VERSION,O as CLAUDE_DIRECT_EFFORT_LEVELS,T as CLAUDE_EFFORT_LEVELS,d as CLAUDE_EFFORT_OPTIONS,c as CLAUDE_ENV_EFFORT_LEVELS,a as GRIX_RELAY_ANTHROPIC_API_KEY_PLACEHOLDER,p as buildClaudeDirectEnv,I as isClaudeDirectEnv,s as normalizeClaudeEffort,C as normalizeClaudeEnvEffort,R as parseClaudeDirectCapability,m as stripGrixRelayEnv};
1
+ const C=1,A=["low","medium","high","xhigh","max","auto"],O=["low","medium","high","xhigh","max"],T=A,R=O,L={"x-high":"xhigh",x_high:"xhigh",default:"auto","model-default":"auto",model_default:"auto"};function d(t){const o=typeof t=="string"?t.trim().toLowerCase():String(t??"").trim().toLowerCase();if(!o)return;const e=L[o]??o;return A.includes(e)?e:void 0}function s(t){const o=d(t);return o&&o!=="auto"?o:void 0}function E(t){return typeof t!="string"?void 0:t.trim()||void 0}function a(t){if(!t||typeof t!="object")return null;const o=t;if(o.version!==1)return null;const e=o.claude;if(!e||typeof e!="object"||e.supported!==!0)return null;const n=E(e.base_url);if(!n)return null;try{const i=new URL(n);if(i.protocol!=="https:"&&i.protocol!=="http:")return null}catch{return null}const r=E(e.primary_model);if(!r)return null;const _=E(e.fast_model),l=E(e.effort),u=d(l);if(l&&!u)return null;const f=u==="auto"?void 0:u;return{baseUrl:n,primaryModel:r,..._?{fastModel:_}:{},...f?{effort:f}:{}}}function D(t,o){const e=t.fastModel??t.primaryModel,n={ANTHROPIC_BASE_URL:t.baseUrl,ANTHROPIC_AUTH_TOKEN:o,ANTHROPIC_MODEL:t.primaryModel,ANTHROPIC_DEFAULT_OPUS_MODEL:t.primaryModel,ANTHROPIC_DEFAULT_SONNET_MODEL:t.primaryModel,ANTHROPIC_DEFAULT_HAIKU_MODEL:e,CLAUDE_CODE_SUBAGENT_MODEL:e,CLAUDE_CODE_DISABLE_ADVISOR_TOOL:"1"},r=s(t.effort);return r&&(n.CLAUDE_CODE_EFFORT_LEVEL=r),n}function I(t){return!!(t.ANTHROPIC_BASE_URL&&t.ANTHROPIC_AUTH_TOKEN)}const c="grix-relay-placeholder";function p(t,o){const e={...t},n=new Set([o.caCertPath,o.caBundlePath].filter(r=>!!r));for(const r of["HTTPS_PROXY","https_proxy","HTTP_PROXY","http_proxy"])o.proxyUrl&&e[r]===o.proxyUrl&&delete e[r];for(const r of["NODE_EXTRA_CA_CERTS","SSL_CERT_FILE"]){const _=e[r];_&&n.has(_)&&delete e[r]}return delete e.GRIX_RELAY_PROXY,e.ANTHROPIC_API_KEY===c&&delete e.ANTHROPIC_API_KEY,e.CLAUDE_CODE_DISABLE_ADVISOR_TOOL==="1"&&delete e.CLAUDE_CODE_DISABLE_ADVISOR_TOOL,e}export{C as CLAUDE_DIRECT_CAPABILITY_VERSION,R as CLAUDE_DIRECT_EFFORT_LEVELS,T as CLAUDE_EFFORT_LEVELS,A as CLAUDE_EFFORT_OPTIONS,O as CLAUDE_ENV_EFFORT_LEVELS,c as GRIX_RELAY_ANTHROPIC_API_KEY_PLACEHOLDER,D as buildClaudeDirectEnv,I as isClaudeDirectEnv,d as normalizeClaudeEffort,s as normalizeClaudeEnvEffort,a as parseClaudeDirectCapability,p as stripGrixRelayEnv};
@@ -1 +1 @@
1
- import{ProxyManager as y}from"./proxy-manager.js";import{ProxyManager as g,ProxyNoRelayRouteError as E}from"./proxy-manager.js";import{RelayFetchError as A,RelayToggleCoordinator as d,deriveGatewayBaseUrls as m,fetchRelayCredentialWithRetry as h}from"./relay-credential-fetch.js";import{relayHostsForClientType as Y}from"./relay-hosts.js";import{buildGatewayRoute as w}from"./gateway-route.js";import{RelayStateStore as K}from"./relay-state.js";import{SecretStore as b,SecretStoreError as L}from"./secret-store.js";import{ensureKiroRelay as X,stopKiroRelay as H,stopAllKiroRelays as S,getKiroRelaySpawnEnv as v,getKiroRelayDebug as U,kiroRelayHomeDir as G}from"./kiro-relay.js";let e=null;function c(r){return e||(e=new y(r)),e}function p(){return e}function u(){e=null}class s extends Error{agentName;code="RELAY_PROXY_UNAVAILABLE";constructor(o){super(`agent "${o}" has Grix relay enabled but the local MITM proxy is not running; refusing to start it (it would silently fall back to your own account). Fix the proxy or turn relay off.`),this.agentName=o,this.name="ProxyRelayUnavailableError"}}const i="localhost,127.0.0.1,::1",x="grix-relay-placeholder";function P(r,o,n){if(e?.isRelayExpectedButUnavailable(o))throw new s(o);const l=e?.getInjectionEnv(o);if(!l)return r;const t={...r,...l};n?.trim().toLowerCase()==="claude"&&!t.ANTHROPIC_API_KEY&&!t.ANTHROPIC_AUTH_TOKEN&&(t.ANTHROPIC_API_KEY=x),n?.trim().toLowerCase()==="codex"&&(t.GRIX_RELAY_PROXY="1");const a=r?.NO_PROXY??r?.no_proxy??process.env.NO_PROXY??process.env.no_proxy;return t.NO_PROXY=a&&a.trim()?`${a},${i}`:i,t}export{x as GRIX_RELAY_ANTHROPIC_API_KEY,g as ProxyManager,E as ProxyNoRelayRouteError,s as ProxyRelayUnavailableError,A as RelayFetchError,K as RelayStateStore,d as RelayToggleCoordinator,b as SecretStore,L as SecretStoreError,P as applyProxyEnv,w as buildGatewayRoute,m as deriveGatewayBaseUrls,X as ensureKiroRelay,h as fetchRelayCredentialWithRetry,U as getKiroRelayDebug,v as getKiroRelaySpawnEnv,p as getProxyManager,c as initProxyManager,G as kiroRelayHomeDir,Y as relayHostsForClientType,u as resetProxyManagerForTest,S as stopAllKiroRelays,H as stopKiroRelay};
1
+ import{ProxyManager as y}from"./proxy-manager.js";import{ProxyManager as E,ProxyNoRelayRouteError as O}from"./proxy-manager.js";import{RelayFetchError as g,RelayToggleCoordinator as d,deriveGatewayBaseUrls as m,fetchRelayCredentialWithRetry as I}from"./relay-credential-fetch.js";import{relayHostsForClientType as C}from"./relay-hosts.js";import{buildGatewayRoute as L}from"./gateway-route.js";import{RelayStateStore as w}from"./relay-state.js";import{SecretStore as T,SecretStoreError as S}from"./secret-store.js";import{ensureKiroRelay as M,stopKiroRelay as X,stopAllKiroRelays as H,getKiroRelaySpawnEnv as U,getKiroRelayDebug as v,kiroRelayHomeDir as D}from"./kiro-relay.js";let o=null;function c(r){return o||(o=new y(r)),o}function p(){return o}function u(){o=null}class s extends Error{agentName;code="RELAY_PROXY_UNAVAILABLE";constructor(t){super(`agent "${t}" has Grix relay enabled but the local MITM proxy is not running; refusing to start it (it would silently fall back to your own account). Fix the proxy or turn relay off.`),this.agentName=t,this.name="ProxyRelayUnavailableError"}}const i="localhost,127.0.0.1,::1",x="grix-relay-placeholder";function _(r,t,n){if(o?.isRelayExpectedButUnavailable(t))throw new s(t);const l=o?.getInjectionEnv(t);if(!l)return r;const e={...r,...l};n?.trim().toLowerCase()==="claude"&&(!e.ANTHROPIC_API_KEY&&!e.ANTHROPIC_AUTH_TOKEN&&(e.ANTHROPIC_API_KEY=x),e.CLAUDE_CODE_DISABLE_ADVISOR_TOOL="1"),n?.trim().toLowerCase()==="codex"&&(e.GRIX_RELAY_PROXY="1");const a=r?.NO_PROXY??r?.no_proxy??process.env.NO_PROXY??process.env.no_proxy;return e.NO_PROXY=a&&a.trim()?`${a},${i}`:i,e}export{x as GRIX_RELAY_ANTHROPIC_API_KEY,E as ProxyManager,O as ProxyNoRelayRouteError,s as ProxyRelayUnavailableError,g as RelayFetchError,w as RelayStateStore,d as RelayToggleCoordinator,T as SecretStore,S as SecretStoreError,_ as applyProxyEnv,L as buildGatewayRoute,m as deriveGatewayBaseUrls,M as ensureKiroRelay,I as fetchRelayCredentialWithRetry,v as getKiroRelayDebug,U as getKiroRelaySpawnEnv,p as getProxyManager,c as initProxyManager,D as kiroRelayHomeDir,C as relayHostsForClientType,u as resetProxyManagerForTest,H as stopAllKiroRelays,X as stopKiroRelay};
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: grix-access-control
3
- description: Manage sender access control with the typed `grix_access_control` tool — allow/remove a sender on the group-chat allowlist, or set the access policy. Approval of group visitors normally happens via the owner's one-tap approval card (no agent involvement); this tool is the auxiliary management entry. Trigger when the user asks to allowlist or block a sender, or change who is allowed to use the agent.
3
+ description: "Manage group-chat sender allowlists and access policy with `grix_access_control`. Use only when asked to allow, remove, or change who may use the agent; visitor approval normally uses the owner’s one-tap card."
4
4
  trigger: When the user wants to manually allow or remove a sender, or change the policy for who may use the agent in group chats
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: grix-admin
3
- description: Grix agent administration through the `grix_admin` tool — create remote API agents, manage agent categories, rotate API keys — and bind an agent's remote parameters into the local grix-connector config with reload and verification. For "create me an agent for X" requests, run `grix-egg` discovery first; use this skill when the user already has agent parameters to bind, asks for category management, or grix-egg found no matching egg / the user wants a blank agent.
3
+ description: "Create remote agents, manage categories, rotate keys, and bind supplied agent settings locally. For new-agent requests, search eggs first; use this for supplied settings, category operations, or a blank agent after no egg fits."
4
4
  trigger: When the user wants to bind an existing agent's parameters into the local grix-connector, list / create / update / assign agent categories, or create a blank agent after grix-egg discovery found nothing suitable
5
5
  ---
6
6
 
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: grix-agent-dispatch
3
- description: Dispatch one of the owner's other agents to do work in a given directory (`grix_dispatch_agent`), and update an agent's display name and/or text introduction (`grix_agent_update`). Dispatched agents write back via the skill procedure `report_dispatch_result` (not a tool; wire format `[dispatch-result]` via `grix_session_send` with `quoted_message_id`). Trigger when the user asks to hand a task to another agent, run work in a specific directory via a sibling agent, stop or redirect a dispatched agent that is still working, rename an agent / change an agent's introduction, or when you were dispatched and must report via `report_dispatch_result`.
3
+ description: "Dispatch work to another agent in a specified directory, stop or redirect a running task, or update an agent name/introduction. If you were dispatched, report back via this skill's `report_dispatch_result` procedure (not a tool), which sends `[dispatch-result]`."
4
4
  trigger: When the user wants to hand a task to another of the owner's agents, have an agent work in a specific directory, abort or redirect a running dispatched task, or rename an agent / change its introduction; or when you were dispatched yourself and must write back via report_dispatch_result
5
5
  ---
6
6