@north-light/cli 0.3.576 → 0.3.578
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/contract.d.ts +1 -1
- package/dist/api/contract.js +1 -1
- package/dist/api/dto/run-events.d.ts +10 -4
- package/dist/builtin-memory/crouter-sdk/release-notes.md +12 -0
- package/dist/builtin-memory/crouter-sdk/streaming.md +2 -0
- package/dist/builtin-memory/northlight-apps/concepts/runs.md +2 -0
- package/dist/builtin-memory/northlight-apps/guides/stream-a-run.md +1 -1
- package/dist/builtin-memory/northlight-apps/guides/test-your-app.md +1 -1
- package/dist/clients/attach/viewer.js +207 -207
- package/dist/core/io.js +4 -4
- package/dist/core/llm/refusal.d.ts +2 -1
- package/dist/core/llm/refusal.js +1 -1
- package/dist/core/llm/run.js +1 -1
- package/dist/core/model-routes.d.ts +11 -0
- package/dist/core/model-routes.js +1 -1
- package/dist/core/peer/envelope.d.ts +2 -0
- package/dist/core/peer/envelope.js +1 -1
- package/dist/core/providers/call.js +1 -1
- package/dist/core/runs/operations.d.ts +1 -1
- package/dist/core/runs/operations.js +5 -5
- package/dist/core/runtime/broker/daemon-ops.d.ts +4 -0
- package/dist/core/runtime/broker/daemon-ops.js +1 -1
- package/dist/core/runtime/broker/held-deferred-inbox.d.ts +4 -0
- package/dist/core/runtime/broker/held-deferred-inbox.js +1 -1
- package/dist/core/runtime/broker/rebind.d.ts +3 -0
- package/dist/core/runtime/broker/rebind.js +1 -1
- package/dist/core/runtime/broker/run-steer.d.ts +15 -0
- package/dist/core/runtime/broker/run-steer.js +1 -0
- 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.js +1 -1
- package/dist/core/runtime/revive.d.ts +6 -0
- package/dist/core/runtime/revive.js +2 -2
- package/dist/core/runtime/run-command.js +1 -1
- package/dist/core/runtime/runner/blaxel/client.d.ts +2 -2
- package/dist/core/runtime/runner/blaxel/client.js +1 -1
- package/dist/core/runtime/runner/blaxel/runner.js +2 -2
- package/dist/core/runtime/spawn.js +2 -2
- package/dist/daemon/api/handlers/messages.js +2 -2
- package/dist/daemon/api/handlers/nodes.js +1 -1
- package/dist/daemon/api/handlers/runs.js +1 -1
- package/dist/daemon/peer/forward.js +1 -1
- package/dist/daemon/runs/append-section.js +2 -2
- package/dist/pi-extensions/canvas-bash-valve.js +6 -6
- package/dist/pi-extensions/canvas-inbox-watcher.js +2 -2
- package/dist/pi-extensions/canvas-stophook.js +1 -1
- package/docs/apps/concepts/runs.md +2 -0
- package/docs/apps/guides/stream-a-run.md +1 -1
- package/docs/apps/guides/test-your-app.md +1 -1
- package/docs/sdk/release-notes.md +12 -0
- package/docs/sdk/streaming.md +2 -0
- package/package.json +2 -2
- package/packages/crouter-identity/package.json +1 -1
- package/runtime.lock.json +162 -665
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var
|
|
2
|
-
`):""}f(fe,"messageText");function H(s){return s==="quit"||s==="reload"||s==="new"||s==="resume"||s==="fork"}f(H,"isSessionShutdownReason");function he(s){switch(s){case"quit":return"shutdown";case"reload":case"new":case"resume":case"fork":return"reload";default:return s}}f(he,"disposalReasonForShutdown");function ue(s){return typeof s=="string"?s.slice(0,128):s===null?"null":s===void 0?"undefined":typeof s=="number"||typeof s=="boolean"||typeof s=="bigint"?String(s).slice(0,128):typeof s}f(ue,"boundedRuntimeReason");class ce{static{f(this,"CanvasInboxWatcher")}pi;cadence;generation;timer;backstop;debounceTimer;signalUnsubscribers=[];rerun=!1;retryNeeded=!1;polledOk=!1;armed=!1;lastCtx;streaming=!1;runNode=q();nodeId;claims=new Map;reportBodies=new Map;tickInFlight;buffer=[];lastArrival=0;pendingHandoffs=[];pendingCommit;promptJoinInFlight=!1;replayUnseenInherited=!1;seeded=!1;disposed=!1;disposalReason;fatalError;fatalEscaped=!1;constructor(t,e,i){this.pi=t,this.cadence=e,this.generation=i}start(){const t=f((e,i)=>{this.canMutate()&&this.captureCtx(e,i)},"capture");this.pi.on("session_start",(e,i)=>{this.canMutate()&&(this.captureCtx(e,i),this.arm())}),this.pi.on("turn_end",t),this.pi.on("agent_start",(e,i)=>{this.canMutate()&&(this.captureCtx(e,i),this.streaming=!0)}),this.pi.on("agent_end",(e,i)=>{this.canMutate()&&(this.captureCtx(e,i),this.streaming=!1)}),this.pi.on("message_end",e=>{if(!this.canMutate())return;const i=e?.message;if(i?.role!=="user"&&i?.role!=="custom"||!this.pendingHandoffs.some(d=>d.awaitingDequeue!==void 0))return;const r=_(fe(i.content)),n=this.pendingHandoffs.find(d=>d.awaitingDequeue===r);n!==void 0&&delete n.awaitingDequeue}),this.pi.on("agent_settled",async(e,i)=>{if(!this.canMutate())return;this.captureCtx(e,i);const r=E();if(r!==void 0)try{this.assertNodeOwnership(r,"settle"),await this.tickInFlight,this.seeded||await this.claimMail(r);const n=await this.settle(r,i,!1,!0);n==="refresh_held"&&this.dispose("refresh",!1),this.runNode&&n==="settled"&&this.canMutate()&&this.buffer.length>0&&await this.flushOrdinary(r),this.syncTimers()}catch(n){this.dispose("shutdown",!1,void 0,{error:n,stage:"settle"})}}),this.pi.on("session_shutdown",async e=>{if(!this.canMutate())return;let i;try{i=e?.reason}catch{i=void 0}const r=H(i)?he(i):"reload";H(i)||w({level:"warn",event:"inbox.lifecycle.unknown_shutdown_reason",outcome:"failed",fields:{reason:ue(i)}});try{await this.disposeAtSettlement(r,this.lastCtx)}catch(n){this.dispose(r,!1,void 0,{error:n,stage:"settle"})}})}arm(){if(this.armed)return;this.armed=!0;const t=S();this.signalUnsubscribers.push(t.subscribe("state",()=>this.syncTimers()),t.subscribe("mail",()=>this.runTick("schedule")),t.subscribe("resync",()=>this.runTick("schedule"))),this.syncTimers(),t.state!=="connected"&&this.runTick("schedule")}async disposeAtSettlement(t,e){const i=E();if(i===void 0){this.dispose(t,!1);return}try{this.assertNodeOwnership(i,"settle");const r=await this.settle(i,e,t!=="refresh");this.dispose(r==="refresh_held"?"refresh":t,!1)}catch(r){this.dispose(t,!1,void 0,{error:r,stage:"settle"})}}dispose(t,e,i,r){if(this.disposed)return;this.disposed=!0,this.disposalReason=t,this.clearTimer();for(const d of this.signalUnsubscribers.splice(0))d();const n=r;{const d=[...new Set([...this.pendingCommit?.handoffs??[],...this.pendingHandoffs.splice(0)])];this.buffer.length=0,this.claims.clear(),this.reportBodies.clear(),this.pendingCommit=void 0,this.promptJoinInFlight=!1,this.replayUnseenInherited=!1,this.nodeId=void 0,this.lastCtx=void 0,this.lastArrival=0,this.streaming=!1,this.seeded=!1,this.ownsCurrentGeneration()&&(p=void 0);for(const a of d)M(a,t)}if(n!==void 0){this.scheduleHandlerFatal(n.error,n.stage);return}}ownsCurrentGeneration(){return p===this&&p.generation===this.generation}canMutate(){return this.ownsCurrentGeneration()&&!this.disposed&&this.fatalError===void 0}captureCtx(t,e){e!==void 0&&(this.lastCtx=e)}clearTimer(){this.timer!==void 0&&clearInterval(this.timer),this.backstop!==void 0&&clearInterval(this.backstop),this.debounceTimer!==void 0&&clearTimeout(this.debounceTimer),this.timer=this.backstop=this.debounceTimer=void 0}syncTimers(){if(!this.armed||!this.canMutate())return;const t=S().state,e=t==="connected",i=t!=="stopped"&&(t!=="connected"||this.buffer.length>0||this.pendingCommit!==void 0||this.retryNeeded);i&&this.timer===void 0?(this.timer=setInterval(()=>this.runTick("schedule"),this.cadence.tickMs),this.timer.unref?.()):!i&&this.timer!==void 0&&(clearInterval(this.timer),this.timer=void 0),e&&this.backstop===void 0?(this.backstop=setInterval(()=>this.runTick("schedule"),G()),this.backstop.unref?.()):!e&&this.backstop!==void 0&&(clearInterval(this.backstop),this.backstop=void 0),this.buffer.length===0&&this.debounceTimer!==void 0&&(clearTimeout(this.debounceTimer),this.debounceTimer=void 0)}armDebounce(){this.debounceTimer!==void 0&&clearTimeout(this.debounceTimer);const t=Math.max(0,this.lastArrival+this.cadence.debounceMs-Date.now());this.debounceTimer=setTimeout(()=>{this.debounceTimer=void 0,this.runTick("schedule")},t),this.debounceTimer.unref?.()}isIdle(){if(this.runNode&&re())return!1;try{if(typeof this.lastCtx?.isIdle=="function")return this.lastCtx.isIdle()===!0}catch{}return!this.streaming}assertNodeOwnership(t,e){!this.seeded||this.nodeId===void 0||this.nodeId===t||this.raiseReadFatal(e,new Error(`watcher node changed from ${this.nodeId} to ${t}`))}raiseFatal(t,e,i,r){throw this.fatalError===void 0&&(this.fatalError=new D(e,i),this.clearTimer(),w({level:"error",event:t,outcome:"failed",error:i,error_class:k(i),fields:r})),this.fatalError}raiseReadFatal(t,e){return this.raiseFatal("inbox.read.failed",`inbox ${t} state is corrupt`,e,{stage:t})}raiseSituationalFatal(t,e){return this.raiseFatal("inbox.situational_context.missing","situational context marker has no readable sidecar",e,{entry_id:t})}escapeFatal(t,e){if(!this.fatalEscaped){if(this.fatalEscaped=!0,e==="throw")throw t;queueMicrotask(()=>{throw t})}}scheduleHandlerFatal(t,e){let i;if(t instanceof D)i=t;else try{this.raiseReadFatal(e,t)}catch(r){i=r}this.escapeFatal(i,"schedule")}runTick(t="throw"){if(!this.canMutate())return;if(this.tickInFlight!==void 0){this.rerun=!0;return}const e=this.tick().then(()=>{this.retryNeeded=!1,this.polledOk=!0}).catch(i=>{if(this.canMutate()){if(R(i)){this.retryNeeded=!0,w({level:"warn",event:"inbox.read.failed",outcome:"failed",error:i,error_class:k(i),fields:{stage:"poll"}});return}if(this.polledOk&&Y(i)){this.clearTimer(),w({level:"info",event:"inbox.poll.token_revoked",outcome:"succeeded",fields:{stage:"poll"}}),N()?.("token-revoked");return}this.scheduleHandlerFatal(i,"poll")}}).finally(()=>{this.tickInFlight===e&&(this.tickInFlight=void 0),this.syncTimers(),this.rerun&&this.canMutate()&&(this.rerun=!1,this.runTick("schedule"))});this.tickInFlight=e}async claimMail(t){this.assertNodeOwnership(t,"poll");let e;try{e=await L(t,"wake",this.reportBodies)}catch(a){throw R(a)&&(this.replayUnseenInherited=!0),a}if(!this.canMutate()||e.action==="hold")return!1;const i=this.replayUnseenInherited;this.replayUnseenInherited=!1,this.nodeId=t,this.seeded=!0;const r=new Set(e.deliveries.map(a=>a.entry.entry_id)),n=this.buffer.filter(a=>!r.has(a.entry_id));for(const a of n)this.claims.delete(a.entry_id);if(this.buffer.splice(0,this.buffer.length,...this.buffer.filter(a=>r.has(a.entry_id))),n.length>0){const a=globalThis[Symbol.for("@crouton-kit/crtr:watcher-cancel-probe")];typeof a=="function"&&a(n.map(l=>l.entry_id),process.hrtime.bigint())}let d=!1;for(const a of e.deliveries){const l=a.entry.entry_id;this.claims.has(l)||(a.entry=V(a.entry),this.claims.set(l,a),a.handoff==="inherited"&&!i?m.fresh(o=>{this.pendingHandoffs.push({...x([a.entry],"visible"),operationId:o,settleAtAgentSettled:!0})}):(this.buffer.push(a.entry),this.lastArrival=Date.now(),d=!0))}return d&&this.armDebounce(),this.syncTimers(),!0}async tick(){const t=E();if(t!==void 0){if(this.pendingCommit!==void 0){await this.retryPendingCommit(t)==="refresh_held"&&this.canMutate()&&this.dispose("refresh",!1);return}this.promptJoinInFlight||P()||this.pendingHandoffs.length>=b||await this.claimMail(t)&&this.buffer.length>0&&(!this.runNode||this.isIdle()||this.buffer.some(e=>e.tier==="critical"))&&Date.now()-this.lastArrival>=this.cadence.debounceMs&&await this.flushOrdinary(t)}}missingChannelEntries(t){const e=t.filter(n=>this.claims.has(n.entry_id)),i=this.coveredEntryIds("hidden"),r=this.coveredEntryIds("visible");return{hiddenEntries:e.filter(n=>(n.data?.situational===!0||n.data?.situationalOnly===!0)&&!i.has(n.entry_id)),visibleEntries:e.filter(n=>n.data?.situationalOnly!==!0&&!r.has(n.entry_id))}}visibleRoute(t){return t.length===0?"none":this.isIdle()?"idle":this.runNode?t.some(e=>e.tier==="critical")?"critical":"none":t.some(e=>e.tier==="critical")?"critical":t.some(e=>e.tier==="urgent"||e.kind==="final")?"steer":"followUp"}buildPlan(t){const{hiddenEntries:e,visibleEntries:i}=this.missingChannelEntries(t),r=new Set(e.map(u=>u.entry_id)),n=new Set(i.map(u=>u.entry_id)),d=t.filter(u=>r.has(u.entry_id)||n.has(u.entry_id)),a=this.isIdle()&&d.length>0&&d.every(u=>u.tier==="deferred"),l=this.visibleRoute(i)==="critical",o=!a&&!l&&e.length>0,c=!a&&!l&&i.length>0;return{hiddenEntries:e,visibleEntries:i,deferredHold:a,sendCount:Number(o)+Number(c)}}ordinaryPlan(){return this.buildPlan(this.buffer)}async contextCards(t,e){const i=[];if(e.some(r=>r.data?.situational===!0)){const r=e.at(-1).entry_id;let n;try{n=(await F(t)).situational_card}catch(d){this.raiseSituationalFatal(r,d)}n===null&&this.raiseSituationalFatal(r,new Error(`missing situational context for entry ${r}`)),i.push(n)}for(const r of e)r.data?.situationalOnly===!0&&i.push(...j(r));return i}digest(t,e){try{return X(t)}catch(i){this.raiseReadFatal(e,i)}}sendDelivery(t,e,i,r,n){this.pendingHandoffs.length>=b&&this.raiseReadFatal(r,new Error(`pending handoff capacity exceeded before ${t} send`));let d;try{d=x(e,t)}catch(o){this.raiseReadFatal(r,o)}let a;try{m.fresh(o=>{a=o,v({level:"info",event:"inbox.delivery.started",operation_id:o,fields:y(d)}),i()})}catch(o){return a===void 0&&this.raiseReadFatal(r,o),T(a,d,"send",o),"failed"}a===void 0&&this.raiseReadFatal(r,new Error(`${t} delivery returned without an operation id`));const l={operationId:a,...d,...n===void 0?{}:{awaitingDequeue:n}};return this.canMutate()?(this.pendingHandoffs.push(l),"handed-off"):(this.disposed&&this.disposalReason!==void 0&&M(l,this.disposalReason),"inactive")}sendContext(t,e,i,r,n,d){const a=r==="steer"||r==="followUp"?r:this.isIdle()?void 0:"followUp",l=a===void 0||i.length===0?void 0:_(i.at(-1));return this.sendDelivery("hidden",e,()=>{this.runNode&&n&&this.pi.appendEntry("crtr-turn-input",{message_ids:e.map(o=>o.entry_id)}),i.forEach((o,c)=>{const u=n&&c===i.length-1;this.pi.sendMessage({customType:I,content:o,display:!0,details:{nodeId:t}},a!==void 0?{deliverAs:a}:u?{deliverAs:"followUp",triggerTurn:!0}:{})})},d,l)}sendVisible(t,e,i,r,n,d){return this.sendDelivery("visible",t,()=>{if(n!=="idle"&&n!=="steer"&&n!=="followUp")throw new Error(`visible send requested for non-send route ${n}`);for(const a of e)this.pi.sendMessage({customType:I,content:a,display:!0},n==="idle"?{}:{deliverAs:n});if(K(i,r),n==="idle"){const a=ne();if(a===void 0)throw new Error("broker idle-turn admission is unavailable");a(i,this.runNode?t.map(l=>l.entry_id):[])}else this.pi.sendUserMessage(i,{deliverAs:n})},d,n==="steer"||n==="followUp"?_(i):void 0)}abortCritical(){try{this.lastCtx?.abort?.()}catch{}}requeueFromBatch(t,e){if(e.size===0)return;const i=t.filter(d=>e.has(d.entry_id)),r=new Set(i.map(d=>d.entry_id)),n=this.buffer.filter(d=>!r.has(d.entry_id));this.buffer.splice(0,this.buffer.length,...i,...n)}async executePlan(t,e,i){const r=new Set,n=this.visibleRoute(e.visibleEntries);if(n==="critical"){if(this.abortCritical(),!this.canMutate())return{inactive:!0,requeueEntryIds:r};for(const o of e.visibleEntries)r.add(o.entry_id);for(const o of e.hiddenEntries)r.add(o.entry_id);return{inactive:!1,requeueEntryIds:r}}if(this.runNode&&n==="none")return{inactive:!1,requeueEntryIds:new Set([...e.hiddenEntries,...e.visibleEntries].map(o=>o.entry_id))};const d=e.visibleEntries.length>0?this.digest(e.visibleEntries,i):[],[a,...l]=d;for(const o of l)for(const c of o.entries)r.add(c.entry_id);if(e.hiddenEntries.length>0){const o=await this.contextCards(t,e.hiddenEntries),c=this.sendContext(t,e.hiddenEntries,o,n,a===void 0,i);if(c==="inactive")return{inactive:!0,requeueEntryIds:r};if(c==="failed")for(const u of e.hiddenEntries)r.add(u.entry_id)}if(!this.canMutate())return{inactive:!0,requeueEntryIds:r};if(a!==void 0){const o=this.sendVisible(a.entries,a.cards,a.text,oe(a),n,i);if(o==="inactive")return{inactive:!0,requeueEntryIds:r};if(o==="failed")for(const c of a.entries)r.add(c.entry_id);else a.kind==="human"&&(await Z(t,a.text).catch(()=>{}),ee(t,a.text))}return{inactive:!1,requeueEntryIds:r}}async flushOrdinary(t){if(this.buffer.length===0)return"empty";const e=this.ordinaryPlan();if(e.deferredHold)return"held";if(this.pendingHandoffs.length+e.sendCount>b)return"capacity-blocked";const i=[...this.buffer],r=await this.executePlan(t,e,"poll");return r.inactive||(this.buffer.splice(0,i.length),this.requeueFromBatch(i,r.requeueEntryIds)),"attempted"}async prependHeldDeferredInbox(t){if(!this.canMutate()||this.nodeId===void 0||P())return;const e=this.ordinaryPlan();if(!e.deferredHold)return;const i=e.visibleEntries.length===0?[]:this.digest(e.visibleEntries,"poll"),r=+(e.hiddenEntries.length>0)+i.length;if(this.pendingHandoffs.length+r>b)return;const n=[...this.buffer];this.promptJoinInFlight=!0;try{this.runNode&&this.pi.appendEntry("crtr-turn-input",{message_ids:[...e.hiddenEntries,...e.visibleEntries].map(d=>d.entry_id)}),e.hiddenEntries.length>0&&await this.sendPromptJoinDelivery(t,"hidden",e.hiddenEntries,await this.contextCards(this.nodeId,e.hiddenEntries));for(const d of i)await this.sendPromptJoinDelivery(t,"visible",d.entries,[...d.cards,d.text]);if(!this.canMutate())return;this.buffer.splice(0,n.length)}finally{this.promptJoinInFlight=!1}}async sendPromptJoinDelivery(t,e,i,r){let n;try{n=x(i,e)}catch(l){this.raiseReadFatal("poll",l)}let d;try{await m.fresh(async l=>{d=l,v({level:"info",event:"inbox.delivery.started",operation_id:l,fields:y(n)});for(const o of r)await t.sendCustomMessage({customType:I,content:o,display:!0})})}catch(l){throw d===void 0&&this.raiseReadFatal("poll",l),T(d,n,"send",l),l}d===void 0&&this.raiseReadFatal("poll",new Error(`${e} prompt-join delivery returned without an operation id`));const a={operationId:d,...n,settleAtAgentSettled:!0};if(!this.canMutate()){this.disposed&&this.disposalReason!==void 0&&M(a,this.disposalReason);return}this.pendingHandoffs.push(a)}coveredEntryIds(t){const e=new Set;for(const i of this.pendingHandoffs)if(i.channel===t)for(const r of i.entryIds)e.add(r);return e}retryPendingCommit(t){const e=this.pendingCommit;if(e===void 0)return Promise.resolve("settled");if(e.attempt!==void 0)return e.attempt;const i=this.attemptPendingCommit(t,e).finally(()=>{e.attempt===i&&(e.attempt=void 0)});return e.attempt=i,i}async attemptPendingCommit(t,e){let i=!1;try{const n=await z(t,e.receipts);if(n.action==="hold")return"refresh_held";for(const d of e.receipts){const a=n.results.find(l=>l.delivery_id===d.delivery_id);if(a?.outcome!==d.disposition&&a?.outcome!=="stale")throw new Error("daemon returned no terminal mail settlement outcome")}i=n.results.every(d=>d.outcome==="acknowledged")}catch(n){if(this.pendingCommit===e)for(const d of e.handoffs)T(d.operationId,d,"receipt_commit",n);return String(n?.message).startsWith("conversation_write_failed")&&(O({level:"error",event:"broker.exited",node_id:t,error:n,fields:{fault:"conversation_write_failed"}}),N()?.("conversation_write_failed",1)),"held"}if(this.pendingCommit!==e)return"settled";for(const n of e.entryIds)this.claims.delete(n);if(e.receipts.some(n=>n.disposition==="released")){const n=new Set(e.entryIds);this.buffer.splice(0,this.buffer.length,...this.buffer.filter(d=>!n.has(d.entry_id)))}this.pendingCommit=void 0;const r=this.detachPending(n=>n.entryIds.every(d=>!this.claims.has(d)));for(const n of r)i&&le(n);return"settled"}async settle(t,e,i,r=!1){if(i)try{if(e?.hasPendingMessages?.()===!0)return"held"}catch{}if(this.pendingCommit!==void 0)return this.retryPendingCommit(t);const n=Q(),d=!n&&this.pendingHandoffs.some(h=>h.awaitingDequeue!==void 0)&&await this.nodeRefreshing(t);if(this.pendingCommit!==void 0)return this.retryPendingCommit(t);const a=new Set(this.buffer.map(h=>h.entry_id)),l=new Set(d?this.pendingHandoffs.filter(h=>h.awaitingDequeue!==void 0).flatMap(h=>[...h.entryIds]):[]),o=this.pendingHandoffs.filter(h=>(r||h.settleAtAgentSettled!==!0)&&h.entryIds.every(g=>!l.has(g))),c=new Set(o.flatMap(h=>[...h.entryIds])),u=[...this.claims.keys()].filter(h=>n||c.has(h)&&!a.has(h));return u.length===0?"settled":(this.pendingCommit={handoffs:o,entryIds:u,receipts:u.map(h=>{const g=this.claims.get(h);return{delivery_id:g.delivery_id,attempts:g.attempts,disposition:n?"released":"acknowledged"}})},this.retryPendingCommit(t))}async nodeRefreshing(t){try{return(await F(t)).node.intent==="refresh"}catch{return!0}}detachPending(t){const e=[];for(let i=this.pendingHandoffs.length-1;i>=0;i-=1){const r=this.pendingHandoffs[i];t(r)&&e.push(...this.pendingHandoffs.splice(i,1))}return e.reverse(),e}}function me(s,t){p?.dispose("reload",!1);const e=new ce(s,t,++ae);p=e;const i=f(r=>e.prependHeldDeferredInbox(r),"promptJoin");globalThis[se]=i;try{e.start()}catch(r){throw e.dispose("reload",!1),r}return e}f(me,"installWatcher");function pe(s){const t=me(s,de());return()=>t.dispose("shutdown",!1)}f(pe,"registerCanvasInboxWatcher");var Oe=pe;export{Oe as default,pe as registerCanvasInboxWatcher};
|
|
1
|
+
var J=Object.defineProperty;var l=(r,t)=>J(r,"name",{value:t,configurable:!0});import{envInboxBetweenTurns as $,envNodeId as G,envProfileId as X,envWatcherDebounceMs as j,envWatcherTickMs as z,envWatcherBackstopMs as L}from"../shared/env.js";import{coalesceBrokerInbox as V,entryCards as Q}from"../core/runtime/broker/inbox.js";import{acknowledgeBrokerMail as Y,claimBrokerMail as K,brokerExtensionState as O,recordConversationWriteFault as Z}from"../core/runtime/broker/daemon-ops.js";import{materializeSpilledBody as ee}from"../core/runtime/broker/spilled-body.js";import{brokerSignalClient as P}from"../core/runtime/broker/signal-stream.js";import{wasTurnRefused as te}from"../core/runtime/broker/extension-abort.js";import{isDaemonTransportApiError as A,isTokenRevokedApiError as ie}from"../api/errors.js";import{announceMessageOrigin as ne,messageSignature as C}from"../core/runtime/stamp/channel.js";import{captureGoalIfAbsent as se,generateAndCommitInitialName as re}from"./broker-local.js";import{emitEvent as D}from"../core/events/emit.js";import{errorClassFromError as ae}from"../core/events/errors.js";import{operationIdContext as g}from"../core/events/operation-id.js";import{SITUATIONAL_CONTEXT_CUSTOM_TYPE as x}from"../shared/generated-context.js";import{isProfilePaused as de}from"../core/profiles/manifest.js";import{brokerDisposeAndExit as H,brokerIdleTurnStart as oe,brokerRunTurnBusy as fe,brokerRunSteer as _,HELD_DEFERRED_INBOX_PROMPT_JOIN as le}from"../core/runtime/broker/held-deferred-inbox.js";const E=64,U=16;let v,he=0;class q extends Error{static{l(this,"WatcherFatalError")}constructor(t,e){super(t,{cause:e}),this.name="WatcherFatalError"}}function ue(){return{tickMs:z(),debounceMs:j()}}l(ue,"resolveCadence");function T(){const r=G();return r===void 0||r.trim()===""?void 0:r}l(T,"currentNodeId");function B(){const r=X();return r!==void 0&&r!==""&&de(r)}l(B,"profilePaused");function M(r){try{return ae(r)}catch{return{class:"unknown"}}}l(M,"safeErrorClass");function w(r){try{D(r)}catch{}}l(w,"emitBestEffort");function I(r){try{g.fresh(t=>{w({...r,operation_id:t})})}catch{}}l(I,"emitFreshBestEffort");function S(r,t){try{g.run(r,()=>{w({...t,operation_id:r})})}catch{}}l(S,"emitStoredBestEffort");function ce(r){return r.kind==="human"?{type:"human"}:{type:"runtime",kind:"inbox",entries:r.entries.map(t=>({...t.from===null?{}:{from:t.from},...t.from_name===void 0?{}:{fromName:t.from_name},kind:t.kind,tier:t.tier,...t.ref===void 0?{}:{ref:t.ref}}))}}l(ce,"deliveryOrigin");function k(r,t){if(r.length===0)throw new Error(`cannot create an empty ${t} delivery`);const e=[...new Set(r.map(n=>n.operation_id))].sort(),i=e.length-U;return{channel:t,entryIds:r.map(n=>n.entry_id),throughEntryId:r.at(-1).entry_id,sourceOperationIds:e.slice(0,U),...i>0?{sourceOperationIdsOmitted:i}:{}}}l(k,"deliveryFacts");function b(r){return{channel:r.channel,entry_ids:r.entryIds,through_entry_id:r.throughEntryId,source_operation_ids:r.sourceOperationIds,...r.sourceOperationIdsOmitted===void 0?{}:{source_operation_ids_omitted:r.sourceOperationIdsOmitted}}}l(b,"deliveryFields");function me(r){S(r.operationId,{level:"info",event:"inbox.delivery.completed",outcome:"succeeded",fields:b(r)})}l(me,"emitDeliveryCompleted");function F(r,t,e,i){S(r,{level:"error",event:"inbox.delivery.failed",outcome:"failed",error:i,error_class:M(i),fields:{stage:e,...b(t)}})}l(F,"emitDeliveryFailure");function R(r,t){S(r.operationId,{level:"error",event:"inbox.delivery.failed",outcome:"failed",error_class:{class:"unknown"},fields:{stage:"abandoned",reason:t,...b(r)}})}l(R,"emitDeliveryAbandoned");function pe(r){return typeof r=="string"?r:Array.isArray(r)?r.filter(t=>typeof t=="object"&&t!==null&&typeof t.text=="string").map(t=>t.text).join(`
|
|
2
|
+
`):""}l(pe,"messageText");function W(r){return r==="quit"||r==="reload"||r==="new"||r==="resume"||r==="fork"}l(W,"isSessionShutdownReason");function ye(r){switch(r){case"quit":return"shutdown";case"reload":case"new":case"resume":case"fork":return"reload";default:return r}}l(ye,"disposalReasonForShutdown");function ge(r){return typeof r=="string"?r.slice(0,128):r===null?"null":r===void 0?"undefined":typeof r=="number"||typeof r=="boolean"||typeof r=="bigint"?String(r).slice(0,128):typeof r}l(ge,"boundedRuntimeReason");class be{static{l(this,"CanvasInboxWatcher")}pi;cadence;generation;timer;backstop;debounceTimer;signalUnsubscribers=[];rerun=!1;retryNeeded=!1;polledOk=!1;armed=!1;lastCtx;streaming=!1;runNode=$();nodeId;claims=new Map;reportBodies=new Map;tickInFlight;buffer=[];lastArrival=0;pendingHandoffs=[];pendingCommit;promptJoinInFlight=!1;replayUnseenInherited=!1;seeded=!1;disposed=!1;disposalReason;fatalError;fatalEscaped=!1;constructor(t,e,i){this.pi=t,this.cadence=e,this.generation=i}start(){const t=l((e,i)=>{this.canMutate()&&this.captureCtx(e,i)},"capture");this.pi.on("session_start",(e,i)=>{this.canMutate()&&(this.captureCtx(e,i),this.arm())}),this.pi.on("turn_end",t),this.pi.on("agent_start",(e,i)=>{this.canMutate()&&(this.captureCtx(e,i),this.streaming=!0)}),this.pi.on("agent_end",(e,i)=>{this.canMutate()&&(this.captureCtx(e,i),this.streaming=!1)}),this.pi.on("message_end",e=>{if(!this.canMutate())return;const i=e?.message;if(i?.role!=="user"&&i?.role!=="custom"||!this.pendingHandoffs.some(d=>d.awaitingDequeue!==void 0))return;const n=C(pe(i.content)),s=this.pendingHandoffs.find(d=>d.awaitingDequeue===n);s!==void 0&&delete s.awaitingDequeue}),this.pi.on("agent_settled",async(e,i)=>{if(!this.canMutate())return;this.captureCtx(e,i);const n=T();if(n!==void 0)try{this.assertNodeOwnership(n,"settle"),await this.tickInFlight,this.seeded||await this.claimMail(n),this.returnUnconsumedSteers();const s=await this.settle(n,i,!1,!0);s==="refresh_held"&&this.dispose("refresh",!1),this.runNode&&s==="settled"&&this.canMutate()&&this.buffer.length>0&&await this.flushOrdinary(n),this.syncTimers()}catch(s){this.dispose("shutdown",!1,void 0,{error:s,stage:"settle"})}}),this.pi.on("session_shutdown",async e=>{if(!this.canMutate())return;let i;try{i=e?.reason}catch{i=void 0}const n=W(i)?ye(i):"reload";W(i)||I({level:"warn",event:"inbox.lifecycle.unknown_shutdown_reason",outcome:"failed",fields:{reason:ge(i)}});try{await this.disposeAtSettlement(n,this.lastCtx)}catch(s){this.dispose(n,!1,void 0,{error:s,stage:"settle"})}})}arm(){if(this.armed)return;this.armed=!0;const t=P();this.signalUnsubscribers.push(t.subscribe("state",()=>this.syncTimers()),t.subscribe("mail",()=>this.runTick("schedule")),t.subscribe("resync",()=>this.runTick("schedule"))),this.syncTimers(),t.state!=="connected"&&this.runTick("schedule")}async disposeAtSettlement(t,e){const i=T();if(i===void 0){this.dispose(t,!1);return}try{this.assertNodeOwnership(i,"settle"),this.returnUnconsumedSteers();const n=await this.settle(i,e,t!=="refresh");this.dispose(n==="refresh_held"?"refresh":t,!1)}catch(n){this.dispose(t,!1,void 0,{error:n,stage:"settle"})}}dispose(t,e,i,n){if(this.disposed)return;this.disposed=!0,this.disposalReason=t,this.clearTimer();for(const d of this.signalUnsubscribers.splice(0))d();const s=n;{const d=[...new Set([...this.pendingCommit?.handoffs??[],...this.pendingHandoffs.splice(0)])];this.buffer.length=0,this.claims.clear(),this.reportBodies.clear(),this.pendingCommit=void 0,this.promptJoinInFlight=!1,this.replayUnseenInherited=!1,this.nodeId=void 0,this.lastCtx=void 0,this.lastArrival=0,this.streaming=!1,this.seeded=!1,this.ownsCurrentGeneration()&&(v=void 0);for(const a of d)R(a,t)}if(s!==void 0){this.scheduleHandlerFatal(s.error,s.stage);return}}ownsCurrentGeneration(){return v===this&&v.generation===this.generation}canMutate(){return this.ownsCurrentGeneration()&&!this.disposed&&this.fatalError===void 0}captureCtx(t,e){e!==void 0&&(this.lastCtx=e)}clearTimer(){this.timer!==void 0&&clearInterval(this.timer),this.backstop!==void 0&&clearInterval(this.backstop),this.debounceTimer!==void 0&&clearTimeout(this.debounceTimer),this.timer=this.backstop=this.debounceTimer=void 0}syncTimers(){if(!this.armed||!this.canMutate())return;const t=P().state,e=t==="connected",i=t!=="stopped"&&(t!=="connected"||this.buffer.length>0||this.pendingCommit!==void 0||this.retryNeeded);i&&this.timer===void 0?(this.timer=setInterval(()=>this.runTick("schedule"),this.cadence.tickMs),this.timer.unref?.()):!i&&this.timer!==void 0&&(clearInterval(this.timer),this.timer=void 0),e&&this.backstop===void 0?(this.backstop=setInterval(()=>this.runTick("schedule"),L()),this.backstop.unref?.()):!e&&this.backstop!==void 0&&(clearInterval(this.backstop),this.backstop=void 0),this.buffer.length===0&&this.debounceTimer!==void 0&&(clearTimeout(this.debounceTimer),this.debounceTimer=void 0)}armDebounce(){this.debounceTimer!==void 0&&clearTimeout(this.debounceTimer);const t=Math.max(0,this.lastArrival+this.cadence.debounceMs-Date.now());this.debounceTimer=setTimeout(()=>{this.debounceTimer=void 0,this.runTick("schedule")},t),this.debounceTimer.unref?.()}isIdle(){if(this.runNode&&fe())return!1;try{if(typeof this.lastCtx?.isIdle=="function")return this.lastCtx.isIdle()===!0}catch{}return!this.streaming}assertNodeOwnership(t,e){!this.seeded||this.nodeId===void 0||this.nodeId===t||this.raiseReadFatal(e,new Error(`watcher node changed from ${this.nodeId} to ${t}`))}raiseFatal(t,e,i,n){throw this.fatalError===void 0&&(this.fatalError=new q(e,i),this.clearTimer(),I({level:"error",event:t,outcome:"failed",error:i,error_class:M(i),fields:n})),this.fatalError}raiseReadFatal(t,e){return this.raiseFatal("inbox.read.failed",`inbox ${t} state is corrupt`,e,{stage:t})}raiseSituationalFatal(t,e){return this.raiseFatal("inbox.situational_context.missing","situational context marker has no readable sidecar",e,{entry_id:t})}escapeFatal(t,e){if(!this.fatalEscaped){if(this.fatalEscaped=!0,e==="throw")throw t;queueMicrotask(()=>{throw t})}}scheduleHandlerFatal(t,e){let i;if(t instanceof q)i=t;else try{this.raiseReadFatal(e,t)}catch(n){i=n}this.escapeFatal(i,"schedule")}runTick(t="throw"){if(!this.canMutate())return;if(this.tickInFlight!==void 0){this.rerun=!0;return}const e=this.tick().then(()=>{this.retryNeeded=!1,this.polledOk=!0}).catch(i=>{if(this.canMutate()){if(A(i)){this.retryNeeded=!0,I({level:"warn",event:"inbox.read.failed",outcome:"failed",error:i,error_class:M(i),fields:{stage:"poll"}});return}if(this.polledOk&&ie(i)){this.clearTimer(),I({level:"info",event:"inbox.poll.token_revoked",outcome:"succeeded",fields:{stage:"poll"}}),H()?.("token-revoked");return}this.scheduleHandlerFatal(i,"poll")}}).finally(()=>{this.tickInFlight===e&&(this.tickInFlight=void 0),this.syncTimers(),this.rerun&&this.canMutate()&&(this.rerun=!1,this.runTick("schedule"))});this.tickInFlight=e}async claimMail(t){this.assertNodeOwnership(t,"poll");let e;try{e=await K(t,"wake",this.reportBodies)}catch(a){throw A(a)&&(this.replayUnseenInherited=!0),a}if(!this.canMutate()||e.action==="hold")return!1;const i=this.replayUnseenInherited;this.replayUnseenInherited=!1,this.nodeId=t,this.seeded=!0;const n=new Set(e.deliveries.map(a=>a.entry.entry_id)),s=this.buffer.filter(a=>!n.has(a.entry_id));for(const a of s)this.claims.delete(a.entry_id);if(this.buffer.splice(0,this.buffer.length,...this.buffer.filter(a=>n.has(a.entry_id))),s.length>0){const a=globalThis[Symbol.for("@crouton-kit/crtr:watcher-cancel-probe")];typeof a=="function"&&a(s.map(f=>f.entry_id),process.hrtime.bigint())}let d=!1;for(const a of e.deliveries){const f=a.entry.entry_id;this.claims.has(f)||(a.entry=ee(a.entry),this.claims.set(f,a),a.handoff==="inherited"&&!i?g.fresh(o=>{this.pendingHandoffs.push({...k([a.entry],"visible"),operationId:o,settleAtAgentSettled:!0})}):(this.buffer.push(a.entry),this.lastArrival=Date.now(),d=!0))}return d&&this.armDebounce(),this.syncTimers(),!0}async tick(){const t=T();if(t!==void 0){if(this.pendingCommit!==void 0){await this.retryPendingCommit(t)==="refresh_held"&&this.canMutate()&&this.dispose("refresh",!1);return}this.promptJoinInFlight||B()||this.pendingHandoffs.length>=E||await this.claimMail(t)&&this.buffer.length>0&&(!this.runNode||this.isIdle()||this.buffer.some(e=>e.tier==="critical")||this.buffer.some(e=>this.isRunSteer(e))&&_()?.steerable())&&Date.now()-this.lastArrival>=this.cadence.debounceMs&&await this.flushOrdinary(t)}}missingChannelEntries(t){const e=t.filter(s=>this.claims.has(s.entry_id)),i=this.coveredEntryIds("hidden"),n=this.coveredEntryIds("visible");return{hiddenEntries:e.filter(s=>(s.data?.situational===!0||s.data?.situationalOnly===!0)&&!i.has(s.entry_id)),visibleEntries:e.filter(s=>s.data?.situationalOnly!==!0&&!n.has(s.entry_id))}}isRunSteer(t){return this.runNode&&t.kind==="message"&&(t.from??"system")==="human"&&t.data?.steer===!0}returnUnconsumedSteers(){const t=_()?.takeUnconsumed()??[];if(t.length===0)return;const e=new Set(t.flatMap(n=>n.messageIds));this.detachPending(n=>n.settlesThroughBridge===!0&&n.entryIds.every(s=>e.has(s)));const i=[...e].map(n=>this.claims.get(n)?.entry).filter(n=>n!==void 0);this.requeueFromBatch(i,e)}visibleRoute(t){return t.length===0?"none":this.isIdle()?"idle":this.runNode?t.some(e=>e.tier==="critical")?"critical":t.some(e=>this.isRunSteer(e))&&_()?.steerable()?"steer":"none":t.some(e=>e.tier==="critical")?"critical":t.some(e=>e.tier==="urgent"||e.kind==="final")?"steer":"followUp"}buildPlan(t){const{hiddenEntries:e,visibleEntries:i}=this.missingChannelEntries(t),n=new Set(e.map(u=>u.entry_id)),s=new Set(i.map(u=>u.entry_id)),d=t.filter(u=>n.has(u.entry_id)||s.has(u.entry_id)),a=this.isIdle()&&d.length>0&&d.every(u=>u.tier==="deferred"),f=this.visibleRoute(i)==="critical",o=!a&&!f&&e.length>0,m=!a&&!f&&i.length>0;return{hiddenEntries:e,visibleEntries:i,deferredHold:a,sendCount:Number(o)+Number(m)}}ordinaryPlan(){return this.buildPlan(this.buffer)}async contextCards(t,e){const i=[];if(e.some(n=>n.data?.situational===!0)){const n=e.at(-1).entry_id;let s;try{s=(await O(t)).situational_card}catch(d){this.raiseSituationalFatal(n,d)}s===null&&this.raiseSituationalFatal(n,new Error(`missing situational context for entry ${n}`)),i.push(s)}for(const n of e)n.data?.situationalOnly===!0&&i.push(...Q(n));return i}digest(t,e){try{return V(t)}catch(i){this.raiseReadFatal(e,i)}}sendDelivery(t,e,i,n,s){this.pendingHandoffs.length>=E&&this.raiseReadFatal(n,new Error(`pending handoff capacity exceeded before ${t} send`));let d;try{d=k(e,t)}catch(o){this.raiseReadFatal(n,o)}let a;try{g.fresh(o=>{a=o,w({level:"info",event:"inbox.delivery.started",operation_id:o,fields:b(d)}),i()})}catch(o){return a===void 0&&this.raiseReadFatal(n,o),F(a,d,"send",o),"failed"}a===void 0&&this.raiseReadFatal(n,new Error(`${t} delivery returned without an operation id`));const f={operationId:a,...d,...s===void 0?{}:{awaitingDequeue:s}};return this.canMutate()?(this.pendingHandoffs.push(f),"handed-off"):(this.disposed&&this.disposalReason!==void 0&&R(f,this.disposalReason),"inactive")}sendContext(t,e,i,n,s,d){const a=n==="steer"||n==="followUp"?n:this.isIdle()?void 0:"followUp",f=a===void 0||i.length===0?void 0:C(i.at(-1));return this.sendDelivery("hidden",e,()=>{this.runNode&&s&&this.pi.appendEntry("crtr-turn-input",{message_ids:e.map(o=>o.entry_id)}),i.forEach((o,m)=>{const u=s&&m===i.length-1;this.pi.sendMessage({customType:x,content:o,display:!0,details:{nodeId:t}},a!==void 0?{deliverAs:a}:u?{deliverAs:"followUp",triggerTurn:!0}:{})})},d,f)}sendVisible(t,e,i,n,s,d){return this.sendDelivery("visible",t,()=>{if(s!=="idle"&&s!=="steer"&&s!=="followUp")throw new Error(`visible send requested for non-send route ${s}`);for(const a of e)this.pi.sendMessage({customType:x,content:a,display:!0},s==="idle"?{}:{deliverAs:s});if(ne(i,n),s==="idle"){const a=oe();if(a===void 0)throw new Error("broker idle-turn admission is unavailable");a(i,this.runNode?t.map(f=>f.entry_id):[])}else this.pi.sendUserMessage(i,{deliverAs:s})},d,s==="steer"||s==="followUp"?C(i):void 0)}abortCritical(){try{this.lastCtx?.abort?.()}catch{}}requeueFromBatch(t,e){if(e.size===0)return;const i=t.filter(d=>e.has(d.entry_id)),n=new Set(i.map(d=>d.entry_id)),s=this.buffer.filter(d=>!n.has(d.entry_id));this.buffer.splice(0,this.buffer.length,...i,...s)}async executePlan(t,e,i){const n=new Set,s=this.visibleRoute(e.visibleEntries);if(s==="critical"){if(this.abortCritical(),!this.canMutate())return{inactive:!0,requeueEntryIds:n};for(const o of e.visibleEntries)n.add(o.entry_id);for(const o of e.hiddenEntries)n.add(o.entry_id);return{inactive:!1,requeueEntryIds:n}}if(this.runNode&&s==="none")return{inactive:!1,requeueEntryIds:new Set([...e.hiddenEntries,...e.visibleEntries].map(o=>o.entry_id))};if(this.runNode&&s==="steer"){let o=-1;e.visibleEntries.forEach((h,y)=>{this.isRunSteer(h)&&(o=y)});const m=e.visibleEntries.slice(0,o+1);if(e.hiddenEntries.length>0||m.some(h=>h.kind!=="message"||h.tier==="deferred"||(h.from??"system")!=="human"))return{inactive:!1,requeueEntryIds:new Set([...e.hiddenEntries,...e.visibleEntries].map(h=>h.entry_id))};const u=this.digest(m,i),c=u.map(h=>({text:h.text,messageIds:h.entries.map(y=>y.entry_id),cards:h.cards}));if(_()?.accept(c)!=="accepted")return{inactive:!1,requeueEntryIds:new Set([...e.hiddenEntries,...e.visibleEntries].map(h=>h.entry_id))};for(const h of u){const y=k(h.entries,"visible");g.fresh(N=>{w({level:"info",event:"inbox.delivery.started",operation_id:N,fields:b(y)}),this.pendingHandoffs.push({...y,operationId:N,settlesThroughBridge:!0})})}const p=new Set(m.map(h=>h.entry_id));for(const h of e.visibleEntries)p.has(h.entry_id)||n.add(h.entry_id);for(const h of e.hiddenEntries)n.add(h.entry_id);return{inactive:!1,requeueEntryIds:n}}const d=e.visibleEntries.length>0?this.digest(e.visibleEntries,i):[],[a,...f]=d;for(const o of f)for(const m of o.entries)n.add(m.entry_id);if(e.hiddenEntries.length>0){const o=await this.contextCards(t,e.hiddenEntries),m=this.sendContext(t,e.hiddenEntries,o,s,a===void 0,i);if(m==="inactive")return{inactive:!0,requeueEntryIds:n};if(m==="failed")for(const u of e.hiddenEntries)n.add(u.entry_id)}if(!this.canMutate())return{inactive:!0,requeueEntryIds:n};if(a!==void 0){const o=this.sendVisible(a.entries,a.cards,a.text,ce(a),s,i);if(o==="inactive")return{inactive:!0,requeueEntryIds:n};if(o==="failed")for(const m of a.entries)n.add(m.entry_id);else a.kind==="human"&&(await se(t,a.text).catch(()=>{}),re(t,a.text))}return{inactive:!1,requeueEntryIds:n}}async flushOrdinary(t){if(this.buffer.length===0)return"empty";const e=this.ordinaryPlan();if(e.deferredHold)return"held";if(this.pendingHandoffs.length+e.sendCount>E)return"capacity-blocked";const i=[...this.buffer],n=await this.executePlan(t,e,"poll");return n.inactive||(this.buffer.splice(0,i.length),this.requeueFromBatch(i,n.requeueEntryIds)),"attempted"}async prependHeldDeferredInbox(t){if(!this.canMutate()||this.nodeId===void 0||B())return;const e=this.ordinaryPlan();if(!e.deferredHold)return;const i=e.visibleEntries.length===0?[]:this.digest(e.visibleEntries,"poll"),n=+(e.hiddenEntries.length>0)+i.length;if(this.pendingHandoffs.length+n>E)return;const s=[...this.buffer];this.promptJoinInFlight=!0;try{this.runNode&&this.pi.appendEntry("crtr-turn-input",{message_ids:[...e.hiddenEntries,...e.visibleEntries].map(d=>d.entry_id)}),e.hiddenEntries.length>0&&await this.sendPromptJoinDelivery(t,"hidden",e.hiddenEntries,await this.contextCards(this.nodeId,e.hiddenEntries));for(const d of i)await this.sendPromptJoinDelivery(t,"visible",d.entries,[...d.cards,d.text]);if(!this.canMutate())return;this.buffer.splice(0,s.length)}finally{this.promptJoinInFlight=!1}}async sendPromptJoinDelivery(t,e,i,n){let s;try{s=k(i,e)}catch(f){this.raiseReadFatal("poll",f)}let d;try{await g.fresh(async f=>{d=f,w({level:"info",event:"inbox.delivery.started",operation_id:f,fields:b(s)});for(const o of n)await t.sendCustomMessage({customType:x,content:o,display:!0})})}catch(f){throw d===void 0&&this.raiseReadFatal("poll",f),F(d,s,"send",f),f}d===void 0&&this.raiseReadFatal("poll",new Error(`${e} prompt-join delivery returned without an operation id`));const a={operationId:d,...s,settleAtAgentSettled:!0};if(!this.canMutate()){this.disposed&&this.disposalReason!==void 0&&R(a,this.disposalReason);return}this.pendingHandoffs.push(a)}coveredEntryIds(t){const e=new Set;for(const i of this.pendingHandoffs)if(i.channel===t)for(const n of i.entryIds)e.add(n);return e}retryPendingCommit(t){const e=this.pendingCommit;if(e===void 0)return Promise.resolve("settled");if(e.attempt!==void 0)return e.attempt;const i=this.attemptPendingCommit(t,e).finally(()=>{e.attempt===i&&(e.attempt=void 0)});return e.attempt=i,i}async attemptPendingCommit(t,e){let i=!1;try{const s=await Y(t,e.receipts);if(s.action==="hold")return"refresh_held";for(const d of e.receipts){const a=s.results.find(f=>f.delivery_id===d.delivery_id);if(a?.outcome!==d.disposition&&a?.outcome!=="stale")throw new Error("daemon returned no terminal mail settlement outcome")}i=s.results.every(d=>d.outcome==="acknowledged")}catch(s){if(this.pendingCommit===e)for(const d of e.handoffs)F(d.operationId,d,"receipt_commit",s);return String(s?.message).startsWith("conversation_write_failed")&&(D({level:"error",event:"broker.exited",node_id:t,error:s,fields:{fault:"conversation_write_failed"}}),await Z(t,s),H()?.("conversation_write_failed",1)),"held"}if(this.pendingCommit!==e)return"settled";for(const s of e.entryIds)this.claims.delete(s);if(e.receipts.some(s=>s.disposition==="released")){const s=new Set(e.entryIds);this.buffer.splice(0,this.buffer.length,...this.buffer.filter(d=>!s.has(d.entry_id)))}this.pendingCommit=void 0;const n=this.detachPending(s=>s.entryIds.every(d=>!this.claims.has(d)));for(const s of n)i&&me(s);return"settled"}async settle(t,e,i,n=!1){if(i)try{if(e?.hasPendingMessages?.()===!0)return"held"}catch{}if(this.pendingCommit!==void 0)return this.retryPendingCommit(t);const s=te(),d=!s&&this.pendingHandoffs.some(c=>c.awaitingDequeue!==void 0)&&await this.nodeRefreshing(t);if(this.pendingCommit!==void 0)return this.retryPendingCommit(t);const a=new Set(this.buffer.map(c=>c.entry_id)),f=new Set(d?this.pendingHandoffs.filter(c=>c.awaitingDequeue!==void 0).flatMap(c=>[...c.entryIds]):[]),o=this.pendingHandoffs.filter(c=>(n||c.settleAtAgentSettled!==!0)&&c.entryIds.every(p=>!f.has(p))),m=new Set(o.flatMap(c=>[...c.entryIds])),u=[...this.claims.keys()].filter(c=>s||m.has(c)&&!a.has(c));return u.length===0?"settled":(this.pendingCommit={handoffs:o,entryIds:u,receipts:u.map(c=>{const p=this.claims.get(c);return{delivery_id:p.delivery_id,attempts:p.attempts,disposition:s?"released":"acknowledged"}})},this.retryPendingCommit(t))}async nodeRefreshing(t){try{return(await O(t)).node.intent==="refresh"}catch{return!0}}detachPending(t){const e=[];for(let i=this.pendingHandoffs.length-1;i>=0;i-=1){const n=this.pendingHandoffs[i];t(n)&&e.push(...this.pendingHandoffs.splice(i,1))}return e.reverse(),e}}function ve(r,t){v?.dispose("reload",!1);const e=new be(r,t,++he);v=e;const i=l(n=>e.prependHeldDeferredInbox(n),"promptJoin");globalThis[le]=i;try{e.start()}catch(n){throw e.dispose("reload",!1),n}return e}l(ve,"installWatcher");function we(r){const t=ve(r,ue());return()=>t.dispose("shutdown",!1)}l(we,"registerCanvasInboxWatcher");var He=we;export{He as default,we as registerCanvasInboxWatcher};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var
|
|
1
|
+
var J=Object.defineProperty;var l=(n,t)=>J(n,"name",{value:t,configurable:!0});import{brokerSignalClient as A}from"../core/runtime/broker/signal-stream.js";import{brokerExecutionId as K}from"../core/runtime/broker/daemon-ops.js";import{envNodeId as Z}from"../shared/env.js";import{stripCdPrefix as ee}from"../shared/strip-cd-prefix.js";import{brokerRecovery as te,mutateBrokerFault as j,recordBrokerTelemetry as ne,recordBrokerTurn as x,clearBrokerPushedFinal as re,consumeBrokerPushedFinal as oe}from"../core/runtime/broker/daemon-ops.js";import{bindBrokerSession as se,cachedBrokerNode as L,postBrokerIdle as ae,relaunchBrokerRoot as ie,settleBroker as Y}from"../core/runtime/broker/daemon-ops.js";import{emitEvent as F}from"../core/events/emit.js";import{CONTEXT_NUDGE_CUSTOM_TYPE as le,formatCard as ue}from"../shared/generated-context.js";import{isReviewBoundary as ce}from"../core/runtime/session-visibility.js";import{clearRefusedTurn as de,isRuntimeTeardownInProgress as fe,refuseTurn as he,runRefreshAbort as ye}from"../core/runtime/broker/extension-abort.js";import{announceMessageOrigin as z}from"../core/runtime/stamp/channel.js";const G=80;function pe(n,t){const i=t??{},s=l(w=>typeof w=="string"?w:"","pick"),h=ee(s(i.command).trim())||s(i.path)||s(i.file_path)||s(i.pattern)||s(i.description)||s(i.prompt),y=(h!==""?`${n}: ${h}`:n).replace(/\s+/g," ").trim();return y.length>G?y.slice(0,G):y}l(pe,"summarizeActivity");function me(n){for(let t=n.length-1;t>=0;t--)if(n[t]?.role==="assistant")return n[t]}l(me,"lastAssistantMessage");function ge(n){try{const t=n?.sessionManager?.getBranch();if(!Array.isArray(t))return[];const i=new Set;for(const s of t){if(!ce(s))continue;const u=s.details?.reviewId;typeof u=="string"&&i.add(u)}return[...i]}catch{return[]}}l(ge,"currentReviewBoundaryIds");const Q=1e4,C=[13e4,15e4,17e4,185e3,2e5];function we(n){const t=C[0],i=C[C.length-1];if(n<t)return null;if(n>=i)return i+Math.floor((n-i)/Q)*Q;let s=t;for(const u of C)n>=u&&(s=u);return s}l(we,"steerBand");function _e(n,t,i){const s=Math.round(n/1e3),u=n>=185e3;if(i==="orchestrator")return n<15e4?`Context ~${s}k and growing. When you reach a good stopping point, consider updating your roadmap (\`crtr doc edit roadmap\`) and running \`crtr node yield\` to refresh against it \u2014 no rush yet.`:u?`Context ~${s}k \u2014 this is getting long. Stop taking on new work now: bring your roadmap current, hand off anything outstanding, and \`crtr node yield\` immediately to refresh before this context overflows.`:`Context ~${s}k. Update your roadmap (\`crtr doc edit roadmap\`) so a fresh revive can continue, delegate any outstanding work, then \`crtr node yield\` to refresh.`;if(t==="resident"){const h="If substantial work remains, `crtr node yield` to continue fresh against your goal and your note. Add --promote only when worthwhile independent work can run in parallel and coordinating it should become your primary job; `crtr node yield -h` has the boundary.";return n<15e4?`Context ~${s}k and growing. ${h} Otherwise no rush \u2014 wrap up when you reach a good stopping point.`:u?`Context ~${s}k \u2014 this is getting long. Wrap up now before this context overflows: finish what's in hand, or \`crtr node yield\` immediately to continue fresh against your goal and your note if substantial work remains.`:`Context ~${s}k. ${h} If you're near done, just finish here; if there's more open-ended work, \`crtr node yield\` rather than letting this context grow.`}return n<15e4?`Context ~${s}k and growing. If you're near done, finish with \`crtr push final\`. If real work remains, \`crtr node yield\` to continue in a fresh window against your goal and your note \u2014 no rush yet.`:u?`Context ~${s}k \u2014 this is getting long. Wrap up now before this context overflows: \`crtr push final\` if you're close, otherwise \`crtr node yield\` immediately to continue in a fresh window against your goal and your note.`:`Context ~${s}k. If you're close, finish with \`crtr push final\`; otherwise \`crtr node yield\` now to refresh into a clean window and keep going against your goal and your note.`}l(_e,"steerNote");function ke(n){const t=Z();if(t===void 0||t.trim()==="")return;let i=0,s=0,u="",h=null,y=null;const w=new Set;let k=!1,I=!1;const N=l(e=>{if(!I){I=!0;try{ye(()=>e?.abort?.())}catch{}}},"abortForRefresh");let v;const V=A().subscribe("node",()=>{const e=A();k&&e.state==="connected"&&e.latestNode?.intent==="refresh"&&N(v)}),c=l((e,r)=>{F({event:"broker.daemon.operation.failed",level:"error",node_id:t,error:r,fields:{operation:e}})},"emitDaemonOperationFailure"),D=l((e,r)=>{if(e.action==="reprompt"){z(e.prompt,{type:"runtime",kind:"stop-guard"}),n.sendUserMessage(e.prompt,{deliverAs:"followUp"});return}if(e.action==="stay_resident"){ae(t).then(()=>A().stop(),o=>c("idle",o));return}if(e.action==="shutdown")try{r?.shutdown?.()}catch{}},"enactSettleDirective"),X=3e3;let O=0,S=Promise.resolve(),d=null,U=null,q=-1/0,p=null,R=0;const B=l(()=>{if(d===null||d===U)return;const e=d;U=e,q=Date.now(),S=S.then(()=>ne(t,e)).catch(r=>c("telemetry",r))},"queueTelemetry"),E=l((e,r)=>{if(d!==null&&d.tokens_in===i&&d.tokens_out===s&&d.model===u&&d.context_tokens===e&&d.last_activity===r)return;R=Math.max(Date.now(),R+1),d={tokens_in:i,tokens_out:s,model:u,context_tokens:e,last_activity:r,updated_at:new Date(R).toISOString()};const o=2e3-(Date.now()-q);o<=0?B():p===null&&(p=setTimeout(()=>{p=null,B()},o),p.unref?.())},"publishTelemetry"),$=l(()=>(p!==null&&clearTimeout(p),p=null,B(),S),"flushTelemetry");let M=Promise.resolve();const H=l(e=>(M=M.catch(()=>{}).then(async()=>{const r=await x(t,{event:"progress"});if(r.fault_link==="daemon\u2192node"&&(await te(t)).fault?.op==="conversation_write_failed"){if(!e)return;await(await import("../core/conversation-store/index.js")).flushConversation(),await j(t,{op:"clear",link:"daemon\u2192node"})}else(r.fault_link==="daemon\u2192node"||e&&r.fault_link==="pi\u2192provider")&&await j(t,{op:"clear",link:r.fault_link})}),M),"reportProgress"),T=l(()=>{const e=Date.now();e-O<X||(O=e,H(!1).catch(r=>c("turn_progress",r)))},"heartbeat");n.on("session_start",async(e,r)=>{try{const o=r?.sessionManager?.getSessionId?.();if(typeof o!="string"||o==="")return;const m=r?.sessionManager?.getSessionFile?.(),g=typeof m=="string"&&m!==""?m:null,_=typeof e?.reason=="string"?e.reason:null;_==="new"&&(i=0,s=0,w.clear());const a=await se(t,{piSessionId:o,sessionFile:g,pid:process.pid,reason:_,reviewBoundaryIds:ge(r)});if(a.action==="none"&&A().start(t,K()),a.action==="shutdown"){try{r?.shutdown?.()}catch{}return}if(a.action==="relaunch_root"){ie(t).catch(f=>{const b=f instanceof Error?f.message:String(f);r?.ui?.notify?.(`/new refused: ${b}`,"error"),F({event:"broker.daemon.operation.failed",level:"error",node_id:t,error:f,fields:{operation:"relaunch_root"}})});return}}catch(o){F({event:"broker.daemon.operation.failed",level:"error",node_id:t,error:o,fields:{operation:"session_bound"}})}}),n.on("agent_start",async(e,r)=>{k=!0,v=r;try{if(!(await x(t,{event:"started"})).applied)throw new Error("daemon refused turn open")}catch(o){c("turn_open",o),r?.ui?.notify?.("Turn refused: the broker no longer owns this node.","error"),he(()=>r?.abort?.())}}),n.on("input",async()=>{k||(I=!1),de();try{await re(t)}catch(e){throw c("clear_pushed_final",e),e}}),n.on("tool_execution_start",e=>{try{y=pe(String(e?.toolName??""),e?.args),E(h,y),T()}catch{}}),n.on("tool_execution_update",()=>{try{T()}catch{}}),n.on("message_update",()=>{try{T()}catch{}}),n.on("tool_execution_end",async(e,r)=>{try{T(),(await L(t)).intent==="refresh"&&N(r)}catch{}}),n.on("session_shutdown",async(e,r)=>{V(),k=!1,v=void 0,await $();try{await x(t,{event:"closed",end_reason:"teardown-aborted"})}catch(o){c("turn_close_teardown",o)}if(e?.reason==="quit")try{const o=await Y(t,{stopReason:"quit",pushedFinal:!1});D(o,r)}catch(o){c("settle_quit",o)}});const W=l(e=>{e?.role!=="assistant"||e.usage==null||(i+=Number(e.usage.input??0)||0,s+=Number(e.usage.output??0)||0,typeof e.model=="string"&&e.model!==""&&(u=e.model))},"accumulate");n.on("turn_end",async(e,r)=>{W(e?.message);let o=null;try{const a=r.getContextUsage()?.tokens;typeof a=="number"&&(o=a)}catch{}o!==null&&(h=o),E(o,y),await $();try{const a=e?.message?.stopReason!=="error"&&e?.message?.stopReason!=="aborted";await H(a)}catch(a){c("turn_end_fault_clear",a)}const m=Array.isArray(e?.message?.content)?e.message.content:[],g=e?.message?.stopReason??"",_=g!=="error"&&g!=="aborted"&&m.some(a=>a?.type==="toolCall");try{const a=o!==null?we(o):null,f=a!==null&&!w.has(a)?await L(t):null;if(a!==null&&f!==null){w.add(a);const b=ue("context-nudge",{},_e(a,f.lifecycle,f.mode));_?(z(b,{type:"runtime",kind:"context-nudge"}),n.sendUserMessage(b,{deliverAs:"steer"})):n.sendMessage({customType:le,content:b,display:!0},{deliverAs:"nextTurn"})}}catch(a){c("turn_boundary",a)}});let P=null;n.on("agent_end",e=>{P=e;try{const r=Array.isArray(e?.messages)?e.messages:[];for(const o of r)W(o)}catch{}}),n.on("agent_settled",async(e,r)=>{k=!1,v=void 0,E(h,y),await $();const o=P;if(P=null,fe())return;try{await x(t,{event:"closed",end_reason:"settled"})}catch(a){c("turn_close",a);return}const m=Array.isArray(o?.messages)?o.messages:[],g=me(m),_=typeof g?.stopReason=="string"?g.stopReason:"";try{const a=o===null?{pushedFinal:!1}:await oe(t),f=await Y(t,{stopReason:_,pushedFinal:a.pushedFinal});D(f,r)}catch(a){c("settle",a)}})}l(ke,"registerCanvasStophook");var Me=ke;export{Me as default,ke as registerCanvasStophook,_e as steerNote};
|
|
@@ -24,6 +24,8 @@ A run is an agent that works on a person's Northlight runtime, on your behalf an
|
|
|
24
24
|
|
|
25
25
|
`runs.wait` returns on `waiting_on_user`, `idle` and `settled`, so check the status before you read a result.
|
|
26
26
|
|
|
27
|
+
A turn that fails on a model error leaves the run `idle`, not `settled`, with `last_turn_error` set (`{code, message}`); the same error is on that turn's `turn.completed` event. The run stays usable, and a retry is a `runs.message`. When `code` is `rate_limited`, every model route is rate-limited and `retry_at` (an ISO time) says when the limit is expected to lift: send the retry after `retry_at`, or `runs.cancel` the run, rather than wait for its deadline. A message sent before `retry_at` fails the same way.
|
|
28
|
+
|
|
27
29
|
## Outcome and result
|
|
28
30
|
|
|
29
31
|
A `settled` run has an `outcome`:
|
|
@@ -42,7 +42,7 @@ A chat app sends a message and shows the answer to it. `runs.reply(runId, sent,
|
|
|
42
42
|
const sent = await runtime.runs.message(runId, 'What did the report say?');
|
|
43
43
|
for await (const event of runtime.runs.reply(runId, sent)) {
|
|
44
44
|
if (event.type === 'text.delta') append(event.delta);
|
|
45
|
-
if (event.type === 'turn.completed' && event.error) showError(event.error); // {code: 'content_refused' | 'model_error', message}
|
|
45
|
+
if (event.type === 'turn.completed' && event.error) showError(event.error); // {code: 'content_refused' | 'model_error' | 'rate_limited', message, retry_at?}
|
|
46
46
|
}
|
|
47
47
|
// or collect it: text as it streams, then the whole text and how the turn ended
|
|
48
48
|
const {text, ended, error, outcome} = await runtime.runs.reply(runId, sent).collect({onDelta: (delta) => append(delta)});
|
|
@@ -60,7 +60,7 @@ A responder gets `{run, kind: 'start' | 'message', messages}`. It is called afte
|
|
|
60
60
|
| Method | Effect |
|
|
61
61
|
|---|---|
|
|
62
62
|
| `reply(text, {chunks = 2, messageIds?})` | One turn: `node.turn.started`, text deltas, `node.output_text.done`, `node.turn.completed`. Delivers `messageIds` (default: every pending message). The run goes `idle` (`waiting_on_user` with an open question). |
|
|
63
|
-
| `failTurn({code: 'model_error' \| 'content_refused', message})` | The same turn ending `stop_reason: 'error'`; `runs.get` shows `last_turn_error`; `runs.reply(...).collect()` ends `error`. |
|
|
63
|
+
| `failTurn({code: 'model_error' \| 'content_refused' \| 'rate_limited', message, retry_at?})` | The same turn ending `stop_reason: 'error'`; `runs.get` shows `last_turn_error`; `runs.reply(...).collect()` ends `error`. `retry_at` (ISO) is required with `rate_limited` and refused with any other code. |
|
|
64
64
|
| `setActivity(activity, {at?})` | Fake-only: status `running` with this `activity` until the next event. The only way to reach `writing` or a streaming tool call. |
|
|
65
65
|
| `settle(ending)` | `{result}`, `{declined: {reason, code, retryable}}`, `{failure: 'canceled' \| 'deadline_exceeded'}`, or `{runtimeError: reason}`. Emits `node.settled` with the outcome the runtime writes. |
|
|
66
66
|
| `idle()` | Goes idle without a new turn (stopped without submitting). |
|
|
@@ -7,10 +7,22 @@ description: Behavior changes in @north-light/sdk that an app must act on, newes
|
|
|
7
7
|
|
|
8
8
|
Changes to `@north-light/sdk` that can change what an existing app sees. Newest first.
|
|
9
9
|
|
|
10
|
+
## 0.3.578
|
|
11
|
+
|
|
12
|
+
`runs.message` now steers a running root turn by default: the agent reads it at its next step. Pass `{ steer: false }` to wait for the current turn to end and start a separate turn. `start_turn: false` remains deferred and cannot use `steer: true`. When a later message joins a turn, `runs.reply` stops yielding text for the earlier message at that boundary, but still waits for the turn's completion. An app on an older SDK gets steering as soon as the runtime upgrades, because it cannot send `steer: false`; its `runs.reply` then streams the answer to a joined later message as part of the earlier reply. Upgrade the SDK to get the `RunReply` boundary and the opt-out.
|
|
13
|
+
|
|
14
|
+
## 0.3.577
|
|
15
|
+
|
|
16
|
+
`POST /v1/nodes` with a pinned `cwd` that is not an existing directory on the runtime's host now answers `cwd_missing` instead of creating a node whose broker then fails to launch. A sandbox, isolated or worktree node is not checked. `POST /v1/nodes/{id}/messages` with `reopen` to a dormant node whose recorded cwd is gone now answers `cwd_missing` before the reopen is committed or any mail is queued, instead of accepting the message and reporting `wake_failed`.
|
|
17
|
+
|
|
10
18
|
## 0.3.576
|
|
11
19
|
|
|
12
20
|
On a cloud role, `provider.tools` now reports a granted provider as `available` once its bundle is installed in the deployment's shared plugin directory. It no longer answers `500` when a person has no materialized bundle; a granted provider still being installed reports `installing` or `install_failed`. Providers without that person's grant remain hidden. The Mac's plugin settings and provider tools behavior are unchanged.
|
|
13
21
|
|
|
22
|
+
## Next release
|
|
23
|
+
|
|
24
|
+
A turn that ends because every model route is rate-limited for longer than a turn waits now reports `error.code: 'rate_limited'` with `error.retry_at` (ISO time the limit is expected to lift), on `turn.completed` and `runs.get().last_turn_error`. It was `model_error` with the time only inside `message`. The run stays `idle` and usable, as before. An app that matches `error.code` exhaustively should handle the new value; one that treats any other code as a model error needs no change.
|
|
25
|
+
|
|
14
26
|
## 0.3.572
|
|
15
27
|
|
|
16
28
|
`POST /v1/runs` works on a cloud role (a runtime started with `--role api` or `--role reconcile`). It answered `500 server_failure` because the role has no root launcher and the run start tried to prepare an app OS user and folder. Behavior on a person's Mac and on a hosted guest with a launcher is unchanged.
|
package/docs/sdk/streaming.md
CHANGED
|
@@ -68,6 +68,8 @@ Every event except `error` carries `node_id` and `sequence_number` in addition t
|
|
|
68
68
|
| `node.settled` | `{ node_id, sequence_number, outcome }` — terminal; the daemon ends the response after it |
|
|
69
69
|
| `error` | `{ error: { code: 'stream_gap' \| 'stream_dropped' \| 'stream_error', message, details?: { earliest_sequence?: number } } }` — `stream_gap` is recoverable; the other codes terminate the response |
|
|
70
70
|
|
|
71
|
+
A turn can emit more than one `node.turn.started`. A `run.message` sent while the turn is running steers by default, so the agent reads it at its next step and the stream emits another `node.turn.started` whose `input.message_ids` holds the joined message; the turn ends with one `node.turn.completed` whose `message_ids` lists every message that joined it. A reply to one message therefore ends at the turn's completion, not at the next `node.turn.started`; the SDK's `RunReply` stops yielding text once a later message joins. Send `{ steer: false }` to start a separate turn after the current one ends.
|
|
72
|
+
|
|
71
73
|
`summary` on a tool-call event states whether arguments are null, an array and its item count, an object and its field count, or a primitive type. It never includes argument values or tool output.
|
|
72
74
|
|
|
73
75
|
**Deliberately not carried:** thinking deltas, the model's tool-call construction deltas, raw tool output, and the system prompt. Those belong to the owner's viewer, not to an application's run stream.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@north-light/cli",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.578",
|
|
4
4
|
"description": "crtr — agent runtime with memory, plugins, and marketplaces",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -145,7 +145,7 @@
|
|
|
145
145
|
},
|
|
146
146
|
"license": "UNLICENSED",
|
|
147
147
|
"dependencies": {
|
|
148
|
-
"@north-light/identity": "0.3.
|
|
148
|
+
"@north-light/identity": "0.3.578",
|
|
149
149
|
"@earendil-works/chord": "1.1.0",
|
|
150
150
|
"@earendil-works/pi-agent-core": "1.1.0",
|
|
151
151
|
"@earendil-works/pi-ai": "1.1.0",
|