shennian 0.5.21 → 0.5.22
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.
|
@@ -861,8 +861,8 @@
|
|
|
861
861
|
},
|
|
862
862
|
{
|
|
863
863
|
"file": "src/room/activation-service.js",
|
|
864
|
-
"beforeBytes":
|
|
865
|
-
"afterBytes":
|
|
864
|
+
"beforeBytes": 29557,
|
|
865
|
+
"afterBytes": 16983
|
|
866
866
|
},
|
|
867
867
|
{
|
|
868
868
|
"file": "src/room/attachment-cache.js",
|
|
@@ -1226,8 +1226,8 @@
|
|
|
1226
1226
|
},
|
|
1227
1227
|
{
|
|
1228
1228
|
"file": "src/session/queue-helpers.js",
|
|
1229
|
-
"beforeBytes":
|
|
1230
|
-
"afterBytes":
|
|
1229
|
+
"beforeBytes": 9648,
|
|
1230
|
+
"afterBytes": 4739
|
|
1231
1231
|
},
|
|
1232
1232
|
{
|
|
1233
1233
|
"file": "src/session/queue-message.js",
|
|
@@ -1251,8 +1251,8 @@
|
|
|
1251
1251
|
},
|
|
1252
1252
|
{
|
|
1253
1253
|
"file": "src/session/queue.js",
|
|
1254
|
-
"beforeBytes":
|
|
1255
|
-
"afterBytes":
|
|
1254
|
+
"beforeBytes": 43859,
|
|
1255
|
+
"afterBytes": 19352
|
|
1256
1256
|
},
|
|
1257
1257
|
{
|
|
1258
1258
|
"file": "src/session/queued-chat-dispatch.js",
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import{isAvailableBuiltinAgentType as k,managedAgentExecutionMode as P}from"@shennian/wire";import{getBuiltinAgentVersion as S,resolveBuiltinCommand as B}from"../agents/command-spec.js";import{registerCustomRuntimeSecurity as K,resolveCustomRuntimeExecutableFingerprint as $}from"../agents/custom-managed-runtime.js";import{loadConfig as x}from"../config/index.js";import{resolveManagedAgentExecutableIdentity as
|
|
1
|
+
import{isAvailableBuiltinAgentType as k,managedAgentExecutionMode as P}from"@shennian/wire";import{getBuiltinAgentVersion as S,resolveBuiltinCommand as B}from"../agents/command-spec.js";import{registerCustomRuntimeSecurity as K,resolveCustomRuntimeExecutableFingerprint as $}from"../agents/custom-managed-runtime.js";import{loadConfig as x}from"../config/index.js";import{resolveManagedAgentExecutableIdentity as T}from"../security/managed-agent-executable.js";import{compileManagedAgentPolicy as W}from"../security/managed-agent-policy.js";import{resolveManagedAgentRuntimeProtection as R}from"../security/managed-agent-runtime.js";import{selectRoomActivationTargets as q}from"./activation-policy.js";import{buildManagedAgentPermissionPrompt as E,composeManagedRoomPrompt as D}from"./managed-prompt-composer.js";import{isCurrentRegistration as f}from"./registration-authority.js";const N=4,F=6e4,O=6,V=5*6e4;class ce{deps;latestContexts=new Map;constructor(e){this.deps=e}async processMessages(e,o,t,a={roomName:"\u5F53\u524D\u7FA4\u804A"}){const d=[],m=[],c=new Map,u=new Set,g=[...o].sort((i,s)=>J(i.sequence,s.sequence));for(const i of t){const s=this.deps.registry.getByRegistryKey(i.registryKey);!s?.binding||!f(this.deps.registry,i)||s.binding.roomId!==e||s.binding.status!=="active"&&s.binding.status!=="paused"&&s.binding.activationQueue.length}for(const i of t){const s=this.deps.registry.getByRegistryKey(i.registryKey);if(!s?.binding||!f(this.deps.registry,i)||s.binding.roomId!==e||s.binding.activationQueue.length===0&&!s.binding.activeActivation||(u.add(s.registryKey),s.binding.status!=="active"||s.binding.activationMode==="paused")||s.binding.activationQueue.length===0)continue;const l=this.deps.observations.getBySource(s);if(!l?.workspacePath||l.lifecycleState==="closed")throw new Error("managed_room_workspace_unavailable");this.latestContexts.set(s.registryKey,a);for(const r of s.binding.activationQueue)d.push({registration:s,input:{params:{sessionId:s.nianSessionId,text:r.deliveryText??"\u7FA4\u804A\u4E2D\u6709\u4E00\u6761\u5F85\u5904\u7406\u6D88\u606F\uFF0C\u8BF7\u7ED3\u5408\u5F53\u524D\u7FA4\u804A\u4E0A\u4E0B\u6587\u5904\u7406\u3002",agentType:y(s.runtimeAdapter),sessionMode:a.agentsByIdentityId?.[s.binding.agentIdentityId]?.sessionMode??"standard",managerConfig:a.agentsByIdentityId?.[s.binding.agentIdentityId]?.managerConfig??null,managerDefaultWorkerAgentType:a.agentsByIdentityId?.[s.binding.agentIdentityId]?.managerConfig?.defaultWorkerAgentType??null,managerDefaultWorkerModelId:a.agentsByIdentityId?.[s.binding.agentIdentityId]?.managerConfig?.defaultWorkerModelId??null,workDir:l.workspacePath,agentSessionId:s.sourceSessionKey,queueMessageId:`room-activation-${s.binding.bindingId}-${r.causeMessageId}`,clientMessageId:`room-activation-${s.binding.bindingId}-${r.causeMessageId}`},context:{registryKey:s.registryKey,causeMessageId:r.causeMessageId,rootCauseMessageId:r.rootCauseMessageId,sequence:r.sequence,hopCount:r.hopCount}}})}for(const i of g){const s=new Set(q(i,t).map(l=>l.registration.registryKey));for(const l of t){const r=this.deps.registry.getByRegistryKey(l.registryKey);if(!r?.binding||!f(this.deps.registry,l)||r.binding.roomId!==e||r.binding.status!=="active"&&r.binding.status!=="paused"||a.agentsByIdentityId?.[r.binding.agentIdentityId]?.configurationPending||BigInt(i.sequence)<=BigInt(r.binding.lastActivatedSequence))continue;const h=c.get(r.registryKey)??[...r.binding.mentionContext??[]];if(c.set(r.registryKey,h),s.has(r.registryKey)){const p=(i.activationCause?.hopCount??0)+(i.author.principalType==="agent"?1:0),I=i.activationCause?.rootCauseMessageId??i.id;if(p>N)this.audit(r,i.id,I,p,"suppressed","max_hops");else{const w=this.deps.registry.claimActivation({registryKey:r.registryKey,causeMessageId:i.id,windowMs:F,maxActivations:O,pauseMs:V,now:this.deps.now?.()});if(!w.allowed){w.newlyPaused&&this.audit(r,i.id,I,p,"suppressed","rate_limited"),m.push({registryKey:r.registryKey,sequence:i.sequence});continue}const b=this.deps.observations.getBySource(r);if(!b?.workspacePath||b.lifecycleState==="closed")throw new Error("managed_room_workspace_unavailable");const M=v([i]),A=r.binding.activationMode==="mention_only"?Q([...h.map(C=>C.deliveryText),M]):M;this.latestContexts.set(r.registryKey,a),d.push({registration:r,input:{params:{sessionId:r.nianSessionId,text:A,agentType:y(r.runtimeAdapter),sessionMode:a.agentsByIdentityId?.[r.binding.agentIdentityId]?.sessionMode??"standard",managerConfig:a.agentsByIdentityId?.[r.binding.agentIdentityId]?.managerConfig??null,managerDefaultWorkerAgentType:a.agentsByIdentityId?.[r.binding.agentIdentityId]?.managerConfig?.defaultWorkerAgentType??null,managerDefaultWorkerModelId:a.agentsByIdentityId?.[r.binding.agentIdentityId]?.managerConfig?.defaultWorkerModelId??null,workDir:b.workspacePath,agentSessionId:r.sourceSessionKey,queueMessageId:`room-activation-${r.binding.bindingId}-${i.id}`,clientMessageId:`room-activation-${r.binding.bindingId}-${i.id}`,roomMessageCreatedAt:i.createdAt},context:{registryKey:r.registryKey,causeMessageId:i.id,rootCauseMessageId:I,sequence:i.sequence,hopCount:p}}}),r.binding.activationMode==="mention_only"&&c.set(r.registryKey,[])}}else r.binding.activationMode==="mention_only"&&i.kind!=="system"&&i.author.membershipId!==r.binding.agentMembershipId&&(h.some(p=>p.sequence===i.sequence)||h.push({sequence:i.sequence,deliveryText:v([i])}));m.push({registryKey:r.registryKey,sequence:i.sequence})}}await this.deps.enqueueConversationBatch(d.map(i=>i.input));for(const i of u)this.deps.registry.retireLegacyActivationState(i,this.deps.now?.()??new Date);for(const[i,s]of c)this.deps.registry.getByRegistryKey(i)?.lifecycleState!=="closed"&&this.deps.registry.replaceMentionContext(i,s,this.deps.now?.()??new Date);for(const i of d)this.audit(i.registration,i.input.context.causeMessageId,i.input.context.rootCauseMessageId,i.input.context.hopCount,"queued","conversation_queue");for(const i of m)this.deps.registry.getByRegistryKey(i.registryKey)?.lifecycleState!=="closed"&&this.deps.registry.advanceCursor({registryKey:i.registryKey,cursor:"activated",sequence:i.sequence})}async prepareConversationTurn(e){const o=e.at(-1);if(!o)throw new Error("managed_room_queue_context_missing");const t=this.deps.registry.getByRegistryKey(o.registryKey);if(!t)throw new Error("managed_room_binding_unavailable");const a=await this.prepareManagedTurn(t,o.causeMessageId);return this.audit(t,o.causeMessageId,o.rootCauseMessageId,o.hopCount,"activated","conversation_queue_dispatch"),a}async prepareDirectConversationTurn(e,o={}){const t=o.roomOrigin?this.deps.registry.getByRegistryKey(o.roomOrigin.registryKey):this.deps.registry.getByNianSessionId(e);return t?.nianSessionId!==e||!t||o.roomOrigin&&(t.registrationEpoch!==o.roomOrigin.registrationEpoch||t.binding?.bindingId!==o.roomOrigin.bindingId||t.binding.roomId!==o.roomOrigin.roomId)?null:this.prepareManagedTurn(t,void 0,o)}async prepareManagedTurn(e,o,t){if(!f(this.deps.registry,e)||!e.binding||e.binding.status!=="active")throw new Error("managed_room_binding_unavailable");const a=this.deps.loadContext?await this.deps.loadContext(e):this.latestContexts.get(e.registryKey);if(!a)throw new Error("managed_room_prompt_context_unavailable");const d=a.agentsByIdentityId?.[e.binding.agentIdentityId];if(d?.configurationPending)throw new Error("managed_agent_configuration_pending");if(!d?.permissionPolicy)throw new Error("managed_agent_policy_missing");const m=d.sessionMode==="manager"?"manager":"standard",c=m==="manager"?{...d.managerConfig,defaultWorkerAgentType:d.managerConfig?.defaultWorkerAgentType??y(e.runtimeAdapter),defaultWorkerModelId:d.managerConfig?.defaultWorkerModelId??null}:null,u=this.deps.observations.getBySource(e);if(!u?.workspacePath||u.lifecycleState==="closed")throw new Error("managed_room_workspace_unavailable");const g=this.deps.resolveManagedAgentPolicy?await this.deps.resolveManagedAgentPolicy({registration:e,permissionPolicy:d.permissionPolicy,permissionConfirmation:d.permissionConfirmation,workDir:u.workspacePath}):await U({registration:e,permissionPolicy:d.permissionPolicy,permissionConfirmation:d.permissionConfirmation,workDir:u.workspacePath});if(!f(this.deps.registry,e))throw new Error("managed_room_binding_unavailable");const i=H(a,e,g),s=this.deps.issueManagedRoomContext(e.registryKey,o,t?.allowedRoomActions,t?.propagateWorkerRoomOrigin);if(!/^mrc_[A-Za-z0-9_-]{43}$/.test(s))throw new Error("managed_room_context_unavailable");return{agentType:y(e.runtimeAdapter),effectiveModelId:a.effectiveModelsBySessionId?.[e.nianSessionId],workDir:g.adapterPolicy.workDir,agentSessionId:e.sourceSessionKey,systemPrompt:t?G({managerEvent:t.managerEvent===!0,scheduledTask:t.scheduledTask===!0,roomSendAllowed:t.allowedRoomActions?.includes("send")===!0,agentSystemPrompt:a.agentSystemPromptsByIdentityId?.[e.binding.agentIdentityId],managedAgentPolicy:g,runtimeAdapter:y(e.runtimeAdapter)}):i.systemPrompt,sessionMode:m,managerConfig:c,managerDefaultWorkerAgentType:c?.defaultWorkerAgentType??null,managerDefaultWorkerModelId:c?.defaultWorkerModelId??null,roomContextRegistryKey:e.registryKey,managedRoomContextToken:s,managedAgentPolicy:g,managedRoomPromptSnapshot:i.snapshot}}audit(e,o,t,a,d,m){e.binding&&this.deps.audit?.record({roomId:e.binding.roomId,bindingId:e.binding.bindingId,causeMessageId:o,rootCauseMessageId:t,hopCount:a,outcome:d,reason:m,at:this.deps.now?.()})}}function v(n){if(n.length===1&&n[0].kind==="system")return`[\u7FA4\u4E8B\u4EF6]
|
|
2
2
|
${n[0].text?.trim()||"\u7FA4\u804A\u72B6\u6001\u53D1\u751F\u53D8\u5316\u3002"}`;const e=n.map(o=>{const t=o.text?.trim()||"\u53D1\u9001\u4E86\u4E00\u6761\u6D88\u606F",a=o.attachments.length>0?`
|
|
3
3
|
${o.attachments.map(L).join(`
|
|
4
|
-
`)}`:"";return{speaker:o.author.displayName,body:`${t}${a}`}});return
|
|
4
|
+
`)}`:"";return{speaker:o.author.displayName,body:`${t}${a}`}});return _(e)}function L(n){return`\u9644\u4EF6\uFF1A${`${j(n.name)} \xB7 ${z(n.byteSize)}`}\uFF5C${n.mimeType}\uFF5CattachmentId=${n.attachmentId}`}function j(n){return String(n||"\u9644\u4EF6").replace(/[[\]\\]/g,"\\$&").replace(/[\r\n]+/g," ")}function z(n){const e=Number(n);if(!Number.isFinite(e)||e<0)return`${n} B`;if(e<1024)return`${e} B`;const o=["KB","MB","GB","TB"];let t=e,a=-1;do t/=1024,a+=1;while(t>=1024&&a<o.length-1);const d=t>=100?0:t>=10?1:2;return`${t.toFixed(d).replace(/\.0+$|(?<=\.[0-9])0+$/,"")} ${o[a]}`}function Q(n){return _(n.map(X))}function X(n){const e=n.match(/^\[群消息\][ \t]+<([^>\n]+)>\n([\s\S]*)$/);if(e)return{speaker:e[1],body:e[2]};const o=n.match(/^\[群消息\]\n<([^>\n]+)>\n([\s\S]*)$/);if(o)return{speaker:o[1],body:o[2]};const t=n.match(/^群消息\n([^\n]+)\n([\s\S]*)$/);if(t)return{speaker:t[1],body:t[2]};const a=n.match(/^([^\n]+)\n([\s\S]*)$/);return a?{speaker:a[1],body:a[2]}:{speaker:"\u7FA4\u6210\u5458",body:n.trim()}}function _(n){if(n.length===1){const[e]=n;return`[\u7FA4\u6D88\u606F] <${e.speaker}>
|
|
5
5
|
${e.body}`}return`[\u7FA4\u6D88\u606F]
|
|
6
6
|
${n.map(e=>`<${e.speaker}>
|
|
7
7
|
${e.body}`).join(`
|
|
8
8
|
|
|
9
|
-
`)}`}function G(n){const e=E({requestedPolicy:n.managedAgentPolicy.requestedPolicy,enforcement:n.managedAgentPolicy.enforcement,resolvedWorkDir:n.managedAgentPolicy.adapterPolicy.workDir}),o=n.managerEvent&&n.roomSendAllowed?`\u8FD9\u662F\u7531\u5F53\u524D\u7FA4\u804A\u4EFB\u52A1\u521B\u5EFA\u7684 Worker \u89E6\u53D1\u7684\u79C1\u6709 Manager \u7EED\u8F6E\u3002\u5148\u4F7F\u7528 Manager \u5DE5\u5177\u8BFB\u53D6\u5E76\u6838\u9A8C Worker \u7ED3\u679C\u3002\u53EA\u628A\u9762\u5411\u7528\u6237\u7684\u6700\u7EC8\u8FDB\u5C55\u6216\u7ED3\u8BBA\u53D1\u9001\u5230\u8BE5\u4EFB\u52A1\u539F\u59CB\u7FA4\u804A\uFF0C\u4E0D\u53D1\u9001 Worker \u539F\u59CB\u6D3B\u52A8\u3001\u5DE5\u5177\u65E5\u5FD7\u3001\u5185\u90E8\u6807\u8BC6\u6216\u8C03\u5EA6\u7EC6\u8282\u3002\u9700\u8981\u53D1\u5E03\u65F6\u5FC5\u987B\u663E\u5F0F\u4F7F\u7528${n.runtimeAdapter==="codex"?" shennian_room_send \u5DE5\u5177":" shennian room send \u547D\u4EE4"}\uFF1B\u53EA\u5728\u5F53\u524D\u5185\u90E8\u5BF9\u8BDD\u4E2D\u751F\u6210\u6587\u5B57\u4E0D\u4F1A\u53D1\u9001\u5230\u7FA4\u804A\u3002`:!n.managerEvent&&n.roomSendAllowed?`\u8FD9\u662F Owner \u4E0E Manager \u7684\u79C1\u6709\u5BF9\u8BDD\u3002\u4F60\u4ECD\u53EF\u4EE3\u8868\u5F53\u524D\u7ED1\u5B9A\u7684\u667A\u80FD\u4F53\uFF0C\u6309 Owner \u660E\u786E\u8981\u6C42\u5C06\u8FDB\u5C55\u6216\u7ED3\u8BBA\u663E\u5F0F\u53D1\u9001\u5230\u5B83\u6240\u5C5E\u7684 Room\uFF1B\u9700\u8981\u53D1\u5E03\u65F6\u5FC5\u987B\u4F7F\u7528${n.runtimeAdapter==="codex"?" shennian_room_send \u5DE5\u5177":" shennian room send \u547D\u4EE4"}\u3002\u4F60\u4E0D\u80FD\u8BFB\u53D6 Room \u5386\u53F2\u6216\u5411\u5176\u4ED6 Room \u53D1\u9001\u3002`:n.managerEvent?"\u8FD9\u662F Worker \u89E6\u53D1\u7684\u79C1\u6709 Manager \u7EED\u8F6E\u3002\u53EF\u4EE5\u4F7F\u7528 Manager \u5DE5\u5177\u8BFB\u53D6\u5E76\u6838\u9A8C Worker \u7ED3\u679C\uFF0C\u4F46\u4E0D\u5F97\u8BFB\u53D6\u3001\u53D1\u9001\u6216\u56DE\u590D\u4EFB\u4F55 Room \u5185\u5BB9\u3002":"\u8FD9\u662F Owner \u4E0E Manager \u7684\u79C1\u6709\u5BF9\u8BDD\u3002\u53EF\u4EE5\u4F7F\u7528 Manager \u5DE5\u5177\u7BA1\u7406 Worker\uFF0C\u4F46\u5F53\u524D\u6CA1\u6709 Room \u53D1\u5E03\u6743\u9650\u3002",t=n.agentSystemPrompt?.trim();return[`[\u795E\u5FF5\u53D7\u7BA1\u79C1\u6709\u7EED\u8F6E\u89C4\u5219]
|
|
9
|
+
`)}`}function G(n){const e=E({requestedPolicy:n.managedAgentPolicy.requestedPolicy,enforcement:n.managedAgentPolicy.enforcement,resolvedWorkDir:n.managedAgentPolicy.adapterPolicy.workDir}),o=n.scheduledTask?`\u8FD9\u662F\u670D\u52A1\u5668\u5DF2\u4FDD\u5B58\u7684\u5B9A\u65F6\u4EFB\u52A1\u73B0\u5728\u89E6\u53D1\uFF0C\u4E0D\u662F\u8981\u6C42\u4F60\u521B\u5EFA\u6216\u4FEE\u6539\u5B9A\u65F6\u4EFB\u52A1\u3002\u7ACB\u5373\u6267\u884C\u672C\u8F6E\u6536\u5230\u7684\u5DE5\u4F5C\u5185\u5BB9\uFF1B\u5176\u4E2D\u7684\u5468\u671F\u548C\u65F6\u95F4\u53EA\u662F\u539F\u5B89\u6392\u80CC\u666F\uFF0C\u4E0D\u8981\u518D\u6B21\u8C03\u7528\u5B9A\u65F6\u4EFB\u52A1\u521B\u5EFA\u5DE5\u5177\u3002\u9700\u8981\u5411\u5F53\u524D\u7ED1\u5B9A\u7FA4\u804A\u6C47\u62A5\u65F6\uFF0C\u5FC5\u987B\u663E\u5F0F\u4F7F\u7528${n.runtimeAdapter==="codex"?" shennian_room_send \u5DE5\u5177":" shennian room send \u547D\u4EE4"}\uFF1B\u53EA\u5728\u5185\u90E8\u5BF9\u8BDD\u56DE\u590D\u4E0D\u4F1A\u53D1\u5E03\u5230\u7FA4\u804A\u3002\u53EA\u80FD\u5411\u5F53\u524D\u7ED1\u5B9A\u7FA4\u804A\u53D1\u9001\uFF0C\u4E0D\u80FD\u8BFB\u53D6\u7FA4\u5386\u53F2\u6216\u64CD\u4F5C\u5176\u4ED6\u7FA4\u804A\u3002\u82E5\u6267\u884C\u6216\u53D1\u9001\u5931\u8D25\uFF0C\u5982\u5B9E\u62A5\u544A\uFF0C\u4E0D\u5F97\u58F0\u79F0\u5DF2\u64AD\u62A5\u3002`:n.managerEvent&&n.roomSendAllowed?`\u8FD9\u662F\u7531\u5F53\u524D\u7FA4\u804A\u4EFB\u52A1\u521B\u5EFA\u7684 Worker \u89E6\u53D1\u7684\u79C1\u6709 Manager \u7EED\u8F6E\u3002\u5148\u4F7F\u7528 Manager \u5DE5\u5177\u8BFB\u53D6\u5E76\u6838\u9A8C Worker \u7ED3\u679C\u3002\u53EA\u628A\u9762\u5411\u7528\u6237\u7684\u6700\u7EC8\u8FDB\u5C55\u6216\u7ED3\u8BBA\u53D1\u9001\u5230\u8BE5\u4EFB\u52A1\u539F\u59CB\u7FA4\u804A\uFF0C\u4E0D\u53D1\u9001 Worker \u539F\u59CB\u6D3B\u52A8\u3001\u5DE5\u5177\u65E5\u5FD7\u3001\u5185\u90E8\u6807\u8BC6\u6216\u8C03\u5EA6\u7EC6\u8282\u3002\u9700\u8981\u53D1\u5E03\u65F6\u5FC5\u987B\u663E\u5F0F\u4F7F\u7528${n.runtimeAdapter==="codex"?" shennian_room_send \u5DE5\u5177":" shennian room send \u547D\u4EE4"}\uFF1B\u53EA\u5728\u5F53\u524D\u5185\u90E8\u5BF9\u8BDD\u4E2D\u751F\u6210\u6587\u5B57\u4E0D\u4F1A\u53D1\u9001\u5230\u7FA4\u804A\u3002`:!n.managerEvent&&n.roomSendAllowed?`\u8FD9\u662F Owner \u4E0E Manager \u7684\u79C1\u6709\u5BF9\u8BDD\u3002\u4F60\u4ECD\u53EF\u4EE3\u8868\u5F53\u524D\u7ED1\u5B9A\u7684\u667A\u80FD\u4F53\uFF0C\u6309 Owner \u660E\u786E\u8981\u6C42\u5C06\u8FDB\u5C55\u6216\u7ED3\u8BBA\u663E\u5F0F\u53D1\u9001\u5230\u5B83\u6240\u5C5E\u7684 Room\uFF1B\u9700\u8981\u53D1\u5E03\u65F6\u5FC5\u987B\u4F7F\u7528${n.runtimeAdapter==="codex"?" shennian_room_send \u5DE5\u5177":" shennian room send \u547D\u4EE4"}\u3002\u4F60\u4E0D\u80FD\u8BFB\u53D6 Room \u5386\u53F2\u6216\u5411\u5176\u4ED6 Room \u53D1\u9001\u3002`:n.managerEvent?"\u8FD9\u662F Worker \u89E6\u53D1\u7684\u79C1\u6709 Manager \u7EED\u8F6E\u3002\u53EF\u4EE5\u4F7F\u7528 Manager \u5DE5\u5177\u8BFB\u53D6\u5E76\u6838\u9A8C Worker \u7ED3\u679C\uFF0C\u4F46\u4E0D\u5F97\u8BFB\u53D6\u3001\u53D1\u9001\u6216\u56DE\u590D\u4EFB\u4F55 Room \u5185\u5BB9\u3002":"\u8FD9\u662F Owner \u4E0E Manager \u7684\u79C1\u6709\u5BF9\u8BDD\u3002\u53EF\u4EE5\u4F7F\u7528 Manager \u5DE5\u5177\u7BA1\u7406 Worker\uFF0C\u4F46\u5F53\u524D\u6CA1\u6709 Room \u53D1\u5E03\u6743\u9650\u3002",t=n.agentSystemPrompt?.trim();return[`[\u795E\u5FF5\u53D7\u7BA1\u79C1\u6709\u7EED\u8F6E\u89C4\u5219]
|
|
10
10
|
${o}
|
|
11
11
|
\u4E0D\u5F97\u731C\u6D4B\u6216\u5C55\u793A Room\u3001Agent\u3001Session\u3001Binding\u3001Membership\u3001Machine \u6807\u8BC6\u6216\u4EFB\u4F55\u51ED\u636E\u3002`,e,t?`[\u667A\u80FD\u4F53\u79C1\u6709\u7CFB\u7EDF\u63D0\u793A\u8BCD]
|
|
12
12
|
${t}`:""].filter(Boolean).join(`
|
|
13
13
|
|
|
14
|
-
`)}function H(n,e,o){const t=e.binding?n.agentsByIdentityId?.[e.binding.agentIdentityId]:void 0;if(!e.binding||!t)throw new Error("managed_room_prompt_incomplete");return D({runtimeAdapter:y(e.runtimeAdapter),agent:{displayName:t.displayName,description:t.description,systemPrompt:n.agentSystemPromptsByIdentityId?.[e.binding.agentIdentityId],configurationVersion:t.configurationVersion},room:{name:n.roomName,activationMode:e.binding.activationMode,members:n.members},runtimePermissions:{requestedPolicy:o.requestedPolicy,enforcement:o.enforcement,resolvedWorkDir:o.adapterPolicy.workDir}})}async function U(n){const e=y(n.registration.runtimeAdapter),o=k(e)?B(e):null,t=e.startsWith("custom:")?x().customAgents?.[e.slice(7)]:void 0;t&&K(e,t);const a=n.runtime?.version??(o?S(e,o):t?.caps.version),d=n.runtime?{platform:n.runtime.runtimePlatform??process.platform,isWsl:n.runtime.runtimeIsWsl??!1,executableFingerprint:n.runtime.executableFingerprint}:o?
|
|
14
|
+
`)}function H(n,e,o){const t=e.binding?n.agentsByIdentityId?.[e.binding.agentIdentityId]:void 0;if(!e.binding||!t)throw new Error("managed_room_prompt_incomplete");return D({runtimeAdapter:y(e.runtimeAdapter),agent:{displayName:t.displayName,description:t.description,systemPrompt:n.agentSystemPromptsByIdentityId?.[e.binding.agentIdentityId],configurationVersion:t.configurationVersion},room:{name:n.roomName,activationMode:e.binding.activationMode,members:n.members},runtimePermissions:{requestedPolicy:o.requestedPolicy,enforcement:o.enforcement,resolvedWorkDir:o.adapterPolicy.workDir}})}async function U(n){const e=y(n.registration.runtimeAdapter),o=k(e)?B(e):null,t=e.startsWith("custom:")?x().customAgents?.[e.slice(7)]:void 0;t&&K(e,t);const a=n.runtime?.version??(o?S(e,o):t?.caps.version),d=n.runtime?{platform:n.runtime.runtimePlatform??process.platform,isWsl:n.runtime.runtimeIsWsl??!1,executableFingerprint:n.runtime.executableFingerprint}:o?T(o):{platform:process.platform,isWsl:process.platform==="linux"&&!!(process.env.WSL_DISTRO_NAME||process.env.WSL_INTEROP),executableFingerprint:t?$(t):void 0},m={agentType:e,runtimeVersion:a,platform:d.platform,isWsl:d.isWsl,executableFingerprint:d.executableFingerprint,requireExecutableFingerprint:!0},c=R(m);if(e==="codex"&&n.permissionConfirmation&&(n.permissionConfirmation.platform==="win32"&&c.platform==="wsl"||n.permissionConfirmation.platform==="wsl"&&c.platform==="win32"))throw new Error("managed_agent_runtime_changed");const u=Z({confirmation:n.permissionConfirmation,policy:n.permissionPolicy,runtimeAdapter:e,protection:c}),g=await W({...m,policy:n.permissionPolicy,workDir:n.workDir,hostFullAccessConfirmed:u&&n.permissionConfirmation?.hostFullAccess,limitedProtectionConfirmed:u&&n.permissionConfirmation?.limitedProtection});if(!g.ok){const i=g.unsupportedCapabilities?.length?`:${g.unsupportedCapabilities.join(",")}`:"";throw new Error(`${g.errorCode}${i}`)}return g.value}function Z(n){const{confirmation:e,policy:o,runtimeAdapter:t}=n,a=P(o);return!!(e&&e.policyVersion===o.version&&e.runtimeAdapter===t&&(e.executionMode??"restricted")===a&&e.hostFullAccess===(a==="native-full"||o.fileAccess==="host-full"))}function y(n){return n==="claude_code"?"claude":n}function J(n,e){const o=BigInt(n),t=BigInt(e);return o<t?-1:o>t?1:0}export{ce as RoomActivationService,Z as managedAgentPermissionConfirmationMatches,U as resolveManagedAgentPolicy};
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import{listSessionRecords as p}from"./store.js";const _={allowedRoomActions:["send"],propagateWorkerRoomOrigin:!1};function
|
|
2
|
-
`)?"event":"message":null,trigger:m(n)})}function
|
|
1
|
+
import{listSessionRecords as p}from"./store.js";const _={allowedRoomActions:["send"],propagateWorkerRoomOrigin:!1},I={allowedRoomActions:["send"],propagateWorkerRoomOrigin:!1,scheduledTask:!0};function R(n,e){return n?{roomOrigin:n.roomOrigin,allowedRoomActions:n.roomOrigin?["send"]:[],managerEvent:!0}:e?_:void 0}function S(n,e){const r=l(e);if(r)return n.find(i=>l(i)===r)??null;if(e.origin!=="external")return null;const t=g(e);return n.find(i=>g(i)===t)??null}function O(n){const{dispatchBlock:e,origin:r,managedRoom:t,managedAgentDirect:i,trigger:a,externalQueuedSubmissionId:o,...u}=n;return u}function b(n){const e=n.reduce((o,u)=>{const d=c(u);return o===null||d<o?d:o},null);if(e===null)return[];const r=n.filter(o=>c(o)===e),t=r[0];if(!t)return[];if(s(t))return[t];if(t.trigger?.kind==="manager_worker"||t.trigger?.kind==="scheduled")return[t];const i=f(t),a=[];for(const o of r){if(f(o)!==i)break;a.push(o)}return a}function s(n){if(n.origin==="external"||n.origin==="room"||n.managedRoom)return!1;const e=n.trigger?.kind;return e==null||e==="personal"||e==="managed_direct"}function y(n){return n?.trim()||void 0}function D(n,e){const r=n.find(t=>t.id===e&&s(t));return r?[r]:[]}function c(n){const e=m(n).kind;return e==="personal"||e==="managed_direct"?0:e==="manager_event"||e==="manager_worker"?1:2}function m(n){const e=n.trigger;return e?e.kind==="room_activation"?{kind:e.kind,registryKey:e.registryKey}:e.kind==="manager_worker"?{kind:e.kind,parentSessionId:e.parentSessionId,roomOrigin:e.roomOrigin??null}:e.kind==="manager_event"?{kind:e.kind,roomOrigin:e.roomOrigin??null}:{kind:e.kind}:n.managedRoom?{kind:"room_activation",registryKey:n.managedRoom.registryKey}:n.managedAgentDirect?{kind:"managed_direct"}:{kind:"personal"}}function f(n){return JSON.stringify({agentType:n.agentType,sessionMode:n.sessionMode??null,workDir:n.workDir,agentSessionId:n.agentSessionId??null,modelId:y(n.modelId)??null,systemPrompt:n.systemPrompt??null,reasoningEffort:n.reasoningEffort??null,managerConfig:n.managerConfig??null,managerDefaultWorkerAgentType:n.managerDefaultWorkerAgentType??null,managerDefaultWorkerModelId:n.managerDefaultWorkerModelId??null,externalChannel:n.externalChannel??null,replyTarget:n.replyTarget??null,roomRegistryKey:n.managedRoom?.registryKey??null,roomInputKind:n.managedRoom?n.text.trimStart().startsWith(`[\u7FA4\u4E8B\u4EF6]
|
|
2
|
+
`)?"event":"message":null,trigger:m(n)})}function T(n){return n.every(e=>e.managedRoom)?n.every(e=>e.text.trimStart().startsWith(`[\u7FA4\u4E8B\u4EF6]
|
|
3
3
|
`))?`[\u7FA4\u4E8B\u4EF6]
|
|
4
|
-
${n.map(
|
|
4
|
+
${n.map(e=>e.text.trim().slice(6)).filter(Boolean).join(`
|
|
5
5
|
|
|
6
6
|
`)}`:`[\u7FA4\u6D88\u606F]
|
|
7
|
-
${n.map(
|
|
7
|
+
${n.map(e=>k(e.text)).filter(Boolean).join(`
|
|
8
8
|
|
|
9
9
|
`)}`:`[\u8FDE\u7EED\u7528\u6237\u6D88\u606F]
|
|
10
|
-
${n.map((r
|
|
11
|
-
${
|
|
10
|
+
${n.map((e,r)=>`<\u6D88\u606F ${r+1}>
|
|
11
|
+
${e.text.trim()}`).join(`
|
|
12
12
|
|
|
13
|
-
`)}`}function k(n){const
|
|
14
|
-
${
|
|
15
|
-
`)?
|
|
16
|
-
`)}function l(n){const
|
|
13
|
+
`)}`}function k(n){const e=n.trim(),r=e.match(/^\[群消息\][ \t]+<([^>\n]+)>\n([\s\S]*)$/);return r?`<${r[1]}>
|
|
14
|
+
${r[2]}`:e.startsWith(`[\u7FA4\u6D88\u606F]
|
|
15
|
+
`)?e.slice(6):e}function g(n){const e=l(n);return e?`id:${e}`:["body",h(n.text),...(n.attachments??[]).map(r=>r.path||`${r.name}:${r.mimeType}`)].join(`
|
|
16
|
+
`)}function l(n){const e=typeof n.clientMessageId=="string"?n.clientMessageId.trim():"";if(e)return e;const r=typeof n.id=="string"?n.id.trim():"";return r&&!r.startsWith("queue-")?r:""}function M(n){const e=new Set,r=[];for(const t of n){const i=t.path||`${t.name}:${t.mimeType}`;e.has(i)||(e.add(i),r.push(t))}return r.length?r:void 0}function h(n){return String(n||"").replace(/\s+/g," ").trim()}function v(n,e){const r=n.toLowerCase();if(r.includes("managed claim session conflicts with source binding"))return"managed_claim_source_binding_conflict";const t=r.match(/\b(?:managed_(?:agent|room)|agent_validation|acp|native|codex)_[a-z0-9_]+\b/)?.[0];return t||(r.includes("no rollout found")?"missing_rollout":r.includes("managed_room_permission_snapshot_mismatch")?"managed_room_permission_snapshot_mismatch":r.includes("managed_room_prompt_snapshot_mismatch")?"managed_room_prompt_snapshot_mismatch":r.includes("managed_room_turn_preparer_unavailable")?"managed_room_turn_preparer_unavailable":r.includes("timeout")?"timeout":r.includes("connection")?"connection_error":e)}function C(n,e){if(n.sessions.has(e.sessionId))return null;const r=p().find(t=>t.sessionId===e.sessionId)?.agentSessionId?.trim();return!r||r.startsWith("managed:")?null:r}export{_ as OWNER_DIRECT_TURN_OPTIONS,I as SCHEDULED_ROOM_TURN_OPTIONS,v as classifyQueueError,M as dedupeQueuedAttachments,S as findDuplicateQueuedMessage,T as formatQueuedBatch,s as isControllableQueueMessage,R as managedDirectTurnOptions,y as normalizeQueuedModelId,C as resolveManagedRoomNativeSessionId,O as stripLocalQueueFields,b as takeCompatibleBatch,D as takeControllableMessage};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{NativeSourceDeletionStore as K}from"../native-fusion/native-source-deletions.js";import{QueueRetryScheduler as G}from"./queue-retry.js";import{findDuplicateQueuedMessage as P,stripLocalQueueFields as H,takeCompatibleBatch as b,formatQueuedBatch as V,dedupeQueuedAttachments as X,classifyQueueError as Y,normalizeQueuedModelId as k,resolveManagedRoomNativeSessionId as E,managedDirectTurnOptions as W}from"./queue-helpers.js";import{CODEX_DESKTOP_SEND_UNAVAILABLE as Z}from"@shennian/wire";import{isCodexThreadTailInterrupted as ee}from"../native-fusion/codex-files.js";import{mergeProjectedSessions as te}from"./projection.js";import{assertFinishedAttachmentReferences as ne,markAttachmentReferences as se}from"./attachment-transfer-store.js";import{appendMessage as F,getMessageDeliveryStatus as x,listSessionRecords as A,recordSession as L,tombstoneMessage as ie,upsertMessage as re}from"./store.js";import{handleQueueDispatchFailure as ae,queueBlockedUntil as O,resolveQueueRecoveryNotice as j}from"./queue-dispatch-failure.js";import{resetCommandSpecCache as oe}from"../agents/command-spec.js";import{requestSessionIndexPublish as y}from"./index-publisher.js";import{clearPersistedManagerRoomOrigins as de,purgeQueuedSessionData as ue,readQueue as h,writeQueue as w}from"./queue-storage.js";import{parsePersonalAttachmentReferences as le}from"./attachment-reference.js";import{getPersonalSyncIdentity as N}from"../personal-sync/epoch.js";import{getDaemonInstallationId as z}from"../personal-sync/identity.js";import{isStewardSessionId as B,pinStewardWorkDir as ge}from"../steward/session.js";import{classifyStewardFailure as ce}from"../steward/failover.js";import{tryStewardFailover as me}from"./handlers/steward.js";import{isTrustedManagerEvent as he}from"./manager-event-authority.js";import{getQueueSnapshot as pe,handleQueueDelete as fe,handleQueueEdit as Ie,handleQueueGet as Se,handleQueuePromote as we}from"./queue-control.js";import{TerminalQueuedChatDispatchError as $,nowIso as J,queueEnvelope as Q,queueMessageFromParams as U}from"./queue-message.js";import{purgeQueuedSessionData as Je}from"./queue-storage.js";import{TerminalQueuedChatDispatchError as Ke}from"./queue-message.js";class Ne{opts;validateScheduledTarget;async enqueueScheduled(e){return this.handleEnqueue(e,!0)}draining=new Set;promoting=new Set;disposed=!1;retries=new G(e=>{this.wakeSession(e)});deletions=new K;inFlightMessageIds=new Map;deferredLogState=new Map;prepareManagedRoomTurn=null;prepareManagedAgentDirectTurn=null;constructor(e){this.opts=e,de(),setTimeout(()=>this.drainIdleQueues(),0).unref?.()}stop(){this.disposed=!0,this.retries.stop()}getSnapshot(e){return pe({getRuntime:this.opts.getRuntime,inFlightMessageIds:this.inFlightMessageIds,broadcast:t=>this.broadcast(t)},e)}async switchUnavailableSteward(e,t,n){const i=n instanceof Error?n.message:String(n);return ce(i)==="crashed"||!t.text?!1:me(this.opts.getRuntime(),e,{agentType:t.agentType},{state:"error",runId:"",message:i},t.text).catch(()=>!1)}isImmediateSendAvailable(e){const t=this.opts.getRuntime(),n=t.sessions.get(e);return n?.currentRunId?n.journalRunId?t.runJournal?.get(e,n.journalRunId)?.deliveryMode==="direct":!1:!0}setManagedRoomTurnPreparer(e){this.prepareManagedRoomTurn=e}setManagedAgentDirectTurnPreparer(e){this.prepareManagedAgentDirectTurn=e}async enqueueManagedRoomBatch(e){if(e.length===0)return;const t=this.opts.getRuntime(),n=h(),i=new Set,r=new Map;let d=!1;for(const s of e){const a=s.params;if(this.deletions.hasSession(a.sessionId)){delete n.sessions[a.sessionId],d=!0;continue}if(!a.sessionId||!a.text||!a.agentType||!a.workDir)throw new Error("sessionId, text, agentType and workDir are required");const l=U({...N(z()),...a});typeof a.roomMessageCreatedAt=="string"&&Number.isFinite(Date.parse(a.roomMessageCreatedAt))&&(l.createdAt=new Date(a.roomMessageCreatedAt).toISOString()),l.origin="room",l.managedRoom=s.context,l.trigger={kind:"room_activation",...s.context};const o=n.sessions[a.sessionId]??[],m=P(o,l),c=l.clientMessageId??l.id,S=x(a.sessionId,c);if(!m&&S.state==="not_found")o.push(l),n.sessions[a.sessionId]=o,r.set(`${l.sessionId}\0${c}`,l),i.add(a.sessionId),d=!0;else if(m&&S.state==="not_found")r.set(`${m.sessionId}\0${c}`,m),i.add(a.sessionId);else if(m&&S.state==="queued")i.add(a.sessionId);else if(m){const I=o.filter(f=>f.id!==m.id);I.length?n.sessions[a.sessionId]=I:delete n.sessions[a.sessionId],d=!0}}d&&w(n);let u;for(const s of i)try{for(const a of r.values())a.sessionId===s&&(F(s,Q(a),"queued"),L({sessionId:s,agentType:a.agentType,sessionMode:a.sessionMode,managerConfig:a.managerConfig,workDir:a.workDir,agentSessionId:E(t,a),modelId:a.modelId}));this.logLifecycle("enqueue.persisted",s,{origin:"room",pendingCount:h().sessions[s]?.length??0}),this.broadcast(s),this.wakeSession(s)}catch(a){u=a,this.logLifecycle("enqueue.commit-failed",s,{failureClass:Y(a instanceof Error?a.message:"","canonical_commit_failed")},"error"),this.retries.schedule(s,!0)}if(i.size&&y(t.client),u)throw u}async handleEnqueue(e,t=!1){const n=this.opts.getRuntime(),i=e.params;if(i.scheduledTask&&!t)throw new Error("schedule_source_untrusted");if((i.managerEventId||i.managerEventRoomOrigin||i.managedWorkerParentSessionId||i.managerWorkerRoomOrigin||e.params.managerWorkerNativeFull||e.params.managedRecoverySource)&&!he(e))throw new Error("manager_event_source_untrusted");const r=!t&&!i.managedWorkerParentSessionId?n.managerRuntime?.getWorkerControllerSessionId?.(String(i.sessionId??""),String(i.workDir??"")):null,d=r?{...i,managedWorkerParentSessionId:r}:i,u=!t&&(B(String(d.sessionId??""))||d.sessionScope==="steward");if(u){if((d.sessionMode??"standard")!=="standard")throw new Error("steward_session_mode_invalid");if(!B(d.sessionId)&&A().some(q=>q.sessionId===d.sessionId))throw new Error("steward_scope_conflict")}const s=u?{...d,workDir:ge(),sessionMode:"standard"}:d,a=!!(t&&s.scheduledTask?.bindingId);if(te(s.sessionListProjection),!s.sessionId||!s.text||!s.agentType||!s.workDir)return n.client.sendRes({type:"res",id:e.id,ok:!1,error:"sessionId, text, agentType and workDir are required"}),!1;const l=W(s.managerEventId?{roomOrigin:s.managerEventRoomOrigin}:null,!!s.managedAgentDirect),o=s.managedAgentDirect||a?await this.prepareManagedAgentDirectTurn?.(s.sessionId,l):null;if((s.managedAgentDirect||a)&&!o)throw new Error("managed_agent_context_unavailable");const m=o?A().find(q=>q.sessionId===s.sessionId):null,c=o?{...s,...o,agentType:o.agentType,sessionMode:o.sessionMode,managerConfig:o.managerConfig,workDir:o.workDir,agentSessionId:o.agentSessionId?.startsWith("managed:")?m?.agentSessionId&&!m.agentSessionId.startsWith("managed:")?m.agentSessionId:null:o.agentSessionId,modelId:o.effectiveModelId!==void 0?k(o.effectiveModelId):m?.modelId??void 0,systemPrompt:o.systemPrompt,externalChannel:s.managedAgentDirect?null:s.externalChannel,replyTarget:s.managedAgentDirect?null:s.replyTarget,managerDefaultWorkerAgentType:o.managerDefaultWorkerAgentType,managerDefaultWorkerModelId:o.managerDefaultWorkerModelId}:s,S=n.resolvePath(c.workDir),I=le(c.attachments);I?.length&&ne(S,I);const f={text:c.text,attachments:I,localized:!1},T=n.sessions.get(c.sessionId);if(c.agentType==="codex"&&c.agentSessionId&&T?.currentRunId?.startsWith("dispatch:")&&ee(c.agentSessionId))return n.client.sendRes({type:"res",id:e.id,ok:!1,error:Z}),!1;o?.managedRoomContextToken&&n.revokeManagedRoomContextToken?.(o.managedRoomContextToken);const C=await this.isSessionBusy(c.sessionId),M=h(),_=M.sessions[c.sessionId]??[],g=U({...c,text:f.text,attachments:f.attachments,systemPrompt:o?null:c.systemPrompt});o&&(s.managedAgentDirect&&(g.managedAgentDirect=!0),g.trigger?.kind!=="manager_event"&&g.trigger?.kind!=="scheduled"&&(g.trigger={kind:"managed_direct"}));const v=g.clientMessageId??g.id,R=x(c.sessionId,v);if(R.state!=="not_found")return n.client.sendRes({type:"res",id:e.id,ok:!0,payload:{queued:R.state==="queued",queueMessageId:g.id,...R,queue:this.getSnapshot(c.sessionId)}}),!0;const D=P(_,g);D||(M.sessions[c.sessionId]=[..._,g],w(M));const p=D??g;return L({sessionId:p.sessionId,agentType:p.agentType,sessionMode:p.sessionMode,managerConfig:p.managerConfig,workDir:p.workDir,agentSessionId:p.agentSessionId,modelId:p.modelId,...u?{sessionScope:"steward"}:{}}),F(p.sessionId,Q(p),"queued"),se(n.resolvePath(p.workDir),p.attachments??[]),y(n.client),this.logLifecycle("enqueue.persisted",c.sessionId,{origin:c.origin??"app",queueMessageId:p.id,pendingCount:(h().sessions[c.sessionId]??[]).length}),this.broadcast(c.sessionId),n.client.sendRes({type:"res",id:e.id,ok:!0,payload:{queued:!0,queueMessageId:D?.id??g.id,...x(c.sessionId,D?.clientMessageId??D?.id??g.clientMessageId??g.id),queue:this.getSnapshot(c.sessionId),...f.localized?{localizedAttachments:!0}:{}}}),C?this.retries.schedule(c.sessionId):this.wakeSession(c.sessionId),!0}async handleGet(e){await Se(this.queueControlContext(),e)}async handleEdit(e){await Ie(this.queueControlContext(),e)}async handleDelete(e){await fe(this.queueControlContext(),e)}queueControlContext(){return{getRuntime:this.opts.getRuntime,inFlightMessageIds:this.inFlightMessageIds,broadcast:e=>this.broadcast(e)}}async handlePromote(e){await we({...this.queueControlContext(),promoting:this.promoting,draining:this.draining,isImmediateSendAvailable:t=>this.isImmediateSendAvailable(t),canInjectActiveBatch:(t,n)=>this.canInjectActiveBatch(t,n),interruptQueuedSession:this.opts.interruptQueuedSession,dispatchQueuedMessages:t=>this.dispatchQueuedMessages(t),markExternalQueued:(t,n)=>this.markExternalQueued(t,n),removeBatch:(t,n)=>this.removeBatch(t,n),wakeSession:t=>this.wakeSession(t)},e)}isDispatching(e){return this.inFlightMessageIds.has(e)}noteTerminal(e){const t=h().sessions[e]?.find(n=>!!n.externalQueuedSubmissionId);t&&this.noteExternalClaim(e,t.clientMessageId??t.id),this.wakeSession(e)}purgeSession(e){ue(e),this.retries.cancel(e)}discardPendingManagedRoomMessages(e){if(this.deletions.hasSession(e)){const u=h().sessions[e]?.length??0;return this.purgeSession(e),u}const t=h(),n=t.sessions[e]??[],i=this.inFlightMessageIds.get(e)??new Set,r=n.filter(u=>u.managedRoom&&!i.has(u.id));if(r.length===0)return 0;const d=n.filter(u=>!r.includes(u));d.length?t.sessions[e]=d:delete t.sessions[e],w(t);for(const u of r)ie(e,u.clientMessageId??u.id);return y(this.opts.getRuntime().client),this.logLifecycle("managed-room.discarded-paused",e,{discardedCount:r.length,pendingCount:d.length}),this.broadcast(e),r.length}wakeSession(e){this.drainNext(e).catch(()=>{this.logLifecycle("drain.retry-required",e,{},"error"),this.retries.schedule(e,!0)})}drainIdleQueues(){if(this.disposed)return;const e=h();for(const t of Object.keys(e.sessions))this.wakeSession(t)}async drainNext(e){if(this.disposed||this.draining.has(e)||this.promoting.has(e))return;this.draining.add(e);let t=!1,n=!1,i=[];try{if(this.deletions.hasSession(e)){this.purgeSession(e);return}if(await this.isSessionBusy(e)){const o=h().sessions[e]?.length??0,m=this.deferredLogState.get(e),c=Date.now();(!m||m.pendingCount!==o||c-m.at>=3e4)&&(this.logLifecycle("drain.deferred",e,{pendingCount:o}),this.deferredLogState.set(e,{at:c,pendingCount:o}));return}this.deferredLogState.delete(e);const r=h(),d=r.sessions[e]??[],u=d.filter(o=>{const m=o.clientMessageId??o.id,c=x(e,m).state;return c==="queued"||c==="not_found"});if(u.length!==d.length&&(u.length?r.sessions[e]=u:delete r.sessions[e],w(r),this.logLifecycle("drain.pruned-terminal",e,{prunedCount:d.length-u.length,pendingCount:u.length})),u.some(o=>!!o.externalQueuedSubmissionId)){this.broadcast(e);return}const s=b(u);if(s.length===0){this.broadcast(e);return}if(O(s))return;s.some(o=>(o.dispatchBlock?.retryAt??0)>0)&&oe(),i=s,this.inFlightMessageIds.set(e,new Set(s.map(o=>o.id))),this.logLifecycle("dispatch.start",e,{batchCount:s.length,queueMessageId:s[0].id,origin:s[0].origin??"app"}),this.broadcast(e);for(const o of s)re(e,Q(o),"queued");const a=await this.dispatchQueuedMessages(s);if(a.deliveryMode==="external_owner_queue"){this.markExternalQueued(s,a.queuedSubmissionId),j(s),s.some(o=>o.dispatchBlock)&&y(this.opts.getRuntime().client),this.logLifecycle("dispatch.external-queued",e,{batchCount:s.length,queueMessageId:s[0].id}),this.broadcast(e);return}const l=this.removeBatch(e,s);j(s),s.some(o=>o.dispatchBlock)&&y(this.opts.getRuntime().client),this.logLifecycle("dispatch.accepted",e,{batchCount:s.length,queueMessageId:s[0].id,pendingCount:l}),this.deferredLogState.delete(e),t=l>0,this.broadcast(e)}catch(r){const d=i[0];if(d&&B(e)&&await this.switchUnavailableSteward(e,d,r)){this.removeBatch(e,i),this.broadcast(e);return}const u=ae({error:r,sessionId:e,batch:i,publish:()=>y(this.opts.getRuntime().client),isManagedWorker:!!this.opts.getRuntime().managerRuntime?.isManagedWorkerSession(e),removeBatch:()=>this.removeBatch(e,i),log:(s,a)=>this.logLifecycle(s,e,a,"error")});t=u.drainAgain,n=u.transientFailure,this.broadcast(e)}finally{this.inFlightMessageIds.delete(e),this.draining.delete(e);const r=h().sessions[e]??[];r.length?(this.broadcast(e),r.some(d=>!!d.externalQueuedSubmissionId)?this.retries.cancel(e):t?queueMicrotask(()=>this.wakeSession(e)):this.retries.schedule(e,n,O(b(r)))):this.retries.cancel(e)}}noteExternalClaim(e,t){const n=h(),i=n.sessions[e]??[],r=i.filter(d=>(d.clientMessageId??d.id)!==t);r.length!==i.length&&(r.length?n.sessions[e]=r:delete n.sessions[e],w(n),this.broadcast(e))}canInjectActiveBatch(e,t){if(!e.adapter.supportsActiveInput||!e.adapter.injectActiveInput||!e.journalRunId)return!1;const n=this.opts.getRuntime().runJournal?.get(t[0].sessionId,e.journalRunId),i=t[0].trigger?.kind==="managed_direct"||t[0].managedAgentDirect?null:"personal";return!!(i&&t[0].systemPrompt==null&&n&&n.source===i&&n.deliveryMode==="direct"&&n.agentType===t[0].agentType&&n.workDir===e.workDir&&n.agentSessionId===e.agentSessionId&&n.modelId===(t[0].modelId??null)&&n.reasoningEffort===(t[0].reasoningEffort??null))}removeBatch(e,t){if(t.length===0)return h().sessions[e]?.length??0;const n=h(),i=new Set(t.map(d=>d.id)),r=(n.sessions[e]??[]).filter(d=>!i.has(d.id));return r.length?n.sessions[e]=r:delete n.sessions[e],w(n),r.length}logLifecycle(e,t,n,i="info"){const r=`[chat.queue] ${JSON.stringify({at:J(),event:e,sessionId:t,...n})}`;i==="error"?console.error(r):console.info(r)}async dispatchQueuedMessages(e){const t=e[0],n=t.trigger?.kind==="scheduled"?t.trigger:null;if(n&&await this.validateScheduledTarget?.({sessionId:t.sessionId,...n})!=="ready")throw new $("schedule_target_unavailable");const i=e.flatMap(g=>{if(g.trigger?.kind==="room_activation"){const{kind:v,...R}=g.trigger;return[R]}return!g.trigger&&g.managedRoom?[g.managedRoom]:[]}),r=e.find(g=>g.trigger?.kind==="manager_event")?.trigger,d=e.some(g=>g.trigger?.kind==="managed_direct"||!!g.managedAgentDirect),u=d||!!n?.bindingId,s=e.find(g=>g.trigger?.kind==="manager_worker")?.trigger,a=r?.kind==="manager_event"||d,l=i.length>0?await this.prepareManagedRoomTurn?.(i):u||r?.kind==="manager_event"?await this.prepareManagedAgentDirectTurn?.(t.sessionId,W(r?.kind==="manager_event"?r:null,d)):void 0;if(i.length>0&&!l)throw new Error("managed_room_turn_preparer_unavailable");if(u&&!l)throw new Error("managed_agent_context_unavailable");if(r?.kind==="manager_event"&&this.opts.getRuntime().managerRuntime?.isManagedRoomBoundManager(t.sessionId)&&!l)throw new Error("managed_agent_context_unavailable");const o=new Set((h().sessions[t.sessionId]??[]).map(g=>g.id));if(this.disposed||this.deletions.hasSession(t.sessionId)||e.some(g=>!o.has(g.id)))throw l?.managedRoomContextToken&&this.opts.getRuntime().revokeManagedRoomContextToken?.(l.managedRoomContextToken),this.disposed?new Error("queue_stopped"):new $("queued_dispatch_cancelled");const m=l??null,c=m?.sessionMode==="manager"?m.managerConfig:null,S=e.length===1?t.text:V(e),I=X(e.flatMap(g=>g.attachments??[])),f=u||r?.kind==="manager_event"&&!!l,T=f?l.agentSessionId?.startsWith("managed:")?E(this.opts.getRuntime(),t):l.agentSessionId:i.length>0?E(this.opts.getRuntime(),t):t.agentSessionId??null,C=l?A().find(g=>g.sessionId===t.sessionId):null,M=l?.effectiveModelId!==void 0?k(l.effectiveModelId):k(C?.modelId)??k(t.modelId),_=l?.effectiveModelId!==void 0?"room_effective_model":k(C?.modelId)?"persisted_session_model":k(t.modelId)?"queued_message_model":"pi_default_model";return await this.opts.dispatchQueuedReq({type:"req",id:`queue-send-${t.id}-${Date.now()}`,method:"chat.send",params:{...N(z()),sessionId:t.sessionId,text:S,agentType:f?l.agentType:t.agentType,sessionMode:m?.sessionMode??t.sessionMode,managerConfig:m?c:t.managerConfig,workDir:f?l.workDir:t.workDir,agentSessionId:T,modelId:M,modelSelectionSource:_,systemPrompt:l?.systemPrompt??t.systemPrompt??null,managerDefaultWorkerAgentType:m?m.managerDefaultWorkerAgentType:t.managerDefaultWorkerAgentType,managerDefaultWorkerModelId:m?m.managerDefaultWorkerModelId:t.managerDefaultWorkerModelId,reasoningEffort:t.reasoningEffort??void 0,clientMessageId:t.clientMessageId??t.id,attachments:I,externalChannel:a?void 0:t.externalChannel,replyTarget:a?void 0:t.replyTarget,roomContextRegistryKey:a?void 0:l?.roomContextRegistryKey,activationCauseMessageId:a?void 0:i.at(-1)?.causeMessageId,rootCauseMessageId:a?void 0:i.at(-1)?.rootCauseMessageId,activationSequence:a?void 0:i.at(-1)?.sequence,activationHopCount:a?void 0:i.at(-1)?.hopCount,managedRecoverySource:r?.kind==="manager_event"?"manager_event":u?"managed_direct":i.length>0?"managed_room":void 0,managerEventId:r?.kind==="manager_event"?r.eventId:void 0,managedWorkerParentSessionId:s?.kind==="manager_worker"?s.parentSessionId:void 0,managerWorkerRoomOrigin:s?.kind==="manager_worker"?s.roomOrigin:void 0,managerWorkerNativeFull:s?.kind==="manager_worker"&&this.opts.getRuntime().managerRuntime?.isExternalWorkerController(s.parentSessionId,t.workDir)||void 0,managedRoomContextToken:l?.managedRoomContextToken,scheduledDelivery:!!n,suppressExternalOwnerEcho:i.length>0||!!n||void 0,queuedBatchItems:e.map(g=>{const v=H(g);return a?{...v,systemPrompt:l?.systemPrompt??null,externalChannel:null,replyTarget:null}:v}),waitForDispatch:!0}},l??void 0)??{}}markExternalQueued(e,t){const n=h(),i=new Set(e.map(u=>u.id)),r=n.sessions[e[0].sessionId]??[];let d=!1;for(const u of r)i.has(u.id)&&(u.externalQueuedSubmissionId=t||u.id,u.updatedAt=J(),d=!0);d&&w(n)}async isSessionBusy(e){const t=this.opts.getRuntime().recoveryBarrier;if(t?.isDispatchFrozen()||t?.isRecovering(e))return!0;const n=this.opts.getRuntime().sessions.get(e);if(!n)return!1;if(n.currentRunId){if(!(n.currentRunId.startsWith("dispatch:")&&!!this.opts.getRuntime().runJournal&&!n.journalRunId)||(n.adapter.getStatus?await n.adapter.getStatus().catch(()=>null):null)?.active)return!0;this.logLifecycle("drain.recovered-stale-dispatch",e,{staleRunId:n.currentRunId}),n.currentRunId=null,n.currentRunPhase=null}if(!n.adapter.getStatus)return!1;const i=await n.adapter.getStatus().catch(()=>null);return i?.active?(i.runId&&(n.currentRunId=i.runId,n.currentRunPhase=i.runPhase??n.currentRunPhase),!0):!1}broadcast(e){this.opts.getRuntime().client.sendEvent({type:"event",event:"session.queue.update",payload:{queue:this.getSnapshot(e)}})}}export{Ne as ChatQueueManager,Ke as TerminalQueuedChatDispatchError,Je as purgeQueuedSessionData};
|
|
1
|
+
import{NativeSourceDeletionStore as G}from"../native-fusion/native-source-deletions.js";import{QueueRetryScheduler as H}from"./queue-retry.js";import{findDuplicateQueuedMessage as P,stripLocalQueueFields as V,takeCompatibleBatch as b,formatQueuedBatch as X,dedupeQueuedAttachments as Y,classifyQueueError as Z,normalizeQueuedModelId as k,resolveManagedRoomNativeSessionId as E,managedDirectTurnOptions as W,SCHEDULED_ROOM_TURN_OPTIONS as F}from"./queue-helpers.js";import{CODEX_DESKTOP_SEND_UNAVAILABLE as ee}from"@shennian/wire";import{isCodexThreadTailInterrupted as te}from"../native-fusion/codex-files.js";import{mergeProjectedSessions as ne}from"./projection.js";import{assertFinishedAttachmentReferences as se,markAttachmentReferences as ie}from"./attachment-transfer-store.js";import{appendMessage as L,getMessageDeliveryStatus as x,listSessionRecords as A,recordSession as O,tombstoneMessage as re,upsertMessage as ae}from"./store.js";import{handleQueueDispatchFailure as oe,queueBlockedUntil as j,resolveQueueRecoveryNotice as N}from"./queue-dispatch-failure.js";import{resetCommandSpecCache as de}from"../agents/command-spec.js";import{requestSessionIndexPublish as y}from"./index-publisher.js";import{clearPersistedManagerRoomOrigins as ue,purgeQueuedSessionData as le,readQueue as h,writeQueue as w}from"./queue-storage.js";import{parsePersonalAttachmentReferences as ge}from"./attachment-reference.js";import{getPersonalSyncIdentity as z}from"../personal-sync/epoch.js";import{getDaemonInstallationId as $}from"../personal-sync/identity.js";import{isStewardSessionId as B,pinStewardWorkDir as ce}from"../steward/session.js";import{classifyStewardFailure as me}from"../steward/failover.js";import{tryStewardFailover as he}from"./handlers/steward.js";import{isTrustedManagerEvent as pe}from"./manager-event-authority.js";import{getQueueSnapshot as fe,handleQueueDelete as Ie,handleQueueEdit as Se,handleQueueGet as we,handleQueuePromote as ke}from"./queue-control.js";import{TerminalQueuedChatDispatchError as U,nowIso as J,queueEnvelope as Q,queueMessageFromParams as K}from"./queue-message.js";import{purgeQueuedSessionData as Je}from"./queue-storage.js";import{TerminalQueuedChatDispatchError as Ge}from"./queue-message.js";class ze{opts;validateScheduledTarget;async enqueueScheduled(e){return this.handleEnqueue(e,!0)}draining=new Set;promoting=new Set;disposed=!1;retries=new H(e=>{this.wakeSession(e)});deletions=new G;inFlightMessageIds=new Map;deferredLogState=new Map;prepareManagedRoomTurn=null;prepareManagedAgentDirectTurn=null;constructor(e){this.opts=e,ue(),setTimeout(()=>this.drainIdleQueues(),0).unref?.()}stop(){this.disposed=!0,this.retries.stop()}getSnapshot(e){return fe({getRuntime:this.opts.getRuntime,inFlightMessageIds:this.inFlightMessageIds,broadcast:t=>this.broadcast(t)},e)}async switchUnavailableSteward(e,t,n){const i=n instanceof Error?n.message:String(n);return me(i)==="crashed"||!t.text?!1:he(this.opts.getRuntime(),e,{agentType:t.agentType},{state:"error",runId:"",message:i},t.text).catch(()=>!1)}isImmediateSendAvailable(e){const t=this.opts.getRuntime(),n=t.sessions.get(e);return n?.currentRunId?n.journalRunId?t.runJournal?.get(e,n.journalRunId)?.deliveryMode==="direct":!1:!0}setManagedRoomTurnPreparer(e){this.prepareManagedRoomTurn=e}setManagedAgentDirectTurnPreparer(e){this.prepareManagedAgentDirectTurn=e}async enqueueManagedRoomBatch(e){if(e.length===0)return;const t=this.opts.getRuntime(),n=h(),i=new Set,a=new Map;let d=!1;for(const s of e){const r=s.params;if(this.deletions.hasSession(r.sessionId)){delete n.sessions[r.sessionId],d=!0;continue}if(!r.sessionId||!r.text||!r.agentType||!r.workDir)throw new Error("sessionId, text, agentType and workDir are required");const l=K({...z($()),...r});typeof r.roomMessageCreatedAt=="string"&&Number.isFinite(Date.parse(r.roomMessageCreatedAt))&&(l.createdAt=new Date(r.roomMessageCreatedAt).toISOString()),l.origin="room",l.managedRoom=s.context,l.trigger={kind:"room_activation",...s.context};const o=n.sessions[r.sessionId]??[],m=P(o,l),c=l.clientMessageId??l.id,S=x(r.sessionId,c);if(!m&&S.state==="not_found")o.push(l),n.sessions[r.sessionId]=o,a.set(`${l.sessionId}\0${c}`,l),i.add(r.sessionId),d=!0;else if(m&&S.state==="not_found")a.set(`${m.sessionId}\0${c}`,m),i.add(r.sessionId);else if(m&&S.state==="queued")i.add(r.sessionId);else if(m){const I=o.filter(f=>f.id!==m.id);I.length?n.sessions[r.sessionId]=I:delete n.sessions[r.sessionId],d=!0}}d&&w(n);let u;for(const s of i)try{for(const r of a.values())r.sessionId===s&&(L(s,Q(r),"queued"),O({sessionId:s,agentType:r.agentType,sessionMode:r.sessionMode,managerConfig:r.managerConfig,workDir:r.workDir,agentSessionId:E(t,r),modelId:r.modelId}));this.logLifecycle("enqueue.persisted",s,{origin:"room",pendingCount:h().sessions[s]?.length??0}),this.broadcast(s),this.wakeSession(s)}catch(r){u=r,this.logLifecycle("enqueue.commit-failed",s,{failureClass:Z(r instanceof Error?r.message:"","canonical_commit_failed")},"error"),this.retries.schedule(s,!0)}if(i.size&&y(t.client),u)throw u}async handleEnqueue(e,t=!1){const n=this.opts.getRuntime(),i=e.params;if(i.scheduledTask&&!t)throw new Error("schedule_source_untrusted");if((i.managerEventId||i.managerEventRoomOrigin||i.managedWorkerParentSessionId||i.managerWorkerRoomOrigin||e.params.managerWorkerNativeFull||e.params.managedRecoverySource)&&!pe(e))throw new Error("manager_event_source_untrusted");const a=!t&&!i.managedWorkerParentSessionId?n.managerRuntime?.getWorkerControllerSessionId?.(String(i.sessionId??""),String(i.workDir??"")):null,d=a?{...i,managedWorkerParentSessionId:a}:i,u=!t&&(B(String(d.sessionId??""))||d.sessionScope==="steward");if(u){if((d.sessionMode??"standard")!=="standard")throw new Error("steward_session_mode_invalid");if(!B(d.sessionId)&&A().some(q=>q.sessionId===d.sessionId))throw new Error("steward_scope_conflict")}const s=u?{...d,workDir:ce(),sessionMode:"standard"}:d,r=!!(t&&s.scheduledTask?.bindingId);if(ne(s.sessionListProjection),!s.sessionId||!s.text||!s.agentType||!s.workDir)return n.client.sendRes({type:"res",id:e.id,ok:!1,error:"sessionId, text, agentType and workDir are required"}),!1;const l=r?F:W(s.managerEventId?{roomOrigin:s.managerEventRoomOrigin}:null,!!s.managedAgentDirect),o=s.managedAgentDirect||r?await this.prepareManagedAgentDirectTurn?.(s.sessionId,l):null;if((s.managedAgentDirect||r)&&!o)throw new Error("managed_agent_context_unavailable");const m=o?A().find(q=>q.sessionId===s.sessionId):null,c=o?{...s,...o,agentType:o.agentType,sessionMode:o.sessionMode,managerConfig:o.managerConfig,workDir:o.workDir,agentSessionId:o.agentSessionId?.startsWith("managed:")?m?.agentSessionId&&!m.agentSessionId.startsWith("managed:")?m.agentSessionId:null:o.agentSessionId,modelId:o.effectiveModelId!==void 0?k(o.effectiveModelId):m?.modelId??void 0,systemPrompt:o.systemPrompt,externalChannel:s.managedAgentDirect?null:s.externalChannel,replyTarget:s.managedAgentDirect?null:s.replyTarget,managerDefaultWorkerAgentType:o.managerDefaultWorkerAgentType,managerDefaultWorkerModelId:o.managerDefaultWorkerModelId}:s,S=n.resolvePath(c.workDir),I=ge(c.attachments);I?.length&&se(S,I);const f={text:c.text,attachments:I,localized:!1},T=n.sessions.get(c.sessionId);if(c.agentType==="codex"&&c.agentSessionId&&T?.currentRunId?.startsWith("dispatch:")&&te(c.agentSessionId))return n.client.sendRes({type:"res",id:e.id,ok:!1,error:ee}),!1;o?.managedRoomContextToken&&n.revokeManagedRoomContextToken?.(o.managedRoomContextToken);const C=await this.isSessionBusy(c.sessionId),M=h(),_=M.sessions[c.sessionId]??[],g=K({...c,text:f.text,attachments:f.attachments,systemPrompt:o?null:c.systemPrompt});o&&(s.managedAgentDirect&&(g.managedAgentDirect=!0),g.trigger?.kind!=="manager_event"&&g.trigger?.kind!=="scheduled"&&(g.trigger={kind:"managed_direct"}));const v=g.clientMessageId??g.id,R=x(c.sessionId,v);if(R.state!=="not_found")return n.client.sendRes({type:"res",id:e.id,ok:!0,payload:{queued:R.state==="queued",queueMessageId:g.id,...R,queue:this.getSnapshot(c.sessionId)}}),!0;const D=P(_,g);D||(M.sessions[c.sessionId]=[..._,g],w(M));const p=D??g;return O({sessionId:p.sessionId,agentType:p.agentType,sessionMode:p.sessionMode,managerConfig:p.managerConfig,workDir:p.workDir,agentSessionId:p.agentSessionId,modelId:p.modelId,...u?{sessionScope:"steward"}:{}}),L(p.sessionId,Q(p),"queued"),ie(n.resolvePath(p.workDir),p.attachments??[]),y(n.client),this.logLifecycle("enqueue.persisted",c.sessionId,{origin:c.origin??"app",queueMessageId:p.id,pendingCount:(h().sessions[c.sessionId]??[]).length}),this.broadcast(c.sessionId),n.client.sendRes({type:"res",id:e.id,ok:!0,payload:{queued:!0,queueMessageId:D?.id??g.id,...x(c.sessionId,D?.clientMessageId??D?.id??g.clientMessageId??g.id),queue:this.getSnapshot(c.sessionId),...f.localized?{localizedAttachments:!0}:{}}}),C?this.retries.schedule(c.sessionId):this.wakeSession(c.sessionId),!0}async handleGet(e){await we(this.queueControlContext(),e)}async handleEdit(e){await Se(this.queueControlContext(),e)}async handleDelete(e){await Ie(this.queueControlContext(),e)}queueControlContext(){return{getRuntime:this.opts.getRuntime,inFlightMessageIds:this.inFlightMessageIds,broadcast:e=>this.broadcast(e)}}async handlePromote(e){await ke({...this.queueControlContext(),promoting:this.promoting,draining:this.draining,isImmediateSendAvailable:t=>this.isImmediateSendAvailable(t),canInjectActiveBatch:(t,n)=>this.canInjectActiveBatch(t,n),interruptQueuedSession:this.opts.interruptQueuedSession,dispatchQueuedMessages:t=>this.dispatchQueuedMessages(t),markExternalQueued:(t,n)=>this.markExternalQueued(t,n),removeBatch:(t,n)=>this.removeBatch(t,n),wakeSession:t=>this.wakeSession(t)},e)}isDispatching(e){return this.inFlightMessageIds.has(e)}noteTerminal(e){const t=h().sessions[e]?.find(n=>!!n.externalQueuedSubmissionId);t&&this.noteExternalClaim(e,t.clientMessageId??t.id),this.wakeSession(e)}purgeSession(e){le(e),this.retries.cancel(e)}discardPendingManagedRoomMessages(e){if(this.deletions.hasSession(e)){const u=h().sessions[e]?.length??0;return this.purgeSession(e),u}const t=h(),n=t.sessions[e]??[],i=this.inFlightMessageIds.get(e)??new Set,a=n.filter(u=>u.managedRoom&&!i.has(u.id));if(a.length===0)return 0;const d=n.filter(u=>!a.includes(u));d.length?t.sessions[e]=d:delete t.sessions[e],w(t);for(const u of a)re(e,u.clientMessageId??u.id);return y(this.opts.getRuntime().client),this.logLifecycle("managed-room.discarded-paused",e,{discardedCount:a.length,pendingCount:d.length}),this.broadcast(e),a.length}wakeSession(e){this.drainNext(e).catch(()=>{this.logLifecycle("drain.retry-required",e,{},"error"),this.retries.schedule(e,!0)})}drainIdleQueues(){if(this.disposed)return;const e=h();for(const t of Object.keys(e.sessions))this.wakeSession(t)}async drainNext(e){if(this.disposed||this.draining.has(e)||this.promoting.has(e))return;this.draining.add(e);let t=!1,n=!1,i=[];try{if(this.deletions.hasSession(e)){this.purgeSession(e);return}if(await this.isSessionBusy(e)){const o=h().sessions[e]?.length??0,m=this.deferredLogState.get(e),c=Date.now();(!m||m.pendingCount!==o||c-m.at>=3e4)&&(this.logLifecycle("drain.deferred",e,{pendingCount:o}),this.deferredLogState.set(e,{at:c,pendingCount:o}));return}this.deferredLogState.delete(e);const a=h(),d=a.sessions[e]??[],u=d.filter(o=>{const m=o.clientMessageId??o.id,c=x(e,m).state;return c==="queued"||c==="not_found"});if(u.length!==d.length&&(u.length?a.sessions[e]=u:delete a.sessions[e],w(a),this.logLifecycle("drain.pruned-terminal",e,{prunedCount:d.length-u.length,pendingCount:u.length})),u.some(o=>!!o.externalQueuedSubmissionId)){this.broadcast(e);return}const s=b(u);if(s.length===0){this.broadcast(e);return}if(j(s))return;s.some(o=>(o.dispatchBlock?.retryAt??0)>0)&&de(),i=s,this.inFlightMessageIds.set(e,new Set(s.map(o=>o.id))),this.logLifecycle("dispatch.start",e,{batchCount:s.length,queueMessageId:s[0].id,origin:s[0].origin??"app"}),this.broadcast(e);for(const o of s)ae(e,Q(o),"queued");const r=await this.dispatchQueuedMessages(s);if(r.deliveryMode==="external_owner_queue"){this.markExternalQueued(s,r.queuedSubmissionId),N(s),s.some(o=>o.dispatchBlock)&&y(this.opts.getRuntime().client),this.logLifecycle("dispatch.external-queued",e,{batchCount:s.length,queueMessageId:s[0].id}),this.broadcast(e);return}const l=this.removeBatch(e,s);N(s),s.some(o=>o.dispatchBlock)&&y(this.opts.getRuntime().client),this.logLifecycle("dispatch.accepted",e,{batchCount:s.length,queueMessageId:s[0].id,pendingCount:l}),this.deferredLogState.delete(e),t=l>0,this.broadcast(e)}catch(a){const d=i[0];if(d&&B(e)&&await this.switchUnavailableSteward(e,d,a)){this.removeBatch(e,i),this.broadcast(e);return}const u=oe({error:a,sessionId:e,batch:i,publish:()=>y(this.opts.getRuntime().client),isManagedWorker:!!this.opts.getRuntime().managerRuntime?.isManagedWorkerSession(e),removeBatch:()=>this.removeBatch(e,i),log:(s,r)=>this.logLifecycle(s,e,r,"error")});t=u.drainAgain,n=u.transientFailure,this.broadcast(e)}finally{this.inFlightMessageIds.delete(e),this.draining.delete(e);const a=h().sessions[e]??[];a.length?(this.broadcast(e),a.some(d=>!!d.externalQueuedSubmissionId)?this.retries.cancel(e):t?queueMicrotask(()=>this.wakeSession(e)):this.retries.schedule(e,n,j(b(a)))):this.retries.cancel(e)}}noteExternalClaim(e,t){const n=h(),i=n.sessions[e]??[],a=i.filter(d=>(d.clientMessageId??d.id)!==t);a.length!==i.length&&(a.length?n.sessions[e]=a:delete n.sessions[e],w(n),this.broadcast(e))}canInjectActiveBatch(e,t){if(!e.adapter.supportsActiveInput||!e.adapter.injectActiveInput||!e.journalRunId)return!1;const n=this.opts.getRuntime().runJournal?.get(t[0].sessionId,e.journalRunId),i=t[0].trigger?.kind==="managed_direct"||t[0].managedAgentDirect?null:"personal";return!!(i&&t[0].systemPrompt==null&&n&&n.source===i&&n.deliveryMode==="direct"&&n.agentType===t[0].agentType&&n.workDir===e.workDir&&n.agentSessionId===e.agentSessionId&&n.modelId===(t[0].modelId??null)&&n.reasoningEffort===(t[0].reasoningEffort??null))}removeBatch(e,t){if(t.length===0)return h().sessions[e]?.length??0;const n=h(),i=new Set(t.map(d=>d.id)),a=(n.sessions[e]??[]).filter(d=>!i.has(d.id));return a.length?n.sessions[e]=a:delete n.sessions[e],w(n),a.length}logLifecycle(e,t,n,i="info"){const a=`[chat.queue] ${JSON.stringify({at:J(),event:e,sessionId:t,...n})}`;i==="error"?console.error(a):console.info(a)}async dispatchQueuedMessages(e){const t=e[0],n=t.trigger?.kind==="scheduled"?t.trigger:null;if(n&&await this.validateScheduledTarget?.({sessionId:t.sessionId,...n})!=="ready")throw new U("schedule_target_unavailable");const i=e.flatMap(g=>{if(g.trigger?.kind==="room_activation"){const{kind:v,...R}=g.trigger;return[R]}return!g.trigger&&g.managedRoom?[g.managedRoom]:[]}),a=e.find(g=>g.trigger?.kind==="manager_event")?.trigger,d=e.some(g=>g.trigger?.kind==="managed_direct"||!!g.managedAgentDirect),u=d||!!n?.bindingId,s=e.find(g=>g.trigger?.kind==="manager_worker")?.trigger,r=a?.kind==="manager_event"||d,l=i.length>0?await this.prepareManagedRoomTurn?.(i):u||a?.kind==="manager_event"?await this.prepareManagedAgentDirectTurn?.(t.sessionId,n?.bindingId?F:W(a?.kind==="manager_event"?a:null,d)):void 0;if(i.length>0&&!l)throw new Error("managed_room_turn_preparer_unavailable");if(u&&!l)throw new Error("managed_agent_context_unavailable");if(a?.kind==="manager_event"&&this.opts.getRuntime().managerRuntime?.isManagedRoomBoundManager(t.sessionId)&&!l)throw new Error("managed_agent_context_unavailable");const o=new Set((h().sessions[t.sessionId]??[]).map(g=>g.id));if(this.disposed||this.deletions.hasSession(t.sessionId)||e.some(g=>!o.has(g.id)))throw l?.managedRoomContextToken&&this.opts.getRuntime().revokeManagedRoomContextToken?.(l.managedRoomContextToken),this.disposed?new Error("queue_stopped"):new U("queued_dispatch_cancelled");const m=l??null,c=m?.sessionMode==="manager"?m.managerConfig:null,S=e.length===1?t.text:X(e),I=Y(e.flatMap(g=>g.attachments??[])),f=u||a?.kind==="manager_event"&&!!l,T=f?l.agentSessionId?.startsWith("managed:")?E(this.opts.getRuntime(),t):l.agentSessionId:i.length>0?E(this.opts.getRuntime(),t):t.agentSessionId??null,C=l?A().find(g=>g.sessionId===t.sessionId):null,M=l?.effectiveModelId!==void 0?k(l.effectiveModelId):k(C?.modelId)??k(t.modelId),_=l?.effectiveModelId!==void 0?"room_effective_model":k(C?.modelId)?"persisted_session_model":k(t.modelId)?"queued_message_model":"pi_default_model";return await this.opts.dispatchQueuedReq({type:"req",id:`queue-send-${t.id}-${Date.now()}`,method:"chat.send",params:{...z($()),sessionId:t.sessionId,text:S,agentType:f?l.agentType:t.agentType,sessionMode:m?.sessionMode??t.sessionMode,managerConfig:m?c:t.managerConfig,workDir:f?l.workDir:t.workDir,agentSessionId:T,modelId:M,modelSelectionSource:_,systemPrompt:l?.systemPrompt??t.systemPrompt??null,managerDefaultWorkerAgentType:m?m.managerDefaultWorkerAgentType:t.managerDefaultWorkerAgentType,managerDefaultWorkerModelId:m?m.managerDefaultWorkerModelId:t.managerDefaultWorkerModelId,reasoningEffort:t.reasoningEffort??void 0,clientMessageId:t.clientMessageId??t.id,attachments:I,externalChannel:r?void 0:t.externalChannel,replyTarget:r?void 0:t.replyTarget,roomContextRegistryKey:r?void 0:l?.roomContextRegistryKey,activationCauseMessageId:r?void 0:i.at(-1)?.causeMessageId,rootCauseMessageId:r?void 0:i.at(-1)?.rootCauseMessageId,activationSequence:r?void 0:i.at(-1)?.sequence,activationHopCount:r?void 0:i.at(-1)?.hopCount,managedRecoverySource:a?.kind==="manager_event"?"manager_event":u?"managed_direct":i.length>0?"managed_room":void 0,managerEventId:a?.kind==="manager_event"?a.eventId:void 0,managedWorkerParentSessionId:s?.kind==="manager_worker"?s.parentSessionId:void 0,managerWorkerRoomOrigin:s?.kind==="manager_worker"?s.roomOrigin:void 0,managerWorkerNativeFull:s?.kind==="manager_worker"&&this.opts.getRuntime().managerRuntime?.isExternalWorkerController(s.parentSessionId,t.workDir)||void 0,managedRoomContextToken:l?.managedRoomContextToken,scheduledDelivery:!!n,suppressExternalOwnerEcho:i.length>0||!!n||void 0,queuedBatchItems:e.map(g=>{const v=V(g);return r?{...v,systemPrompt:l?.systemPrompt??null,externalChannel:null,replyTarget:null}:v}),waitForDispatch:!0}},l??void 0)??{}}markExternalQueued(e,t){const n=h(),i=new Set(e.map(u=>u.id)),a=n.sessions[e[0].sessionId]??[];let d=!1;for(const u of a)i.has(u.id)&&(u.externalQueuedSubmissionId=t||u.id,u.updatedAt=J(),d=!0);d&&w(n)}async isSessionBusy(e){const t=this.opts.getRuntime().recoveryBarrier;if(t?.isDispatchFrozen()||t?.isRecovering(e))return!0;const n=this.opts.getRuntime().sessions.get(e);if(!n)return!1;if(n.currentRunId){if(!(n.currentRunId.startsWith("dispatch:")&&!!this.opts.getRuntime().runJournal&&!n.journalRunId)||(n.adapter.getStatus?await n.adapter.getStatus().catch(()=>null):null)?.active)return!0;this.logLifecycle("drain.recovered-stale-dispatch",e,{staleRunId:n.currentRunId}),n.currentRunId=null,n.currentRunPhase=null}if(!n.adapter.getStatus)return!1;const i=await n.adapter.getStatus().catch(()=>null);return i?.active?(i.runId&&(n.currentRunId=i.runId,n.currentRunPhase=i.runPhase??n.currentRunPhase),!0):!1}broadcast(e){this.opts.getRuntime().client.sendEvent({type:"event",event:"session.queue.update",payload:{queue:this.getSnapshot(e)}})}}export{ze as ChatQueueManager,Ge as TerminalQueuedChatDispatchError,Je as purgeQueuedSessionData};
|