@north-light/cli 0.3.524 → 0.3.526
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/command-manifest/result.d.ts +4 -2
- package/dist/api/command-manifest/result.js +1 -1
- package/dist/api/command-manifest/schema.js +1 -1
- package/dist/api/plugin-manifest-schema.d.ts +3 -0
- package/dist/builtin-memory/crouter-plugin/deploying.md +2 -2
- package/dist/builtin-memory/crouter-plugin/output.md +3 -1
- package/dist/clients/attach/chrome/roster.d.ts +1 -1
- package/dist/clients/attach/chrome/roster.js +4 -4
- package/dist/clients/attach/render/chat-view.d.ts +9 -0
- package/dist/clients/attach/render/chat-view.js +3 -3
- package/dist/clients/attach/render/page-block.d.ts +2 -0
- package/dist/clients/attach/render/page-block.js +1 -1
- package/dist/clients/attach/session/connection.d.ts +1 -1
- package/dist/clients/attach/session/context.d.ts +1 -1
- package/dist/clients/attach/session/profile-files.d.ts +3 -3
- package/dist/clients/attach/session/profile-files.js +1 -1
- package/dist/clients/attach/viewer.js +633 -756
- package/dist/commands/pkg/browse/command-view.js +1 -1
- package/dist/core/canvas/db.d.ts +28 -2
- package/dist/core/canvas/db.js +2 -2
- package/dist/core/canvas/migrations.js +53 -53
- package/dist/core/canvas/nav-model.js +1 -1
- package/dist/core/canvas/recovery.d.ts +13 -0
- package/dist/core/canvas/recovery.js +2 -2
- package/dist/core/conversation-store/client.d.ts +2 -2
- package/dist/core/conversation-store/index.d.ts +30 -2
- package/dist/core/conversation-store/index.js +1 -1
- package/dist/core/conversation-store/patch.js +1 -1
- package/dist/core/graph/watches.d.ts +2 -0
- package/dist/core/graph/watches.js +9 -9
- package/dist/core/help.js +7 -7
- package/dist/core/llm/run.js +2 -2
- package/dist/core/runtime/broker/fault-retry.d.ts +9 -3
- package/dist/core/runtime/broker/fault-retry.js +1 -1
- package/dist/core/runtime/broker/rebind.d.ts +4 -0
- package/dist/core/runtime/broker/rebind.js +1 -1
- package/dist/core/runtime/broker/run-turn-queue.d.ts +2 -0
- package/dist/core/runtime/broker/run-turn-queue.js +1 -1
- package/dist/core/runtime/broker-persona-guidance.d.ts +1 -1
- package/dist/core/runtime/broker-persona-guidance.js +3 -3
- package/dist/core/runtime/broker.js +1 -1
- package/dist/core/runtime/close.d.ts +2 -2
- package/dist/core/runtime/close.js +1 -1
- package/dist/daemon/crtrd.js +8 -8
- package/dist/daemon/reconcilers/broker-supervision.d.ts +6 -2
- package/dist/daemon/reconcilers/broker-supervision.js +4 -4
- package/dist/daemon/runs/observer.js +2 -2
- package/docs/plugin/deploying.md +2 -2
- package/docs/plugin/output.md +3 -1
- package/package.json +2 -2
- package/packages/crouter-identity/package.json +1 -1
- package/runtime.lock.json +12 -12
|
@@ -1 +1 @@
|
|
|
1
|
-
var ie=Object.defineProperty;var y=(r,e)=>ie(r,"name",{value:e,configurable:!0});import{envModelIntent as G,envNodeCwd as $,envProfileId as L}from"../../../shared/env.js";import{isContextOverflow as D}from"@earendil-works/pi-ai";import{classify as N}from"../../fault-classifier.js";import{isModelNotFoundError as ne,isProviderUnconfiguredError as re}from"../fault.js";import{brokerRecovery as se,mutateBrokerFault as U,mutateBrokerProviderRetry as b}from"./daemon-ops.js";import{extractCoolingDeadline as oe}from"../managed-provider-cooling.js";import{extractProviderFailureDetails as ae}from"../../provider-failure.js";import{expandModelCandidates as B,modelRequestFromConfig as Y,probeRouteAvailability as de}from"../../model-routes.js";import{operationIdContext as W}from"../../events/operation-id.js";import{emitEvent as F}from"../../events/emit.js";import{CONNECTION_FAULT_RECOVERY_BODY as le,PROVIDER_FAULT_RECOVERY_BODY as ue,RUN_CONNECTION_FAULT_RETRY_BODY as ce,formatCard as q,formatModelFallbackRecovery as pe}from"../../../shared/generated-context.js";import{markFatalOnExhaust as V,nextFaultRetry as j,policyFor as J}from"../fault-recovery.js";import{parseModelSpec as X}from"../model-selection.js";import{endedByAbort as z}from"../session-cycles.js";import{resolveProviderCandidates as fe}from"../../subscription-state.js";import{announceMessageOrigin as H}from"../stamp/channel.js";import{LLM_REFUSAL_DIAGNOSTIC as he,refusalRetryAt as me}from"./model-adapter.js";import{isSafetyRefusal as K}from"../../llm/refusal.js";const ge=2147483647,Q=3e4;function ye(r,e,t){const i=Date.parse(r);return!Number.isFinite(i)||t+e-i>Q}y(ye,"runTurnRetryExpired");function ve(r,e){return r!=="connection"?ue:e?ce:le}y(ve,"retryCardBody");function w(r){return{link:r.link,op:r.op,kind:r.kind,retry:r.retry,message:r.message,since:r.since,operation_id:r.operation_id,...r.anchor_entry_id===void 0?{}:{anchorEntryId:r.anchor_entry_id},...r.provider_error===void 0?{}:{providerError:r.provider_error}}}y(w,"policyFault");function S(r){return{link:r.link,op:r.op,kind:r.kind,retry:r.retry,message:r.message,...r.operation_id===void 0?{}:{operation_id:r.operation_id},...r.since===void 0?{}:{since:r.since},...r.anchorEntryId===void 0?{}:{anchor_entry_id:r.anchorEntryId},...r.providerError===void 0?{}:{provider_error:r.providerError}}}y(S,"faultInput");function Z(r,e){const t=y(i=>`${i.providerId}/${i.modelId}`===e.modelSpec,"onLiveModel");return(r.find(i=>t(i)&&i.thinkingLevel===e.thinkingLevel)??r.find(t))?.rank}y(Z,"liveRouteRank");function ee(r){const e=N("pi\u2192provider",r),t=r.diagnostics?.some(i=>i.type===he)??!1;return{classified:e,disposition:t?"fatal":e.disposition}}y(ee,"settledProviderFault");function Ue(r,e){if(r.stopReason!=="error"||z(r)||K(r)||D(r,e))return!1;const{classified:t,disposition:i}=ee(r);return i==="auto"&&(t.kind==="connection"||t.kind==="rate-limit"||t.kind==="overloaded")}y(Ue,"willDaemonRetry");const Fe=/does not support assistant message prefill|conversation must end with a user message/i;function ke(r,e){return e&&Fe.test(r)}y(ke,"isPrefillRejectionDuringEpisode");class Be{static{y(this,"FaultRetry")}deps;timer=null;failedRetryRoutes=new Set;notFoundModels=new Set;providerFallbackInFlight=null;notFoundFallbackInFlight=null;stagedCapacityFailure=null;personaGateFailed=!1;constructor(e){this.deps=e}clearTimer(){this.timer!==null&&(clearTimeout(this.timer),this.timer=null)}reset(){this.clearTimer(),this.deps.turnEnds?.abandon(),this.providerFallbackInFlight=null,this.notFoundFallbackInFlight=null,this.stagedCapacityFailure=null,this.personaGateFailed=!1}abandonTurnEnd(){this.deps.turnEnds?.abandon()}notePersonaGateFailure(){this.personaGateFailed=!0}state(){return se(this.deps.nodeId)}async recordFault(e){return(await U(this.deps.nodeId,{op:"record",input:e})).fault}async clearFault(e,t=!1){await U(this.deps.nodeId,{op:"clear",...e===void 0?{}:{link:e},...t?{preserve_episode:!0}:{}})}sessionId(e){const t=e.sessionManager.getSessionId?.();return typeof t=="string"&&t!==""?t:null}async clearEpisode(e){const t=this.sessionId(e);t!==null&&await b(this.deps.nodeId,{op:"clear",session_id:t})}onEvent(e){this.maybeSwitchProviderForRetry(e),this.maybeFallbackOnUnusableModel(e)}isActiveAutoFault(e){return e===null||e.retry.disposition!=="auto"||e.retry.by!=="daemon"?!1:e.kind==="connection"||e.kind==="rate-limit"||e.kind==="overloaded"}async publishSettledProviderFault(e){const t=e.stagedProviderAgentEnd,i=e.stagedWatchdogAbort,n=e.stagedRefreshAbort,o=e.stagedOverflowFailure,a=this.stagedCapacityFailure?.generation===e?this.stagedCapacityFailure:null,c=this.personaGateFailed;this.stagedCapacityFailure=null,this.personaGateFailed=!1,e.stagedProviderAgentEnd=null,e.stagedWatchdogAbort=!1,e.stagedRefreshAbort=!1,e.stagedOverflowFailure=null;const s=e.session,l=await this.state(),p=l.fault,h=l.episode,f=this.sessionId(s),m=this.isActiveAutoFault(p)&&p.link==="pi\u2192provider"?p:h?.state==="admitted"&&h.session_id===f&&this.isActiveAutoFault(h.fault)?h.fault:null,d=m===null?null:{since:m.since,anchorEntryId:m.anchor_entry_id,attempt:m.retry.attempt},u=[...Array.isArray(t?.messages)?t.messages:[]].reverse().find(R=>typeof R=="object"&&R!==null&&R.role==="assistant");if(c){await this.clearEpisode(s);return}if(a!==null||o!==null){await this.clearFault("pi\u2192provider"),await this.clearEpisode(s),await this.recordFault({link:"pi\u2192provider",op:"context overflow recovery",kind:"context-overflow",retry:{disposition:"fatal"},message:a?.errorMessage??o.errorMessage,anchor_entry_id:s.sessionManager.getLeafId?.()??void 0});return}if(i&&u?.stopReason==="aborted"){await this.recordPendingProviderFault(s,{link:"pi\u2192provider",op:"generation turn",kind:"connection",retry:{disposition:"auto",by:"daemon",...d?.attempt!==void 0?{attempt:d.attempt}:{}},message:typeof u.errorMessage=="string"?u.errorMessage:"engine error (no errorMessage recorded)",...d!==null?{since:d.since}:{},anchor_entry_id:d?.anchorEntryId??s.sessionManager.getLeafId?.()??void 0});return}if(u?.stopReason!=="error"){u!==void 0&&await this.clearEpisode(s);return}if(n){await this.clearEpisode(s);return}if(K(u)){await this.clearEpisode(s);return}const k=typeof u.errorMessage=="string"?u.errorMessage:"engine error (no errorMessage recorded)";if(z({stopReason:"error",errorMessage:k})){await this.clearEpisode(s);return}const v=D(u,s.model?.contextWindow),I=ee(u),A=d!==null&&I.disposition!=="auto"&&ke(k,!0),te=A?{kind:"connection",disposition:"auto"}:I.classified,E=A?"auto":I.disposition,M=oe(u),x=me(u),C=ae(u),T=typeof u.provider=="string"&&u.provider!==""?u.provider:s.model?.provider,O=typeof u.model=="string"&&u.model!==""?u.model:s.model?.id,P=C===void 0||T===void 0||O===void 0?void 0:{provider:T,model:O,...C};v&&(await this.clearFault("pi\u2192provider"),await this.clearEpisode(s));const _={link:"pi\u2192provider",op:"generation turn",kind:v?"context-overflow":te.kind,retry:v?{disposition:"fatal"}:E==="auto"?{disposition:"auto",by:"daemon",...M!==void 0?{nextAt:new Date(M).toISOString()}:{},...d?.attempt!==void 0?{attempt:d.attempt}:{}}:{disposition:E,...x!==void 0?{nextAt:new Date(x).toISOString()}:{}},message:k,...!v&&E==="auto"&&d!==null?{since:d.since}:{},anchor_entry_id:!v&&E==="auto"&&d?.anchorEntryId!==void 0?d.anchorEntryId:s.sessionManager.getLeafId?.()??void 0,...P===void 0?{}:{provider_error:P}};_.retry.disposition==="auto"?await this.recordPendingProviderFault(s,_):(await this.clearEpisode(s),await this.clearFault("pi\u2192provider"),await this.recordFault(_))}async recoverOnStartup(){const e=this.deps.installedGeneration();if(e===void 0)return"none";const t=(await this.state()).episode,i=this.sessionId(e.session);if(this.deps.cfg.newCycle===!0)return t!==null&&i!==null&&t.session_id===i&&await b(this.deps.nodeId,{op:"invalidate",session_id:i}),"none";if(t===null||i===null||t.session_id!==i)return"none";if(t.state==="admitted")if(t.fault.anchor_entry_id!==void 0&&!this.hasProgressPastAnchor(e.session,t.fault.anchor_entry_id)){if(!(await b(this.deps.nodeId,{op:"reopen",session_id:i})).applied)return"none"}else return await this.clearEpisode(e.session),"none";else if(t.state!=="pending")return"none";return await this.recordFault(S(w(t.fault))),await this.schedule(),"retry-armed"}hasProgressPastAnchor(e,t){const i=e.sessionManager.getBranch(),n=i.findIndex(a=>a.id===t);return(n===-1?i:i.slice(n+1)).some(a=>{if(a.type!=="message")return!1;const{message:c}=a;return c.role==="toolResult"?!0:c.role==="assistant"&&Array.isArray(c.content)&&c.content.length>0})}async schedule(){const e=this.deps.installedGeneration(),t=this.deps.currentSession();if(t.isStreaming||this.timer!==null)return;if(e===void 0){this.abandonTurnEnd();return}const i=await this.state(),n=i.fault;if(!this.isActiveAutoFault(n)||this.sessionId(t)!==null&&!this.pendingEpisodeMatches(t,n,i)){this.clearTimer(),this.abandonTurnEnd();return}const o=Date.now(),a=this.faultRetryDelayMs(n,o);if(a!==null&&this.deps.turnEnds?.holding()===!0&&ye(n.since,a,o)){await this.endRunTurnOnFault(t,n,a);return}a!==null?this.clearAndArmFaultRetry(a,e):this.abandonTurnEnd()}async endRunTurnOnFault(e,t,i){this.clearTimer(),this.abandonTurnEnd(),F({level:"info",event:"broker.runtime.diagnostic",fields:{message:`run turn completed on provider fault: ${t.kind} retry in ${i}ms is past the ${Q}ms turn window (since ${t.since}, attempt ${t.retry.attempt??0})`}}),await this.clearEpisode(e),await this.clearFault("pi\u2192provider")}async rearmIfStranded(){if(this.timer!==null||this.deps.installedGeneration()===void 0)return;const e=this.deps.currentSession();if(e.isStreaming)return;const t=await this.state();!this.isActiveAutoFault(t.fault)||!this.pendingEpisodeMatches(e,t.fault,t)||await this.schedule()}maybeSwitchProviderForRetry(e){if(e.type!=="auto_retry_start")return;const t=N("pi\u2192provider",e.errorMessage??"").kind;if(t!=="rate-limit"&&t!=="connection"||this.providerFallbackInFlight!==null||this.deps.cfg.modelExact===!0)return;const i=this.deps.installedGeneration();if(i===void 0)return;const n=this.deps.currentSession(),o=this.deps.currentServices(),a=this.deps.formatModelSpec(n.model,n.thinkingLevel);if(a===null)return;const c=Y(this.deps.cfg.model,G(),!1);if(c===void 0)return;const s=B(c,$()??this.deps.cfg.cwd,L()),l=X(a),p=Z(s,l),h=p===void 0?{route:void 0,capacityExhausted:!1}:this.nextEligibleFallbackRoute(s.slice(p+1),this.deps.registryOf(o),n.getContextUsage()?.tokens,d=>!this.failedRetryRoutes.has(d.routeId));if(h.route===void 0){h.capacityExhausted&&(this.stageCapacityFailure(i,n),queueMicrotask(()=>{this.deps.installedGeneration()===i&&this.deps.currentSession()===n&&n.abortRetry()}));return}const f=h.route,m=(async()=>{const d=this.deps.registryOf(o).find(f.providerId,f.modelId);if(!d||(await n.setModel(d),this.deps.installedGeneration()!==i||this.deps.currentSession()!==n))return;const g=`${f.providerId}/${f.modelId}`===l.modelSpec?l.thinkingLevel:f.thinkingLevel;n.setThinkingLevel(g??"off"),this.failedRetryRoutes.add(f.routeId),await this.deps.broadcastModelChanged(!1)})().catch(d=>{F({level:"debug",event:"broker.runtime.diagnostic",fields:{message:`provider route fallback failed: ${d instanceof Error?d.message:String(d)}`}})}).finally(()=>{this.deps.installedGeneration()===i&&(this.providerFallbackInFlight=null)});this.providerFallbackInFlight=m}maybeFallbackOnUnusableModel(e){if(e.type!=="message_end"||e.message.role!=="assistant"||e.message.stopReason!=="error")return;const t=re(e.message.errorMessage??"");if(!t&&!ne(e.message.errorMessage??"")||this.deps.cfg.modelExact===!0||this.notFoundFallbackInFlight!==null)return;const i=this.deps.installedGeneration();if(i===void 0)return;const n=this.deps.currentSession(),o=this.deps.currentServices(),a=this.deps.formatModelSpec(n.model,n.thinkingLevel);if(a===null)return;const c=X(a);this.notFoundModels.add(c.modelSpec);const s=Y(this.deps.cfg.model,G(),!1),l=s?B(s,$()??this.deps.cfg.cwd,L()):[],p=Z(l,c),h=p===void 0?{route:void 0,capacityExhausted:!1}:this.nextEligibleFallbackRoute(l.slice(p+1),this.deps.registryOf(o),n.getContextUsage()?.tokens,g=>!this.notFoundModels.has(`${g.providerId}/${g.modelId}`));if(h.route===void 0){h.capacityExhausted&&this.stageCapacityFailure(i,n);return}const f=h.route,m=`${f.providerId}/${f.modelId}${f.thinkingLevel?`:${f.thinkingLevel}`:""}`,d=(async()=>{const g=this.deps.registryOf(o).find(f.providerId,f.modelId);if(g===void 0){F({level:"debug",event:"broker.runtime.diagnostic",fields:{message:`${t?"unconfigured-provider":"not_found"} fallback skipped: ${m} is not registered`}});return}if(await n.setModel(g),this.deps.installedGeneration()!==i||this.deps.currentSession()!==n)return;n.setThinkingLevel(f.thinkingLevel??"off"),await this.deps.broadcastModelChanged();const u=this.deps.formatModelSpec(n.model,n.thinkingLevel)??m;if(F({level:"debug",event:"broker.runtime.diagnostic",fields:{message:`${t?"unconfigured-provider":"not_found"} fallback: ${a} unavailable \u2192 ${u}; re-driving turn`}}),await n.agent.waitForIdle(),this.deps.installedGeneration()!==i||this.deps.currentSession()!==n)return;t&&await this.clearFault("pi\u2192provider");const k=q("recovery",{},pe(a,u,t?"credential":"not-found"));H(k,{type:"runtime",kind:"recovery"}),await this.deps.turnAdmission.admit(v=>W.fresh(()=>n.prompt(k,{preflightResult:v})))})().catch(g=>{F({level:"debug",event:"broker.runtime.diagnostic",fields:{message:`${t?"unconfigured-provider":"not_found"} fallback failed: ${g instanceof Error?g.message:String(g)}`}})}).finally(()=>{this.deps.installedGeneration()===i&&(this.notFoundFallbackInFlight=null)});this.notFoundFallbackInFlight=d}nextEligibleFallbackRoute(e,t,i,n){let o=0,a=0;for(const c of e){if(!n(c)||fe([{...c,...de(c,t),automaticFallback:!0}]).candidates.length===0)continue;const s=t.find(c.providerId,c.modelId);if(s!==void 0){if(o++,this.targetCannotFitContext(s.contextWindow,i)){a++;continue}return{route:c,capacityExhausted:!1}}}return{route:void 0,capacityExhausted:o>0&&o===a}}targetCannotFitContext(e,t){return Number.isFinite(e)&&Number.isFinite(t)&&e<t}stageCapacityFailure(e,t){const i=t.getContextUsage()?.tokens;this.stagedCapacityFailure={generation:e,errorMessage:Number.isFinite(i)?`All available fallback models have context windows smaller than the current conversation (${i} tokens).`:"All available fallback models have context windows smaller than the current conversation."}}async recordPendingProviderFault(e,t){const i=this.sessionId(e);if(i===null){await this.recordFault(t);return}await b(this.deps.nodeId,{op:"record-pending",session_id:i,input:t})}pendingEpisodeMatches(e,t,i){const n=this.sessionId(e),o=i.episode;return n!==null&&o!==null&&o.state==="pending"&&o.session_id===n&&o.fault.fault_id===t.fault_id}faultRetryDelayMs(e,t){if(e.retry.nextAt!==void 0){const i=Date.parse(e.retry.nextAt)-t;return Number.isFinite(i)?Math.max(0,i):null}return j(w(e),t)?.delayMs??null}clearAndArmFaultRetry(e,t){if(this.deps.installedGeneration()!==t)return;this.clearTimer();const i=Math.min(Math.max(0,e),ge),n=Math.max(0,e-i);this.timer=setTimeout(()=>{if(this.timer=null,this.deps.installedGeneration()===t){if(n>0){this.clearAndArmFaultRetry(n,t);return}this.runFaultRetry().catch(o=>{this.abandonTurnEnd(),F({level:"warn",event:"broker.runtime.diagnostic",fields:{message:`fault retry fire failed: ${o instanceof Error?o.message:String(o)}`}})})}},i),typeof this.timer.unref=="function"&&this.timer.unref()}async runFaultRetry(){await this.attemptFaultRetry()===void 0&&this.abandonTurnEnd()}async attemptFaultRetry(){const e=this.deps.installedGeneration();if(e===void 0)return;const t=e.session;if(t.isStreaming)return;const i=(await this.state()).fault;if(!this.isActiveAutoFault(i))return;let n=i;if(i.kind==="connection"&&this.deps.turnEnds===void 0){const l=await this.deps.retryProbe();if(this.deps.installedGeneration()!==e||this.deps.currentSession()!==t||t.isStreaming)return;const p=(await this.state()).fault;if(!this.isActiveAutoFault(p)||p.since!==i.since)return;if(!l)return this.clearAndArmFaultRetry(J(p.kind).baseDelayMs,e),"rearmed";n=p}const o=this.deps.turnEnds!==void 0,a=n.retry.attempt??0,c=J(n.kind);if(a>=c.max){await this.recordFault(S(V(w(n)))),await this.clearEpisode(t);return}const s=j(w(n),Date.now());if(s===null){await this.recordFault(S(V(w(n)))),await this.clearEpisode(t);return}if(n.anchor_entry_id!==void 0)try{if((t.sessionManager.getLeafId?.()??null)!==n.anchor_entry_id){const l=await t.navigateTree(n.anchor_entry_id);if(this.deps.installedGeneration()!==e||this.deps.currentSession()!==t)return;l.cancelled||this.deps.reWelcomeAll()}}catch(l){F({level:"debug",event:"broker.runtime.diagnostic",fields:{message:`fault retry rewind skipped: ${l instanceof Error?l.message:String(l)}`}})}if(!(this.deps.installedGeneration()!==e||this.deps.currentSession()!==t))return this.deps.turnAdmission.admit(async l=>{const p=(await this.state()).fault;if(this.deps.installedGeneration()!==e||this.deps.currentSession()!==t||t.isStreaming||!this.isActiveAutoFault(p)||p.since!==n.since){l();return}const h=this.sessionId(t);if(h===null){l();return}if(!(await b(this.deps.nodeId,{op:"admit",session_id:h,fault_id:p.fault_id,retry:s.fault.retry})).applied){l();return}const m=q("recovery",o?{attempt:s.attempt}:{attempt:s.attempt,max:s.max},ve(n.kind,o));H(m,{type:"runtime",kind:"recovery"}),this.deps.turnEnds?.beginRecovery();try{await W.fresh(()=>t.prompt(m,{preflightResult:l}))}finally{this.deps.turnEnds?.recoveryReturned()}return"prompted"})}}export{Be as FaultRetry,Q as RUN_TURN_RETRY_WINDOW_MS,ke as isPrefillRejectionDuringEpisode,ve as retryCardBody,ye as runTurnRetryExpired,ee as settledProviderFault,Ue as willDaemonRetry};
|
|
1
|
+
var ae=Object.defineProperty;var h=(r,e)=>ae(r,"name",{value:e,configurable:!0});import{envModelIntent as N,envNodeCwd as G,envProfileId as U}from"../../../shared/env.js";import{isContextOverflow as Y}from"@earendil-works/pi-ai";import{classify as B}from"../../fault-classifier.js";import{isDaemonTransportApiError as de}from"../../../api/errors.js";import{isModelNotFoundError as le,isProviderUnconfiguredError as ce}from"../fault.js";import{brokerRecovery as ue,mutateBrokerFault as W,mutateBrokerProviderRetry as _}from"./daemon-ops.js";import{extractCoolingDeadline as pe}from"../managed-provider-cooling.js";import{extractProviderFailureDetails as fe}from"../../provider-failure.js";import{expandModelCandidates as q,modelRequestFromConfig as V,probeRouteAvailability as he}from"../../model-routes.js";import{operationIdContext as j}from"../../events/operation-id.js";import{emitEvent as w}from"../../events/emit.js";import{CONNECTION_FAULT_RECOVERY_BODY as me,PROVIDER_FAULT_RECOVERY_BODY as ge,RUN_CONNECTION_FAULT_RETRY_BODY as ye,formatCard as X,formatModelFallbackRecovery as ve}from"../../../shared/generated-context.js";import{markFatalOnExhaust as J,nextFaultRetry as z,policyFor as H}from"../fault-recovery.js";import{parseModelSpec as K}from"../model-selection.js";import{endedByAbort as Q}from"../session-cycles.js";import{resolveProviderCandidates as Fe}from"../../subscription-state.js";import{announceMessageOrigin as Z}from"../stamp/channel.js";import{LLM_REFUSAL_DIAGNOSTIC as we,refusalRetryAt as ke}from"./model-adapter.js";import{isSafetyRefusal as ee}from"../../llm/refusal.js";const be=2147483647,te=3e4;function _e(r,e,t){const n=Date.parse(r);return!Number.isFinite(n)||t+e-n>te}h(_e,"runTurnRetryExpired");class ne extends Error{static{h(this,"StaleOutcome")}}const Ee=1e3,Ie=3e4;function Re(r,e){return r!=="connection"?ge:e?ye:me}h(Re,"retryCardBody");function E(r){return{link:r.link,op:r.op,kind:r.kind,retry:r.retry,message:r.message,since:r.since,operation_id:r.operation_id,...r.anchor_entry_id===void 0?{}:{anchorEntryId:r.anchor_entry_id},...r.provider_error===void 0?{}:{providerError:r.provider_error}}}h(E,"policyFault");function x(r){return{link:r.link,op:r.op,kind:r.kind,retry:r.retry,message:r.message,...r.operation_id===void 0?{}:{operation_id:r.operation_id},...r.since===void 0?{}:{since:r.since},...r.anchorEntryId===void 0?{}:{anchor_entry_id:r.anchorEntryId},...r.providerError===void 0?{}:{provider_error:r.providerError}}}h(x,"faultInput");function ie(r,e){const t=h(n=>`${n.providerId}/${n.modelId}`===e.modelSpec,"onLiveModel");return(r.find(n=>t(n)&&n.thinkingLevel===e.thinkingLevel)??r.find(t))?.rank}h(ie,"liveRouteRank");function re(r){const e=B("pi\u2192provider",r),t=r.diagnostics?.some(n=>n.type===we)??!1;return{classified:e,disposition:t?"fatal":e.disposition}}h(re,"settledProviderFault");function He(r,e){if(r.stopReason!=="error"||Q(r)||ee(r)||Y(r,e))return!1;const{classified:t,disposition:n}=re(r);return n==="auto"&&(t.kind==="connection"||t.kind==="rate-limit"||t.kind==="overloaded")}h(He,"willDaemonRetry");const Se=/does not support assistant message prefill|conversation must end with a user message/i;function Ae(r,e){return e&&Se.test(r)}h(Ae,"isPrefillRejectionDuringEpisode");class Ke{static{h(this,"FaultRetry")}deps;timer=null;failedRetryRoutes=new Set;notFoundModels=new Set;providerFallbackInFlight=null;notFoundFallbackInFlight=null;stagedCapacityFailure=null;agentStarts=0;constructor(e){this.deps=e}clearTimer(){this.timer!==null&&(clearTimeout(this.timer),this.timer=null)}reset(){this.clearTimer(),this.deps.turnEnds?.abandon(),this.providerFallbackInFlight=null,this.notFoundFallbackInFlight=null,this.stagedCapacityFailure=null}abandonTurnEnd(){this.deps.turnEnds?.abandon()}state(){return ue(this.deps.nodeId)}async recordFault(e){return(await W(this.deps.nodeId,{op:"record",input:e})).fault}async clearFault(e,t=!1){await W(this.deps.nodeId,{op:"clear",...e===void 0?{}:{link:e},...t?{preserve_episode:!0}:{}})}sessionId(e){const t=e.sessionManager.getSessionId?.();return typeof t=="string"&&t!==""?t:null}async clearEpisode(e){const t=this.sessionId(e);t!==null&&await _(this.deps.nodeId,{op:"clear",session_id:t})}onEvent(e){e.type==="agent_start"&&this.agentStarts++,this.maybeSwitchProviderForRetry(e),this.maybeFallbackOnUnusableModel(e)}isActiveAutoFault(e){return e===null||e.retry.disposition!=="auto"||e.retry.by!=="daemon"?!1:e.kind==="connection"||e.kind==="rate-limit"||e.kind==="overloaded"}async publishSettledProviderFault(e){const t={agentEnd:e.stagedProviderAgentEnd,watchdogAbort:e.stagedWatchdogAbort,refreshAbort:e.stagedRefreshAbort,overflowFailure:e.stagedOverflowFailure,capacityFailure:this.stagedCapacityFailure?.generation===e?this.stagedCapacityFailure:null};this.stagedCapacityFailure=null,e.stagedProviderAgentEnd=null,e.stagedWatchdogAbort=!1,e.stagedRefreshAbort=!1,e.stagedOverflowFailure=null;const n=this.agentStarts,i=h(()=>{if(this.deps.installedGeneration()!==e||this.agentStarts!==n)throw new ne},"assertCurrent");let a=Ee;try{for(;;){try{await this.recordStagedOutcome(e,t,i);return}catch(o){if(!de(o))throw o;w({level:"warn",event:"broker.runtime.diagnostic",fields:{message:`settled turn fault write waiting for the daemon: ${o.message}`}})}await new Promise(o=>setTimeout(o,a)),a=Math.min(a*2,Ie),i()}}catch(o){if(!(o instanceof ne))throw o}}async recordStagedOutcome(e,t,n){const{agentEnd:i,watchdogAbort:a,refreshAbort:o,overflowFailure:d,capacityFailure:p}=t,s=e.session,l=h(async F=>{n(),await this.clearEpisode(F)},"clearEpisode"),y=h(async F=>{n(),await this.recordFault(F)},"recordFault"),u=h(async(F,oe)=>{n(),await this.recordPendingProviderFault(F,oe)},"recordPendingProviderFault"),v=await this.state(),m=v.fault,f=v.episode,I=this.sessionId(s),k=this.isActiveAutoFault(m)&&m.link==="pi\u2192provider"?m:f?.state==="admitted"&&f.session_id===I&&this.isActiveAutoFault(f.fault)?f.fault:null,g=k===null?null:{since:k.since,anchorEntryId:k.anchor_entry_id,attempt:k.retry.attempt},c=[...Array.isArray(i?.messages)?i.messages:[]].reverse().find(F=>typeof F=="object"&&F!==null&&F.role==="assistant");if(p!==null||d!==null){await l(s),await y({link:"pi\u2192provider",op:"context overflow recovery",kind:"context-overflow",retry:{disposition:"fatal"},message:p?.errorMessage??d.errorMessage,anchor_entry_id:s.sessionManager.getLeafId?.()??void 0});return}if(a&&c?.stopReason==="aborted"){await u(s,{link:"pi\u2192provider",op:"generation turn",kind:"connection",retry:{disposition:"auto",by:"daemon",...g?.attempt!==void 0?{attempt:g.attempt}:{}},message:typeof c.errorMessage=="string"?c.errorMessage:"engine error (no errorMessage recorded)",...g!==null?{since:g.since}:{},anchor_entry_id:g?.anchorEntryId??s.sessionManager.getLeafId?.()??void 0});return}if(c?.stopReason!=="error"){c!==void 0&&await l(s);return}if(o){await l(s);return}if(ee(c)){await l(s);return}const S=typeof c.errorMessage=="string"?c.errorMessage:"engine error (no errorMessage recorded)";if(Q({stopReason:"error",errorMessage:S})){await l(s);return}const b=Y(c,s.model?.contextWindow),A=re(c),T=g!==null&&A.disposition!=="auto"&&Ae(S,!0),se=T?{kind:"connection",disposition:"auto"}:A.classified,R=T?"auto":A.disposition,C=pe(c),O=ke(c),P=fe(c),$=typeof c.provider=="string"&&c.provider!==""?c.provider:s.model?.provider,L=typeof c.model=="string"&&c.model!==""?c.model:s.model?.id,D=P===void 0||$===void 0||L===void 0?void 0:{provider:$,model:L,...P};b&&await l(s);const M={link:"pi\u2192provider",op:"generation turn",kind:b?"context-overflow":se.kind,retry:b?{disposition:"fatal"}:R==="auto"?{disposition:"auto",by:"daemon",...C!==void 0?{nextAt:new Date(C).toISOString()}:{},...g?.attempt!==void 0?{attempt:g.attempt}:{}}:{disposition:R,...O!==void 0?{nextAt:new Date(O).toISOString()}:{}},message:S,...!b&&R==="auto"&&g!==null?{since:g.since}:{},anchor_entry_id:!b&&R==="auto"&&g?.anchorEntryId!==void 0?g.anchorEntryId:s.sessionManager.getLeafId?.()??void 0,...D===void 0?{}:{provider_error:D}};M.retry.disposition==="auto"?await u(s,M):(await l(s),await y(M))}async recoverOnStartup(){const e=this.deps.installedGeneration();if(e===void 0)return"none";const t=(await this.state()).episode,n=this.sessionId(e.session);if(this.deps.cfg.newCycle===!0)return t!==null&&n!==null&&t.session_id===n&&await _(this.deps.nodeId,{op:"invalidate",session_id:n}),"none";if(t===null||n===null||t.session_id!==n)return"none";if(t.state==="admitted")if(t.fault.anchor_entry_id!==void 0&&!this.hasProgressPastAnchor(e.session,t.fault.anchor_entry_id)){if(!(await _(this.deps.nodeId,{op:"reopen",session_id:n})).applied)return"none"}else return await this.clearEpisode(e.session),"none";else if(t.state!=="pending")return"none";return await this.recordFault(x(E(t.fault))),await this.schedule(),"retry-armed"}hasProgressPastAnchor(e,t){const n=e.sessionManager.getBranch(),i=n.findIndex(o=>o.id===t);return(i===-1?n:n.slice(i+1)).some(o=>{if(o.type!=="message")return!1;const{message:d}=o;return d.role==="toolResult"?!0:d.role==="assistant"&&Array.isArray(d.content)&&d.content.length>0})}async schedule(){const e=this.deps.installedGeneration(),t=this.deps.currentSession();if(t.isStreaming||this.timer!==null)return;if(e===void 0){this.abandonTurnEnd();return}const n=await this.state(),i=n.fault;if(!this.isActiveAutoFault(i)||this.sessionId(t)!==null&&!this.pendingEpisodeMatches(t,i,n)){this.clearTimer(),this.abandonTurnEnd();return}const a=Date.now(),o=this.faultRetryDelayMs(i,a);if(o!==null&&this.deps.turnEnds?.holding()===!0&&_e(i.since,o,a)){await this.endRunTurnOnFault(t,i,o);return}o!==null?this.clearAndArmFaultRetry(o,e):this.abandonTurnEnd()}async endRunTurnOnFault(e,t,n){this.clearTimer(),this.abandonTurnEnd(),w({level:"info",event:"broker.runtime.diagnostic",fields:{message:`run turn completed on provider fault: ${t.kind} retry in ${n}ms is past the ${te}ms turn window (since ${t.since}, attempt ${t.retry.attempt??0})`}}),await this.clearEpisode(e),await this.clearFault("pi\u2192provider")}async rearmIfStranded(){if(this.timer!==null||this.deps.installedGeneration()===void 0)return;const e=this.deps.currentSession();if(e.isStreaming)return;const t=await this.state();!this.isActiveAutoFault(t.fault)||!this.pendingEpisodeMatches(e,t.fault,t)||await this.schedule()}maybeSwitchProviderForRetry(e){if(e.type!=="auto_retry_start")return;const t=B("pi\u2192provider",e.errorMessage??"").kind;if(t!=="rate-limit"&&t!=="connection"||this.providerFallbackInFlight!==null||this.deps.cfg.modelExact===!0)return;const n=this.deps.installedGeneration();if(n===void 0)return;const i=this.deps.currentSession(),a=this.deps.currentServices(),o=this.deps.formatModelSpec(i.model,i.thinkingLevel);if(o===null)return;const d=V(this.deps.cfg.model,N(),!1);if(d===void 0)return;const p=q(d,G()??this.deps.cfg.cwd,U()),s=K(o),l=ie(p,s),y=l===void 0?{route:void 0,capacityExhausted:!1}:this.nextEligibleFallbackRoute(p.slice(l+1),this.deps.registryOf(a),i.getContextUsage()?.tokens,m=>!this.failedRetryRoutes.has(m.routeId));if(y.route===void 0){y.capacityExhausted&&(this.stageCapacityFailure(n,i),queueMicrotask(()=>{this.deps.installedGeneration()===n&&this.deps.currentSession()===i&&i.abortRetry()}));return}const u=y.route,v=(async()=>{const m=this.deps.registryOf(a).find(u.providerId,u.modelId);if(!m||(await i.setModel(m),this.deps.installedGeneration()!==n||this.deps.currentSession()!==i))return;const f=`${u.providerId}/${u.modelId}`===s.modelSpec?s.thinkingLevel:u.thinkingLevel;i.setThinkingLevel(f??"off"),this.failedRetryRoutes.add(u.routeId),await this.deps.broadcastModelChanged(!1)})().catch(m=>{w({level:"debug",event:"broker.runtime.diagnostic",fields:{message:`provider route fallback failed: ${m instanceof Error?m.message:String(m)}`}})}).finally(()=>{this.deps.installedGeneration()===n&&(this.providerFallbackInFlight=null)});this.providerFallbackInFlight=v}maybeFallbackOnUnusableModel(e){if(e.type!=="message_end"||e.message.role!=="assistant"||e.message.stopReason!=="error")return;const t=ce(e.message.errorMessage??"");if(!t&&!le(e.message.errorMessage??"")||this.deps.cfg.modelExact===!0||this.notFoundFallbackInFlight!==null)return;const n=this.deps.installedGeneration();if(n===void 0)return;const i=this.deps.currentSession(),a=this.deps.currentServices(),o=this.deps.formatModelSpec(i.model,i.thinkingLevel);if(o===null)return;const d=K(o);this.notFoundModels.add(d.modelSpec);const p=V(this.deps.cfg.model,N(),!1),s=p?q(p,G()??this.deps.cfg.cwd,U()):[],l=ie(s,d),y=l===void 0?{route:void 0,capacityExhausted:!1}:this.nextEligibleFallbackRoute(s.slice(l+1),this.deps.registryOf(a),i.getContextUsage()?.tokens,f=>!this.notFoundModels.has(`${f.providerId}/${f.modelId}`));if(y.route===void 0){y.capacityExhausted&&this.stageCapacityFailure(n,i);return}const u=y.route,v=`${u.providerId}/${u.modelId}${u.thinkingLevel?`:${u.thinkingLevel}`:""}`,m=(async()=>{const f=this.deps.registryOf(a).find(u.providerId,u.modelId);if(f===void 0){w({level:"debug",event:"broker.runtime.diagnostic",fields:{message:`${t?"unconfigured-provider":"not_found"} fallback skipped: ${v} is not registered`}});return}if(await i.setModel(f),this.deps.installedGeneration()!==n||this.deps.currentSession()!==i)return;i.setThinkingLevel(u.thinkingLevel??"off"),await this.deps.broadcastModelChanged();const I=this.deps.formatModelSpec(i.model,i.thinkingLevel)??v;if(w({level:"debug",event:"broker.runtime.diagnostic",fields:{message:`${t?"unconfigured-provider":"not_found"} fallback: ${o} unavailable \u2192 ${I}; re-driving turn`}}),await i.agent.waitForIdle(),this.deps.installedGeneration()!==n||this.deps.currentSession()!==i)return;t&&await this.clearFault("pi\u2192provider");const k=X("recovery",{},ve(o,I,t?"credential":"not-found"));Z(k,{type:"runtime",kind:"recovery"}),await this.deps.turnAdmission.admit(g=>j.fresh(()=>i.prompt(k,{preflightResult:g})))})().catch(f=>{w({level:"debug",event:"broker.runtime.diagnostic",fields:{message:`${t?"unconfigured-provider":"not_found"} fallback failed: ${f instanceof Error?f.message:String(f)}`}})}).finally(()=>{this.deps.installedGeneration()===n&&(this.notFoundFallbackInFlight=null)});this.notFoundFallbackInFlight=m}nextEligibleFallbackRoute(e,t,n,i){let a=0,o=0;for(const d of e){if(!i(d)||Fe([{...d,...he(d,t),automaticFallback:!0}]).candidates.length===0)continue;const p=t.find(d.providerId,d.modelId);if(p!==void 0){if(a++,this.targetCannotFitContext(p.contextWindow,n)){o++;continue}return{route:d,capacityExhausted:!1}}}return{route:void 0,capacityExhausted:a>0&&a===o}}targetCannotFitContext(e,t){return Number.isFinite(e)&&Number.isFinite(t)&&e<t}stageCapacityFailure(e,t){const n=t.getContextUsage()?.tokens;this.stagedCapacityFailure={generation:e,errorMessage:Number.isFinite(n)?`All available fallback models have context windows smaller than the current conversation (${n} tokens).`:"All available fallback models have context windows smaller than the current conversation."}}async recordPendingProviderFault(e,t){const n=this.sessionId(e);if(n===null){await this.recordFault(t);return}await _(this.deps.nodeId,{op:"record-pending",session_id:n,input:t})}pendingEpisodeMatches(e,t,n){const i=this.sessionId(e),a=n.episode;return i!==null&&a!==null&&a.state==="pending"&&a.session_id===i&&a.fault.fault_id===t.fault_id}faultRetryDelayMs(e,t){if(e.retry.nextAt!==void 0){const n=Date.parse(e.retry.nextAt)-t;return Number.isFinite(n)?Math.max(0,n):null}return z(E(e),t)?.delayMs??null}clearAndArmFaultRetry(e,t){if(this.deps.installedGeneration()!==t)return;this.clearTimer();const n=Math.min(Math.max(0,e),be),i=Math.max(0,e-n);this.timer=setTimeout(()=>{if(this.timer=null,this.deps.installedGeneration()===t){if(i>0){this.clearAndArmFaultRetry(i,t);return}this.runFaultRetry().catch(a=>{this.abandonTurnEnd(),w({level:"warn",event:"broker.runtime.diagnostic",fields:{message:`fault retry fire failed: ${a instanceof Error?a.message:String(a)}`}})})}},n),typeof this.timer.unref=="function"&&this.timer.unref()}async runFaultRetry(){await this.attemptFaultRetry()===void 0&&this.abandonTurnEnd()}async attemptFaultRetry(){const e=this.deps.installedGeneration();if(e===void 0)return;const t=e.session;if(t.isStreaming)return;const n=(await this.state()).fault;if(!this.isActiveAutoFault(n))return;let i=n;if(n.kind==="connection"&&this.deps.turnEnds===void 0){const s=await this.deps.retryProbe();if(this.deps.installedGeneration()!==e||this.deps.currentSession()!==t||t.isStreaming)return;const l=(await this.state()).fault;if(!this.isActiveAutoFault(l)||l.since!==n.since)return;if(!s)return this.clearAndArmFaultRetry(H(l.kind).baseDelayMs,e),"rearmed";i=l}const a=this.deps.turnEnds!==void 0,o=i.retry.attempt??0,d=H(i.kind);if(o>=d.max){await this.recordFault(x(J(E(i)))),await this.clearEpisode(t);return}const p=z(E(i),Date.now());if(p===null){await this.recordFault(x(J(E(i)))),await this.clearEpisode(t);return}if(i.anchor_entry_id!==void 0)try{if((t.sessionManager.getLeafId?.()??null)!==i.anchor_entry_id){const s=await t.navigateTree(i.anchor_entry_id);if(this.deps.installedGeneration()!==e||this.deps.currentSession()!==t)return;s.cancelled||this.deps.reWelcomeAll()}}catch(s){w({level:"debug",event:"broker.runtime.diagnostic",fields:{message:`fault retry rewind skipped: ${s instanceof Error?s.message:String(s)}`}})}if(!(this.deps.installedGeneration()!==e||this.deps.currentSession()!==t))return this.deps.turnAdmission.admit(async s=>{const l=(await this.state()).fault;if(this.deps.installedGeneration()!==e||this.deps.currentSession()!==t||t.isStreaming||!this.isActiveAutoFault(l)||l.since!==i.since){s();return}const y=this.sessionId(t);if(y===null){s();return}if(!(await _(this.deps.nodeId,{op:"admit",session_id:y,fault_id:l.fault_id,retry:p.fault.retry})).applied){s();return}const v=X("recovery",a?{attempt:p.attempt}:{attempt:p.attempt,max:p.max},Re(i.kind,a));Z(v,{type:"runtime",kind:"recovery"}),this.deps.turnEnds?.beginRecovery();try{await j.fresh(()=>t.prompt(v,{preflightResult:s}))}finally{this.deps.turnEnds?.recoveryReturned()}return"prompted"})}}export{Ke as FaultRetry,te as RUN_TURN_RETRY_WINDOW_MS,Ae as isPrefillRejectionDuringEpisode,Re as retryCardBody,_e as runTurnRetryExpired,re as settledProviderFault,He as willDaemonRetry};
|
|
@@ -59,6 +59,8 @@ export declare class RebindDriver {
|
|
|
59
59
|
private latestRebindRequest;
|
|
60
60
|
private replacementTail;
|
|
61
61
|
private admittedReplacements;
|
|
62
|
+
private rebindsInFlight;
|
|
63
|
+
private rebinding;
|
|
62
64
|
private agentRunActiveValue;
|
|
63
65
|
private shutdownRequested;
|
|
64
66
|
constructor(deps: RebindDriverDeps);
|
|
@@ -67,6 +69,8 @@ export declare class RebindDriver {
|
|
|
67
69
|
installedGeneration(): SubscriptionGeneration | undefined;
|
|
68
70
|
isAgentRunActive(): boolean;
|
|
69
71
|
isReplacing(): boolean;
|
|
72
|
+
/** Resolves when the rebinds requested so far have finished binding extensions (every session_start hook), failed, or been superseded; undefined when none is in flight. */
|
|
73
|
+
pendingRebind(): Promise<void> | undefined;
|
|
70
74
|
requestShutdown(): void;
|
|
71
75
|
setRebindSession(): void;
|
|
72
76
|
enqueueRebind(candidateSession: BrokerSession, candidateServices: AgentSessionServices): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var k=Object.defineProperty;var l=(
|
|
1
|
+
var k=Object.defineProperty;var l=(a,e)=>k(a,"name",{value:e,configurable:!0});import{mkdirSync as v,writeFileSync as _}from"node:fs";import{join as I}from"node:path";import{nodeRunJobDir as A}from"../../canvas/paths.js";import{emitEvent as u}from"../../events/emit.js";import{operationIdContext as c}from"../../events/operation-id.js";import{installPersonaTransitionGate as E}from"../broker-persona-guidance.js";import{installRetryCardElision as T}from"./retry-card-elision.js";import{abortSessionFromExtension as w}from"./extension-abort.js";import{brokerRecovery as S,mutateBrokerFault as x,mutateBrokerProviderRetry as P}from"./daemon-ops.js";const f=2,m=3e4,b=Symbol("replacement-deadline-exceeded"),V="(interrupted)",g=Symbol.for("crtr.trailing-thinking-guard");function C(a){for(let e=a.length-1;e>=0;e--){const t=a[e];if(t!==void 0){if(t.type==="text"){if(t.text.trim().length===0)continue;return t}if(t.type==="thinking"){const d=t.thinkingSignature,r=typeof d=="string"&&d.trim().length>0;if(t.redacted!==!0&&t.thinking.trim().length===0&&!r)continue;return t}return t}}}l(C,"lastSerializedBlock");function y(a){return a.map(e=>e.role!=="assistant"||e.stopReason==="error"||e.stopReason==="aborted"||C(e.content)?.type!=="thinking"?e:{...e,content:[...e.content,{type:"text",text:V}]})}l(y,"guardTrailingThinking");function N(a){const e=a.convertToLlm;if(e[g]===!0)return;const t=l(d=>{const r=e(d);return r instanceof Promise?r.then(y):y(r)},"wrapped");t[g]=!0,a.convertToLlm=t}l(N,"installTrailingThinkingGuard");class ${static{l(this,"RebindDriver")}deps;sessionValue;servicesValue;unsubscribe;installed;nextSubscriptionGeneration=0;rebindTail=Promise.resolve();latestRebindRequest=0;replacementTail=Promise.resolve();admittedReplacements=0;rebindsInFlight=0;rebinding;agentRunActiveValue=!1;shutdownRequested=!1;constructor(e){this.deps=e,this.sessionValue=e.session,this.servicesValue=e.services}session(){return this.sessionValue}services(){return this.servicesValue}installedGeneration(){return this.installed}isAgentRunActive(){return this.agentRunActiveValue}isReplacing(){return this.admittedReplacements>0}pendingRebind(){return this.rebinding?.done}requestShutdown(){if(!this.agentRunActiveValue){this.deps.disposeAndExit("shutdown-hook");return}this.shutdownRequested=!0}setRebindSession(){this.deps.runtime?.setRebindSession(e=>this.enqueueRebind(e,this.deps.runtime.services))}enqueueRebind(e,t){const d=++this.latestRebindRequest;if(this.rebindsInFlight++===0){let n;this.rebinding={done:new Promise(o=>{n=o}),resolve:n}}const r=this.rebindTail.then(async()=>{if(d!==this.latestRebindRequest)return;if(this.installed!==void 0){typeof this.sessionValue.sessionFile=="string"&&this.sessionValue.sessionFile!==""&&await P(this.deps.nodeId,{op:"invalidate",session_id:this.sessionValue.sessionManager.getSessionId()});const i=(await S(this.deps.nodeId)).fault;i?.link==="pi\u2192provider"&&i.retry.disposition==="auto"&&i.retry.by==="daemon"&&await x(this.deps.nodeId,{op:"clear",link:"pi\u2192provider",preserve_episode:!0})}this.installed?.executingTools.clear(),this.removeInstalledSubscription(),this.deps.setActiveSession(e),this.deps.projection().reset(),this.deps.faultRetry().reset(),this.agentRunActiveValue=!1,this.deps.onSessionRebind(),this.deps.toolGroups.resetForSession(),this.sessionValue=e,this.servicesValue=t;const n=e.agent;n&&(E(this.deps.nodeId,{agent:n,sessionManager:e.sessionManager}),T(n),n.steeringMode="all",n.followUpMode="all",N(n));const o={id:++this.nextSubscriptionGeneration,session:e,fallback:{blocked:!1},stagedProviderAgentEnd:null,stagedWatchdogAbort:!1,stagedRefreshAbort:!1,stagedOverflowFailure:null,executingTools:new Set};if(this.unsubscribe=this.sessionValue.subscribe(i=>{if(!this.deps.projection().isCurrent(o))return;if(c.current()!==void 0){this.executeSubscriptionCallback(o,i);return}const s=o.fallback;if(i.type==="turn_start"&&s.storedId!==void 0){s.storedId=void 0,s.blocked=!0,c.fresh(()=>{u({level:"warn",event:"broker.turn.fallback_overlap",fields:{generation:o.id,engine_event:i.type}}),this.executeSubscriptionCallback(o,i)});return}if(i.type==="turn_start"&&!s.blocked){c.fresh(R=>{s.storedId=R,this.executeSubscriptionCallback(o,i)});return}const h=s.storedId;if(h!==void 0&&!s.blocked){c.run(h,()=>{this.executeSubscriptionCallback(o,i),i.type==="agent_settled"&&s.storedId===h&&(s.storedId=void 0)});return}this.executeSubscriptionCallback(o,i)}),this.installed=o,await e.bindExtensions({uiContext:this.deps.uiContext(),mode:"rpc",abortHandler:l(()=>w(e,()=>{const i=this.installed;i?.session===e&&(i.stagedRefreshAbort=!0)}),"abortHandler"),shutdownHandler:l(()=>this.requestShutdown(),"shutdownHandler")}),d===this.latestRebindRequest){if(this.deps.cfg.editorName!==void 0&&this.deps.cfg.editorName!=="")try{e.setSessionName(this.deps.cfg.editorName)}catch{}try{this.deps.turnReplies.seed(this.deps.transcriptMessages(e))}catch(i){u({level:"debug",event:"broker.runtime.diagnostic",fields:{message:`turn reply seed failed: ${String(i)}`}})}this.deps.projection().rearmIfStreaming(o),this.captureSystemPrompt(e)}}).finally(()=>{--this.rebindsInFlight>0||(this.rebinding?.resolve(),this.rebinding=void 0)});return this.rebindTail=r.catch(()=>{}),r}runReplacement(e,t,d){const r=this.deps.runtime;if(r===void 0){this.deps.registry.sendFrame(e,{type:"error",code:"engine_error",message:"session replacement unsupported at this engine pin"});return}if(this.admittedReplacements>=f){c.fresh(()=>u({level:"warn",event:"broker.session_replacement.rejected",outcome:"skipped",fields:{op:t,reason:"capacity",admitted:f,cap:f}})),this.ackTo(e,t,!1,`session replacement busy (${f} active or queued)`);return}this.admittedReplacements++;const n=this.replacementTail.then(async()=>{try{await c.fresh(async()=>{const o=process.hrtime.bigint();let i;try{const p=new Promise(h=>{i=setTimeout(()=>h(b),m)}),s=await Promise.race([d(r),p]);if(s===b){u({level:"error",event:"broker.session_replacement.timed_out",outcome:"failed",duration_ms:Number(process.hrtime.bigint()-o)/1e6,fields:{op:t,deadline_ms:m,mutation_outcome:"indeterminate"}}),this.ackTo(e,t,!1,"session replacement timed out; broker restarting because session state is indeterminate"),this.deps.disposeAndExit("session-replacement-timeout",1);return}s.cancelled||this.deps.reWelcomeAll(),this.ackTo(e,t,!s.cancelled,s.cancelled?s.detail??"cancelled by extension":void 0)}catch(p){u({level:"error",event:"broker.session_replacement.failed",outcome:"failed",error:p,fields:{op:t,mutation_outcome:"indeterminate"}}),this.ackTo(e,t,!1,"session replacement failed; broker restarting because session state is indeterminate"),this.deps.disposeAndExit("session-replacement-failed",1)}finally{clearTimeout(i)}})}finally{this.admittedReplacements--,this.admittedReplacements===0&&this.deps.onReplacementIdle?.()}});this.replacementTail=n.catch(()=>{})}removeInstalledSubscription(){this.unsubscribe?.(),this.unsubscribe=void 0,this.installed=void 0}captureSystemPrompt(e){try{const t=A(this.deps.nodeId);v(t,{recursive:!0}),_(I(t,"system-prompt.md"),e.systemPrompt,"utf8")}catch{}}executeSubscriptionCallback(e,t){try{t.type==="agent_start"&&(this.agentRunActiveValue=!0),t.type==="agent_end"&&(e.stagedProviderAgentEnd=t,e.stagedOverflowFailure=null),t.type==="compaction_end"&&t.reason==="overflow"&&t.willRetry===!1&&typeof t.errorMessage=="string"&&(e.stagedOverflowFailure={errorMessage:t.errorMessage}),t.type==="agent_settled"&&(this.agentRunActiveValue=!1,this.publishAndScheduleProviderRecovery(e)),this.deps.toolGroups.observeToolGroupEvent(t),this.deps.turnReplies.observe(t),this.deps.projection().relayEvent(t,e)}catch(d){u({level:"debug",event:"broker.runtime.diagnostic",fields:{message:`event relay threw: ${String(d)}`}})}}async publishAndScheduleProviderRecovery(e){try{if(await this.deps.faultRetry().publishSettledProviderFault(e),this.shutdownRequested){this.deps.disposeAndExit("shutdown-after-settle");return}await this.deps.faultRetry().schedule()}catch(t){this.deps.faultRetry().abandonTurnEnd(),u({level:"error",event:"broker.daemon.operation.failed",node_id:this.deps.nodeId,error:t,fields:{operation:"provider_fault_settlement"}}),this.shutdownRequested&&this.deps.disposeAndExit("shutdown-after-settle")}}ackTo(e,t,d=!0,r,n){this.deps.registry.sendFrame(e,{type:"ack",for:t,ok:d,...r!==void 0?{detail:r}:{},...n!==void 0?{id:n}:{}})}}export{$ as RebindDriver};
|
|
@@ -37,6 +37,8 @@ export type RunTurnQueueDeps = {
|
|
|
37
37
|
runNode: boolean;
|
|
38
38
|
session: () => BrokerSession;
|
|
39
39
|
isReplacing: () => boolean;
|
|
40
|
+
/** Set while a rebind is still binding extensions: no turn may start before every session_start hook has finished. */
|
|
41
|
+
pendingRebind: () => Promise<void> | undefined;
|
|
40
42
|
isAgentRunActive: () => boolean;
|
|
41
43
|
/** Frame/kickoff prompt dispatches still igniting. Zero before the frame
|
|
42
44
|
* dispatcher exists. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var R=Object.defineProperty;var i=(n,e)=>R(n,"name",{value:e,configurable:!0});function A(n){const{runNode:e,session:c,turnAdmission:p}=n,o=[];let f=!1,r=!1;const v=i(()=>n.isReplacing()||n.isAgentRunActive()||c().isStreaming,"engineBusy"),d=i(()=>r||f||v(),"mustQueue"),a=i(()=>{if(d())return;const t=o.shift();t&&g(t.text,t.messageIds)},"drain"),g=i((t,s=[])=>{const l=n.pendingRebind();if(l!==void 0){l.then(()=>g(t,s));return}if(e&&d()){o.push({text:t,messageIds:s});return}e&&(f=!0),p.admit(async h=>{const u=c();if(e&&u.isStreaming)return o.unshift({text:t,messageIds:s}),h(),Promise.resolve();const m=e?await n.prependDeferred(u):[];return e&&s.length+m.length>0&&u.sessionManager.appendCustomEntry("crtr-turn-input",{message_ids:[...m,...s]}),u.prompt(t,{preflightResult:h,...!e&&u.isStreaming?{streamingBehavior:"steer"}:{}})}).catch(n.onError).finally(()=>{e&&(f=!1,a())})},"start");return{start:g,drain:a,busy:i(()=>n.pendingRebind()!==void 0||r||f||n.pendingDispatches()>0||n.isAgentRunActive()||c().isStreaming,"busy"),holdForKickoff:i(()=>{e&&(r=!0)},"holdForKickoff"),releaseKickoff:i(()=>{r&&(r=!1,a())},"releaseKickoff"),queued:i(()=>o,"queued")}}i(A,"createRunTurnQueue");export{A as createRunTurnQueue};
|
|
@@ -23,5 +23,5 @@ interface PersonaTransitionSession {
|
|
|
23
23
|
};
|
|
24
24
|
}
|
|
25
25
|
/** Gate each provider request on durable delivery of the current persona delta. */
|
|
26
|
-
export declare function installPersonaTransitionGate(nodeId: string, session: PersonaTransitionSession
|
|
26
|
+
export declare function installPersonaTransitionGate(nodeId: string, session: PersonaTransitionSession): void;
|
|
27
27
|
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var
|
|
2
|
-
`)}a(
|
|
1
|
+
var k=Object.defineProperty;var a=(o,e)=>k(o,"name",{value:e,configurable:!0});import{emitEvent as g}from"../events/emit.js";import{brokerDelivery as b,brokerExtensionState as f,commitBrokerPersonaAck as p}from"./broker/daemon-ops.js";import{buildSubPersonaMenu as m}from"../substrate/delivery/sub-persona-menu.js";import{orchestratorContextNote as v}from"./bearings-render.js";import{formatCard as x}from"../../shared/generated-context.js";function T(o){return[`You are now a ${o.kind.toUpperCase()} ORCHESTRATOR. Your scarce resource is your own context window.`,"Your job is to manage context and delegate \u2014 not to do the goal yourself.","","Your roadmap is your document `roadmap`; it loads at every new session of yours. Author it now with `crtr doc edit roadmap`: state the goal and exit criteria, and set the preview to the goal\u2019s first line, using the approach below.","",v(),"","What promotion changes is how long your documents matter: you now persist across refresh cycles, so the documents you own (`crtr doc write`) carry what this goal needs between your refreshes, and a lesson that should outlive this node gets another owner (`--owner user|repo|profile`).","","Then delegate each unit with `crtr node new --kind <kind>`. When your context fills, run `crtr node yield` to refresh against this roadmap."].join(`
|
|
2
|
+
`)}a(T,"orchestrationGuidance");function C(){return"You are HANDS-ON again \u2014 base mode. Do the work yourself in THIS window and finish it here; stop delegating by default. You no longer drive a roadmap, so `crtr node yield` is not your exit. Spawn a child only for a cleanly separable unit, never as your first move."}a(C,"baseModeGuidance");function P(o,e){if(o.kind===e.kind)return"";const r=m(o.kind),n=m(e.kind);return r===n?"":n===""?`The ${e.kind} kind has no specialist sub-personas available.`:n}a(P,"subPersonaGuidance");function S(o,e,r,n){const t=[];return e.mode!==r.mode&&t.push(r.mode==="orchestrator"?T(o.node):C()),t.push(P(e,r)),t.push(n),t.filter(i=>i!=="").join(`
|
|
3
3
|
|
|
4
|
-
`)}a(
|
|
4
|
+
`)}a(S,"transitionGuidance");function u(o){const e=o.node,r={kind:e.kind,mode:e.mode,lifecycle:e.lifecycle},n=e.persona_ack,t=n===void 0?r:{kind:n.kind??e.kind,mode:n.mode,lifecycle:n.lifecycle};return t.kind===r.kind&&t.mode===r.mode&&t.lifecycle===r.lifecycle?null:{from:t,to:r}}a(u,"personaDriftFromBrokerState");async function M(o){const e=u(o);if(e===null)return!1;if(!(await p(o.node.node_id,e)).applied)throw new Error(`persona baseline acknowledgment was rejected for ${o.node.node_id}`);return!0}a(M,"acknowledgePersonaBaseline");async function D(o,e){const r=o.node.node_id;let n=o,t=u(n);if(t===null)return!1;let i=t.from;for(;;){const s={kind:n.node.kind,mode:n.node.mode,lifecycle:n.node.lifecycle};if(i.kind!==s.kind||i.mode!==s.mode||i.lifecycle!==s.lifecycle){const l=await b(r,{activity:"persona"}),c=S(n,i,s,l.content);c!==""&&await e(x("persona-transition",{},c)),i=s}if(t=u(n),t===null||(await p(r,t)).applied)return!0;n=await f(r)}}a(D,"deliverPendingPersonaTransition");function B(o,e){const{agent:r}=e,n=r.transformContext;r.transformContext=async(t,i)=>{const s=n===void 0?t:await n(t,i);try{const d=await f(o);return await D(d,l=>{const c={nodeId:o},h={role:"custom",customType:"crtr-persona-transition",content:l,display:!0,details:c,timestamp:Date.now()};e.sessionManager.appendCustomMessageEntry("crtr-persona-transition",l,!0,c);const w=r.state.messages;for(const y of new Set([w,t,s]))y.push(h)}),s}catch(d){throw g({event:"broker.daemon.operation.failed",level:"error",node_id:o,error:d,fields:{operation:"persona_transition"}}),d}}}a(B,"installPersonaTransitionGate");export{M as acknowledgePersonaBaseline,D as deliverPendingPersonaTransition,B as installPersonaTransitionGate,u as personaDriftFromBrokerState};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var Pe=Object.defineProperty;var n=(t,o)=>Pe(t,"name",{value:o,configurable:!0});import{envInboxBetweenTurns as Oe,envModelIntent as Ie,envNodeCwd as De,envNodeId as Ne,envProfileId as Fe,envScopes as Le,isSandboxedNode as $e,scopeAllowed as Be}from"../../shared/env.js";import{createServer as Ue}from"node:net";import{existsSync as ye,readFileSync as Ge,unlinkSync as be}from"node:fs";import{join as Te}from"node:path";import{randomUUID as x}from"node:crypto";import{mark as Ke}from"../timing.js";import{SUBMIT_RESULT_TOOL as je}from"./structured-output.js";import{installSessionManagerStorePatch as We}from"../conversation-store/index.js";import{getAgentDir as Y,ModelRegistry as qe,ModelRuntime as Ve}from"@earendil-works/pi-coding-agent";import{nodeRunDir as Xe,viewSocketPath as He}from"../canvas/paths.js";import{bindBrokerEventSource as Ye}from"../events/source.js";import{emitEvent as T,flushBrokerLog as ze}from"../events/emit.js";import{operationIdContext as Je}from"../events/operation-id.js";import{findMissingPackagePaths as Qe}from"./package-health.js";import{installBrokerConfigSnapshot as Ze}from"../config.js";import{FRONT_DOOR_ENV as en}from"./front-door.js";import{CANVAS_EXTENSIONS as re,piInvocationToSdkConfig as nn}from"./launch.js";import{assertEngineVersion as tn,loadBrokerEngine as rn}from"./broker-sdk.js";import{initCrtrTheme as on}from"./crtr-theme.js";import{resolveBundledPiPackageDir as sn}from"./pi-cli.js";import{captureSessionChatCapabilities as an}from"./command-surface.js";import{InMemoryCredentialStore as dn}from"@earendil-works/pi-ai";import{configureBrokerModelRuntime as ln}from"./broker/model-adapter.js";import{mutateBrokerFault as z,recordBrokerTurn as ke}from"./broker/daemon-ops.js";import{modelRequestFromConfig as cn,expandModelCandidates as mn,parseModelSpec as un,unregisteredConcreteModel as fn}from"../model-routes.js";import{KNOWN_STREAM_WAIT_UI as pn}from"./stream-watchdog.js";import{probeOnline as gn}from"./connectivity.js";import{CRTR_CYCLE_CUSTOM_TYPE as vn,cycleAwareMessages as hn,endedByAbort as Sn}from"./session-cycles.js";import{turnErrorOf as _n}from"../llm/refusal.js";import{projectTranscript as wn}from"./session-visibility.js";import{currentTurnVisibility as yn}from"./turn-visibility.js";import{isUnknownModel as oe}from"./model-selection.js";import{BrokerClientRegistry as bn}from"./broker/client-registry.js";import{ToolGroupTracker as Tn}from"./broker/tool-groups.js";import{TurnReplyTracker as kn}from"./broker/turn-replies.js";import{onNodeNamed as En}from"./broker/node-named.js";import{FaultRetry as Rn,willDaemonRetry as Mn}from"./broker/fault-retry.js";import{RunTurnEnds as xn}from"./broker/run-turn-end.js";import{createTurnAdmissionGate as Cn}from"./broker/turn-admission.js";import{BROKER_IDLE_TURN_START as An,BROKER_RUN_TURN_BUSY as Pn}from"./broker/held-deferred-inbox.js";import{prependRunDeferredMail as On,settleRunDeferredMail as In}from"./broker/run-deferred-mail.js";import{createRunTurnQueue as Dn}from"./broker/run-turn-queue.js";import{EventProjection as Nn}from"./broker/event-projection.js";import{createFrameDispatchContext as Fn,handleFrame as Ln}from"./broker/frame-dispatch.js";import{hydratePersistedAdvertisedCommandMessages as $n,installAdvertisedCommandInvocationContract as Bn}from"./advertised-command-invocation.js";import{RebindDriver as Un}from"./broker/rebind.js";import{beginRuntimeTeardown as Gn}from"./broker/extension-abort.js";import{receiveNodeToken as Kn}from"./broker/node-token.js";import{serveCliRelay as jn}from"./broker/cli-relay.js";import{decodeKickoffOrigin as Wn,KICKOFF_ORIGIN_ENV as qn}from"./stamp/protocol.js";import{announceMessageOrigin as Vn}from"./stamp/channel.js";import{brokerExtensionState as Xn,commitBrokerModel as Hn}from"./broker/daemon-ops.js";import{composerNames as Yn}from"./broker/frame-memory-refs.js";import{FrameOverflowError as zn,normalizeSnapshotTail as Jn}from"./broker-protocol.js";import{ReviewBoundaryNavigationError as ur,REVIEW_BOUNDARY_NAVIGATION_CODE as fr}from"./broker/frame-replies.js";function se(t){return new qe(t.modelRuntime)}n(se,"registryOf");function B(t,o){if(t==null||oe(t))return null;const i=o!==void 0&&o!==""&&o!=="off"?`:${o}`:"";return`${t.provider}/${t.id}${i}`}n(B,"formatModelSpec");function Qn(t,o){const i=B(t,void 0);return i===null?null:`${i}:${o===void 0||o===""?"off":o}`}n(Qn,"formatExactModelSpec");const Zn=12e4;let J=null;import{brokerSignalClient as Q}from"./broker/signal-stream.js";function et(){Q().stop();const t=J;if(J=null,t!==null)try{t.dispose()}catch{}}n(et,"disposeActiveSession");function nt(t,o){const i=Be(o,"crtr:act")?void 0:["bash"],m=t!==void 0&&t.length>0?[...new Set([...t,je])]:t===void 0?void 0:[...t];return{...m!==void 0?{tools:m}:{},...i!==void 0?{excludeTools:i}:{}}}n(nt,"brokerToolOptions");async function lr(t,o=process.hrtime.bigint(),i=new Date().toISOString()){Ye(t);const m=await Kn(),s=await jn(t,m);process.env.CRTR_API_SOCKET=s.path,Je.fresh(()=>{T({level:"info",event:"broker.startup.cli_entry",ts:i,duration_ms:0,fields:{runtime_version:process.version,engine_version:null,model:null}}),T({level:"info",event:"broker.startup.module_loaded",duration_ms:Number(process.hrtime.bigint()-o)/1e6,fields:{runtime_version:process.version,engine_version:null,model:null}})});const a=new Set;let l=null;const d=n((e,r=null)=>{a.has(e)||(a.add(e),Ke(e,{duration_ms:Number(process.hrtime.bigint()-o)/1e6}),T({level:"info",event:e,duration_ms:Number(process.hrtime.bigint()-o)/1e6,fields:{runtime_version:process.version,engine_version:l,model:r}}))},"emitStartupMilestone");process.env[en]="1",process.env.CRTR_BROKER_PID=String(process.pid),delete process.env.TMUX_PANE,delete process.env.TMUX,We(t);const p=await rn();tn(p.VERSION),l=p.VERSION;const _=Xe(t),E=Te(_,"broker-launch.json"),w=JSON.parse(Ge(E,"utf8"));if($e()){if(!w.configSnapshot)throw new Error("broker launch is missing its config snapshot");Ze(w.configSnapshot)}const u=nn(w);u.modelExact===!0?process.env.CRTR_MODEL_EXACT="1":delete process.env.CRTR_MODEL_EXACT;const y=await Yn(t);let b,C;const V=n(e=>{b!==void 0?b(e):C??=e},"onSignal");process.on("SIGTERM",()=>V("SIGTERM")),process.on("SIGINT",()=>V("SIGINT"));let{session:U,services:A,resuming:ae,runtime:G}=await st(p,u);d("broker.startup.session_built");const R=(await Xn(t)).node.review_binding?.review_id,k=Oe();J=U;const D=gn;try{process.env.PI_PACKAGE_DIR=sn(),on(A.settingsManager.getTheme(),Y(),!1)}catch(e){T({level:"error",event:"broker.theme.initialization_failed",error:e})}try{for(const e of Qe(Y()))T({level:"warn",event:"broker.startup.warning",fields:{stage:"package_health",source:e.source,resolved_path:e.resolved}})}catch{}const K=He(t),g=new bn(t),X=new Map,O=new Tn(t,e=>g.broadcast(e)),j=new kn(t,e=>g.broadcast(e));En(e=>g.broadcast({type:"node_named",...e}));let N=!1,de=!1,H,le,f,W;const Z=new xn;let F,ce=n(()=>{},"notifyTurnAccepted"),me=n(()=>{},"resetFrameState");const ee=Cn();let ue=n(()=>0,"pendingPromptDispatches"),fe;const L=Dn({runNode:k,session:n(()=>f.session(),"session"),isReplacing:n(()=>f.isReplacing(),"isReplacing"),isAgentRunActive:n(()=>f.isAgentRunActive(),"isAgentRunActive"),pendingDispatches:n(()=>ue(),"pendingDispatches"),turnAdmission:ee,prependDeferred:n(e=>On(t,e),"prependDeferred"),onError:n(e=>T({level:"error",event:"broker.inbox.idle_prompt_failed",error:e}),"onError")}),pe=L.drain;u.firstPrompt!==void 0&&u.firstPrompt!==""&&L.holdForKickoff(),globalThis[An]=L.start,globalThis[Pn]=L.busy,f=new Un({nodeId:t,cfg:u,session:U,services:A,runtime:G,registry:g,toolGroups:O,turnReplies:j,transcriptMessages:n(e=>ie(e,R)?.map(({message:r})=>r)??e.sessionManager.buildSessionContext().messages,"transcriptMessages"),uiContext:n(()=>le,"uiContext"),faultRetry:n(()=>W,"faultRetry"),projection:n(()=>F,"projection"),setActiveSession:n(e=>{if(J=e,fe?.(),k){let r="stop",c,v=!1;fe=e.subscribe(h=>{if(h.type==="agent_start"&&(r="stop",c=void 0,v=!1,Z.started()),h.type==="agent_end"){const S=[...h.messages??[]].reverse().find($=>$.role==="assistant");S&&(r=S.stopReason,c=Sn(S)?void 0:_n(S),v=S.role==="assistant"&&Mn(S,e.model?.contextWindow))}h.type==="agent_settled"&&(Z.settled(e.sessionManager,{stop_reason:r,...c?{error:c}:{}},v),In(t,e).catch(S=>{T({level:"error",event:"broker.run_deferred_mail.settle_failed",error:S})}),queueMicrotask(()=>{f.session()===e&&pe()}))})}},"setActiveSession"),disposeAndExit:n((e,r)=>q(e,r),"disposeAndExit"),onSessionRebind:n(()=>{me()},"onSessionRebind"),onReplacementIdle:n(()=>{k&&pe()},"onReplacementIdle"),reWelcomeAll:n(()=>ne(),"reWelcomeAll")});const ge=n(async(e,r=!1)=>{const c=f.session(),v=B(c.model,c.thinkingLevel);if(v===null)return null;const h=await Hn(t,{spec:v,...e!==void 0?{intent:e}:{},userSelected:r});return r&&(u.model=h.modelOverride,e!==void 0?(process.env.CRTR_MODEL_INTENT=`${e.family}/${e.strength}`,delete process.env.CRTR_MODEL_EXACT,u.modelExact=void 0):(delete process.env.CRTR_MODEL_INTENT,process.env.CRTR_MODEL_EXACT="1",u.modelExact=!0)),h.modelOverride},"persistModelChoice"),ve=n(async(e=!0,r,c=!1)=>{const v=f.session(),h=B(v.model,v.thinkingLevel),S=e?await ge(r,c):h;g.broadcast({type:"model_changed",model:oe(v.model)?void 0:v.model,spec:S})},"broadcastModelChanged");W=new Rn({nodeId:t,cfg:u,retryProbe:D,currentSession:n(()=>f.session(),"currentSession"),currentServices:n(()=>f.services(),"currentServices"),installedGeneration:n(()=>f.installedGeneration(),"installedGeneration"),registryOf:se,formatModelSpec:B,broadcastModelChanged:ve,turnAdmission:ee,reWelcomeAll:n(()=>ne(),"reWelcomeAll"),...k?{turnEnds:Z}:{}});const he=n(()=>{W.rearmIfStranded().catch(e=>{T({level:"warn",event:"broker.runtime.diagnostic",fields:{message:`fault retry re-arm failed: ${e instanceof Error?e.message:String(e)}`}})})},"rearmStrandedRetry");Q().subscribe("resync",he),Q().subscribe("fault-retry",he),F=new Nn({registry:g,faultRetry:W,installedGeneration:n(()=>f.installedGeneration(),"installedGeneration"),currentSession:n(()=>f.session(),"currentSession"),notifyTurnAccepted:n(()=>ce(),"notifyTurnAccepted"),emitStartupMilestone:d,formatModelSpec:B});const Re=n(e=>{const r=f.session(),c=ie(r,R),v=Jn(e.snapshotTail),h=c===void 0||v===void 0?c:c.slice(-v),S=h?.map(({message:I})=>I)??r.sessionManager.buildSessionContext().messages,$=O.summaries(),we=h!==void 0&&v!==void 0?tt(S):void 0,Ae=we===void 0?$:Object.fromEntries(Object.entries($).filter(([I])=>we.has(I)));return{messages:S,...h===void 0?{}:{messageIds:h.map(({id:I})=>I)},messageVisibility:h?.map(({visibility:I})=>I)??S.map(()=>"visible"),turnVisibility:yn(),stats:r.getSessionStats(),state:{model:oe(r.model)?void 0:r.model,thinkingLevel:r.thinkingLevel,isStreaming:r.isStreaming,isCompacting:r.isCompacting,steeringMode:r.steeringMode,followUpMode:r.followUpMode,sessionFile:r.sessionFile,sessionId:r.sessionId,sessionName:r.sessionName,autoCompactionEnabled:r.autoCompactionEnabled,messageCount:r.messages.length,pendingMessageCount:r.pendingMessageCount},display:{...g.displaySnapshot()},toolGroupSummaries:Ae,turnReplies:j.snapshot(),workingActivity:F.currentWorkingActivity(),queued:{steering:[...r.getSteeringMessages()],followUp:[...r.getFollowUpMessages()]}}},"buildSnapshot"),Se=n(e=>{const r=e.role==="controller"?X.values().next().value:void 0;g.sendFrame(e,{type:"welcome",snapshot:Re(e),role:e.role,pending_dialog:r!==void 0?r.request:null,agentDir:Y()},!0)},"sendWelcome"),Me=n(e=>{const r=[...X.values()];for(let c=1;c<r.length;c++)g.sendFrame(e,r[c].request)},"replayExtraPendingDialogsTo"),ne=n(()=>{try{const e=f.session();j.seed(ie(e,R)?.map(({message:r})=>r)??e.sessionManager.buildSessionContext().messages)}catch(e){T({level:"debug",event:"broker.runtime.diagnostic",fields:{message:`turn reply reseed failed: ${String(e)}`}})}g.forEachHelloed(Se)},"reWelcomeAll"),_e=n(async e=>{if(!N){N=!0,Q().stop(),O.persistPendingSummary(),F.dispose(),et();try{H?.close()}catch{}s.close(),g.dispose();try{ye(K)&&be(K)}catch{}g.clearAttachState(),await ze(),process.exit(e)}},"completeExit"),q=n((e,r=0)=>{if(N)return;const c=e==="shutdown-hook"||e==="shutdown-after-settle";if(c&&O.finishOpenToolGroup(!0),c&&(O.hasSummaryTasks()||j.hasTasks())){if(de)return;de=!0,Promise.allSettled([O.waitForSummaryTasks(),j.waitForTasks()]).finally(()=>_e(r));return}_e(r)},"disposeAndExit");le=it({writable:n(()=>g.writableClients(),"writable"),forward:n((e,r)=>g.sendFrame(e,r),"forward"),pending:X,broadcast:n(e=>g.broadcastUi(e),"broadcast"),onKnownStreamWait:n(e=>F.knownStreamWait(e),"onKnownStreamWait")}),f.setRebindSession(),await f.enqueueRebind(U,A),d("broker.startup.extensions_bound");const M=Fn({nodeId:t,registry:g,toolGroups:O,projection:F,rebind:f,boundaryReviewId:R,pendingDialogs:X,sendWelcome:Se,replayExtraPendingDialogsTo:Me,reWelcomeAll:ne,disposeAndExit:q,persistModelChoice:ge,broadcastModelChanged:ve,registryOf:se,formatModelSpec:B,formatExactModelSpec:Qn,turnAdmission:ee,memoryInventory:y,runNode:k,onKickoffAdmitted:L.releaseKickoff});ce=M.notifyTurnAccepted,me=M.resetForSession,ue=M.pendingPromptDispatches;const xe=2500;let te=!1;const Ce=n(async e=>{if(N||te)return;if(te=!0,f.isAgentRunActive()||f.session().isStreaming||M.pendingPromptDispatches()>0){const c=Date.now()+xe;for(;M.pendingPromptDispatches()>0&&!f.session().isStreaming&&Date.now()<c;)await new Promise(v=>setTimeout(v,25));if(f.session().isStreaming){const v=c-Date.now();if(v>0){let h;try{Gn(),await Promise.race([f.session().abort().then(()=>!0,()=>!1),new Promise($=>{h=setTimeout(()=>$(!1),v)})])&&await ke(t,{event:"closed",end_reason:"teardown-aborted"})}finally{h!==void 0&&clearTimeout(h)}}}else(M.pendingPromptDispatches()>0||f.isAgentRunActive())&&await ke(t,{event:"interrupted"})}q(e)},"abortAndExit");if(b=n(e=>{Ce(e)},"signalTeardown"),C!==void 0){b(C);return}try{ye(K)&&be(K)}catch{}H=Ue(e=>{const r=g.create(e);e.on("data",v=>{let h;try{h=r.decoder.push(v)}catch(S){S instanceof zn?(g.sendFrame(r,{type:"error",code:"frame_overflow",message:S.message}),g.dropClient(r,`frame overflow: ${S.message}`)):g.dropClient(r,`decoder error: ${String(S)}`);return}for(const S of h)try{Ln(M,r,S)}catch{}});const c=n(()=>{g.removeClient(r)},"drop");e.on("close",c),e.on("error",()=>{})}),H.on("error",e=>{N||(T({level:"error",event:"broker.socket.failed",error:e}),q("socket-error",1))}),H.listen(K,async()=>{Promise.all([z(t,{op:"clear",link:"viewer\u2194broker"}),z(t,{op:"clear",link:"relay\u2194broker"})]).catch(r=>T({level:"error",event:"broker.daemon.operation.failed",node_id:t,error:r,fields:{operation:"broker_socket_bound_fault_clear"}}));let e;try{e=await W.recoverOnStartup()}catch(r){T({level:"error",event:"broker.daemon.operation.failed",node_id:t,error:r,fields:{operation:"recovery_startup"}}),q("recovery-startup-failed",1);return}if(!(N||te))if(e!=="retry-armed"&&u.firstPrompt!==void 0&&u.firstPrompt!==""){const r=Wn(process.env[qn]);r!==null&&Vn(u.firstPrompt,r);const c=process.env.CRTR_KICKOFF_MESSAGE_IDS;M.kickoff(u.firstPrompt,c?JSON.parse(c):[])}else L.releaseKickoff()}),g.persistAttachState()}n(lr,"runBroker");function tt(t){const o=new Set;for(const i of t)if(!(i.role!=="assistant"||!Array.isArray(i.content)))for(const m of i.content)m!==null&&typeof m=="object"&&m.type==="toolCall"&&typeof m.id=="string"&&o.add(m.id);return o}n(tt,"toolCallIds");function ie(t,o){const i=t.sessionManager,m=hn(i);return m!==void 0&&$n(m.map(({message:s})=>s)),m===void 0?void 0:wn(m,{boundaryReviewId:o,sessionEntries:i.getEntries?.()})}n(ie,"snapshotMessages");function Ee(){const t=Ne();if(t===void 0||t==="")throw new Error("broker launch is missing CRTR_NODE_ID");return t}n(Ee,"currentBrokerNodeId");async function rt(t,o){const i=cn(o.model,Ie(),o.modelExact===!0);if(i===void 0)return;const m=se(t),s={cwd:De()??o.cwd,profileId:Fe()},a=fn(i,m,s);if(a!==void 0)throw await z(Ee(),{op:"record",input:{link:"crtr\u2192pi",op:"model resolution at launch",kind:"model-not-found",retry:{disposition:"fatal"},message:`model '${a.request.spec}' is not registered in the serving model registry`}}),new Error(`[broker] FATAL: model '${a.request.spec}' is not registered in the serving model registry`);const l=mn(i,s.cwd,s.profileId),d=un(i.spec);for(const p of l){const _=m.find(p.providerId,p.modelId);if(_===void 0)continue;const w=d?.providerId===p.providerId&&d.modelId===p.modelId?d.thinkingLevel??(p.thinkingLevel===void 0?void 0:"off"):p.thinkingLevel;return{model:_,thinkingLevel:w}}if(o.modelExact===!0){const p=l.map(_=>`'${_.providerId}/${_.modelId}' unregistered`).join("; ");throw await z(Ee(),{op:"record",input:{link:"crtr\u2192pi",op:"model resolution at launch",kind:"model-not-found",retry:{disposition:"fatal"},message:`exact-consult model '${o.model}' is unavailable \u2014 refusing to substitute (${p})`}}),new Error(`[broker] FATAL: exact-consult model '${o.model}' is unavailable`)}T({level:"warn",event:"broker.model.none_viable",fields:{rejected_candidates:l.map(p=>({provider:p.providerId,model:p.modelId,reason:"unregistered"})).slice(0,16)}})}n(rt,"resolveLaunchModel");function ot(t){let o=!0;return{runtime:new Proxy(t,{get(m,s,a){return o&&s==="getAvailableSnapshot"?()=>[]:o&&s==="getAvailable"?async()=>[]:o&&s==="getModel"?()=>{}:Reflect.get(m,s,a)}}),reveal:n(()=>{o=!1},"reveal")}}n(ot,"modelLessRegistry");async function st(t,o){const i=Y(),m=n(async w=>{const u=await Ve.create({credentials:new dn,modelsPath:Te(w.agentDir,"models.json")});ln(u);const y=await t.createAgentSessionServices({cwd:w.cwd,agentDir:w.agentDir,modelRuntime:u,resourceLoaderOptions:{additionalExtensionPaths:o.extensionPaths,appendSystemPrompt:o.appendSystemPromptPath!==void 0?[o.appendSystemPromptPath]:void 0,noContextFiles:!0,extensionsOverride:n(P=>({...P,extensions:P.extensions.filter(R=>!/[/\\]provider-rotation\.(?:ts|js)$/.test(R.path))}),"extensionsOverride")}}),b=y.resourceLoader.getExtensions();if(o.extensionPaths.some(P=>re.includes(P))){const P=new Set(b.extensions.map(k=>k.path)),R=re.filter(k=>!P.has(k));if(R.length>0){const k=b.errors.filter(D=>re.includes(D.path)).map(D=>`${D.path}: ${D.error}`).join("; ");throw new Error(`[broker] FATAL: mandatory canvas extensions failed to load: ${R.join(", ")}${k===""?"":` (${k})`}`)}}y.settingsManager.getRetryEnabled=()=>!1;const C=await rt(y,o),V=C?.model,U=C?.thinkingLevel,A=C===void 0?ot(y.modelRuntime):void 0,ae=A!==void 0?{...y,modelRuntime:A.runtime}:y,G=await t.createAgentSessionFromServices({services:ae,sessionManager:w.sessionManager,model:V,thinkingLevel:U,...nt(o.tools,Le()),sessionStartEvent:w.sessionStartEvent});return Bn(G.session),an(G.session),A?.reveal(),{...G,services:y}},"buildForManager"),s=o.resumeSessionPath,a=o.forkFrom!==void 0&&o.forkFrom!=="";if(!a&&(s===void 0||s==="")&&o.resumeSessionId!==void 0&&o.resumeSessionId!=="")throw new Error(`[broker] resume requires a session .jsonl PATH; got only a bare id '${o.resumeSessionId}' (pi_session_file was never captured for this node)`);const l=!a&&s!==void 0&&s!=="",d=l&&o.newCycle===!0,p=l&&!d;let _;if(a)_=t.SessionManager.forkFrom(o.forkFrom,o.cwd);else if(p||d){if(_=t.SessionManager.open(s),d){const w=_.getLeafId();_.resetLeaf(),_.appendCustomEntry(vn,{cycle:Number(process.env.CRTR_CYCLES),fromLeaf:w})}}else _=t.SessionManager.create(o.cwd);if(t.createAgentSessionRuntime!==void 0){const w=n(async y=>{const b=await m({cwd:y.cwd,agentDir:y.agentDir,sessionManager:y.sessionManager,sessionStartEvent:y.sessionStartEvent});return{...b,diagnostics:b.services.diagnostics??[]}},"factory"),u=await t.createAgentSessionRuntime(w,{cwd:o.cwd,agentDir:i,sessionManager:_});return{session:u.session,services:u.services,resuming:p,runtime:u}}const E=await m({cwd:o.cwd,agentDir:i,sessionManager:_});return{session:E.session,services:E.services,resuming:p,runtime:void 0}}n(st,"buildBrokerSession");function it(t){const o=n((s,a,l,d)=>{if(d?.signal?.aborted)return Promise.resolve(s);const p=t.writable();return p.length===0?Promise.resolve(s):new Promise(_=>{let E;const w=n(()=>{E!==void 0&&clearTimeout(E),d?.signal?.removeEventListener("abort",u),t.pending.delete(a.id)},"cleanup"),u=n(()=>{w(),t.broadcast({type:"extension_ui_dismiss",id:a.id}),_(s)},"onAbort");d?.signal?.addEventListener("abort",u,{once:!0});const y=d?.timeout!==void 0?d.timeout:Zn;E=setTimeout(()=>{w(),t.broadcast({type:"extension_ui_dismiss",id:a.id}),_(s)},y),typeof E.unref=="function"&&E.unref(),t.pending.set(a.id,{request:a,resolve:n(b=>{w(),t.broadcast({type:"extension_ui_dismiss",id:a.id}),_(l(b))},"resolve")});for(const b of p)t.forward(b,a)})},"dialogPromise"),i=n(()=>{},"noop");return{[pn]:t.onKnownStreamWait??(s=>()=>{}),get theme(){const s=globalThis[Symbol.for("@earendil-works/pi-coding-agent:theme")];if(s==null)throw new Error("Theme not initialized. Call initTheme() first.");return s},select:n((s,a,l)=>o(void 0,{type:"extension_ui_request",id:x(),method:"select",title:s,options:a,timeout:l?.timeout},d=>"cancelled"in d&&d.cancelled?void 0:"value"in d?d.value:void 0,l),"select"),confirm:n((s,a,l)=>o(!1,{type:"extension_ui_request",id:x(),method:"confirm",title:s,message:a,timeout:l?.timeout},d=>"cancelled"in d&&d.cancelled?!1:"confirmed"in d?d.confirmed:!1,l),"confirm"),input:n((s,a,l)=>o(void 0,{type:"extension_ui_request",id:x(),method:"input",title:s,placeholder:a,timeout:l?.timeout},d=>"cancelled"in d&&d.cancelled?void 0:"value"in d?d.value:void 0,l),"input"),editor:n((s,a)=>o(void 0,{type:"extension_ui_request",id:x(),method:"editor",title:s,prefill:a},l=>"cancelled"in l&&l.cancelled?void 0:"value"in l?l.value:void 0),"editor"),setStatus:n((s,a)=>t.broadcast({type:"extension_ui_request",id:x(),method:"setStatus",statusKey:s,statusText:a}),"setStatus"),setWidget:n((s,a,l)=>{typeof a!="function"&&t.broadcast({type:"extension_ui_request",id:x(),method:"setWidget",widgetKey:s,widgetLines:a,widgetPlacement:l?.placement})},"setWidget"),setTitle:n(s=>t.broadcast({type:"extension_ui_request",id:x(),method:"setTitle",title:s}),"setTitle"),notify:n((s,a)=>{const l=a==="warn"?"warning":a;t.broadcast({type:"extension_ui_request",id:x(),method:"notify",message:s,notifyType:l})},"notify"),onTerminalInput:n(()=>i,"onTerminalInput"),setWorkingMessage:i,setWorkingVisible:i,setWorkingIndicator:i,setHiddenThinkingLabel:i,setFooter:i,setHeader:i,custom:n(()=>Promise.resolve(void 0),"custom"),pasteToEditor:i,setEditorText:i,getEditorText:n(()=>"","getEditorText"),addAutocompleteProvider:i,setEditorComponent:i,getEditorComponent:n(()=>{},"getEditorComponent"),getAllThemes:n(()=>[],"getAllThemes"),getTheme:n(()=>{},"getTheme"),setTheme:i,getToolsExpanded:n(()=>!1,"getToolsExpanded"),setToolsExpanded:i}}n(it,"makeBrokerUiContext");export{fr as REVIEW_BOUNDARY_NAVIGATION_CODE,ur as ReviewBoundaryNavigationError,nt as brokerToolOptions,st as buildBrokerSession,et as disposeActiveSession,it as makeBrokerUiContext,lr as runBroker,ie as snapshotMessages};
|
|
1
|
+
var Pe=Object.defineProperty;var n=(t,o)=>Pe(t,"name",{value:o,configurable:!0});import{envInboxBetweenTurns as Oe,envModelIntent as Ie,envNodeCwd as De,envNodeId as Ne,envProfileId as Fe,envScopes as Le,isSandboxedNode as $e,scopeAllowed as Be}from"../../shared/env.js";import{createServer as Ue}from"node:net";import{existsSync as ye,readFileSync as Ge,unlinkSync as be}from"node:fs";import{join as Te}from"node:path";import{randomUUID as x}from"node:crypto";import{mark as Ke}from"../timing.js";import{SUBMIT_RESULT_TOOL as je}from"./structured-output.js";import{installSessionManagerStorePatch as We}from"../conversation-store/index.js";import{getAgentDir as Y,ModelRegistry as qe,ModelRuntime as Ve}from"@earendil-works/pi-coding-agent";import{nodeRunDir as Xe,viewSocketPath as He}from"../canvas/paths.js";import{bindBrokerEventSource as Ye}from"../events/source.js";import{emitEvent as T,flushBrokerLog as ze}from"../events/emit.js";import{operationIdContext as Je}from"../events/operation-id.js";import{findMissingPackagePaths as Qe}from"./package-health.js";import{installBrokerConfigSnapshot as Ze}from"../config.js";import{FRONT_DOOR_ENV as en}from"./front-door.js";import{CANVAS_EXTENSIONS as re,piInvocationToSdkConfig as nn}from"./launch.js";import{assertEngineVersion as tn,loadBrokerEngine as rn}from"./broker-sdk.js";import{initCrtrTheme as on}from"./crtr-theme.js";import{resolveBundledPiPackageDir as sn}from"./pi-cli.js";import{captureSessionChatCapabilities as an}from"./command-surface.js";import{InMemoryCredentialStore as dn}from"@earendil-works/pi-ai";import{configureBrokerModelRuntime as ln}from"./broker/model-adapter.js";import{mutateBrokerFault as z,recordBrokerTurn as Re}from"./broker/daemon-ops.js";import{modelRequestFromConfig as cn,expandModelCandidates as mn,parseModelSpec as un,unregisteredConcreteModel as fn}from"../model-routes.js";import{KNOWN_STREAM_WAIT_UI as pn}from"./stream-watchdog.js";import{probeOnline as gn}from"./connectivity.js";import{CRTR_CYCLE_CUSTOM_TYPE as vn,cycleAwareMessages as hn,endedByAbort as Sn}from"./session-cycles.js";import{turnErrorOf as _n}from"../llm/refusal.js";import{projectTranscript as wn}from"./session-visibility.js";import{currentTurnVisibility as yn}from"./turn-visibility.js";import{isUnknownModel as oe}from"./model-selection.js";import{BrokerClientRegistry as bn}from"./broker/client-registry.js";import{ToolGroupTracker as Tn}from"./broker/tool-groups.js";import{TurnReplyTracker as Rn}from"./broker/turn-replies.js";import{onNodeNamed as kn}from"./broker/node-named.js";import{FaultRetry as En,willDaemonRetry as Mn}from"./broker/fault-retry.js";import{RunTurnEnds as xn}from"./broker/run-turn-end.js";import{createTurnAdmissionGate as Cn}from"./broker/turn-admission.js";import{BROKER_IDLE_TURN_START as An,BROKER_RUN_TURN_BUSY as Pn}from"./broker/held-deferred-inbox.js";import{prependRunDeferredMail as On,settleRunDeferredMail as In}from"./broker/run-deferred-mail.js";import{createRunTurnQueue as Dn}from"./broker/run-turn-queue.js";import{EventProjection as Nn}from"./broker/event-projection.js";import{createFrameDispatchContext as Fn,handleFrame as Ln}from"./broker/frame-dispatch.js";import{hydratePersistedAdvertisedCommandMessages as $n,installAdvertisedCommandInvocationContract as Bn}from"./advertised-command-invocation.js";import{RebindDriver as Un}from"./broker/rebind.js";import{beginRuntimeTeardown as Gn}from"./broker/extension-abort.js";import{receiveNodeToken as Kn}from"./broker/node-token.js";import{serveCliRelay as jn}from"./broker/cli-relay.js";import{decodeKickoffOrigin as Wn,KICKOFF_ORIGIN_ENV as qn}from"./stamp/protocol.js";import{announceMessageOrigin as Vn}from"./stamp/channel.js";import{brokerExtensionState as Xn,commitBrokerModel as Hn}from"./broker/daemon-ops.js";import{composerNames as Yn}from"./broker/frame-memory-refs.js";import{FrameOverflowError as zn,normalizeSnapshotTail as Jn}from"./broker-protocol.js";import{ReviewBoundaryNavigationError as ur,REVIEW_BOUNDARY_NAVIGATION_CODE as fr}from"./broker/frame-replies.js";function se(t){return new qe(t.modelRuntime)}n(se,"registryOf");function B(t,o){if(t==null||oe(t))return null;const i=o!==void 0&&o!==""&&o!=="off"?`:${o}`:"";return`${t.provider}/${t.id}${i}`}n(B,"formatModelSpec");function Qn(t,o){const i=B(t,void 0);return i===null?null:`${i}:${o===void 0||o===""?"off":o}`}n(Qn,"formatExactModelSpec");const Zn=12e4;let J=null;import{brokerSignalClient as Q}from"./broker/signal-stream.js";function et(){Q().stop();const t=J;if(J=null,t!==null)try{t.dispose()}catch{}}n(et,"disposeActiveSession");function nt(t,o){const i=Be(o,"crtr:act")?void 0:["bash"],m=t!==void 0&&t.length>0?[...new Set([...t,je])]:t===void 0?void 0:[...t];return{...m!==void 0?{tools:m}:{},...i!==void 0?{excludeTools:i}:{}}}n(nt,"brokerToolOptions");async function lr(t,o=process.hrtime.bigint(),i=new Date().toISOString()){Ye(t);const m=await Kn(),s=await jn(t,m);process.env.CRTR_API_SOCKET=s.path,Je.fresh(()=>{T({level:"info",event:"broker.startup.cli_entry",ts:i,duration_ms:0,fields:{runtime_version:process.version,engine_version:null,model:null}}),T({level:"info",event:"broker.startup.module_loaded",duration_ms:Number(process.hrtime.bigint()-o)/1e6,fields:{runtime_version:process.version,engine_version:null,model:null}})});const a=new Set;let l=null;const d=n((e,r=null)=>{a.has(e)||(a.add(e),Ke(e,{duration_ms:Number(process.hrtime.bigint()-o)/1e6}),T({level:"info",event:e,duration_ms:Number(process.hrtime.bigint()-o)/1e6,fields:{runtime_version:process.version,engine_version:l,model:r}}))},"emitStartupMilestone");process.env[en]="1",process.env.CRTR_BROKER_PID=String(process.pid),delete process.env.TMUX_PANE,delete process.env.TMUX,We(t);const p=await rn();tn(p.VERSION),l=p.VERSION;const _=Xe(t),k=Te(_,"broker-launch.json"),w=JSON.parse(Ge(k,"utf8"));if($e()){if(!w.configSnapshot)throw new Error("broker launch is missing its config snapshot");Ze(w.configSnapshot)}const f=nn(w);f.modelExact===!0?process.env.CRTR_MODEL_EXACT="1":delete process.env.CRTR_MODEL_EXACT;const y=await Yn(t);let b,C;const V=n(e=>{b!==void 0?b(e):C??=e},"onSignal");process.on("SIGTERM",()=>V("SIGTERM")),process.on("SIGINT",()=>V("SIGINT"));let{session:U,services:A,resuming:ae,runtime:G}=await st(p,f);d("broker.startup.session_built");const E=(await Xn(t)).node.review_binding?.review_id,R=Oe();J=U;const D=gn;try{process.env.PI_PACKAGE_DIR=sn(),on(A.settingsManager.getTheme(),Y(),!1)}catch(e){T({level:"error",event:"broker.theme.initialization_failed",error:e})}try{for(const e of Qe(Y()))T({level:"warn",event:"broker.startup.warning",fields:{stage:"package_health",source:e.source,resolved_path:e.resolved}})}catch{}const K=He(t),g=new bn(t),X=new Map,O=new Tn(t,e=>g.broadcast(e)),j=new Rn(t,e=>g.broadcast(e));kn(e=>g.broadcast({type:"node_named",...e}));let N=!1,de=!1,H,le,u,W;const Z=new xn;let F,ce=n(()=>{},"notifyTurnAccepted"),me=n(()=>{},"resetFrameState");const ee=Cn();let ue=n(()=>0,"pendingPromptDispatches"),fe;const L=Dn({runNode:R,session:n(()=>u.session(),"session"),isReplacing:n(()=>u.isReplacing(),"isReplacing"),pendingRebind:n(()=>u.pendingRebind(),"pendingRebind"),isAgentRunActive:n(()=>u.isAgentRunActive(),"isAgentRunActive"),pendingDispatches:n(()=>ue(),"pendingDispatches"),turnAdmission:ee,prependDeferred:n(e=>On(t,e),"prependDeferred"),onError:n(e=>T({level:"error",event:"broker.inbox.idle_prompt_failed",error:e}),"onError")}),pe=L.drain;f.firstPrompt!==void 0&&f.firstPrompt!==""&&L.holdForKickoff(),globalThis[An]=L.start,globalThis[Pn]=L.busy,u=new Un({nodeId:t,cfg:f,session:U,services:A,runtime:G,registry:g,toolGroups:O,turnReplies:j,transcriptMessages:n(e=>ie(e,E)?.map(({message:r})=>r)??e.sessionManager.buildSessionContext().messages,"transcriptMessages"),uiContext:n(()=>le,"uiContext"),faultRetry:n(()=>W,"faultRetry"),projection:n(()=>F,"projection"),setActiveSession:n(e=>{if(J=e,fe?.(),R){let r="stop",c,v=!1;fe=e.subscribe(h=>{if(h.type==="agent_start"&&(r="stop",c=void 0,v=!1,Z.started()),h.type==="agent_end"){const S=[...h.messages??[]].reverse().find($=>$.role==="assistant");S&&(r=S.stopReason,c=Sn(S)?void 0:_n(S),v=S.role==="assistant"&&Mn(S,e.model?.contextWindow))}h.type==="agent_settled"&&(Z.settled(e.sessionManager,{stop_reason:r,...c?{error:c}:{}},v),In(t,e).catch(S=>{T({level:"error",event:"broker.run_deferred_mail.settle_failed",error:S})}),queueMicrotask(()=>{u.session()===e&&pe()}))})}},"setActiveSession"),disposeAndExit:n((e,r)=>q(e,r),"disposeAndExit"),onSessionRebind:n(()=>{me()},"onSessionRebind"),onReplacementIdle:n(()=>{R&&pe()},"onReplacementIdle"),reWelcomeAll:n(()=>ne(),"reWelcomeAll")});const ge=n(async(e,r=!1)=>{const c=u.session(),v=B(c.model,c.thinkingLevel);if(v===null)return null;const h=await Hn(t,{spec:v,...e!==void 0?{intent:e}:{},userSelected:r});return r&&(f.model=h.modelOverride,e!==void 0?(process.env.CRTR_MODEL_INTENT=`${e.family}/${e.strength}`,delete process.env.CRTR_MODEL_EXACT,f.modelExact=void 0):(delete process.env.CRTR_MODEL_INTENT,process.env.CRTR_MODEL_EXACT="1",f.modelExact=!0)),h.modelOverride},"persistModelChoice"),ve=n(async(e=!0,r,c=!1)=>{const v=u.session(),h=B(v.model,v.thinkingLevel),S=e?await ge(r,c):h;g.broadcast({type:"model_changed",model:oe(v.model)?void 0:v.model,spec:S})},"broadcastModelChanged");W=new En({nodeId:t,cfg:f,retryProbe:D,currentSession:n(()=>u.session(),"currentSession"),currentServices:n(()=>u.services(),"currentServices"),installedGeneration:n(()=>u.installedGeneration(),"installedGeneration"),registryOf:se,formatModelSpec:B,broadcastModelChanged:ve,turnAdmission:ee,reWelcomeAll:n(()=>ne(),"reWelcomeAll"),...R?{turnEnds:Z}:{}});const he=n(()=>{W.rearmIfStranded().catch(e=>{T({level:"warn",event:"broker.runtime.diagnostic",fields:{message:`fault retry re-arm failed: ${e instanceof Error?e.message:String(e)}`}})})},"rearmStrandedRetry");Q().subscribe("resync",he),Q().subscribe("fault-retry",he),F=new Nn({registry:g,faultRetry:W,installedGeneration:n(()=>u.installedGeneration(),"installedGeneration"),currentSession:n(()=>u.session(),"currentSession"),notifyTurnAccepted:n(()=>ce(),"notifyTurnAccepted"),emitStartupMilestone:d,formatModelSpec:B});const Ee=n(e=>{const r=u.session(),c=ie(r,E),v=Jn(e.snapshotTail),h=c===void 0||v===void 0?c:c.slice(-v),S=h?.map(({message:I})=>I)??r.sessionManager.buildSessionContext().messages,$=O.summaries(),we=h!==void 0&&v!==void 0?tt(S):void 0,Ae=we===void 0?$:Object.fromEntries(Object.entries($).filter(([I])=>we.has(I)));return{messages:S,...h===void 0?{}:{messageIds:h.map(({id:I})=>I)},messageVisibility:h?.map(({visibility:I})=>I)??S.map(()=>"visible"),turnVisibility:yn(),stats:r.getSessionStats(),state:{model:oe(r.model)?void 0:r.model,thinkingLevel:r.thinkingLevel,isStreaming:r.isStreaming,isCompacting:r.isCompacting,steeringMode:r.steeringMode,followUpMode:r.followUpMode,sessionFile:r.sessionFile,sessionId:r.sessionId,sessionName:r.sessionName,autoCompactionEnabled:r.autoCompactionEnabled,messageCount:r.messages.length,pendingMessageCount:r.pendingMessageCount},display:{...g.displaySnapshot()},toolGroupSummaries:Ae,turnReplies:j.snapshot(),workingActivity:F.currentWorkingActivity(),queued:{steering:[...r.getSteeringMessages()],followUp:[...r.getFollowUpMessages()]}}},"buildSnapshot"),Se=n(e=>{const r=e.role==="controller"?X.values().next().value:void 0;g.sendFrame(e,{type:"welcome",snapshot:Ee(e),role:e.role,pending_dialog:r!==void 0?r.request:null,agentDir:Y()},!0)},"sendWelcome"),Me=n(e=>{const r=[...X.values()];for(let c=1;c<r.length;c++)g.sendFrame(e,r[c].request)},"replayExtraPendingDialogsTo"),ne=n(()=>{try{const e=u.session();j.seed(ie(e,E)?.map(({message:r})=>r)??e.sessionManager.buildSessionContext().messages)}catch(e){T({level:"debug",event:"broker.runtime.diagnostic",fields:{message:`turn reply reseed failed: ${String(e)}`}})}g.forEachHelloed(Se)},"reWelcomeAll"),_e=n(async e=>{if(!N){N=!0,Q().stop(),O.persistPendingSummary(),F.dispose(),et();try{H?.close()}catch{}s.close(),g.dispose();try{ye(K)&&be(K)}catch{}g.clearAttachState(),await ze(),process.exit(e)}},"completeExit"),q=n((e,r=0)=>{if(N)return;const c=e==="shutdown-hook"||e==="shutdown-after-settle";if(c&&O.finishOpenToolGroup(!0),c&&(O.hasSummaryTasks()||j.hasTasks())){if(de)return;de=!0,Promise.allSettled([O.waitForSummaryTasks(),j.waitForTasks()]).finally(()=>_e(r));return}_e(r)},"disposeAndExit");le=it({writable:n(()=>g.writableClients(),"writable"),forward:n((e,r)=>g.sendFrame(e,r),"forward"),pending:X,broadcast:n(e=>g.broadcastUi(e),"broadcast"),onKnownStreamWait:n(e=>F.knownStreamWait(e),"onKnownStreamWait")}),u.setRebindSession(),await u.enqueueRebind(U,A),d("broker.startup.extensions_bound");const M=Fn({nodeId:t,registry:g,toolGroups:O,projection:F,rebind:u,boundaryReviewId:E,pendingDialogs:X,sendWelcome:Se,replayExtraPendingDialogsTo:Me,reWelcomeAll:ne,disposeAndExit:q,persistModelChoice:ge,broadcastModelChanged:ve,registryOf:se,formatModelSpec:B,formatExactModelSpec:Qn,turnAdmission:ee,memoryInventory:y,runNode:R,onKickoffAdmitted:L.releaseKickoff});ce=M.notifyTurnAccepted,me=M.resetForSession,ue=M.pendingPromptDispatches;const xe=2500;let te=!1;const Ce=n(async e=>{if(N||te)return;if(te=!0,u.isAgentRunActive()||u.session().isStreaming||M.pendingPromptDispatches()>0){const c=Date.now()+xe;for(;M.pendingPromptDispatches()>0&&!u.session().isStreaming&&Date.now()<c;)await new Promise(v=>setTimeout(v,25));if(u.session().isStreaming){const v=c-Date.now();if(v>0){let h;try{Gn(),await Promise.race([u.session().abort().then(()=>!0,()=>!1),new Promise($=>{h=setTimeout(()=>$(!1),v)})])&&await Re(t,{event:"closed",end_reason:"teardown-aborted"})}finally{h!==void 0&&clearTimeout(h)}}}else(M.pendingPromptDispatches()>0||u.isAgentRunActive())&&await Re(t,{event:"interrupted"})}q(e)},"abortAndExit");if(b=n(e=>{Ce(e)},"signalTeardown"),C!==void 0){b(C);return}try{ye(K)&&be(K)}catch{}H=Ue(e=>{const r=g.create(e);e.on("data",v=>{let h;try{h=r.decoder.push(v)}catch(S){S instanceof zn?(g.sendFrame(r,{type:"error",code:"frame_overflow",message:S.message}),g.dropClient(r,`frame overflow: ${S.message}`)):g.dropClient(r,`decoder error: ${String(S)}`);return}for(const S of h)try{Ln(M,r,S)}catch{}});const c=n(()=>{g.removeClient(r)},"drop");e.on("close",c),e.on("error",()=>{})}),H.on("error",e=>{N||(T({level:"error",event:"broker.socket.failed",error:e}),q("socket-error",1))}),H.listen(K,async()=>{Promise.all([z(t,{op:"clear",link:"viewer\u2194broker"}),z(t,{op:"clear",link:"relay\u2194broker"})]).catch(r=>T({level:"error",event:"broker.daemon.operation.failed",node_id:t,error:r,fields:{operation:"broker_socket_bound_fault_clear"}}));let e;try{e=await W.recoverOnStartup()}catch(r){T({level:"error",event:"broker.daemon.operation.failed",node_id:t,error:r,fields:{operation:"recovery_startup"}}),q("recovery-startup-failed",1);return}if(!(N||te))if(e!=="retry-armed"&&f.firstPrompt!==void 0&&f.firstPrompt!==""){const r=Wn(process.env[qn]);r!==null&&Vn(f.firstPrompt,r);const c=process.env.CRTR_KICKOFF_MESSAGE_IDS;M.kickoff(f.firstPrompt,c?JSON.parse(c):[])}else L.releaseKickoff()}),g.persistAttachState()}n(lr,"runBroker");function tt(t){const o=new Set;for(const i of t)if(!(i.role!=="assistant"||!Array.isArray(i.content)))for(const m of i.content)m!==null&&typeof m=="object"&&m.type==="toolCall"&&typeof m.id=="string"&&o.add(m.id);return o}n(tt,"toolCallIds");function ie(t,o){const i=t.sessionManager,m=hn(i);return m!==void 0&&$n(m.map(({message:s})=>s)),m===void 0?void 0:wn(m,{boundaryReviewId:o,sessionEntries:i.getEntries?.()})}n(ie,"snapshotMessages");function ke(){const t=Ne();if(t===void 0||t==="")throw new Error("broker launch is missing CRTR_NODE_ID");return t}n(ke,"currentBrokerNodeId");async function rt(t,o){const i=cn(o.model,Ie(),o.modelExact===!0);if(i===void 0)return;const m=se(t),s={cwd:De()??o.cwd,profileId:Fe()},a=fn(i,m,s);if(a!==void 0)throw await z(ke(),{op:"record",input:{link:"crtr\u2192pi",op:"model resolution at launch",kind:"model-not-found",retry:{disposition:"fatal"},message:`model '${a.request.spec}' is not registered in the serving model registry`}}),new Error(`[broker] FATAL: model '${a.request.spec}' is not registered in the serving model registry`);const l=mn(i,s.cwd,s.profileId),d=un(i.spec);for(const p of l){const _=m.find(p.providerId,p.modelId);if(_===void 0)continue;const w=d?.providerId===p.providerId&&d.modelId===p.modelId?d.thinkingLevel??(p.thinkingLevel===void 0?void 0:"off"):p.thinkingLevel;return{model:_,thinkingLevel:w}}if(o.modelExact===!0){const p=l.map(_=>`'${_.providerId}/${_.modelId}' unregistered`).join("; ");throw await z(ke(),{op:"record",input:{link:"crtr\u2192pi",op:"model resolution at launch",kind:"model-not-found",retry:{disposition:"fatal"},message:`exact-consult model '${o.model}' is unavailable \u2014 refusing to substitute (${p})`}}),new Error(`[broker] FATAL: exact-consult model '${o.model}' is unavailable`)}T({level:"warn",event:"broker.model.none_viable",fields:{rejected_candidates:l.map(p=>({provider:p.providerId,model:p.modelId,reason:"unregistered"})).slice(0,16)}})}n(rt,"resolveLaunchModel");function ot(t){let o=!0;return{runtime:new Proxy(t,{get(m,s,a){return o&&s==="getAvailableSnapshot"?()=>[]:o&&s==="getAvailable"?async()=>[]:o&&s==="getModel"?()=>{}:Reflect.get(m,s,a)}}),reveal:n(()=>{o=!1},"reveal")}}n(ot,"modelLessRegistry");async function st(t,o){const i=Y(),m=n(async w=>{const f=await Ve.create({credentials:new dn,modelsPath:Te(w.agentDir,"models.json")});ln(f);const y=await t.createAgentSessionServices({cwd:w.cwd,agentDir:w.agentDir,modelRuntime:f,resourceLoaderOptions:{additionalExtensionPaths:o.extensionPaths,appendSystemPrompt:o.appendSystemPromptPath!==void 0?[o.appendSystemPromptPath]:void 0,noContextFiles:!0,extensionsOverride:n(P=>({...P,extensions:P.extensions.filter(E=>!/[/\\]provider-rotation\.(?:ts|js)$/.test(E.path))}),"extensionsOverride")}}),b=y.resourceLoader.getExtensions();if(o.extensionPaths.some(P=>re.includes(P))){const P=new Set(b.extensions.map(R=>R.path)),E=re.filter(R=>!P.has(R));if(E.length>0){const R=b.errors.filter(D=>re.includes(D.path)).map(D=>`${D.path}: ${D.error}`).join("; ");throw new Error(`[broker] FATAL: mandatory canvas extensions failed to load: ${E.join(", ")}${R===""?"":` (${R})`}`)}}y.settingsManager.getRetryEnabled=()=>!1;const C=await rt(y,o),V=C?.model,U=C?.thinkingLevel,A=C===void 0?ot(y.modelRuntime):void 0,ae=A!==void 0?{...y,modelRuntime:A.runtime}:y,G=await t.createAgentSessionFromServices({services:ae,sessionManager:w.sessionManager,model:V,thinkingLevel:U,...nt(o.tools,Le()),sessionStartEvent:w.sessionStartEvent});return Bn(G.session),an(G.session),A?.reveal(),{...G,services:y}},"buildForManager"),s=o.resumeSessionPath,a=o.forkFrom!==void 0&&o.forkFrom!=="";if(!a&&(s===void 0||s==="")&&o.resumeSessionId!==void 0&&o.resumeSessionId!=="")throw new Error(`[broker] resume requires a session .jsonl PATH; got only a bare id '${o.resumeSessionId}' (pi_session_file was never captured for this node)`);const l=!a&&s!==void 0&&s!=="",d=l&&o.newCycle===!0,p=l&&!d;let _;if(a)_=t.SessionManager.forkFrom(o.forkFrom,o.cwd);else if(p||d){if(_=t.SessionManager.open(s),d){const w=_.getLeafId();_.resetLeaf(),_.appendCustomEntry(vn,{cycle:Number(process.env.CRTR_CYCLES),fromLeaf:w})}}else _=t.SessionManager.create(o.cwd);if(t.createAgentSessionRuntime!==void 0){const w=n(async y=>{const b=await m({cwd:y.cwd,agentDir:y.agentDir,sessionManager:y.sessionManager,sessionStartEvent:y.sessionStartEvent});return{...b,diagnostics:b.services.diagnostics??[]}},"factory"),f=await t.createAgentSessionRuntime(w,{cwd:o.cwd,agentDir:i,sessionManager:_});return{session:f.session,services:f.services,resuming:p,runtime:f}}const k=await m({cwd:o.cwd,agentDir:i,sessionManager:_});return{session:k.session,services:k.services,resuming:p,runtime:void 0}}n(st,"buildBrokerSession");function it(t){const o=n((s,a,l,d)=>{if(d?.signal?.aborted)return Promise.resolve(s);const p=t.writable();return p.length===0?Promise.resolve(s):new Promise(_=>{let k;const w=n(()=>{k!==void 0&&clearTimeout(k),d?.signal?.removeEventListener("abort",f),t.pending.delete(a.id)},"cleanup"),f=n(()=>{w(),t.broadcast({type:"extension_ui_dismiss",id:a.id}),_(s)},"onAbort");d?.signal?.addEventListener("abort",f,{once:!0});const y=d?.timeout!==void 0?d.timeout:Zn;k=setTimeout(()=>{w(),t.broadcast({type:"extension_ui_dismiss",id:a.id}),_(s)},y),typeof k.unref=="function"&&k.unref(),t.pending.set(a.id,{request:a,resolve:n(b=>{w(),t.broadcast({type:"extension_ui_dismiss",id:a.id}),_(l(b))},"resolve")});for(const b of p)t.forward(b,a)})},"dialogPromise"),i=n(()=>{},"noop");return{[pn]:t.onKnownStreamWait??(s=>()=>{}),get theme(){const s=globalThis[Symbol.for("@earendil-works/pi-coding-agent:theme")];if(s==null)throw new Error("Theme not initialized. Call initTheme() first.");return s},select:n((s,a,l)=>o(void 0,{type:"extension_ui_request",id:x(),method:"select",title:s,options:a,timeout:l?.timeout},d=>"cancelled"in d&&d.cancelled?void 0:"value"in d?d.value:void 0,l),"select"),confirm:n((s,a,l)=>o(!1,{type:"extension_ui_request",id:x(),method:"confirm",title:s,message:a,timeout:l?.timeout},d=>"cancelled"in d&&d.cancelled?!1:"confirmed"in d?d.confirmed:!1,l),"confirm"),input:n((s,a,l)=>o(void 0,{type:"extension_ui_request",id:x(),method:"input",title:s,placeholder:a,timeout:l?.timeout},d=>"cancelled"in d&&d.cancelled?void 0:"value"in d?d.value:void 0,l),"input"),editor:n((s,a)=>o(void 0,{type:"extension_ui_request",id:x(),method:"editor",title:s,prefill:a},l=>"cancelled"in l&&l.cancelled?void 0:"value"in l?l.value:void 0),"editor"),setStatus:n((s,a)=>t.broadcast({type:"extension_ui_request",id:x(),method:"setStatus",statusKey:s,statusText:a}),"setStatus"),setWidget:n((s,a,l)=>{typeof a!="function"&&t.broadcast({type:"extension_ui_request",id:x(),method:"setWidget",widgetKey:s,widgetLines:a,widgetPlacement:l?.placement})},"setWidget"),setTitle:n(s=>t.broadcast({type:"extension_ui_request",id:x(),method:"setTitle",title:s}),"setTitle"),notify:n((s,a)=>{const l=a==="warn"?"warning":a;t.broadcast({type:"extension_ui_request",id:x(),method:"notify",message:s,notifyType:l})},"notify"),onTerminalInput:n(()=>i,"onTerminalInput"),setWorkingMessage:i,setWorkingVisible:i,setWorkingIndicator:i,setHiddenThinkingLabel:i,setFooter:i,setHeader:i,custom:n(()=>Promise.resolve(void 0),"custom"),pasteToEditor:i,setEditorText:i,getEditorText:n(()=>"","getEditorText"),addAutocompleteProvider:i,setEditorComponent:i,getEditorComponent:n(()=>{},"getEditorComponent"),getAllThemes:n(()=>[],"getAllThemes"),getTheme:n(()=>{},"getTheme"),setTheme:i,getToolsExpanded:n(()=>!1,"getToolsExpanded"),setToolsExpanded:i}}n(it,"makeBrokerUiContext");export{fr as REVIEW_BOUNDARY_NAVIGATION_CODE,ur as ReviewBoundaryNavigationError,nt as brokerToolOptions,st as buildBrokerSession,et as disposeActiveSession,it as makeBrokerUiContext,lr as runBroker,ie as snapshotMessages};
|
|
@@ -4,8 +4,8 @@ export type NoticeEvent = 'notice.crash' | 'notice.deadline' | 'notice.close';
|
|
|
4
4
|
/** Publish a lifecycle notice on `nodeId` to its watchers, inside the caller's write when one
|
|
5
5
|
* is open. The message body carries today's sentence (as `body`, which the inbox card shows)
|
|
6
6
|
* and data; `publish` picks the recipients, their tier and wake from each watch. A node whose
|
|
7
|
-
* object is already gone publishes nothing. */
|
|
8
|
-
export declare function publishNotice(nodeId: string, event: NoticeEvent, label: string, data: Record<string, unknown>, tier?: InboxTier, actor?: ObjectRow | null): void;
|
|
7
|
+
* object is already gone publishes nothing. `onlyWatchers` narrows the recipients to those watchers. */
|
|
8
|
+
export declare function publishNotice(nodeId: string, event: NoticeEvent, label: string, data: Record<string, unknown>, tier?: InboxTier, actor?: ObjectRow | null, onlyWatchers?: readonly string[]): void;
|
|
9
9
|
export interface CloseNodeResult {
|
|
10
10
|
/** The focused node that was closed — the cascade root. */
|
|
11
11
|
root: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var k=Object.defineProperty;var a=(r,o)=>k(r,"name",{value:o,configurable:!0});import{getNode as h,subscriptionsOf as u,subscribersOf as E}from"../canvas/index.js";import{transition as w}from"./lifecycle.js";import{stopNodeSandboxes as $}from"../spaces/stop.js";import{tearDownNode as D,reapIfEmpty as N}from"./placement.js";import{crtrHome as L,jobDir as O}from"../canvas/paths.js";import{contextDir as x,nodeAgentDir as S}from"../canvas/node-agent-paths.js";import{readLiveSession as j}from"../canvas/sessions.js";import{discoverLifecycleHookRegistry as H}from"../command-hooks/discovery.js";import{invokeLifecycleHooks as A}from"../command-hooks/transport/exec-lifecycle.js";import{emitEvent as p}from"../events/emit.js";import{enqueueNodeMail as B}from"../feed/messages.js";import{withCanvasWrite as v}from"../canvas/db.js";import{recordActedOn as C}from"../graph/edges.js";import{publish as R}from"../graph/events.js";import{getById as y,nodeObject as T,ownerForGrantee as Y}from"../graph/objects.js";const q={deferred:3,normal:5,urgent:7,critical:7};function P(r,o,l,s,d="normal",
|
|
1
|
+
var k=Object.defineProperty;var a=(r,o)=>k(r,"name",{value:o,configurable:!0});import{getNode as h,subscriptionsOf as u,subscribersOf as E}from"../canvas/index.js";import{transition as w}from"./lifecycle.js";import{stopNodeSandboxes as $}from"../spaces/stop.js";import{tearDownNode as D,reapIfEmpty as N}from"./placement.js";import{crtrHome as L,jobDir as O}from"../canvas/paths.js";import{contextDir as x,nodeAgentDir as S}from"../canvas/node-agent-paths.js";import{readLiveSession as j}from"../canvas/sessions.js";import{discoverLifecycleHookRegistry as H}from"../command-hooks/discovery.js";import{invokeLifecycleHooks as A}from"../command-hooks/transport/exec-lifecycle.js";import{emitEvent as p}from"../events/emit.js";import{enqueueNodeMail as B}from"../feed/messages.js";import{withCanvasWrite as v}from"../canvas/db.js";import{recordActedOn as C}from"../graph/edges.js";import{publish as R}from"../graph/events.js";import{getById as y,nodeObject as T,ownerForGrantee as Y}from"../graph/objects.js";const q={deferred:3,normal:5,urgent:7,critical:7};function P(r,o,l,s,d="normal",i=null,c){v(e=>{const n=y(e,r);n===null||n.type!=="node"||R(e,{event:o,object:n,actor:i,level:q[d],attrs:{},messageBody:{...s,body:l},...c===void 0?{}:{onlyWatchers:c}})})}a(P,"publishNotice");function z(r){const o=new Set([r]);let l=!0;for(;l;){l=!1;for(const s of[...o])for(const d of u(s)){const i=d.node_id;o.has(i)||E(i).every(c=>o.has(c.node_id))&&(o.add(i),l=!0)}}return o}a(z,"closingSet");function F(r,o){const l=[],s=new Set([r]),d=[r];for(;d.length>0;){const i=d.shift();l.push(i);for(const c of u(i))o.has(c.node_id)&&!s.has(c.node_id)&&(s.add(c.node_id),d.push(c.node_id))}for(const i of o)s.has(i)||l.push(i);return l.reverse()}a(F,"killOrder");function G(r,o){const l=r?"You were CLOSED by the user from the canvas":"You were CANCELED \u2014 an ancestor of yours was closed from the canvas";if(o.length===0)return`${l}. Your pi session is preserved; this resume reopened it.`;const s=o.slice(0,4).map(i=>{const c=h(i);return c!==null?`${c.name} (${i})`:i}),d=o.length>s.length?` +${o.length-s.length} more`:"";return`${l}. ${o.length} child node(s) you subscribe to were canceled with you and are no longer running: ${s.join(", ")}${d}. Resuming will NOT restore them \u2014 re-spawn if you still need that work.`}a(G,"cancellationLabel");function se(r,o={}){if(h(r)===null)throw new Error(`closeNode: unknown node ${r}`);const l=o.rootEvent??"cancel",s=z(r),d=F(r,s),i=[];for(const e of s)for(const n of u(e))!s.has(n.node_id)&&!i.includes(n.node_id)&&i.push(n.node_id);const c=[];for(const e of d)try{const n=h(e);if(n===null)continue;const _=u(e).map(t=>t.node_id).filter(t=>s.has(t));let m;try{const t=H(n.cwd,n.profile_id).plans.get("node:close")??[];if(t.length>0){const f={node:{id:e,name:n.name,kind:n.kind,mode:n.mode,lifecycle:n.lifecycle,cwd:n.cwd,nodeDir:S(e),contextDir:x(e),jobDir:O(e)},runtime:{isBirth:!1,canvasHome:L(),profile:n.profile_id??null}};m=a(()=>A(t,f),"afterTeardown")}}catch(t){p({level:"error",event:"node.close_hook.discovery_failed",node_id:e,error:t})}const b=$(e,o.stopReason??"node_closed",{...e===r?{excludePid:o.callerPid}:{},...m?{after:m}:{}});try{o.registerDetached?.(b.then(()=>{}))}catch(t){p({level:"error",event:"node.close_hook.detached_registration_failed",node_id:e,error:t})}if(v(t=>{const f=y(t,e);if(f===null||f.type!=="node")return;const g=o.closer!==void 0?T(t,o.closer):Y(t,"user:local");C(t,g,f),P(e,"notice.close",`Child closed \u2014 ${n.name} (${e}) was closed from the canvas and is no longer running.`,{reason:"child-closed",child:e},"normal",g)}),o.preserveEmpty||n.run_id!==null&&n.pi_pid!==null&&j(e)?.sessionId!=null||!N(e,void 0,!1)){const t=n.final_report!==null&&n.final_report!==void 0;e===r&&l==="finish"||t?(n.status==="active"||n.status==="idle")&&w(e,"finish"):w(e,"cancel",{reason:"closed"}),D(e),B(e,{kind:"message",label:G(e===r,_),bodyJson:{reason:"user-close",cascade_root:r,canceled_children:_},urgency:"normal",wake:1})}c.push(e)}catch(n){p({level:"error",event:"node.close.failed",node_id:e,error:n})}return{root:r,closed:c,spared:i}}a(se,"closeNode");export{se as closeNode,z as closingSet,P as publishNotice};
|
package/dist/daemon/crtrd.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
var Pe=Object.defineProperty;var a=(t,n)=>Pe(t,"name",{value:n,configurable:!0});import{startPeerOutbox as xe}from"./peer/outbox.js";import{reportMachineStatus as Ie}from"../core/peer/directory.js";import{createPeerRelay as De}from"./peer/relay-service.js";import{writeFileSync as Te,readFileSync as Ce,rmSync as $e,mkdirSync as ee,existsSync as E,chmodSync as Le}from"node:fs";import{createServer as re}from"node:http";import{dirname as Ae}from"node:path";import{envCrtrdTcp as Ne,envDocumentPort as Me}from"../shared/env.js";import{serveCanvasConversationStore as Oe}from"../core/canvas/sessions.js";import{pollRunObservers as Ge}from"./runs/observer.js";import{randomBytes as Fe}from"node:crypto";import{apiSocketPath as He,crtrHome as je}from"../core/canvas/paths.js";import{activeAppUsers as Be}from"../core/spaces/users.js";import{ensureAppSpace as qe,ensureUserFiles as ze}from"../core/spaces/space.js";import{LAUNCHER_SOCKET as x}from"../launcher/spec.js";import{launcherRequest as D}from"../launcher/client.js";import{installLauncherEventSink as We}from"./launcher-events.js";import{initializeEmptyLayout as Ue,layoutNeedsMigration as Ke,socketDir as te}from"../core/layout.js";import{migrateLooseKeys as Je}from"../core/layout-migrate/loose-keys.js";import{relocateProfileFolders as Ve}from"../core/profiles/relocate.js";import{getNode as Qe,listNodesForSupervision as ne,setFrozen as oe}from"../core/canvas/index.js";import{createApiServer as Ye}from"./api/server.js";import{createDocumentListener as Xe}from"./api/document-listener.js";import{documentSecret as Ze}from"./api/document-secret.js";import{createAppListener as er}from"./api/app-listener.js";import{installLocalTerminalGrant as rr}from"../core/grants/local.js";import{onRunEventAppended as tr}from"../core/runs/events.js";import{runNotices as nr}from"./run-notices.js";import{createGrantSync as or,GRANT_SYNC_INTERVAL_S as ir}from"../core/grants/sync.js";import{runRemovalCascades as sr}from"../core/grants/remove.js";import{sweepSandboxes as ar}from"../core/grants/on-sync.js";import{rebuildCronExecutions as cr}from"./cron/run-socket.js";import{hasSyncedGrants as dr}from"../core/grants/mirror.js";import{readConfig as ie}from"../core/config.js";import{reconcileUndeliveredTickets as lr}from"./human/sweep.js";import{resetHandedOffDeliveries as pr}from"../core/canvas/deliveries.js";import{resetHandedOffDaemonActions as mr}from"../core/canvas/daemon-actions.js";import{sweepReviews as fr}from"./review/sweep.js";import{pidfilePath as j}from"./pidfile.js";import{rendererWarning as ur}from"../core/runtime/package-health.js";import{DEFAULT_INTERVAL_MS as hr}from"./supervise-cadence.js";import{createResumeDetector as vr}from"./resume-detector.js";import{BrokerSupervisionReconciler as wr}from"./reconcilers/broker-supervision.js";import{ControllerDeathReconciler as gr}from"./reconcilers/controller-death.js";import{NodeLifecycleReconciler as yr}from"./reconcilers/node-lifecycle/tick.js";import{NodeDeadlineReconciler as Sr}from"./reconcilers/node-deadline.js";import{CronLaneReconciler as _r}from"./reconcilers/cron-lane.js";import{DeliveryLaneReconciler as br}from"./reconcilers/delivery-lane.js";import{ActionLaneReconciler as kr}from"./reconcilers/action-lane.js";import{endLiveExecution as Er,migrateLegacyExecutionIdentities as Rr}from"../core/canvas/executions.js";import{revokePriorEpochNodeTokens as Pr}from"../core/canvas/node-tokens.js";import{PendingReviewSubmitReconciler as xr}from"./reconcilers/pending-review-submit.js";import{StorageMaintenanceReconciler as Ir}from"./reconcilers/storage-maintenance.js";import{StorageDueWorkReconciler as Dr}from"./reconcilers/storage-due-work.js";import{BashDeadlineReconciler as Tr}from"./reconcilers/bash-deadline.js";import{FaultRetryBackstopReconciler as Cr}from"./reconcilers/fault-retry-backstop.js";import{StructuredRequestReconciler as $r}from"./reconcilers/structured-request-lane.js";import{reconcileStructuredRequestSidecars as Lr}from"./structured-requests/boot.js";import{captureLivenessSnapshot as se,capturePidCommand as Ar,captureTeardownSnapshot as ae,isPidAlive as Nr,isAnyPidAlive as ce,killProcessTreePids as de}from"../core/canvas/pid.js";import{bindFleet as Mr,boundFleet as Or}from"../core/runtime/fleet.js";import{bindDaemonControl as Gr,clearDaemonControl as Fr}from"./control.js";import{execDaemon as Hr,spawnDaemon as jr}from"./manage.js";import{reconcileAndMigrateBoot as Br}from"../core/canvas/boot.js";import{resolveInstallId as qr}from"../core/canvas/install-id.js";import{setInstallId as zr}from"../core/runtime/nodes.js";import{claimDaemonOwnership as Wr,releaseDaemonOwnership as le}from"../core/canvas/daemon-owner.js";import{migrate as Ur,openDb as pe,withCanvasWrite as Kr,bindDaemonCanvasOpenHook as Jr,clearDaemonCanvasOpenHook as me}from"../core/canvas/db.js";import{brokerSignalBus as B}from"./broker-signals/bus.js";import{brokerSignalStreams as Vr}from"./api/handlers/broker-signals.js";import{reconcilePackages as Qr}from"../core/graph/package-reconcile.js";import{startRepoSync as Yr}from"../core/graph/repo-sync/index.js";import{prewarmRecentRecipes as Xr,reapStaleSpares as Zr}from"../core/runtime/warm-pool.js";import{DaemonFleet as et}from"./fleet.js";import{BOOT_MIGRATIONS as rt}from"./boot-migrations.js";import{applyJoinedOwner as tt}from"./joined-owner.js";import{emitEvent as f}from"../core/events/emit.js";import{operationIdContext as _}from"../core/events/operation-id.js";import{bindDaemonEventSource as nt}from"../core/events/source.js";import{activateCanvasImport as ot,MigrationBlockedError as it,runForcedCanvasImport as st}from"../migrations/activation.js";import{convertLegacyProviderStore as at,convertLegacyScopedStore as ct}from"../core/scoped-state/migrate.js";import{userScopeRoot as dt}from"../core/scope.js";import{secretsDir as lt}from"../core/layout.js";function q(t,n){return t.includes(` --canvas-home ${n} `)}a(q,"brokerCommandDeclaresCanvasHome");function z(t){return/ --epoch (\S+) /.exec(t)?.[1]??null}a(z,"brokerCommandEpoch");const pt=5e3,fe=150;async function mt(t){const n=se();if(n===null)throw f({level:"error",event:"daemon.census.snapshot_failed",fields:{invariant:"prior-epoch brokers are reaped before readiness"}}),new Error("prior-epoch broker census could not capture the process table");const c=je(),u=[];for(const[s,m]of n.processes){const y=m.command;if(m.zombie||!y.includes("broker-cli.js")||!q(y,c)||z(y)===t)continue;const b=y.trim().split(/\s+/).at(-1)??"";b===""||b.endsWith("broker-cli.js")||u.push({pid:s,nodeId:b})}let h=0;const o=[];for(const s of u){const m=Ar(s.pid);if(m===null||!m.includes("broker-cli.js")||!q(m,c)||z(m)===t||m.trim().split(/\s+/).at(-1)!==s.nodeId)continue;const y=ae(s.pid,null);if(!y.reused){try{process.platform==="linux"&&E(x)?await D({operation:"stop",pid:s.pid}):process.kill(s.pid,"SIGTERM")}catch{continue}h++,o.push({pid:s.pid,snap:y})}}const g=Date.now()+pt;for(;Date.now()<g&&o.some(s=>ce(s.snap.tree.length>0?s.snap.tree:[s.pid]));)await new Promise(s=>setTimeout(s,fe));let w=0;for(const s of o){const m=s.snap.tree.length>0?s.snap.tree:[s.pid];ce(m)&&(process.platform==="linux"&&E(x)?await D({operation:"stop",pid:s.pid}):de(m,"SIGKILL",s.snap.identities),w++)}w>0&&await new Promise(s=>setTimeout(s,fe));const d=se();if(d===null)throw f({level:"error",event:"daemon.census.snapshot_failed",fields:{invariant:"prior-epoch brokers are reaped before readiness",stage:"final"}}),new Error("prior-epoch broker census could not capture the final process table");const p=[];for(const[s,m]of d.processes){const y=m.command;m.zombie||!y.includes("broker-cli.js")||q(y,c)&&z(y)!==t&&p.push(s)}if(p.length>0)throw new Error(`prior-epoch broker census could not prove termination of pid(s): ${p.join(", ")}`);f({level:"info",event:"daemon.census.completed",fields:{prior_epoch_brokers:u.length,sigtermed:h,sigkilled:w}})}a(mt,"reapPriorEpochBrokers");const ft=5e3;async function ut(t){const n=Array.from(t.entries());if(n.length===0)return;for(const[o]of n){const g=Qe(o)?.status;(g==="active"||g==="idle")&&oe(o,new Date().toISOString())}const c=n.map(([,o])=>({pid:o.pid,snap:ae(o.pid,null),exited:o.handle.exited}));for(const o of c)if(!o.snap.reused)try{process.platform==="linux"&&E(x)?await D({operation:"stop",pid:o.pid}):process.kill(o.pid,"SIGTERM")}catch{}const u=new Promise(o=>{setTimeout(o,ft).unref()});await Promise.allSettled(c.map(o=>Promise.race([o.exited.then(()=>{}),u])));const h=[];for(const o of c)Nr(o.pid)&&(process.platform==="linux"&&E(x)?await D({operation:"stop",pid:o.pid}):de(o.snap.tree.length>0?o.snap.tree:[o.pid],"SIGKILL",o.snap.identities),h.push(o));await Promise.all(h.map(o=>o.exited));for(const[o]of n)Er(o,{reason:"daemon-teardown"});f({level:"info",event:"daemon.fleet_teardown.completed",fields:{brokers:c.length,sigkilled:h.length}})}a(ut,"teardownFleet");function ue(){ee(Ae(j()),{recursive:!0}),Te(j(),String(process.pid),"utf8")}a(ue,"writePidfile");function he(t){return typeof t=="object"&&t!==null&&t.code==="ENOENT"}a(he,"isMissingPathError");function ve(t){const n=j();let c;try{c=Ce(n,"utf8")}catch(u){if(he(u))return;throw u}if(c.trim()!==String(t))throw new Error(`daemon readiness mirror does not name this invocation (expected pid ${t})`);try{$e(n)}catch(u){if(he(u))return;throw u}}a(ve,"removeOwnedPidfileMirror");const ht={acceptsDetachedWork:a(()=>!0,"acceptsDetachedWork"),registerDetached:a(t=>{t.catch(()=>{})},"registerDetached")},W=new wr,vt=new gr,wt=new yr,gt=new Sr,yt=new _r,St=new br,_t=new kr,bt=new xr,kt=new Ir,Et=new Dr,Rt=new Tr,Pt=new Cr,xt=new $r;async function It(t=Date.now(),n=ht){const c=Or(),u=await W.runFleetPreamble(c);let h,o;try{const w=ne();h=w.filter(d=>d.status==="active"||d.status==="idle"),o=w.filter(d=>d.status==="done"||d.status==="canceled"||d.status==="dead")}catch(w){f({level:"error",event:"canvas.node_list.failed",error:w});return}await W.run(t,{rows:h,fleet:c,lifecycle:n}),vt.run(t,{rows:h});const g=await wt.run(t,{rows:[...h,...o],fleet:c});gt.run(t),xt.run(t),yt.run(t,{lifecycle:n}),St.run(t,{lifecycle:n}),_t.run(t,{lifecycle:n}),bt.run(t,{lifecycle:n}),kt.run(t,{lifecycle:n,fleet:c}),Et.run(t,{lifecycle:n}),Ge(),Pt.run(t,{fleet:c,lifecycle:n}),await Rt.run(t,{rows:h}),W.warnIfSaturated({fleet:c,lifecycle:n,thresholds:u,frozen:g})}a(It,"superviseTick");async function Dt(t){ee(te(),{recursive:!0,mode:493}),process.platform==="linux"&&Le(te(),493);const n=He();if(E(n))throw new Error(`layout refusal cannot bind occupied socket: ${n}`);const c=re((d,p)=>{if(d.method==="GET"&&d.url==="/healthz"){p.writeHead(200,{"content-type":"application/json; charset=utf-8"}),p.end(JSON.stringify({ok:!1,daemon_up:!0,store_accessible:!1,brokers_reconciled:!1,startup_phase:"blocked",startup_blocked:"layout_migration_required"}));return}p.writeHead(503,{"content-type":"application/json; charset=utf-8"}),p.end(JSON.stringify({error:{code:"layout_migration_required",message:"run crtr sys migrate while the runtime is offline",type:"server_error",origin:"runtime",retryable:!1}}))});await new Promise((d,p)=>{c.once("error",p),c.listen(n,()=>{c.off("error",p),d()})});let u;const h=t.tcp??Ne();if(h){const d=/^(.*):(\d+)$/.exec(h);if(!d||Number(d[2])>65535)throw new Error(`invalid refusal TCP address: ${h}`);const p=re(c.listeners("request")[0]);await new Promise((s,m)=>{p.once("error",m),p.listen(Number(d[2]),d[1],()=>{p.off("error",m),s()})}),u=p}ue();let o;const g=a(()=>(o??=(async()=>{c.closeAllConnections(),u?.closeAllConnections(),await Promise.all([c,u].filter(d=>d!==void 0).map(d=>new Promise((p,s)=>d.close(m=>m?s(m):p())))),ve(process.pid),process.off("SIGINT",w),process.off("SIGTERM",w)})(),o),"cleanup"),w=a(()=>{g().then(()=>process.exit(0),d=>{process.stderr.write(`[crtrd] layout refusal cleanup failed: ${String(d)}
|
|
2
|
-
`),process.exit(1)})},"onSignal");return process.on("SIGINT",w),process.on("SIGTERM",w),g}a(
|
|
1
|
+
var Pe=Object.defineProperty;var a=(t,n)=>Pe(t,"name",{value:n,configurable:!0});import{startPeerOutbox as xe}from"./peer/outbox.js";import{reportMachineStatus as Ie}from"../core/peer/directory.js";import{createPeerRelay as De}from"./peer/relay-service.js";import{writeFileSync as Te,readFileSync as Ce,rmSync as $e,mkdirSync as ee,existsSync as E,chmodSync as Le}from"node:fs";import{createServer as re}from"node:http";import{dirname as Ae}from"node:path";import{envCrtrdTcp as Ne,envDocumentPort as Me}from"../shared/env.js";import{serveCanvasConversationStore as Oe}from"../core/canvas/sessions.js";import{pollRunObservers as Fe}from"./runs/observer.js";import{randomBytes as Ge}from"node:crypto";import{apiSocketPath as He,crtrHome as je}from"../core/canvas/paths.js";import{activeAppUsers as Be}from"../core/spaces/users.js";import{ensureAppSpace as qe,ensureUserFiles as ze}from"../core/spaces/space.js";import{LAUNCHER_SOCKET as x}from"../launcher/spec.js";import{launcherRequest as D}from"../launcher/client.js";import{installLauncherEventSink as We}from"./launcher-events.js";import{initializeEmptyLayout as Ue,layoutNeedsMigration as Ke,socketDir as te}from"../core/layout.js";import{migrateLooseKeys as Je}from"../core/layout-migrate/loose-keys.js";import{relocateProfileFolders as Ve}from"../core/profiles/relocate.js";import{getNode as Qe,listNodesForSupervision as ne,setFrozen as oe}from"../core/canvas/index.js";import{createApiServer as Ye}from"./api/server.js";import{createDocumentListener as Xe}from"./api/document-listener.js";import{documentSecret as Ze}from"./api/document-secret.js";import{createAppListener as er}from"./api/app-listener.js";import{installLocalTerminalGrant as rr}from"../core/grants/local.js";import{onRunEventAppended as tr}from"../core/runs/events.js";import{runNotices as nr}from"./run-notices.js";import{createGrantSync as or,GRANT_SYNC_INTERVAL_S as ir}from"../core/grants/sync.js";import{runRemovalCascades as sr}from"../core/grants/remove.js";import{sweepSandboxes as ar}from"../core/grants/on-sync.js";import{rebuildCronExecutions as cr}from"./cron/run-socket.js";import{hasSyncedGrants as dr}from"../core/grants/mirror.js";import{readConfig as ie}from"../core/config.js";import{reconcileUndeliveredTickets as lr}from"./human/sweep.js";import{resetHandedOffDeliveries as pr}from"../core/canvas/deliveries.js";import{resetHandedOffDaemonActions as mr}from"../core/canvas/daemon-actions.js";import{sweepReviews as fr}from"./review/sweep.js";import{pidfilePath as B}from"./pidfile.js";import{rendererWarning as ur}from"../core/runtime/package-health.js";import{DEFAULT_INTERVAL_MS as hr}from"./supervise-cadence.js";import{createResumeDetector as vr}from"./resume-detector.js";import{setFatalFaultAnnouncer as wr}from"../core/canvas/recovery.js";import{BrokerSupervisionReconciler as gr}from"./reconcilers/broker-supervision.js";import{ControllerDeathReconciler as yr}from"./reconcilers/controller-death.js";import{NodeLifecycleReconciler as Sr}from"./reconcilers/node-lifecycle/tick.js";import{NodeDeadlineReconciler as _r}from"./reconcilers/node-deadline.js";import{CronLaneReconciler as br}from"./reconcilers/cron-lane.js";import{DeliveryLaneReconciler as kr}from"./reconcilers/delivery-lane.js";import{ActionLaneReconciler as Er}from"./reconcilers/action-lane.js";import{endLiveExecution as Rr,migrateLegacyExecutionIdentities as Pr}from"../core/canvas/executions.js";import{revokePriorEpochNodeTokens as xr}from"../core/canvas/node-tokens.js";import{PendingReviewSubmitReconciler as Ir}from"./reconcilers/pending-review-submit.js";import{StorageMaintenanceReconciler as Dr}from"./reconcilers/storage-maintenance.js";import{StorageDueWorkReconciler as Tr}from"./reconcilers/storage-due-work.js";import{BashDeadlineReconciler as Cr}from"./reconcilers/bash-deadline.js";import{FaultRetryBackstopReconciler as $r}from"./reconcilers/fault-retry-backstop.js";import{StructuredRequestReconciler as Lr}from"./reconcilers/structured-request-lane.js";import{reconcileStructuredRequestSidecars as Ar}from"./structured-requests/boot.js";import{captureLivenessSnapshot as se,capturePidCommand as Nr,captureTeardownSnapshot as ae,isPidAlive as Mr,isAnyPidAlive as ce,killProcessTreePids as de}from"../core/canvas/pid.js";import{bindFleet as Or,boundFleet as Fr}from"../core/runtime/fleet.js";import{bindDaemonControl as Gr,clearDaemonControl as Hr}from"./control.js";import{execDaemon as jr,spawnDaemon as Br}from"./manage.js";import{reconcileAndMigrateBoot as qr}from"../core/canvas/boot.js";import{resolveInstallId as zr}from"../core/canvas/install-id.js";import{setInstallId as Wr}from"../core/runtime/nodes.js";import{claimDaemonOwnership as Ur,releaseDaemonOwnership as le}from"../core/canvas/daemon-owner.js";import{migrate as Kr,openDb as pe,withCanvasWrite as Jr,bindDaemonCanvasOpenHook as Vr,clearDaemonCanvasOpenHook as me}from"../core/canvas/db.js";import{brokerSignalBus as q}from"./broker-signals/bus.js";import{brokerSignalStreams as Qr}from"./api/handlers/broker-signals.js";import{reconcilePackages as Yr}from"../core/graph/package-reconcile.js";import{startRepoSync as Xr}from"../core/graph/repo-sync/index.js";import{prewarmRecentRecipes as Zr,reapStaleSpares as et}from"../core/runtime/warm-pool.js";import{DaemonFleet as rt}from"./fleet.js";import{BOOT_MIGRATIONS as tt}from"./boot-migrations.js";import{applyJoinedOwner as nt}from"./joined-owner.js";import{emitEvent as f}from"../core/events/emit.js";import{operationIdContext as _}from"../core/events/operation-id.js";import{bindDaemonEventSource as ot}from"../core/events/source.js";import{activateCanvasImport as it,MigrationBlockedError as st,runForcedCanvasImport as at}from"../migrations/activation.js";import{convertLegacyProviderStore as ct,convertLegacyScopedStore as dt}from"../core/scoped-state/migrate.js";import{userScopeRoot as lt}from"../core/scope.js";import{secretsDir as pt}from"../core/layout.js";function z(t,n){return t.includes(` --canvas-home ${n} `)}a(z,"brokerCommandDeclaresCanvasHome");function W(t){return/ --epoch (\S+) /.exec(t)?.[1]??null}a(W,"brokerCommandEpoch");const mt=5e3,fe=150;async function ft(t){const n=se();if(n===null)throw f({level:"error",event:"daemon.census.snapshot_failed",fields:{invariant:"prior-epoch brokers are reaped before readiness"}}),new Error("prior-epoch broker census could not capture the process table");const c=je(),u=[];for(const[s,m]of n.processes){const y=m.command;if(m.zombie||!y.includes("broker-cli.js")||!z(y,c)||W(y)===t)continue;const b=y.trim().split(/\s+/).at(-1)??"";b===""||b.endsWith("broker-cli.js")||u.push({pid:s,nodeId:b})}let h=0;const o=[];for(const s of u){const m=Nr(s.pid);if(m===null||!m.includes("broker-cli.js")||!z(m,c)||W(m)===t||m.trim().split(/\s+/).at(-1)!==s.nodeId)continue;const y=ae(s.pid,null);if(!y.reused){try{process.platform==="linux"&&E(x)?await D({operation:"stop",pid:s.pid}):process.kill(s.pid,"SIGTERM")}catch{continue}h++,o.push({pid:s.pid,snap:y})}}const g=Date.now()+mt;for(;Date.now()<g&&o.some(s=>ce(s.snap.tree.length>0?s.snap.tree:[s.pid]));)await new Promise(s=>setTimeout(s,fe));let w=0;for(const s of o){const m=s.snap.tree.length>0?s.snap.tree:[s.pid];ce(m)&&(process.platform==="linux"&&E(x)?await D({operation:"stop",pid:s.pid}):de(m,"SIGKILL",s.snap.identities),w++)}w>0&&await new Promise(s=>setTimeout(s,fe));const d=se();if(d===null)throw f({level:"error",event:"daemon.census.snapshot_failed",fields:{invariant:"prior-epoch brokers are reaped before readiness",stage:"final"}}),new Error("prior-epoch broker census could not capture the final process table");const p=[];for(const[s,m]of d.processes){const y=m.command;m.zombie||!y.includes("broker-cli.js")||z(y,c)&&W(y)!==t&&p.push(s)}if(p.length>0)throw new Error(`prior-epoch broker census could not prove termination of pid(s): ${p.join(", ")}`);f({level:"info",event:"daemon.census.completed",fields:{prior_epoch_brokers:u.length,sigtermed:h,sigkilled:w}})}a(ft,"reapPriorEpochBrokers");const ut=5e3;async function ht(t){const n=Array.from(t.entries());if(n.length===0)return;for(const[o]of n){const g=Qe(o)?.status;(g==="active"||g==="idle")&&oe(o,new Date().toISOString())}const c=n.map(([,o])=>({pid:o.pid,snap:ae(o.pid,null),exited:o.handle.exited}));for(const o of c)if(!o.snap.reused)try{process.platform==="linux"&&E(x)?await D({operation:"stop",pid:o.pid}):process.kill(o.pid,"SIGTERM")}catch{}const u=new Promise(o=>{setTimeout(o,ut).unref()});await Promise.allSettled(c.map(o=>Promise.race([o.exited.then(()=>{}),u])));const h=[];for(const o of c)Mr(o.pid)&&(process.platform==="linux"&&E(x)?await D({operation:"stop",pid:o.pid}):de(o.snap.tree.length>0?o.snap.tree:[o.pid],"SIGKILL",o.snap.identities),h.push(o));await Promise.all(h.map(o=>o.exited));for(const[o]of n)Rr(o,{reason:"daemon-teardown"});f({level:"info",event:"daemon.fleet_teardown.completed",fields:{brokers:c.length,sigkilled:h.length}})}a(ht,"teardownFleet");function ue(){ee(Ae(B()),{recursive:!0}),Te(B(),String(process.pid),"utf8")}a(ue,"writePidfile");function he(t){return typeof t=="object"&&t!==null&&t.code==="ENOENT"}a(he,"isMissingPathError");function ve(t){const n=B();let c;try{c=Ce(n,"utf8")}catch(u){if(he(u))return;throw u}if(c.trim()!==String(t))throw new Error(`daemon readiness mirror does not name this invocation (expected pid ${t})`);try{$e(n)}catch(u){if(he(u))return;throw u}}a(ve,"removeOwnedPidfileMirror");const vt={acceptsDetachedWork:a(()=>!0,"acceptsDetachedWork"),registerDetached:a(t=>{t.catch(()=>{})},"registerDetached")},O=new gr;wr(t=>O.handleFatalFault(t,!1));const wt=new yr,gt=new Sr,yt=new _r,St=new br,_t=new kr,bt=new Er,kt=new Ir,Et=new Dr,Rt=new Tr,Pt=new Cr,xt=new $r,It=new Lr;async function Dt(t=Date.now(),n=vt){const c=Fr(),u=await O.runFleetPreamble(c);let h,o;try{const w=ne();h=w.filter(d=>d.status==="active"||d.status==="idle"),o=w.filter(d=>d.status==="done"||d.status==="canceled"||d.status==="dead")}catch(w){f({level:"error",event:"canvas.node_list.failed",error:w});return}await O.run(t,{rows:h,fleet:c,lifecycle:n}),wt.run(t,{rows:h});const g=await gt.run(t,{rows:[...h,...o],fleet:c});yt.run(t),It.run(t),St.run(t,{lifecycle:n}),_t.run(t,{lifecycle:n}),bt.run(t,{lifecycle:n}),kt.run(t,{lifecycle:n}),Et.run(t,{lifecycle:n,fleet:c}),Rt.run(t,{lifecycle:n}),Fe(),xt.run(t,{fleet:c,lifecycle:n}),await Pt.run(t,{rows:h}),O.warnIfSaturated({fleet:c,lifecycle:n,thresholds:u,frozen:g})}a(Dt,"superviseTick");async function Tt(t){ee(te(),{recursive:!0,mode:493}),process.platform==="linux"&&Le(te(),493);const n=He();if(E(n))throw new Error(`layout refusal cannot bind occupied socket: ${n}`);const c=re((d,p)=>{if(d.method==="GET"&&d.url==="/healthz"){p.writeHead(200,{"content-type":"application/json; charset=utf-8"}),p.end(JSON.stringify({ok:!1,daemon_up:!0,store_accessible:!1,brokers_reconciled:!1,startup_phase:"blocked",startup_blocked:"layout_migration_required"}));return}p.writeHead(503,{"content-type":"application/json; charset=utf-8"}),p.end(JSON.stringify({error:{code:"layout_migration_required",message:"run crtr sys migrate while the runtime is offline",type:"server_error",origin:"runtime",retryable:!1}}))});await new Promise((d,p)=>{c.once("error",p),c.listen(n,()=>{c.off("error",p),d()})});let u;const h=t.tcp??Ne();if(h){const d=/^(.*):(\d+)$/.exec(h);if(!d||Number(d[2])>65535)throw new Error(`invalid refusal TCP address: ${h}`);const p=re(c.listeners("request")[0]);await new Promise((s,m)=>{p.once("error",m),p.listen(Number(d[2]),d[1],()=>{p.off("error",m),s()})}),u=p}ue();let o;const g=a(()=>(o??=(async()=>{c.closeAllConnections(),u?.closeAllConnections(),await Promise.all([c,u].filter(d=>d!==void 0).map(d=>new Promise((p,s)=>d.close(m=>m?s(m):p())))),ve(process.pid),process.off("SIGINT",w),process.off("SIGTERM",w)})(),o),"cleanup"),w=a(()=>{g().then(()=>process.exit(0),d=>{process.stderr.write(`[crtrd] layout refusal cleanup failed: ${String(d)}
|
|
2
|
+
`),process.exit(1)})},"onSignal");return process.on("SIGINT",w),process.on("SIGTERM",w),g}a(Tt,"serveLayoutRefusal");async function Ct(t={}){if(Ke())return Tt(t);Ue();const n=Ur(Ge(16).toString("hex"));if(!n.claimed){if(n.reason==="incumbent_alive")process.stderr.write(`[crtrd] already running (pid ${n.incumbentPid??"?"})
|
|
3
3
|
`);else{const r=[n.incumbentPid!==void 0?`pid ${n.incumbentPid}`:void 0,n.verdict!==void 0?`verdict ${n.verdict}`:void 0].filter(i=>i!==void 0),e=r.length>0?` (${r.join(", ")})`:"";process.stderr.write(`[crtrd] claim lost: ${n.reason}${e}
|
|
4
|
-
`),n.reason==="own_identity_indeterminate"&&process.stderr.write("[crtrd] cannot read its own process identity. crouter needs /proc on Linux, or the `ps` command elsewhere (Debian/Ubuntu: apt-get install procps).\n"),(n.reason==="own_identity_indeterminate"||n.reason==="incumbent_malformed")&&(process.exitCode=1)}return async()=>{}}const c=n.claim;let u=null;try{await
|
|
5
|
-
`);if(process.platform==="darwin"){const{readConfig:e,updateConfig:i}=await import("../core/config.js");if(e("user").paths?.user_files===void 0){const{homedir:l}=await import("node:os");i("user",S=>{S.paths??={},S.paths.user_files??=l()})}}await
|
|
6
|
-
`);
|
|
4
|
+
`),n.reason==="own_identity_indeterminate"&&process.stderr.write("[crtrd] cannot read its own process identity. crouter needs /proc on Linux, or the `ps` command elsewhere (Debian/Ubuntu: apt-get install procps).\n"),(n.reason==="own_identity_indeterminate"||n.reason==="incumbent_malformed")&&(process.exitCode=1)}return async()=>{}}const c=n.claim;let u=null;try{await ft(c.token),dt({kind:"user",root:lt()});for(const e of Ve())process.stderr.write(`[crtrd] ${e}
|
|
5
|
+
`);if(process.platform==="darwin"){const{readConfig:e,updateConfig:i}=await import("../core/config.js");if(e("user").paths?.user_files===void 0){const{homedir:l}=await import("node:os");i("user",S=>{S.paths??={},S.paths.user_files??=l()})}}await ct(pt());for(const e of Je())process.stderr.write(`[crtrd] ${e}
|
|
6
|
+
`);Kr(pe()),Vr(e=>q.install(e));const r=Jr(e=>Yr(e));for(const e of r.conflicts)process.stderr.write(`[crtrd] plugin documents not reconciled: ${e.message}
|
|
7
7
|
`);for(const e of r.invalid)process.stderr.write(`[crtrd] package file is not a document: ${e.path}: ${e.error}
|
|
8
8
|
`);for(const e of r.quarantined)process.stderr.write(`[crtrd] plugin "${e.name}" has a damaged ${e.file} (${e.reason}); ${e.movedTo!==void 0?`moved to ${e.movedTo}`:"left in place and skipped"}
|
|
9
9
|
`);for(const e of r.kinds.refused)process.stderr.write(`[crtrd] plugin "${e.plugin}" kind ${e.kind} not registered: ${e.message}
|
|
10
10
|
`);for(const e of r.kinds.invalid)process.stderr.write(`[crtrd] plugin "${e.plugin}" declares invalid object kinds or scopes; no kinds registered and no app token: ${e.error}
|
|
11
|
-
`);u=
|
|
11
|
+
`);u=nt(),process.platform==="linux"&&E(x)&&(We(),await D({operation:"users.sync",users:Be()})),xr(c.token)}catch(r){me(),q.close();try{const{released:e}=le(c);if(!e)throw new Error("daemon ownership claim was not released")}catch(e){throw new AggregateError([r,e],"daemon startup failed and cleanup also failed")}throw r}let h=!0,o,g=Promise.resolve(),w=!1,d,p;const s=new Set;let m=!1,y=!1,b,A,F,U=!1,N,T,C,$,G;const we=vr();let R,v={phase:"initializing",message:"daemon startup is running the canvas import and normal services are unavailable",blockerPaths:[]},I="initial startup activation",ge=null;function ye(){return v.phase==="ready"?null:{phase:v.phase,message:v.message,blockerPaths:v.blockerPaths}}a(ye,"startupBlock");function k(r){s.add(r),r.finally(()=>{s.delete(r)}).catch(()=>{})}a(k,"registerDetached");const K={acceptsDetachedWork:a(()=>h,"acceptsDetachedWork"),registerDetached:k};Xr(K,pe);async function Se(){try{h=!1,Qr.close(),me(),q.close(),d!==void 0&&(clearInterval(d),d=void 0),C!==void 0&&(clearInterval(C),C=void 0),G?.(),G=void 0;let r;do r=g,await r;while(r!==g);for(;s.size>0;)await Promise.allSettled([...s]);if(p!==void 0&&(await ht(p),p.dispose()),F!==void 0&&await F.close(),A!==void 0&&!U&&(U=!0,await A.close()),$!==void 0){const e=$;$=void 0,await e.stop()}if(T!==void 0){const e=T;T=void 0,await e.close()}if(N!==void 0){const e=N;N=void 0,await e.close()}if(m||(ve(process.pid),m=!0),m&&!y){const{released:e}=le(c);if(!e)throw new Error("daemon ownership claim was not released");y=!0}}finally{Hr(),process.off("SIGINT",Q),process.off("SIGTERM",Y),process.off("exit",X)}}a(Se,"cleanupAttempt");const M=1e3;let J=!1;function _e(){return J?{graceMs:M}:(J=!0,_.fresh(()=>{f({level:"info",event:"daemon.handover.armed",fields:{pid:process.pid,grace_ms:M}})}),setTimeout(()=>{be()},M),{graceMs:M})}a(_e,"requestHandover");async function be(){try{await P()}catch(r){const e=r instanceof Error?r.stack??r.message:String(r);process.stderr.write(`[crtrd] handover cleanup failed:
|
|
12
12
|
${e}
|
|
13
|
-
`),process.exit(1)}try{process.platform==="linux"&&E(x)&&(await D({operation:"daemon.handover"}),process.exit(0)),process.pid===1&&await
|
|
13
|
+
`),process.exit(1)}try{process.platform==="linux"&&E(x)&&(await D({operation:"daemon.handover"}),process.exit(0)),process.pid===1&&await jr();const r=await Br({waitForJoinLock:!0});_.fresh(()=>{f({level:"info",event:"daemon.handover.completed",fields:{predecessor_pid:process.pid,successor_pid:r.pid??r.existing_pid??null,spawned:r.started}})})}catch(r){_.fresh(()=>{f({level:"error",event:"daemon.handover.successor_failed",error:r})});const e=r instanceof Error?r.message:String(r);process.stderr.write(`[crtrd] handover successor failed to start: ${e}
|
|
14
14
|
`),process.exit(1)}process.exit(0)}a(be,"performHandover");function P(){if(b!==void 0)return b;const r=Se();return b=r,r.then(()=>{b===r&&(b=void 0)},()=>{b===r&&(b=void 0)}),r}a(P,"requestCleanup");async function V(r){try{await P(),process.exit(0)}catch(e){process.exitCode=1;const i=e instanceof Error?e.stack??`${e.name}: ${e.message}`:String(e);process.stderr.write(`[crtrd] ${r} cleanup failed:
|
|
15
15
|
${i}
|
|
16
|
-
`),process.exit(1)}}a(V,"handleSignal");function Q(){V("SIGINT")}a(Q,"onSigint");function Y(){V("SIGTERM")}a(Y,"onSigterm");function X(){P().catch(()=>{})}a(X,"onExit");function
|
|
16
|
+
`),process.exit(1)}}a(V,"handleSignal");function Q(){V("SIGINT")}a(Q,"onSigint");function Y(){V("SIGTERM")}a(Y,"onSigterm");function X(){P().catch(()=>{})}a(X,"onExit");function H(r){h&&(g=g.then(r).then(()=>{},e=>{_.fresh(()=>{f({level:"error",event:"daemon.lane_job.failed",error:e})})}))}a(H,"enqueue");function Z(){!h||w||(we.check()&&R&&(f({level:"info",event:"daemon.resume.detected"}),k(R().catch(()=>{}))),w=!0,H(async()=>{if(w=!1,!!h)try{await Dt(Date.now(),K)}catch(r){_.fresh(()=>{f({level:"error",event:"daemon.tick.failed",error:r})})}}))}a(Z,"enqueueTick");let L=null;async function ke(){if(L!==null)throw{status:500,code:"admission_failed",message:`daemon admission previously failed: ${L instanceof Error?L.message:String(L)}`};if(v.phase==="ready")return{admitted:!1,already_admitted:!0,startup_phase:"ready"};if(v.phase!=="prepared"&&v.phase!=="recovering")throw{status:409,code:"not_prepared",message:v.message};const r=v.phase==="prepared";try{return await j(),v={phase:"ready",message:"",blockerPaths:[]},r?{admitted:!0,already_admitted:!1,startup_phase:"ready"}:{admitted:!1,already_admitted:!0,startup_phase:"ready"}}catch(e){throw L=e,{status:500,code:"admission_failed",message:`daemon admission failed: ${e instanceof Error?e.message:String(e)}`}}}a(ke,"admitStartup");async function Ee(r){if(I!==null)throw{status:409,code:"migration_in_progress",message:`the canvas import is already running (${I})`};I="repair";try{const e=await at({dryRun:r.dryRun});if(r.dryRun||e.pending||v.phase!=="blocked")return{result:e,resumed:!1};if(t.prepare)return v={phase:"prepared",message:"daemon storage is prepared and normal services are unavailable until admission",blockerPaths:[]},{result:e,resumed:!1};try{return await j(),v={phase:"ready",message:"",blockerPaths:[]},{result:e,resumed:!0}}catch(i){const l=i instanceof Error?i.message:String(i);return setTimeout(()=>{P().catch(()=>{})},1e3),{result:e,resumed:!1,resumeError:l}}}finally{I=null}}a(Ee,"repairMigrations");async function Re(){o=t.intervalMs??hr;const r=c.token;p=new rt({epoch:r,enqueue:H}),Or(p),v={phase:"recovering",message:"daemon startup recovery is running and normal services are unavailable",blockerPaths:[]},_.fresh(()=>{f({level:"info",event:"daemon.started",fields:{pid:process.pid,interval_ms:o}})});const e=zr();if(Wr(e),_.fresh(()=>{f({level:"info",event:"daemon.install_id.resolved",fields:{install_id:e}})}),_.fresh(()=>{let i;try{i=ur()}catch{return}i!==null&&f({level:"warn",event:"daemon.startup.warning",fields:{stage:"termrender",warning:i.slice(0,2048)}})}),await _.fresh(async()=>{await fr(),await lr(),pr(Date.now()),mr(Date.now())}),_.fresh(()=>{const{reconcile:i,migrated:l}=qr(Pr);i.changed&&f({level:"info",event:"daemon.boot_change.reconciled",fields:{cleared_count:i.cleared.length,same_boot_proven:i.sameBootProven}}),l.length>0&&f({level:"info",event:"daemon.pid_identity.migrated",fields:{migrated_count:l.length}})}),_.fresh(()=>{for(const i of ne())i.status!=="active"||i.pi_pid!=null||i.frozen_at!=null||i.respawn_not_before!=null||(oe(i.node_id,new Date().toISOString()),f({level:"warn",event:"daemon.startup.launch_debt_recorded",node_id:i.node_id}))}),_.fresh(()=>{Ar();for(const i of tt){const l=i.apply();l.changed&&f({level:"info",event:"daemon.boot_migration.applied",fields:{migration:i.id,...l.summary}})}}),k(cr()),R){const i=a(()=>{k(R().catch(()=>{})),k(Ie().then(l=>$?.observe(l)).then(()=>{},l=>{f({level:"warn",event:"daemon.peer.status_failed",error:l})}))},"refresh");k(sr().catch(()=>{})),k(ar().then(({completion:l})=>l).catch(l=>{f({level:"error",event:"daemon.grants.sweep_failed",error:l})})),i(),C=setInterval(i,ir*1e3),C.unref(),G=xe({joined:!0,register:k})}H(()=>{et(),Zr()}),d=setInterval(Z,o),Z()}a(Re,"completeStartup");function j(){return ge??=Re().catch(r=>{throw v={phase:"initializing",message:"daemon startup recovery failed and normal services are unavailable",blockerPaths:[]},r})}a(j,"resumeStartup");try{process.on("SIGINT",Q),process.on("SIGTERM",Y),process.on("exit",X),ot(),u!==null&&f({level:"info",event:"daemon.joined_owner.applied",fields:{owner:u.owner,rows:u.rows}}),N=await Oe();const r=c.token;Gr({epoch:r,requestHandover:_e,registerDetached:k,startupBlock:ye,admitStartup:ke,repairMigrations:Ee}),ue(),A=Ye({tcp:t.tcp}),await A.ready;const e=Me()??ie("user").document_port,i=Xe(e,Ze());try{await i.ready,F=i}catch(S){f({level:"warn",event:"daemon.document_listener.bind_failed",fields:{port:e,error:S instanceof Error?S.message:String(S)}})}const l=ie("user").runtime;l?.issuer?(R=or(l.issuer,k),l.unsandboxed===!0&&($=De({syncGrants:R})),tr(S=>nr().appended(S))):rr(),l?.unsandboxed===!0&&l.listener!==void 0&&f({level:"warn",event:"daemon.app_listener.refused_unsandboxed",fields:{reason:"runtime.unsandboxed is set; runtime.listener is ignored"}}),l!==void 0&&l.listener!==void 0&&l.unsandboxed!==!0&&(T=er(l,()=>dr(l.issuer.replace(/\/$/,"")),R),await T.ready);try{await it()}catch(S){if(I=null,S instanceof st)return v={phase:"blocked",message:S.message,blockerPaths:S.blockerPaths},P;throw S}process.platform==="linux"&&E(x)&&(ze(),await qe("app:terminal"));try{t.prepare?v={phase:"prepared",message:"daemon storage is prepared and normal services are unavailable until admission",blockerPaths:[]}:(await j(),v={phase:"ready",message:"",blockerPaths:[]})}finally{I=null}return P}catch(r){try{await P()}catch(e){throw new AggregateError([r,e],"daemon startup failed and cleanup also failed")}throw r}}a(Ct,"runDaemon");var co=Ct;export{z as brokerCommandDeclaresCanvasHome,W as brokerCommandEpoch,co as default,Ct as runDaemon,Dt as superviseTick,ht as teardownFleet};
|
|
@@ -61,7 +61,6 @@ export declare function treeHasDescendants(psOutput: string, rootPid: number): b
|
|
|
61
61
|
export declare class BrokerSupervisionReconciler {
|
|
62
62
|
private readonly yieldStalls;
|
|
63
63
|
private readonly wedgeNotifiedAt;
|
|
64
|
-
private readonly fatalFaultNotifiedAt;
|
|
65
64
|
private readonly unattendedSince;
|
|
66
65
|
private readonly sampleTree;
|
|
67
66
|
private readonly signal;
|
|
@@ -93,6 +92,11 @@ export declare class BrokerSupervisionReconciler {
|
|
|
93
92
|
private signalYieldStall;
|
|
94
93
|
private readTreeSample;
|
|
95
94
|
private handleWedgeDetection;
|
|
96
|
-
|
|
95
|
+
/** Publish a fatal provider fault's notice once per episode and, for a node that settles on it, end the node.
|
|
96
|
+
* The notices, the `notified_since` mark and the terminal transition commit in one write, so a daemon exit
|
|
97
|
+
* leaves the fault either fully announced or fully unannounced. The daemon registers this as the announcer
|
|
98
|
+
* every clear of an unannounced fatal fault runs first with `settle` false: a clear ends the fault on purpose
|
|
99
|
+
* (a revive, a completed turn), so it announces but does not end the node. */
|
|
100
|
+
handleFatalFault(id: string, settle?: boolean): void;
|
|
97
101
|
}
|
|
98
102
|
export {};
|