shennian 0.3.28 → 0.3.29

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.
@@ -401,8 +401,8 @@
401
401
  },
402
402
  {
403
403
  "file": "src/room/activation-service.js",
404
- "beforeBytes": 15557,
405
- "afterBytes": 9269
404
+ "beforeBytes": 15683,
405
+ "afterBytes": 9330
406
406
  },
407
407
  {
408
408
  "file": "src/room/agent-tool.js",
@@ -1,4 +1,4 @@
1
- import{selectRoomActivationTargets as A}from"./activation-policy.js";import{isInterruptedRoomActivation as _}from"./session-registry.js";const M=4,w=6e4,$=6,g=5*6e4,C=5*6e4;class O{deps;constructor(e){this.deps=e}async processMessages(e,t,i,s={roomName:"\u5F53\u524D\u7FA4\u804A"}){const a=[...t].sort((o,c)=>q(o.sequence,c.sequence));for(const o of a){const c=new Set(A(o,i).map(d=>d.registration.registryKey));for(const d of i){const r=this.deps.registry.getByRegistryKey(d.registryKey);if(!(!r?.binding||r.binding.roomId!==e)&&!(BigInt(o.sequence)<=BigInt(r.binding.lastActivatedSequence))){if(c.has(r.registryKey)){const u=(o.activationCause?.hopCount??0)+(o.author.principalType==="agent"?1:0),p=o.activationCause?.rootCauseMessageId??o.id;if(u>M)this.audit(r,o.id,p,u,"suppressed","max_hops");else{const m=r.binding.activeActivation;m&&_(m)&&await this.stopActiveActivation(r,"suppressed","daemon_restart_interrupted",this.deps.now?.()??new Date);const y=h([o]),I=r.binding.activationMode==="mention_only"?S([...(r.binding.mentionContext??[]).map(b=>b.deliveryText),y]):y;this.deps.registry.enqueueActivation(r.registryKey,{causeMessageId:o.id,rootCauseMessageId:p,sequence:o.sequence,hopCount:u,enqueuedAt:(this.deps.now?.()??new Date).toISOString(),attempts:0,deliveryText:I,systemPrompt:f(s,r)},this.deps.now?.()??new Date,r.binding.activationMode==="mention_only"),this.audit(r,o.id,p,u,"queued","policy_match")}}else r.binding.activationMode==="mention_only"&&o.kind!=="system"&&o.author.membershipId!==r.binding.agentMembershipId&&this.deps.registry.appendMentionContext(r.registryKey,{sequence:o.sequence,deliveryText:h([o])},this.deps.now?.()??new Date);this.deps.registry.advanceCursor({registryKey:r.registryKey,cursor:"activated",sequence:o.sequence})}}}for(const o of i)await this.drain(o.registryKey)}async drain(e){await this.deps.registry.runExclusive(e,async()=>{let t=this.deps.registry.getByRegistryKey(e),i=t?.binding;if(!t||!i)return;if(i.activeActivation){const c=this.deps.now?.()??new Date,d=this.deps.activationTurnTimeoutMs??C,r=Date.parse(i.activeActivation.dispatchedAt??i.activeActivation.enqueuedAt);if(c.getTime()-r<d||!await this.stopActiveActivation(t,"failed","turn_timeout",c)||(t=this.deps.registry.getByRegistryKey(e),i=t?.binding,!t||!i))return}const s=i.activationQueue[0];if(!s||i.status!=="active"||i.activationMode==="paused"||!t.capabilities.canResumeIdleSession||t.lifecycleState!=="inactive"&&!t.capabilities.canActivateWhileHostOpen)return;const a=this.deps.observations.getBySource(t);if(!a?.workspacePath||a.lifecycleState==="closed")return;const o=this.deps.registry.claimActivation({registryKey:e,windowMs:w,maxActivations:$,pauseMs:g,now:this.deps.now?.()});if(!o.allowed){o.newlyPaused&&this.audit(t,s.causeMessageId,s.rootCauseMessageId,s.hopCount,"suppressed","rate_limited");return}this.deps.registry.markActivationDispatching(e,s.causeMessageId);try{const c=await this.deps.activate({sessionId:t.nianSessionId,agentType:v(t.runtimeAdapter),agentSessionId:t.sourceSessionKey,workDir:a.workspacePath,text:s.deliveryText??"\u7FA4\u804A\u4E2D\u6709\u4E00\u6761\u65B0\u6D88\u606F\uFF0C\u8BF7\u7ED3\u5408\u5F53\u524D\u7FA4\u804A\u4E0A\u4E0B\u6587\u5904\u7406\u3002",systemPrompt:s.systemPrompt??f({roomName:"\u5F53\u524D\u7FA4\u804A"},t),roomContextRegistryKey:t.registryKey,clientMessageId:`room-activation-${i.bindingId}-${s.causeMessageId}`});this.deps.registry.updateLifecycle(e,c?.externalOwnerQueued?"inactive":"active"),this.audit(t,s.causeMessageId,s.rootCauseMessageId,s.hopCount,"activated","idle_resume")}catch(c){throw this.deps.registry.retryActiveActivation({registryKey:e,maxAttempts:3,pauseMs:g,now:this.deps.now?.()}),this.audit(t,s.causeMessageId,s.rootCauseMessageId,s.hopCount,"failed",c instanceof Error?c.name:"activation_error"),c}})}async stopActiveActivation(e,t,i,s){const a=e.binding?.activeActivation;if(!a)return!0;try{await this.deps.abort({sessionId:e.nianSessionId,agentType:v(e.runtimeAdapter)})}catch(o){return this.audit(e,a.causeMessageId,a.rootCauseMessageId,a.hopCount,"failed",o instanceof Error?`${i}_${o.name}`:`${i}_abort_error`),!1}return this.deps.registry.clearActiveActivation(e.registryKey,s),this.deps.registry.updateLifecycle(e.registryKey,"inactive",s),this.audit(e,a.causeMessageId,a.rootCauseMessageId,a.hopCount,t,i),!0}audit(e,t,i,s,a,o){e.binding&&this.deps.audit?.record({roomId:e.binding.roomId,bindingId:e.binding.bindingId,causeMessageId:t,rootCauseMessageId:i,hopCount:s,outcome:a,reason:o,at:this.deps.now?.()})}}function h(n){const e=n.map(t=>{const i=t.text?.trim()||"\u53D1\u9001\u4E86\u4E00\u6761\u6D88\u606F",s=t.attachments.length>0?`
1
+ import{selectRoomActivationTargets as A}from"./activation-policy.js";import{isInterruptedRoomActivation as _}from"./session-registry.js";const M=4,w=6e4,$=6,g=5*6e4,C=5*6e4;class O{deps;constructor(e){this.deps=e}async processMessages(e,t,i,s={roomName:"\u5F53\u524D\u7FA4\u804A"}){const a=[...t].sort((o,c)=>q(o.sequence,c.sequence));for(const o of a){const c=new Set(A(o,i).map(d=>d.registration.registryKey));for(const d of i){const r=this.deps.registry.getByRegistryKey(d.registryKey);if(!(!r?.binding||r.binding.roomId!==e)&&!(r.binding.status!=="active"&&r.binding.status!=="paused")&&!(BigInt(o.sequence)<=BigInt(r.binding.lastActivatedSequence))){if(c.has(r.registryKey)){const u=(o.activationCause?.hopCount??0)+(o.author.principalType==="agent"?1:0),p=o.activationCause?.rootCauseMessageId??o.id;if(u>M)this.audit(r,o.id,p,u,"suppressed","max_hops");else{const m=r.binding.activeActivation;m&&_(m)&&await this.stopActiveActivation(r,"suppressed","daemon_restart_interrupted",this.deps.now?.()??new Date);const y=h([o]),I=r.binding.activationMode==="mention_only"?S([...(r.binding.mentionContext??[]).map(b=>b.deliveryText),y]):y;this.deps.registry.enqueueActivation(r.registryKey,{causeMessageId:o.id,rootCauseMessageId:p,sequence:o.sequence,hopCount:u,enqueuedAt:(this.deps.now?.()??new Date).toISOString(),attempts:0,deliveryText:I,systemPrompt:f(s,r)},this.deps.now?.()??new Date,r.binding.activationMode==="mention_only"),this.audit(r,o.id,p,u,"queued","policy_match")}}else r.binding.activationMode==="mention_only"&&o.kind!=="system"&&o.author.membershipId!==r.binding.agentMembershipId&&this.deps.registry.appendMentionContext(r.registryKey,{sequence:o.sequence,deliveryText:h([o])},this.deps.now?.()??new Date);this.deps.registry.advanceCursor({registryKey:r.registryKey,cursor:"activated",sequence:o.sequence})}}}for(const o of i)await this.drain(o.registryKey)}async drain(e){await this.deps.registry.runExclusive(e,async()=>{let t=this.deps.registry.getByRegistryKey(e),i=t?.binding;if(!t||!i)return;if(i.activeActivation){const c=this.deps.now?.()??new Date,d=this.deps.activationTurnTimeoutMs??C,r=Date.parse(i.activeActivation.dispatchedAt??i.activeActivation.enqueuedAt);if(c.getTime()-r<d||!await this.stopActiveActivation(t,"failed","turn_timeout",c)||(t=this.deps.registry.getByRegistryKey(e),i=t?.binding,!t||!i))return}const s=i.activationQueue[0];if(!s||i.status!=="active"||i.activationMode==="paused"||!t.capabilities.canResumeIdleSession||t.lifecycleState!=="inactive"&&!t.capabilities.canActivateWhileHostOpen)return;const a=this.deps.observations.getBySource(t);if(!a?.workspacePath||a.lifecycleState==="closed")return;const o=this.deps.registry.claimActivation({registryKey:e,windowMs:w,maxActivations:$,pauseMs:g,now:this.deps.now?.()});if(!o.allowed){o.newlyPaused&&this.audit(t,s.causeMessageId,s.rootCauseMessageId,s.hopCount,"suppressed","rate_limited");return}this.deps.registry.markActivationDispatching(e,s.causeMessageId);try{const c=await this.deps.activate({sessionId:t.nianSessionId,agentType:v(t.runtimeAdapter),agentSessionId:t.sourceSessionKey,workDir:a.workspacePath,text:s.deliveryText??"\u7FA4\u804A\u4E2D\u6709\u4E00\u6761\u65B0\u6D88\u606F\uFF0C\u8BF7\u7ED3\u5408\u5F53\u524D\u7FA4\u804A\u4E0A\u4E0B\u6587\u5904\u7406\u3002",systemPrompt:s.systemPrompt??f({roomName:"\u5F53\u524D\u7FA4\u804A"},t),roomContextRegistryKey:t.registryKey,clientMessageId:`room-activation-${i.bindingId}-${s.causeMessageId}`});this.deps.registry.updateLifecycle(e,c?.externalOwnerQueued?"inactive":"active"),this.audit(t,s.causeMessageId,s.rootCauseMessageId,s.hopCount,"activated","idle_resume")}catch(c){throw this.deps.registry.retryActiveActivation({registryKey:e,maxAttempts:3,pauseMs:g,now:this.deps.now?.()}),this.audit(t,s.causeMessageId,s.rootCauseMessageId,s.hopCount,"failed",c instanceof Error?c.name:"activation_error"),c}})}async stopActiveActivation(e,t,i,s){const a=e.binding?.activeActivation;if(!a)return!0;try{await this.deps.abort({sessionId:e.nianSessionId,agentType:v(e.runtimeAdapter)})}catch(o){return this.audit(e,a.causeMessageId,a.rootCauseMessageId,a.hopCount,"failed",o instanceof Error?`${i}_${o.name}`:`${i}_abort_error`),!1}return this.deps.registry.clearActiveActivation(e.registryKey,s),this.deps.registry.updateLifecycle(e.registryKey,"inactive",s),this.audit(e,a.causeMessageId,a.rootCauseMessageId,a.hopCount,t,i),!0}audit(e,t,i,s,a,o){e.binding&&this.deps.audit?.record({roomId:e.binding.roomId,bindingId:e.binding.bindingId,causeMessageId:t,rootCauseMessageId:i,hopCount:s,outcome:a,reason:o,at:this.deps.now?.()})}}function h(n){const e=n.map(t=>{const i=t.text?.trim()||"\u53D1\u9001\u4E86\u4E00\u6761\u6D88\u606F",s=t.attachments.length>0?`
2
2
  \u9644\u4EF6\uFF1A${t.attachments.map(a=>a.name).join("\u3001")}`:"";return{speaker:t.author.displayName,body:`${i}${s}`}});return l(e)}function S(n){return l(n.map(T))}function T(n){const e=n.match(/^\[群消息\][ \t]+<([^>\n]+)>\n([\s\S]*)$/);if(e)return{speaker:e[1],body:e[2]};const t=n.match(/^\[群消息\]\n<([^>\n]+)>\n([\s\S]*)$/);if(t)return{speaker:t[1],body:t[2]};const i=n.match(/^群消息\n([^\n]+)\n([\s\S]*)$/);if(i)return{speaker:i[1],body:i[2]};const s=n.match(/^([^\n]+)\n([\s\S]*)$/);return s?{speaker:s[1],body:s[2]}:{speaker:"\u7FA4\u6210\u5458",body:n.trim()}}function l(n){if(n.length===1){const[e]=n;return`[\u7FA4\u6D88\u606F] <${e.speaker}>
3
3
  ${e.body}`}return`[\u7FA4\u6D88\u606F]
4
4
  ${n.map(e=>`<${e.speaker}>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shennian",
3
- "version": "0.3.28",
3
+ "version": "0.3.29",
4
4
  "description": "Shennian — AI Agent Control Plane CLI",
5
5
  "type": "module",
6
6
  "bin": {