shennian 0.3.51 → 0.3.53
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/publish-build-manifest.json +4 -4
- package/dist/src/session/queue.js +4 -4
- package/dist/src/session/store.d.ts +3 -0
- package/dist/src/session/store.js +2 -2
- package/node_modules/@shennian/wire/dist/session-sync.d.ts +12 -2
- package/node_modules/@shennian/wire/dist/session-sync.js +3 -1
- package/package.json +1 -1
|
@@ -591,13 +591,13 @@
|
|
|
591
591
|
},
|
|
592
592
|
{
|
|
593
593
|
"file": "src/session/queue.js",
|
|
594
|
-
"beforeBytes":
|
|
595
|
-
"afterBytes":
|
|
594
|
+
"beforeBytes": 18893,
|
|
595
|
+
"afterBytes": 8613
|
|
596
596
|
},
|
|
597
597
|
{
|
|
598
598
|
"file": "src/session/store.js",
|
|
599
|
-
"beforeBytes":
|
|
600
|
-
"afterBytes":
|
|
599
|
+
"beforeBytes": 17364,
|
|
600
|
+
"afterBytes": 9292
|
|
601
601
|
},
|
|
602
602
|
{
|
|
603
603
|
"file": "src/session/tool-detail-store.js",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
`,{encoding:"utf8",mode:384,flag:"wx"});const i=
|
|
1
|
+
import l from"node:fs";import{randomUUID as y}from"node:crypto";import{buildUserMessagePayload as A}from"@shennian/wire";import{mergeProjectedSessions as E}from"./projection.js";import{parsePersonalAttachmentReferences as I}from"./attachment-reference.js";import{assertFinishedAttachmentReferences as D,markAttachmentReferences as w}from"./attachment-transfer-store.js";import{resolvePersonalSyncV1Path as R}from"../personal-sync/paths.js";import{appendMessage as $,getMessageDeliveryStatus as T,recordSession as Q,tombstoneMessage as W,upsertMessage as b}from"./store.js";import{requestSessionIndexPublish as M}from"./index-publisher.js";function C(){return{sessions:{}}}function x(){return new Date().toISOString()}function N(n){return`enqueue-send-${n}-${y()}`}function f(){try{const n=JSON.parse(l.readFileSync(v(),"utf-8"));return{sessions:n.sessions&&typeof n.sessions=="object"?n.sessions:{}}}catch(n){if(n.code==="ENOENT"||n instanceof Error&&n.message.startsWith("ENOENT:"))return C();throw n}}function p(n){const e=R();l.mkdirSync(e,{recursive:!0,mode:448});const s=v(),t=`${s}.tmp-${process.pid}-${y()}`;try{l.writeFileSync(t,`${JSON.stringify(n,null,2)}
|
|
2
|
+
`,{encoding:"utf8",mode:384,flag:"wx"});const i=l.openSync(t,"r");if(typeof i=="number")try{l.fsyncSync(i)}finally{l.closeSync(i)}l.renameSync(t,s)}finally{try{l.unlinkSync(t)}catch{}}}function v(){return R("outbound-queue.json")}function B(n){const e=x();return{id:n.queueMessageId||n.clientMessageId||`queue-${y()}`,sessionId:n.sessionId,text:n.text,agentType:n.agentType,sessionMode:n.sessionMode,managerConfig:n.managerConfig,workDir:n.workDir,agentSessionId:n.agentSessionId??null,modelId:n.modelId??null,systemPrompt:n.systemPrompt??null,managerDefaultWorkerAgentType:n.managerDefaultWorkerAgentType??null,managerDefaultWorkerModelId:n.managerDefaultWorkerModelId??null,reasoningEffort:n.reasoningEffort??null,clientMessageId:n.clientMessageId??null,attachments:I(n.attachments),externalChannel:n.externalChannel??null,replyTarget:n.replyTarget??null,origin:n.origin,createdAt:e,updatedAt:e}}function S(n){return{id:n.clientMessageId??n.id,sessionId:n.sessionId,role:"user",ts:Date.parse(n.createdAt),payload:A(n.text,n.attachments)}}class Y{opts;draining=new Set;constructor(e){this.opts=e,setTimeout(()=>this.drainIdleQueues(),0).unref?.()}getSnapshot(e){return{sessionId:e,busy:!!this.opts.getRuntime().sessions.get(e)?.currentRunId,pending:f().sessions[e]??[]}}async handleEnqueue(e){const s=this.opts.getRuntime(),t=e.params;if(E(t.sessionListProjection),!t.sessionId||!t.text||!t.agentType||!t.workDir){s.client.sendRes({type:"res",id:e.id,ok:!1,error:"sessionId, text, agentType and workDir are required"});return}const i=s.resolvePath(t.workDir),o=I(t.attachments);o?.length&&D(i,o);const r={text:t.text,attachments:o,localized:!1},a=await this.isSessionBusy(t.sessionId),d=f(),h=d.sessions[t.sessionId]??[];if(!a&&!h.length){await this.opts.dispatchReq({...e,id:N(e.id),method:"chat.send",params:{...t,text:r.text,responseId:e.id,clientMessageId:t.clientMessageId??t.queueMessageId,waitForDispatch:!0,attachments:r.attachments}});return}const c=B({...t,text:r.text,attachments:r.attachments}),P=c.clientMessageId??c.id,m=T(t.sessionId,P);if(m.state!=="not_found"){s.client.sendRes({type:"res",id:e.id,ok:!0,payload:{queued:m.state==="queued",queueMessageId:c.id,...m,queue:this.getSnapshot(t.sessionId)}});return}const g=z(h,c);g||(d.sessions[t.sessionId]=[...h,c],p(d));const u=g??c;Q({sessionId:u.sessionId,agentType:u.agentType,sessionMode:u.sessionMode,managerConfig:u.managerConfig,workDir:u.workDir,agentSessionId:u.agentSessionId,modelId:u.modelId}),$(u.sessionId,S(u),"queued"),w(s.resolvePath(u.workDir),u.attachments??[]),M(s.client),this.broadcast(t.sessionId),s.client.sendRes({type:"res",id:e.id,ok:!0,payload:{queued:!0,queueMessageId:g?.id??c.id,...T(t.sessionId,g?.clientMessageId??g?.id??c.clientMessageId??c.id),queue:this.getSnapshot(t.sessionId),...r.localized?{localizedAttachments:!0}:{}}}),a||this.drainNext(t.sessionId)}async handleGet(e){const s=this.opts.getRuntime(),t=e.params;if(!t.sessionId){s.client.sendRes({type:"res",id:e.id,ok:!1,error:"sessionId is required"});return}s.client.sendRes({type:"res",id:e.id,ok:!0,payload:{queue:this.getSnapshot(t.sessionId)}}),this.getSnapshot(t.sessionId).busy||this.drainNext(t.sessionId)}async handleEdit(e){const s=this.opts.getRuntime(),t=e.params;if(!t.sessionId||!t.queueMessageId||!t.text){s.client.sendRes({type:"res",id:e.id,ok:!1,error:"sessionId, queueMessageId and text are required"});return}const i=f(),o=i.sessions[t.sessionId]??[],r=o.findIndex(h=>h.id===t.queueMessageId);if(r<0){s.client.sendRes({type:"res",id:e.id,ok:!1,error:"Queued message not found"});return}const a=I(t.attachments),d=s.resolvePath(o[r].workDir);a?.length&&D(d,a),o[r]={...o[r],text:t.text,attachments:a,updatedAt:x()},i.sessions[t.sessionId]=o,p(i),b(t.sessionId,S(o[r]),"queued"),o[r].attachments?.length&&w(d,o[r].attachments??[]),M(s.client),this.broadcast(t.sessionId),s.client.sendRes({type:"res",id:e.id,ok:!0,payload:{queue:this.getSnapshot(t.sessionId)}})}async handleDelete(e){const s=this.opts.getRuntime(),t=e.params;if(!t.sessionId||!t.queueMessageId){s.client.sendRes({type:"res",id:e.id,ok:!1,error:"sessionId and queueMessageId are required"});return}const i=f(),o=i.sessions[t.sessionId]??[],r=o.find(d=>d.id===t.queueMessageId),a=o.filter(d=>d.id!==t.queueMessageId);if(a.length===o.length){s.client.sendRes({type:"res",id:e.id,ok:!1,error:"Queued message not found"});return}a.length?i.sessions[t.sessionId]=a:delete i.sessions[t.sessionId],p(i),W(t.sessionId,r?.clientMessageId??r?.id??t.queueMessageId),M(s.client),this.broadcast(t.sessionId),s.client.sendRes({type:"res",id:e.id,ok:!0,payload:{queue:this.getSnapshot(t.sessionId)}})}noteTerminal(e){this.drainNext(e)}purgeSession(e){const s=f();s.sessions[e]&&(delete s.sessions[e],p(s),this.draining.delete(e))}drainIdleQueues(){const e=f();for(const s of Object.keys(e.sessions))this.drainNext(s)}async drainNext(e){if(this.draining.has(e)||await this.isSessionBusy(e))return;const i=(f().sessions[e]??[])[0];if(!i){this.broadcast(e);return}const o=i;this.draining.add(e);try{b(e,S(o),"queued"),await this.dispatchQueuedMessage(o);const r=f(),a=(r.sessions[e]??[]).filter(d=>d.id!==i.id);a.length?r.sessions[e]=a:delete r.sessions[e],p(r),this.broadcast(e)}finally{this.draining.delete(e)}}mergeExternalMessages(e,s){const t=[e];for(;s[0]?.origin==="external";)t.push(s.shift());const i=j(t);return i.length===1?i[0]:{...e,id:`external-batch-${e.id}`,text:i.map(o=>o.text).filter(Boolean).join(`
|
|
3
3
|
|
|
4
|
-
`),attachments:
|
|
5
|
-
`)}function
|
|
4
|
+
`),attachments:F(i.flatMap(o=>o.attachments??[])),updatedAt:x()}}async dispatchQueuedMessage(e){await this.opts.dispatchReq({type:"req",id:`queue-send-${e.id}-${Date.now()}`,method:"chat.send",params:{sessionId:e.sessionId,text:e.text,agentType:e.agentType,sessionMode:e.sessionMode,managerConfig:e.managerConfig,workDir:e.workDir,agentSessionId:e.agentSessionId??null,modelId:e.modelId??void 0,systemPrompt:e.systemPrompt??null,managerDefaultWorkerAgentType:e.managerDefaultWorkerAgentType,managerDefaultWorkerModelId:e.managerDefaultWorkerModelId,reasoningEffort:e.reasoningEffort??void 0,clientMessageId:e.clientMessageId??e.id,attachments:e.attachments,externalChannel:e.externalChannel,replyTarget:e.replyTarget,waitForDispatch:!0}})}async isSessionBusy(e){const s=this.opts.getRuntime().sessions.get(e);if(!s)return!1;if(s.currentRunId)return!0;if(!s.adapter.getStatus)return!1;const t=await s.adapter.getStatus().catch(()=>null);return t?.active?(t.runId&&(s.currentRunId=t.runId,s.currentRunPhase=t.runPhase??s.currentRunPhase),!0):!1}broadcast(e){this.opts.getRuntime().client.sendEvent({type:"event",event:"session.queue.update",payload:{queue:this.getSnapshot(e)}})}}function j(n){const e=new Set,s=[];for(const t of n){const i=k(t);e.has(i)||(e.add(i),s.push(t))}return s}function z(n,e){const s=q(e);if(s)return n.find(i=>q(i)===s)??null;if(e.origin!=="external")return null;const t=k(e);return n.find(i=>k(i)===t)??null}function k(n){const e=q(n);return e?`id:${e}`:["body",O(n.text),...(n.attachments??[]).map(s=>s.path||`${s.name}:${s.mimeType}`)].join(`
|
|
5
|
+
`)}function q(n){const e=typeof n.clientMessageId=="string"?n.clientMessageId.trim():"";if(e)return e;const s=typeof n.id=="string"?n.id.trim():"";return s&&!s.startsWith("queue-")?s:""}function F(n){const e=new Set,s=[];for(const t of n){const i=t.path||`${t.name}:${t.mimeType}`;e.has(i)||(e.add(i),s.push(t))}return s.length?s:void 0}function O(n){return String(n||"").replace(/\s+/g," ").trim()}export{Y as ChatQueueManager};
|
|
@@ -19,6 +19,9 @@ export type LocalSessionRecord = {
|
|
|
19
19
|
updatedAt: string;
|
|
20
20
|
lastActivityAt: string;
|
|
21
21
|
lastMessagePreview?: string | null;
|
|
22
|
+
localReady: boolean;
|
|
23
|
+
firstUserMessageId: string | null;
|
|
24
|
+
firstUserBodyRevision: number | null;
|
|
22
25
|
bodyRevision: number;
|
|
23
26
|
indexRevision: number;
|
|
24
27
|
title: string;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import
|
|
2
|
-
`,"utf8"),r.fsyncSync(s),r.closeSync(s),s=void 0,r.renameSync(n,t),process.platform!=="win32"){const o=r.openSync(i,"r");try{r.fsyncSync(o)}finally{r.closeSync(o)}}}finally{s!==void 0&&r.closeSync(s);try{r.unlinkSync(n)}catch{}}}export{C as PERSONAL_SYNC_V1_ROOT_NAME,z as acknowledgeSessionIndexUpdate,Q as appendMessage,K as applyGeneratedSessionTitle,H as claimSessionTitleGenerationCandidates,ne as getCanonicalSessionStore,d as getDaemonInstallationId,Z as getMessageDeliveryStatus,Y as listPendingSessionIndexUpdates,
|
|
1
|
+
import A from"node:crypto";import r from"node:fs";import y from"node:path";import{SESSION_SYNC_PROTOCOL_VERSION as k,SESSION_TITLE_SOURCE_PRIORITY as m,sessionPreviewFromPayload as b}from"@shennian/wire";import{PERSONAL_SYNC_V1_ROOT_NAME as C,resolvePersonalSyncV1Path as O}from"../personal-sync/paths.js";import{CanonicalSessionStore as E}from"./canonical-store.js";import{getDaemonInstallationId as d}from"../personal-sync/identity.js";import{NativeSourceDeletionStore as U}from"../native-fusion/native-source-deletions.js";let S=null,x=null;function I(){return O()}function a(){const t=y.join(I(),"canonical");return(!S||x!==t)&&(S=new E(t,d()),x=t),S}function p(){return y.join(I(),"session-index.json")}function f(){const t=p();if(!r.existsSync(t))return{};const e=JSON.parse(r.readFileSync(t,"utf8"));if(!e||typeof e!="object"||Array.isArray(e))throw new Error(`invalid personal session index: ${t}`);const i=d();for(const n of Object.values(e))if(n.daemonInstallationId!==i)throw new Error(`personal session index belongs to another daemon installation: ${t}`);return e}function g(t){P(p(),t)}function B(t){return b(t.payload,120)}function v(t){if(new U({rootDir:I(),daemonInstallationId:d()}).hasSession(t))throw new Error(`session_deleted:${t}`)}function D(t){v(t.sessionId),d();const e=f(),i=e[t.sessionId],n=new Date().toISOString(),s=a().getManifest(t.sessionId)?.bodyRevision??i?.bodyRevision??0,o=a().getManifest(t.sessionId),l=h(i,t),c={daemonInstallationId:d(),sessionId:t.sessionId,agentType:t.agentType,sessionMode:t.sessionMode??i?.sessionMode,managerConfig:t.managerConfig??i?.managerConfig??null,workDir:t.workDir,agentSessionId:t.agentSessionId??i?.agentSessionId??null,modelId:t.modelId??i?.modelId??null,managerDefaultWorkerAgentType:t.managerDefaultWorkerAgentType??i?.managerDefaultWorkerAgentType??null,managerDefaultWorkerModelId:t.managerDefaultWorkerModelId??i?.managerDefaultWorkerModelId??null,status:t.status??i?.status??"active",createdAt:i?.createdAt??n,updatedAt:n,lastActivityAt:t.lastActivityAt??i?.lastActivityAt??n,lastMessagePreview:t.lastMessagePreview??i?.lastMessagePreview??null,localReady:i?.localReady===!0,firstUserMessageId:i?.firstUserMessageId??null,firstUserBodyRevision:i?.firstUserBodyRevision??null,bodyRevision:s,indexRevision:(i?.indexRevision??0)+1,...l,firstAvailableSeq:o?.firstAvailableSeq??i?.firstAvailableSeq??null,visibleMessageCount:o?.visibleMessageCount??i?.visibleMessageCount??0,lastVisibleMessageId:o?.lastVisibleMessageId??i?.lastVisibleMessageId??null,lastBodyCommittedAt:o?.lastBodyCommittedAt??i?.lastBodyCommittedAt??null,deletionRevision:i?.deletionRevision??0,deletedAt:t.deletedAt??i?.deletedAt??null,syncedIndexRevision:i?.syncedIndexRevision??0,titleGenerationAttemptedAt:i?.titleGenerationAttemptedAt??null};return e[t.sessionId]=c,g(e),c}function _(){return Object.values(f())}function F(t){if(!t)throw new Error("sessionId is required");const e=f();e[t]&&(delete e[t],g(e))}function J(t){a().purgeSession(t)}function Y(){const t=d();return _().filter(e=>e.indexRevision>e.syncedIndexRevision&&e.localReady&&!!e.firstUserMessageId&&e.firstUserBodyRevision!=null).sort((e,i)=>e.indexRevision-i.indexRevision).map(e=>({protocolVersion:k,daemonInstallationId:t,session:{id:e.sessionId,agentType:e.agentType,sessionMode:e.sessionMode,managerConfig:e.managerConfig,agentSessionId:e.agentSessionId??null,modelId:e.modelId??null,managerDefaultWorkerAgentType:e.managerDefaultWorkerAgentType??null,managerDefaultWorkerModelId:e.managerDefaultWorkerModelId??null,title:e.title,titleSource:e.titleSource,titleRevision:e.titleRevision,titleLockedByUser:e.titleLockedByUser,titleOriginEventId:e.titleOriginEventId,status:e.status??"active",workDir:e.workDir,lastMessagePreview:e.lastMessagePreview??null,bodyStorageMode:"machine_local",localReady:!0,firstUserBoundary:{role:"user",messageId:e.firstUserMessageId,bodyRevision:e.firstUserBodyRevision},bodyRevision:e.bodyRevision,indexRevision:e.indexRevision,firstAvailableSeq:e.firstAvailableSeq,visibleMessageCount:e.visibleMessageCount,lastVisibleMessageId:e.lastVisibleMessageId,lastBodyCommittedAt:e.lastBodyCommittedAt,deletionRevision:e.deletionRevision,lastActivityAt:e.lastActivityAt,createdAt:e.createdAt,updatedAt:e.updatedAt,deletedAt:e.deletedAt}}))}function z(t,e){const i=f(),n=i[t];if(!(!n||e<=n.syncedIndexRevision)){if(e>n.indexRevision)throw new Error(`cannot acknowledge future index revision ${e} for ${t}`);i[t]={...n,syncedIndexRevision:e},g(i)}}const T=2*6e4;function H(t=Date.now(),e=T){const i=f(),n=[],s=new Date(t).toISOString();for(const o of Object.values(i)){if(o.titleSource!=="first_user_fallback"||o.titleLockedByUser||o.titleGenerationAttemptedAt||!o.title.trim())continue;const l=o.status==="completed"||o.status==="failed",c=o.visibleMessageCount>=2;let u=null;if(o.agentType==="claude"&&c?u="agent_native_unavailable":l?u="terminal":c&&t-Date.parse(o.createdAt)>=e&&(u="grace_elapsed"),!u)continue;const R=b(o.title,240);if(!R)continue;const w=A.randomUUID();i[o.sessionId]={...o,titleGenerationAttemptedAt:s},n.push({sessionId:o.sessionId,requestId:w,titleSeed:R,baseTitleRevision:o.titleRevision,eligibility:u})}return n.length>0&&g(i),n}function K(t,e){const n=f()[t];return!n||n.titleLockedByUser||m[n.titleSource]>=m.shennian_generated||e.titleRevision<=n.titleRevision?!1:(D({sessionId:t,agentType:n.agentType,sessionMode:n.sessionMode,managerConfig:n.managerConfig,workDir:n.workDir,agentSessionId:n.agentSessionId,modelId:n.modelId,status:n.status,title:e.title,titleSource:"shennian_generated",titleRevision:e.titleRevision,titleLockedByUser:!1,titleOriginEventId:e.titleOriginEventId}),!0)}function Q(t,e,i){v(t),d();const n=a().append(t,e,i);return M(t,e,n.bodyRevision),n.bodyRevision}function X(t,e,i){v(t),d();const n=a().upsert(t,e,i);return M(t,e,n.bodyRevision),n.bodyRevision}function Z(t,e){const i=a().getMessageState(t,e);return!i||i.tombstoned||!i.message||!i.deliveryState?{state:"not_found",sessionId:t,clientMessageId:e}:{state:i.deliveryState,sessionId:t,clientMessageId:e,messageId:i.message.id,deliveryState:i.deliveryState,bodyRevision:i.lastRevision,committedAt:new Date(i.message.ts).toISOString()}}function ee(t,e){v(t),d();const i=a().tombstone(t,e),n=f(),s=n[t];return s&&(n[t]={...s,bodyRevision:i.bodyRevision,indexRevision:s.indexRevision+1,updatedAt:new Date().toISOString()},g(n)),i.bodyRevision}function M(t,e,i){const n=f(),s=n[t];if(!s)return;const o=B(e),l=a().getManifest(t),c=e.role==="user"&&o&&!s.title?{title:o,titleSource:"first_user_fallback",titleRevision:s.titleRevision+1,titleLockedByUser:!1,titleOriginEventId:e.id}:null,u=e.role==="user"&&!s.localReady?{localReady:!0,firstUserMessageId:e.id,firstUserBodyRevision:i}:null;n[t]={...s,...c??{},...u??{},bodyRevision:i,indexRevision:s.indexRevision+1,updatedAt:new Date().toISOString(),lastActivityAt:new Date(e.ts).toISOString(),lastMessagePreview:o??s.lastMessagePreview??null,firstAvailableSeq:l?.firstAvailableSeq??s.firstAvailableSeq,visibleMessageCount:l?.visibleMessageCount??s.visibleMessageCount,lastVisibleMessageId:l?.lastVisibleMessageId??s.lastVisibleMessageId,lastBodyCommittedAt:l?.lastBodyCommittedAt??s.lastBodyCommittedAt},g(n)}function h(t,e){const i={title:t?.title??"",titleSource:t?.titleSource??"first_user_fallback",titleRevision:t?.titleRevision??0,titleLockedByUser:t?.titleLockedByUser??!1,titleOriginEventId:t?.titleOriginEventId??null},n=e.title?.trim()??"";if(!n)return i;if(!e.titleSource)throw new Error("titleSource is required with title");const s=e.titleSource==="shennian_manual";if(e.titleLockedByUser!==void 0&&e.titleLockedByUser!==s)throw new Error("titleLockedByUser conflicts with titleSource");const o=n===i.title&&e.titleSource===i.titleSource,l=e.titleRevision??i.titleRevision+(o?0:1);if(!Number.isSafeInteger(l)||l<0)throw new Error("invalid titleRevision");const c=m[e.titleSource],u=m[i.titleSource];return c<u||l<i.titleRevision||l===i.titleRevision&&!o?i:{title:n,titleSource:e.titleSource,titleRevision:l,titleLockedByUser:s,titleOriginEventId:e.titleOriginEventId??i.titleOriginEventId}}function te(t,e){const i=e?.limit&&e.limit>0?Math.min(e.limit,500):500;let s=a().readRecent(t,i).messages;return e?.before!==void 0&&(s=s.filter(o=>o.ts<e.before)),[...s].sort((o,l)=>l.ts-o.ts)}function ie(){return a().listSessionIds()}function ne(){return a()}function P(t,e){const i=y.dirname(t);r.mkdirSync(i,{recursive:!0,mode:448});const n=`${t}.tmp-${process.pid}-${A.randomBytes(6).toString("hex")}`;let s;try{if(s=r.openSync(n,"wx",384),r.writeFileSync(s,`${JSON.stringify(e,null,2)}
|
|
2
|
+
`,"utf8"),r.fsyncSync(s),r.closeSync(s),s=void 0,r.renameSync(n,t),process.platform!=="win32"){const o=r.openSync(i,"r");try{r.fsyncSync(o)}finally{r.closeSync(o)}}}finally{s!==void 0&&r.closeSync(s);try{r.unlinkSync(n)}catch{}}}export{C as PERSONAL_SYNC_V1_ROOT_NAME,z as acknowledgeSessionIndexUpdate,Q as appendMessage,K as applyGeneratedSessionTitle,H as claimSessionTitleGenerationCandidates,ne as getCanonicalSessionStore,d as getDaemonInstallationId,Z as getMessageDeliveryStatus,Y as listPendingSessionIndexUpdates,_ as listSessionRecords,ie as listSessions,J as purgeCanonicalSession,F as purgeSessionRecord,te as readMessages,D as recordSession,ee as tombstoneMessage,X as upsertMessage};
|
|
@@ -3,13 +3,13 @@ import type { AgentType, ManagerConfig, SessionMode } from './session.ts';
|
|
|
3
3
|
export declare const SESSION_SYNC_PROTOCOL_VERSION: 1;
|
|
4
4
|
export type SessionSyncProtocolVersion = typeof SESSION_SYNC_PROTOCOL_VERSION;
|
|
5
5
|
export declare const SESSION_SYNC_RELEASE_GATE: {
|
|
6
|
-
readonly minCliVersion: "0.3.
|
|
6
|
+
readonly minCliVersion: "0.3.52";
|
|
7
7
|
readonly minAppBuild: {
|
|
8
8
|
readonly ios: 51;
|
|
9
9
|
readonly android: 12;
|
|
10
10
|
};
|
|
11
11
|
};
|
|
12
|
-
export declare const SESSION_SYNC_REQUIRED_CAPABILITIES: readonly ["session_index_v1", "session_body_revision_v1", "session_history_subscription_v1", "local_canonical_v1", "session_title_authority_v1", "session_title_seed_v1", "session_tool_detail_v1", "voice_session_body_relay_v1", "native_source_tombstone_v1", "session_durable_send_v1", "daemon_installation_identity_v1"];
|
|
12
|
+
export declare const SESSION_SYNC_REQUIRED_CAPABILITIES: readonly ["session_index_v1", "session_body_revision_v1", "session_history_subscription_v1", "local_canonical_v1", "session_title_authority_v1", "session_title_seed_v1", "session_tool_detail_v1", "voice_session_body_relay_v1", "native_source_tombstone_v1", "session_durable_send_v1", "daemon_installation_identity_v1", "session_user_boundary_v1", "session_terminal_outbox_v1"];
|
|
13
13
|
export declare const SESSION_SYNC_EVENT_NAMES: readonly ["session.index.updated", "session.body.delta"];
|
|
14
14
|
export declare const SESSION_HISTORY_LIMITS: {
|
|
15
15
|
readonly defaultSnapshotMessages: 100;
|
|
@@ -201,6 +201,16 @@ export type DaemonSessionIndexProjection = {
|
|
|
201
201
|
workDir: string;
|
|
202
202
|
lastMessagePreview: string | null;
|
|
203
203
|
bodyStorageMode: SessionBodyStorageMode;
|
|
204
|
+
/**
|
|
205
|
+
* Set only after the daemon has durably committed the first canonical user
|
|
206
|
+
* message. A pre-user agent/tool projection is never publishable.
|
|
207
|
+
*/
|
|
208
|
+
localReady: true;
|
|
209
|
+
firstUserBoundary: {
|
|
210
|
+
role: 'user';
|
|
211
|
+
messageId: string;
|
|
212
|
+
bodyRevision: number;
|
|
213
|
+
};
|
|
204
214
|
bodyRevision: number;
|
|
205
215
|
indexRevision: number;
|
|
206
216
|
firstAvailableSeq: number | null;
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
// @test src/__tests__/session-sync.test.ts
|
|
3
3
|
export const SESSION_SYNC_PROTOCOL_VERSION = 1;
|
|
4
4
|
export const SESSION_SYNC_RELEASE_GATE = {
|
|
5
|
-
minCliVersion: '0.3.
|
|
5
|
+
minCliVersion: '0.3.52',
|
|
6
6
|
minAppBuild: { ios: 51, android: 12 },
|
|
7
7
|
};
|
|
8
8
|
export const SESSION_SYNC_REQUIRED_CAPABILITIES = [
|
|
@@ -17,6 +17,8 @@ export const SESSION_SYNC_REQUIRED_CAPABILITIES = [
|
|
|
17
17
|
'native_source_tombstone_v1',
|
|
18
18
|
'session_durable_send_v1',
|
|
19
19
|
'daemon_installation_identity_v1',
|
|
20
|
+
'session_user_boundary_v1',
|
|
21
|
+
'session_terminal_outbox_v1',
|
|
20
22
|
];
|
|
21
23
|
export const SESSION_SYNC_EVENT_NAMES = [
|
|
22
24
|
'session.index.updated',
|