@asaidimu/utils-workspace 2.1.1 → 3.0.0
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/index.d.mts +306 -112
- package/index.d.ts +306 -112
- package/index.js +1 -1
- package/index.mjs +1 -1
- package/package.json +2 -1
package/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e,t,s=require("uuid"),r=Object.create,n=Object.defineProperty,o=Object.getOwnPropertyDescriptor,i=Object.getOwnPropertyNames,a=Object.getPrototypeOf,c=Object.prototype.hasOwnProperty,d=(e,t,s)=>(s=null!=e?r(a(e)):{},((e,t,s,r)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let a of i(t))c.call(e,a)||a===s||n(e,a,{get:()=>t[a],enumerable:!(r=o(t,a))||r.enumerable});return e})(e&&e.__esModule?s:n(s,"default",{value:e,enumerable:!0}),e)),l=(e={"node_modules/@asaidimu/events/index.js"(e,t){var s,r=Object.defineProperty,n=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyNames,i=Object.prototype.hasOwnProperty,a={};((e,t)=>{for(var s in t)r(e,s,{get:t[s],enumerable:!0})})(a,{createEventBus:()=>c}),t.exports=(s=a,((e,t,s,a)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let c of o(t))i.call(e,c)||c===s||r(e,c,{get:()=>t[c],enumerable:!(a=n(t,c))||a.enumerable});return e})(r({},"__esModule",{value:!0}),s));var c=(e={async:!1,batchSize:1e3,batchDelay:16,errorHandler:e=>console.error("EventBus Error:",e),crossTab:!1,channelName:"event-bus-channel"})=>{const t=new Map;let s=[],r=0,n=0;const o=new Map,i=new Map;let a=null;e.crossTab&&"undefined"!=typeof BroadcastChannel?a=new BroadcastChannel(e.channelName):e.crossTab&&console.warn("BroadcastChannel is not supported in this browser. Cross-tab notifications are disabled.");const c=(e,t)=>{r++,n+=t,o.set(e,(o.get(e)||0)+1)},d=()=>{const t=s;s=[],t.forEach((({name:t,payload:s})=>{const r=performance.now();try{(i.get(t)||[]).forEach((e=>e(s)))}catch(r){e.errorHandler({...r,eventName:t,payload:s})}c(t,performance.now()-r)}))},l=(()=>{let t;return()=>{clearTimeout(t),t=setTimeout(d,e.batchDelay)}})(),u=e=>{const s=t.get(e);s?i.set(e,Array.from(s)):i.delete(e)};return a&&(a.onmessage=e=>{const{name:t,payload:s}=e.data;(i.get(t)||[]).forEach((e=>e(s)))}),{subscribe:(e,s)=>{t.has(e)||t.set(e,new Set);const r=t.get(e);return r.add(s),u(e),()=>{r.delete(s),0===r.size?(t.delete(e),i.delete(e)):u(e)}},emit:({name:t,payload:r})=>{if(e.async)return s.push({name:t,payload:r}),s.length>=e.batchSize?d():l(),void(a&&a.postMessage({name:t,payload:r}));const n=performance.now();try{(i.get(t)||[]).forEach((e=>e(r))),a&&a.postMessage({name:t,payload:r})}catch(s){e.errorHandler({...s,eventName:t,payload:r})}c(t,performance.now()-n)},getMetrics:()=>({totalEvents:r,activeSubscriptions:Array.from(t.values()).reduce(((e,t)=>e+t.size),0),eventCounts:o,averageEmitDuration:r>0?n/r:0}),clear:()=>{t.clear(),i.clear(),s=[],r=0,n=0,o.clear(),a&&(a.close(),a=null)}}}}},function(){return t||(0,e[i(e)[0]])((t={exports:{}}).exports,t),t.exports}),u=[{name:"role",version:"1.0.0",description:"AI persona with a system prompt and associated preference defaults.",fields:{name:{name:"name",type:"string",required:!0},label:{name:"label",type:"string",required:!0},description:{name:"description",type:"string",required:!1},persona:{name:"persona",type:"string",required:!0},preferences:{name:"preferences",type:"array",required:!1,itemsType:"string"}},indexes:[{name:"by_name",fields:["name"],type:"unique"},{name:"by_label",fields:["label"],type:"normal"}],constraints:[],migrations:[]},{name:"preference",version:"1.0.0",description:"A user behavioural instruction, scoped to zero or more topics.",fields:{id:{name:"id",type:"string",required:!0},content:{name:"content",type:"string",required:!0},topics:{name:"topics",type:"array",required:!1,itemsType:"string"},timestamp:{name:"timestamp",type:"string",required:!0}},indexes:[{name:"by_id",fields:["id"],type:"unique"},{name:"by_topics",fields:["topics"],type:"normal"},{name:"by_timestamp",fields:["timestamp"],type:"btree"}],constraints:[],migrations:[]},{name:"context",version:"1.0.0",description:"Injected background knowledge, scoped to topics. Content is a discriminated union.",fields:{key:{name:"key",type:"string",required:!0},topics:{name:"topics",type:"array",required:!1,itemsType:"string"},content:{name:"content",type:"record",required:!0},timestamp:{name:"timestamp",type:"string",required:!0},metadata:{name:"metadata",type:"record",required:!1}},indexes:[{name:"by_key",fields:["key"],type:"unique"},{name:"by_topics",fields:["topics"],type:"normal"},{name:"by_timestamp",fields:["timestamp"],type:"btree"}],constraints:[],migrations:[]},{name:"session",version:"1.0.0",description:"Session metadata. The head field tracks the current tip of the turn DAG.",fields:{id:{name:"id",type:"string",required:!0},label:{name:"label",type:"string",required:!0},role:{name:"role",type:"string",required:!0},topics:{name:"topics",type:"array",required:!1,itemsType:"string"},preferences:{name:"preferences",type:"array",required:!1,itemsType:"string"},metadata:{name:"metadata",type:"record",required:!1},flushedTurnCount:{name:"flushedTurnCount",type:"number",required:!0},head:{name:"head",type:"record",required:!1}},indexes:[{name:"by_id",fields:["id"],type:"unique"},{name:"by_role",fields:["role"],type:"normal"}],constraints:[],migrations:[]},{name:"turn",version:"1.0.0",description:["A single message in a session transcript, stored as a flat document.","The DAG is reconstructed in memory by TurnTree.buildNodeGraph() at session open time.","$id is a composite key: `${sessionId}:${id}:${version}`."].join(" "),fields:{id:{name:"id",type:"string",required:!0},sessionId:{name:"sessionId",type:"string",required:!0},version:{name:"version",type:"number",required:!0},role:{name:"role",type:"enum",required:!0,values:["user","assistant","tool"]},blocks:{name:"blocks",type:"array",required:!0},timestamp:{name:"timestamp",type:"string",required:!0},roleSnapshot:{name:"roleSnapshot",type:"string",required:!1},parent:{name:"parent",type:"record",required:!1}},indexes:[{name:"by_session",fields:["sessionId"],type:"normal"},{name:"by_session_parent",fields:["sessionId","parent"],type:"composite"},{name:"by_session_id_ver",fields:["sessionId","id","version"],type:"composite",unique:!0}],constraints:[],migrations:[]}],h=class e extends Error{constructor(t,s){super(t,{cause:s}),this.name="SyncError",Object.setPrototypeOf(this,e.prototype)}},p=class extends h{constructor(e){super(`[ArtifactContainer] Operation timed out: ${e}`)}},f=class{_locked=!1;_capacity;_yieldMode;waiters=[];constructor(e){this._capacity=e?.capacity??1/0,this._yieldMode=e?.yieldMode??"macrotask"}async lock(e){if(!this._locked)return void(this._locked=!0);if(this.waiters.length>=this._capacity)throw new Error(`Mutex queue is full (capacity: ${this._capacity})`);let t;const s=new Promise((e=>t=e));this.waiters.push(t),null!=e?await Promise.race([s,new Promise(((s,r)=>setTimeout((()=>{const e=this.waiters.indexOf(t);-1!==e&&this.waiters.splice(e,1),r(new p("Mutex lock timed out"))}),e)))]):await s}tryLock(){return!this._locked&&(this._locked=!0,!0)}unlock(){if(!this._locked)throw new Error("Mutex is not locked");const e=this.waiters.shift();e?"microtask"===this._yieldMode?queueMicrotask(e):setTimeout(e,0):this._locked=!1}locked(){return this._locked}pending(){return this.waiters.length}},m=class{mutex=new f({yieldMode:"microtask"});promise=null;_value=null;_error;_done=!1;retry;throws;constructor({retry:e,throws:t}={}){this.retry=Boolean(e),this.throws=Boolean(t)}async do(e,t){return this._done?this.peek():this.promise?this._awaitWithTimeout(this.promise,t,"Once do() timed out"):(await this.mutex.lock(),this.promise?(this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")):(this.promise=(async()=>{try{const t=await e();this._value=t,this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.promise=null}return this.peek()})(),this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")))}doSync(e){if(this._done){if(this.throws&&this._error)throw this._error;return this.peek()}if(this.promise){const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}if(!this.mutex.tryLock()){const e=new Error("Cannot execute doSync: lock is currently held.");if(this.throws)throw e;return{value:null,error:e}}if(this.promise||this._done){if(this.mutex.unlock(),this._done){if(this.throws&&this._error)throw this._error;return this.peek()}const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}try{const t=e();this._value=t,this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.mutex.unlock()}return this.peek()}isReady(){return this._done&&null===this.promise}running(){return null!==this.promise&&!this._done}peek(){return{value:this._value,error:this._error}}get(){if(!this._done)throw new Error("Once operation is not yet complete");if(this._error)throw this._error;return this._value}reset(){this._done=!1,this.promise=null,this._value=null,this._error=void 0}resolved(){return this.promise}done(){return this._done}_awaitWithTimeout(e,t,s="Operation timed out"){return null==t?e:Promise.race([e,new Promise(((e,r)=>setTimeout((()=>r(new p(s))),t)))])}};var y={ROLE:"role",PREFERENCE:"preference",CONTEXT:"context",SESSION:"session",TURN:"turn"};d(l());var b=Symbol.for("delete"),w=e=>Array.isArray(e)?[...e]:{...e};function g(){return b}d(l()),d(l()),d(l()),d(l()),d(l()),d(l());var v=function(e){const t=e?.deleteMarker||b;function s(e){if(null==e)return e;if(Array.isArray(e))return e.filter((e=>e!==t)).map((e=>"object"!=typeof e||null===e||Array.isArray(e)?e:s(e)));if("object"==typeof e){const r={};for(const[n,o]of Object.entries(e))if(o!==t)if("object"==typeof o&&null!==o){const e=s(o);void 0!==e&&(r[n]=e)}else r[n]=o;return r}return e===t?void 0:e}return function(e,r){if("object"!=typeof e||null===e)return"object"==typeof r&&null!==r?s(r):r===t?{}:r;if("object"!=typeof r||null===r)return e;const n=w(e),o=[{target:n,source:r}];for(;o.length>0;){const{target:e,source:s}=o.pop();for(const r of Object.keys(s)){const n=s[r];if(n!==t)if(Array.isArray(n))e[r]=n;else if("object"==typeof n&&null!==n){const t=r in e&&"object"==typeof e[r]&&null!==e[r]?e[r]:{};e[r]=w(t),o.push({target:e[r],source:n})}else e[r]=n;else delete e[r]}}return n}}({deleteMarker:b});function x(e){return{ok:!0,value:e}}function S(e){return{ok:!1,error:e}}function T(e){return Object.fromEntries(Object.entries(e).filter((([e,t])=>null!=t)))}var k=class{db;constructor(e){this.db=e}async turns(){return this.db.collection(y.TURN)}async sessions(){return this.db.collection(y.SESSION)}turnFilter(e,t,s){return{operator:"and",conditions:[{field:"sessionId",operator:"eq",value:e},{field:"id",operator:"eq",value:t},{field:"version",operator:"eq",value:s}]}}async getHead(e){const t=await this.sessions(),s=await t.find({field:"id",operator:"eq",value:e});return s?.head??null}async setHead(e,t){const s=await this.sessions(),r=await s.find({field:"id",operator:"eq",value:e});if(!r)return;const n={...r.state(),head:t??void 0};await r.update(n)}async append(e,t){const s=await this.getHead(e),r={...t,sessionId:e,version:t.version??0,parent:t.parent?t.parent:s?{id:s.id,version:s.version}:null},n=await this.turns();return await n.create(T(r)),r}async appendBatch(e,t,s){if(0!==t.length){for(const s of t)await this.append(e,s);await this.setHead(e,s)}}async replaceVersion(e,t){const s=await this.turns(),r=await s.find(this.turnFilter(e,t.id,t.version)),n=T(t);r?await r.update({...n,sessionId:e}):await s.create({...n,sessionId:e})}async branch(e,t){const s=await this.turns();await s.create(T({...t,sessionId:e})),await this.setHead(e,{id:t.id,version:t.version})}async loadAllTurns(e){const t=await this.turns();return(await t.filter({field:"sessionId",operator:"eq",value:e})).map((e=>e.state()))}async getActiveChain(e,t=[]){const s=await this.getHead(e);if(!s&&0===t.length)return[];const r=await this.loadAllTurns(e);return[...s?O(r,s):[],...t]}async buildNodeGraph(e,t=[]){const s=await this.loadAllTurns(e),r=await this.getHead(e),n=new Set;if(r)for(const e of O(s,r))n.add(`${e.id}:${e.version}`);const o={};for(const e of s){o[e.id]||(o[e.id]={id:e.id,versions:{},activeVersion:e.version,role:e.role,blocks:e.blocks,timestamp:e.timestamp,roleSnapshot:e.roleSnapshot,parent:e.parent,children:{}});const t=o[e.id];t.versions[e.version]=e,n.has(`${e.id}:${e.version}`)&&(e.version>=t.activeVersion||!n.has(`${e.id}:${t.activeVersion}`))&&(t.activeVersion=e.version,t.blocks=e.blocks,t.timestamp=e.timestamp,t.roleSnapshot=e.roleSnapshot,t.parent=e.parent)}for(const e of Object.values(o))if(e.parent){const t=o[e.parent.id];if(t){const s=e.parent.version;t.children[s]||(t.children[s]=[]),t.children[s].includes(e.id)||t.children[s].push(e.id)}}for(const e of t)if(o[e.id]){const t=o[e.id];if(t.versions[e.version]=e,e.version>t.activeVersion&&(t.activeVersion=e.version,t.blocks=e.blocks,t.timestamp=e.timestamp,t.roleSnapshot=e.roleSnapshot),e.parent){const t=o[e.parent.id];if(t){const s=e.parent.version;t.children[s]||(t.children[s]=[]),t.children[s].includes(e.id)||t.children[s].push(e.id)}}}else if(o[e.id]={id:e.id,versions:{[e.version]:e},activeVersion:e.version,role:e.role,blocks:e.blocks,timestamp:e.timestamp,roleSnapshot:e.roleSnapshot,parent:e.parent,children:{}},e.parent){const t=o[e.parent.id];if(t){const s=e.parent.version;t.children[s]||(t.children[s]=[]),t.children[s].includes(e.id)||t.children[s].push(e.id)}}return o}async deleteSubtree(e,t,s,r){const n=function(e,t,s){const r=new Map;for(const t of e)if(t.parent){const e=`${t.parent.id}:${t.parent.version}`;let s=r.get(e);s||(s=new Set,r.set(e,s)),s.add(`${t.id}:${t.version}`)}const n=new Set,o=[`${t}:${s}`];for(;o.length>0;){const e=o.pop();n.add(e);const t=r.get(e);if(t)for(const e of t)n.has(e)||o.push(e)}return n}(await this.loadAllTurns(e),t,s),o=await this.turns();await Promise.all(Array.from(n).map((async t=>{const[s,r]=t.split(":"),n=await o.find(this.turnFilter(e,s,Number(r)));n&&await n.delete()}))),await this.setHead(e,r)}async copyTranscript(e,t){const s=await this.getHead(e),r=await this.loadAllTurns(e),n=s?O(r,s):[],o=await this.turns();for(const e of n)await o.create(T({...e,sessionId:t}));await this.setHead(t,s?{...s}:null)}};function O(e,t){const s=new Map;for(const t of e)s.set(`${t.id}:${t.version}`,t);const r=[];let n=t;for(;n;){const e=s.get(`${n.id}:${n.version}`);if(!e)break;r.push(e),n=e.parent}return r.reverse()}async function C(e){const t=await crypto.subtle.digest("SHA-256",e);return Array.from(new Uint8Array(t)).map((e=>e.toString(16).padStart(2,"0"))).join("")}var N=class{storage;config;recordCache=new Map;onRegistryChanged;constructor(e,t={}){this.storage=e,this.config={eagerEviction:t.eagerEviction??!1}}async init(){const e=await this.storage.listRecords();for(const t of e)this.recordCache.set(t.sha256,t)}async register(e,t,s){try{const r=await C(e),n=(new Date).toISOString(),o=this.recordCache.get(r);if(o){const e={...o,refCount:o.refCount+1,lastUsedAt:n};await this.storage.saveRecord(e),this.recordCache.set(r,e),this.onRegistryChanged?.(r,e)}else{const o={sha256:r,mediaType:t,sizeBytes:e.byteLength,filename:s,refCount:1,remoteIds:{},createdAt:n,lastUsedAt:n};"function"==typeof this.storage.registerBlob?await this.storage.registerBlob(o,e):(await this.storage.storeBytes(r,e),await this.storage.saveRecord(o)),this.recordCache.set(r,o),this.onRegistryChanged?.(r,o)}const i=this.recordCache.get(r);return x({sha256:r,mediaType:t,sizeBytes:i.sizeBytes,filename:i.filename,previewUrl:i.previewUrl})}catch(e){return S({code:"BLOB_ERROR",reason:e instanceof Error?e.message:String(e)})}}async retain(e){const t=this.recordCache.get(e);if(!t)return S({code:"NOT_FOUND",resource:"blob",id:e});const s={...t,refCount:t.refCount+1,lastUsedAt:(new Date).toISOString()};return await this.storage.saveRecord(s),this.recordCache.set(e,s),this.onRegistryChanged?.(e,s),x(void 0)}async release(e){const t=this.recordCache.get(e);if(!t)return S({code:"NOT_FOUND",resource:"blob",id:e});const s=Math.max(0,t.refCount-1),r={...t,refCount:s,lastUsedAt:(new Date).toISOString()};return 0===s&&this.config.eagerEviction?(await this.storage.deleteBytes(e),await this.storage.deleteRecord(e),this.recordCache.delete(e),this.onRegistryChanged?.(e,null)):(await this.storage.saveRecord(r),this.recordCache.set(e,r),this.onRegistryChanged?.(e,r)),x(void 0)}async recordRemoteId(e,t,s){const r=this.recordCache.get(e);if(!r)return S({code:"NOT_FOUND",resource:"blob",id:e});if(r.remoteIds[t]===s)return x(void 0);const n={...r,remoteIds:{...r.remoteIds,[t]:s}};return await this.storage.saveRecord(n),this.recordCache.set(e,n),x(void 0)}getRemoteId(e,t){return this.recordCache.get(e)?.remoteIds[t]??null}async resolveRef(e,t){try{if(t){const s=this.getRemoteId(e.sha256,t);if(s)return x({kind:"remote",sha256:e.sha256,mediaType:e.mediaType,fileId:s,providerId:t})}const s=await this.storage.loadBytes(e.sha256);return s?x({kind:"inline",sha256:e.sha256,mediaType:e.mediaType,data:s}):S({code:"BLOB_ERROR",reason:`Blob bytes not found locally for sha256=${e.sha256}. The blob may have been evicted. Re-register it before resolving.`})}catch(e){return S({code:"BLOB_ERROR",reason:e instanceof Error?e.message:String(e)})}}async resolveRefs(e,t){const s=function(e){const t=new Set,s=[];for(const r of e)t.has(r.sha256)||(t.add(r.sha256),s.push(r));return s}(e),r=await Promise.all(s.map((async e=>({ref:e,result:await this.resolveRef(e,t)})))),n=new Map,o=[];for(const{ref:e,result:t}of r)t.ok?n.set(e.sha256,t.value):o.push({ref:e,error:t.error});return{resolved:n,errors:o}}async gc(){const e=Array.from(this.recordCache.values()).filter((e=>0===e.refCount));return await Promise.all(e.map((e=>this.storage.deleteBytes(e.sha256)))),e.length}async gcFull(){const e=Array.from(this.recordCache.values()).filter((e=>0===e.refCount));return await Promise.all(e.map((async e=>{await this.storage.deleteBytes(e.sha256),await this.storage.deleteRecord(e.sha256),this.recordCache.delete(e.sha256),this.onRegistryChanged?.(e.sha256,null)}))),e.length}async purge(e){return this.recordCache.has(e)?(await this.storage.deleteBytes(e),await this.storage.deleteRecord(e),this.recordCache.delete(e),this.onRegistryChanged?.(e,null),x(void 0)):S({code:"NOT_FOUND",resource:"blob",id:e})}getRecord(e){return this.recordCache.get(e)??null}getAllRecords(){const e={};for(const[t,s]of this.recordCache)e[t]=s;return e}};var _=10,B=50,I=20,R=class{map=new Map;max;constructor(e){this.max=e}get(e){if(!this.map.has(e))return;const t=this.map.get(e);return this.map.delete(e),this.map.set(e,t),t}set(e,t){if(this.map.has(e)&&this.map.delete(e),this.map.set(e,t),this.map.size>this.max){const e=this.map.keys().next().value;void 0!==e&&this.map.delete(e)}}has(e){return this.map.has(e)}delete(e){this.map.delete(e)}};function E({index:e},t){switch(t.type){case"role:add":{const s=t.payload;if(e.roles[s.name])return S({code:"DUPLICATE_KEY",resource:"role",key:s.name});const r={name:s.name,label:s.label,description:s.description,preferences:s.preferences.length};return x({index:{roles:{[s.name]:r}}})}case"role:update":{const{name:s,...r}=t.payload;if(!e.roles[s])return S({code:"NOT_FOUND",resource:"role",id:s});const n=e.roles[s],o={...n,...r,preferences:r.preferences?.length??n.preferences};return x({index:{roles:{[s]:o}}})}case"role:delete":{const{name:s}=t.payload;if(!e.roles[s])return S({code:"NOT_FOUND",resource:"role",id:s});return Object.values(e.sessions).some((e=>e.role===s))?S({code:"INVALID_COMMAND",reason:`Cannot delete role "${s}" — it is still referenced by one or more sessions`}):x({index:{roles:{[s]:g()}}})}case"preference:add":{const s=t.payload,r={id:s.id,topics:s.topics,timestamp:s.timestamp,snippet:s.content.substring(0,100)},n={};return s.topics.forEach((r=>{const o=e.topics[r];n[r]={topic:r,contextKeys:o?.contextKeys??[],preferences:[...o?.preferences??[],s.id],metadata:{created:o?.metadata?.created??t.timestamp,updated:t.timestamp,entries:o?.metadata?.entries??0}}})),x({index:{preferences:{[s.id]:r},topics:n}})}case"preference:update":{const{id:s,...r}=t.payload;if(!e.preferences[s])return S({code:"NOT_FOUND",resource:"preference",id:s});const n=e.preferences[s],o={...n,...r,snippet:r.content?r.content.substring(0,100):n.snippet},i={};return r.topics&&(n.topics.forEach((t=>{const r=e.topics[t];r&&(i[t]={preferences:r.preferences.filter((e=>e!==s))})})),r.topics.forEach((r=>{const n=e.topics[r]??{topic:r,contextKeys:[],preferences:[],metadata:{created:t.timestamp,updated:t.timestamp,entries:0}};i[r]={...n,preferences:[...new Set([...n.preferences,s])],metadata:{updated:t.timestamp}}}))),x({index:{preferences:{[s]:o},topics:i}})}case"preference:delete":{const{id:s}=t.payload;if(!e.preferences[s])return S({code:"NOT_FOUND",resource:"preference",id:s});const r=e.preferences[s],n={};return r.topics.forEach((t=>{const r=e.topics[t];r&&(n[t]={preferences:r.preferences.filter((e=>e!==s))})})),x({index:{preferences:{[s]:g()},topics:n}})}case"context:add":{const s=t.payload;if(e.context[s.key])return S({code:"DUPLICATE_KEY",resource:"context",key:s.key});const r=s.content,n={key:s.key,topics:s.topics,timestamp:s.timestamp,source:s.key.split(":")[0],preview:"text"===r.kind?r.value.substring(0,200):"json"===r.kind?JSON.stringify(r.value).substring(0,200):void 0,metadata:s.metadata},o={};return s.topics.forEach((r=>{const n=e.topics[r],i=n?.contextKeys??[],a=i.includes(s.key)?i:[...i,s.key];o[r]={topic:r,contextKeys:a,preferences:n?.preferences??[],metadata:{updated:t.timestamp,entries:a.length}}})),x({index:{context:{[s.key]:n},topics:o}})}case"context:update":{const{key:s,...r}=t.payload;if(!e.context[s])return S({code:"NOT_FOUND",resource:"context",id:s});const n=e.context[s],o=r.content,i={...n,...r,preview:o?"text"===o.kind?o.value.substring(0,200):"json"===o.kind?JSON.stringify(o.value).substring(0,200):void 0:n.preview},a={};return r.topics&&(n.topics.forEach((t=>{const r=e.topics[t];r&&(a[t]={contextKeys:r.contextKeys.filter((e=>e!==s))})})),r.topics.forEach((r=>{const n=e.topics[r]??{contextKeys:[]},o=n.contextKeys.includes(s)?n.contextKeys:[...n.contextKeys,s];a[r]={contextKeys:o,metadata:{updated:t.timestamp,entries:o.length}}}))),x({index:{context:{[s]:i},topics:a}})}case"context:delete":{const{key:s}=t.payload;if(!e.context[s])return S({code:"NOT_FOUND",resource:"context",id:s});const r=e.context[s],n={};return r.topics.forEach((r=>{const o=e.topics[r];o&&(n[r]={contextKeys:o.contextKeys.filter((e=>e!==s)),metadata:{updated:t.timestamp,entries:o.contextKeys.length-1}})})),x({index:{context:{[s]:g()},topics:n}})}case"session:create":{const{id:s,label:r,role:n,topics:o,preferences:i=[]}=t.payload;if(e.sessions[s])return S({code:"DUPLICATE_KEY",resource:"session",key:s});if(!e.roles[n])return S({code:"NOT_FOUND",resource:"role",id:n});const a={id:s,label:r,role:n,topics:o,preferences:i,metadata:{created:t.timestamp,updated:t.timestamp},flushedTurnCount:0,head:null};return x({index:{sessions:{[s]:a}}})}case"session:role:switch":{const{sessionId:s,role:r}=t.payload;return e.sessions[s]?x({index:{sessions:{[s]:{role:r,metadata:{updated:t.timestamp}}}}}):S({code:"NOT_FOUND",resource:"session",id:s})}case"session:topics:add":{const{sessionId:s,topics:r}=t.payload;if(!e.sessions[s])return S({code:"NOT_FOUND",resource:"session",id:s});const n=e.sessions[s],o=[...new Set([...n.topics,...r])];return x({index:{sessions:{[s]:{topics:o,metadata:{updated:t.timestamp}}}}})}case"session:preferences:override":{const{sessionId:s,preferences:r}=t.payload;return e.sessions[s]?x({index:{sessions:{[s]:{preferences:r,metadata:{updated:t.timestamp}}}}}):S({code:"NOT_FOUND",resource:"session",id:s})}case"session:fork":{const{sourceSessionId:s,newSessionId:r,label:n,role:o,topics:i}=t.payload;if(!e.sessions[s])return S({code:"NOT_FOUND",resource:"session",id:s});if(e.sessions[r])return S({code:"DUPLICATE_KEY",resource:"session",key:r});const a=e.sessions[s],c={id:r,label:n,role:o??a.role,topics:i??[...a.topics],preferences:[...a.preferences],metadata:{created:t.timestamp,updated:t.timestamp},flushedTurnCount:a.flushedTurnCount,head:a.head};return x({index:{sessions:{[r]:c}}})}case"session:delete":{const{sessionId:s}=t.payload;return e.sessions[s]?x({index:{sessions:{[s]:g()}}}):S({code:"NOT_FOUND",resource:"session",id:s})}case"turn:add":{const{sessionId:s,turn:r}=t.payload;return e.sessions[s]?x({index:{sessions:{[s]:{head:{id:r.id,version:r.version},metadata:{updated:t.timestamp},flushedTurnCount:(e.sessions[s]?.flushedTurnCount??0)+1}}}}):S({code:"NOT_FOUND",resource:"session",id:s})}case"turn:edit":{const{sessionId:s,turnId:r,newVersion:n}=t.payload;return e.sessions[s]?x({index:{sessions:{[s]:{head:{id:r,version:n},metadata:{updated:t.timestamp}}}}}):S({code:"NOT_FOUND",resource:"session",id:s})}case"turn:branch":{const{sessionId:s,newTurn:r}=t.payload;return e.sessions[s]?x({index:{sessions:{[s]:{head:{id:r.id,version:r.version},metadata:{updated:t.timestamp}}}}}):S({code:"NOT_FOUND",resource:"session",id:s})}case"turn:delete":{const{sessionId:s,newHead:r}=t.payload;return e.sessions[s]?x({index:{sessions:{[s]:{head:r,metadata:{updated:t.timestamp}}}}}):S({code:"NOT_FOUND",resource:"session",id:s})}case"blob:register":default:return x({});case"blob:retain":{const{sha256:s}=t.payload;return e.blobs[s]?x({}):S({code:"NOT_FOUND",resource:"blob",id:s})}case"blob:release":{const{sha256:s}=t.payload;return e.blobs[s]?x({}):S({code:"NOT_FOUND",resource:"blob",id:s})}case"blob:purge":{const{sha256:s}=t.payload;return e.blobs[s]?x({}):S({code:"NOT_FOUND",resource:"blob",id:s})}case"blob:record_remote_id":{const{sha256:s}=t.payload;return e.blobs[s]?x({}):S({code:"NOT_FOUND",resource:"blob",id:s})}}}function D(e){return Math.ceil(e.length/4)}function j(e,t){return Math.ceil(e/1024*t)}function U(e){if("text"===e.kind)return e.value;if("json"===e.kind){const t=[],s=e=>{"string"==typeof e?t.push(e):e&&"object"==typeof e&&Object.values(e).forEach(s)};return s(e.value),t.join(" ")}return""}function A(e,t){return{id:crypto.randomUUID(),version:0,role:e,blocks:t,timestamp:(new Date).toISOString(),parent:null}}var M=class{rank(e){const{entries:t,recentMessages:s,config:r}=e,n=r.recentMessageWindow??3,o=r.minScore??0,i=r.freshnessHalfLifeDays??30;if(0===s.length)return[...t].sort(((e,t)=>this.freshnessWeight(t.timestamp,i)-this.freshnessWeight(e.timestamp,i)));const a=this.tokenize(s.slice(-n).join(" "));return t.map((e=>{const t=U(e.content);return{entry:e,score:.7*this.jaccardSimilarity(a,this.tokenize(t))+.3*this.freshnessWeight(e.timestamp,i)}})).filter((e=>e.score>o)).sort(((e,t)=>t.score-e.score)).map((e=>e.entry))}tokenize(e){return new Set(e.toLowerCase().replace(/[^\w\s]/g," ").split(/\s+/).filter((e=>e.length>2)))}jaccardSimilarity(e,t){if(0===e.size&&0===t.size)return 0;let s=0;for(const r of e)t.has(r)&&s++;const r=e.size+t.size-s;return 0===r?0:s/r}freshnessWeight(e,t){const s=(Date.now()-new Date(e).getTime())/864e5;return Math.pow(.5,s/t)}},F=class{plan(e){const{systemInstructions:t,persona:s,preferences:r,context:n,transcript:o,budget:i}=e;if(!i)return{preferences:r,context:n,transcript:o,truncated:{preferences:0,interactions:0,context:0},breakdown:{system:0,persona:0,preferences:0,transcript:0,context:0},totalUsed:0,lastRoleBeforeTruncation:null};const a=i.estimator??D,c=i.blobTokensPerKB??.25;let d=i.total;const l={system:0,persona:0,preferences:0,transcript:0,context:0},u=a(t??""),h=a(s);d-=u+h,l.system+=u,l.persona+=h;const p=[];let f=0;for(const e of r){const t=a(e.content);d>=t?(d-=t,l.preferences+=t,p.push(e)):f++}const m=[];let y=0,b=null;for(let e=o.length-1;e>=0;e--){const t=o[e],s=this.estimateTurnTokens(t,a,c);d>=s?(d-=s,l.transcript+=s,m.unshift(t)):(y++,"user"!==t.role||b||(b=t.roleSnapshot??null))}const w=[];let g=0;for(const e of n){let t=a(U(e.content));"blob"===e.content.kind&&(t+=j(e.content.sizeBytes,c)),d>=t?(d-=t,l.context+=t,w.push(e)):g++}return{preferences:p,context:w,transcript:m,truncated:{preferences:f,interactions:y,context:g},breakdown:l,totalUsed:i.total-Math.max(0,d),lastRoleBeforeTruncation:b}}estimateTurnTokens(e,t,s){return e.blocks.reduce(((e,r)=>{switch(r.type){case"text":return e+t(r.text);case"tool_use":return e+t(JSON.stringify(r.input));case"tool_result":return e+t("string"==typeof r.content?r.content:JSON.stringify(r.content));case"thinking":return e+t(r.thinking);case"image":case"document":{const t=r.ref;return t?e+j(t.sizeBytes,s):e}default:return e}}),0)}},q=class{assemble(e){const{session:t,plan:s,resolvedBlobs:r,summaryBlockText:n,warnings:o,conflicts:i,budgetTotal:a}=e,c=[],d=[];for(const e of s.context)if("text"===e.content.kind||"json"===e.content.kind)c.push(e);else if("blob"===e.content.kind){const t=r.get(e.content.sha256);t&&d.push(this.buildReferentialBlock(e.content,t))}const l=[];if(d.length>0&&l.push(A("user",d)),n||s.truncated.interactions>0){const e=[];n&&e.push({type:"summary",text:n}),s.truncated.interactions>0&&e.push({type:"text",text:`[${s.truncated.interactions} earlier turn(s) omitted due to token budget]`}),l.push(A("user",e)),l.push(A("assistant",[{type:"text",text:"Understood."}]))}let u=s.lastRoleBeforeTruncation,h=null!==s.lastRoleBeforeTruncation;for(const e of s.transcript){const t=this.resolveTurnBlocks(e,r);"user"===e.role&&e.roleSnapshot&&h&&e.roleSnapshot!==u&&t.unshift({type:"role_transition",previousRole:u,newRole:e.roleSnapshot}),"user"===e.role&&(u=e.roleSnapshot??null,h=!0),l.push({...e,blocks:t})}return{system:{instructions:t.instructions,persona:t.role.persona,preferences:s.preferences,context:c},context:s.context,transcript:{turns:l},budget:{total:a,used:s.totalUsed,breakdown:s.breakdown},truncated:s.truncated,warnings:o,conflicts:i}}buildReferentialBlock(e,t){return e.mediaType.startsWith("image/")?{type:"image",blob:t}:{type:"document",blob:t,title:e.filename}}resolveTurnBlocks(e,t){return e.blocks.map((e=>{if("image"===e.type||"document"===e.type){const s=e.ref;if(s){const r=t.get(s.sha256);if(r)return{...e,blob:r}}}return e}))}},P={maxBufferSize:10,flushIntervalMs:3e4},$=class{sessionId;nodes;head;dirtyBuffer=[];flushTimer=null;flushChain=Promise.resolve();flushConfig;tree;contentStore;constructor(e,t,s,r,n,o=P){this.sessionId=e,this.nodes=t,this.head=s,this.tree=r,this.contentStore=n,this.flushConfig=o}activeChain(){if(!this.head)return[];const e=[];let t=this.head.id;for(;null!==t;){const s=this.nodes[t];if(!s)break;e.push(s),t=s.parent?.id??null}return e.reverse()}siblings(e){const t=this.nodes[e];if(!t)return[];if(!t.parent)return Object.values(this.nodes).filter((e=>null===e.parent));const s=this.nodes[t.parent.id];if(!s)return[t];const r=t.parent.version,n=s.children[r];return n?n.map((e=>this.nodes[e])).filter((e=>void 0!==e)):[t]}branchInfo(e){const t=this.nodes[e];if(!t)return{versions:[],currentIndex:-1,total:0,hasPrev:!1,hasNext:!1};const s=Object.keys(t.versions).map(Number).sort(((e,t)=>e-t)),r=s.indexOf(t.activeVersion);return{versions:s,currentIndex:r,total:s.length,hasPrev:r>0,hasNext:r<s.length-1}}async addTurn(e,t){const s=e.index.sessions[this.sessionId];if(!s)return S({code:"NOT_FOUND",resource:"session",id:this.sessionId});const r={...t,version:t.version??0,parent:null!==t.parent?t.parent:null!==this.head?{id:this.head.id,version:this.head.version}:null};return this.upsertNode(r),this.head={id:r.id,version:r.version},this.dirtyBuffer.push(r),this.scheduleFlush(),this.dirtyBuffer.length>=this.flushConfig.maxBufferSize&&await this.flush(),x({index:{sessions:{[this.sessionId]:{head:{id:r.id,version:r.version},flushedTurnCount:s.flushedTurnCount+1,metadata:{updated:r.timestamp}}}}})}async editTurn(e,t,s,r){if(!e.index.sessions[this.sessionId])return S({code:"NOT_FOUND",resource:"session",id:this.sessionId});const n=this.nodes[t];if(!n)return S({code:"NOT_FOUND",resource:"turn",id:t});const o=n.activeVersion+1,i={id:t,version:o,role:n.role,blocks:s,timestamp:(new Date).toISOString(),roleSnapshot:r??n.roleSnapshot,parent:n.parent};n.versions[o]=i,n.activeVersion=o,n.blocks=s,n.timestamp=i.timestamp,void 0!==r&&(n.roleSnapshot=r),n.children[o]||(n.children[o]=[]);const a={id:t,version:o};return this.head=a,await this.tree.replaceVersion(this.sessionId,i),await this.tree.setHead(this.sessionId,a),x({index:{sessions:{[this.sessionId]:{head:a,metadata:{updated:i.timestamp}}}}})}async branchFrom(e,t){const s=e.index.sessions[this.sessionId];if(!s)return S({code:"NOT_FOUND",resource:"session",id:this.sessionId});if(!t.parent)return S({code:"INVALID_COMMAND",reason:"branchFrom requires newTurn.parent to be set"});return this.nodes[t.parent.id]?(this.upsertNode(t),this.head={id:t.id,version:t.version},await this.tree.branch(this.sessionId,t),x({index:{sessions:{[this.sessionId]:{head:{id:t.id,version:t.version},flushedTurnCount:s.flushedTurnCount+1,metadata:{updated:t.timestamp}}}}})):S({code:"NOT_FOUND",resource:"turn",id:t.parent.id})}async deleteTurn(e,t,s,r){const n=e.index.sessions[this.sessionId];if(!n)return S({code:"NOT_FOUND",resource:"session",id:this.sessionId});const o=this.nodes[t];if(!o)return S({code:"NOT_FOUND",resource:"turn",id:t});const i=this.collectSubtreeIds(t);if(o.parent){const e=this.nodes[o.parent.id];if(e){const s=o.parent.version,r=e.children[s];r&&(e.children[s]=r.filter((e=>e!==t)))}}for(const e of i)delete this.nodes[e];this.head=r,await this.tree.deleteSubtree(this.sessionId,t,s,r);const a=(new Date).toISOString();return x({index:{sessions:{[this.sessionId]:{head:r,flushedTurnCount:Math.max(0,n.flushedTurnCount-i.size),metadata:{updated:a}}}}})}switchVersionLeft(e,t){return this.switchVersion(t,-1)}switchVersionRight(e,t){return this.switchVersion(t,1)}switchVersion(e,t){const s=this.nodes[e];if(!s)return S({code:"NOT_FOUND",resource:"turn",id:e});const r=Object.keys(s.versions).map(Number).sort(((e,t)=>e-t)),n=r.indexOf(s.activeVersion);if(-1===n)return S({code:"INVALID_COMMAND",reason:"Current version not found"});const o=n+t;if(o<0||o>=r.length)return S({code:"INVALID_COMMAND",reason:`No ${t<0?"previous":"next"} version available for turn ${e}`});const i=r[o];s.activeVersion=i,s.blocks=s.versions[i].blocks,s.timestamp=s.versions[i].timestamp,s.versions[i].roleSnapshot&&(s.roleSnapshot=s.versions[i].roleSnapshot);const a=this.findSubtreeTipForVersion(e,i);this.head=a;const c=(new Date).toISOString();return x({index:{sessions:{[this.sessionId]:{head:a,metadata:{updated:c}}}}})}async resolve(e){return e.index.sessions[this.sessionId]?this.contentStore.resolveSession(e,this.sessionId,this.activeChain().map((e=>e.versions[e.activeVersion]))):S({code:"NOT_FOUND",resource:"session",id:this.sessionId})}async flush(){return this.flushChain=this.flushChain.then((()=>this.doFlush())),this.flushChain}async dispose(){this.cancelFlushTimer(),await this.flush()}findSubtreeTipForVersion(e,t){let s=e,r=t;for(;;){const e=this.nodes[s];if(!e)break;const t=e.children[r];if(!t||0===t.length)break;s=t[0],r=this.nodes[s]?.activeVersion??0}return{id:s,version:r}}collectSubtreeIds(e){const t=new Set,s=[e];for(;s.length>0;){const e=s.pop();t.add(e);const r=this.nodes[e];if(r&&r.children)for(const e of Object.keys(r.children)){const n=r.children[Number(e)];if(n)for(const e of n)t.has(e)||s.push(e)}}return t}upsertNode(e){const t=e.id,s=e.version;if(this.nodes[t]){const r=this.nodes[t];r.versions[s]=e,s>=r.activeVersion&&(r.activeVersion=s,r.blocks=e.blocks,r.timestamp=e.timestamp,void 0!==e.roleSnapshot&&(r.roleSnapshot=e.roleSnapshot)),r.children[s]||(r.children[s]=[])}else this.nodes[t]={id:t,versions:{[s]:e},activeVersion:s,role:e.role,blocks:e.blocks,timestamp:e.timestamp,roleSnapshot:e.roleSnapshot,parent:e.parent,children:{[s]:[]}};if(e.parent){const s=this.nodes[e.parent.id];if(s){const r=e.parent.version;s.children[r]||(s.children[r]=[]),s.children[r].includes(t)||s.children[r].push(t)}}}scheduleFlush(){null===this.flushTimer&&(this.flushTimer=setTimeout((()=>{this.flushTimer=null,this.flushChain=this.flushChain.then((()=>this.doFlush()))}),this.flushConfig.flushIntervalMs))}cancelFlushTimer(){null!==this.flushTimer&&(clearTimeout(this.flushTimer),this.flushTimer=null)}async doFlush(){if(0===this.dirtyBuffer.length)return;const e=this.dirtyBuffer.splice(0,this.dirtyBuffer.length),t=this.head;try{await this.tree.appendBatch(this.sessionId,e,t),0===this.dirtyBuffer.length&&this.cancelFlushTimer()}catch(t){throw this.dirtyBuffer.unshift(...e),this.flushChain=Promise.resolve(),t}}};var z=10,V=3e4,K="blob_bytes",L="blob_records";function H(e){return new Promise(((t,s)=>{e.onsuccess=()=>t(e.result),e.onerror=()=>s(e.error)}))}function W(e){return new Promise(((t,s)=>{e.oncomplete=()=>t(),e.onerror=()=>s(e.error),e.onabort=()=>s(new Error("Transaction aborted"))}))}exports.BlobStore=N,exports.COLLECTIONS=y,exports.ContentStore=class e{db;tree;blobs;roleCache;preferenceCache;contextCache;onBlobRegistryChanged;constructor(e,t,s={}){this.db=e,this.tree=new k(e),this.blobs=new N(t),this.blobs.onRegistryChanged=(e,t)=>{this.onBlobRegistryChanged?.(e,t)};const r={roles:s.cache?.roles??_,preferences:s.cache?.preferences??B,context:s.cache?.context??I};this.roleCache=new R(r.roles),this.preferenceCache=new R(r.preferences),this.contextCache=new R(r.context)}static async create(t,s,r){const n=new e(t,s,r);return await n.init(),n}async init(e){await this.db.open(e),await this.blobs.init()}getTurnTree(){return this.tree}async getRole(e){const t=this.roleCache.get(e);if(t)return x(t);const s=await this.db.collection(y.ROLE),r=await s.find({field:"name",operator:"eq",value:e});if(!r)return S({code:"NOT_FOUND",resource:"role",id:e});const n=r.state();return this.roleCache.set(e,n),x(n)}async saveRole(e){const t=await this.db.collection(y.ROLE),s=await t.find({field:"name",operator:"eq",value:e.name});s?await s.update(e):await t.create(e),this.roleCache.set(e.name,e)}async deleteRole(e){const t=await this.db.collection(y.ROLE),s=await t.find({field:"name",operator:"eq",value:e});s&&await s.delete(),this.roleCache.delete(e)}async getPreference(e){const t=this.preferenceCache.get(e);if(t)return x(t);const s=await this.db.collection(y.PREFERENCE),r=await s.find({field:"id",operator:"eq",value:e});if(!r)return S({code:"NOT_FOUND",resource:"preference",id:e});const n=r.state();return this.preferenceCache.set(e,n),x(n)}async savePreference(e){const t=await this.db.collection(y.PREFERENCE),s=await t.find({field:"id",operator:"eq",value:e.id});s?await s.update(e):await t.create(e),this.preferenceCache.set(e.id,e)}async deletePreference(e){const t=await this.db.collection(y.PREFERENCE),s=await t.find({field:"id",operator:"eq",value:e});s&&await s.delete(),this.preferenceCache.delete(e)}async getContext(e){const t=this.contextCache.get(e);if(t)return x(t);const s=await this.db.collection(y.CONTEXT),r=await s.find({field:"key",operator:"eq",value:e});if(!r)return S({code:"NOT_FOUND",resource:"context",id:e});const n=r.state();return this.contextCache.set(e,n),x(n)}async saveContext(e){const t=await this.db.collection(y.CONTEXT),s=await t.find({field:"key",operator:"eq",value:e.key});s?await s.update(e):await t.create(e),this.contextCache.set(e.key,e)}async deleteContext(e){const t=await this.db.collection(y.CONTEXT),s=await t.find({field:"key",operator:"eq",value:e});s&&await s.delete(),this.contextCache.delete(e)}async getContextByTopics(e,t){const s=new Set;for(const r of t){const t=e.topics[r];t&&t.contextKeys.forEach((e=>s.add(e)))}if(0===s.size)return[];const r=[],n=[];for(const e of s){const t=this.contextCache.get(e);t?n.push(t):r.push(e)}let o=[];if(r.length>0){const e=await this.db.collection(y.CONTEXT),t=await e.filter({operator:"or",conditions:r.map((e=>({field:"key",operator:"eq",value:e})))});for(const e of t){const t=e.state();this.contextCache.set(t.key,t),o.push(t)}}return[...n,...o].sort(((e,t)=>new Date(t.timestamp).getTime()-new Date(e.timestamp).getTime()))}async saveSession(e){const t=await this.db.collection(y.SESSION),s=await t.find({field:"id",operator:"eq",value:e.id}),r=T(e);s?await s.update(r):await t.create(r)}async updateSessionMeta(e,t){const s=await this.db.collection(y.SESSION),r=await s.find({field:"id",operator:"eq",value:e});if(!r)return;const n=r.state(),o=v(n,t);await r.update(T(o))}async deleteSession(e){const t=await this.db.collection(y.SESSION),s=await t.find({field:"id",operator:"eq",value:e});s&&await s.delete()}async registerBlob(e,t,s){return this.blobs.register(e,t,s)}async retainBlob(e){return this.blobs.retain(e)}async releaseBlob(e){return this.blobs.release(e)}async purgeBlob(e){return this.blobs.purge(e)}async recordBlobRemoteId(e,t,s){return this.blobs.recordRemoteId(e,t,s)}getBlobRecord(e){return this.blobs.getRecord(e)}getAllBlobRecords(){return this.blobs.getAllRecords()}getBlobResolver(){return this.blobs.resolveRefs.bind(this.blobs)}async recordTurn(e,t){return await this.tree.append(e,t),x(void 0)}async editTurn(e,t,s,r,n){const o=(await this.tree.loadAllTurns(e)).find((e=>e.id===t&&e.version===r-1));if(!o)return S({code:"NOT_FOUND",resource:"turn",id:t});const i={id:t,version:r,role:o.role,blocks:s,timestamp:(new Date).toISOString(),roleSnapshot:n??o.roleSnapshot,parent:o.parent};await this.tree.replaceVersion(e,i);const a=await this.tree.getHead(e);return a?.id===t&&await this.tree.setHead(e,{id:i.id,version:i.version}),x(void 0)}async branchTurn(e,t){return await this.tree.branch(e,t),x(void 0)}async deleteTurnSubtree(e,t,s,r){return await this.tree.deleteSubtree(e,t,s,r),x(void 0)}async copyTranscript(e,t){await this.tree.copyTranscript(e,t)}async resolveSession(e,t,s){const r=e.index.sessions[t];if(!r)return S({code:"NOT_FOUND",resource:"session",id:t});const n=await this.getRole(r.role);if(!n.ok)return n;const o=n.value,i=function(e,t){return e.preferences.length>0?e.preferences:t.preferences}(r,o),a={session:r,role:o,preferences:function(e,t){return e.filter((e=>0===e.topics.length||e.topics.some((e=>t.includes(e)))))}((await Promise.all(i.map((e=>this.getPreference(e))))).filter((e=>e.ok)).map((e=>e.value)),r.topics),context:await this.getContextByTopics(e.index,r.topics),transcript:s??await this.tree.getActiveChain(t),instructions:e.settings?.prompt};return x({...a,preferences:Object.freeze([...a.preferences]),context:Object.freeze([...a.context]),transcript:Object.freeze([...a.transcript])})}},exports.IndexedDBBlobStorage=class{dbName;db=null;constructor(e={}){this.dbName=e.dbName??"aiworkspace-blobs"}async open(){this.db||(this.db=await new Promise(((e,t)=>{const s=indexedDB.open(this.dbName,1);s.onupgradeneeded=e=>{const t=e.target.result;this.createSchema(t)},s.onsuccess=()=>e(s.result),s.onerror=()=>t(s.error),s.onblocked=()=>t(new Error(`[IndexedDBBlobStorage] Database "${this.dbName}" blocked.`))})),this.db.onversionchange=()=>{this.db?.close(),this.db=null})}createSchema(e){e.objectStoreNames.contains(K)||e.createObjectStore(K,{keyPath:"sha256"}),e.objectStoreNames.contains(L)||e.createObjectStore(L,{keyPath:"sha256"})}close(){this.db?.close(),this.db=null}async deleteDatabase(){this.close(),await new Promise(((e,t)=>{const s=indexedDB.deleteDatabase(this.dbName);s.onsuccess=()=>e(),s.onerror=()=>t(s.error)}))}getDB(){if(!this.db)throw new Error("[IndexedDBBlobStorage] Database not open. Call open() first.");return this.db}readTx(...e){return this.getDB().transaction(e,"readonly")}writeTx(...e){return this.getDB().transaction(e,"readwrite")}async storeBytes(e,t){const s=this.readTx(K);if(await H(s.objectStore(K).get(e)))return;const r=this.writeTx(K);r.objectStore(K).put({sha256:e,data:t}),await W(r)}async loadBytes(e){const t=this.readTx(K),s=await H(t.objectStore(K).get(e));return s?.data??null}async hasBytes(e){const t=this.readTx(K);return await H(t.objectStore(K).count(e))>0}async deleteBytes(e){const t=this.writeTx(K);t.objectStore(K).delete(e),await W(t)}async saveRecord(e){const t=this.writeTx(L);t.objectStore(L).put(e),await W(t)}async loadRecord(e){const t=this.readTx(L);return await H(t.objectStore(L).get(e))??null}async deleteRecord(e){const t=this.writeTx(L);t.objectStore(L).delete(e),await W(t)}async listRecords(){return H(this.readTx(L).objectStore(L).getAll())}async exportAllBytes(){const e=this.readTx(K);return(await H(e.objectStore(K).getAll())).map((({sha256:e,data:t})=>[e,t]))}async registerBlob(e,t){await new Promise(((s,r)=>{const n=this.getDB().transaction([K,L],"readwrite"),o=n.objectStore(K),i=n.objectStore(L),a=o.count(e.sha256);a.onsuccess=()=>{0===a.result&&o.put({sha256:e.sha256,data:t}),i.put(e)},a.onerror=()=>r(a.error),n.oncomplete=()=>s(),n.onerror=()=>r(n.error),n.onabort=()=>r(new Error("registerBlob transaction aborted"))}))}},exports.MemoryBlobStorage=class{bytes=new Map;records=new Map;async storeBytes(e,t){this.bytes.has(e)||this.bytes.set(e,t)}async loadBytes(e){return this.bytes.get(e)??null}async hasBytes(e){return this.bytes.has(e)}async deleteBytes(e){this.bytes.delete(e)}async saveRecord(e){this.records.set(e.sha256,{...e})}async loadRecord(e){return this.records.get(e)??null}async deleteRecord(e){this.records.delete(e)}async listRecords(){return Array.from(this.records.values()).map((e=>({...e})))}async exportAllBytes(){return Array.from(this.bytes.entries()).map((([e,t])=>[e,new Uint8Array(t)]))}async registerBlob(e,t){this.bytes.has(e.sha256)||this.bytes.set(e.sha256,t),this.records.set(e.sha256,{...e})}},exports.PromptBuilder=class{retriever;planner;assembler;summarizer;blobResolver;constructor(e){this.blobResolver=e.blobResolver,this.retriever=e.retriever??new M,this.planner=e.planner??new F,this.assembler=e.assembler??new q,this.summarizer=e.summarizer}async build(e,t={}){const s=[],{resolved:r,conflicts:n}=this.resolvePreferenceConflicts(e.preferences);n.length>0&&s.push(`${n.length} preference conflict(s) resolved.`);const o=this.extractRecentUserQueries(e.transcript,t.relevanceConfig),i=this.retriever.rank({entries:e.context,recentMessages:o,config:t.relevanceConfig??{}});let a=e.transcript,c=null;if(this.summarizer&&a.length>0){const e=t.tokenBudget?Math.floor(.25*t.tokenBudget.total):2e3,s=await this.summarizer.summarize(a,e);c=s.summary,a=s.remaining}const d=this.planner.plan({systemInstructions:e.instructions,persona:e.role.persona,preferences:r,context:i,transcript:a,budget:t.tokenBudget}),l=this.collectUsedBlobRefs(d.context,d.transcript),u=this.deduplicateBlobRefs(l),{resolved:h,errors:p}=await this.blobResolver(u,t.providerId??null);for(const e of p)s.push(`Failed to resolve blob ${e.ref.sha256.slice(0,8)}: ${e.error.code}`);const f=u.filter((e=>!h.has(e.sha256)));return f.length>0&&s.push(`${f.length} blob(s) unresolved and omitted: `+f.map((e=>e.sha256.slice(0,8))).join(", ")),d.truncated.preferences>0&&s.push(`${d.truncated.preferences} preference(s) dropped.`),d.truncated.interactions>0&&s.push(`${d.truncated.interactions} turn(s) trimmed.`),d.truncated.context>0&&s.push(`${d.truncated.context} context entry/entries dropped.`),this.assembler.assemble({session:e,plan:d,resolvedBlobs:h,summaryBlockText:c,warnings:s,conflicts:n,budgetTotal:t.tokenBudget?.total??0})}collectUsedBlobRefs(e,t){const s=[];for(const t of e)"blob"===t.content.kind&&s.push(t.content);for(const e of t)for(const t of e.blocks)if("image"===t.type||"document"===t.type){const e=t.ref;e&&s.push(e)}return s}deduplicateBlobRefs(e){const t=new Set,s=[];for(const r of e)t.has(r.sha256)||(t.add(r.sha256),s.push(r));return s}extractRecentUserQueries(e,t){const s=t?.recentMessageWindow??3;return e.filter((e=>"user"===e.role)).slice(-s).flatMap((e=>e.blocks.filter((e=>"text"===e.type)).map((e=>e.text))))}resolvePreferenceConflicts(e){const t=[],s=new Map;for(const r of e)if(0!==r.topics.length)for(const e of r.topics){const n=s.get(e);if(!n){s.set(e,r);continue}const o=new Date(n.timestamp).getTime(),i=new Date(r.timestamp).getTime();i>o?(t.push({topic:e,kept:r.id,dropped:n.id,reason:"superseded_by_newer"}),s.set(e,r)):o>i&&t.push({topic:e,kept:n.id,dropped:r.id,reason:"superseded_by_newer"})}const r=new Set(t.map((e=>e.dropped)));return{resolved:e.filter((e=>!r.has(e.id))),conflicts:Array.from(new Set(t))}}},exports.Session=$,exports.SessionManager=class{workspaceManager;contentStore;flushConfig;constructor(e,t,s={}){this.workspaceManager=e,this.contentStore=t,this.flushConfig={maxBufferSize:s.flush?.maxBufferSize??z,flushIntervalMs:s.flush?.flushIntervalMs??V}}async open(e,t){const s=e.index.sessions[t];if(!s)return S({code:"NOT_FOUND",resource:"session",id:t});const r=this.contentStore.getTurnTree();try{const e=await r.buildNodeGraph(t);return x({session:new $(t,e,s.head,r,this.contentStore,this.flushConfig),patch:{}})}catch(e){return S({code:"BACKEND_ERROR",reason:e instanceof Error?e.message:String(e)})}}async close(e){await e.dispose()}get workspace(){return this.workspaceManager}},exports.TurnTree=k,exports.WorkspaceManager=class{contentStore;onWorkspacePatch;constructor(e){this.contentStore=e,this.contentStore.onBlobRegistryChanged=(e,t)=>{const s={index:{blobs:{[e]:t??void 0}}};this.onWorkspacePatch?.(s)}}reduce(e,t){return E(e,t)}async dispatch(e,t){const s=E(e,t);if(!s.ok)return s;let r={};try{r=await this.handleContentSideEffects(e,t)}catch(e){return S({code:"BACKEND_ERROR",reason:e instanceof Error?e.message:String(e)})}return x(v(s.value,r))}async resolveSession(e,t){return this.contentStore.resolveSession(e,t)}async handleContentSideEffects(e,t){switch(t.type){case"blob:register":{const{data:e,mediaType:s,filename:r}=t.payload,n=await this.contentStore.registerBlob(e,s,r);if(!n.ok)throw Object.assign(new Error(n.error.code),{wsError:n.error});const o=n.value,i=this.contentStore.getBlobRecord(o.sha256);if(!i)throw new Error("Record missing after register");return{index:{blobs:{[o.sha256]:i}}}}case"blob:retain":{const{sha256:e}=t.payload,s=await this.contentStore.retainBlob(e);if(!s.ok)throw Object.assign(new Error(s.error.code),{wsError:s.error});const r=this.contentStore.getBlobRecord(e);return{index:{blobs:{[e]:r??void 0}}}}case"blob:release":{const{sha256:e}=t.payload,s=await this.contentStore.releaseBlob(e);if(!s.ok)throw Object.assign(new Error(s.error.code),{wsError:s.error});const r=this.contentStore.getBlobRecord(e);return{index:{blobs:{[e]:r??void 0}}}}case"blob:purge":{const{sha256:e}=t.payload,s=await this.contentStore.purgeBlob(e);if(!s.ok)throw Object.assign(new Error(s.error.code),{wsError:s.error});return{index:{blobs:{[e]:void 0}}}}case"blob:record_remote_id":{const{sha256:e,providerId:s,fileId:r}=t.payload,n=await this.contentStore.recordBlobRemoteId(e,s,r);if(!n.ok)throw Object.assign(new Error(n.error.code),{wsError:n.error});const o=this.contentStore.getBlobRecord(e);return{index:{blobs:{[e]:o??void 0}}}}case"role:add":return await this.contentStore.saveRole(t.payload),{};case"role:update":{const{name:e,...s}=t.payload,r=await this.contentStore.getRole(e);if(!r.ok)throw new Error(`role:update — "${e}" not found`);return await this.contentStore.saveRole({...r.value,...s,name:e}),{}}case"role:delete":return await this.contentStore.deleteRole(t.payload.name),{};case"preference:add":return await this.contentStore.savePreference(t.payload),{};case"preference:update":{const{id:e,...s}=t.payload,r=await this.contentStore.getPreference(e);if(!r.ok)throw new Error(`preference:update — "${e}" not found`);return await this.contentStore.savePreference({...r.value,...s,id:e}),{}}case"preference:delete":return await this.contentStore.deletePreference(t.payload.id),{};case"context:add":case"context:update":return await this.contentStore.saveContext(t.payload),{};case"context:delete":return await this.contentStore.deleteContext(t.payload.key),{};case"session:create":{const{id:e,label:s,role:r,topics:n,preferences:o=[]}=t.payload;return await this.contentStore.saveSession({id:e,label:s,role:r,topics:n,preferences:o,metadata:{created:t.timestamp,updated:t.timestamp},flushedTurnCount:0,head:null}),{}}case"session:fork":{const{sourceSessionId:s,newSessionId:r,label:n,role:o,topics:i}=t.payload;if(!e.index.sessions[s])throw new Error(`session:fork — source session "${s}" not found`);await this.contentStore.copyTranscript(s,r);const a=e.index.sessions[s],c={id:r,label:n,role:o??a.role,topics:i??[...a.topics],preferences:[...a.preferences],metadata:{created:t.timestamp,updated:t.timestamp},flushedTurnCount:a.flushedTurnCount,head:a.head?{...a.head}:null};return await this.contentStore.saveSession(c),{}}case"session:delete":return await this.contentStore.deleteSession(t.payload.sessionId),{};case"session:role:switch":case"session:topics:add":case"session:preferences:override":{const e=t.payload.sessionId,s=await this.contentStore.db.collection("session"),r=await s.find({field:"id",operator:"eq",value:e});if(!r)return{};if("session:role:switch"===t.type)await this.contentStore.updateSessionMeta(e,{role:t.payload.role});else if("session:topics:add"===t.type){const s=r.state();await this.contentStore.updateSessionMeta(e,{topics:[...new Set([...s.topics,...t.payload.topics])]})}else await this.contentStore.updateSessionMeta(e,{preferences:t.payload.preferences});return{}}case"turn:add":return await this.contentStore.recordTurn(t.payload.sessionId,t.payload.turn),{};case"turn:edit":{const{sessionId:e,turnId:s,newBlocks:r,newVersion:n,roleSnapshot:o}=t.payload;return await this.contentStore.editTurn(e,s,r,n,o),{}}case"turn:branch":return await this.contentStore.branchTurn(t.payload.sessionId,t.payload.newTurn),{};case"turn:delete":{const{sessionId:e,turnId:s,version:r,newHead:n}=t.payload;return await this.contentStore.deleteTurnSubtree(e,s,r,n),{}}default:return{}}}},exports.buildTurnNode=function(e,t=[]){return{id:e.id,versions:{[e.version]:e},activeVersion:e.version,role:e.role,blocks:e.blocks,timestamp:e.timestamp,roleSnapshot:e.roleSnapshot,parent:e.parent,children:{[e.version]:[...t]}}},exports.computeSHA256=C,exports.createSimpleWorkspace=function({name:e,owner:t,language:r}){return{id:s.v7(),settings:{language:r},project:{name:e,owner:t},index:{roles:{},topics:{},preferences:{},context:{},sessions:{},blobs:{}}}},exports.createWorkspaceDatabase=function(e){const t=new m({retry:!0,throws:!0}),s=new m({retry:!0,throws:!0});return{open:async(s=[])=>(await t.do((async()=>{const t=[...u,...s];await e.setupCollections(t)}))).value,collection:async t=>e.collection(t),close:async()=>(await s.do((()=>{e.close()}))).value}},exports.del=g,exports.err=S,exports.extractBlobRecord=function(e){const t=e?.index?.blobs;if(!t)return null;const s=t[Object.keys(t)[0]];return s||null},exports.extractBlobRef=function(e){return{sha256:e.sha256,mediaType:e.mediaType,sizeBytes:e.sizeBytes,filename:e.filename,previewUrl:e.previewUrl}},exports.merge=v,exports.ok=x,exports.omitNullUndefined=T,exports.workspaceReducer=E;
|
|
1
|
+
"use strict";var e,t,s=require("uuid"),r=Object.create,n=Object.defineProperty,o=Object.getOwnPropertyDescriptor,a=Object.getOwnPropertyNames,i=Object.getPrototypeOf,c=Object.prototype.hasOwnProperty,d=(e,t,s)=>(s=null!=e?r(i(e)):{},((e,t,s,r)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let i of a(t))c.call(e,i)||i===s||n(e,i,{get:()=>t[i],enumerable:!(r=o(t,i))||r.enumerable});return e})(e&&e.__esModule?s:n(s,"default",{value:e,enumerable:!0}),e)),l=(e={"node_modules/@asaidimu/events/index.js"(e,t){var s,r=Object.defineProperty,n=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyNames,a=Object.prototype.hasOwnProperty,i={};((e,t)=>{for(var s in t)r(e,s,{get:t[s],enumerable:!0})})(i,{createEventBus:()=>c}),t.exports=(s=i,((e,t,s,i)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let c of o(t))a.call(e,c)||c===s||r(e,c,{get:()=>t[c],enumerable:!(i=n(t,c))||i.enumerable});return e})(r({},"__esModule",{value:!0}),s));var c=(e={async:!1,batchSize:1e3,batchDelay:16,errorHandler:e=>console.error("EventBus Error:",e),crossTab:!1,channelName:"event-bus-channel"})=>{const t=new Map;let s=[],r=0,n=0;const o=new Map,a=new Map;let i=null;e.crossTab&&"undefined"!=typeof BroadcastChannel?i=new BroadcastChannel(e.channelName):e.crossTab&&console.warn("BroadcastChannel is not supported in this browser. Cross-tab notifications are disabled.");const c=(e,t)=>{r++,n+=t,o.set(e,(o.get(e)||0)+1)},d=()=>{const t=s;s=[],t.forEach((({name:t,payload:s})=>{const r=performance.now();try{(a.get(t)||[]).forEach((e=>e(s)))}catch(r){e.errorHandler({...r,eventName:t,payload:s})}c(t,performance.now()-r)}))},l=(()=>{let t;return()=>{clearTimeout(t),t=setTimeout(d,e.batchDelay)}})(),u=e=>{const s=t.get(e);s?a.set(e,Array.from(s)):a.delete(e)};return i&&(i.onmessage=e=>{const{name:t,payload:s}=e.data;(a.get(t)||[]).forEach((e=>e(s)))}),{subscribe:(e,s)=>{t.has(e)||t.set(e,new Set);const r=t.get(e);return r.add(s),u(e),()=>{r.delete(s),0===r.size?(t.delete(e),a.delete(e)):u(e)}},emit:({name:t,payload:r})=>{if(e.async)return s.push({name:t,payload:r}),s.length>=e.batchSize?d():l(),void(i&&i.postMessage({name:t,payload:r}));const n=performance.now();try{(a.get(t)||[]).forEach((e=>e(r))),i&&i.postMessage({name:t,payload:r})}catch(s){e.errorHandler({...s,eventName:t,payload:r})}c(t,performance.now()-n)},getMetrics:()=>({totalEvents:r,activeSubscriptions:Array.from(t.values()).reduce(((e,t)=>e+t.size),0),eventCounts:o,averageEmitDuration:r>0?n/r:0}),clear:()=>{t.clear(),a.clear(),s=[],r=0,n=0,o.clear(),i&&(i.close(),i=null)}}}}},function(){return t||(0,e[a(e)[0]])((t={exports:{}}).exports,t),t.exports}),u=[{name:"role",version:"1.0.0",description:"AI persona with a system prompt and associated preference defaults.",fields:{name:{name:"name",type:"string",required:!0},label:{name:"label",type:"string",required:!0},description:{name:"description",type:"string",required:!1},persona:{name:"persona",type:"string",required:!0},preferences:{name:"preferences",type:"array",required:!1,itemsType:"string"}},indexes:[{name:"by_name",fields:["name"],type:"unique"},{name:"by_label",fields:["label"],type:"normal"}],constraints:[],migrations:[]},{name:"preference",version:"1.0.0",description:"A user behavioural instruction, scoped to zero or more topics.",fields:{id:{name:"id",type:"string",required:!0},content:{name:"content",type:"string",required:!0},topics:{name:"topics",type:"array",required:!1,itemsType:"string"},timestamp:{name:"timestamp",type:"string",required:!0}},indexes:[{name:"by_id",fields:["id"],type:"unique"},{name:"by_topics",fields:["topics"],type:"normal"},{name:"by_timestamp",fields:["timestamp"],type:"btree"}],constraints:[],migrations:[]},{name:"context",version:"1.0.0",description:"Injected background knowledge, scoped to topics. Content is a discriminated union.",fields:{key:{name:"key",type:"string",required:!0},topics:{name:"topics",type:"array",required:!1,itemsType:"string"},content:{name:"content",type:"record",required:!0},timestamp:{name:"timestamp",type:"string",required:!0},metadata:{name:"metadata",type:"record",required:!1}},indexes:[{name:"by_key",fields:["key"],type:"unique"},{name:"by_topics",fields:["topics"],type:"normal"},{name:"by_timestamp",fields:["timestamp"],type:"btree"}],constraints:[],migrations:[]},{name:"session",version:"1.0.0",description:"Session metadata. The head field tracks the current tip of the turn DAG.",fields:{id:{name:"id",type:"string",required:!0},label:{name:"label",type:"string",required:!0},role:{name:"role",type:"string",required:!0},topics:{name:"topics",type:"array",required:!1,itemsType:"string"},preferences:{name:"preferences",type:"array",required:!1,itemsType:"string"},metadata:{name:"metadata",type:"record",required:!1},flushedTurnCount:{name:"flushedTurnCount",type:"number",required:!0},head:{name:"head",type:"record",required:!1}},indexes:[{name:"by_id",fields:["id"],type:"unique"},{name:"by_role",fields:["role"],type:"normal"}],constraints:[],migrations:[]},{name:"turn",version:"1.0.0",description:["A single message in a session transcript, stored as a flat document.","The DAG is reconstructed in memory by TurnTree.buildNodeGraph() at session open time.","$id is a composite key: `${sessionId}:${id}:${version}`."].join(" "),fields:{id:{name:"id",type:"string",required:!0},sessionId:{name:"sessionId",type:"string",required:!0},version:{name:"version",type:"number",required:!0},owner:{name:"owner",type:"enum",required:!0,values:["user","assistant","tool"]},blocks:{name:"blocks",type:"array",required:!0},timestamp:{name:"timestamp",type:"string",required:!0},role:{name:"role",type:"string",required:!1},parent:{name:"parent",type:"record",required:!1}},indexes:[{name:"by_session",fields:["sessionId"],type:"normal"},{name:"by_session_parent",fields:["sessionId","parent"],type:"composite"},{name:"by_session_id_ver",fields:["sessionId","id","version"],type:"composite",unique:!0}],constraints:[],migrations:[]},{name:"task",version:"1.0.0",description:"A first-class task entity with status, steps, and topics.",fields:{id:{name:"id",type:"string",required:!0},title:{name:"title",type:"string",required:!0},description:{name:"description",type:"string",required:!1},status:{name:"status",type:"enum",required:!0,values:["todo","active","done","blocked","defered"]},steps:{name:"steps",type:"array",required:!0,itemsType:"record"},topics:{name:"topics",type:"array",required:!1,itemsType:"string"},metadata:{name:"metadata",type:"record",required:!1},created:{name:"created",type:"string",required:!0},updated:{name:"updated",type:"string",required:!0}},indexes:[{name:"by_id",fields:["id"],type:"unique"},{name:"by_status",fields:["status"],type:"normal"},{name:"by_topics",fields:["topics"],type:"normal"},{name:"by_updated",fields:["updated"],type:"btree"}],constraints:[],migrations:[]}],p=class e extends Error{constructor(t,s){super(t,{cause:s}),this.name="SyncError",Object.setPrototypeOf(this,e.prototype)}},h=class extends p{constructor(e){super(`[ArtifactContainer] Operation timed out: ${e}`)}},f=class{_locked=!1;_capacity;_yieldMode;waiters=[];constructor(e){this._capacity=e?.capacity??1/0,this._yieldMode=e?.yieldMode??"macrotask"}async lock(e){if(!this._locked)return void(this._locked=!0);if(this.waiters.length>=this._capacity)throw new Error(`Mutex queue is full (capacity: ${this._capacity})`);let t;const s=new Promise((e=>t=e));this.waiters.push(t),null!=e?await Promise.race([s,new Promise(((s,r)=>setTimeout((()=>{const e=this.waiters.indexOf(t);-1!==e&&this.waiters.splice(e,1),r(new h("Mutex lock timed out"))}),e)))]):await s}tryLock(){return!this._locked&&(this._locked=!0,!0)}unlock(){if(!this._locked)throw new Error("Mutex is not locked");const e=this.waiters.shift();e?"microtask"===this._yieldMode?queueMicrotask(e):setTimeout(e,0):this._locked=!1}locked(){return this._locked}pending(){return this.waiters.length}},m=class{mutex=new f({yieldMode:"microtask"});promise=null;_value=null;_error;_done=!1;retry;throws;constructor({retry:e,throws:t}={}){this.retry=Boolean(e),this.throws=Boolean(t)}async do(e,t){return this._done?this.peek():this.promise?this._awaitWithTimeout(this.promise,t,"Once do() timed out"):(await this.mutex.lock(),this.promise?(this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")):(this.promise=(async()=>{try{const t=await e();this._value=t,this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.promise=null}return this.peek()})(),this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")))}doSync(e){if(this._done){if(this.throws&&this._error)throw this._error;return this.peek()}if(this.promise){const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}if(!this.mutex.tryLock()){const e=new Error("Cannot execute doSync: lock is currently held.");if(this.throws)throw e;return{value:null,error:e}}if(this.promise||this._done){if(this.mutex.unlock(),this._done){if(this.throws&&this._error)throw this._error;return this.peek()}const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}try{const t=e();this._value=t,this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.mutex.unlock()}return this.peek()}isReady(){return this._done&&null===this.promise}running(){return null!==this.promise&&!this._done}peek(){return{value:this._value,error:this._error}}get(){if(!this._done)throw new Error("Once operation is not yet complete");if(this._error)throw this._error;return this._value}reset(){this._done=!1,this.promise=null,this._value=null,this._error=void 0}resolved(){return this.promise}done(){return this._done}_awaitWithTimeout(e,t,s="Operation timed out"){return null==t?e:Promise.race([e,new Promise(((e,r)=>setTimeout((()=>r(new h(s))),t)))])}};var y={ROLE:"role",PREFERENCE:"preference",CONTEXT:"context",SESSION:"session",TURN:"turn",TASK:"task"};d(l());var b=Symbol.for("delete"),w=e=>Array.isArray(e)?[...e]:{...e};function g(){return b}d(l()),d(l()),d(l()),d(l()),d(l()),d(l());var v=function(e){const t=e?.deleteMarker||b;function s(e){if(null==e)return e;if(Array.isArray(e))return e.filter((e=>e!==t)).map((e=>"object"!=typeof e||null===e||Array.isArray(e)?e:s(e)));if("object"==typeof e){const r={};for(const[n,o]of Object.entries(e))if(o!==t)if("object"==typeof o&&null!==o){const e=s(o);void 0!==e&&(r[n]=e)}else r[n]=o;return r}return e===t?void 0:e}return function(e,r){if("object"!=typeof e||null===e)return"object"==typeof r&&null!==r?s(r):r===t?{}:r;if("object"!=typeof r||null===r)return e;const n=w(e),o=[{target:n,source:r}];for(;o.length>0;){const{target:e,source:s}=o.pop();for(const r of Object.keys(s)){const n=s[r];if(n!==t)if(Array.isArray(n))e[r]=n;else if("object"==typeof n&&null!==n){const t=r in e&&"object"==typeof e[r]&&null!==e[r]?e[r]:{};e[r]=w(t),o.push({target:e[r],source:n})}else e[r]=n;else delete e[r]}}return n}}({deleteMarker:b});function k(e){return{ok:!0,value:e}}function x(e){return{ok:!1,error:e}}function T(e){return Object.fromEntries(Object.entries(e).filter((([e,t])=>null!=t)))}var S=class{db;constructor(e){this.db=e}async turns(){return this.db.collection(y.TURN)}async sessions(){return this.db.collection(y.SESSION)}turnFilter(e,t,s){return{operator:"and",conditions:[{field:"sessionId",operator:"eq",value:e},{field:"id",operator:"eq",value:t},{field:"version",operator:"eq",value:s}]}}async loadRaw(e){const[t,s]=await Promise.all([this.loadAllTurns(e),this.getHead(e)]);return{turns:t,head:s}}async getHead(e){const t=await this.sessions(),s=await t.find({field:"id",operator:"eq",value:e});return s?.head??null}async setHead(e,t){const s=await this.sessions(),r=await s.find({field:"id",operator:"eq",value:e});if(!r)return;const n={...r.state(),head:t??void 0};await r.update(n)}async save(e,t,s){const r={...t,sessionId:e,version:t.version??0,parent:t.parent?t.parent:s?{id:s.id,version:s.version}:null},n=await this.turns();return await n.create(T(r)),r}async append(e,t){const s=await this.getHead(e),r=this.save(e,t,s);return await this.setHead(e,{id:t.id,version:t.version}),r}async appendBatch(e,t,s){const r=await this.getHead(e);if(0!==t.length){for(const s of t)await this.save(e,s,r);await this.setHead(e,s)}}async replaceVersion(e,t){const s=await this.turns(),r=await s.find(this.turnFilter(e,t.id,t.version)),n=T(t);r?await r.update({...n,sessionId:e}):await s.create({...n,sessionId:e})}async branch(e,t){const s=await this.turns();await s.create(T({...t,sessionId:e})),await this.setHead(e,{id:t.id,version:t.version})}async loadAllTurns(e){const t=await this.turns();return(await t.filter({field:"sessionId",operator:"eq",value:e})).map((e=>e.state()))}async loadTurnVersions(e,t){const s=await this.turns();return(await s.filter({operator:"and",conditions:[{field:"sessionId",operator:"eq",value:e},{field:"id",operator:"eq",value:t}]})).map((e=>e.state()))}buildNodes(e,t,s=[]){const r=function(e,t){if(!t)return new Set;const s=new Map;for(const t of e)s.set(`${t.id}:${t.version}`,t);const r=new Set;let n=t;for(;n;){const e=`${n.id}:${n.version}`;if(r.has(e))break;r.add(e);const t=s.get(e);if(!t)break;n=t.parent}return r}(e,t),n={},o={},a=[...e,...s];for(const e of a){n[e.id]||(n[e.id]={id:e.id,versions:{},activeVersion:e.version,role:e.owner,blocks:e.blocks,timestamp:e.timestamp,roleSnapshot:e.role,parent:e.parent,children:{}},o[e.id]=new Set);const t=n[e.id];t.versions[e.version]=e;const s=r.has(`${e.id}:${e.version}`),a=r.has(`${e.id}:${t.activeVersion}`);if(s&&(!a||e.version>=t.activeVersion)&&(t.activeVersion=e.version,t.blocks=e.blocks,t.timestamp=e.timestamp,t.roleSnapshot=e.role,t.parent=e.parent),e.parent){const t=`${e.parent.id}:${e.parent.version}`;if(o[e.parent.id]||(o[e.parent.id]=new Set),!o[e.parent.id].has(t+":"+e.id)){o[e.parent.id].add(t+":"+e.id),n[e.parent.id]||(n[e.parent.id]={id:e.parent.id,versions:{},activeVersion:e.parent.version,role:"user",blocks:[],timestamp:"",roleSnapshot:void 0,parent:null,children:{}});const s=n[e.parent.id],r=e.parent.version;s.children[r]||(s.children[r]=[]),s.children[r].push(e.id)}}}return n}async buildNodeGraph(e,t=[]){const{turns:s,head:r}=await this.loadRaw(e);return this.buildNodes(s,r,t)}async getActiveChain(e,t=[]){const{turns:s,head:r}=await this.loadRaw(e);if(!r&&0===t.length)return[];return[...r?O(s,r):[],...t]}async buildActiveChain(e){const{turns:t,head:s}=await this.loadRaw(e);if(!s)return[];const r=this.buildNodes(t,s),n=[];let o=s.id;for(;null!==o;){const e=r[o];if(!e)break;n.push(e),o=e.parent?.id??null}return n.reverse()}async getTurnSiblings(e,t){const{turns:s,head:r}=await this.loadRaw(t),n=this.buildNodes(s,r),o=n[e];if(!o)return[];if(!o.parent)return Object.values(n).filter((e=>null===e.parent));const a=n[o.parent.id];if(!a)return[o];const i=o.parent.version,c=a.children[i];return c?c.map((e=>n[e])).filter((e=>void 0!==e)):[o]}async branchInfo(e,t){const{turns:s,head:r}=await this.loadRaw(t),n=this.buildNodes(s,r)[e];if(!n)return{versions:[],currentIndex:-1,total:0,hasPrev:!1,hasNext:!1};const o=Object.keys(n.versions).map(Number).sort(((e,t)=>e-t)),a=o.indexOf(n.activeVersion);return{versions:o,currentIndex:a,total:o.length,hasPrev:a>0,hasNext:a<o.length-1}}async deleteSubtree(e,t,s,r){const n=function(e,t,s){const r=new Map;for(const t of e)if(t.parent){const e=`${t.parent.id}:${t.parent.version}`;let s=r.get(e);s||(s=new Set,r.set(e,s)),s.add(`${t.id}:${t.version}`)}const n=new Set,o=[`${t}:${s}`];for(;o.length>0;){const e=o.pop();n.add(e);const t=r.get(e);if(t)for(const e of t)n.has(e)||o.push(e)}return n}(await this.loadAllTurns(e),t,s),o=await this.turns();await Promise.all(Array.from(n).map((async t=>{const[s,r]=t.split(":"),n=await o.find(this.turnFilter(e,s,Number(r)));n&&await n.delete()}))),await this.setHead(e,r)}async copyTranscript(e,t){const{turns:s,head:r}=await this.loadRaw(e),n=r?O(s,r):[],o=await this.turns();for(const e of n)await o.create(T({...e,sessionId:t}));await this.setHead(t,r?{...r}:null)}};function O(e,t){const s=new Map;for(const t of e)s.set(`${t.id}:${t.version}`,t);const r=[];let n=t;for(;n;){const e=s.get(`${n.id}:${n.version}`);if(!e)break;r.push(e),n=e.parent}return r.reverse()}async function _(e){const t=await crypto.subtle.digest("SHA-256",e);return Array.from(new Uint8Array(t)).map((e=>e.toString(16).padStart(2,"0"))).join("")}var N=class{storage;config;bus;recordCache=new Map;constructor(e,t,s={}){this.storage=e,this.bus=t,this.config={eagerEviction:s.eagerEviction??!1}}subscribe(e,t){return this.bus.subscribe(e,t)}async init(){const e=await this.storage.listRecords();for(const t of e)this.recordCache.set(t.sha256,t)}async register(e,t,s){try{const r=await _(e),n=(new Date).toISOString(),o=this.recordCache.get(r);if(o){const e={...o,refCount:o.refCount+1,lastUsedAt:n};await this.storage.saveRecord(e),this.recordCache.set(r,e)}else{const o={sha256:r,mediaType:t,sizeBytes:e.byteLength,filename:s,refCount:1,remoteIds:{},createdAt:n,lastUsedAt:n};"function"==typeof this.storage.registerBlob?await this.storage.registerBlob(o,e):(await this.storage.storeBytes(r,e),await this.storage.saveRecord(o)),this.recordCache.set(r,o)}const a=this.recordCache.get(r);return k({sha256:r,mediaType:t,sizeBytes:a.sizeBytes,filename:a.filename,previewUrl:a.previewUrl})}catch(e){return x({code:"BLOB_ERROR",reason:e instanceof Error?e.message:String(e)})}}async retain(e){const t=this.recordCache.get(e);if(!t)return x({code:"NOT_FOUND",resource:"blob",id:e});const s={...t,refCount:t.refCount+1,lastUsedAt:(new Date).toISOString()};return await this.storage.saveRecord(s),this.recordCache.set(e,s),k(void 0)}async release(e){const t=this.recordCache.get(e);if(!t)return x({code:"NOT_FOUND",resource:"blob",id:e});const s=Math.max(0,t.refCount-1),r={...t,refCount:s,lastUsedAt:(new Date).toISOString()};return 0===s&&this.config.eagerEviction?(await this.storage.deleteBytes(e),await this.storage.deleteRecord(e),this.recordCache.delete(e)):(await this.storage.saveRecord(r),this.recordCache.set(e,r)),k(void 0)}async recordRemoteId(e,t,s){const r=this.recordCache.get(e);if(!r)return x({code:"NOT_FOUND",resource:"blob",id:e});if(r.remoteIds[t]===s)return k(void 0);const n={...r,remoteIds:{...r.remoteIds,[t]:s}};return await this.storage.saveRecord(n),this.recordCache.set(e,n),k(void 0)}getRemoteId(e,t){return this.recordCache.get(e)?.remoteIds[t]??null}async resolveRef(e,t){try{if(t){const s=this.getRemoteId(e.sha256,t);if(s)return k({kind:"remote",sha256:e.sha256,mediaType:e.mediaType,fileId:s,providerId:t})}const s=await this.storage.loadBytes(e.sha256);return s?k({kind:"inline",sha256:e.sha256,mediaType:e.mediaType,data:s}):x({code:"BLOB_ERROR",reason:`Blob bytes not found locally for sha256=${e.sha256}. The blob may have been evicted. Re-register it before resolving.`})}catch(e){return x({code:"BLOB_ERROR",reason:e instanceof Error?e.message:String(e)})}}async resolveRefs(e,t){const s=function(e){const t=new Set,s=[];for(const r of e)t.has(r.sha256)||(t.add(r.sha256),s.push(r));return s}(e),r=await Promise.all(s.map((async e=>({ref:e,result:await this.resolveRef(e,t)})))),n=new Map,o=[];for(const{ref:e,result:t}of r)t.ok?n.set(e.sha256,t.value):o.push({ref:e,error:t.error});return{resolved:n,errors:o}}async gc(){const e=Array.from(this.recordCache.values()).filter((e=>0===e.refCount));return await Promise.all(e.map((async e=>{await this.storage.deleteBytes(e.sha256),await this.storage.deleteRecord(e.sha256),this.recordCache.delete(e.sha256),this.bus.emit({name:"blobs:changed",payload:{sha256:e.sha256,record:null}})}))),e.length}async purge(e){return this.recordCache.has(e)?(await this.storage.deleteBytes(e),await this.storage.deleteRecord(e),this.recordCache.delete(e),k(void 0)):x({code:"NOT_FOUND",resource:"blob",id:e})}getRecord(e){return this.recordCache.get(e)??null}getAllRecords(){const e={};for(const[t,s]of this.recordCache)e[t]=s;return e}};var I=10,C=50,R=20,E=10,B=class{map=new Map;max;constructor(e){this.max=e}get(e){if(!this.map.has(e))return;const t=this.map.get(e);return this.map.delete(e),this.map.set(e,t),t}set(e,t){if(this.map.has(e)&&this.map.delete(e),this.map.set(e,t),this.map.size>this.max){const e=this.map.keys().next().value;void 0!==e&&this.map.delete(e)}}has(e){return this.map.has(e)}delete(e){this.map.delete(e)}};function D({index:e},t){switch(t.type){case"role:add":{const s=t.payload;if(e.roles[s.name])return x({code:"DUPLICATE_KEY",resource:"role",key:s.name});const r={name:s.name,label:s.label,description:s.description,preferences:s.preferences.length};return k({index:{roles:{[s.name]:r}}})}case"role:update":{const{name:s,...r}=t.payload;if(!e.roles[s])return x({code:"NOT_FOUND",resource:"role",id:s});const n=e.roles[s],o={...n,...r,preferences:r.preferences?.length??n.preferences};return k({index:{roles:{[s]:o}}})}case"role:delete":{const{name:s}=t.payload;if(!e.roles[s])return x({code:"NOT_FOUND",resource:"role",id:s});return Object.values(e.sessions).some((e=>e.role===s))?x({code:"INVALID_COMMAND",reason:`Cannot delete role "${s}" — it is still referenced by one or more sessions`}):k({index:{roles:{[s]:g()}}})}case"preference:add":{const s=t.payload,r={id:s.id,topics:s.topics,timestamp:s.timestamp,snippet:s.content.substring(0,100)},n={};return s.topics.forEach((r=>{const o=e.topics[r],a=[...o?.preferences??[],s.id],i=o?.contextKeys??[],c=o?.tasks??[],d=i.length+a.length+c.length;n[r]={topic:r,contextKeys:i,preferences:a,tasks:c,metadata:{created:o?.metadata?.created??t.timestamp,updated:t.timestamp,entries:d}}})),k({index:{preferences:{[s.id]:r},topics:n}})}case"preference:update":{const{id:s,...r}=t.payload;if(!e.preferences[s])return x({code:"NOT_FOUND",resource:"preference",id:s});const n=e.preferences[s],o={...n,...r,snippet:r.content?r.content.substring(0,100):n.snippet},a={};return r.topics&&(n.topics.forEach((r=>{const n=e.topics[r];if(n){const e=n.preferences.filter((e=>e!==s)),o=n.contextKeys.length+e.length+n.tasks.length;a[r]={preferences:e,metadata:{...n.metadata,updated:t.timestamp,entries:o}}}})),r.topics.forEach((r=>{const n=e.topics[r]??{contextKeys:[],preferences:[],tasks:[],metadata:{created:t.timestamp}},o=[...n.preferences,s],i=n.contextKeys.length+o.length+n.tasks.length;a[r]={topic:r,contextKeys:n.contextKeys,preferences:o,tasks:n.tasks,metadata:{created:n.metadata?.created??t.timestamp,updated:t.timestamp,entries:i}}}))),k({index:{preferences:{[s]:o},topics:a}})}case"preference:delete":{const{id:s}=t.payload;if(!e.preferences[s])return x({code:"NOT_FOUND",resource:"preference",id:s});const r=e.preferences[s],n={};return r.topics.forEach((r=>{const o=e.topics[r];if(o){const e=o.preferences.filter((e=>e!==s)),a=o.contextKeys.length+e.length+o.tasks.length;n[r]={preferences:e,metadata:{...o.metadata,updated:t.timestamp,entries:a}}}})),k({index:{preferences:{[s]:g()},topics:n}})}case"context:add":{const s=t.payload;if(e.context[s.key])return x({code:"DUPLICATE_KEY",resource:"context",key:s.key});const r=s.content,n={key:s.key,topics:s.topics,timestamp:s.timestamp,source:s.key.split(":")[0],preview:"text"===r.kind?r.value.substring(0,200):"json"===r.kind?JSON.stringify(r.value).substring(0,200):void 0,metadata:s.metadata},o={};return s.topics.forEach((r=>{const n=e.topics[r],a=[...n?.contextKeys??[],s.key],i=n?.preferences??[],c=n?.tasks??[],d=a.length+i.length+c.length;o[r]={topic:r,contextKeys:a,preferences:i,tasks:c,metadata:{created:n?.metadata?.created??t.timestamp,updated:t.timestamp,entries:d}}})),k({index:{context:{[s.key]:n},topics:o}})}case"context:update":{const{key:s,...r}=t.payload;if(!e.context[s])return x({code:"NOT_FOUND",resource:"context",id:s});const n=e.context[s],o=r.content,a={...n,...r,preview:o?"text"===o.kind?o.value.substring(0,200):"json"===o.kind?JSON.stringify(o.value).substring(0,200):void 0:n.preview},i={};return r.topics&&(n.topics.forEach((r=>{const n=e.topics[r];if(n){const e=n.contextKeys.filter((e=>e!==s)),o=e.length+n.preferences.length+n.tasks.length;i[r]={contextKeys:e,metadata:{...n.metadata,updated:t.timestamp,entries:o}}}})),r.topics.forEach((r=>{const n=e.topics[r]??{contextKeys:[],preferences:[],tasks:[],metadata:{created:t.timestamp}},o=n.contextKeys.includes(s)?n.contextKeys:[...n.contextKeys,s],a=o.length+n.preferences.length+n.tasks.length;i[r]={topic:r,contextKeys:o,preferences:n.preferences,tasks:n.tasks,metadata:{created:n.metadata?.created??t.timestamp,updated:t.timestamp,entries:a}}}))),k({index:{context:{[s]:a},topics:i}})}case"context:delete":{const{key:s}=t.payload;if(!e.context[s])return x({code:"NOT_FOUND",resource:"context",id:s});const r=e.context[s],n={};return r.topics.forEach((r=>{const o=e.topics[r];if(o){const e=o.contextKeys.filter((e=>e!==s)),a=e.length+o.preferences.length+o.tasks.length;n[r]={contextKeys:e,metadata:{...o.metadata,updated:t.timestamp,entries:a}}}})),k({index:{context:{[s]:g()},topics:n}})}case"session:create":{const{id:s,label:r,role:n,topics:o,preferences:a=[]}=t.payload;if(e.sessions[s])return x({code:"DUPLICATE_KEY",resource:"session",key:s});if(!e.roles[n])return x({code:"NOT_FOUND",resource:"role",id:n});const i={id:s,label:r,role:n,topics:o,preferences:a,metadata:{created:t.timestamp,updated:t.timestamp},flushedTurnCount:0,head:null,task:null};return k({index:{sessions:{[s]:i}}})}case"session:role:switch":{const{sessionId:s,role:r}=t.payload;return e.sessions[s]?k({index:{sessions:{[s]:{role:r,metadata:{updated:t.timestamp}}}}}):x({code:"NOT_FOUND",resource:"session",id:s})}case"session:topics:add":{const{sessionId:s,topics:r}=t.payload;if(!e.sessions[s])return x({code:"NOT_FOUND",resource:"session",id:s});const n=e.sessions[s],o=[...new Set([...n.topics,...r])];return k({index:{sessions:{[s]:{topics:o,metadata:{updated:t.timestamp}}}}})}case"session:preferences:override":{const{sessionId:s,preferences:r}=t.payload;return e.sessions[s]?k({index:{sessions:{[s]:{preferences:r,metadata:{updated:t.timestamp}}}}}):x({code:"NOT_FOUND",resource:"session",id:s})}case"session:fork":{const{sourceSessionId:s,newSessionId:r,label:n,role:o,topics:a}=t.payload;if(!e.sessions[s])return x({code:"NOT_FOUND",resource:"session",id:s});if(e.sessions[r])return x({code:"DUPLICATE_KEY",resource:"session",key:r});const i=e.sessions[s],c={id:r,label:n,role:o??i.role,topics:a??[...i.topics],preferences:[...i.preferences],metadata:{created:t.timestamp,updated:t.timestamp},flushedTurnCount:i.flushedTurnCount,head:i.head,task:i.task};return k({index:{sessions:{[r]:c}}})}case"session:delete":{const{sessionId:s}=t.payload;return e.sessions[s]?k({index:{sessions:{[s]:g()}}}):x({code:"NOT_FOUND",resource:"session",id:s})}case"task:add":{const s=t.payload;if(e.tasks[s.id])return x({code:"DUPLICATE_KEY",resource:"task",key:s.id});const r={id:s.id,title:s.title,status:s.status,steps:{completed:s.steps.filter((e=>e.completed)).length,total:s.steps.length},topics:s.topics},n={};return s.topics.forEach((r=>{const o=e.topics[r],a=[...o?.tasks??[],s.id],i=o?.contextKeys??[],c=o?.preferences??[],d=i.length+c.length+a.length;n[r]={topic:r,contextKeys:i,preferences:c,tasks:a,metadata:{created:o?.metadata?.created??t.timestamp,updated:t.timestamp,entries:d}}})),k({index:{tasks:{[s.id]:r},topics:n}})}case"task:update":{const{id:s,...r}=t.payload;if(!e.tasks[s])return x({code:"NOT_FOUND",resource:"task",id:s});const n=e.tasks[s],o={...n,...r,steps:r.steps?{completed:r.steps.filter((e=>e.completed)).length,total:r.steps.length}:n.steps},a={};return r.topics&&(n.topics.forEach((r=>{const n=e.topics[r];if(n){const e=n.tasks.filter((e=>e!==s)),o=n.contextKeys.length+n.preferences.length+e.length;a[r]={tasks:e,metadata:{...n.metadata,updated:t.timestamp,entries:o}}}})),r.topics.forEach((r=>{const n=e.topics[r]??{contextKeys:[],preferences:[],tasks:[],metadata:{created:t.timestamp}},o=[...new Set([...n.tasks,s])],i=n.contextKeys.length+n.preferences.length+o.length;a[r]={topic:r,contextKeys:n.contextKeys,preferences:n.preferences,tasks:o,metadata:{created:n.metadata?.created??t.timestamp,updated:t.timestamp,entries:i}}}))),k({index:{tasks:{[s]:o},topics:a}})}case"task:delete":{const{id:s}=t.payload;if(!e.tasks[s])return x({code:"NOT_FOUND",resource:"task",id:s});const r=e.tasks[s],n={};return r.topics.forEach((r=>{const o=e.topics[r];if(o){const e=o.tasks.filter((e=>e!==s)),a=o.contextKeys.length+o.preferences.length+e.length;n[r]={tasks:e,metadata:{...o.metadata,updated:t.timestamp,entries:a}}}})),k({index:{tasks:{[s]:g()},topics:n}})}case"turn:save":case"turn:add":{const{sessionId:s,turn:r}=t.payload;return e.sessions[s]?k({index:{sessions:{[s]:{head:{id:r.id,version:r.version},metadata:{updated:t.timestamp},flushedTurnCount:(e.sessions[s]?.flushedTurnCount??0)+1}}}}):x({code:"NOT_FOUND",resource:"session",id:s})}case"turn:edit":{const{sessionId:s,turnId:r,newVersion:n}=t.payload;return e.sessions[s]?k({index:{sessions:{[s]:{head:{id:r,version:n},metadata:{updated:t.timestamp}}}}}):x({code:"NOT_FOUND",resource:"session",id:s})}case"turn:branch":{const{sessionId:s,turn:r}=t.payload;return e.sessions[s]?k({index:{sessions:{[s]:{head:{id:r.id,version:r.version},metadata:{updated:t.timestamp}}}}}):x({code:"NOT_FOUND",resource:"session",id:s})}case"turn:delete":{const{sessionId:s,newHead:r}=t.payload;return e.sessions[s]?k({index:{sessions:{[s]:{head:r,metadata:{updated:t.timestamp}}}}}):x({code:"NOT_FOUND",resource:"session",id:s})}case"blob:register":case"tool:call":default:return k({});case"blob:retain":{const{sha256:s}=t.payload;return e.blobs[s]?k({}):x({code:"NOT_FOUND",resource:"blob",id:s})}case"blob:release":{const{sha256:s}=t.payload;return e.blobs[s]?k({}):x({code:"NOT_FOUND",resource:"blob",id:s})}case"blob:purge":{const{sha256:s}=t.payload;return e.blobs[s]?k({}):x({code:"NOT_FOUND",resource:"blob",id:s})}case"blob:record_remote_id":{const{sha256:s}=t.payload;return e.blobs[s]?k({}):x({code:"NOT_FOUND",resource:"blob",id:s})}}}function q(e){return Math.ceil(e.length/4)}function j(e,t){return Math.ceil(e/1024*t)}function U(e){if("text"===e.kind)return e.value;if("json"===e.kind){const t=[],s=e=>{"string"==typeof e?t.push(e):e&&"object"==typeof e&&Object.values(e).forEach(s)};return s(e.value),t.join(" ")}return""}function A(e,t){return{id:crypto.randomUUID(),version:0,owner:e,blocks:t,timestamp:(new Date).toISOString(),parent:null}}var M=class{rank(e){const{entries:t,recentMessages:s,config:r}=e,n=r.recentMessageWindow??3,o=r.minScore??0,a=r.freshnessHalfLifeDays??30;if(0===s.length)return[...t].sort(((e,t)=>this.freshnessWeight(t.timestamp,a)-this.freshnessWeight(e.timestamp,a)));const i=this.tokenize(s.slice(-n).join(" "));return t.map((e=>{const t=U(e.content);return{entry:e,score:.7*this.jaccardSimilarity(i,this.tokenize(t))+.3*this.freshnessWeight(e.timestamp,a)}})).filter((e=>e.score>o)).sort(((e,t)=>t.score-e.score)).map((e=>e.entry))}tokenize(e){return new Set(e.toLowerCase().replace(/[^\w\s]/g," ").split(/\s+/).filter((e=>e.length>2)))}jaccardSimilarity(e,t){if(0===e.size&&0===t.size)return 0;let s=0;for(const r of e)t.has(r)&&s++;const r=e.size+t.size-s;return 0===r?0:s/r}freshnessWeight(e,t){const s=(Date.now()-new Date(e).getTime())/864e5;return Math.pow(.5,s/t)}},P=class{plan(e){const{systemInstructions:t,persona:s,preferences:r,context:n,task:o,transcript:a,budget:i}=e;if(!i)return{preferences:r,context:n,task:o,transcript:a,truncated:{preferences:0,interactions:0,context:0},breakdown:{system:0,persona:0,preferences:0,transcript:0,context:0,tasks:0},totalUsed:0,lastRoleBeforeTruncation:null};const c=i.estimator??q,d=i.blobTokensPerKB??.25;let l=i.total;const u={system:0,persona:0,preferences:0,transcript:0,context:0,tasks:0},p=c(t??""),h=c(s);l-=p+h,u.system+=p,u.persona+=h;const f=[];let m=0;for(const e of r){const t=c(e.content);l>=t?(l-=t,u.preferences+=t,f.push(e)):m++}const y=[];let b=0,w=null;for(let e=a.length-1;e>=0;e--){const t=a[e],s=this.estimateTurnTokens(t,c,d);l>=s?(l-=s,u.transcript+=s,y.unshift(t)):(b++,"user"!==t.owner||w||(w=t.role??null))}const g=[];let v=0;for(const e of n){let t=c(U(e.content));"blob"===e.content.kind&&(t+=j(e.content.sizeBytes,d)),l>=t?(l-=t,u.context+=t,g.push(e)):v++}return{preferences:f,context:g,task:o,transcript:y,truncated:{preferences:m,interactions:b,context:v},breakdown:u,totalUsed:i.total-Math.max(0,l),lastRoleBeforeTruncation:w}}estimateTurnTokens(e,t,s){return e.blocks.reduce(((e,r)=>{switch(r.type){case"text":return e+t(r.text);case"tool:use":return e+t(JSON.stringify(r.input));case"tool:result":return e+t("string"==typeof r.content?r.content:JSON.stringify(r.content));case"thinking":return e+t(r.thinking);case"image":case"document":{const t=r.ref;return t?e+j(t.sizeBytes,s):e}default:return e}}),0)}},F=class{assemble(e){const{session:t,plan:r,resolvedBlobs:n,summaryBlockText:o,warnings:a,conflicts:i,budgetTotal:c}=e,d=[],l=[];for(const e of r.context)if("text"===e.content.kind||"json"===e.content.kind)d.push(e);else if("blob"===e.content.kind){const t=n.get(e.content.sha256);t&&l.push(this.buildReferentialBlock(e.content,t))}const u=[];if(l.length>0&&u.push(A("user",l)),o||r.truncated.interactions>0){const e=[];o&&e.push({type:"summary",text:o,id:"summary"}),r.truncated.interactions>0&&e.push({id:"notice",type:"text",text:`[${r.truncated.interactions} earlier turn(s) omitted due to token budget]`}),u.push(A("user",e)),u.push(A("assistant",[{id:s.v7(),type:"text",text:"Understood."}]))}let p=r.lastRoleBeforeTruncation,h=null!==r.lastRoleBeforeTruncation;for(const e of r.transcript){const t=this.resolveTurnBlocks(e,n);"user"===e.owner&&e.role&&h&&e.role!==p&&t.unshift({type:"role:transition",previousRole:p,newRole:e.role}),"user"===e.owner&&(p=e.role??null,h=!0),u.push({...e,blocks:t})}return{system:{instructions:t.instructions,persona:t.role.persona,preferences:r.preferences,context:d,task:r.task},context:r.context,transcript:{turns:u},budget:{total:c,used:r.totalUsed,breakdown:r.breakdown},truncated:r.truncated,warnings:a,conflicts:i}}buildReferentialBlock(e,t){return e.mediaType.startsWith("image/")?{type:"image",blob:t}:{type:"document",blob:t,title:e.filename}}resolveTurnBlocks(e,t){return e.blocks.map((e=>{if("image"===e.type||"document"===e.type){const s=e.ref;if(s){const r=t.get(s.sha256);if(r)return{...e,blob:r}}}return e}))}},$=class{constructor(e,t){this._owner=e,this._turn=t?structuredClone(t):{id:s.v7(),version:0,owner:this._owner,blocks:[],timestamp:(new Date).toISOString(),role:void 0,parent:null}}_turn;addText(e){const t={id:s.v7(),type:"text",text:e};return this._turn.blocks.push(t),this}addImage(e,t){const r={id:s.v7(),type:"image",ref:e,altText:t};return this._turn.blocks.push(r),this}addDocument(e,t){const r={id:s.v7(),type:"document",ref:e,title:t};return this._turn.blocks.push(r),this}addToolUse(e,t){const r={id:s.v7(),type:"tool:use",name:e,input:t};return this._turn.blocks.push(r),this}addToolResult(e,t,r){const n={id:s.v7(),type:"tool:result",useId:e,content:t,isError:r};return this._turn.blocks.push(n),this}addSummary(e){const t={id:s.v7(),type:"summary",text:e};return this._turn.blocks.push(t),this}addRoleTransition(e,t){const r={id:s.v7(),type:"role:transition",previousRole:e,newRole:t};return this._turn.blocks.push(r),this}addThinking(e){const t={id:s.v7(),type:"thinking",thinking:e};return this._turn.blocks.push(t),this}addTaskProposal(e,t,r="create",n){const o=t.map((e=>({id:e.id??s.v7(),text:e.text,status:e.status??"todo"}))),a={id:s.v7(),type:"task:proposal",title:e,steps:o,action:r,taskId:n};return this._turn.blocks.push(a),this}addBlock(e){return this._turn.blocks.push(e),this}deleteBlock(e){return this._turn.blocks=this._turn.blocks.filter((t=>t.id!==e)),this}editTextBlock(e,t){const s=this._turn.blocks.findIndex((t=>t.id===e));if(-1===s)throw new Error(`Block with ID ${e} not found.`);const r=this._turn.blocks[s];if("text"!==r.type)throw new Error(`Block with ID ${e} is not a TextBlock.`);return this._turn.blocks[s]={...r,text:t},this}withId(e){return this._turn.id=e,this}withVersion(e){return this._turn.version=e,this}withTimestamp(e){return this._turn.timestamp=e,this}withParent(e){return this._turn.parent=e,this}withRoleSnapshot(e){return this._turn.role=e,this}build(){return structuredClone(this._turn)}},K=class{constructor(e,t,s){this.sessionId=e,this.tree=t,this.manager=s}async turns(){return this.tree.buildActiveChain(this.sessionId)}async siblings(e){return this.tree.getTurnSiblings(e,this.sessionId)}async branchInfo(e){return this.tree.branchInfo(e,this.sessionId)}id(){return this.sessionId}startTurn(e){return new $(e)}async addTurn(e,t){if(!e.index.sessions[this.sessionId])return x({code:"NOT_FOUND",resource:"session",id:this.sessionId});const s={...t,version:t.version??0};return this.manager.dispatch(e,{type:"turn:add",payload:{sessionId:this.sessionId,turn:s},timestamp:s.timestamp})}async editTurn(e,t,s,r){if(!e.index.sessions[this.sessionId])return x({code:"NOT_FOUND",resource:"session",id:this.sessionId});const n=await this.tree.loadTurnVersions(this.sessionId,t);if(0===n.length)return x({code:"NOT_FOUND",resource:"turn",id:t});const o=Math.max(...n.map((e=>e.version))),a=n.find((e=>e.version===o)),i=o+1,c=(new Date).toISOString();return this.manager.dispatch(e,{type:"turn:edit",payload:{sessionId:this.sessionId,turnId:t,newBlocks:s,roleSnapshot:r??a.role,newVersion:i},timestamp:c})}async branch(e,t){return e.index.sessions[this.sessionId]?t.parent?this.manager.dispatch(e,{type:"turn:branch",payload:{sessionId:this.sessionId,turn:t},timestamp:t.timestamp}):x({code:"INVALID_COMMAND",reason:"branchFrom requires turn.parent to be set"}):x({code:"NOT_FOUND",resource:"session",id:this.sessionId})}async deleteTurn(e,t,s,r){if(!e.index.sessions[this.sessionId])return x({code:"NOT_FOUND",resource:"session",id:this.sessionId});const n=await this.tree.loadTurnVersions(this.sessionId,t);if(0===n.length)return x({code:"NOT_FOUND",resource:"turn",id:t});return n.some((e=>e.version===s))?this.manager.dispatch(e,{type:"turn:delete",payload:{sessionId:this.sessionId,turnId:t,version:s,newHead:r},timestamp:(new Date).toISOString()}):x({code:"NOT_FOUND",resource:"turn version",id:`${t}:${s}`})}async switchVersionLeft(e,t){return this.switchVersion(e,t,-1)}async switchVersionRight(e,t){return this.switchVersion(e,t,1)}async switchVersion(e,t,s){if(!e.index.sessions[this.sessionId])return x({code:"NOT_FOUND",resource:"session",id:this.sessionId});const r=await this.tree.buildNodeGraph(this.sessionId),n=r[t];if(!n)return x({code:"NOT_FOUND",resource:"turn",id:t});const o=Object.keys(n.versions).map(Number).sort(((e,t)=>e-t)),a=o.indexOf(n.activeVersion);if(-1===a)return x({code:"INVALID_COMMAND",reason:"Active version not found in version list"});const i=a+s;if(i<0||i>=o.length)return x({code:"INVALID_COMMAND",reason:`No ${s<0?"previous":"next"} version available for turn ${t}`});const c=function(e,t,s){let r=t,n=s;for(;;){const t=e[r];if(!t)break;const s=t.children[n];if(!s||0===s.length)break;const o=s[0],a=e[o];if(!a)break;r=o,n=a.activeVersion}return{id:r,version:n}}(r,t,o[i]);await this.tree.setHead(this.sessionId,c);const d=(new Date).toISOString();return k({index:{sessions:{[this.sessionId]:{head:c,metadata:{updated:d}}}}})}async resolve(e){if(!e.index.sessions[this.sessionId])return x({code:"NOT_FOUND",resource:"session",id:this.sessionId});const t=(await this.turns()).map((e=>e.versions[e.activeVersion]));return this.manager.resolveSession(e,this.sessionId,t)}};var z="blob_bytes",V="blob_records";function L(e){return new Promise(((t,s)=>{e.onsuccess=()=>t(e.result),e.onerror=()=>s(e.error)}))}function H(e){return new Promise(((t,s)=>{e.oncomplete=()=>t(),e.onerror=()=>s(e.error),e.onabort=()=>s(new Error("Transaction aborted"))}))}exports.BlobStore=N,exports.COLLECTIONS=y,exports.ContentStore=class e{db;tree;blobs;roleCache;preferenceCache;contextCache;taskCache;bus;subscribe(e,t){return this.bus.subscribe(e,t)}constructor(e,t,s,r={}){this.db=e,this.tree=new S(e),this.blobs=new N(t,s);const n={roles:r.cache?.roles??I,preferences:r.cache?.preferences??C,context:r.cache?.context??R,tasks:r.cache?.tasks??E};this.roleCache=new B(n.roles),this.preferenceCache=new B(n.preferences),this.contextCache=new B(n.context),this.taskCache=new B(n.tasks),this.bus=s}static async create(t,s,r,n){const o=new e(t,s,r,n);return await o.init(),o}async init(e){await this.db.open(e),await this.blobs.init()}getTurnTree(){return this.tree}async getRole(e){const t=this.roleCache.get(e);if(t)return k(t);const s=await this.db.collection(y.ROLE),r=await s.find({field:"name",operator:"eq",value:e});if(!r)return x({code:"NOT_FOUND",resource:"role",id:e});const n=r.state();return this.roleCache.set(e,n),k(n)}async saveRole(e){const t=await this.db.collection(y.ROLE),s=await t.find({field:"name",operator:"eq",value:e.name});s?await s.update(e):await t.create(e),this.roleCache.set(e.name,e)}async deleteRole(e){const t=await this.db.collection(y.ROLE),s=await t.find({field:"name",operator:"eq",value:e});s&&await s.delete(),this.roleCache.delete(e)}async getPreference(e){const t=this.preferenceCache.get(e);if(t)return k(t);const s=await this.db.collection(y.PREFERENCE),r=await s.find({field:"id",operator:"eq",value:e});if(!r)return x({code:"NOT_FOUND",resource:"preference",id:e});const n=r.state();return this.preferenceCache.set(e,n),k(n)}async savePreference(e){const t=await this.db.collection(y.PREFERENCE),s=await t.find({field:"id",operator:"eq",value:e.id});s?await s.update(e):await t.create(e),this.preferenceCache.set(e.id,e)}async deletePreference(e){const t=await this.db.collection(y.PREFERENCE),s=await t.find({field:"id",operator:"eq",value:e});s&&await s.delete(),this.preferenceCache.delete(e)}async getContext(e){const t=this.contextCache.get(e);if(t)return k(t);const s=await this.db.collection(y.CONTEXT),r=await s.find({field:"key",operator:"eq",value:e});if(!r)return x({code:"NOT_FOUND",resource:"context",id:e});const n=r.state();return this.contextCache.set(e,n),k(n)}async saveContext(e){const t=await this.db.collection(y.CONTEXT),s=await t.find({field:"key",operator:"eq",value:e.key});s?await s.update(e):await t.create(e),this.contextCache.set(e.key,e)}async deleteContext(e){const t=await this.db.collection(y.CONTEXT),s=await t.find({field:"key",operator:"eq",value:e});s&&await s.delete(),this.contextCache.delete(e)}async getContextByTopics(e,t){const s=new Set;for(const r of t){const t=e.topics[r];t&&t.contextKeys.forEach((e=>s.add(e)))}if(0===s.size)return[];const r=[],n=[];for(const e of s){const t=this.contextCache.get(e);t?n.push(t):r.push(e)}let o=[];if(r.length>0){const e=await this.db.collection(y.CONTEXT),t=await e.filter({operator:"or",conditions:r.map((e=>({field:"key",operator:"eq",value:e})))});for(const e of t){const t=e.state();this.contextCache.set(t.key,t),o.push(t)}}return[...n,...o].sort(((e,t)=>new Date(t.timestamp).getTime()-new Date(e.timestamp).getTime()))}async getTask(e){const t=this.taskCache.get(e);if(t)return k(t);const s=await this.db.collection(y.TASK),r=await s.find({field:"id",operator:"eq",value:e});if(!r)return x({code:"NOT_FOUND",resource:"task",id:e});const n=r.state();return this.taskCache.set(e,n),k(n)}async saveTask(e){const t=await this.db.collection(y.TASK),s=await t.find({field:"id",operator:"eq",value:e.id});s?await s.update(e):await t.create(e),this.taskCache.set(e.id,e)}async deleteTask(e){const t=await this.db.collection(y.TASK),s=await t.find({field:"id",operator:"eq",value:e});s&&await s.delete(),this.taskCache.delete(e)}async getTasksByTopics(e,t){const s=new Set;for(const r of t){const t=e.topics[r];t&&t.tasks&&t.tasks.forEach((e=>s.add(e)))}if(0===s.size)return[];const r=[],n=[];for(const e of s){const t=this.taskCache.get(e);t?n.push(t):r.push(e)}let o=[];if(r.length>0){const e=await this.db.collection(y.TASK),t=await e.filter({operator:"or",conditions:r.map((e=>({field:"id",operator:"eq",value:e})))});for(const e of t){const t=e.state();this.taskCache.set(t.id,t),o.push(t)}}return[...n,...o].sort(((e,t)=>new Date(t.updated).getTime()-new Date(e.updated).getTime()))}async saveSession(e){const t=await this.db.collection(y.SESSION),s=await t.find({field:"id",operator:"eq",value:e.id}),r=T(e);s?await s.update(r):await t.create(r)}async updateSessionMeta(e,t){const s=await this.db.collection(y.SESSION),r=await s.find({field:"id",operator:"eq",value:e});if(!r)return;const n=r.state(),o=v(n,t);await r.update(T(o))}async deleteSession(e){const t=await this.db.collection(y.SESSION),s=await t.find({field:"id",operator:"eq",value:e});s&&await s.delete()}async registerBlob(e,t,s){return this.blobs.register(e,t,s)}async retainBlob(e){return this.blobs.retain(e)}async releaseBlob(e){return this.blobs.release(e)}async purgeBlob(e){return this.blobs.purge(e)}async recordBlobRemoteId(e,t,s){return this.blobs.recordRemoteId(e,t,s)}getBlobRecord(e){return this.blobs.getRecord(e)}getAllBlobRecords(){return this.blobs.getAllRecords()}getBlobResolver(){return this.blobs.resolveRefs.bind(this.blobs)}async appendTurn(e,t){return k(await this.tree.append(e,t))}async saveTurn(e,t){return k(await this.tree.save(e,t))}async editTurn(e,t,s,r,n){const o=(await this.tree.loadTurnVersions(e,t)).find((e=>e.version===r-1));if(!o)return x({code:"NOT_FOUND",resource:"turn",id:t});const a={id:t,version:r,owner:o.owner,blocks:s,timestamp:(new Date).toISOString(),role:n??o.role,parent:o.parent};await this.tree.replaceVersion(e,a);const i=await this.tree.getHead(e);return i?.id===t&&await this.tree.setHead(e,{id:a.id,version:a.version}),k(void 0)}async branchTurn(e,t){return await this.tree.branch(e,t),k(void 0)}async deleteTurnSubtree(e,t,s,r){return await this.tree.deleteSubtree(e,t,s,r),k(void 0)}async copyTranscript(e,t){await this.tree.copyTranscript(e,t)}async resolveSession(e,t,s){const r=e.index.sessions[t];if(!r)return x({code:"NOT_FOUND",resource:"session",id:t});const n=await this.getRole(r.role);if(!n.ok)return n;const o=n.value,a=function(e,t){return e.preferences.length>0?e.preferences:t.preferences}(r,o),i=function(e,t){return e.filter((e=>0===e.topics.length||e.topics.some((e=>t.includes(e)))))}((await Promise.all(a.map((e=>this.getPreference(e))))).filter((e=>e.ok)).map((e=>e.value)),r.topics),c=await this.getContextByTopics(e.index,r.topics),d=await this.getTasksByTopics(e.index,r.topics);let l=null;if(r.task&&!d.find((e=>e.id===r.task))){const e=await this.getTask(r.task);e.ok&&(l=e.value)}const u=s??await this.tree.getActiveChain(t),p={session:r,role:o,preferences:i,context:c,task:l,transcript:u,instructions:e.settings?.prompt};return k({...p,preferences:Object.freeze([...p.preferences]),context:Object.freeze([...p.context]),transcript:Object.freeze([...p.transcript])})}async gc(){return this.blobs.gc()}},exports.IndexedDBBlobStorage=class{dbName;db=null;constructor(e={}){this.dbName=e.dbName??"aiworkspace-blobs"}async open(){this.db||(this.db=await new Promise(((e,t)=>{const s=indexedDB.open(this.dbName,1);s.onupgradeneeded=e=>{const t=e.target.result;this.createSchema(t)},s.onsuccess=()=>e(s.result),s.onerror=()=>t(s.error),s.onblocked=()=>t(new Error(`[IndexedDBBlobStorage] Database "${this.dbName}" blocked.`))})),this.db.onversionchange=()=>{this.db?.close(),this.db=null})}createSchema(e){e.objectStoreNames.contains(z)||e.createObjectStore(z,{keyPath:"sha256"}),e.objectStoreNames.contains(V)||e.createObjectStore(V,{keyPath:"sha256"})}close(){this.db?.close(),this.db=null}async deleteDatabase(){this.close(),await new Promise(((e,t)=>{const s=indexedDB.deleteDatabase(this.dbName);s.onsuccess=()=>e(),s.onerror=()=>t(s.error)}))}getDB(){if(!this.db)throw new Error("[IndexedDBBlobStorage] Database not open. Call open() first.");return this.db}readTx(...e){return this.getDB().transaction(e,"readonly")}writeTx(...e){return this.getDB().transaction(e,"readwrite")}async storeBytes(e,t){const s=this.readTx(z);if(await L(s.objectStore(z).get(e)))return;const r=this.writeTx(z);r.objectStore(z).put({sha256:e,data:t}),await H(r)}async loadBytes(e){const t=this.readTx(z),s=await L(t.objectStore(z).get(e));return s?.data??null}async hasBytes(e){const t=this.readTx(z);return await L(t.objectStore(z).count(e))>0}async deleteBytes(e){const t=this.writeTx(z);t.objectStore(z).delete(e),await H(t)}async saveRecord(e){const t=this.writeTx(V);t.objectStore(V).put(e),await H(t)}async loadRecord(e){const t=this.readTx(V);return await L(t.objectStore(V).get(e))??null}async deleteRecord(e){const t=this.writeTx(V);t.objectStore(V).delete(e),await H(t)}async listRecords(){return L(this.readTx(V).objectStore(V).getAll())}async exportAllBytes(){const e=this.readTx(z);return(await L(e.objectStore(z).getAll())).map((({sha256:e,data:t})=>[e,t]))}async registerBlob(e,t){await new Promise(((s,r)=>{const n=this.getDB().transaction([z,V],"readwrite"),o=n.objectStore(z),a=n.objectStore(V),i=o.count(e.sha256);i.onsuccess=()=>{0===i.result&&o.put({sha256:e.sha256,data:t}),a.put(e)},i.onerror=()=>r(i.error),n.oncomplete=()=>s(),n.onerror=()=>r(n.error),n.onabort=()=>r(new Error("registerBlob transaction aborted"))}))}},exports.MemoryBlobStorage=class{bytes=new Map;records=new Map;async storeBytes(e,t){this.bytes.has(e)||this.bytes.set(e,t)}async loadBytes(e){return this.bytes.get(e)??null}async hasBytes(e){return this.bytes.has(e)}async deleteBytes(e){this.bytes.delete(e)}async saveRecord(e){this.records.set(e.sha256,{...e})}async loadRecord(e){return this.records.get(e)??null}async deleteRecord(e){this.records.delete(e)}async listRecords(){return Array.from(this.records.values()).map((e=>({...e})))}async exportAllBytes(){return Array.from(this.bytes.entries()).map((([e,t])=>[e,new Uint8Array(t)]))}async registerBlob(e,t){this.bytes.has(e.sha256)||this.bytes.set(e.sha256,t),this.records.set(e.sha256,{...e})}},exports.PromptBuilder=class{retriever;planner;assembler;summarizer;blobResolver;constructor(e){this.blobResolver=e.blobResolver,this.retriever=e.retriever??new M,this.planner=e.planner??new P,this.assembler=e.assembler??new F,this.summarizer=e.summarizer}async build(e,t={}){const s=[],{resolved:r,conflicts:n}=this.resolvePreferenceConflicts(e.preferences);n.length>0&&s.push(`${n.length} preference conflict(s) resolved.`);const o=this.extractRecentUserQueries(e.transcript,t.relevanceConfig),a=this.retriever.rank({entries:e.context,recentMessages:o,config:t.relevanceConfig??{}});let i=e.transcript,c=null;if(this.summarizer&&i.length>0){const e=t.tokenBudget?Math.floor(.25*t.tokenBudget.total):2e3,s=await this.summarizer.summarize(i,e);c=s.summary,i=s.remaining}const d=this.planner.plan({systemInstructions:e.instructions,persona:e.role.persona,preferences:r,context:a,task:e.task,transcript:i,budget:t.tokenBudget}),l=this.collectUsedBlobRefs(d.context,d.transcript),u=this.deduplicateBlobRefs(l),{resolved:p,errors:h}=await this.blobResolver(u,t.providerId??null);for(const e of h)s.push(`Failed to resolve blob ${e.ref.sha256.slice(0,8)}: ${e.error.code}`);const f=u.filter((e=>!p.has(e.sha256)));return f.length>0&&s.push(`${f.length} blob(s) unresolved and omitted: `+f.map((e=>e.sha256.slice(0,8))).join(", ")),d.truncated.preferences>0&&s.push(`${d.truncated.preferences} preference(s) dropped.`),d.truncated.interactions>0&&s.push(`${d.truncated.interactions} turn(s) trimmed.`),d.truncated.context>0&&s.push(`${d.truncated.context} context entry/entries dropped.`),this.assembler.assemble({session:e,plan:d,resolvedBlobs:p,summaryBlockText:c,warnings:s,conflicts:n,budgetTotal:t.tokenBudget?.total??0})}collectUsedBlobRefs(e,t){const s=[];for(const t of e)"blob"===t.content.kind&&s.push(t.content);for(const e of t)for(const t of e.blocks)if("image"===t.type||"document"===t.type){const e=t.ref;e&&s.push(e)}return s}deduplicateBlobRefs(e){const t=new Set,s=[];for(const r of e)t.has(r.sha256)||(t.add(r.sha256),s.push(r));return s}extractRecentUserQueries(e,t){const s=t?.recentMessageWindow??3;return e.filter((e=>"user"===e.owner)).slice(-s).flatMap((e=>e.blocks.filter((e=>"text"===e.type)).map((e=>e.text))))}resolvePreferenceConflicts(e){const t=[],s=new Map;for(const r of e)if(0!==r.topics.length)for(const e of r.topics){const n=s.get(e);if(!n){s.set(e,r);continue}const o=new Date(n.timestamp).getTime(),a=new Date(r.timestamp).getTime();a>o?(t.push({topic:e,kept:r.id,dropped:n.id,reason:"superseded_by_newer"}),s.set(e,r)):o>a&&t.push({topic:e,kept:n.id,dropped:r.id,reason:"superseded_by_newer"})}const r=new Set(t.map((e=>e.dropped)));return{resolved:e.filter((e=>!r.has(e.id))),conflicts:Array.from(new Set(t))}}},exports.Session=K,exports.SessionManager=class{workspaceManager;contentStore;constructor(e,t){this.workspaceManager=e,this.contentStore=t}async open(e,t){if(!e.index.sessions[t])return x({code:"NOT_FOUND",resource:"session",id:t});try{return k({session:new K(t,this.contentStore.getTurnTree(),this.workspaceManager),patch:{}})}catch(e){return x({code:"BACKEND_ERROR",reason:e instanceof Error?e.message:String(e)})}}get workspace(){return this.workspaceManager}async close(e){}},exports.TurnTree=S,exports.WorkspaceManager=class{contentStore;permissionGuard;toolRegistry;bus;subscribe(e,t){return this.bus.subscribe(e,t)}constructor(e){this.contentStore=e.contentStore,this.permissionGuard=e.permissionGuard,this.toolRegistry=e.toolRegistry,this.bus=e.eventBus,this.bus.subscribe("blobs:changed",(({sha256:e,record:t})=>{const s={index:{blobs:{[e]:t??void 0}}};this.bus.emit({name:"workspace:changed",payload:s})})),this.toolRegistry&&this.toolRegistry.onRegistryChanged((e=>{this.bus.emit({name:"workspace:changed",payload:{index:{tools:e.reduce(((e,t)=>(e[t.name]=t,e)),{})}}})}))}init(e){if(!this.toolRegistry)return{};const t={};for(const e of this.toolRegistry.list())t[e.name]=e;return{index:{tools:t}}}reduce(e,t){return D(e,t)}async dispatch(e,t){if(this.permissionGuard){const e="tool:call"===t.type?{type:"tool",payload:t.payload}:{type:"command",payload:t},s=await this.permissionGuard.authenticate(e);if(!s.ok)return s}const s=D(e,t);if(!s.ok)return s;let r={};try{r=await this.handleContentSideEffects(e,t)}catch(e){return x({code:"BACKEND_ERROR",reason:e instanceof Error?e.message:String(e)})}return k(v(s.value,r))}async resolveSession(e,t,s){return this.contentStore.resolveSession(e,t,s)}async handleContentSideEffects(e,t){switch(t.type){case"blob:register":{const{data:e,mediaType:s,filename:r}=t.payload,n=await this.contentStore.registerBlob(e,s,r);if(!n.ok)throw Object.assign(new Error(n.error.code),{wsError:n.error});const o=n.value,a=this.contentStore.getBlobRecord(o.sha256);if(!a)throw new Error("Record missing after register");return{index:{blobs:{[o.sha256]:a}}}}case"blob:retain":{const{sha256:e}=t.payload,s=await this.contentStore.retainBlob(e);if(!s.ok)throw Object.assign(new Error(s.error.code),{wsError:s.error});const r=this.contentStore.getBlobRecord(e);return{index:{blobs:{[e]:r??void 0}}}}case"blob:release":{const{sha256:e}=t.payload,s=await this.contentStore.releaseBlob(e);if(!s.ok)throw Object.assign(new Error(s.error.code),{wsError:s.error});const r=this.contentStore.getBlobRecord(e);return{index:{blobs:{[e]:r??void 0}}}}case"blob:purge":{const{sha256:e}=t.payload,s=await this.contentStore.purgeBlob(e);if(!s.ok)throw Object.assign(new Error(s.error.code),{wsError:s.error});return{index:{blobs:{[e]:void 0}}}}case"blob:record_remote_id":{const{sha256:e,providerId:s,fileId:r}=t.payload,n=await this.contentStore.recordBlobRemoteId(e,s,r);if(!n.ok)throw Object.assign(new Error(n.error.code),{wsError:n.error});const o=this.contentStore.getBlobRecord(e);return{index:{blobs:{[e]:o??void 0}}}}case"role:add":return await this.contentStore.saveRole(t.payload),{};case"role:update":{const{name:e,...s}=t.payload,r=await this.contentStore.getRole(e);if(!r.ok)throw new Error(`role:update — "${e}" not found`);return await this.contentStore.saveRole({...r.value,...s,name:e}),{}}case"role:delete":return await this.contentStore.deleteRole(t.payload.name),{};case"preference:add":return await this.contentStore.savePreference(t.payload),{};case"preference:update":{const{id:e,...s}=t.payload,r=await this.contentStore.getPreference(e);if(!r.ok)throw new Error(`preference:update — "${e}" not found`);return await this.contentStore.savePreference({...r.value,...s,id:e}),{}}case"preference:delete":return await this.contentStore.deletePreference(t.payload.id),{};case"context:add":case"context:update":return await this.contentStore.saveContext(t.payload),{};case"context:delete":return await this.contentStore.deleteContext(t.payload.key),{};case"task:add":return await this.contentStore.saveTask(t.payload),{};case"task:update":{const{id:e,...s}=t.payload,r=await this.contentStore.getTask(e);if(!r.ok)throw new Error(`task:update — "${e}" not found`);return await this.contentStore.saveTask({...r.value,...s,id:e}),{}}case"task:delete":return await this.contentStore.deleteTask(t.payload.id),{};case"session:create":{const{id:e,label:s,role:r,topics:n,preferences:o=[]}=t.payload;return await this.contentStore.saveSession({id:e,label:s,role:r,topics:n,preferences:o,metadata:{created:t.timestamp,updated:t.timestamp},flushedTurnCount:0,head:null,task:null}),{}}case"session:fork":{const{sourceSessionId:s,newSessionId:r,label:n,role:o,topics:a}=t.payload;if(!e.index.sessions[s])throw new Error(`session:fork — source session "${s}" not found`);await this.contentStore.copyTranscript(s,r);const i=e.index.sessions[s],c={id:r,label:n,role:o??i.role,topics:a??[...i.topics],preferences:[...i.preferences],metadata:{created:t.timestamp,updated:t.timestamp},flushedTurnCount:i.flushedTurnCount,head:i.head?{...i.head}:null,task:i.task};return await this.contentStore.saveSession(c),{}}case"session:delete":return await this.contentStore.deleteSession(t.payload.sessionId),{};case"session:role:switch":case"session:topics:add":case"session:preferences:override":{const e=t.payload.sessionId,s=await this.contentStore.db.collection("session"),r=await s.find({field:"id",operator:"eq",value:e});if(!r)return{};if("session:role:switch"===t.type)await this.contentStore.updateSessionMeta(e,{role:t.payload.role});else if("session:topics:add"===t.type){const s=r.state();await this.contentStore.updateSessionMeta(e,{topics:[...new Set([...s.topics,...t.payload.topics])]})}else await this.contentStore.updateSessionMeta(e,{preferences:t.payload.preferences});return{}}case"turn:add":return await this.contentStore.appendTurn(t.payload.sessionId,t.payload.turn),{};case"turn:save":return await this.contentStore.saveTurn(t.payload.sessionId,t.payload.turn),{};case"turn:edit":{const{sessionId:e,turnId:s,newBlocks:r,newVersion:n,roleSnapshot:o}=t.payload;return await this.contentStore.editTurn(e,s,r,n,o),{}}case"turn:branch":return await this.contentStore.branchTurn(t.payload.sessionId,t.payload.turn),{};case"turn:delete":{const{sessionId:e,turnId:s,version:r,newHead:n}=t.payload;return await this.contentStore.deleteTurnSubtree(e,s,r,n),{}}case"tool:call":{if(!this.toolRegistry)throw new Error("tool:call — no toolRegistry configured");const e=await this.toolRegistry.execute(t.payload);if(!e.ok)throw Object.assign(new Error(e.error.code),{wsError:e.error});return{}}default:return{}}}},exports.computeSHA256=_,exports.createProjectWorkspace=function({project:e,language:t}){const r={...e,id:s.v7()};return{id:s.v7(),settings:{language:t},project:r,index:{roles:{},topics:{},preferences:{},context:{},sessions:{},blobs:{},tasks:{},tools:{}}}},exports.createSimpleWorkspace=function({name:e,owner:t,language:r}){return{id:s.v7(),settings:{language:r},project:{id:s.v7(),name:e,owner:t},index:{roles:{},topics:{},preferences:{},context:{},sessions:{},blobs:{},tasks:{},tools:{}}}},exports.createWorkspaceDatabase=function(e){const t=new m({retry:!0,throws:!0}),s=new m({retry:!0,throws:!0});return{open:async(s=[])=>(await t.do((async()=>{const t=[...u,...s];await e.setupCollections(t)}))).value,collection:async t=>e.collection(t),close:async()=>(await s.do((()=>{e.close()}))).value}},exports.del=g,exports.err=x,exports.extractBlobRecord=function(e){const t=e?.index?.blobs;if(!t)return null;const s=t[Object.keys(t)[0]];return s||null},exports.extractBlobRef=function(e){return{sha256:e.sha256,mediaType:e.mediaType,sizeBytes:e.sizeBytes,filename:e.filename,previewUrl:e.previewUrl}},exports.merge=v,exports.ok=k,exports.omitNullUndefined=T,exports.workspaceReducer=D;
|
package/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{v7 as e}from"uuid";var t,s,r=Object.create,n=Object.defineProperty,o=Object.getOwnPropertyDescriptor,i=Object.getOwnPropertyNames,a=Object.getPrototypeOf,c=Object.prototype.hasOwnProperty,d=(e,t,s)=>(s=null!=e?r(a(e)):{},((e,t,s,r)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let a of i(t))c.call(e,a)||a===s||n(e,a,{get:()=>t[a],enumerable:!(r=o(t,a))||r.enumerable});return e})(e&&e.__esModule?s:n(s,"default",{value:e,enumerable:!0}),e)),l=(t={"node_modules/@asaidimu/events/index.js"(e,t){var s,r=Object.defineProperty,n=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyNames,i=Object.prototype.hasOwnProperty,a={};((e,t)=>{for(var s in t)r(e,s,{get:t[s],enumerable:!0})})(a,{createEventBus:()=>c}),t.exports=(s=a,((e,t,s,a)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let c of o(t))i.call(e,c)||c===s||r(e,c,{get:()=>t[c],enumerable:!(a=n(t,c))||a.enumerable});return e})(r({},"__esModule",{value:!0}),s));var c=(e={async:!1,batchSize:1e3,batchDelay:16,errorHandler:e=>console.error("EventBus Error:",e),crossTab:!1,channelName:"event-bus-channel"})=>{const t=new Map;let s=[],r=0,n=0;const o=new Map,i=new Map;let a=null;e.crossTab&&"undefined"!=typeof BroadcastChannel?a=new BroadcastChannel(e.channelName):e.crossTab&&console.warn("BroadcastChannel is not supported in this browser. Cross-tab notifications are disabled.");const c=(e,t)=>{r++,n+=t,o.set(e,(o.get(e)||0)+1)},d=()=>{const t=s;s=[],t.forEach((({name:t,payload:s})=>{const r=performance.now();try{(i.get(t)||[]).forEach((e=>e(s)))}catch(r){e.errorHandler({...r,eventName:t,payload:s})}c(t,performance.now()-r)}))},l=(()=>{let t;return()=>{clearTimeout(t),t=setTimeout(d,e.batchDelay)}})(),u=e=>{const s=t.get(e);s?i.set(e,Array.from(s)):i.delete(e)};return a&&(a.onmessage=e=>{const{name:t,payload:s}=e.data;(i.get(t)||[]).forEach((e=>e(s)))}),{subscribe:(e,s)=>{t.has(e)||t.set(e,new Set);const r=t.get(e);return r.add(s),u(e),()=>{r.delete(s),0===r.size?(t.delete(e),i.delete(e)):u(e)}},emit:({name:t,payload:r})=>{if(e.async)return s.push({name:t,payload:r}),s.length>=e.batchSize?d():l(),void(a&&a.postMessage({name:t,payload:r}));const n=performance.now();try{(i.get(t)||[]).forEach((e=>e(r))),a&&a.postMessage({name:t,payload:r})}catch(s){e.errorHandler({...s,eventName:t,payload:r})}c(t,performance.now()-n)},getMetrics:()=>({totalEvents:r,activeSubscriptions:Array.from(t.values()).reduce(((e,t)=>e+t.size),0),eventCounts:o,averageEmitDuration:r>0?n/r:0}),clear:()=>{t.clear(),i.clear(),s=[],r=0,n=0,o.clear(),a&&(a.close(),a=null)}}}}},function(){return s||(0,t[i(t)[0]])((s={exports:{}}).exports,s),s.exports}),u=[{name:"role",version:"1.0.0",description:"AI persona with a system prompt and associated preference defaults.",fields:{name:{name:"name",type:"string",required:!0},label:{name:"label",type:"string",required:!0},description:{name:"description",type:"string",required:!1},persona:{name:"persona",type:"string",required:!0},preferences:{name:"preferences",type:"array",required:!1,itemsType:"string"}},indexes:[{name:"by_name",fields:["name"],type:"unique"},{name:"by_label",fields:["label"],type:"normal"}],constraints:[],migrations:[]},{name:"preference",version:"1.0.0",description:"A user behavioural instruction, scoped to zero or more topics.",fields:{id:{name:"id",type:"string",required:!0},content:{name:"content",type:"string",required:!0},topics:{name:"topics",type:"array",required:!1,itemsType:"string"},timestamp:{name:"timestamp",type:"string",required:!0}},indexes:[{name:"by_id",fields:["id"],type:"unique"},{name:"by_topics",fields:["topics"],type:"normal"},{name:"by_timestamp",fields:["timestamp"],type:"btree"}],constraints:[],migrations:[]},{name:"context",version:"1.0.0",description:"Injected background knowledge, scoped to topics. Content is a discriminated union.",fields:{key:{name:"key",type:"string",required:!0},topics:{name:"topics",type:"array",required:!1,itemsType:"string"},content:{name:"content",type:"record",required:!0},timestamp:{name:"timestamp",type:"string",required:!0},metadata:{name:"metadata",type:"record",required:!1}},indexes:[{name:"by_key",fields:["key"],type:"unique"},{name:"by_topics",fields:["topics"],type:"normal"},{name:"by_timestamp",fields:["timestamp"],type:"btree"}],constraints:[],migrations:[]},{name:"session",version:"1.0.0",description:"Session metadata. The head field tracks the current tip of the turn DAG.",fields:{id:{name:"id",type:"string",required:!0},label:{name:"label",type:"string",required:!0},role:{name:"role",type:"string",required:!0},topics:{name:"topics",type:"array",required:!1,itemsType:"string"},preferences:{name:"preferences",type:"array",required:!1,itemsType:"string"},metadata:{name:"metadata",type:"record",required:!1},flushedTurnCount:{name:"flushedTurnCount",type:"number",required:!0},head:{name:"head",type:"record",required:!1}},indexes:[{name:"by_id",fields:["id"],type:"unique"},{name:"by_role",fields:["role"],type:"normal"}],constraints:[],migrations:[]},{name:"turn",version:"1.0.0",description:["A single message in a session transcript, stored as a flat document.","The DAG is reconstructed in memory by TurnTree.buildNodeGraph() at session open time.","$id is a composite key: `${sessionId}:${id}:${version}`."].join(" "),fields:{id:{name:"id",type:"string",required:!0},sessionId:{name:"sessionId",type:"string",required:!0},version:{name:"version",type:"number",required:!0},role:{name:"role",type:"enum",required:!0,values:["user","assistant","tool"]},blocks:{name:"blocks",type:"array",required:!0},timestamp:{name:"timestamp",type:"string",required:!0},roleSnapshot:{name:"roleSnapshot",type:"string",required:!1},parent:{name:"parent",type:"record",required:!1}},indexes:[{name:"by_session",fields:["sessionId"],type:"normal"},{name:"by_session_parent",fields:["sessionId","parent"],type:"composite"},{name:"by_session_id_ver",fields:["sessionId","id","version"],type:"composite",unique:!0}],constraints:[],migrations:[]}],h=class e extends Error{constructor(t,s){super(t,{cause:s}),this.name="SyncError",Object.setPrototypeOf(this,e.prototype)}},p=class extends h{constructor(e){super(`[ArtifactContainer] Operation timed out: ${e}`)}},f=class{_locked=!1;_capacity;_yieldMode;waiters=[];constructor(e){this._capacity=e?.capacity??1/0,this._yieldMode=e?.yieldMode??"macrotask"}async lock(e){if(!this._locked)return void(this._locked=!0);if(this.waiters.length>=this._capacity)throw new Error(`Mutex queue is full (capacity: ${this._capacity})`);let t;const s=new Promise((e=>t=e));this.waiters.push(t),null!=e?await Promise.race([s,new Promise(((s,r)=>setTimeout((()=>{const e=this.waiters.indexOf(t);-1!==e&&this.waiters.splice(e,1),r(new p("Mutex lock timed out"))}),e)))]):await s}tryLock(){return!this._locked&&(this._locked=!0,!0)}unlock(){if(!this._locked)throw new Error("Mutex is not locked");const e=this.waiters.shift();e?"microtask"===this._yieldMode?queueMicrotask(e):setTimeout(e,0):this._locked=!1}locked(){return this._locked}pending(){return this.waiters.length}},m=class{mutex=new f({yieldMode:"microtask"});promise=null;_value=null;_error;_done=!1;retry;throws;constructor({retry:e,throws:t}={}){this.retry=Boolean(e),this.throws=Boolean(t)}async do(e,t){return this._done?this.peek():this.promise?this._awaitWithTimeout(this.promise,t,"Once do() timed out"):(await this.mutex.lock(),this.promise?(this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")):(this.promise=(async()=>{try{const t=await e();this._value=t,this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.promise=null}return this.peek()})(),this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")))}doSync(e){if(this._done){if(this.throws&&this._error)throw this._error;return this.peek()}if(this.promise){const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}if(!this.mutex.tryLock()){const e=new Error("Cannot execute doSync: lock is currently held.");if(this.throws)throw e;return{value:null,error:e}}if(this.promise||this._done){if(this.mutex.unlock(),this._done){if(this.throws&&this._error)throw this._error;return this.peek()}const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}try{const t=e();this._value=t,this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.mutex.unlock()}return this.peek()}isReady(){return this._done&&null===this.promise}running(){return null!==this.promise&&!this._done}peek(){return{value:this._value,error:this._error}}get(){if(!this._done)throw new Error("Once operation is not yet complete");if(this._error)throw this._error;return this._value}reset(){this._done=!1,this.promise=null,this._value=null,this._error=void 0}resolved(){return this.promise}done(){return this._done}_awaitWithTimeout(e,t,s="Operation timed out"){return null==t?e:Promise.race([e,new Promise(((e,r)=>setTimeout((()=>r(new p(s))),t)))])}};function y(e){const t=new m({retry:!0,throws:!0}),s=new m({retry:!0,throws:!0});return{open:async(s=[])=>(await t.do((async()=>{const t=[...u,...s];await e.setupCollections(t)}))).value,collection:async t=>e.collection(t),close:async()=>(await s.do((()=>{e.close()}))).value}}var b={ROLE:"role",PREFERENCE:"preference",CONTEXT:"context",SESSION:"session",TURN:"turn"};d(l());var w=Symbol.for("delete"),g=e=>Array.isArray(e)?[...e]:{...e};function v(){return w}d(l()),d(l()),d(l()),d(l()),d(l()),d(l());var x=function(e){const t=e?.deleteMarker||w;function s(e){if(null==e)return e;if(Array.isArray(e))return e.filter((e=>e!==t)).map((e=>"object"!=typeof e||null===e||Array.isArray(e)?e:s(e)));if("object"==typeof e){const r={};for(const[n,o]of Object.entries(e))if(o!==t)if("object"==typeof o&&null!==o){const e=s(o);void 0!==e&&(r[n]=e)}else r[n]=o;return r}return e===t?void 0:e}return function(e,r){if("object"!=typeof e||null===e)return"object"==typeof r&&null!==r?s(r):r===t?{}:r;if("object"!=typeof r||null===r)return e;const n=g(e),o=[{target:n,source:r}];for(;o.length>0;){const{target:e,source:s}=o.pop();for(const r of Object.keys(s)){const n=s[r];if(n!==t)if(Array.isArray(n))e[r]=n;else if("object"==typeof n&&null!==n){const t=r in e&&"object"==typeof e[r]&&null!==e[r]?e[r]:{};e[r]=g(t),o.push({target:e[r],source:n})}else e[r]=n;else delete e[r]}}return n}}({deleteMarker:w});function S(e){return{ok:!0,value:e}}function T(e){return{ok:!1,error:e}}function k(e){return Object.fromEntries(Object.entries(e).filter((([e,t])=>null!=t)))}function O({name:t,owner:s,language:r}){return{id:e(),settings:{language:r},project:{name:t,owner:s},index:{roles:{},topics:{},preferences:{},context:{},sessions:{},blobs:{}}}}function C(e){const t=e?.index?.blobs;if(!t)return null;const s=t[Object.keys(t)[0]];return s||null}function _(e){return{sha256:e.sha256,mediaType:e.mediaType,sizeBytes:e.sizeBytes,filename:e.filename,previewUrl:e.previewUrl}}var N=class{db;constructor(e){this.db=e}async turns(){return this.db.collection(b.TURN)}async sessions(){return this.db.collection(b.SESSION)}turnFilter(e,t,s){return{operator:"and",conditions:[{field:"sessionId",operator:"eq",value:e},{field:"id",operator:"eq",value:t},{field:"version",operator:"eq",value:s}]}}async getHead(e){const t=await this.sessions(),s=await t.find({field:"id",operator:"eq",value:e});return s?.head??null}async setHead(e,t){const s=await this.sessions(),r=await s.find({field:"id",operator:"eq",value:e});if(!r)return;const n={...r.state(),head:t??void 0};await r.update(n)}async append(e,t){const s=await this.getHead(e),r={...t,sessionId:e,version:t.version??0,parent:t.parent?t.parent:s?{id:s.id,version:s.version}:null},n=await this.turns();return await n.create(k(r)),r}async appendBatch(e,t,s){if(0!==t.length){for(const s of t)await this.append(e,s);await this.setHead(e,s)}}async replaceVersion(e,t){const s=await this.turns(),r=await s.find(this.turnFilter(e,t.id,t.version)),n=k(t);r?await r.update({...n,sessionId:e}):await s.create({...n,sessionId:e})}async branch(e,t){const s=await this.turns();await s.create(k({...t,sessionId:e})),await this.setHead(e,{id:t.id,version:t.version})}async loadAllTurns(e){const t=await this.turns();return(await t.filter({field:"sessionId",operator:"eq",value:e})).map((e=>e.state()))}async getActiveChain(e,t=[]){const s=await this.getHead(e);if(!s&&0===t.length)return[];const r=await this.loadAllTurns(e);return[...s?I(r,s):[],...t]}async buildNodeGraph(e,t=[]){const s=await this.loadAllTurns(e),r=await this.getHead(e),n=new Set;if(r)for(const e of I(s,r))n.add(`${e.id}:${e.version}`);const o={};for(const e of s){o[e.id]||(o[e.id]={id:e.id,versions:{},activeVersion:e.version,role:e.role,blocks:e.blocks,timestamp:e.timestamp,roleSnapshot:e.roleSnapshot,parent:e.parent,children:{}});const t=o[e.id];t.versions[e.version]=e,n.has(`${e.id}:${e.version}`)&&(e.version>=t.activeVersion||!n.has(`${e.id}:${t.activeVersion}`))&&(t.activeVersion=e.version,t.blocks=e.blocks,t.timestamp=e.timestamp,t.roleSnapshot=e.roleSnapshot,t.parent=e.parent)}for(const e of Object.values(o))if(e.parent){const t=o[e.parent.id];if(t){const s=e.parent.version;t.children[s]||(t.children[s]=[]),t.children[s].includes(e.id)||t.children[s].push(e.id)}}for(const e of t)if(o[e.id]){const t=o[e.id];if(t.versions[e.version]=e,e.version>t.activeVersion&&(t.activeVersion=e.version,t.blocks=e.blocks,t.timestamp=e.timestamp,t.roleSnapshot=e.roleSnapshot),e.parent){const t=o[e.parent.id];if(t){const s=e.parent.version;t.children[s]||(t.children[s]=[]),t.children[s].includes(e.id)||t.children[s].push(e.id)}}}else if(o[e.id]={id:e.id,versions:{[e.version]:e},activeVersion:e.version,role:e.role,blocks:e.blocks,timestamp:e.timestamp,roleSnapshot:e.roleSnapshot,parent:e.parent,children:{}},e.parent){const t=o[e.parent.id];if(t){const s=e.parent.version;t.children[s]||(t.children[s]=[]),t.children[s].includes(e.id)||t.children[s].push(e.id)}}return o}async deleteSubtree(e,t,s,r){const n=function(e,t,s){const r=new Map;for(const t of e)if(t.parent){const e=`${t.parent.id}:${t.parent.version}`;let s=r.get(e);s||(s=new Set,r.set(e,s)),s.add(`${t.id}:${t.version}`)}const n=new Set,o=[`${t}:${s}`];for(;o.length>0;){const e=o.pop();n.add(e);const t=r.get(e);if(t)for(const e of t)n.has(e)||o.push(e)}return n}(await this.loadAllTurns(e),t,s),o=await this.turns();await Promise.all(Array.from(n).map((async t=>{const[s,r]=t.split(":"),n=await o.find(this.turnFilter(e,s,Number(r)));n&&await n.delete()}))),await this.setHead(e,r)}async copyTranscript(e,t){const s=await this.getHead(e),r=await this.loadAllTurns(e),n=s?I(r,s):[],o=await this.turns();for(const e of n)await o.create(k({...e,sessionId:t}));await this.setHead(t,s?{...s}:null)}};function I(e,t){const s=new Map;for(const t of e)s.set(`${t.id}:${t.version}`,t);const r=[];let n=t;for(;n;){const e=s.get(`${n.id}:${n.version}`);if(!e)break;r.push(e),n=e.parent}return r.reverse()}async function B(e){const t=await crypto.subtle.digest("SHA-256",e);return Array.from(new Uint8Array(t)).map((e=>e.toString(16).padStart(2,"0"))).join("")}var R=class{storage;config;recordCache=new Map;onRegistryChanged;constructor(e,t={}){this.storage=e,this.config={eagerEviction:t.eagerEviction??!1}}async init(){const e=await this.storage.listRecords();for(const t of e)this.recordCache.set(t.sha256,t)}async register(e,t,s){try{const r=await B(e),n=(new Date).toISOString(),o=this.recordCache.get(r);if(o){const e={...o,refCount:o.refCount+1,lastUsedAt:n};await this.storage.saveRecord(e),this.recordCache.set(r,e),this.onRegistryChanged?.(r,e)}else{const o={sha256:r,mediaType:t,sizeBytes:e.byteLength,filename:s,refCount:1,remoteIds:{},createdAt:n,lastUsedAt:n};"function"==typeof this.storage.registerBlob?await this.storage.registerBlob(o,e):(await this.storage.storeBytes(r,e),await this.storage.saveRecord(o)),this.recordCache.set(r,o),this.onRegistryChanged?.(r,o)}const i=this.recordCache.get(r);return S({sha256:r,mediaType:t,sizeBytes:i.sizeBytes,filename:i.filename,previewUrl:i.previewUrl})}catch(e){return T({code:"BLOB_ERROR",reason:e instanceof Error?e.message:String(e)})}}async retain(e){const t=this.recordCache.get(e);if(!t)return T({code:"NOT_FOUND",resource:"blob",id:e});const s={...t,refCount:t.refCount+1,lastUsedAt:(new Date).toISOString()};return await this.storage.saveRecord(s),this.recordCache.set(e,s),this.onRegistryChanged?.(e,s),S(void 0)}async release(e){const t=this.recordCache.get(e);if(!t)return T({code:"NOT_FOUND",resource:"blob",id:e});const s=Math.max(0,t.refCount-1),r={...t,refCount:s,lastUsedAt:(new Date).toISOString()};return 0===s&&this.config.eagerEviction?(await this.storage.deleteBytes(e),await this.storage.deleteRecord(e),this.recordCache.delete(e),this.onRegistryChanged?.(e,null)):(await this.storage.saveRecord(r),this.recordCache.set(e,r),this.onRegistryChanged?.(e,r)),S(void 0)}async recordRemoteId(e,t,s){const r=this.recordCache.get(e);if(!r)return T({code:"NOT_FOUND",resource:"blob",id:e});if(r.remoteIds[t]===s)return S(void 0);const n={...r,remoteIds:{...r.remoteIds,[t]:s}};return await this.storage.saveRecord(n),this.recordCache.set(e,n),S(void 0)}getRemoteId(e,t){return this.recordCache.get(e)?.remoteIds[t]??null}async resolveRef(e,t){try{if(t){const s=this.getRemoteId(e.sha256,t);if(s)return S({kind:"remote",sha256:e.sha256,mediaType:e.mediaType,fileId:s,providerId:t})}const s=await this.storage.loadBytes(e.sha256);return s?S({kind:"inline",sha256:e.sha256,mediaType:e.mediaType,data:s}):T({code:"BLOB_ERROR",reason:`Blob bytes not found locally for sha256=${e.sha256}. The blob may have been evicted. Re-register it before resolving.`})}catch(e){return T({code:"BLOB_ERROR",reason:e instanceof Error?e.message:String(e)})}}async resolveRefs(e,t){const s=function(e){const t=new Set,s=[];for(const r of e)t.has(r.sha256)||(t.add(r.sha256),s.push(r));return s}(e),r=await Promise.all(s.map((async e=>({ref:e,result:await this.resolveRef(e,t)})))),n=new Map,o=[];for(const{ref:e,result:t}of r)t.ok?n.set(e.sha256,t.value):o.push({ref:e,error:t.error});return{resolved:n,errors:o}}async gc(){const e=Array.from(this.recordCache.values()).filter((e=>0===e.refCount));return await Promise.all(e.map((e=>this.storage.deleteBytes(e.sha256)))),e.length}async gcFull(){const e=Array.from(this.recordCache.values()).filter((e=>0===e.refCount));return await Promise.all(e.map((async e=>{await this.storage.deleteBytes(e.sha256),await this.storage.deleteRecord(e.sha256),this.recordCache.delete(e.sha256),this.onRegistryChanged?.(e.sha256,null)}))),e.length}async purge(e){return this.recordCache.has(e)?(await this.storage.deleteBytes(e),await this.storage.deleteRecord(e),this.recordCache.delete(e),this.onRegistryChanged?.(e,null),S(void 0)):T({code:"NOT_FOUND",resource:"blob",id:e})}getRecord(e){return this.recordCache.get(e)??null}getAllRecords(){const e={};for(const[t,s]of this.recordCache)e[t]=s;return e}};var E=10,D=50,j=20,U=class{map=new Map;max;constructor(e){this.max=e}get(e){if(!this.map.has(e))return;const t=this.map.get(e);return this.map.delete(e),this.map.set(e,t),t}set(e,t){if(this.map.has(e)&&this.map.delete(e),this.map.set(e,t),this.map.size>this.max){const e=this.map.keys().next().value;void 0!==e&&this.map.delete(e)}}has(e){return this.map.has(e)}delete(e){this.map.delete(e)}};var A=class e{db;tree;blobs;roleCache;preferenceCache;contextCache;onBlobRegistryChanged;constructor(e,t,s={}){this.db=e,this.tree=new N(e),this.blobs=new R(t),this.blobs.onRegistryChanged=(e,t)=>{this.onBlobRegistryChanged?.(e,t)};const r={roles:s.cache?.roles??E,preferences:s.cache?.preferences??D,context:s.cache?.context??j};this.roleCache=new U(r.roles),this.preferenceCache=new U(r.preferences),this.contextCache=new U(r.context)}static async create(t,s,r){const n=new e(t,s,r);return await n.init(),n}async init(e){await this.db.open(e),await this.blobs.init()}getTurnTree(){return this.tree}async getRole(e){const t=this.roleCache.get(e);if(t)return S(t);const s=await this.db.collection(b.ROLE),r=await s.find({field:"name",operator:"eq",value:e});if(!r)return T({code:"NOT_FOUND",resource:"role",id:e});const n=r.state();return this.roleCache.set(e,n),S(n)}async saveRole(e){const t=await this.db.collection(b.ROLE),s=await t.find({field:"name",operator:"eq",value:e.name});s?await s.update(e):await t.create(e),this.roleCache.set(e.name,e)}async deleteRole(e){const t=await this.db.collection(b.ROLE),s=await t.find({field:"name",operator:"eq",value:e});s&&await s.delete(),this.roleCache.delete(e)}async getPreference(e){const t=this.preferenceCache.get(e);if(t)return S(t);const s=await this.db.collection(b.PREFERENCE),r=await s.find({field:"id",operator:"eq",value:e});if(!r)return T({code:"NOT_FOUND",resource:"preference",id:e});const n=r.state();return this.preferenceCache.set(e,n),S(n)}async savePreference(e){const t=await this.db.collection(b.PREFERENCE),s=await t.find({field:"id",operator:"eq",value:e.id});s?await s.update(e):await t.create(e),this.preferenceCache.set(e.id,e)}async deletePreference(e){const t=await this.db.collection(b.PREFERENCE),s=await t.find({field:"id",operator:"eq",value:e});s&&await s.delete(),this.preferenceCache.delete(e)}async getContext(e){const t=this.contextCache.get(e);if(t)return S(t);const s=await this.db.collection(b.CONTEXT),r=await s.find({field:"key",operator:"eq",value:e});if(!r)return T({code:"NOT_FOUND",resource:"context",id:e});const n=r.state();return this.contextCache.set(e,n),S(n)}async saveContext(e){const t=await this.db.collection(b.CONTEXT),s=await t.find({field:"key",operator:"eq",value:e.key});s?await s.update(e):await t.create(e),this.contextCache.set(e.key,e)}async deleteContext(e){const t=await this.db.collection(b.CONTEXT),s=await t.find({field:"key",operator:"eq",value:e});s&&await s.delete(),this.contextCache.delete(e)}async getContextByTopics(e,t){const s=new Set;for(const r of t){const t=e.topics[r];t&&t.contextKeys.forEach((e=>s.add(e)))}if(0===s.size)return[];const r=[],n=[];for(const e of s){const t=this.contextCache.get(e);t?n.push(t):r.push(e)}let o=[];if(r.length>0){const e=await this.db.collection(b.CONTEXT),t=await e.filter({operator:"or",conditions:r.map((e=>({field:"key",operator:"eq",value:e})))});for(const e of t){const t=e.state();this.contextCache.set(t.key,t),o.push(t)}}return[...n,...o].sort(((e,t)=>new Date(t.timestamp).getTime()-new Date(e.timestamp).getTime()))}async saveSession(e){const t=await this.db.collection(b.SESSION),s=await t.find({field:"id",operator:"eq",value:e.id}),r=k(e);s?await s.update(r):await t.create(r)}async updateSessionMeta(e,t){const s=await this.db.collection(b.SESSION),r=await s.find({field:"id",operator:"eq",value:e});if(!r)return;const n=r.state(),o=x(n,t);await r.update(k(o))}async deleteSession(e){const t=await this.db.collection(b.SESSION),s=await t.find({field:"id",operator:"eq",value:e});s&&await s.delete()}async registerBlob(e,t,s){return this.blobs.register(e,t,s)}async retainBlob(e){return this.blobs.retain(e)}async releaseBlob(e){return this.blobs.release(e)}async purgeBlob(e){return this.blobs.purge(e)}async recordBlobRemoteId(e,t,s){return this.blobs.recordRemoteId(e,t,s)}getBlobRecord(e){return this.blobs.getRecord(e)}getAllBlobRecords(){return this.blobs.getAllRecords()}getBlobResolver(){return this.blobs.resolveRefs.bind(this.blobs)}async recordTurn(e,t){return await this.tree.append(e,t),S(void 0)}async editTurn(e,t,s,r,n){const o=(await this.tree.loadAllTurns(e)).find((e=>e.id===t&&e.version===r-1));if(!o)return T({code:"NOT_FOUND",resource:"turn",id:t});const i={id:t,version:r,role:o.role,blocks:s,timestamp:(new Date).toISOString(),roleSnapshot:n??o.roleSnapshot,parent:o.parent};await this.tree.replaceVersion(e,i);const a=await this.tree.getHead(e);return a?.id===t&&await this.tree.setHead(e,{id:i.id,version:i.version}),S(void 0)}async branchTurn(e,t){return await this.tree.branch(e,t),S(void 0)}async deleteTurnSubtree(e,t,s,r){return await this.tree.deleteSubtree(e,t,s,r),S(void 0)}async copyTranscript(e,t){await this.tree.copyTranscript(e,t)}async resolveSession(e,t,s){const r=e.index.sessions[t];if(!r)return T({code:"NOT_FOUND",resource:"session",id:t});const n=await this.getRole(r.role);if(!n.ok)return n;const o=n.value,i=function(e,t){return e.preferences.length>0?e.preferences:t.preferences}(r,o),a={session:r,role:o,preferences:function(e,t){return e.filter((e=>0===e.topics.length||e.topics.some((e=>t.includes(e)))))}((await Promise.all(i.map((e=>this.getPreference(e))))).filter((e=>e.ok)).map((e=>e.value)),r.topics),context:await this.getContextByTopics(e.index,r.topics),transcript:s??await this.tree.getActiveChain(t),instructions:e.settings?.prompt};return S({...a,preferences:Object.freeze([...a.preferences]),context:Object.freeze([...a.context]),transcript:Object.freeze([...a.transcript])})}};function F({index:e},t){switch(t.type){case"role:add":{const s=t.payload;if(e.roles[s.name])return T({code:"DUPLICATE_KEY",resource:"role",key:s.name});const r={name:s.name,label:s.label,description:s.description,preferences:s.preferences.length};return S({index:{roles:{[s.name]:r}}})}case"role:update":{const{name:s,...r}=t.payload;if(!e.roles[s])return T({code:"NOT_FOUND",resource:"role",id:s});const n=e.roles[s],o={...n,...r,preferences:r.preferences?.length??n.preferences};return S({index:{roles:{[s]:o}}})}case"role:delete":{const{name:s}=t.payload;if(!e.roles[s])return T({code:"NOT_FOUND",resource:"role",id:s});return Object.values(e.sessions).some((e=>e.role===s))?T({code:"INVALID_COMMAND",reason:`Cannot delete role "${s}" — it is still referenced by one or more sessions`}):S({index:{roles:{[s]:v()}}})}case"preference:add":{const s=t.payload,r={id:s.id,topics:s.topics,timestamp:s.timestamp,snippet:s.content.substring(0,100)},n={};return s.topics.forEach((r=>{const o=e.topics[r];n[r]={topic:r,contextKeys:o?.contextKeys??[],preferences:[...o?.preferences??[],s.id],metadata:{created:o?.metadata?.created??t.timestamp,updated:t.timestamp,entries:o?.metadata?.entries??0}}})),S({index:{preferences:{[s.id]:r},topics:n}})}case"preference:update":{const{id:s,...r}=t.payload;if(!e.preferences[s])return T({code:"NOT_FOUND",resource:"preference",id:s});const n=e.preferences[s],o={...n,...r,snippet:r.content?r.content.substring(0,100):n.snippet},i={};return r.topics&&(n.topics.forEach((t=>{const r=e.topics[t];r&&(i[t]={preferences:r.preferences.filter((e=>e!==s))})})),r.topics.forEach((r=>{const n=e.topics[r]??{topic:r,contextKeys:[],preferences:[],metadata:{created:t.timestamp,updated:t.timestamp,entries:0}};i[r]={...n,preferences:[...new Set([...n.preferences,s])],metadata:{updated:t.timestamp}}}))),S({index:{preferences:{[s]:o},topics:i}})}case"preference:delete":{const{id:s}=t.payload;if(!e.preferences[s])return T({code:"NOT_FOUND",resource:"preference",id:s});const r=e.preferences[s],n={};return r.topics.forEach((t=>{const r=e.topics[t];r&&(n[t]={preferences:r.preferences.filter((e=>e!==s))})})),S({index:{preferences:{[s]:v()},topics:n}})}case"context:add":{const s=t.payload;if(e.context[s.key])return T({code:"DUPLICATE_KEY",resource:"context",key:s.key});const r=s.content,n={key:s.key,topics:s.topics,timestamp:s.timestamp,source:s.key.split(":")[0],preview:"text"===r.kind?r.value.substring(0,200):"json"===r.kind?JSON.stringify(r.value).substring(0,200):void 0,metadata:s.metadata},o={};return s.topics.forEach((r=>{const n=e.topics[r],i=n?.contextKeys??[],a=i.includes(s.key)?i:[...i,s.key];o[r]={topic:r,contextKeys:a,preferences:n?.preferences??[],metadata:{updated:t.timestamp,entries:a.length}}})),S({index:{context:{[s.key]:n},topics:o}})}case"context:update":{const{key:s,...r}=t.payload;if(!e.context[s])return T({code:"NOT_FOUND",resource:"context",id:s});const n=e.context[s],o=r.content,i={...n,...r,preview:o?"text"===o.kind?o.value.substring(0,200):"json"===o.kind?JSON.stringify(o.value).substring(0,200):void 0:n.preview},a={};return r.topics&&(n.topics.forEach((t=>{const r=e.topics[t];r&&(a[t]={contextKeys:r.contextKeys.filter((e=>e!==s))})})),r.topics.forEach((r=>{const n=e.topics[r]??{contextKeys:[]},o=n.contextKeys.includes(s)?n.contextKeys:[...n.contextKeys,s];a[r]={contextKeys:o,metadata:{updated:t.timestamp,entries:o.length}}}))),S({index:{context:{[s]:i},topics:a}})}case"context:delete":{const{key:s}=t.payload;if(!e.context[s])return T({code:"NOT_FOUND",resource:"context",id:s});const r=e.context[s],n={};return r.topics.forEach((r=>{const o=e.topics[r];o&&(n[r]={contextKeys:o.contextKeys.filter((e=>e!==s)),metadata:{updated:t.timestamp,entries:o.contextKeys.length-1}})})),S({index:{context:{[s]:v()},topics:n}})}case"session:create":{const{id:s,label:r,role:n,topics:o,preferences:i=[]}=t.payload;if(e.sessions[s])return T({code:"DUPLICATE_KEY",resource:"session",key:s});if(!e.roles[n])return T({code:"NOT_FOUND",resource:"role",id:n});const a={id:s,label:r,role:n,topics:o,preferences:i,metadata:{created:t.timestamp,updated:t.timestamp},flushedTurnCount:0,head:null};return S({index:{sessions:{[s]:a}}})}case"session:role:switch":{const{sessionId:s,role:r}=t.payload;return e.sessions[s]?S({index:{sessions:{[s]:{role:r,metadata:{updated:t.timestamp}}}}}):T({code:"NOT_FOUND",resource:"session",id:s})}case"session:topics:add":{const{sessionId:s,topics:r}=t.payload;if(!e.sessions[s])return T({code:"NOT_FOUND",resource:"session",id:s});const n=e.sessions[s],o=[...new Set([...n.topics,...r])];return S({index:{sessions:{[s]:{topics:o,metadata:{updated:t.timestamp}}}}})}case"session:preferences:override":{const{sessionId:s,preferences:r}=t.payload;return e.sessions[s]?S({index:{sessions:{[s]:{preferences:r,metadata:{updated:t.timestamp}}}}}):T({code:"NOT_FOUND",resource:"session",id:s})}case"session:fork":{const{sourceSessionId:s,newSessionId:r,label:n,role:o,topics:i}=t.payload;if(!e.sessions[s])return T({code:"NOT_FOUND",resource:"session",id:s});if(e.sessions[r])return T({code:"DUPLICATE_KEY",resource:"session",key:r});const a=e.sessions[s],c={id:r,label:n,role:o??a.role,topics:i??[...a.topics],preferences:[...a.preferences],metadata:{created:t.timestamp,updated:t.timestamp},flushedTurnCount:a.flushedTurnCount,head:a.head};return S({index:{sessions:{[r]:c}}})}case"session:delete":{const{sessionId:s}=t.payload;return e.sessions[s]?S({index:{sessions:{[s]:v()}}}):T({code:"NOT_FOUND",resource:"session",id:s})}case"turn:add":{const{sessionId:s,turn:r}=t.payload;return e.sessions[s]?S({index:{sessions:{[s]:{head:{id:r.id,version:r.version},metadata:{updated:t.timestamp},flushedTurnCount:(e.sessions[s]?.flushedTurnCount??0)+1}}}}):T({code:"NOT_FOUND",resource:"session",id:s})}case"turn:edit":{const{sessionId:s,turnId:r,newVersion:n}=t.payload;return e.sessions[s]?S({index:{sessions:{[s]:{head:{id:r,version:n},metadata:{updated:t.timestamp}}}}}):T({code:"NOT_FOUND",resource:"session",id:s})}case"turn:branch":{const{sessionId:s,newTurn:r}=t.payload;return e.sessions[s]?S({index:{sessions:{[s]:{head:{id:r.id,version:r.version},metadata:{updated:t.timestamp}}}}}):T({code:"NOT_FOUND",resource:"session",id:s})}case"turn:delete":{const{sessionId:s,newHead:r}=t.payload;return e.sessions[s]?S({index:{sessions:{[s]:{head:r,metadata:{updated:t.timestamp}}}}}):T({code:"NOT_FOUND",resource:"session",id:s})}case"blob:register":default:return S({});case"blob:retain":{const{sha256:s}=t.payload;return e.blobs[s]?S({}):T({code:"NOT_FOUND",resource:"blob",id:s})}case"blob:release":{const{sha256:s}=t.payload;return e.blobs[s]?S({}):T({code:"NOT_FOUND",resource:"blob",id:s})}case"blob:purge":{const{sha256:s}=t.payload;return e.blobs[s]?S({}):T({code:"NOT_FOUND",resource:"blob",id:s})}case"blob:record_remote_id":{const{sha256:s}=t.payload;return e.blobs[s]?S({}):T({code:"NOT_FOUND",resource:"blob",id:s})}}}var q=class{contentStore;onWorkspacePatch;constructor(e){this.contentStore=e,this.contentStore.onBlobRegistryChanged=(e,t)=>{const s={index:{blobs:{[e]:t??void 0}}};this.onWorkspacePatch?.(s)}}reduce(e,t){return F(e,t)}async dispatch(e,t){const s=F(e,t);if(!s.ok)return s;let r={};try{r=await this.handleContentSideEffects(e,t)}catch(e){return T({code:"BACKEND_ERROR",reason:e instanceof Error?e.message:String(e)})}return S(x(s.value,r))}async resolveSession(e,t){return this.contentStore.resolveSession(e,t)}async handleContentSideEffects(e,t){switch(t.type){case"blob:register":{const{data:e,mediaType:s,filename:r}=t.payload,n=await this.contentStore.registerBlob(e,s,r);if(!n.ok)throw Object.assign(new Error(n.error.code),{wsError:n.error});const o=n.value,i=this.contentStore.getBlobRecord(o.sha256);if(!i)throw new Error("Record missing after register");return{index:{blobs:{[o.sha256]:i}}}}case"blob:retain":{const{sha256:e}=t.payload,s=await this.contentStore.retainBlob(e);if(!s.ok)throw Object.assign(new Error(s.error.code),{wsError:s.error});const r=this.contentStore.getBlobRecord(e);return{index:{blobs:{[e]:r??void 0}}}}case"blob:release":{const{sha256:e}=t.payload,s=await this.contentStore.releaseBlob(e);if(!s.ok)throw Object.assign(new Error(s.error.code),{wsError:s.error});const r=this.contentStore.getBlobRecord(e);return{index:{blobs:{[e]:r??void 0}}}}case"blob:purge":{const{sha256:e}=t.payload,s=await this.contentStore.purgeBlob(e);if(!s.ok)throw Object.assign(new Error(s.error.code),{wsError:s.error});return{index:{blobs:{[e]:void 0}}}}case"blob:record_remote_id":{const{sha256:e,providerId:s,fileId:r}=t.payload,n=await this.contentStore.recordBlobRemoteId(e,s,r);if(!n.ok)throw Object.assign(new Error(n.error.code),{wsError:n.error});const o=this.contentStore.getBlobRecord(e);return{index:{blobs:{[e]:o??void 0}}}}case"role:add":return await this.contentStore.saveRole(t.payload),{};case"role:update":{const{name:e,...s}=t.payload,r=await this.contentStore.getRole(e);if(!r.ok)throw new Error(`role:update — "${e}" not found`);return await this.contentStore.saveRole({...r.value,...s,name:e}),{}}case"role:delete":return await this.contentStore.deleteRole(t.payload.name),{};case"preference:add":return await this.contentStore.savePreference(t.payload),{};case"preference:update":{const{id:e,...s}=t.payload,r=await this.contentStore.getPreference(e);if(!r.ok)throw new Error(`preference:update — "${e}" not found`);return await this.contentStore.savePreference({...r.value,...s,id:e}),{}}case"preference:delete":return await this.contentStore.deletePreference(t.payload.id),{};case"context:add":case"context:update":return await this.contentStore.saveContext(t.payload),{};case"context:delete":return await this.contentStore.deleteContext(t.payload.key),{};case"session:create":{const{id:e,label:s,role:r,topics:n,preferences:o=[]}=t.payload;return await this.contentStore.saveSession({id:e,label:s,role:r,topics:n,preferences:o,metadata:{created:t.timestamp,updated:t.timestamp},flushedTurnCount:0,head:null}),{}}case"session:fork":{const{sourceSessionId:s,newSessionId:r,label:n,role:o,topics:i}=t.payload;if(!e.index.sessions[s])throw new Error(`session:fork — source session "${s}" not found`);await this.contentStore.copyTranscript(s,r);const a=e.index.sessions[s],c={id:r,label:n,role:o??a.role,topics:i??[...a.topics],preferences:[...a.preferences],metadata:{created:t.timestamp,updated:t.timestamp},flushedTurnCount:a.flushedTurnCount,head:a.head?{...a.head}:null};return await this.contentStore.saveSession(c),{}}case"session:delete":return await this.contentStore.deleteSession(t.payload.sessionId),{};case"session:role:switch":case"session:topics:add":case"session:preferences:override":{const e=t.payload.sessionId,s=await this.contentStore.db.collection("session"),r=await s.find({field:"id",operator:"eq",value:e});if(!r)return{};if("session:role:switch"===t.type)await this.contentStore.updateSessionMeta(e,{role:t.payload.role});else if("session:topics:add"===t.type){const s=r.state();await this.contentStore.updateSessionMeta(e,{topics:[...new Set([...s.topics,...t.payload.topics])]})}else await this.contentStore.updateSessionMeta(e,{preferences:t.payload.preferences});return{}}case"turn:add":return await this.contentStore.recordTurn(t.payload.sessionId,t.payload.turn),{};case"turn:edit":{const{sessionId:e,turnId:s,newBlocks:r,newVersion:n,roleSnapshot:o}=t.payload;return await this.contentStore.editTurn(e,s,r,n,o),{}}case"turn:branch":return await this.contentStore.branchTurn(t.payload.sessionId,t.payload.newTurn),{};case"turn:delete":{const{sessionId:e,turnId:s,version:r,newHead:n}=t.payload;return await this.contentStore.deleteTurnSubtree(e,s,r,n),{}}default:return{}}}};function M(e){return Math.ceil(e.length/4)}function P(e,t){return Math.ceil(e/1024*t)}function $(e){if("text"===e.kind)return e.value;if("json"===e.kind){const t=[],s=e=>{"string"==typeof e?t.push(e):e&&"object"==typeof e&&Object.values(e).forEach(s)};return s(e.value),t.join(" ")}return""}function z(e,t){return{id:crypto.randomUUID(),version:0,role:e,blocks:t,timestamp:(new Date).toISOString(),parent:null}}var V=class{rank(e){const{entries:t,recentMessages:s,config:r}=e,n=r.recentMessageWindow??3,o=r.minScore??0,i=r.freshnessHalfLifeDays??30;if(0===s.length)return[...t].sort(((e,t)=>this.freshnessWeight(t.timestamp,i)-this.freshnessWeight(e.timestamp,i)));const a=this.tokenize(s.slice(-n).join(" "));return t.map((e=>{const t=$(e.content);return{entry:e,score:.7*this.jaccardSimilarity(a,this.tokenize(t))+.3*this.freshnessWeight(e.timestamp,i)}})).filter((e=>e.score>o)).sort(((e,t)=>t.score-e.score)).map((e=>e.entry))}tokenize(e){return new Set(e.toLowerCase().replace(/[^\w\s]/g," ").split(/\s+/).filter((e=>e.length>2)))}jaccardSimilarity(e,t){if(0===e.size&&0===t.size)return 0;let s=0;for(const r of e)t.has(r)&&s++;const r=e.size+t.size-s;return 0===r?0:s/r}freshnessWeight(e,t){const s=(Date.now()-new Date(e).getTime())/864e5;return Math.pow(.5,s/t)}},K=class{plan(e){const{systemInstructions:t,persona:s,preferences:r,context:n,transcript:o,budget:i}=e;if(!i)return{preferences:r,context:n,transcript:o,truncated:{preferences:0,interactions:0,context:0},breakdown:{system:0,persona:0,preferences:0,transcript:0,context:0},totalUsed:0,lastRoleBeforeTruncation:null};const a=i.estimator??M,c=i.blobTokensPerKB??.25;let d=i.total;const l={system:0,persona:0,preferences:0,transcript:0,context:0},u=a(t??""),h=a(s);d-=u+h,l.system+=u,l.persona+=h;const p=[];let f=0;for(const e of r){const t=a(e.content);d>=t?(d-=t,l.preferences+=t,p.push(e)):f++}const m=[];let y=0,b=null;for(let e=o.length-1;e>=0;e--){const t=o[e],s=this.estimateTurnTokens(t,a,c);d>=s?(d-=s,l.transcript+=s,m.unshift(t)):(y++,"user"!==t.role||b||(b=t.roleSnapshot??null))}const w=[];let g=0;for(const e of n){let t=a($(e.content));"blob"===e.content.kind&&(t+=P(e.content.sizeBytes,c)),d>=t?(d-=t,l.context+=t,w.push(e)):g++}return{preferences:p,context:w,transcript:m,truncated:{preferences:f,interactions:y,context:g},breakdown:l,totalUsed:i.total-Math.max(0,d),lastRoleBeforeTruncation:b}}estimateTurnTokens(e,t,s){return e.blocks.reduce(((e,r)=>{switch(r.type){case"text":return e+t(r.text);case"tool_use":return e+t(JSON.stringify(r.input));case"tool_result":return e+t("string"==typeof r.content?r.content:JSON.stringify(r.content));case"thinking":return e+t(r.thinking);case"image":case"document":{const t=r.ref;return t?e+P(t.sizeBytes,s):e}default:return e}}),0)}},L=class{assemble(e){const{session:t,plan:s,resolvedBlobs:r,summaryBlockText:n,warnings:o,conflicts:i,budgetTotal:a}=e,c=[],d=[];for(const e of s.context)if("text"===e.content.kind||"json"===e.content.kind)c.push(e);else if("blob"===e.content.kind){const t=r.get(e.content.sha256);t&&d.push(this.buildReferentialBlock(e.content,t))}const l=[];if(d.length>0&&l.push(z("user",d)),n||s.truncated.interactions>0){const e=[];n&&e.push({type:"summary",text:n}),s.truncated.interactions>0&&e.push({type:"text",text:`[${s.truncated.interactions} earlier turn(s) omitted due to token budget]`}),l.push(z("user",e)),l.push(z("assistant",[{type:"text",text:"Understood."}]))}let u=s.lastRoleBeforeTruncation,h=null!==s.lastRoleBeforeTruncation;for(const e of s.transcript){const t=this.resolveTurnBlocks(e,r);"user"===e.role&&e.roleSnapshot&&h&&e.roleSnapshot!==u&&t.unshift({type:"role_transition",previousRole:u,newRole:e.roleSnapshot}),"user"===e.role&&(u=e.roleSnapshot??null,h=!0),l.push({...e,blocks:t})}return{system:{instructions:t.instructions,persona:t.role.persona,preferences:s.preferences,context:c},context:s.context,transcript:{turns:l},budget:{total:a,used:s.totalUsed,breakdown:s.breakdown},truncated:s.truncated,warnings:o,conflicts:i}}buildReferentialBlock(e,t){return e.mediaType.startsWith("image/")?{type:"image",blob:t}:{type:"document",blob:t,title:e.filename}}resolveTurnBlocks(e,t){return e.blocks.map((e=>{if("image"===e.type||"document"===e.type){const s=e.ref;if(s){const r=t.get(s.sha256);if(r)return{...e,blob:r}}}return e}))}},H=class{retriever;planner;assembler;summarizer;blobResolver;constructor(e){this.blobResolver=e.blobResolver,this.retriever=e.retriever??new V,this.planner=e.planner??new K,this.assembler=e.assembler??new L,this.summarizer=e.summarizer}async build(e,t={}){const s=[],{resolved:r,conflicts:n}=this.resolvePreferenceConflicts(e.preferences);n.length>0&&s.push(`${n.length} preference conflict(s) resolved.`);const o=this.extractRecentUserQueries(e.transcript,t.relevanceConfig),i=this.retriever.rank({entries:e.context,recentMessages:o,config:t.relevanceConfig??{}});let a=e.transcript,c=null;if(this.summarizer&&a.length>0){const e=t.tokenBudget?Math.floor(.25*t.tokenBudget.total):2e3,s=await this.summarizer.summarize(a,e);c=s.summary,a=s.remaining}const d=this.planner.plan({systemInstructions:e.instructions,persona:e.role.persona,preferences:r,context:i,transcript:a,budget:t.tokenBudget}),l=this.collectUsedBlobRefs(d.context,d.transcript),u=this.deduplicateBlobRefs(l),{resolved:h,errors:p}=await this.blobResolver(u,t.providerId??null);for(const e of p)s.push(`Failed to resolve blob ${e.ref.sha256.slice(0,8)}: ${e.error.code}`);const f=u.filter((e=>!h.has(e.sha256)));return f.length>0&&s.push(`${f.length} blob(s) unresolved and omitted: `+f.map((e=>e.sha256.slice(0,8))).join(", ")),d.truncated.preferences>0&&s.push(`${d.truncated.preferences} preference(s) dropped.`),d.truncated.interactions>0&&s.push(`${d.truncated.interactions} turn(s) trimmed.`),d.truncated.context>0&&s.push(`${d.truncated.context} context entry/entries dropped.`),this.assembler.assemble({session:e,plan:d,resolvedBlobs:h,summaryBlockText:c,warnings:s,conflicts:n,budgetTotal:t.tokenBudget?.total??0})}collectUsedBlobRefs(e,t){const s=[];for(const t of e)"blob"===t.content.kind&&s.push(t.content);for(const e of t)for(const t of e.blocks)if("image"===t.type||"document"===t.type){const e=t.ref;e&&s.push(e)}return s}deduplicateBlobRefs(e){const t=new Set,s=[];for(const r of e)t.has(r.sha256)||(t.add(r.sha256),s.push(r));return s}extractRecentUserQueries(e,t){const s=t?.recentMessageWindow??3;return e.filter((e=>"user"===e.role)).slice(-s).flatMap((e=>e.blocks.filter((e=>"text"===e.type)).map((e=>e.text))))}resolvePreferenceConflicts(e){const t=[],s=new Map;for(const r of e)if(0!==r.topics.length)for(const e of r.topics){const n=s.get(e);if(!n){s.set(e,r);continue}const o=new Date(n.timestamp).getTime(),i=new Date(r.timestamp).getTime();i>o?(t.push({topic:e,kept:r.id,dropped:n.id,reason:"superseded_by_newer"}),s.set(e,r)):o>i&&t.push({topic:e,kept:n.id,dropped:r.id,reason:"superseded_by_newer"})}const r=new Set(t.map((e=>e.dropped)));return{resolved:e.filter((e=>!r.has(e.id))),conflicts:Array.from(new Set(t))}}},W={maxBufferSize:10,flushIntervalMs:3e4},G=class{sessionId;nodes;head;dirtyBuffer=[];flushTimer=null;flushChain=Promise.resolve();flushConfig;tree;contentStore;constructor(e,t,s,r,n,o=W){this.sessionId=e,this.nodes=t,this.head=s,this.tree=r,this.contentStore=n,this.flushConfig=o}activeChain(){if(!this.head)return[];const e=[];let t=this.head.id;for(;null!==t;){const s=this.nodes[t];if(!s)break;e.push(s),t=s.parent?.id??null}return e.reverse()}siblings(e){const t=this.nodes[e];if(!t)return[];if(!t.parent)return Object.values(this.nodes).filter((e=>null===e.parent));const s=this.nodes[t.parent.id];if(!s)return[t];const r=t.parent.version,n=s.children[r];return n?n.map((e=>this.nodes[e])).filter((e=>void 0!==e)):[t]}branchInfo(e){const t=this.nodes[e];if(!t)return{versions:[],currentIndex:-1,total:0,hasPrev:!1,hasNext:!1};const s=Object.keys(t.versions).map(Number).sort(((e,t)=>e-t)),r=s.indexOf(t.activeVersion);return{versions:s,currentIndex:r,total:s.length,hasPrev:r>0,hasNext:r<s.length-1}}async addTurn(e,t){const s=e.index.sessions[this.sessionId];if(!s)return T({code:"NOT_FOUND",resource:"session",id:this.sessionId});const r={...t,version:t.version??0,parent:null!==t.parent?t.parent:null!==this.head?{id:this.head.id,version:this.head.version}:null};return this.upsertNode(r),this.head={id:r.id,version:r.version},this.dirtyBuffer.push(r),this.scheduleFlush(),this.dirtyBuffer.length>=this.flushConfig.maxBufferSize&&await this.flush(),S({index:{sessions:{[this.sessionId]:{head:{id:r.id,version:r.version},flushedTurnCount:s.flushedTurnCount+1,metadata:{updated:r.timestamp}}}}})}async editTurn(e,t,s,r){if(!e.index.sessions[this.sessionId])return T({code:"NOT_FOUND",resource:"session",id:this.sessionId});const n=this.nodes[t];if(!n)return T({code:"NOT_FOUND",resource:"turn",id:t});const o=n.activeVersion+1,i={id:t,version:o,role:n.role,blocks:s,timestamp:(new Date).toISOString(),roleSnapshot:r??n.roleSnapshot,parent:n.parent};n.versions[o]=i,n.activeVersion=o,n.blocks=s,n.timestamp=i.timestamp,void 0!==r&&(n.roleSnapshot=r),n.children[o]||(n.children[o]=[]);const a={id:t,version:o};return this.head=a,await this.tree.replaceVersion(this.sessionId,i),await this.tree.setHead(this.sessionId,a),S({index:{sessions:{[this.sessionId]:{head:a,metadata:{updated:i.timestamp}}}}})}async branchFrom(e,t){const s=e.index.sessions[this.sessionId];if(!s)return T({code:"NOT_FOUND",resource:"session",id:this.sessionId});if(!t.parent)return T({code:"INVALID_COMMAND",reason:"branchFrom requires newTurn.parent to be set"});return this.nodes[t.parent.id]?(this.upsertNode(t),this.head={id:t.id,version:t.version},await this.tree.branch(this.sessionId,t),S({index:{sessions:{[this.sessionId]:{head:{id:t.id,version:t.version},flushedTurnCount:s.flushedTurnCount+1,metadata:{updated:t.timestamp}}}}})):T({code:"NOT_FOUND",resource:"turn",id:t.parent.id})}async deleteTurn(e,t,s,r){const n=e.index.sessions[this.sessionId];if(!n)return T({code:"NOT_FOUND",resource:"session",id:this.sessionId});const o=this.nodes[t];if(!o)return T({code:"NOT_FOUND",resource:"turn",id:t});const i=this.collectSubtreeIds(t);if(o.parent){const e=this.nodes[o.parent.id];if(e){const s=o.parent.version,r=e.children[s];r&&(e.children[s]=r.filter((e=>e!==t)))}}for(const e of i)delete this.nodes[e];this.head=r,await this.tree.deleteSubtree(this.sessionId,t,s,r);const a=(new Date).toISOString();return S({index:{sessions:{[this.sessionId]:{head:r,flushedTurnCount:Math.max(0,n.flushedTurnCount-i.size),metadata:{updated:a}}}}})}switchVersionLeft(e,t){return this.switchVersion(t,-1)}switchVersionRight(e,t){return this.switchVersion(t,1)}switchVersion(e,t){const s=this.nodes[e];if(!s)return T({code:"NOT_FOUND",resource:"turn",id:e});const r=Object.keys(s.versions).map(Number).sort(((e,t)=>e-t)),n=r.indexOf(s.activeVersion);if(-1===n)return T({code:"INVALID_COMMAND",reason:"Current version not found"});const o=n+t;if(o<0||o>=r.length)return T({code:"INVALID_COMMAND",reason:`No ${t<0?"previous":"next"} version available for turn ${e}`});const i=r[o];s.activeVersion=i,s.blocks=s.versions[i].blocks,s.timestamp=s.versions[i].timestamp,s.versions[i].roleSnapshot&&(s.roleSnapshot=s.versions[i].roleSnapshot);const a=this.findSubtreeTipForVersion(e,i);this.head=a;const c=(new Date).toISOString();return S({index:{sessions:{[this.sessionId]:{head:a,metadata:{updated:c}}}}})}async resolve(e){return e.index.sessions[this.sessionId]?this.contentStore.resolveSession(e,this.sessionId,this.activeChain().map((e=>e.versions[e.activeVersion]))):T({code:"NOT_FOUND",resource:"session",id:this.sessionId})}async flush(){return this.flushChain=this.flushChain.then((()=>this.doFlush())),this.flushChain}async dispose(){this.cancelFlushTimer(),await this.flush()}findSubtreeTipForVersion(e,t){let s=e,r=t;for(;;){const e=this.nodes[s];if(!e)break;const t=e.children[r];if(!t||0===t.length)break;s=t[0],r=this.nodes[s]?.activeVersion??0}return{id:s,version:r}}collectSubtreeIds(e){const t=new Set,s=[e];for(;s.length>0;){const e=s.pop();t.add(e);const r=this.nodes[e];if(r&&r.children)for(const e of Object.keys(r.children)){const n=r.children[Number(e)];if(n)for(const e of n)t.has(e)||s.push(e)}}return t}upsertNode(e){const t=e.id,s=e.version;if(this.nodes[t]){const r=this.nodes[t];r.versions[s]=e,s>=r.activeVersion&&(r.activeVersion=s,r.blocks=e.blocks,r.timestamp=e.timestamp,void 0!==e.roleSnapshot&&(r.roleSnapshot=e.roleSnapshot)),r.children[s]||(r.children[s]=[])}else this.nodes[t]={id:t,versions:{[s]:e},activeVersion:s,role:e.role,blocks:e.blocks,timestamp:e.timestamp,roleSnapshot:e.roleSnapshot,parent:e.parent,children:{[s]:[]}};if(e.parent){const s=this.nodes[e.parent.id];if(s){const r=e.parent.version;s.children[r]||(s.children[r]=[]),s.children[r].includes(t)||s.children[r].push(t)}}}scheduleFlush(){null===this.flushTimer&&(this.flushTimer=setTimeout((()=>{this.flushTimer=null,this.flushChain=this.flushChain.then((()=>this.doFlush()))}),this.flushConfig.flushIntervalMs))}cancelFlushTimer(){null!==this.flushTimer&&(clearTimeout(this.flushTimer),this.flushTimer=null)}async doFlush(){if(0===this.dirtyBuffer.length)return;const e=this.dirtyBuffer.splice(0,this.dirtyBuffer.length),t=this.head;try{await this.tree.appendBatch(this.sessionId,e,t),0===this.dirtyBuffer.length&&this.cancelFlushTimer()}catch(t){throw this.dirtyBuffer.unshift(...e),this.flushChain=Promise.resolve(),t}}};function X(e,t=[]){return{id:e.id,versions:{[e.version]:e},activeVersion:e.version,role:e.role,blocks:e.blocks,timestamp:e.timestamp,roleSnapshot:e.roleSnapshot,parent:e.parent,children:{[e.version]:[...t]}}}var J=10,Y=3e4,Q=class{workspaceManager;contentStore;flushConfig;constructor(e,t,s={}){this.workspaceManager=e,this.contentStore=t,this.flushConfig={maxBufferSize:s.flush?.maxBufferSize??J,flushIntervalMs:s.flush?.flushIntervalMs??Y}}async open(e,t){const s=e.index.sessions[t];if(!s)return T({code:"NOT_FOUND",resource:"session",id:t});const r=this.contentStore.getTurnTree();try{const e=await r.buildNodeGraph(t);return S({session:new G(t,e,s.head,r,this.contentStore,this.flushConfig),patch:{}})}catch(e){return T({code:"BACKEND_ERROR",reason:e instanceof Error?e.message:String(e)})}}async close(e){await e.dispose()}get workspace(){return this.workspaceManager}},Z=class{bytes=new Map;records=new Map;async storeBytes(e,t){this.bytes.has(e)||this.bytes.set(e,t)}async loadBytes(e){return this.bytes.get(e)??null}async hasBytes(e){return this.bytes.has(e)}async deleteBytes(e){this.bytes.delete(e)}async saveRecord(e){this.records.set(e.sha256,{...e})}async loadRecord(e){return this.records.get(e)??null}async deleteRecord(e){this.records.delete(e)}async listRecords(){return Array.from(this.records.values()).map((e=>({...e})))}async exportAllBytes(){return Array.from(this.bytes.entries()).map((([e,t])=>[e,new Uint8Array(t)]))}async registerBlob(e,t){this.bytes.has(e.sha256)||this.bytes.set(e.sha256,t),this.records.set(e.sha256,{...e})}},ee="blob_bytes",te="blob_records";function se(e){return new Promise(((t,s)=>{e.onsuccess=()=>t(e.result),e.onerror=()=>s(e.error)}))}function re(e){return new Promise(((t,s)=>{e.oncomplete=()=>t(),e.onerror=()=>s(e.error),e.onabort=()=>s(new Error("Transaction aborted"))}))}var ne=class{dbName;db=null;constructor(e={}){this.dbName=e.dbName??"aiworkspace-blobs"}async open(){this.db||(this.db=await new Promise(((e,t)=>{const s=indexedDB.open(this.dbName,1);s.onupgradeneeded=e=>{const t=e.target.result;this.createSchema(t)},s.onsuccess=()=>e(s.result),s.onerror=()=>t(s.error),s.onblocked=()=>t(new Error(`[IndexedDBBlobStorage] Database "${this.dbName}" blocked.`))})),this.db.onversionchange=()=>{this.db?.close(),this.db=null})}createSchema(e){e.objectStoreNames.contains(ee)||e.createObjectStore(ee,{keyPath:"sha256"}),e.objectStoreNames.contains(te)||e.createObjectStore(te,{keyPath:"sha256"})}close(){this.db?.close(),this.db=null}async deleteDatabase(){this.close(),await new Promise(((e,t)=>{const s=indexedDB.deleteDatabase(this.dbName);s.onsuccess=()=>e(),s.onerror=()=>t(s.error)}))}getDB(){if(!this.db)throw new Error("[IndexedDBBlobStorage] Database not open. Call open() first.");return this.db}readTx(...e){return this.getDB().transaction(e,"readonly")}writeTx(...e){return this.getDB().transaction(e,"readwrite")}async storeBytes(e,t){const s=this.readTx(ee);if(await se(s.objectStore(ee).get(e)))return;const r=this.writeTx(ee);r.objectStore(ee).put({sha256:e,data:t}),await re(r)}async loadBytes(e){const t=this.readTx(ee),s=await se(t.objectStore(ee).get(e));return s?.data??null}async hasBytes(e){const t=this.readTx(ee);return await se(t.objectStore(ee).count(e))>0}async deleteBytes(e){const t=this.writeTx(ee);t.objectStore(ee).delete(e),await re(t)}async saveRecord(e){const t=this.writeTx(te);t.objectStore(te).put(e),await re(t)}async loadRecord(e){const t=this.readTx(te);return await se(t.objectStore(te).get(e))??null}async deleteRecord(e){const t=this.writeTx(te);t.objectStore(te).delete(e),await re(t)}async listRecords(){return se(this.readTx(te).objectStore(te).getAll())}async exportAllBytes(){const e=this.readTx(ee);return(await se(e.objectStore(ee).getAll())).map((({sha256:e,data:t})=>[e,t]))}async registerBlob(e,t){await new Promise(((s,r)=>{const n=this.getDB().transaction([ee,te],"readwrite"),o=n.objectStore(ee),i=n.objectStore(te),a=o.count(e.sha256);a.onsuccess=()=>{0===a.result&&o.put({sha256:e.sha256,data:t}),i.put(e)},a.onerror=()=>r(a.error),n.oncomplete=()=>s(),n.onerror=()=>r(n.error),n.onabort=()=>r(new Error("registerBlob transaction aborted"))}))}};export{R as BlobStore,b as COLLECTIONS,A as ContentStore,ne as IndexedDBBlobStorage,Z as MemoryBlobStorage,H as PromptBuilder,G as Session,Q as SessionManager,N as TurnTree,q as WorkspaceManager,X as buildTurnNode,B as computeSHA256,O as createSimpleWorkspace,y as createWorkspaceDatabase,v as del,T as err,C as extractBlobRecord,_ as extractBlobRef,x as merge,S as ok,k as omitNullUndefined,F as workspaceReducer};
|
|
1
|
+
import{v7 as e}from"uuid";var t,s,r=Object.create,n=Object.defineProperty,o=Object.getOwnPropertyDescriptor,i=Object.getOwnPropertyNames,a=Object.getPrototypeOf,c=Object.prototype.hasOwnProperty,d=(e,t,s)=>(s=null!=e?r(a(e)):{},((e,t,s,r)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let a of i(t))c.call(e,a)||a===s||n(e,a,{get:()=>t[a],enumerable:!(r=o(t,a))||r.enumerable});return e})(e&&e.__esModule?s:n(s,"default",{value:e,enumerable:!0}),e)),l=(t={"node_modules/@asaidimu/events/index.js"(e,t){var s,r=Object.defineProperty,n=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyNames,i=Object.prototype.hasOwnProperty,a={};((e,t)=>{for(var s in t)r(e,s,{get:t[s],enumerable:!0})})(a,{createEventBus:()=>c}),t.exports=(s=a,((e,t,s,a)=>{if(t&&"object"==typeof t||"function"==typeof t)for(let c of o(t))i.call(e,c)||c===s||r(e,c,{get:()=>t[c],enumerable:!(a=n(t,c))||a.enumerable});return e})(r({},"__esModule",{value:!0}),s));var c=(e={async:!1,batchSize:1e3,batchDelay:16,errorHandler:e=>console.error("EventBus Error:",e),crossTab:!1,channelName:"event-bus-channel"})=>{const t=new Map;let s=[],r=0,n=0;const o=new Map,i=new Map;let a=null;e.crossTab&&"undefined"!=typeof BroadcastChannel?a=new BroadcastChannel(e.channelName):e.crossTab&&console.warn("BroadcastChannel is not supported in this browser. Cross-tab notifications are disabled.");const c=(e,t)=>{r++,n+=t,o.set(e,(o.get(e)||0)+1)},d=()=>{const t=s;s=[],t.forEach((({name:t,payload:s})=>{const r=performance.now();try{(i.get(t)||[]).forEach((e=>e(s)))}catch(r){e.errorHandler({...r,eventName:t,payload:s})}c(t,performance.now()-r)}))},l=(()=>{let t;return()=>{clearTimeout(t),t=setTimeout(d,e.batchDelay)}})(),u=e=>{const s=t.get(e);s?i.set(e,Array.from(s)):i.delete(e)};return a&&(a.onmessage=e=>{const{name:t,payload:s}=e.data;(i.get(t)||[]).forEach((e=>e(s)))}),{subscribe:(e,s)=>{t.has(e)||t.set(e,new Set);const r=t.get(e);return r.add(s),u(e),()=>{r.delete(s),0===r.size?(t.delete(e),i.delete(e)):u(e)}},emit:({name:t,payload:r})=>{if(e.async)return s.push({name:t,payload:r}),s.length>=e.batchSize?d():l(),void(a&&a.postMessage({name:t,payload:r}));const n=performance.now();try{(i.get(t)||[]).forEach((e=>e(r))),a&&a.postMessage({name:t,payload:r})}catch(s){e.errorHandler({...s,eventName:t,payload:r})}c(t,performance.now()-n)},getMetrics:()=>({totalEvents:r,activeSubscriptions:Array.from(t.values()).reduce(((e,t)=>e+t.size),0),eventCounts:o,averageEmitDuration:r>0?n/r:0}),clear:()=>{t.clear(),i.clear(),s=[],r=0,n=0,o.clear(),a&&(a.close(),a=null)}}}}},function(){return s||(0,t[i(t)[0]])((s={exports:{}}).exports,s),s.exports}),u=[{name:"role",version:"1.0.0",description:"AI persona with a system prompt and associated preference defaults.",fields:{name:{name:"name",type:"string",required:!0},label:{name:"label",type:"string",required:!0},description:{name:"description",type:"string",required:!1},persona:{name:"persona",type:"string",required:!0},preferences:{name:"preferences",type:"array",required:!1,itemsType:"string"}},indexes:[{name:"by_name",fields:["name"],type:"unique"},{name:"by_label",fields:["label"],type:"normal"}],constraints:[],migrations:[]},{name:"preference",version:"1.0.0",description:"A user behavioural instruction, scoped to zero or more topics.",fields:{id:{name:"id",type:"string",required:!0},content:{name:"content",type:"string",required:!0},topics:{name:"topics",type:"array",required:!1,itemsType:"string"},timestamp:{name:"timestamp",type:"string",required:!0}},indexes:[{name:"by_id",fields:["id"],type:"unique"},{name:"by_topics",fields:["topics"],type:"normal"},{name:"by_timestamp",fields:["timestamp"],type:"btree"}],constraints:[],migrations:[]},{name:"context",version:"1.0.0",description:"Injected background knowledge, scoped to topics. Content is a discriminated union.",fields:{key:{name:"key",type:"string",required:!0},topics:{name:"topics",type:"array",required:!1,itemsType:"string"},content:{name:"content",type:"record",required:!0},timestamp:{name:"timestamp",type:"string",required:!0},metadata:{name:"metadata",type:"record",required:!1}},indexes:[{name:"by_key",fields:["key"],type:"unique"},{name:"by_topics",fields:["topics"],type:"normal"},{name:"by_timestamp",fields:["timestamp"],type:"btree"}],constraints:[],migrations:[]},{name:"session",version:"1.0.0",description:"Session metadata. The head field tracks the current tip of the turn DAG.",fields:{id:{name:"id",type:"string",required:!0},label:{name:"label",type:"string",required:!0},role:{name:"role",type:"string",required:!0},topics:{name:"topics",type:"array",required:!1,itemsType:"string"},preferences:{name:"preferences",type:"array",required:!1,itemsType:"string"},metadata:{name:"metadata",type:"record",required:!1},flushedTurnCount:{name:"flushedTurnCount",type:"number",required:!0},head:{name:"head",type:"record",required:!1}},indexes:[{name:"by_id",fields:["id"],type:"unique"},{name:"by_role",fields:["role"],type:"normal"}],constraints:[],migrations:[]},{name:"turn",version:"1.0.0",description:["A single message in a session transcript, stored as a flat document.","The DAG is reconstructed in memory by TurnTree.buildNodeGraph() at session open time.","$id is a composite key: `${sessionId}:${id}:${version}`."].join(" "),fields:{id:{name:"id",type:"string",required:!0},sessionId:{name:"sessionId",type:"string",required:!0},version:{name:"version",type:"number",required:!0},owner:{name:"owner",type:"enum",required:!0,values:["user","assistant","tool"]},blocks:{name:"blocks",type:"array",required:!0},timestamp:{name:"timestamp",type:"string",required:!0},role:{name:"role",type:"string",required:!1},parent:{name:"parent",type:"record",required:!1}},indexes:[{name:"by_session",fields:["sessionId"],type:"normal"},{name:"by_session_parent",fields:["sessionId","parent"],type:"composite"},{name:"by_session_id_ver",fields:["sessionId","id","version"],type:"composite",unique:!0}],constraints:[],migrations:[]},{name:"task",version:"1.0.0",description:"A first-class task entity with status, steps, and topics.",fields:{id:{name:"id",type:"string",required:!0},title:{name:"title",type:"string",required:!0},description:{name:"description",type:"string",required:!1},status:{name:"status",type:"enum",required:!0,values:["todo","active","done","blocked","defered"]},steps:{name:"steps",type:"array",required:!0,itemsType:"record"},topics:{name:"topics",type:"array",required:!1,itemsType:"string"},metadata:{name:"metadata",type:"record",required:!1},created:{name:"created",type:"string",required:!0},updated:{name:"updated",type:"string",required:!0}},indexes:[{name:"by_id",fields:["id"],type:"unique"},{name:"by_status",fields:["status"],type:"normal"},{name:"by_topics",fields:["topics"],type:"normal"},{name:"by_updated",fields:["updated"],type:"btree"}],constraints:[],migrations:[]}],p=class e extends Error{constructor(t,s){super(t,{cause:s}),this.name="SyncError",Object.setPrototypeOf(this,e.prototype)}},h=class extends p{constructor(e){super(`[ArtifactContainer] Operation timed out: ${e}`)}},f=class{_locked=!1;_capacity;_yieldMode;waiters=[];constructor(e){this._capacity=e?.capacity??1/0,this._yieldMode=e?.yieldMode??"macrotask"}async lock(e){if(!this._locked)return void(this._locked=!0);if(this.waiters.length>=this._capacity)throw new Error(`Mutex queue is full (capacity: ${this._capacity})`);let t;const s=new Promise((e=>t=e));this.waiters.push(t),null!=e?await Promise.race([s,new Promise(((s,r)=>setTimeout((()=>{const e=this.waiters.indexOf(t);-1!==e&&this.waiters.splice(e,1),r(new h("Mutex lock timed out"))}),e)))]):await s}tryLock(){return!this._locked&&(this._locked=!0,!0)}unlock(){if(!this._locked)throw new Error("Mutex is not locked");const e=this.waiters.shift();e?"microtask"===this._yieldMode?queueMicrotask(e):setTimeout(e,0):this._locked=!1}locked(){return this._locked}pending(){return this.waiters.length}},m=class{mutex=new f({yieldMode:"microtask"});promise=null;_value=null;_error;_done=!1;retry;throws;constructor({retry:e,throws:t}={}){this.retry=Boolean(e),this.throws=Boolean(t)}async do(e,t){return this._done?this.peek():this.promise?this._awaitWithTimeout(this.promise,t,"Once do() timed out"):(await this.mutex.lock(),this.promise?(this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")):(this.promise=(async()=>{try{const t=await e();this._value=t,this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.promise=null}return this.peek()})(),this.mutex.unlock(),this._awaitWithTimeout(this.promise,t,"Once do() timed out")))}doSync(e){if(this._done){if(this.throws&&this._error)throw this._error;return this.peek()}if(this.promise){const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}if(!this.mutex.tryLock()){const e=new Error("Cannot execute doSync: lock is currently held.");if(this.throws)throw e;return{value:null,error:e}}if(this.promise||this._done){if(this.mutex.unlock(),this._done){if(this.throws&&this._error)throw this._error;return this.peek()}const e=new Error("Cannot execute doSync while an async operation is pending.");if(this.throws)throw e;return{value:null,error:e}}try{const t=e();this._value=t,this._done=!0}catch(e){if(this._error=e,this.retry||(this._done=!0),this.throws)throw e}finally{this.mutex.unlock()}return this.peek()}isReady(){return this._done&&null===this.promise}running(){return null!==this.promise&&!this._done}peek(){return{value:this._value,error:this._error}}get(){if(!this._done)throw new Error("Once operation is not yet complete");if(this._error)throw this._error;return this._value}reset(){this._done=!1,this.promise=null,this._value=null,this._error=void 0}resolved(){return this.promise}done(){return this._done}_awaitWithTimeout(e,t,s="Operation timed out"){return null==t?e:Promise.race([e,new Promise(((e,r)=>setTimeout((()=>r(new h(s))),t)))])}};function y(e){const t=new m({retry:!0,throws:!0}),s=new m({retry:!0,throws:!0});return{open:async(s=[])=>(await t.do((async()=>{const t=[...u,...s];await e.setupCollections(t)}))).value,collection:async t=>e.collection(t),close:async()=>(await s.do((()=>{e.close()}))).value}}var b={ROLE:"role",PREFERENCE:"preference",CONTEXT:"context",SESSION:"session",TURN:"turn",TASK:"task"};d(l());var w=Symbol.for("delete"),g=e=>Array.isArray(e)?[...e]:{...e};function v(){return w}d(l()),d(l()),d(l()),d(l()),d(l()),d(l());var k=function(e){const t=e?.deleteMarker||w;function s(e){if(null==e)return e;if(Array.isArray(e))return e.filter((e=>e!==t)).map((e=>"object"!=typeof e||null===e||Array.isArray(e)?e:s(e)));if("object"==typeof e){const r={};for(const[n,o]of Object.entries(e))if(o!==t)if("object"==typeof o&&null!==o){const e=s(o);void 0!==e&&(r[n]=e)}else r[n]=o;return r}return e===t?void 0:e}return function(e,r){if("object"!=typeof e||null===e)return"object"==typeof r&&null!==r?s(r):r===t?{}:r;if("object"!=typeof r||null===r)return e;const n=g(e),o=[{target:n,source:r}];for(;o.length>0;){const{target:e,source:s}=o.pop();for(const r of Object.keys(s)){const n=s[r];if(n!==t)if(Array.isArray(n))e[r]=n;else if("object"==typeof n&&null!==n){const t=r in e&&"object"==typeof e[r]&&null!==e[r]?e[r]:{};e[r]=g(t),o.push({target:e[r],source:n})}else e[r]=n;else delete e[r]}}return n}}({deleteMarker:w});function x(e){return{ok:!0,value:e}}function T(e){return{ok:!1,error:e}}function O(e){return Object.fromEntries(Object.entries(e).filter((([e,t])=>null!=t)))}function S({project:t,language:s}){const r={...t,id:e()};return{id:e(),settings:{language:s},project:r,index:{roles:{},topics:{},preferences:{},context:{},sessions:{},blobs:{},tasks:{},tools:{}}}}function _({name:t,owner:s,language:r}){return{id:e(),settings:{language:r},project:{id:e(),name:t,owner:s},index:{roles:{},topics:{},preferences:{},context:{},sessions:{},blobs:{},tasks:{},tools:{}}}}function N(e){const t=e?.index?.blobs;if(!t)return null;const s=t[Object.keys(t)[0]];return s||null}function I(e){return{sha256:e.sha256,mediaType:e.mediaType,sizeBytes:e.sizeBytes,filename:e.filename,previewUrl:e.previewUrl}}var C=class{db;constructor(e){this.db=e}async turns(){return this.db.collection(b.TURN)}async sessions(){return this.db.collection(b.SESSION)}turnFilter(e,t,s){return{operator:"and",conditions:[{field:"sessionId",operator:"eq",value:e},{field:"id",operator:"eq",value:t},{field:"version",operator:"eq",value:s}]}}async loadRaw(e){const[t,s]=await Promise.all([this.loadAllTurns(e),this.getHead(e)]);return{turns:t,head:s}}async getHead(e){const t=await this.sessions(),s=await t.find({field:"id",operator:"eq",value:e});return s?.head??null}async setHead(e,t){const s=await this.sessions(),r=await s.find({field:"id",operator:"eq",value:e});if(!r)return;const n={...r.state(),head:t??void 0};await r.update(n)}async save(e,t,s){const r={...t,sessionId:e,version:t.version??0,parent:t.parent?t.parent:s?{id:s.id,version:s.version}:null},n=await this.turns();return await n.create(O(r)),r}async append(e,t){const s=await this.getHead(e),r=this.save(e,t,s);return await this.setHead(e,{id:t.id,version:t.version}),r}async appendBatch(e,t,s){const r=await this.getHead(e);if(0!==t.length){for(const s of t)await this.save(e,s,r);await this.setHead(e,s)}}async replaceVersion(e,t){const s=await this.turns(),r=await s.find(this.turnFilter(e,t.id,t.version)),n=O(t);r?await r.update({...n,sessionId:e}):await s.create({...n,sessionId:e})}async branch(e,t){const s=await this.turns();await s.create(O({...t,sessionId:e})),await this.setHead(e,{id:t.id,version:t.version})}async loadAllTurns(e){const t=await this.turns();return(await t.filter({field:"sessionId",operator:"eq",value:e})).map((e=>e.state()))}async loadTurnVersions(e,t){const s=await this.turns();return(await s.filter({operator:"and",conditions:[{field:"sessionId",operator:"eq",value:e},{field:"id",operator:"eq",value:t}]})).map((e=>e.state()))}buildNodes(e,t,s=[]){const r=function(e,t){if(!t)return new Set;const s=new Map;for(const t of e)s.set(`${t.id}:${t.version}`,t);const r=new Set;let n=t;for(;n;){const e=`${n.id}:${n.version}`;if(r.has(e))break;r.add(e);const t=s.get(e);if(!t)break;n=t.parent}return r}(e,t),n={},o={},i=[...e,...s];for(const e of i){n[e.id]||(n[e.id]={id:e.id,versions:{},activeVersion:e.version,role:e.owner,blocks:e.blocks,timestamp:e.timestamp,roleSnapshot:e.role,parent:e.parent,children:{}},o[e.id]=new Set);const t=n[e.id];t.versions[e.version]=e;const s=r.has(`${e.id}:${e.version}`),i=r.has(`${e.id}:${t.activeVersion}`);if(s&&(!i||e.version>=t.activeVersion)&&(t.activeVersion=e.version,t.blocks=e.blocks,t.timestamp=e.timestamp,t.roleSnapshot=e.role,t.parent=e.parent),e.parent){const t=`${e.parent.id}:${e.parent.version}`;if(o[e.parent.id]||(o[e.parent.id]=new Set),!o[e.parent.id].has(t+":"+e.id)){o[e.parent.id].add(t+":"+e.id),n[e.parent.id]||(n[e.parent.id]={id:e.parent.id,versions:{},activeVersion:e.parent.version,role:"user",blocks:[],timestamp:"",roleSnapshot:void 0,parent:null,children:{}});const s=n[e.parent.id],r=e.parent.version;s.children[r]||(s.children[r]=[]),s.children[r].push(e.id)}}}return n}async buildNodeGraph(e,t=[]){const{turns:s,head:r}=await this.loadRaw(e);return this.buildNodes(s,r,t)}async getActiveChain(e,t=[]){const{turns:s,head:r}=await this.loadRaw(e);if(!r&&0===t.length)return[];return[...r?R(s,r):[],...t]}async buildActiveChain(e){const{turns:t,head:s}=await this.loadRaw(e);if(!s)return[];const r=this.buildNodes(t,s),n=[];let o=s.id;for(;null!==o;){const e=r[o];if(!e)break;n.push(e),o=e.parent?.id??null}return n.reverse()}async getTurnSiblings(e,t){const{turns:s,head:r}=await this.loadRaw(t),n=this.buildNodes(s,r),o=n[e];if(!o)return[];if(!o.parent)return Object.values(n).filter((e=>null===e.parent));const i=n[o.parent.id];if(!i)return[o];const a=o.parent.version,c=i.children[a];return c?c.map((e=>n[e])).filter((e=>void 0!==e)):[o]}async branchInfo(e,t){const{turns:s,head:r}=await this.loadRaw(t),n=this.buildNodes(s,r)[e];if(!n)return{versions:[],currentIndex:-1,total:0,hasPrev:!1,hasNext:!1};const o=Object.keys(n.versions).map(Number).sort(((e,t)=>e-t)),i=o.indexOf(n.activeVersion);return{versions:o,currentIndex:i,total:o.length,hasPrev:i>0,hasNext:i<o.length-1}}async deleteSubtree(e,t,s,r){const n=function(e,t,s){const r=new Map;for(const t of e)if(t.parent){const e=`${t.parent.id}:${t.parent.version}`;let s=r.get(e);s||(s=new Set,r.set(e,s)),s.add(`${t.id}:${t.version}`)}const n=new Set,o=[`${t}:${s}`];for(;o.length>0;){const e=o.pop();n.add(e);const t=r.get(e);if(t)for(const e of t)n.has(e)||o.push(e)}return n}(await this.loadAllTurns(e),t,s),o=await this.turns();await Promise.all(Array.from(n).map((async t=>{const[s,r]=t.split(":"),n=await o.find(this.turnFilter(e,s,Number(r)));n&&await n.delete()}))),await this.setHead(e,r)}async copyTranscript(e,t){const{turns:s,head:r}=await this.loadRaw(e),n=r?R(s,r):[],o=await this.turns();for(const e of n)await o.create(O({...e,sessionId:t}));await this.setHead(t,r?{...r}:null)}};function R(e,t){const s=new Map;for(const t of e)s.set(`${t.id}:${t.version}`,t);const r=[];let n=t;for(;n;){const e=s.get(`${n.id}:${n.version}`);if(!e)break;r.push(e),n=e.parent}return r.reverse()}async function E(e){const t=await crypto.subtle.digest("SHA-256",e);return Array.from(new Uint8Array(t)).map((e=>e.toString(16).padStart(2,"0"))).join("")}var B=class{storage;config;bus;recordCache=new Map;constructor(e,t,s={}){this.storage=e,this.bus=t,this.config={eagerEviction:s.eagerEviction??!1}}subscribe(e,t){return this.bus.subscribe(e,t)}async init(){const e=await this.storage.listRecords();for(const t of e)this.recordCache.set(t.sha256,t)}async register(e,t,s){try{const r=await E(e),n=(new Date).toISOString(),o=this.recordCache.get(r);if(o){const e={...o,refCount:o.refCount+1,lastUsedAt:n};await this.storage.saveRecord(e),this.recordCache.set(r,e)}else{const o={sha256:r,mediaType:t,sizeBytes:e.byteLength,filename:s,refCount:1,remoteIds:{},createdAt:n,lastUsedAt:n};"function"==typeof this.storage.registerBlob?await this.storage.registerBlob(o,e):(await this.storage.storeBytes(r,e),await this.storage.saveRecord(o)),this.recordCache.set(r,o)}const i=this.recordCache.get(r);return x({sha256:r,mediaType:t,sizeBytes:i.sizeBytes,filename:i.filename,previewUrl:i.previewUrl})}catch(e){return T({code:"BLOB_ERROR",reason:e instanceof Error?e.message:String(e)})}}async retain(e){const t=this.recordCache.get(e);if(!t)return T({code:"NOT_FOUND",resource:"blob",id:e});const s={...t,refCount:t.refCount+1,lastUsedAt:(new Date).toISOString()};return await this.storage.saveRecord(s),this.recordCache.set(e,s),x(void 0)}async release(e){const t=this.recordCache.get(e);if(!t)return T({code:"NOT_FOUND",resource:"blob",id:e});const s=Math.max(0,t.refCount-1),r={...t,refCount:s,lastUsedAt:(new Date).toISOString()};return 0===s&&this.config.eagerEviction?(await this.storage.deleteBytes(e),await this.storage.deleteRecord(e),this.recordCache.delete(e)):(await this.storage.saveRecord(r),this.recordCache.set(e,r)),x(void 0)}async recordRemoteId(e,t,s){const r=this.recordCache.get(e);if(!r)return T({code:"NOT_FOUND",resource:"blob",id:e});if(r.remoteIds[t]===s)return x(void 0);const n={...r,remoteIds:{...r.remoteIds,[t]:s}};return await this.storage.saveRecord(n),this.recordCache.set(e,n),x(void 0)}getRemoteId(e,t){return this.recordCache.get(e)?.remoteIds[t]??null}async resolveRef(e,t){try{if(t){const s=this.getRemoteId(e.sha256,t);if(s)return x({kind:"remote",sha256:e.sha256,mediaType:e.mediaType,fileId:s,providerId:t})}const s=await this.storage.loadBytes(e.sha256);return s?x({kind:"inline",sha256:e.sha256,mediaType:e.mediaType,data:s}):T({code:"BLOB_ERROR",reason:`Blob bytes not found locally for sha256=${e.sha256}. The blob may have been evicted. Re-register it before resolving.`})}catch(e){return T({code:"BLOB_ERROR",reason:e instanceof Error?e.message:String(e)})}}async resolveRefs(e,t){const s=function(e){const t=new Set,s=[];for(const r of e)t.has(r.sha256)||(t.add(r.sha256),s.push(r));return s}(e),r=await Promise.all(s.map((async e=>({ref:e,result:await this.resolveRef(e,t)})))),n=new Map,o=[];for(const{ref:e,result:t}of r)t.ok?n.set(e.sha256,t.value):o.push({ref:e,error:t.error});return{resolved:n,errors:o}}async gc(){const e=Array.from(this.recordCache.values()).filter((e=>0===e.refCount));return await Promise.all(e.map((async e=>{await this.storage.deleteBytes(e.sha256),await this.storage.deleteRecord(e.sha256),this.recordCache.delete(e.sha256),this.bus.emit({name:"blobs:changed",payload:{sha256:e.sha256,record:null}})}))),e.length}async purge(e){return this.recordCache.has(e)?(await this.storage.deleteBytes(e),await this.storage.deleteRecord(e),this.recordCache.delete(e),x(void 0)):T({code:"NOT_FOUND",resource:"blob",id:e})}getRecord(e){return this.recordCache.get(e)??null}getAllRecords(){const e={};for(const[t,s]of this.recordCache)e[t]=s;return e}};var D=10,q=50,j=20,U=10,A=class{map=new Map;max;constructor(e){this.max=e}get(e){if(!this.map.has(e))return;const t=this.map.get(e);return this.map.delete(e),this.map.set(e,t),t}set(e,t){if(this.map.has(e)&&this.map.delete(e),this.map.set(e,t),this.map.size>this.max){const e=this.map.keys().next().value;void 0!==e&&this.map.delete(e)}}has(e){return this.map.has(e)}delete(e){this.map.delete(e)}};var M=class e{db;tree;blobs;roleCache;preferenceCache;contextCache;taskCache;bus;subscribe(e,t){return this.bus.subscribe(e,t)}constructor(e,t,s,r={}){this.db=e,this.tree=new C(e),this.blobs=new B(t,s);const n={roles:r.cache?.roles??D,preferences:r.cache?.preferences??q,context:r.cache?.context??j,tasks:r.cache?.tasks??U};this.roleCache=new A(n.roles),this.preferenceCache=new A(n.preferences),this.contextCache=new A(n.context),this.taskCache=new A(n.tasks),this.bus=s}static async create(t,s,r,n){const o=new e(t,s,r,n);return await o.init(),o}async init(e){await this.db.open(e),await this.blobs.init()}getTurnTree(){return this.tree}async getRole(e){const t=this.roleCache.get(e);if(t)return x(t);const s=await this.db.collection(b.ROLE),r=await s.find({field:"name",operator:"eq",value:e});if(!r)return T({code:"NOT_FOUND",resource:"role",id:e});const n=r.state();return this.roleCache.set(e,n),x(n)}async saveRole(e){const t=await this.db.collection(b.ROLE),s=await t.find({field:"name",operator:"eq",value:e.name});s?await s.update(e):await t.create(e),this.roleCache.set(e.name,e)}async deleteRole(e){const t=await this.db.collection(b.ROLE),s=await t.find({field:"name",operator:"eq",value:e});s&&await s.delete(),this.roleCache.delete(e)}async getPreference(e){const t=this.preferenceCache.get(e);if(t)return x(t);const s=await this.db.collection(b.PREFERENCE),r=await s.find({field:"id",operator:"eq",value:e});if(!r)return T({code:"NOT_FOUND",resource:"preference",id:e});const n=r.state();return this.preferenceCache.set(e,n),x(n)}async savePreference(e){const t=await this.db.collection(b.PREFERENCE),s=await t.find({field:"id",operator:"eq",value:e.id});s?await s.update(e):await t.create(e),this.preferenceCache.set(e.id,e)}async deletePreference(e){const t=await this.db.collection(b.PREFERENCE),s=await t.find({field:"id",operator:"eq",value:e});s&&await s.delete(),this.preferenceCache.delete(e)}async getContext(e){const t=this.contextCache.get(e);if(t)return x(t);const s=await this.db.collection(b.CONTEXT),r=await s.find({field:"key",operator:"eq",value:e});if(!r)return T({code:"NOT_FOUND",resource:"context",id:e});const n=r.state();return this.contextCache.set(e,n),x(n)}async saveContext(e){const t=await this.db.collection(b.CONTEXT),s=await t.find({field:"key",operator:"eq",value:e.key});s?await s.update(e):await t.create(e),this.contextCache.set(e.key,e)}async deleteContext(e){const t=await this.db.collection(b.CONTEXT),s=await t.find({field:"key",operator:"eq",value:e});s&&await s.delete(),this.contextCache.delete(e)}async getContextByTopics(e,t){const s=new Set;for(const r of t){const t=e.topics[r];t&&t.contextKeys.forEach((e=>s.add(e)))}if(0===s.size)return[];const r=[],n=[];for(const e of s){const t=this.contextCache.get(e);t?n.push(t):r.push(e)}let o=[];if(r.length>0){const e=await this.db.collection(b.CONTEXT),t=await e.filter({operator:"or",conditions:r.map((e=>({field:"key",operator:"eq",value:e})))});for(const e of t){const t=e.state();this.contextCache.set(t.key,t),o.push(t)}}return[...n,...o].sort(((e,t)=>new Date(t.timestamp).getTime()-new Date(e.timestamp).getTime()))}async getTask(e){const t=this.taskCache.get(e);if(t)return x(t);const s=await this.db.collection(b.TASK),r=await s.find({field:"id",operator:"eq",value:e});if(!r)return T({code:"NOT_FOUND",resource:"task",id:e});const n=r.state();return this.taskCache.set(e,n),x(n)}async saveTask(e){const t=await this.db.collection(b.TASK),s=await t.find({field:"id",operator:"eq",value:e.id});s?await s.update(e):await t.create(e),this.taskCache.set(e.id,e)}async deleteTask(e){const t=await this.db.collection(b.TASK),s=await t.find({field:"id",operator:"eq",value:e});s&&await s.delete(),this.taskCache.delete(e)}async getTasksByTopics(e,t){const s=new Set;for(const r of t){const t=e.topics[r];t&&t.tasks&&t.tasks.forEach((e=>s.add(e)))}if(0===s.size)return[];const r=[],n=[];for(const e of s){const t=this.taskCache.get(e);t?n.push(t):r.push(e)}let o=[];if(r.length>0){const e=await this.db.collection(b.TASK),t=await e.filter({operator:"or",conditions:r.map((e=>({field:"id",operator:"eq",value:e})))});for(const e of t){const t=e.state();this.taskCache.set(t.id,t),o.push(t)}}return[...n,...o].sort(((e,t)=>new Date(t.updated).getTime()-new Date(e.updated).getTime()))}async saveSession(e){const t=await this.db.collection(b.SESSION),s=await t.find({field:"id",operator:"eq",value:e.id}),r=O(e);s?await s.update(r):await t.create(r)}async updateSessionMeta(e,t){const s=await this.db.collection(b.SESSION),r=await s.find({field:"id",operator:"eq",value:e});if(!r)return;const n=r.state(),o=k(n,t);await r.update(O(o))}async deleteSession(e){const t=await this.db.collection(b.SESSION),s=await t.find({field:"id",operator:"eq",value:e});s&&await s.delete()}async registerBlob(e,t,s){return this.blobs.register(e,t,s)}async retainBlob(e){return this.blobs.retain(e)}async releaseBlob(e){return this.blobs.release(e)}async purgeBlob(e){return this.blobs.purge(e)}async recordBlobRemoteId(e,t,s){return this.blobs.recordRemoteId(e,t,s)}getBlobRecord(e){return this.blobs.getRecord(e)}getAllBlobRecords(){return this.blobs.getAllRecords()}getBlobResolver(){return this.blobs.resolveRefs.bind(this.blobs)}async appendTurn(e,t){return x(await this.tree.append(e,t))}async saveTurn(e,t){return x(await this.tree.save(e,t))}async editTurn(e,t,s,r,n){const o=(await this.tree.loadTurnVersions(e,t)).find((e=>e.version===r-1));if(!o)return T({code:"NOT_FOUND",resource:"turn",id:t});const i={id:t,version:r,owner:o.owner,blocks:s,timestamp:(new Date).toISOString(),role:n??o.role,parent:o.parent};await this.tree.replaceVersion(e,i);const a=await this.tree.getHead(e);return a?.id===t&&await this.tree.setHead(e,{id:i.id,version:i.version}),x(void 0)}async branchTurn(e,t){return await this.tree.branch(e,t),x(void 0)}async deleteTurnSubtree(e,t,s,r){return await this.tree.deleteSubtree(e,t,s,r),x(void 0)}async copyTranscript(e,t){await this.tree.copyTranscript(e,t)}async resolveSession(e,t,s){const r=e.index.sessions[t];if(!r)return T({code:"NOT_FOUND",resource:"session",id:t});const n=await this.getRole(r.role);if(!n.ok)return n;const o=n.value,i=function(e,t){return e.preferences.length>0?e.preferences:t.preferences}(r,o),a=function(e,t){return e.filter((e=>0===e.topics.length||e.topics.some((e=>t.includes(e)))))}((await Promise.all(i.map((e=>this.getPreference(e))))).filter((e=>e.ok)).map((e=>e.value)),r.topics),c=await this.getContextByTopics(e.index,r.topics),d=await this.getTasksByTopics(e.index,r.topics);let l=null;if(r.task&&!d.find((e=>e.id===r.task))){const e=await this.getTask(r.task);e.ok&&(l=e.value)}const u=s??await this.tree.getActiveChain(t),p={session:r,role:o,preferences:a,context:c,task:l,transcript:u,instructions:e.settings?.prompt};return x({...p,preferences:Object.freeze([...p.preferences]),context:Object.freeze([...p.context]),transcript:Object.freeze([...p.transcript])})}async gc(){return this.blobs.gc()}};function F({index:e},t){switch(t.type){case"role:add":{const s=t.payload;if(e.roles[s.name])return T({code:"DUPLICATE_KEY",resource:"role",key:s.name});const r={name:s.name,label:s.label,description:s.description,preferences:s.preferences.length};return x({index:{roles:{[s.name]:r}}})}case"role:update":{const{name:s,...r}=t.payload;if(!e.roles[s])return T({code:"NOT_FOUND",resource:"role",id:s});const n=e.roles[s],o={...n,...r,preferences:r.preferences?.length??n.preferences};return x({index:{roles:{[s]:o}}})}case"role:delete":{const{name:s}=t.payload;if(!e.roles[s])return T({code:"NOT_FOUND",resource:"role",id:s});return Object.values(e.sessions).some((e=>e.role===s))?T({code:"INVALID_COMMAND",reason:`Cannot delete role "${s}" — it is still referenced by one or more sessions`}):x({index:{roles:{[s]:v()}}})}case"preference:add":{const s=t.payload,r={id:s.id,topics:s.topics,timestamp:s.timestamp,snippet:s.content.substring(0,100)},n={};return s.topics.forEach((r=>{const o=e.topics[r],i=[...o?.preferences??[],s.id],a=o?.contextKeys??[],c=o?.tasks??[],d=a.length+i.length+c.length;n[r]={topic:r,contextKeys:a,preferences:i,tasks:c,metadata:{created:o?.metadata?.created??t.timestamp,updated:t.timestamp,entries:d}}})),x({index:{preferences:{[s.id]:r},topics:n}})}case"preference:update":{const{id:s,...r}=t.payload;if(!e.preferences[s])return T({code:"NOT_FOUND",resource:"preference",id:s});const n=e.preferences[s],o={...n,...r,snippet:r.content?r.content.substring(0,100):n.snippet},i={};return r.topics&&(n.topics.forEach((r=>{const n=e.topics[r];if(n){const e=n.preferences.filter((e=>e!==s)),o=n.contextKeys.length+e.length+n.tasks.length;i[r]={preferences:e,metadata:{...n.metadata,updated:t.timestamp,entries:o}}}})),r.topics.forEach((r=>{const n=e.topics[r]??{contextKeys:[],preferences:[],tasks:[],metadata:{created:t.timestamp}},o=[...n.preferences,s],a=n.contextKeys.length+o.length+n.tasks.length;i[r]={topic:r,contextKeys:n.contextKeys,preferences:o,tasks:n.tasks,metadata:{created:n.metadata?.created??t.timestamp,updated:t.timestamp,entries:a}}}))),x({index:{preferences:{[s]:o},topics:i}})}case"preference:delete":{const{id:s}=t.payload;if(!e.preferences[s])return T({code:"NOT_FOUND",resource:"preference",id:s});const r=e.preferences[s],n={};return r.topics.forEach((r=>{const o=e.topics[r];if(o){const e=o.preferences.filter((e=>e!==s)),i=o.contextKeys.length+e.length+o.tasks.length;n[r]={preferences:e,metadata:{...o.metadata,updated:t.timestamp,entries:i}}}})),x({index:{preferences:{[s]:v()},topics:n}})}case"context:add":{const s=t.payload;if(e.context[s.key])return T({code:"DUPLICATE_KEY",resource:"context",key:s.key});const r=s.content,n={key:s.key,topics:s.topics,timestamp:s.timestamp,source:s.key.split(":")[0],preview:"text"===r.kind?r.value.substring(0,200):"json"===r.kind?JSON.stringify(r.value).substring(0,200):void 0,metadata:s.metadata},o={};return s.topics.forEach((r=>{const n=e.topics[r],i=[...n?.contextKeys??[],s.key],a=n?.preferences??[],c=n?.tasks??[],d=i.length+a.length+c.length;o[r]={topic:r,contextKeys:i,preferences:a,tasks:c,metadata:{created:n?.metadata?.created??t.timestamp,updated:t.timestamp,entries:d}}})),x({index:{context:{[s.key]:n},topics:o}})}case"context:update":{const{key:s,...r}=t.payload;if(!e.context[s])return T({code:"NOT_FOUND",resource:"context",id:s});const n=e.context[s],o=r.content,i={...n,...r,preview:o?"text"===o.kind?o.value.substring(0,200):"json"===o.kind?JSON.stringify(o.value).substring(0,200):void 0:n.preview},a={};return r.topics&&(n.topics.forEach((r=>{const n=e.topics[r];if(n){const e=n.contextKeys.filter((e=>e!==s)),o=e.length+n.preferences.length+n.tasks.length;a[r]={contextKeys:e,metadata:{...n.metadata,updated:t.timestamp,entries:o}}}})),r.topics.forEach((r=>{const n=e.topics[r]??{contextKeys:[],preferences:[],tasks:[],metadata:{created:t.timestamp}},o=n.contextKeys.includes(s)?n.contextKeys:[...n.contextKeys,s],i=o.length+n.preferences.length+n.tasks.length;a[r]={topic:r,contextKeys:o,preferences:n.preferences,tasks:n.tasks,metadata:{created:n.metadata?.created??t.timestamp,updated:t.timestamp,entries:i}}}))),x({index:{context:{[s]:i},topics:a}})}case"context:delete":{const{key:s}=t.payload;if(!e.context[s])return T({code:"NOT_FOUND",resource:"context",id:s});const r=e.context[s],n={};return r.topics.forEach((r=>{const o=e.topics[r];if(o){const e=o.contextKeys.filter((e=>e!==s)),i=e.length+o.preferences.length+o.tasks.length;n[r]={contextKeys:e,metadata:{...o.metadata,updated:t.timestamp,entries:i}}}})),x({index:{context:{[s]:v()},topics:n}})}case"session:create":{const{id:s,label:r,role:n,topics:o,preferences:i=[]}=t.payload;if(e.sessions[s])return T({code:"DUPLICATE_KEY",resource:"session",key:s});if(!e.roles[n])return T({code:"NOT_FOUND",resource:"role",id:n});const a={id:s,label:r,role:n,topics:o,preferences:i,metadata:{created:t.timestamp,updated:t.timestamp},flushedTurnCount:0,head:null,task:null};return x({index:{sessions:{[s]:a}}})}case"session:role:switch":{const{sessionId:s,role:r}=t.payload;return e.sessions[s]?x({index:{sessions:{[s]:{role:r,metadata:{updated:t.timestamp}}}}}):T({code:"NOT_FOUND",resource:"session",id:s})}case"session:topics:add":{const{sessionId:s,topics:r}=t.payload;if(!e.sessions[s])return T({code:"NOT_FOUND",resource:"session",id:s});const n=e.sessions[s],o=[...new Set([...n.topics,...r])];return x({index:{sessions:{[s]:{topics:o,metadata:{updated:t.timestamp}}}}})}case"session:preferences:override":{const{sessionId:s,preferences:r}=t.payload;return e.sessions[s]?x({index:{sessions:{[s]:{preferences:r,metadata:{updated:t.timestamp}}}}}):T({code:"NOT_FOUND",resource:"session",id:s})}case"session:fork":{const{sourceSessionId:s,newSessionId:r,label:n,role:o,topics:i}=t.payload;if(!e.sessions[s])return T({code:"NOT_FOUND",resource:"session",id:s});if(e.sessions[r])return T({code:"DUPLICATE_KEY",resource:"session",key:r});const a=e.sessions[s],c={id:r,label:n,role:o??a.role,topics:i??[...a.topics],preferences:[...a.preferences],metadata:{created:t.timestamp,updated:t.timestamp},flushedTurnCount:a.flushedTurnCount,head:a.head,task:a.task};return x({index:{sessions:{[r]:c}}})}case"session:delete":{const{sessionId:s}=t.payload;return e.sessions[s]?x({index:{sessions:{[s]:v()}}}):T({code:"NOT_FOUND",resource:"session",id:s})}case"task:add":{const s=t.payload;if(e.tasks[s.id])return T({code:"DUPLICATE_KEY",resource:"task",key:s.id});const r={id:s.id,title:s.title,status:s.status,steps:{completed:s.steps.filter((e=>e.completed)).length,total:s.steps.length},topics:s.topics},n={};return s.topics.forEach((r=>{const o=e.topics[r],i=[...o?.tasks??[],s.id],a=o?.contextKeys??[],c=o?.preferences??[],d=a.length+c.length+i.length;n[r]={topic:r,contextKeys:a,preferences:c,tasks:i,metadata:{created:o?.metadata?.created??t.timestamp,updated:t.timestamp,entries:d}}})),x({index:{tasks:{[s.id]:r},topics:n}})}case"task:update":{const{id:s,...r}=t.payload;if(!e.tasks[s])return T({code:"NOT_FOUND",resource:"task",id:s});const n=e.tasks[s],o={...n,...r,steps:r.steps?{completed:r.steps.filter((e=>e.completed)).length,total:r.steps.length}:n.steps},i={};return r.topics&&(n.topics.forEach((r=>{const n=e.topics[r];if(n){const e=n.tasks.filter((e=>e!==s)),o=n.contextKeys.length+n.preferences.length+e.length;i[r]={tasks:e,metadata:{...n.metadata,updated:t.timestamp,entries:o}}}})),r.topics.forEach((r=>{const n=e.topics[r]??{contextKeys:[],preferences:[],tasks:[],metadata:{created:t.timestamp}},o=[...new Set([...n.tasks,s])],a=n.contextKeys.length+n.preferences.length+o.length;i[r]={topic:r,contextKeys:n.contextKeys,preferences:n.preferences,tasks:o,metadata:{created:n.metadata?.created??t.timestamp,updated:t.timestamp,entries:a}}}))),x({index:{tasks:{[s]:o},topics:i}})}case"task:delete":{const{id:s}=t.payload;if(!e.tasks[s])return T({code:"NOT_FOUND",resource:"task",id:s});const r=e.tasks[s],n={};return r.topics.forEach((r=>{const o=e.topics[r];if(o){const e=o.tasks.filter((e=>e!==s)),i=o.contextKeys.length+o.preferences.length+e.length;n[r]={tasks:e,metadata:{...o.metadata,updated:t.timestamp,entries:i}}}})),x({index:{tasks:{[s]:v()},topics:n}})}case"turn:save":case"turn:add":{const{sessionId:s,turn:r}=t.payload;return e.sessions[s]?x({index:{sessions:{[s]:{head:{id:r.id,version:r.version},metadata:{updated:t.timestamp},flushedTurnCount:(e.sessions[s]?.flushedTurnCount??0)+1}}}}):T({code:"NOT_FOUND",resource:"session",id:s})}case"turn:edit":{const{sessionId:s,turnId:r,newVersion:n}=t.payload;return e.sessions[s]?x({index:{sessions:{[s]:{head:{id:r,version:n},metadata:{updated:t.timestamp}}}}}):T({code:"NOT_FOUND",resource:"session",id:s})}case"turn:branch":{const{sessionId:s,turn:r}=t.payload;return e.sessions[s]?x({index:{sessions:{[s]:{head:{id:r.id,version:r.version},metadata:{updated:t.timestamp}}}}}):T({code:"NOT_FOUND",resource:"session",id:s})}case"turn:delete":{const{sessionId:s,newHead:r}=t.payload;return e.sessions[s]?x({index:{sessions:{[s]:{head:r,metadata:{updated:t.timestamp}}}}}):T({code:"NOT_FOUND",resource:"session",id:s})}case"blob:register":case"tool:call":default:return x({});case"blob:retain":{const{sha256:s}=t.payload;return e.blobs[s]?x({}):T({code:"NOT_FOUND",resource:"blob",id:s})}case"blob:release":{const{sha256:s}=t.payload;return e.blobs[s]?x({}):T({code:"NOT_FOUND",resource:"blob",id:s})}case"blob:purge":{const{sha256:s}=t.payload;return e.blobs[s]?x({}):T({code:"NOT_FOUND",resource:"blob",id:s})}case"blob:record_remote_id":{const{sha256:s}=t.payload;return e.blobs[s]?x({}):T({code:"NOT_FOUND",resource:"blob",id:s})}}}var P=class{contentStore;permissionGuard;toolRegistry;bus;subscribe(e,t){return this.bus.subscribe(e,t)}constructor(e){this.contentStore=e.contentStore,this.permissionGuard=e.permissionGuard,this.toolRegistry=e.toolRegistry,this.bus=e.eventBus,this.bus.subscribe("blobs:changed",(({sha256:e,record:t})=>{const s={index:{blobs:{[e]:t??void 0}}};this.bus.emit({name:"workspace:changed",payload:s})})),this.toolRegistry&&this.toolRegistry.onRegistryChanged((e=>{this.bus.emit({name:"workspace:changed",payload:{index:{tools:e.reduce(((e,t)=>(e[t.name]=t,e)),{})}}})}))}init(e){if(!this.toolRegistry)return{};const t={};for(const e of this.toolRegistry.list())t[e.name]=e;return{index:{tools:t}}}reduce(e,t){return F(e,t)}async dispatch(e,t){if(this.permissionGuard){const e="tool:call"===t.type?{type:"tool",payload:t.payload}:{type:"command",payload:t},s=await this.permissionGuard.authenticate(e);if(!s.ok)return s}const s=F(e,t);if(!s.ok)return s;let r={};try{r=await this.handleContentSideEffects(e,t)}catch(e){return T({code:"BACKEND_ERROR",reason:e instanceof Error?e.message:String(e)})}return x(k(s.value,r))}async resolveSession(e,t,s){return this.contentStore.resolveSession(e,t,s)}async handleContentSideEffects(e,t){switch(t.type){case"blob:register":{const{data:e,mediaType:s,filename:r}=t.payload,n=await this.contentStore.registerBlob(e,s,r);if(!n.ok)throw Object.assign(new Error(n.error.code),{wsError:n.error});const o=n.value,i=this.contentStore.getBlobRecord(o.sha256);if(!i)throw new Error("Record missing after register");return{index:{blobs:{[o.sha256]:i}}}}case"blob:retain":{const{sha256:e}=t.payload,s=await this.contentStore.retainBlob(e);if(!s.ok)throw Object.assign(new Error(s.error.code),{wsError:s.error});const r=this.contentStore.getBlobRecord(e);return{index:{blobs:{[e]:r??void 0}}}}case"blob:release":{const{sha256:e}=t.payload,s=await this.contentStore.releaseBlob(e);if(!s.ok)throw Object.assign(new Error(s.error.code),{wsError:s.error});const r=this.contentStore.getBlobRecord(e);return{index:{blobs:{[e]:r??void 0}}}}case"blob:purge":{const{sha256:e}=t.payload,s=await this.contentStore.purgeBlob(e);if(!s.ok)throw Object.assign(new Error(s.error.code),{wsError:s.error});return{index:{blobs:{[e]:void 0}}}}case"blob:record_remote_id":{const{sha256:e,providerId:s,fileId:r}=t.payload,n=await this.contentStore.recordBlobRemoteId(e,s,r);if(!n.ok)throw Object.assign(new Error(n.error.code),{wsError:n.error});const o=this.contentStore.getBlobRecord(e);return{index:{blobs:{[e]:o??void 0}}}}case"role:add":return await this.contentStore.saveRole(t.payload),{};case"role:update":{const{name:e,...s}=t.payload,r=await this.contentStore.getRole(e);if(!r.ok)throw new Error(`role:update — "${e}" not found`);return await this.contentStore.saveRole({...r.value,...s,name:e}),{}}case"role:delete":return await this.contentStore.deleteRole(t.payload.name),{};case"preference:add":return await this.contentStore.savePreference(t.payload),{};case"preference:update":{const{id:e,...s}=t.payload,r=await this.contentStore.getPreference(e);if(!r.ok)throw new Error(`preference:update — "${e}" not found`);return await this.contentStore.savePreference({...r.value,...s,id:e}),{}}case"preference:delete":return await this.contentStore.deletePreference(t.payload.id),{};case"context:add":case"context:update":return await this.contentStore.saveContext(t.payload),{};case"context:delete":return await this.contentStore.deleteContext(t.payload.key),{};case"task:add":return await this.contentStore.saveTask(t.payload),{};case"task:update":{const{id:e,...s}=t.payload,r=await this.contentStore.getTask(e);if(!r.ok)throw new Error(`task:update — "${e}" not found`);return await this.contentStore.saveTask({...r.value,...s,id:e}),{}}case"task:delete":return await this.contentStore.deleteTask(t.payload.id),{};case"session:create":{const{id:e,label:s,role:r,topics:n,preferences:o=[]}=t.payload;return await this.contentStore.saveSession({id:e,label:s,role:r,topics:n,preferences:o,metadata:{created:t.timestamp,updated:t.timestamp},flushedTurnCount:0,head:null,task:null}),{}}case"session:fork":{const{sourceSessionId:s,newSessionId:r,label:n,role:o,topics:i}=t.payload;if(!e.index.sessions[s])throw new Error(`session:fork — source session "${s}" not found`);await this.contentStore.copyTranscript(s,r);const a=e.index.sessions[s],c={id:r,label:n,role:o??a.role,topics:i??[...a.topics],preferences:[...a.preferences],metadata:{created:t.timestamp,updated:t.timestamp},flushedTurnCount:a.flushedTurnCount,head:a.head?{...a.head}:null,task:a.task};return await this.contentStore.saveSession(c),{}}case"session:delete":return await this.contentStore.deleteSession(t.payload.sessionId),{};case"session:role:switch":case"session:topics:add":case"session:preferences:override":{const e=t.payload.sessionId,s=await this.contentStore.db.collection("session"),r=await s.find({field:"id",operator:"eq",value:e});if(!r)return{};if("session:role:switch"===t.type)await this.contentStore.updateSessionMeta(e,{role:t.payload.role});else if("session:topics:add"===t.type){const s=r.state();await this.contentStore.updateSessionMeta(e,{topics:[...new Set([...s.topics,...t.payload.topics])]})}else await this.contentStore.updateSessionMeta(e,{preferences:t.payload.preferences});return{}}case"turn:add":return await this.contentStore.appendTurn(t.payload.sessionId,t.payload.turn),{};case"turn:save":return await this.contentStore.saveTurn(t.payload.sessionId,t.payload.turn),{};case"turn:edit":{const{sessionId:e,turnId:s,newBlocks:r,newVersion:n,roleSnapshot:o}=t.payload;return await this.contentStore.editTurn(e,s,r,n,o),{}}case"turn:branch":return await this.contentStore.branchTurn(t.payload.sessionId,t.payload.turn),{};case"turn:delete":{const{sessionId:e,turnId:s,version:r,newHead:n}=t.payload;return await this.contentStore.deleteTurnSubtree(e,s,r,n),{}}case"tool:call":{if(!this.toolRegistry)throw new Error("tool:call — no toolRegistry configured");const e=await this.toolRegistry.execute(t.payload);if(!e.ok)throw Object.assign(new Error(e.error.code),{wsError:e.error});return{}}default:return{}}}};function $(e){return Math.ceil(e.length/4)}function K(e,t){return Math.ceil(e/1024*t)}function z(e){if("text"===e.kind)return e.value;if("json"===e.kind){const t=[],s=e=>{"string"==typeof e?t.push(e):e&&"object"==typeof e&&Object.values(e).forEach(s)};return s(e.value),t.join(" ")}return""}function V(e,t){return{id:crypto.randomUUID(),version:0,owner:e,blocks:t,timestamp:(new Date).toISOString(),parent:null}}var L=class{rank(e){const{entries:t,recentMessages:s,config:r}=e,n=r.recentMessageWindow??3,o=r.minScore??0,i=r.freshnessHalfLifeDays??30;if(0===s.length)return[...t].sort(((e,t)=>this.freshnessWeight(t.timestamp,i)-this.freshnessWeight(e.timestamp,i)));const a=this.tokenize(s.slice(-n).join(" "));return t.map((e=>{const t=z(e.content);return{entry:e,score:.7*this.jaccardSimilarity(a,this.tokenize(t))+.3*this.freshnessWeight(e.timestamp,i)}})).filter((e=>e.score>o)).sort(((e,t)=>t.score-e.score)).map((e=>e.entry))}tokenize(e){return new Set(e.toLowerCase().replace(/[^\w\s]/g," ").split(/\s+/).filter((e=>e.length>2)))}jaccardSimilarity(e,t){if(0===e.size&&0===t.size)return 0;let s=0;for(const r of e)t.has(r)&&s++;const r=e.size+t.size-s;return 0===r?0:s/r}freshnessWeight(e,t){const s=(Date.now()-new Date(e).getTime())/864e5;return Math.pow(.5,s/t)}},H=class{plan(e){const{systemInstructions:t,persona:s,preferences:r,context:n,task:o,transcript:i,budget:a}=e;if(!a)return{preferences:r,context:n,task:o,transcript:i,truncated:{preferences:0,interactions:0,context:0},breakdown:{system:0,persona:0,preferences:0,transcript:0,context:0,tasks:0},totalUsed:0,lastRoleBeforeTruncation:null};const c=a.estimator??$,d=a.blobTokensPerKB??.25;let l=a.total;const u={system:0,persona:0,preferences:0,transcript:0,context:0,tasks:0},p=c(t??""),h=c(s);l-=p+h,u.system+=p,u.persona+=h;const f=[];let m=0;for(const e of r){const t=c(e.content);l>=t?(l-=t,u.preferences+=t,f.push(e)):m++}const y=[];let b=0,w=null;for(let e=i.length-1;e>=0;e--){const t=i[e],s=this.estimateTurnTokens(t,c,d);l>=s?(l-=s,u.transcript+=s,y.unshift(t)):(b++,"user"!==t.owner||w||(w=t.role??null))}const g=[];let v=0;for(const e of n){let t=c(z(e.content));"blob"===e.content.kind&&(t+=K(e.content.sizeBytes,d)),l>=t?(l-=t,u.context+=t,g.push(e)):v++}return{preferences:f,context:g,task:o,transcript:y,truncated:{preferences:m,interactions:b,context:v},breakdown:u,totalUsed:a.total-Math.max(0,l),lastRoleBeforeTruncation:w}}estimateTurnTokens(e,t,s){return e.blocks.reduce(((e,r)=>{switch(r.type){case"text":return e+t(r.text);case"tool:use":return e+t(JSON.stringify(r.input));case"tool:result":return e+t("string"==typeof r.content?r.content:JSON.stringify(r.content));case"thinking":return e+t(r.thinking);case"image":case"document":{const t=r.ref;return t?e+K(t.sizeBytes,s):e}default:return e}}),0)}},W=class{assemble(t){const{session:s,plan:r,resolvedBlobs:n,summaryBlockText:o,warnings:i,conflicts:a,budgetTotal:c}=t,d=[],l=[];for(const e of r.context)if("text"===e.content.kind||"json"===e.content.kind)d.push(e);else if("blob"===e.content.kind){const t=n.get(e.content.sha256);t&&l.push(this.buildReferentialBlock(e.content,t))}const u=[];if(l.length>0&&u.push(V("user",l)),o||r.truncated.interactions>0){const t=[];o&&t.push({type:"summary",text:o,id:"summary"}),r.truncated.interactions>0&&t.push({id:"notice",type:"text",text:`[${r.truncated.interactions} earlier turn(s) omitted due to token budget]`}),u.push(V("user",t)),u.push(V("assistant",[{id:e(),type:"text",text:"Understood."}]))}let p=r.lastRoleBeforeTruncation,h=null!==r.lastRoleBeforeTruncation;for(const e of r.transcript){const t=this.resolveTurnBlocks(e,n);"user"===e.owner&&e.role&&h&&e.role!==p&&t.unshift({type:"role:transition",previousRole:p,newRole:e.role}),"user"===e.owner&&(p=e.role??null,h=!0),u.push({...e,blocks:t})}return{system:{instructions:s.instructions,persona:s.role.persona,preferences:r.preferences,context:d,task:r.task},context:r.context,transcript:{turns:u},budget:{total:c,used:r.totalUsed,breakdown:r.breakdown},truncated:r.truncated,warnings:i,conflicts:a}}buildReferentialBlock(e,t){return e.mediaType.startsWith("image/")?{type:"image",blob:t}:{type:"document",blob:t,title:e.filename}}resolveTurnBlocks(e,t){return e.blocks.map((e=>{if("image"===e.type||"document"===e.type){const s=e.ref;if(s){const r=t.get(s.sha256);if(r)return{...e,blob:r}}}return e}))}},G=class{retriever;planner;assembler;summarizer;blobResolver;constructor(e){this.blobResolver=e.blobResolver,this.retriever=e.retriever??new L,this.planner=e.planner??new H,this.assembler=e.assembler??new W,this.summarizer=e.summarizer}async build(e,t={}){const s=[],{resolved:r,conflicts:n}=this.resolvePreferenceConflicts(e.preferences);n.length>0&&s.push(`${n.length} preference conflict(s) resolved.`);const o=this.extractRecentUserQueries(e.transcript,t.relevanceConfig),i=this.retriever.rank({entries:e.context,recentMessages:o,config:t.relevanceConfig??{}});let a=e.transcript,c=null;if(this.summarizer&&a.length>0){const e=t.tokenBudget?Math.floor(.25*t.tokenBudget.total):2e3,s=await this.summarizer.summarize(a,e);c=s.summary,a=s.remaining}const d=this.planner.plan({systemInstructions:e.instructions,persona:e.role.persona,preferences:r,context:i,task:e.task,transcript:a,budget:t.tokenBudget}),l=this.collectUsedBlobRefs(d.context,d.transcript),u=this.deduplicateBlobRefs(l),{resolved:p,errors:h}=await this.blobResolver(u,t.providerId??null);for(const e of h)s.push(`Failed to resolve blob ${e.ref.sha256.slice(0,8)}: ${e.error.code}`);const f=u.filter((e=>!p.has(e.sha256)));return f.length>0&&s.push(`${f.length} blob(s) unresolved and omitted: `+f.map((e=>e.sha256.slice(0,8))).join(", ")),d.truncated.preferences>0&&s.push(`${d.truncated.preferences} preference(s) dropped.`),d.truncated.interactions>0&&s.push(`${d.truncated.interactions} turn(s) trimmed.`),d.truncated.context>0&&s.push(`${d.truncated.context} context entry/entries dropped.`),this.assembler.assemble({session:e,plan:d,resolvedBlobs:p,summaryBlockText:c,warnings:s,conflicts:n,budgetTotal:t.tokenBudget?.total??0})}collectUsedBlobRefs(e,t){const s=[];for(const t of e)"blob"===t.content.kind&&s.push(t.content);for(const e of t)for(const t of e.blocks)if("image"===t.type||"document"===t.type){const e=t.ref;e&&s.push(e)}return s}deduplicateBlobRefs(e){const t=new Set,s=[];for(const r of e)t.has(r.sha256)||(t.add(r.sha256),s.push(r));return s}extractRecentUserQueries(e,t){const s=t?.recentMessageWindow??3;return e.filter((e=>"user"===e.owner)).slice(-s).flatMap((e=>e.blocks.filter((e=>"text"===e.type)).map((e=>e.text))))}resolvePreferenceConflicts(e){const t=[],s=new Map;for(const r of e)if(0!==r.topics.length)for(const e of r.topics){const n=s.get(e);if(!n){s.set(e,r);continue}const o=new Date(n.timestamp).getTime(),i=new Date(r.timestamp).getTime();i>o?(t.push({topic:e,kept:r.id,dropped:n.id,reason:"superseded_by_newer"}),s.set(e,r)):o>i&&t.push({topic:e,kept:n.id,dropped:r.id,reason:"superseded_by_newer"})}const r=new Set(t.map((e=>e.dropped)));return{resolved:e.filter((e=>!r.has(e.id))),conflicts:Array.from(new Set(t))}}},X=class{constructor(t,s){this._owner=t,this._turn=s?structuredClone(s):{id:e(),version:0,owner:this._owner,blocks:[],timestamp:(new Date).toISOString(),role:void 0,parent:null}}_turn;addText(t){const s={id:e(),type:"text",text:t};return this._turn.blocks.push(s),this}addImage(t,s){const r={id:e(),type:"image",ref:t,altText:s};return this._turn.blocks.push(r),this}addDocument(t,s){const r={id:e(),type:"document",ref:t,title:s};return this._turn.blocks.push(r),this}addToolUse(t,s){const r={id:e(),type:"tool:use",name:t,input:s};return this._turn.blocks.push(r),this}addToolResult(t,s,r){const n={id:e(),type:"tool:result",useId:t,content:s,isError:r};return this._turn.blocks.push(n),this}addSummary(t){const s={id:e(),type:"summary",text:t};return this._turn.blocks.push(s),this}addRoleTransition(t,s){const r={id:e(),type:"role:transition",previousRole:t,newRole:s};return this._turn.blocks.push(r),this}addThinking(t){const s={id:e(),type:"thinking",thinking:t};return this._turn.blocks.push(s),this}addTaskProposal(t,s,r="create",n){const o=s.map((t=>({id:t.id??e(),text:t.text,status:t.status??"todo"}))),i={id:e(),type:"task:proposal",title:t,steps:o,action:r,taskId:n};return this._turn.blocks.push(i),this}addBlock(e){return this._turn.blocks.push(e),this}deleteBlock(e){return this._turn.blocks=this._turn.blocks.filter((t=>t.id!==e)),this}editTextBlock(e,t){const s=this._turn.blocks.findIndex((t=>t.id===e));if(-1===s)throw new Error(`Block with ID ${e} not found.`);const r=this._turn.blocks[s];if("text"!==r.type)throw new Error(`Block with ID ${e} is not a TextBlock.`);return this._turn.blocks[s]={...r,text:t},this}withId(e){return this._turn.id=e,this}withVersion(e){return this._turn.version=e,this}withTimestamp(e){return this._turn.timestamp=e,this}withParent(e){return this._turn.parent=e,this}withRoleSnapshot(e){return this._turn.role=e,this}build(){return structuredClone(this._turn)}},Y=class{constructor(e,t,s){this.sessionId=e,this.tree=t,this.manager=s}async turns(){return this.tree.buildActiveChain(this.sessionId)}async siblings(e){return this.tree.getTurnSiblings(e,this.sessionId)}async branchInfo(e){return this.tree.branchInfo(e,this.sessionId)}id(){return this.sessionId}startTurn(e){return new X(e)}async addTurn(e,t){if(!e.index.sessions[this.sessionId])return T({code:"NOT_FOUND",resource:"session",id:this.sessionId});const s={...t,version:t.version??0};return this.manager.dispatch(e,{type:"turn:add",payload:{sessionId:this.sessionId,turn:s},timestamp:s.timestamp})}async editTurn(e,t,s,r){if(!e.index.sessions[this.sessionId])return T({code:"NOT_FOUND",resource:"session",id:this.sessionId});const n=await this.tree.loadTurnVersions(this.sessionId,t);if(0===n.length)return T({code:"NOT_FOUND",resource:"turn",id:t});const o=Math.max(...n.map((e=>e.version))),i=n.find((e=>e.version===o)),a=o+1,c=(new Date).toISOString();return this.manager.dispatch(e,{type:"turn:edit",payload:{sessionId:this.sessionId,turnId:t,newBlocks:s,roleSnapshot:r??i.role,newVersion:a},timestamp:c})}async branch(e,t){return e.index.sessions[this.sessionId]?t.parent?this.manager.dispatch(e,{type:"turn:branch",payload:{sessionId:this.sessionId,turn:t},timestamp:t.timestamp}):T({code:"INVALID_COMMAND",reason:"branchFrom requires turn.parent to be set"}):T({code:"NOT_FOUND",resource:"session",id:this.sessionId})}async deleteTurn(e,t,s,r){if(!e.index.sessions[this.sessionId])return T({code:"NOT_FOUND",resource:"session",id:this.sessionId});const n=await this.tree.loadTurnVersions(this.sessionId,t);if(0===n.length)return T({code:"NOT_FOUND",resource:"turn",id:t});return n.some((e=>e.version===s))?this.manager.dispatch(e,{type:"turn:delete",payload:{sessionId:this.sessionId,turnId:t,version:s,newHead:r},timestamp:(new Date).toISOString()}):T({code:"NOT_FOUND",resource:"turn version",id:`${t}:${s}`})}async switchVersionLeft(e,t){return this.switchVersion(e,t,-1)}async switchVersionRight(e,t){return this.switchVersion(e,t,1)}async switchVersion(e,t,s){if(!e.index.sessions[this.sessionId])return T({code:"NOT_FOUND",resource:"session",id:this.sessionId});const r=await this.tree.buildNodeGraph(this.sessionId),n=r[t];if(!n)return T({code:"NOT_FOUND",resource:"turn",id:t});const o=Object.keys(n.versions).map(Number).sort(((e,t)=>e-t)),i=o.indexOf(n.activeVersion);if(-1===i)return T({code:"INVALID_COMMAND",reason:"Active version not found in version list"});const a=i+s;if(a<0||a>=o.length)return T({code:"INVALID_COMMAND",reason:`No ${s<0?"previous":"next"} version available for turn ${t}`});const c=function(e,t,s){let r=t,n=s;for(;;){const t=e[r];if(!t)break;const s=t.children[n];if(!s||0===s.length)break;const o=s[0],i=e[o];if(!i)break;r=o,n=i.activeVersion}return{id:r,version:n}}(r,t,o[a]);await this.tree.setHead(this.sessionId,c);const d=(new Date).toISOString();return x({index:{sessions:{[this.sessionId]:{head:c,metadata:{updated:d}}}}})}async resolve(e){if(!e.index.sessions[this.sessionId])return T({code:"NOT_FOUND",resource:"session",id:this.sessionId});const t=(await this.turns()).map((e=>e.versions[e.activeVersion]));return this.manager.resolveSession(e,this.sessionId,t)}};var J=class{workspaceManager;contentStore;constructor(e,t){this.workspaceManager=e,this.contentStore=t}async open(e,t){if(!e.index.sessions[t])return T({code:"NOT_FOUND",resource:"session",id:t});try{return x({session:new Y(t,this.contentStore.getTurnTree(),this.workspaceManager),patch:{}})}catch(e){return T({code:"BACKEND_ERROR",reason:e instanceof Error?e.message:String(e)})}}get workspace(){return this.workspaceManager}async close(e){}},Q=class{bytes=new Map;records=new Map;async storeBytes(e,t){this.bytes.has(e)||this.bytes.set(e,t)}async loadBytes(e){return this.bytes.get(e)??null}async hasBytes(e){return this.bytes.has(e)}async deleteBytes(e){this.bytes.delete(e)}async saveRecord(e){this.records.set(e.sha256,{...e})}async loadRecord(e){return this.records.get(e)??null}async deleteRecord(e){this.records.delete(e)}async listRecords(){return Array.from(this.records.values()).map((e=>({...e})))}async exportAllBytes(){return Array.from(this.bytes.entries()).map((([e,t])=>[e,new Uint8Array(t)]))}async registerBlob(e,t){this.bytes.has(e.sha256)||this.bytes.set(e.sha256,t),this.records.set(e.sha256,{...e})}},Z="blob_bytes",ee="blob_records";function te(e){return new Promise(((t,s)=>{e.onsuccess=()=>t(e.result),e.onerror=()=>s(e.error)}))}function se(e){return new Promise(((t,s)=>{e.oncomplete=()=>t(),e.onerror=()=>s(e.error),e.onabort=()=>s(new Error("Transaction aborted"))}))}var re=class{dbName;db=null;constructor(e={}){this.dbName=e.dbName??"aiworkspace-blobs"}async open(){this.db||(this.db=await new Promise(((e,t)=>{const s=indexedDB.open(this.dbName,1);s.onupgradeneeded=e=>{const t=e.target.result;this.createSchema(t)},s.onsuccess=()=>e(s.result),s.onerror=()=>t(s.error),s.onblocked=()=>t(new Error(`[IndexedDBBlobStorage] Database "${this.dbName}" blocked.`))})),this.db.onversionchange=()=>{this.db?.close(),this.db=null})}createSchema(e){e.objectStoreNames.contains(Z)||e.createObjectStore(Z,{keyPath:"sha256"}),e.objectStoreNames.contains(ee)||e.createObjectStore(ee,{keyPath:"sha256"})}close(){this.db?.close(),this.db=null}async deleteDatabase(){this.close(),await new Promise(((e,t)=>{const s=indexedDB.deleteDatabase(this.dbName);s.onsuccess=()=>e(),s.onerror=()=>t(s.error)}))}getDB(){if(!this.db)throw new Error("[IndexedDBBlobStorage] Database not open. Call open() first.");return this.db}readTx(...e){return this.getDB().transaction(e,"readonly")}writeTx(...e){return this.getDB().transaction(e,"readwrite")}async storeBytes(e,t){const s=this.readTx(Z);if(await te(s.objectStore(Z).get(e)))return;const r=this.writeTx(Z);r.objectStore(Z).put({sha256:e,data:t}),await se(r)}async loadBytes(e){const t=this.readTx(Z),s=await te(t.objectStore(Z).get(e));return s?.data??null}async hasBytes(e){const t=this.readTx(Z);return await te(t.objectStore(Z).count(e))>0}async deleteBytes(e){const t=this.writeTx(Z);t.objectStore(Z).delete(e),await se(t)}async saveRecord(e){const t=this.writeTx(ee);t.objectStore(ee).put(e),await se(t)}async loadRecord(e){const t=this.readTx(ee);return await te(t.objectStore(ee).get(e))??null}async deleteRecord(e){const t=this.writeTx(ee);t.objectStore(ee).delete(e),await se(t)}async listRecords(){return te(this.readTx(ee).objectStore(ee).getAll())}async exportAllBytes(){const e=this.readTx(Z);return(await te(e.objectStore(Z).getAll())).map((({sha256:e,data:t})=>[e,t]))}async registerBlob(e,t){await new Promise(((s,r)=>{const n=this.getDB().transaction([Z,ee],"readwrite"),o=n.objectStore(Z),i=n.objectStore(ee),a=o.count(e.sha256);a.onsuccess=()=>{0===a.result&&o.put({sha256:e.sha256,data:t}),i.put(e)},a.onerror=()=>r(a.error),n.oncomplete=()=>s(),n.onerror=()=>r(n.error),n.onabort=()=>r(new Error("registerBlob transaction aborted"))}))}};export{B as BlobStore,b as COLLECTIONS,M as ContentStore,re as IndexedDBBlobStorage,Q as MemoryBlobStorage,G as PromptBuilder,Y as Session,J as SessionManager,C as TurnTree,P as WorkspaceManager,E as computeSHA256,S as createProjectWorkspace,_ as createSimpleWorkspace,y as createWorkspaceDatabase,v as del,T as err,N as extractBlobRecord,I as extractBlobRef,k as merge,x as ok,O as omitNullUndefined,F as workspaceReducer};
|