@rizom/brain 0.2.0-alpha.388 → 0.2.0-alpha.389
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/brain.js +37 -37
- package/dist/chunks/{app-tfas6jvz.js → app-wrx5n8k8.js} +2 -2
- package/dist/chunks/{blog-post-adapter-bv0jk610.js → blog-post-adapter-kgjk1gef.js} +2 -2
- package/dist/chunks/{index-k83efmds.js → index-0582hm73.js} +2 -2
- package/dist/chunks/{index-8ptqsk8d.js → index-5kpm747w.js} +3 -3
- package/dist/chunks/{index-8ptqsk8d.js.map → index-5kpm747w.js.map} +3 -3
- package/dist/chunks/{index-9czdjwfv.js → index-car16vq2.js} +3 -3
- package/dist/chunks/{index-5m218smg.js → index-dx5zwaer.js} +2 -2
- package/dist/chunks/{index-a63cw6k9.js → index-j4t6n9e7.js} +3 -3
- package/dist/chunks/{index-a63cw6k9.js.map → index-j4t6n9e7.js.map} +1 -1
- package/dist/chunks/{index-vk4p783n.js → index-t0f3eh8m.js} +2 -2
- package/dist/chunks/{linkedin-template-ebwydkhw.js → linkedin-template-031pret9.js} +2 -2
- package/dist/chunks/{rss-datasource-f8xc488t.js → rss-datasource-9yhmrst5.js} +2 -2
- package/dist/entities.js +1 -1
- package/dist/index.js +1 -1
- package/dist/interfaces.js +1 -1
- package/dist/model.js +38 -38
- package/dist/model.js.map +1 -1
- package/dist/plugins.js +1 -1
- package/dist/services.js +1 -1
- package/package.json +1 -1
- /package/dist/chunks/{app-tfas6jvz.js.map → app-wrx5n8k8.js.map} +0 -0
- /package/dist/chunks/{blog-post-adapter-bv0jk610.js.map → blog-post-adapter-kgjk1gef.js.map} +0 -0
- /package/dist/chunks/{index-k83efmds.js.map → index-0582hm73.js.map} +0 -0
- /package/dist/chunks/{index-9czdjwfv.js.map → index-car16vq2.js.map} +0 -0
- /package/dist/chunks/{index-5m218smg.js.map → index-dx5zwaer.js.map} +0 -0
- /package/dist/chunks/{index-vk4p783n.js.map → index-t0f3eh8m.js.map} +0 -0
- /package/dist/chunks/{linkedin-template-ebwydkhw.js.map → linkedin-template-031pret9.js.map} +0 -0
- /package/dist/chunks/{rss-datasource-f8xc488t.js.map → rss-datasource-9yhmrst5.js.map} +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{ka as a,la as b,ma as c,na as d}from"./index-
|
|
2
|
+
import{ka as a,la as b,ma as c,na as d}from"./index-car16vq2.js";import"./index-sjra4m07.js";import"./index-zncqaqm4.js";import"./index-5kpm747w.js";import"./index-r6mnb8x4.js";import"./index-ye6tb12k.js";import"./index-yq5q69m6.js";import"./index-jtpxbmgp.js";import"./index-09ebfs1j.js";import"./index-4ccsfcjs.js";export{d as App,a as STARTUP_CHECK_API_KEY,c as buildShellConfig,b as toAppConfig};
|
|
3
3
|
|
|
4
4
|
//# debugId=D3620E96E99885C364756E2164756E21
|
|
5
|
-
//# sourceMappingURL=app-
|
|
5
|
+
//# sourceMappingURL=app-wrx5n8k8.js.map
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{B as a,C as b}from"./index-
|
|
2
|
+
import{B as a,C as b}from"./index-dx5zwaer.js";import"./index-0582hm73.js";import"./index-5kpm747w.js";import"./index-r6mnb8x4.js";import"./index-ye6tb12k.js";import"./index-yq5q69m6.js";import"./index-jtpxbmgp.js";import"./index-09ebfs1j.js";import"./index-4ccsfcjs.js";export{a as BlogPostAdapter,b as blogPostAdapter};
|
|
3
3
|
|
|
4
4
|
//# debugId=4B730B9AAEB1463F64756E2164756E21
|
|
5
|
-
//# sourceMappingURL=blog-post-adapter-
|
|
5
|
+
//# sourceMappingURL=blog-post-adapter-kgjk1gef.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{Rc as o}from"./index-
|
|
2
|
+
import{Rc as o}from"./index-5kpm747w.js";import{Lj as t}from"./index-09ebfs1j.js";var a=t.enum(["generating","draft","queued","published","failed"]),e=t.object({title:t.string(),slug:t.string().optional(),status:a,publishedAt:t.string().datetime().optional(),excerpt:t.string(),author:t.string(),coverImageId:t.string().optional(),ogImageId:t.string().optional(),seriesName:t.string().optional(),seriesIndex:t.number().optional(),ogImage:t.string().url().optional(),ogDescription:t.string().optional(),twitterCard:t.enum(["summary","summary_large_image"]).optional(),canonicalUrl:t.string().url().optional(),atprotoUri:t.string().optional()}),i=e.pick({title:!0,status:!0,publishedAt:!0,seriesName:!0,seriesIndex:!0}).extend({slug:t.string(),error:t.string().optional()}),n=o.extend({entityType:t.literal("post"),metadata:i}),r=n.extend({frontmatter:e,body:t.string(),coverImageUrl:t.string().optional()}),s=r.extend({url:t.string().optional(),typeLabel:t.string().optional(),listUrl:t.string().optional(),listLabel:t.string().optional(),seriesUrl:t.string().optional(),coverImageUrl:t.string().optional(),ogImageUrl:t.string().optional(),coverImageWidth:t.number().optional(),coverImageHeight:t.number().optional(),coverImageSrcset:t.string().optional(),coverImageSizes:t.string().optional()}),d=r.extend({url:t.string(),typeLabel:t.string(),listUrl:t.string(),listLabel:t.string(),seriesUrl:t.string().optional(),coverImageUrl:t.string().optional(),ogImageUrl:t.string().optional(),coverImageWidth:t.number().optional(),coverImageHeight:t.number().optional(),coverImageSrcset:t.string().optional(),coverImageSizes:t.string().optional()});
|
|
3
3
|
export{a as E,e as F,n as G,r as H};
|
|
4
4
|
|
|
5
5
|
//# debugId=E85BDB3C876C099464756E2164756E21
|
|
6
|
-
//# sourceMappingURL=index-
|
|
6
|
+
//# sourceMappingURL=index-0582hm73.js.map
|
|
@@ -124,7 +124,7 @@ Instructions:
|
|
|
124
124
|
2. Search through available entities for relevant information
|
|
125
125
|
3. Provide accurate, contextual responses based on the data
|
|
126
126
|
4. If information is missing, clearly state what additional data might be helpful
|
|
127
|
-
5. Structure your response clearly and concisely`,dataSourceId:"shell:ai-content",requiredPermission:"public",useKnowledgeContext:!0,schema:uv,formatter:new Pg};var yhe=a.object({type:a.string().describe("Type of source (e.g., note, article)"),title:a.string().describe("Title or identifier of the source"),relevance:a.number().min(0).max(1).describe("Relevance score")}),JV=a.object({answer:a.string().describe("The answer to the user's query"),sources:a.array(yhe).optional().describe("Sources used to generate the answer"),confidence:a.enum(["high","medium","low"]).optional().describe("Confidence level of the answer"),suggestions:a.array(a.string()).optional().describe("Related topics or follow-up questions")});function ma(e,t){return e.parse(t)}class fa{callback;heartbeatInterval;constructor(e){this.callback=e}static from(e){if(!e)return;return new fa(e)}static noop(){return new fa(async()=>{})}createSub(e){let{scale:t}=e??{};if(t){let{start:n,end:r}=t,o=r-n;return new fa(async(i)=>{let s=n+i.progress/(i.total??100)*o;await this.callback({...i,progress:s,total:100})})}return new fa(this.callback)}async report(e){await this.callback(e)}startHeartbeat(e,t=5000){this.stopHeartbeat(),this.heartbeatInterval=setInterval(()=>{this.report({message:e,progress:0}).catch(()=>{})},t)}stopHeartbeat(){if(this.heartbeatInterval)clearInterval(this.heartbeatInterval),this.heartbeatInterval=void 0}toCallback(){return this.callback}}var xhe=a.object({enabled:a.boolean().describe("Whether the plugin is enabled"),debug:a.boolean().describe("Enable debug logging for this plugin")});function She(e){return e.map((t)=>`${t.path||"<root>"}: ${t.message}`).join("; ")}class Ag extends Error{pluginId;issues;constructor(e,t){super(`Invalid plugin config for ${e} at ${She(t)}; correct the listed fields in brain.yaml or the package's use() configuration`);this.name="PluginConfigValidationError",this.pluginId=e,this.issues=t}}var vhe=a.object({toolName:a.string(),args:a.unknown(),progressToken:a.union([a.string(),a.number()]).optional(),hasProgress:a.boolean().optional(),interfaceType:a.string(),actor:Yi,displayName:a.string().optional(),conversationId:a.string().optional(),channelId:a.string().optional(),channelName:a.string().optional(),runId:a.string().optional(),toolCallId:a.string().optional(),userPermissionLevel:a.enum(["admin","trusted","public"]).optional(),isAnchor:a.boolean().optional(),signal:a.custom((e)=>e instanceof AbortSignal).optional()}),The=a.object({resourceUri:a.string()});class iu{id;version;description;packageName;config;context;get logger(){return this.context?.logger??Fo.createFresh({context:this.id})}constructor(e,t,n,r){this.id=e,this.packageName=t.name,this.version=t.version,this.description=t.description??`${t.name} plugin`;let o=r.safeParse(n);if(!o.success)throw new Ag(e,o.error.issues.map((i)=>({path:i.path.map(String).join("."),code:i.code,message:i.message})));this.config=o.data}setupMessageHandlers(e){e.messaging.subscribe(Og.toolExecute(this.id),async(t)=>{try{let n=vhe.safeParse(t.payload);if(!n.success)return{success:!1,error:"Invalid tool execution request format"};let{toolName:r,args:o,progressToken:i,hasProgress:s,interfaceType:c,actor:l,displayName:u,conversationId:d,channelId:m,channelName:g,runId:h,toolCallId:x,userPermissionLevel:v,isAnchor:E,signal:H}=n.data,Q=(await this.getTools()).find((de)=>de.name===r);if(!Q)return{success:!1,error:`Tool not found: ${r}`};let ue={interfaceType:c,actor:l,...u&&{displayName:u},...d&&{conversationId:d},...m&&{channelId:m},...g&&{channelName:g},...h&&{runId:h},...x&&{toolCallId:x},...v&&{userPermissionLevel:v},...E!==void 0&&{isAnchor:E},...H&&{signal:H},...s&&i!==void 0&&{progressToken:i,sendProgress:async(de)=>{await e.messaging.send({type:Og.progress(this.id),payload:{progressToken:i,notification:de}})}}};return{success:!0,data:await Q.handler(o,ue)}}catch(n){return this.logger.error("Tool execution error",n),{success:!1,error:qe(n)}}}),e.messaging.subscribe(Og.resourceGet(this.id),async(t)=>{try{let n=The.safeParse(t.payload);if(!n.success)return{success:!1,error:"Invalid resource get request format"};let{resourceUri:r}=n.data,i=(await this.getResources()).find((c)=>c.uri===r);if(!i)return{success:!1,error:`Resource not found: ${r}`};return{success:!0,data:await i.handler()}}catch(n){return this.logger.error("Resource fetch error",n),{success:!1,error:qe(n)}}})}async onRegister(e){}async onRegistrationComplete(e){}async finalizeRegistration(){await this.onRegistrationComplete(this.getContext())}async onReady(e){}async ready(){await this.onReady(this.getContext())}async getCapabilities(){let e=await this.getInstructions();return{tools:await this.getTools(),resources:await this.getResources(),...e&&{instructions:e}}}async getTools(){return[]}async getResources(){return[]}async getInstructions(){return}async shutdown(){await this.onShutdown()}async onShutdown(){}getContext(){if(!this.context)throw Error(`Plugin ${this.id}: Plugin not registered yet`);return this.context}determineUserPermissionLevel(e){return"public"}createProgressBridge(e){if(!e)return;let t=this.context;if(!t)return;let n=this.id;return fa.from(async(r)=>{await t.messaging.send({type:Og.progress(n),payload:{progressToken:e,notification:{progress:r.progress,total:r.total,message:r.message}}})})}}var ZV=a.object({id:a.string(),template:a.string(),content:a.unknown().optional(),dataQuery:a.looseObject({entityType:a.string().optional(),template:a.string().optional(),query:a.looseObject({id:a.string().optional(),limit:a.number().optional(),offset:a.number().optional()}).optional()}).optional(),order:a.number().optional()}),UA=["primary","secondary"],VV=a.object({show:a.boolean().default(!1),label:a.string().optional(),slot:a.enum(UA).default("primary"),priority:a.number().min(0).max(100).default(50)}).optional(),WA=a.object({id:a.string(),path:a.string(),title:a.string().default(""),pageLabel:a.string().optional(),description:a.string().default(""),sections:a.array(ZV).default([]),layout:a.string().default("default"),fullscreen:a.boolean().optional(),pluginId:a.string().optional(),sourceEntityType:a.string().optional(),external:a.boolean().optional(),navigation:VV}),GV=a.object({routes:a.array(WA),pluginId:a.string()}),QV=a.object({paths:a.array(a.string()).optional(),pluginId:a.string().optional()}),KV=a.object({pluginId:a.string().optional()}),YV=a.object({path:a.string()}),pv=a.object({label:a.string(),href:a.string(),priority:a.number()});var Che="site:metadata:get",Ehe="site:metadata:updated",HA=a.object({heading:a.string().describe("Main CTA heading text"),buttonText:a.string().describe("Call-to-action button text"),buttonLink:a.string().describe("URL or anchor for the CTA button")}),XV=a.object({blurb:a.string().optional().describe("Short italic subtitle under the section title")}),dv=a.object({represents:a.enum(["brain","anchor"]).default("anchor").describe("Identity represented by the site"),title:a.string().describe("The site's title"),description:a.string().describe("The site's description"),url:a.string().optional().describe("Canonical site URL"),copyright:a.string().optional().describe("Copyright notice text"),logo:a.boolean().optional().describe("Whether to display logo instead of title text in header"),themeMode:a.enum(["light","dark"]).optional().describe("Default theme mode"),analyticsScript:a.string().optional().describe("Analytics script HTML"),cta:HA.optional().describe("Call-to-action configuration"),sections:a.record(a.string(),XV).optional().describe("Optional per-section blurbs, keyed by section id (e.g. 'essays', 'presentations', 'about'). Used by homepage templates that render editorial section headers.")});var whe=a.object({platform:a.enum(["github","instagram","linkedin","email","website"]).describe("Social media platform"),url:a.string().describe("Profile or contact URL"),label:a.string().optional().describe("Optional display label")}),Ihe=dv.extend({copyright:a.string(),navigation:a.object({primary:a.array(pv),secondary:a.array(pv)}),socialLinks:a.array(whe).optional().describe("Social media links from profile metadata")});function Dg(e,t){return t?e.nullable().default(null):e}function ZA(e){switch(e.type){case"string":return Dg(a.string(),e.optional);case"number":return Dg(a.number(),e.optional);case"enum":return Dg(a.enum(e.options),e.optional);case"object":{let t={};for(let[n,r]of Object.entries(e.fields))t[n]=ZA(r);return Dg(a.object(t),e.optional)}case"array":{let t=a.array(Rhe(e));if(e.minItems!==void 0)t=t.min(e.minItems);if(e.length!==void 0)t=t.length(e.length);return Dg(t,e.optional)}}}function Rhe(e){let{items:t}=e;switch(t.type){case"string":return a.string();case"number":return a.number();case"enum":return a.enum(t.options);case"object":{let n={};for(let[r,o]of Object.entries(t.fields))n[r]=ZA(o);return a.object(n)}}}function JA(e,t){switch(t.type){case"string":case"enum":return{key:e,label:t.label,type:"string"};case"number":return{key:e,label:t.label,type:"number"};case"object":return{key:e,label:t.label,type:"object",children:Object.entries(t.fields).map(([n,r])=>JA(n,r))};case"array":{let n={key:e,label:t.label,type:"array"};switch(t.items.type){case"string":case"enum":return n.itemType="string",n;case"number":return n.itemType="number",n;case"object":return n.itemType="object",n.itemMappings=Object.entries(t.items.fields).map(([r,o])=>JA(r,o)),n}}}}function eG(e,t){let n={};for(let[i,s]of Object.entries(t.fields))n[i]=ZA(s);let r=a.object(n),o=new ld(r,{title:t.title,mappings:Object.entries(t.fields).map(([i,s])=>JA(i,s))});return{name:e,description:t.description,schema:r,formatter:o,requiredPermission:t.requiredPermission??"public",layout:{component:t.layout,...t.fullscreen!==void 0?{fullscreen:t.fullscreen}:{}},...t.runtimeScripts?{runtimeScripts:t.runtimeScripts}:{}}}function khe(e){let t={};for(let[n,r]of Object.entries(e.sections))t[n]=eG(n,r);return t}var Phe=dv.omit({url:!0,analyticsScript:!0}),tG=Phe.extend({title:a.string().optional().describe("Optional site title override"),description:a.string().optional().describe("Optional site description override")});function nG(e){return tG.parse(Mg(e).frontmatter)}async function Ahe(e){let n=(await e.listEntities({entityType:"site-info",options:{limit:1}}))[0];if(!n)throw Error("Site info not found \u2014 create a site-info entity");return nG(n.content)}function VA(e,t={}){let n=rG(e),r=rG(t.sharedDomain??"rizom.ai").replace(/^\./,""),o=`.${r}`;if(n.endsWith(o)){let i=n.slice(0,-o.length);if(i.length>0&&!i.includes("."))return`${i}-preview.${r}`}return`preview.${n}`}function rG(e){return e.trim().replace(/^https?:\/\//i,"").replace(/\/$/,"").toLowerCase()}class ud{static instance=null;entityDisplay;constructor(){}static getInstance(){return ud.instance??=new ud,ud.instance}configure(e){this.entityDisplay=e}static resetInstance(){ud.instance=null}hasRoute(e){return this.entityDisplay?.[e]!==void 0}generateUrl(e,t){let n=this.entityDisplay?.[e];if(n)return`/${n.pluralName??n.label.toLowerCase()+"s"}/${t}`;return`/${PT(e)}/${t}`}}var iG=["primary","secondary"];var Ohe=a.custom((e)=>typeof e==="function","Expected a React component"),Dhe=a.strictObject({show:a.boolean().optional(),label:a.string().min(1).optional(),slot:a.enum(iG).optional(),priority:a.number().optional()}),Mhe=a.strictObject({id:a.string().min(1),template:a.string().min(1),content:a.unknown().optional(),dataQuery:a.looseObject({entityType:a.string().optional(),template:a.string().optional(),query:a.record(a.string(),a.unknown()).optional()}).optional(),order:a.number().optional()}),_he=a.strictObject({id:a.string().min(1),path:a.string().startsWith("/"),title:a.string().optional(),pageLabel:a.string().optional(),description:a.string().optional(),sections:a.array(Mhe).optional(),layout:a.string().min(1).optional(),fullscreen:a.boolean().optional(),pluginId:a.string().optional(),sourceEntityType:a.string().optional(),external:a.boolean().optional(),navigation:Dhe.optional()}),Nhe=a.strictObject({label:a.string().min(1),pluralName:a.string().min(1).optional(),layout:a.string().min(1).optional(),paginate:a.boolean().optional(),pageSize:a.number().int().positive().optional(),navigation:a.strictObject({show:a.boolean().optional(),slot:a.enum(iG).optional(),priority:a.number().optional()}).optional()}),Fhe=a.strictObject({schema:a.custom((e)=>e instanceof a.ZodType,"Expected a Zod schema"),component:a.custom((e)=>typeof e==="function","Expected a React component"),title:a.string().min(1),description:a.string(),requiredPermission:a.enum(["admin","trusted","public"]).optional(),fullscreen:a.boolean().optional()}),oG=a.strictObject({namespace:a.string().min(1),sections:a.record(a.string(),Fhe)}),zhe=a.record(a.string(),a.json()),jhe=a.record(a.string(),a.record(a.string(),zhe)),sG={layouts:a.record(a.string(),Ohe).refine((e)=>typeof e.default==="function",{message:'Site layouts must include a "default" component'}),routes:a.array(_he),content:jhe.optional(),sections:a.union([oG,a.array(oG)]).optional(),themeOverride:a.string().optional(),headScripts:a.array(a.string()).optional(),entityDisplay:a.record(a.string(),Nhe),staticAssets:a.record(a.string(),a.string()).optional()},HWe=a.strictObject(sG).partial();var aG=a.strictObject(sG).superRefine((e,t)=>{let n=new Set;for(let[i,s]of e.routes.entries()){if(n.has(s.id))t.addIssue({code:"custom",path:["routes",i,"id"],message:`Duplicate route id "${s.id}"`});n.add(s.id);let c=s.layout??"default";if(!e.layouts[c])t.addIssue({code:"custom",path:["routes",i,"layout"],message:`Unknown layout "${c}"`})}let r=Array.isArray(e.sections)?e.sections:e.sections?[e.sections]:[],o=new Map(r.map((i)=>[i.namespace,i]));if(o.size!==r.length)t.addIssue({code:"custom",path:["sections"],message:"Section group namespaces must be unique"});for(let[i,s]of Object.entries(e.content??{})){let c=o.get(i);if(!c){t.addIssue({code:"custom",path:["content",i],message:`Content namespace "${i}" has no section group`});continue}for(let[l,u]of Object.entries(s)){let d=c.sections[l];if(!d){t.addIssue({code:"custom",path:["content",i,l],message:`Content section "${i}.${l}" is not defined`});continue}let m=d.schema.safeParse(u);if(!m.success)t.addIssue({code:"custom",path:["content",i,l],message:`Content does not satisfy the "${i}.${l}" schema: ${a.prettifyError(m.error)}`})}}});var Bhe=a.string(),Lhe=a.custom((e)=>{if(!jo(e))return!1;let{plugin:t,...n}=e;if(t!==void 0&&typeof t!=="function")return!1;return aG.safeParse(n).success});var GA=a.enum(["file_operations","content_operations","data_processing","batch_processing"]),qhe=a.looseObject({pluginId:a.string().optional(),progressToken:a.union([a.string(),a.number()]).optional(),operationType:GA,operationTarget:a.string().optional(),interfaceType:a.string().optional(),conversationId:a.string().optional(),channelId:a.string().optional(),requestedByActor:Yi.optional(),requestedByUserId:a.string().optional(),requestedByInterface:a.string().optional(),silent:a.boolean().optional(),provenance:es.optional()}),su=a.looseObject({pluginId:a.string().optional(),progressToken:a.union([a.string(),a.number()]).optional(),operationType:GA,operationTarget:a.string().optional(),interfaceType:a.string().optional(),conversationId:a.string().optional(),channelId:a.string().optional(),requestedByActor:Yi.optional(),requestedByUserId:a.string().optional(),requestedByInterface:a.string().optional(),silent:a.boolean().optional(),provenance:es.optional(),rootJobId:a.string()}),d1e=a.enum(["none","skip","replace","coalesce"]);var $he=a.object({id:a.string(),type:a.string(),data:a.string(),status:a.enum(["pending","processing","completed","failed"]),source:a.string().nullable(),priority:a.number(),retryCount:a.number(),maxRetries:a.number(),lastError:a.string().nullable(),createdAt:a.number(),scheduledFor:a.number(),startedAt:a.number().nullable(),completedAt:a.number().nullable(),attemptId:a.string().nullable(),workerSlotId:a.string().nullable(),workerSessionId:a.string().nullable(),leaseExpiresAt:a.number().nullable(),attemptHeartbeatAt:a.number().nullable(),runtimeUpdatedAt:a.number().nullable(),metadata:su,progress:a.custom((e)=>typeof e==="object"&&e!==null&&("progress"in e)&&typeof e.progress==="number").nullable(),result:a.unknown().nullable().optional()}),ga=15000;var QA=a.enum(["pending","processing","completed","failed"]),cG=a.enum(["completed","failed"]),xe={PENDING:"pending",PROCESSING:"processing",COMPLETED:"completed",FAILED:"failed"},Uhe=a.object({id:a.string(),type:a.string(),status:QA,data:a.unknown(),result:a.unknown().optional(),lastError:a.string().optional().nullable(),attempts:a.number(),maxRetries:a.number(),priority:a.number(),createdAt:a.date(),updatedAt:a.date(),processedAt:a.date().optional().nullable(),completedAt:a.date().optional().nullable(),failedAt:a.date().optional().nullable()}),Whe=a.object({jobId:a.string(),type:a.string(),status:cG,result:a.unknown().optional(),error:a.string().optional()}),KA=a.object({success:a.literal(!1),error:a.string().optional()}),mv=a.object({id:a.string(),type:a.enum(["job","batch"]),status:QA,message:a.string().optional(),progress:a.object({current:a.number(),total:a.number(),percentage:a.number()}).optional(),aggregationKey:a.string().optional(),batchDetails:a.object({totalOperations:a.number(),completedOperations:a.number(),failedOperations:a.number(),currentOperation:a.string().optional(),errors:a.array(a.string()).optional()}).optional(),jobDetails:a.object({jobType:a.string(),priority:a.number(),retryCount:a.number()}).optional(),metadata:su});var P=wt("job_queue",{id:W("id").primaryKey().$defaultFn(()=>gt()),type:W("type").notNull(),data:W("data").notNull(),result:W("result",{mode:"json"}),progress:W("progress",{mode:"json"}).$type(),source:W("source"),metadata:W("metadata",{mode:"json"}).$type().notNull(),status:W("status",{enum:["pending","processing","completed","failed"]}).notNull().default("pending"),priority:Re("priority").notNull().default(0),retryCount:Re("retryCount").notNull().default(0),maxRetries:Re("maxRetries").notNull().default(3),lastError:W("lastError"),createdAt:Re("createdAt").notNull().$defaultFn(()=>Date.now()),scheduledFor:Re("scheduledFor").notNull().$defaultFn(()=>Date.now()),startedAt:Re("startedAt"),completedAt:Re("completedAt"),attemptId:W("attemptId"),workerSlotId:W("workerSlotId"),workerSessionId:W("workerSessionId"),leaseExpiresAt:Re("leaseExpiresAt"),attemptHeartbeatAt:Re("attemptHeartbeatAt"),runtimeUpdatedAt:Re("runtimeUpdatedAt")},(e)=>({queueReadyIdx:vt("idx_job_queue_ready").on(e.status,e.priority,e.scheduledFor),jobTypeIdx:vt("idx_job_queue_type").on(e.type,e.status),runtimeUpdatesIdx:vt("idx_job_queue_runtime_updates").on(e.runtimeUpdatedAt,e.id),jobSourceIdx:vt("idx_job_queue_source").on(e.source)})),tt=wt("job_worker_sessions",{slotId:W("slotId").primaryKey(),sessionId:W("sessionId").notNull().unique(),startedAt:Re("startedAt").notNull(),heartbeatAt:Re("heartbeatAt").notNull(),expiresAt:Re("expiresAt").notNull().default(0)},(e)=>({heartbeatIdx:vt("idx_job_worker_sessions_heartbeat").on(e.heartbeatAt),expiresIdx:vt("idx_job_worker_sessions_expires").on(e.expiresAt)}));function lG(e){return ui({url:e.url,schema:{jobQueue:P,jobWorkerSessions:tt},authToken:e.authToken,authTokenEnv:"JOB_QUEUE_DATABASE_AUTH_TOKEN"})}class YA{declarations=new Map;handlers=new Map;validators=new Map;logger;mode;finalizedRegistrations;constructor(e,t){this.logger=e.child("HandlerRegistry"),this.mode=t}registerHandler(e,t,n){if(this.finalizedRegistrations)throw Error("Job handler registrations are finalized");if(this.declarations.has(e))throw Error(`Job handler is already registered for type: ${e}`);if(this.declarations.set(e,{handler:t,pluginId:n}),this.validators.set(e,t),this.mode!=="validation-only")this.handlers.set(e,t);this.logger.debug("Registered job execution declaration",{type:e,pluginId:n,mode:this.mode})}unregisterHandler(e){this.declarations.delete(e),this.handlers.delete(e),this.validators.delete(e),this.logger.debug("Unregistered job handler",{type:e})}unregisterPluginHandlers(e){let t=[...this.declarations.entries()].filter(([,n])=>n.pluginId===e).map(([n])=>n);for(let n of t)this.declarations.delete(n),this.handlers.delete(n),this.validators.delete(n);if(t.length>0)this.logger.debug("Unregistered plugin handlers",{pluginId:e,count:t.length,types:t})}finalizeRegistrations(){return this.finalizedRegistrations??=Object.freeze([...this.declarations.entries()].sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>Object.freeze({type:e,pluginId:t.pluginId}))),this.finalizedRegistrations}getExecutionRegistrations(){if(!this.finalizedRegistrations)throw Error("Job handler registrations are not finalized");return this.finalizedRegistrations}getRegisteredTypes(){return[...this.handlers.keys()]}getHandler(e){return this.handlers.get(e)}getValidator(e){return this.validators.get(e)}}var Hhe=a.looseObject({deduplicationKey:a.string().optional()});class XA{findDuplicate(e,t,n){if(!t||t==="none")return null;let r=this.filterByDeduplicationKey(e,n).sort((i,s)=>s.createdAt-i.createdAt||s.id.localeCompare(i.id)),o=r.find((i)=>i.status===xe.PENDING)??null;if(t==="skip"||t==="replace")return o;return o??r[0]??null}filterByDeduplicationKey(e,t){if(!t)return e;return e.filter((n)=>{let r=Hhe.safeParse(n.metadata);return r.success&&r.data.deduplicationKey===t})}}var Jhe=2000,Zhe=5,Vhe=40,Ghe=new ZP;class eO{db;transactionClient;databaseUrl;logger;deduplicator=new XA;writeRetryBudgetMs;constructor(e,t,n,r,o){this.db=e,this.transactionClient=t,this.databaseUrl=n,this.logger=r.child("JobQueueRepository"),this.writeRetryBudgetMs=o?.writeRetryBudgetMs??Jhe}async insert(e){await this.db.insert(P).values(e)}async enqueueAtomic(e){return Ghe.run(this.databaseUrl,async()=>{let t=Date.now()+this.writeRetryBudgetMs,n=1;for(;;){let r=await this.acquireWriteTransaction(e,t),o={prepared:!1},i=!1;try{let s=await this.decideEnqueue(r,e,()=>{o.prepared=!0});return i=!0,await r.commit(),s}catch(s){let c=i&&this.isSerializationConflict(s)&&!r.closed,l=!0;if(!r.closed)try{await r.rollback()}catch(u){l=!1,this.logger.error("Failed to roll back atomic enqueue",{type:e.jobData.type,rollbackError:u})}if(o.prepared)e.onInsertRollback?.();if(!c||!l)throw s;await this.waitForConflictRetry("commit",e,t,n,s),n++}finally{r.close()}}})}async decideEnqueue(e,t,n){let{jobData:r,strategy:o,deduplicationKey:i,beforeInsert:s}=t,c=o??"none",l=async()=>{await s?.(),n()},u=async()=>{await l(),await this.insertJob(e,r)};if(c==="none")return await u(),{kind:"inserted",jobId:r.id};let d=await this.getActiveDeduplicationCandidates(e,r.type),m=this.deduplicator.findDuplicate(d,c,i);if(!m)return await u(),{kind:"inserted",jobId:r.id};if(c==="skip")return{kind:"skipped",jobId:m.id};if(c==="coalesce"){if((await e.execute({sql:"UPDATE `job_queue` SET `scheduledFor` = ? WHERE `id` = ? AND `status` = ?",args:[Date.now(),m.id,m.status]})).rowsAffected!==1)throw Error(`Atomic coalesce lost selected job ${m.id}`);return{kind:"coalesced",jobId:m.id}}await l();let g=Date.now();if((await e.execute({sql:"UPDATE `job_queue`\n SET `status` = ?,\n `lastError` = ?,\n `completedAt` = ?,\n `runtimeUpdatedAt` = max(?, coalesce((SELECT max(`runtimeUpdatedAt`) FROM `job_queue`), 0) + 1)\n WHERE `id` = ? AND `status` = ?",args:[xe.FAILED,"Replaced by newer job",g,g,m.id,xe.PENDING]})).rowsAffected!==1)throw Error(`Atomic replace lost selected job ${m.id}`);return await this.insertJob(e,r),{kind:"replaced",jobId:r.id,replacedJobId:m.id}}async getActiveDeduplicationCandidates(e,t){return(await e.execute({sql:"SELECT `id`, `status`, `createdAt`, `metadata`\n FROM `job_queue`\n WHERE `type` = ? AND `status` IN (?, ?)",args:[t,xe.PENDING,xe.PROCESSING]})).rows.map((r)=>this.parseDeduplicationCandidate(r))}parseDeduplicationCandidate(e){let{id:t,status:n,createdAt:r,metadata:o}=e;if(typeof t!=="string"||n!==xe.PENDING&&n!==xe.PROCESSING||typeof r!=="number"&&typeof r!=="bigint"||typeof o!=="string")throw Error("Invalid active job row returned during atomic enqueue");let i=JSON.parse(o);return{id:t,status:n,createdAt:Number(r),metadata:i}}async insertJob(e,t){if((await e.execute({sql:"INSERT INTO `job_queue` (\n `id`, `type`, `data`, `result`, `source`, `metadata`,\n `status`, `priority`, `retryCount`, `maxRetries`,\n `lastError`, `createdAt`, `scheduledFor`, `startedAt`,\n `completedAt`\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",args:[t.id,t.type,t.data,this.serializeJson(t.result),t.source,JSON.stringify(t.metadata),t.status,t.priority,t.retryCount,t.maxRetries,t.lastError,t.createdAt,t.scheduledFor,t.startedAt,t.completedAt]})).rowsAffected!==1)throw Error(`Atomic enqueue did not insert job ${t.id}`)}serializeJson(e){if(e===void 0||e===null)return null;return JSON.stringify(e)}acquireWriteTransaction(e,t){return this.retryOnConflict("acquire",e,()=>this.transactionClient.transaction("write"),(n)=>this.isSerializationConflict(n),t)}async waitForConflictRetry(e,t,n,r,o){let i=Math.min(Zhe*2**(r-1),Vhe),s=i/2+Math.random()*(i/2);if(Date.now()+s>=n)throw this.transactionConflictError(e,t,r,o);await new Promise((c)=>setTimeout(c,s))}async retryOnConflict(e,t,n,r,o=Date.now()+this.writeRetryBudgetMs,i=1){try{return await n()}catch(s){if(!r(s))throw s;return await this.waitForConflictRetry(e,t,o,i,s),this.retryOnConflict(e,t,n,r,o,i+1)}}transactionConflictError(e,t,n,r){let o=t.strategy??"none",i=t.deduplicationKey?"present":"absent";return Error(`Failed to ${e} atomic enqueue transaction for type "${t.jobData.type}" within ${this.writeRetryBudgetMs}ms after ${n} attempts (strategy: ${o}, key: ${i})`,{cause:r})}isSerializationConflict(e){for(let t=e;t!==void 0;){let n=typeof t==="object"&&t!==null&&"code"in t?String(t.code):"",r=qe(t,"");if(/SQLITE_(?:BUSY|LOCKED)/u.test(n)||/SQLITE_(?:BUSY|LOCKED)|database is locked|transaction (?:busy|conflict)/iu.test(r))return!0;t=t instanceof Error?t.cause:void 0}return!1}async startWorkerSession(e,t,n=Date.now(),r=ga){let o=n+r;await this.db.insert(tt).values({slotId:e,sessionId:t,startedAt:n,heartbeatAt:n,expiresAt:o}).onConflictDoUpdate({target:tt.slotId,set:{sessionId:t,startedAt:n,heartbeatAt:n,expiresAt:o}})}async heartbeatWorkerSession(e,t,n=Date.now(),r=ga){return(await this.db.update(tt).set({heartbeatAt:n,expiresAt:n+r}).where(ee(C(tt.slotId,e),C(tt.sessionId,t))).returning({slotId:tt.slotId})).length===1}async endWorkerSession(e,t){return(await this.db.delete(tt).where(ee(C(tt.slotId,e),C(tt.sessionId,t))).returning({slotId:tt.slotId})).length===1}async complete(e,t,n){let r=Date.now(),i=(await this.db.update(P).set({status:xe.COMPLETED,result:t,lastError:null,completedAt:r,runtimeUpdatedAt:this.nextRuntimeUpdatedAt(r)}).where(this.attemptWriteGuard(e,n)).returning({id:P.id})).length===1;if(i)this.logger.debug("Job completed",{jobId:e,hasResult:t!==void 0});return i}async update(e,t,n){let o=(await this.db.update(P).set({data:JSON.stringify(t)}).where(this.attemptWriteGuard(e,n)).returning({id:P.id})).length===1;if(o)this.logger.debug("Job data updated",{jobId:e});return o}async recordAttemptProgress(e,t,n,r=Date.now()){return(await this.db.update(P).set({attemptHeartbeatAt:r,runtimeUpdatedAt:this.nextRuntimeUpdatedAt(r),progress:n}).where(this.attemptWriteGuard(e,t)).returning({id:P.id})).length===1}async renewAttemptLease(e,t,n,r){return(await this.db.update(P).set({attemptHeartbeatAt:n,leaseExpiresAt:n+r}).where(this.attemptWriteGuard(e,t)).returning({id:P.id})).length===1}async fail(e,t,n,r=Date.now()){let i=(await this.db.select({retryCount:P.retryCount,maxRetries:P.maxRetries,type:P.type,scheduledFor:P.scheduledFor,startedAt:P.startedAt,runtimeUpdatedAt:P.runtimeUpdatedAt}).from(P).where(this.attemptWriteGuard(e,n)).limit(1))[0];if(!i)return!1;let s=i.retryCount<i.maxRetries,c=s?i.retryCount+1:i.retryCount,l=Math.min(1000*2**i.retryCount,60000),u=s?r+l:i.scheduledFor;if((await this.db.update(P).set({status:s?xe.PENDING:xe.FAILED,retryCount:c,lastError:t.message,scheduledFor:u,completedAt:s?null:r,runtimeUpdatedAt:s?i.runtimeUpdatedAt:this.nextRuntimeUpdatedAt(r),startedAt:s?null:i.startedAt,attemptId:null,workerSlotId:null,workerSessionId:null,leaseExpiresAt:null,attemptHeartbeatAt:null}).where(ee(this.attemptWriteGuard(e,n),C(P.retryCount,i.retryCount))).returning({id:P.id})).length!==1)return!1;if(s)this.logger.debug("Job scheduled for retry",{jobId:e,retryCount:c,backoffMs:l,scheduledFor:new Date(u).toISOString()});else this.logger.error("Job failed after max retries",{jobId:e,type:i.type,retryCount:i.retryCount,error:t.message});return!0}async retireUnownedActiveJob(e){let t=e.reason.trim();if(t.length===0)throw Error("Retired job reason must not be empty");let r=(await this.db.update(P).set({status:xe.FAILED,lastError:t,completedAt:e.now,runtimeUpdatedAt:this.nextRuntimeUpdatedAt(e.now)}).where(ee(C(P.id,e.jobId),C(P.type,e.expectedType),Sr(C(P.status,xe.PENDING),C(P.status,xe.PROCESSING)),Hn(P.attemptId),Hn(P.workerSlotId),Hn(P.workerSessionId),Hn(P.leaseExpiresAt),Hn(P.attemptHeartbeatAt),Hn(P.progress),Hn(P.result))).returning())[0]??null;if(r)this.logger.warn("Retired unowned legacy job",{jobId:r.id,type:r.type,reason:t});return r}async getStatus(e){return(await this.db.select().from(P).where(C(P.id,e)).limit(1))[0]??null}async getJobsByRootJobId(e){return this.db.select().from(P).where(b`json_extract(${P.metadata}, '$.rootJobId') = ${e}`).orderBy(lt(P.createdAt),lt(P.id))}async getStatusByEntityId(e){return(await this.db.select().from(P).where(b`json_extract(${P.data}, '$.id') = ${e}`).orderBy(un(P.createdAt)).limit(1))[0]??null}async getStats(){let e=await this.db.select({status:P.status,count:b`count(*)`}).from(P).groupBy(P.status),t={pending:0,processing:0,failed:0,completed:0,total:0};for(let n of e){let r=Number(n.count);t[n.status]=r,t.total+=r}return t}async getDiagnostics(e=Date.now()){let[t,n,r]=await Promise.all([this.db.select({type:P.type,status:P.status,count:b`count(*)`}).from(P).groupBy(P.type,P.status),this.db.select({oldestPendingAt:b`min(case when ${P.status} = ${xe.PENDING} then ${P.createdAt} end)`,duePending:b`coalesce(sum(case when ${P.status} = ${xe.PENDING} and ${P.scheduledFor} <= ${e} then 1 else 0 end), 0)`,oldestDuePendingAt:b`min(case when ${P.status} = ${xe.PENDING} and ${P.scheduledFor} <= ${e} then ${P.scheduledFor} end)`,latestClaimAt:b`max(${P.startedAt})`,oldestProcessingAt:b`min(case when ${P.status} = ${xe.PROCESSING} then ${P.startedAt} end)`,staleLeaseCount:b`coalesce(sum(case when ${P.status} = ${xe.PROCESSING} and ${P.leaseExpiresAt} is not null and ${P.leaseExpiresAt} <= ${e} then 1 else 0 end), 0)`}).from(P),this.db.select({total:b`count(*)`,active:b`coalesce(sum(case when ${tt.expiresAt} > ${e} then 1 else 0 end), 0)`,stale:b`coalesce(sum(case when ${tt.expiresAt} <= ${e} then 1 else 0 end), 0)`,latestHeartbeatAt:b`max(${tt.heartbeatAt})`}).from(tt)]),o={pending:0,processing:0,completed:0,failed:0},i=t.map((u)=>{let d=Number(u.count);return o[u.status]+=d,{type:u.type,status:u.status,count:d}}),s=n[0],c=r[0],l=(u)=>u===null||u===void 0?null:Math.max(0,e-Number(u));return{totals:o,byType:i,oldestPendingAgeMs:l(s?.oldestPendingAt),duePending:Number(s?.duePending??0),oldestDuePendingAgeMs:l(s?.oldestDuePendingAt),latestClaimAgeMs:l(s?.latestClaimAt),oldestProcessingAgeMs:l(s?.oldestProcessingAt),staleLeaseCount:Number(s?.staleLeaseCount??0),workerSessions:{total:Number(c?.total??0),active:Number(c?.active??0),stale:Number(c?.stale??0),latestHeartbeatAgeMs:l(c?.latestHeartbeatAt)}}}async getRuntimeUpdates(e,t){return(await this.db.select().from(P).where(b`(${P.runtimeUpdatedAt}, ${P.id}) > (${e.updatedAt}, ${e.jobId})`).orderBy(lt(P.runtimeUpdatedAt),lt(P.id)).limit(t)).map((r)=>({job:r,cursor:{updatedAt:r.runtimeUpdatedAt??0,jobId:r.id}}))}async cleanup(e){let t=Date.now()-e;return(await this.db.delete(P).where(ee(Sr(C(P.status,xe.COMPLETED),C(P.status,xe.FAILED)),vr(P.completedAt,t)))).rowsAffected}async getActiveJobs(e){let t=Sr(C(P.status,xe.PENDING),C(P.status,xe.PROCESSING)),n=e&&e.length>0?ee(t,Et(P.type,e)):t;return this.db.select().from(P).where(n).orderBy(un(P.createdAt))}async getRecentJobs(e,t=20){let n=e&&e.length>0?Et(P.type,e):void 0;return this.db.select().from(P).where(n).orderBy(un(P.createdAt)).limit(t)}async getFailedJobs(e){let t=C(P.status,xe.FAILED),n=e&&e.length>0?ee(t,Et(P.type,e)):t;return this.db.select().from(P).where(n).orderBy(un(P.createdAt))}async claimNextReady(e){let{now:t,attemptId:n,workerSlotId:r,workerSessionId:o,leaseDurationMs:i,executableTypes:s}=e,c=this.db.select({slotId:tt.slotId}).from(tt).where(ee(C(tt.slotId,r),C(tt.sessionId,o),Gp(tt.expiresAt,t))),l=this.db.select({slotId:tt.slotId}).from(tt).where(ee(C(tt.slotId,P.workerSlotId),C(tt.sessionId,P.workerSessionId))),u=this.db.select({slotId:tt.slotId}).from(tt).where(ee(C(tt.slotId,P.workerSlotId),C(tt.sessionId,P.workerSessionId),vr(tt.expiresAt,t))),d=ee(C(P.status,xe.PROCESSING),Sr(Hn(P.attemptId),LS(l),ee(vr(P.leaseExpiresAt,t),Ic(u)))),m=b`${P.status} = ${xe.PROCESSING} AND ${P.retryCount} + 1 > ${P.maxRetries}`,g=this.db.select({id:P.id}).from(P).where(ee(Et(P.type,s),Sr(ee(C(P.status,xe.PENDING),vr(P.scheduledFor,t)),d))).orderBy(lt(P.priority),lt(P.createdAt)).limit(1),x=(await this.db.update(P).set({status:b`CASE WHEN ${m} THEN ${xe.FAILED} ELSE ${xe.PROCESSING} END`,retryCount:b`CASE WHEN ${P.status} = ${xe.PROCESSING} THEN ${P.retryCount} + 1 ELSE ${P.retryCount} END`,lastError:b`CASE WHEN ${P.status} = ${xe.PROCESSING} THEN 'Attempt lease expired' ELSE ${P.lastError} END`,startedAt:b`CASE WHEN ${m} THEN ${P.startedAt} ELSE ${t} END`,completedAt:b`CASE WHEN ${m} THEN ${t} ELSE NULL END`,attemptId:b`CASE WHEN ${m} THEN ${P.attemptId} ELSE ${n} END`,workerSlotId:b`CASE WHEN ${m} THEN ${P.workerSlotId} ELSE ${r} END`,workerSessionId:b`CASE WHEN ${m} THEN ${P.workerSessionId} ELSE ${o} END`,leaseExpiresAt:b`CASE WHEN ${m} THEN ${P.leaseExpiresAt} ELSE ${t+i} END`,attemptHeartbeatAt:b`CASE WHEN ${m} THEN ${P.attemptHeartbeatAt} ELSE ${t} END`,runtimeUpdatedAt:b`CASE WHEN ${m} THEN ${this.nextRuntimeUpdatedAt(t)} ELSE ${P.runtimeUpdatedAt} END`}).where(ee(Et(P.id,g),Ic(c))).returning())[0];if(x?.status!==xe.PROCESSING)return null;return this.logger.debug("Job claimed",{jobId:x.id,attemptId:x.attemptId,workerSlotId:r,workerSessionId:o}),x}nextRuntimeUpdatedAt(e){return b`max(${e}, coalesce((select max(${P.runtimeUpdatedAt}) from ${P}), 0) + 1)`}attemptWriteGuard(e,t){return t?ee(C(P.id,e),C(P.status,xe.PROCESSING),C(P.attemptId,t)):ee(C(P.id,e),Hn(P.attemptId),Sr(C(P.status,xe.PENDING),C(P.status,xe.PROCESSING)))}}import{AsyncLocalStorage as Qhe}from"async_hooks";class _c{storage=new Qhe;static createFresh(){return new _c}constructor(){}current(){return this.storage.getStore()}run(e,t,n){if(t.length===0)throw Error("Operation ID must not be empty");let r=es.parse(e),o=Khe(r);return this.storage.run(Object.freeze({provenance:o,operationId:t}),n)}}function Khe(e){if(Object.freeze(e.projectionLineage),e.sourceEntity)Object.freeze(e.sourceEntity);return Object.freeze(e)}class tO{client;logger;handlerRegistry;repository;walInitialization=null;walInitializationSettled=!1;closeRequested=!1;clientClosed=!1;inFlightEnqueues=0;databaseUrl;operationContext;projectionAdmission;directWorkerSlotId=`direct:${gt()}`;directWorkerSessionId=gt();directLeaseDurationMs;directSessionStart=null;close(){this.closeRequested=!0,this.closeClientWhenReady()}static createFresh(e,t,n){return new tO(e,t??Fo.getInstance(),n)}constructor(e,t,n){let{db:r,client:o,url:i}=lG(e);this.client=o,this.databaseUrl=i,this.logger=t.child("JobQueueService"),this.operationContext=n?.operationContext??_c.createFresh(),this.projectionAdmission=n?.projectionAdmission,this.handlerRegistry=new YA(this.logger,n?.handlerRegistrationMode??"combined"),this.repository=new eO(r,o,i,this.logger),this.directLeaseDurationMs=e.claimTimeoutMs??300000}initialize(){if(this.closeRequested)return Promise.resolve();return this.walInitialization??=this.initializeWALMode(),this.walInitialization}async initializeWALMode(){try{await pi(this.client,this.databaseUrl)}catch(e){this.logger.warn("Failed to enable WAL mode (non-fatal)",e)}finally{this.walInitializationSettled=!0,this.closeClientWhenReady()}}closeClientWhenReady(){if(!this.closeRequested||this.inFlightEnqueues>0||this.walInitialization!==null&&!this.walInitializationSettled)return;this.closeClient()}closeClient(){if(this.clientClosed)return;this.clientClosed=!0,this.client.close()}registerHandler(e,t,n){this.handlerRegistry.registerHandler(e,t,n)}unregisterHandler(e){this.handlerRegistry.unregisterHandler(e)}unregisterPluginHandlers(e){this.handlerRegistry.unregisterPluginHandlers(e)}getRegisteredTypes(){return this.handlerRegistry.getRegisteredTypes()}getHandler(e){return this.handlerRegistry.getHandler(e)}getValidator(e){return this.handlerRegistry.getValidator(e)}finalizeHandlerRegistrations(){return this.handlerRegistry.finalizeRegistrations()}getExecutionRegistrations(){return this.handlerRegistry.getExecutionRegistrations()}async enqueue(e){if(this.closeRequested)throw Error("Cannot enqueue a job after the queue service is closed");this.inFlightEnqueues++;try{return await this.enqueueValidated(e)}finally{this.inFlightEnqueues--,this.closeClientWhenReady()}}async enqueueValidated(e){let{type:t,data:n,options:r}=e,o=this.handlerRegistry.getValidator(t);if(!o)throw Error(`No job type declared: ${t}`);let i=o.validateAndParse(n);if(i===null)throw Error(`Invalid job data for type: ${t}`);let s=Date.now(),c=gt(),l=r?.rootJobId??this.operationContext.current()?.provenance.rootJobId??c,u=this.createJobProvenance(c,l,r),d=r?.metadata??{operationType:"data_processing"},{provenance:m,...g}=d,h={id:c,type:t,data:JSON.stringify(i),status:xe.PENDING,priority:r?.priority??0,maxRetries:r?.maxRetries??3,retryCount:0,source:r?.source??null,metadata:{...g,...r?.deduplicationKey&&{deduplicationKey:r.deduplicationKey},rootJobId:l,provenance:u},createdAt:s,scheduledFor:r?.delayMs?s+r.delayMs:s,result:null,lastError:null,startedAt:null,completedAt:null},x,v=()=>{x?.rollback(),x=void 0};try{let E=await this.repository.enqueueAtomic({jobData:h,strategy:r?.deduplication,deduplicationKey:r?.deduplicationKey,beforeInsert:async()=>{x=await this.projectionAdmission?.reserveJobAdmission(u)},onInsertRollback:v});if(x?.commit(),x=void 0,E.kind==="skipped")this.logger.debug("Skipping duplicate job (already pending)",{type:t,existingJobId:E.jobId});else if(E.kind==="coalesced")this.logger.debug("Coalescing with existing job",{type:t,existingJobId:E.jobId});else{if(E.kind==="replaced")this.logger.debug("Replacing duplicate job",{type:t,oldJobId:E.replacedJobId});this.logger.debug("Job enqueued",{id:E.jobId,type:t,priority:h.priority,rootJobId:h.metadata.rootJobId})}return E.jobId}catch(E){throw v(),this.logger.error("Failed to enqueue job",{type:t,error:qe(E)}),E}}createJobProvenance(e,t,n){let r=this.operationContext.current(),o=n?.metadata.provenance??r?.provenance,i=o?.rootJobId===t?o:void 0,s=r?.provenance.rootJobId===t?r.operationId:void 0,c=n?.projection,l=c?[...i?.projectionLineage??[],c.id]:[...i?.projectionLineage??[]],u=c?.id??i?.projectionId;return es.parse({rootJobId:t,causationId:s??i?.causationId??e,...u?{projectionId:u}:{},projectionLineage:l,...c?.sourceEntity?{sourceEntity:c.sourceEntity}:i?.sourceEntity?{sourceEntity:i.sourceEntity}:{},derivationDepth:l.length})}async dequeue(e){let t=this.handlerRegistry.getRegisteredTypes();if(t.length===0)return null;let n=e??await this.getDirectClaimOptions(),r=Date.now(),o=await this.repository.claimNextReady({...n,now:r,attemptId:gt(),executableTypes:t});if(!o)return null;return this.logger.debug("Job dequeued",{id:o.id,type:o.type,priority:o.priority,retryCount:o.retryCount,attemptId:o.attemptId,workerSlotId:o.workerSlotId,workerSessionId:o.workerSessionId}),o}async startWorkerSession(e,t,n=ga){await this.repository.startWorkerSession(e,t,Date.now(),n)}heartbeatWorkerSession(e,t,n=ga){return this.repository.heartbeatWorkerSession(e,t,Date.now(),n)}endWorkerSession(e,t){return this.repository.endWorkerSession(e,t)}renewAttemptLease(e,t,n){return this.repository.renewAttemptLease(e,t,Date.now(),n)}recordAttemptProgress(e,t,n){return this.repository.recordAttemptProgress(e,t,n)}complete(e,t,n){return this.repository.complete(e,t,n)}update(e,t,n){return this.repository.update(e,t,n)}fail(e,t,n){return this.repository.fail(e,t,n)}retireUnownedActiveJob(e){return this.repository.retireUnownedActiveJob(e)}async getDirectClaimOptions(){return this.directSessionStart??=this.repository.startWorkerSession(this.directWorkerSlotId,this.directWorkerSessionId,Date.now(),this.directLeaseDurationMs),await this.directSessionStart,{workerSlotId:this.directWorkerSlotId,workerSessionId:this.directWorkerSessionId,leaseDurationMs:this.directLeaseDurationMs}}async getStatus(e){return this.repository.getStatus(e)}async getJobsByRootJobId(e){return this.repository.getJobsByRootJobId(e)}async getStatusByEntityId(e){return this.repository.getStatusByEntityId(e)}async getStats(){return this.repository.getStats()}getDiagnostics(e){return this.repository.getDiagnostics(e)}async waitForIdle(e={}){let t=e.quietMs??250,n=e.pollIntervalMs??25,r=Date.now()+(e.timeoutMs??30000),o=async(i)=>{e.signal?.throwIfAborted();let{totals:s}=await this.getDiagnostics(),l=s.pending===0&&s.processing===0?i??Date.now():null;if(l!==null&&Date.now()-l>=t)return;if(Date.now()>=r)throw Error(`Timed out waiting for the job queue to settle: ${s.pending} pending, ${s.processing} processing`);return await Bun.sleep(n),o(l)};return o(null)}getRuntimeUpdates(e,t=1000){return this.repository.getRuntimeUpdates(e,t)}async cleanup(e){let t=await this.repository.cleanup(e);if(t>0)this.logger.info("Cleaned up old jobs",{deletedCount:t,olderThanMs:e});return t}async getActiveJobs(e){return this.repository.getActiveJobs(e)}async getRecentJobs(e,t){return this.repository.getRecentJobs(e,t)}async getFailedJobs(e){return this.repository.getFailedJobs(e)}}class uG extends Error{constructor(e,t){super(`Job ${e} exceeded its ${t}ms execution deadline`);this.name="JobDeadlineExceededError"}}class nO{logger;jobQueueService;progressMonitor;config;isRunning=!1;shouldStop=!1;activeJobs=new Set;stats;startTime=0;pollFiber=null;currentPoll=null;workerScope=null;jobFibers=null;activeTransition=null;transitionQueue=[];clock;operationContext;workerSessionId=null;workerHeartbeatStop=null;static createFresh(e,t,n,r,o){return new nO(e,t,n,r,o)}constructor(e,t,n,r,o){if(this.logger=n.child("JobQueueWorker"),this.jobQueueService=e,this.progressMonitor=t,this.clock=o?.clock,this.operationContext=o?.operationContext??_c.createFresh(),this.config={concurrency:r?.concurrency??1,pollInterval:r?.pollInterval??1000,maxJobs:r?.maxJobs??0,autoStart:r?.autoStart??!1,workerSlotId:r?.workerSlotId??process.env.BRAIN_JOB_WORKER_SLOT_ID??"default",defaultExecutionTimeoutMs:r?.defaultExecutionTimeoutMs??300000,cancellationGraceMs:r?.cancellationGraceMs??5000,errorCallbackTimeoutMs:r?.errorCallbackTimeoutMs??1e4,leaseDurationMs:r?.leaseDurationMs??30000,attemptHeartbeatIntervalMs:r?.attemptHeartbeatIntervalMs??1e4,workerHeartbeatIntervalMs:r?.workerHeartbeatIntervalMs??5000,workerSessionTimeoutMs:r?.workerSessionTimeoutMs??ga,onUnhealthy:r?.onUnhealthy??(()=>{return})},this.stats={processedJobs:0,failedJobs:0,activeJobs:0,uptime:0,isRunning:!1,isHealthy:!0},this.logger.debug("JobQueueWorker initialized",{concurrency:this.config.concurrency,pollInterval:this.config.pollInterval,maxJobs:this.config.maxJobs,autoStart:this.config.autoStart}),this.config.autoStart)this.start().catch((i)=>{this.logger.error("Failed to auto-start JobQueueWorker",{error:i})})}start(){return this.requestTransition("start",!0)}async startWorker(){if(this.isRunning){this.logger.warn("Worker is already running");return}this.logger.debug("Starting JobQueueWorker");let e=gt();await this.jobQueueService.startWorkerSession(this.config.workerSlotId,e,this.config.workerSessionTimeoutMs),this.workerSessionId=e,this.isRunning=!0,this.shouldStop=!1,this.startTime=Date.now(),this.stats.isRunning=!0,this.stats.isHealthy=!0,delete this.stats.unhealthyReason,this.startWorkerHeartbeat(),this.workerScope=G.runSync(Bt.make()),this.jobFibers=G.runSync(Bt.extend(xr.make(),this.workerScope)),this.pollFiber=G.runFork(this.runPollingLoop())}stop(){return this.requestTransition("stop",!0)}async stopWorker(e){if(!this.isRunning){this.logger.warn("Worker is not running");return}if(this.logger.debug("Stopping JobQueueWorker"),this.shouldStop=!0,e.awaitInFlightPoll&&this.pollFiber){let n=this.pollFiber;await G.runPromise(Ao.interrupt(n)),this.pollFiber=null}if(e.awaitInFlightPoll&&this.currentPoll)await this.currentPoll,this.currentPoll=null;if(this.jobFibers)this.logger.debug("Waiting for active jobs to complete",{activeJobs:this.activeJobs.size}),await G.runPromise(xr.awaitEmpty(this.jobFibers));await this.closeWorkerScope(),await this.stopWorkerHeartbeat();let t=this.workerSessionId;if(this.workerSessionId=null,t)await this.jobQueueService.endWorkerSession(this.config.workerSlotId,t);this.isRunning=!1,this.stats.isRunning=!1,this.logger.debug("JobQueueWorker stopped")}getStats(){return{...this.stats,activeJobs:this.activeJobs.size,uptime:this.isRunning?Date.now()-this.startTime:0}}isWorkerRunning(){return this.isRunning}isStopRequested(){return this.shouldStop}async processAvailableJobs(){if(!this.isRunning||this.shouldStop)return;try{let e=this.config.concurrency-this.activeJobs.size;if(e<=0)return;if(this.config.maxJobs>0){let r=this.stats.processedJobs+this.stats.failedJobs,o=this.config.maxJobs-r-this.activeJobs.size;if(o<=0){this.logger.debug("Maximum job limit reached, stopping worker",{maxJobs:this.config.maxJobs,processedJobs:this.stats.processedJobs,failedJobs:this.stats.failedJobs}),await this.requestTransition("stop",!1);return}e=Math.min(e,o)}let t=[];for(let r=0;r<e;r++){if(this.isStopRequested())break;let o=this.workerSessionId;if(!o)throw Error("Worker session is not available");let i=await this.jobQueueService.dequeue({workerSlotId:this.config.workerSlotId,workerSessionId:o,leaseDurationMs:this.config.leaseDurationMs});if(i)t.push(i);else break}let n=this.jobFibers;if(!n){if(t.length>0)throw Error("Worker job fiber scope is not available");return}for(let r of t)this.activeJobs.add(r.id),await G.runPromise(xr.run(n,r.id,G.promise(()=>this.processJobWrapper(r))))}catch(e){this.logger.error("Error processing available jobs",{error:e}),this.stats.lastError=qe(e)}}async processJobWrapper(e){let t=e.id;try{this.logger.debug("Processing job",{jobId:t,type:e.type,priority:e.priority,retryCount:e.retryCount});let n=await this.processJob(e);if(n.status==="completed")this.stats.processedJobs++,this.logger.debug("Job completed successfully",{jobId:t,type:n.type});else this.stats.failedJobs++,this.logger.warn("Job failed",{jobId:t,type:n.type,error:n.error})}catch(n){this.stats.failedJobs++,this.logger.error("Error processing job",{jobId:t,type:e.type,error:n}),this.stats.lastError=qe(n)}finally{this.activeJobs.delete(t)}}runPollingLoop(){let t=G.suspend(()=>{if(!this.isWorkerRunning()||this.isStopRequested())return G.interrupt;return this.currentPoll=this.processAvailableJobs(),G.promise(()=>this.currentPoll??Promise.resolve()).pipe(G.andThen(G.suspend(()=>(this.currentPoll=null,!this.isWorkerRunning()||this.isStopRequested()?G.interrupt:G.void))))}).pipe(G.schedule($i.spaced(this.config.pollInterval)),G.asVoid);return(this.clock?G.withClock(t,this.clock):t).pipe(G.ensuring(G.sync(()=>{this.pollFiber=null})))}requestTransition(e,t){let n=this.transitionQueue.at(-1)??this.activeTransition;if(n?.kind===e)return n.promise;let r=()=>{return},o=()=>{return},i=new Promise((c,l)=>{r=c,o=l}),s={kind:e,awaitInFlightPoll:t,promise:i,resolve:r,reject:o};return this.transitionQueue.push(s),this.runNextTransition(),i}runNextTransition(){if(this.activeTransition)return;let e=this.transitionQueue.shift();if(!e)return;this.activeTransition=e,(e.kind==="start"?this.startWorker():this.stopWorker({awaitInFlightPoll:e.awaitInFlightPoll})).then(()=>this.completeTransition(e,!0),(n)=>this.completeTransition(e,!1,n))}completeTransition(e,t,n){if(this.activeTransition!==e)return;if(this.activeTransition=null,t)e.resolve();else e.reject(n);queueMicrotask(()=>this.runNextTransition())}async closeWorkerScope(){let e=this.workerScope;if(this.workerScope=null,this.jobFibers=null,e)await G.runPromise(Bt.close(e,Ct.void))}startHeartbeatLoop(e){let t=null,n=!1,r=setInterval(()=>{if(n||t)return;t=e.beat().then((o)=>{if(!o)e.onStale()}).catch(e.onError).finally(()=>{t=null})},Math.max(1,e.intervalMs));return async()=>{if(n)return;n=!0,clearInterval(r),await t}}startWorkerHeartbeat(){this.workerHeartbeatStop=this.startHeartbeatLoop({intervalMs:this.config.workerHeartbeatIntervalMs,beat:async()=>{let e=this.workerSessionId;if(!e)return!0;return this.jobQueueService.heartbeatWorkerSession(this.config.workerSlotId,e,this.config.workerSessionTimeoutMs)},onStale:()=>this.markUnhealthy("Worker session was superseded"),onError:(e)=>this.markUnhealthy(`Worker session heartbeat failed: ${qe(e)}`)})}async stopWorkerHeartbeat(){await this.workerHeartbeatStop?.(),this.workerHeartbeatStop=null}startAttemptHeartbeat(e,t){let n=e.attemptId;if(!n)return async()=>{return};return this.startHeartbeatLoop({intervalMs:this.config.attemptHeartbeatIntervalMs,beat:()=>this.jobQueueService.renewAttemptLease(e.id,n,this.config.leaseDurationMs),onStale:()=>{let r=Error("Job attempt was superseded");t.abort(r),this.markUnhealthy(r.message)},onError:(r)=>{let o=pd(r);t.abort(o),this.markUnhealthy(`Attempt lease heartbeat failed: ${o.message}`)}})}markUnhealthy(e){if(!this.stats.isHealthy)return;this.stats.isHealthy=!1,this.stats.unhealthyReason=e,this.stats.lastError=e,this.shouldStop=!0,this.logger.error("Job queue worker is unhealthy",{reason:e});try{this.config.onUnhealthy(e)}catch(t){this.logger.error("Job queue worker unhealthy callback failed",{reason:e,error:qe(t)})}}async raceOutcome(e,t){let n,r=new Promise((o)=>{n=setTimeout(()=>o({kind:"timeout"}),Math.max(1,t))});try{return await Promise.race([e,r])}finally{if(n)clearTimeout(n)}}async executeWithDeadline(e,t,n,r){let o=Promise.resolve().then(r).then((l)=>({kind:"success",value:l}),(l)=>({kind:"failure",error:l})),i=await this.raceOutcome(o,t);if(i.kind!=="timeout"){if(i.kind==="failure")throw i.error;return i.value}let s=new uG(e,t);if(n.abort(s),(await this.raceOutcome(o,this.config.cancellationGraceMs)).kind!=="timeout")throw s;throw this.markUnhealthy(`${s.message}; handler ignored cancellation grace`),await o,s}processJob(e){let t=e.metadata.provenance??{rootJobId:e.metadata.rootJobId,causationId:e.id,projectionLineage:[],derivationDepth:0};return this.operationContext.run(t,e.id,()=>this.processJobWithinContext(e))}async processJobWithinContext(e){let t=e.attemptId;if(!t){let c=Error(`Claimed job ${e.id} has no attempt fencing token`);return this.markUnhealthy(c.message),{jobId:e.id,type:e.type,status:xe.FAILED,error:c.message}}let n=this.jobQueueService.getHandler(e.type);if(!n){let c=Error(`No handler registered for job type: ${e.type}`);return await this.jobQueueService.fail(e.id,c,t),{jobId:e.id,type:e.type,status:xe.FAILED,error:c.message}}let r=new AbortController,o=this.startAttemptHeartbeat(e,r),i=!1,s=async()=>{if(i)return;i=!0,await o()};try{this.logger.debug("Processing job",{jobId:e.id,type:e.type,attemptId:t});let c=JSON.parse(e.data),l=n.validateAndParse(c);if(l===null)throw Error(`Invalid job data for type: ${e.type}`);let u=this.progressMonitor.createProgressReporter(e.id,t),d=n.executionTimeoutMs??this.config.defaultExecutionTimeoutMs,m=await this.executeWithDeadline(e.type,d,r,()=>n.process(l,e.id,u,r.signal));await s();let g=KA.safeParse(m);if(g.success){let x=g.data.error??"Handler returned failure",v=Error(x);if(await this.jobQueueService.fail(e.id,v,t))await this.emitTerminalFailure(e,v,n,t);return{jobId:e.id,type:e.type,status:xe.FAILED,error:x}}if(!await this.jobQueueService.complete(e.id,m,t))return{jobId:e.id,type:e.type,status:xe.FAILED,error:"Job attempt no longer owns the claim"};return await this.runHandlerSuccessCallback(n,e,t),await this.progressMonitor.handleJobStatusChange(e.id,"completed",e.metadata),{jobId:e.id,type:e.type,status:xe.COMPLETED,result:m}}catch(c){let l=pd(c);if(await s(),await this.runHandlerErrorCallback("onError",n,e,l,t),await this.jobQueueService.fail(e.id,l,t))await this.emitTerminalFailure(e,l,n,t);return{jobId:e.id,type:e.type,status:xe.FAILED,error:l.message}}}async runHandlerSuccessCallback(e,t,n){let r=e.onTerminalSuccess;if(!r)return;try{let o=e.validateAndParse(JSON.parse(t.data));if(o===null)return;let i=this.progressMonitor.createProgressReporter(t.id,n),s=new AbortController;await this.executeWithDeadline(`${t.type}:onTerminalSuccess`,this.config.errorCallbackTimeoutMs,s,()=>r.call(e,o,t.id,i,s.signal))}catch(o){this.logger.error("Terminal job success callback failed",{jobId:t.id,type:t.type,error:o})}}async emitTerminalFailure(e,t,n,r){if((await this.jobQueueService.getStatus(e.id))?.status!==xe.FAILED)return;await this.runHandlerErrorCallback("onTerminalError",n,e,t,r),await this.progressMonitor.handleJobStatusChange(e.id,"failed",e.metadata)}async runHandlerErrorCallback(e,t,n,r,o){let i=t[e];if(!i)return;try{let s=t.validateAndParse(JSON.parse(n.data));if(s===null)return;let c=this.progressMonitor.createProgressReporter(n.id,o),l=new AbortController;await this.executeWithDeadline(`${n.type}:${e}`,this.config.errorCallbackTimeoutMs,l,()=>i.call(t,r,s,n.id,c,l.signal))}catch(s){this.logger.error(e==="onError"?"Job handler error callback failed":"Job handler terminal error callback failed",{jobId:n.id,error:s})}}}var Yhe=86400000,pG=3600000;class rO{jobQueue;logger;batches=new Map;cleanupFiber=null;cleanupSupervisor=null;inFlightCleanups=new Set;activeTransition=null;transitionQueue=[];acceptingCleanup=!0;clock;static createFresh(e,t,n){return new rO(e,t,n)}constructor(e,t,n){this.jobQueue=e,this.logger=t,this.clock=n?.clock}start(e=pG){return this.requestTransition("start",e)}stop(){return this.requestTransition("stop",pG)}async startCleanup(e){if(this.acceptingCleanup=!0,this.cleanupFiber)return;this.cleanupFiber=G.runFork(this.runCleanupLoop(e))}runCleanupLoop(e){let t=this.cleanupTerminalBatchMetadata().pipe(G.schedule($i.spaced(e)),G.asVoid);return this.clock?G.withClock(t,this.clock):t}scheduleTerminalBatchCleanup(){if(!this.acceptingCleanup)return;this.cleanupSupervisor??=this.createCleanupSupervisor();let e=G.runFork(this.cleanupTerminalBatchMetadata());Gl.unsafeAdd(this.cleanupSupervisor.fibers,e)}async stopCleanup(){this.acceptingCleanup=!1;let e=this.cleanupFiber;if(this.cleanupFiber=null,e)await G.runPromise(Ao.interrupt(e));let t=this.cleanupSupervisor;if(t)await G.runPromise(Gl.awaitEmpty(t.fibers));while(this.inFlightCleanups.size>0)await Promise.allSettled(this.inFlightCleanups);if(t)await G.runPromise(Bt.close(t.scope,Ct.void)),this.cleanupSupervisor=null}requestTransition(e,t){let n=this.transitionQueue.at(-1)??this.activeTransition;if(n?.kind===e)return n.promise;let r=()=>{return},o=()=>{return},i=new Promise((c,l)=>{r=c,o=l}),s={kind:e,intervalMs:t,promise:i,resolve:r,reject:o};return this.transitionQueue.push(s),this.runNextTransition(),i}runNextTransition(){if(this.activeTransition)return;let e=this.transitionQueue.shift();if(!e)return;this.activeTransition=e,(e.kind==="start"?this.startCleanup(e.intervalMs):this.stopCleanup()).then(()=>this.completeTransition(e,!0),(n)=>this.completeTransition(e,!1,n))}completeTransition(e,t,n){if(this.activeTransition!==e)return;if(this.activeTransition=null,t)e.resolve();else e.reject(n);queueMicrotask(()=>this.runNextTransition())}createCleanupSupervisor(){let e=G.runSync(Bt.make()),t=G.runSync(Bt.extend(Gl.make(),e));return{scope:e,fibers:t}}cleanupTerminalBatchMetadata(){return G.tryPromise({try:()=>{let e=this.cleanup(Yhe);return this.inFlightCleanups.add(e),e.then(()=>this.inFlightCleanups.delete(e),()=>this.inFlightCleanups.delete(e)),e},catch:(e)=>e}).pipe(G.asVoid,G.catchAll((e)=>G.sync(()=>{this.logger.warn("Failed to clean up terminal batch metadata",{error:e})})))}validateOperations(e){for(let t of e){let n=this.jobQueue.getValidator(t.type);if(!n)throw Error(`No job type declared: ${t.type}`);if(n.validateAndParse(t.data)===null)throw Error(`Invalid job data for type: ${t.type}`)}}async enqueueBatch(e,t,n,r){if(e.length===0)throw Error("Cannot enqueue empty batch");this.validateOperations(e);let o=[];this.batches.set(n,{jobIds:o,operations:e,source:t.source,startedAt:new Date().toISOString(),metadata:{...t.metadata,rootJobId:n}});try{for(let i of e){let s={...t,rootJobId:n,metadata:{...t.metadata,operationTarget:i.type}},c=await this.jobQueue.enqueue({type:i.type,data:i.data,options:s});o.push(c)}return this.logger.debug("Enqueued batch operations",{batchId:n,operationCount:e.length,jobIds:o,rootJobId:n}),this.scheduleTerminalBatchCleanup(),n}catch(i){throw this.batches.delete(n),this.logger.error("Failed to enqueue batch operations",{error:i,operationCount:e.length,enqueuedJobs:o.length}),i}}async getBatchStatus(e){let t=this.batches.get(e);if(!t)return null;try{let n=await Promise.all(t.jobIds.map((u)=>this.jobQueue.getStatus(u))),r=0,o=0,i=0,s=[];for(let[u,d]of n.entries()){if(!d){o++;let m=t.operations[u],g=t.jobIds[u]??"unknown";s.push(`Missing job ${g}${m?` for ${m.type}`:""}`);continue}switch(d.status){case"completed":r++;break;case"failed":if(o++,d.lastError)s.push(d.lastError);break;case"processing":case"pending":i++;break}}i+=t.operations.length-t.jobIds.length;let c;if(i>0)c=xe.PROCESSING;else if(o>0)c=xe.FAILED;else c=xe.COMPLETED;if(t.terminalAt===void 0&&(c===xe.COMPLETED||c===xe.FAILED))t.terminalAt=Date.now();let l;for(let u=0;u<t.jobIds.length;u++){let d=n[u];if(d&&d.status!=="completed"&&d.status!=="failed"){let m=t.operations[u];if(m)l=`Processing ${m.type}`;break}}return{batchId:e,totalOperations:t.operations.length,completedOperations:r,failedOperations:o,errors:s,status:c,currentOperation:l,metadata:t.metadata}}catch(n){throw this.logger.error("Failed to get batch status",{batchId:e,error:n}),n}}inspectRetention(e){let t=this.batches.get(e);return t?{terminalAt:t.terminalAt}:void 0}async cleanup(e){let t=Date.now()-e,n=0;for(let[r,o]of this.batches.entries()){if(o.terminalAt!==void 0){if(o.terminalAt<=t)this.batches.delete(r),n++;continue}if(new Date(o.startedAt).getTime()<=t){let s=await this.getBatchStatus(r);if(s&&(s.status===xe.COMPLETED||s.status===xe.FAILED))this.batches.delete(r),n++}}return this.logger.debug("Cleaned up batch metadata",{cleaned:n}),n}registerBatch(e,t,n,r,o){this.batches.set(e,{jobIds:t,operations:n,source:r,startedAt:new Date().toISOString(),metadata:o}),this.logger.debug("Registered batch metadata",{batchId:e,operationCount:n.length,jobIds:t})}async getActiveBatches(){let e=[];try{for(let[t,n]of this.batches){let r=await this.getBatchStatus(t);if(r&&(r.status==="pending"||r.status==="processing"))e.push({batchId:t,status:r,metadata:{operations:n.operations,source:n.source,startedAt:n.startedAt,metadata:n.metadata}})}return this.logger.debug("Retrieved active batches",{count:e.length}),e}catch(t){throw this.logger.error("Failed to get active batches",{error:t}),t}}}var Xhe=a.preprocess((e)=>{if(typeof e!=="string")return e;return JSON.parse(e)},a.record(a.string(),a.unknown()));class oO{jobQueueService;messageBus;batchJobManager;logger;mode;pollTimer;pollCursor={updatedAt:0,jobId:""};polling=!1;static createFresh(e,t,n,r,o="combined"){return new oO(e,t,n,r,o)}constructor(e,t,n,r,o){this.jobQueueService=e,this.messageBus=t,this.batchJobManager=n,this.logger=r,this.mode=o}start(){if(this.mode==="durable-reader"&&!this.pollTimer){this.pollCursor={updatedAt:Date.now(),jobId:""},this.pollTimer=setInterval(()=>{this.pollDurableUpdates()},250),this.pollTimer.unref(),this.logger.debug("Job progress monitor ready (durable polling mode)");return}this.logger.debug("Job progress monitor ready (event-driven mode)")}stop(){if(this.pollTimer)clearInterval(this.pollTimer);this.pollTimer=void 0,this.logger.debug("Job progress monitor stopped")}async pollDurableUpdates(){if(this.polling)return;this.polling=!0;try{let e=await this.jobQueueService.getRuntimeUpdates(this.pollCursor,100);for(let t of e)if(this.pollCursor=t.cursor,t.job.status==="processing"&&t.job.progress)await this.publishJobProgress(t.job,t.job.progress);else if(t.job.status==="completed"||t.job.status==="failed")await this.handleJobStatusChange(t.job.id,t.job.status,t.job.metadata)}catch(e){this.logger.error("Failed to poll durable job progress",{error:e})}finally{this.polling=!1}}createProgressReporter(e,t){let n=fa.from(async(r)=>{await this.emitJobProgress(e,r,t)});if(!n)throw Error("Failed to create ProgressReporter");return n}async emitBatchProgress(e,t,n){try{let r={totalOperations:t.totalOperations,completedOperations:t.completedOperations,failedOperations:t.failedOperations,currentOperation:t.currentOperation??"Processing batch...",errors:t.errors},o={id:e,type:"batch",status:t.status,metadata:n,batchDetails:r};if(t.totalOperations>0)o.progress={current:t.completedOperations,total:t.totalOperations,percentage:Math.round(t.completedOperations/t.totalOperations*100)};await this.messageBus.send({type:_g.progress,payload:o,sender:"job-progress-monitor",broadcast:!0}),this.logger.debug("Emitted batch progress update",{batchId:e,status:t.status,progress:`${t.completedOperations}/${t.totalOperations}`})}catch(r){this.logger.error("Error emitting batch progress update",{batchId:e,error:r})}}isBatchChild(e,t){return!!t&&t!==e}get publishesEvents(){return this.mode!=="durable-writer"}async broadcastEvent(e){await this.messageBus.send({type:_g.progress,payload:e,sender:"job-progress-monitor",broadcast:!0})}async emitJobProgress(e,t,n){try{if(n&&!await this.jobQueueService.recordAttemptProgress(e,n,t)){this.logger.debug("Discarding progress from obsolete job attempt",{jobId:e,attemptId:n});return}if(!this.publishesEvents)return;let r=await this.jobQueueService.getStatus(e);if(!r){this.logger.warn("Job not found for progress update",{jobId:e});return}await this.publishJobProgress(r,t)}catch(r){this.logger.error("Error emitting job progress",{jobId:e,error:r})}}async publishJobProgress(e,t){if(e.metadata.silent)return;if(this.isBatchChild(e.id,e.metadata.rootJobId))return;let n=t.total??0,r={id:e.id,type:"job",status:"processing",metadata:e.metadata,message:t.message};if(n>0)r.progress={current:t.progress,total:n,percentage:Math.round(t.progress/n*100)};await this.broadcastEvent(r)}async emitJobCompletion(e){await this.emitJobStatusEvent(e,"completed")}async emitJobFailure(e){await this.emitJobStatusEvent(e,"failed")}async emitJobStatusEvent(e,t){if(!this.publishesEvents)return;try{let n=await this.jobQueueService.getStatus(e);if(!n){this.logger.warn(`Cannot emit ${t} for unknown job`,{jobId:e});return}if(n.metadata.silent)return;if(this.isBatchChild(e,n.metadata.rootJobId)){this.logger.debug(`Skipping individual job ${t} for batch operation`,{jobId:e,rootJobId:n.metadata.rootJobId});return}let r={id:e,type:"job",status:t,message:this.extractStatusMessage(n,t),metadata:n.metadata,jobDetails:{jobType:n.type,priority:n.priority,retryCount:n.retryCount}};await this.broadcastEvent(r),this.logger.debug(`Emitted job ${t} event`,{jobId:e})}catch(n){this.logger.error(`Error emitting job ${t} event`,{jobId:e,error:n})}}extractStatusMessage(e,t){if(t==="failed")return e.lastError??void 0;if(!e.result)return;try{let n=Xhe.parse(e.result),r=n.message;if(r)return String(r);let o=n.routesBuilt;if(o!==void 0)return`${o} routes built`}catch{}return}getStats(){return{isRunning:!0}}async handleJobStatusChange(e,t,n){if(!this.publishesEvents)return;let r=n?su.safeParse(n):void 0,o=r?.success?r.data:void 0;if(o?.silent)return;try{if(await this.emitJobStatusEvent(e,t),o&&this.isBatchChild(e,o.rootJobId))try{let i=o.rootJobId,s=await this.batchJobManager.getBatchStatus(i);if(s){let c=s.metadata??o;await this.emitBatchProgress(i,s,c)}}catch(i){this.logger.warn("Failed to emit batch progress",{jobId:e,rootJobId:o.rootJobId,error:i})}}catch(i){this.logger.error("Failed to handle job status change",{jobId:e,status:t,error:i})}}}var eye=a.record(a.string(),a.unknown());class Ng{logger;schema;jobTypeName;executionTimeoutMs;constructor(e,t){this.logger=e,this.schema=t.schema,this.jobTypeName=t.jobTypeName,this.executionTimeoutMs=t.executionTimeoutMs}validateAndParse(e){if(!this.schema)throw Error(`${this.jobTypeName}: No schema provided. Override validateAndParse() or provide a schema.`);let t=this.schema.safeParse(e);if(!t.success)return this.logger.warn(`Invalid ${this.jobTypeName} job data`,{data:e,validationError:t.error.issues}),null;return this.logger.debug(`${this.jobTypeName} job data validation successful`,{data:this.summarizeDataForLog(t.data)}),t.data}async onError(e,t,n,r,o){this.logger.error(`${this.jobTypeName} job error handler triggered`,{jobId:n,errorMessage:e.message,errorStack:e.stack,data:this.summarizeDataForLog(t)})}async reportProgress(e,t){await e.report({progress:t.progress,total:t.total??100,message:t.message})}summarizeDataForLog(e){let t=eye.safeParse(e);return t.success?t.data:{}}}function Fg(e,t,n){return async(r)=>{let{type:o,data:i,toolContext:s=null,options:c,projection:l}=r,u=s?dG(s):void 0,{metadata:d,...m}=c??{},g={operationType:"data_processing",pluginId:t,...d,...s&&{interfaceType:s.interfaceType,conversationId:s.conversationId,channelId:s.channelId,requestedByActor:s.actor,...u?{requestedByUserId:u}:{},requestedByInterface:s.interfaceType,...s.progressToken!==void 0&&{progressToken:s.progressToken}}};if(s&&!u)delete g.requestedByUserId;let h={...m,source:t,...c?.rootJobId&&{rootJobId:c.rootJobId},...l&&{projection:l},metadata:g},x=n&&!o.includes(":")?`${t}:${o}`:o;return e.enqueue({type:x,data:i,options:h})}}function iO(e,t){return async(n,r)=>{let o=r?.rootJobId??gt(),i=n.map((c)=>({...c,type:c.type.includes(":")?c.type:`${t}:${c.type}`})),s={...r,source:t,rootJobId:o,metadata:{...r?.metadata,operationType:"batch_processing",pluginId:t}};return await e.enqueueBatch(i,s,o,t),o}}function sO(e,t){return(n,r)=>{let o=n.includes(":")?n:`${t}:${n}`;e.registerHandler(o,r,t)}}var tye=a.custom((e)=>typeof e==="object"&&e!==null&&("safeParse"in e)),nye=a.object({name:a.string(),schema:tye});function mG(e){return nye.safeParse(e).success}function rye(e){if(!e)return;return{status:e.status,message:e.message,lastCheck:e.lastCheck?.toISOString(),details:e.details}}function fG(e){return{model:e.model,version:e.version,uptime:e.uptime,entities:e.entities,entityCounts:e.entityCounts,embeddings:e.embeddings,ai:e.ai,daemons:e.daemons.map((t)=>({name:t.name,pluginId:t.pluginId,status:t.status,health:rye(t.health)})),endpoints:e.endpoints,interactions:e.interactions}}var gG={digest:"conversation:digest"};var pe=wt("conversations",{id:W("id").primaryKey(),sessionId:W("session_id").notNull(),interfaceType:W("interface_type").notNull(),channelId:W("channel_id").notNull(),personId:W("person_id"),started:W("started").notNull(),lastActive:W("last_active").notNull(),metadata:W("metadata"),created:W("created").notNull(),updated:W("updated").notNull()},(e)=>({sessionIdx:vt("idx_conversations_session").on(e.sessionId),channelIdx:vt("idx_conversations_channel").on(e.channelId),personIdx:vt("idx_conversations_person").on(e.personId),interfaceSessionIdx:vt("idx_conversations_interface_session").on(e.interfaceType,e.sessionId),interfaceChannelIdx:vt("idx_conversations_interface_channel").on(e.interfaceType,e.channelId)})),Tn=wt("messages",{id:W("id").primaryKey(),conversationId:W("conversation_id").notNull().references(()=>pe.id,{onDelete:"cascade"}),role:W("role").notNull(),content:W("content").notNull(),timestamp:W("timestamp").notNull(),metadata:W("metadata")},(e)=>({conversationIdx:vt("idx_messages_conversation").on(e.conversationId),timestampIdx:vt("idx_messages_timestamp").on(e.timestamp)})),au=wt("summary_tracking",{conversationId:W("conversation_id").primaryKey().references(()=>pe.id,{onDelete:"cascade"}),lastSummarizedAt:W("last_summarized_at"),lastMessageId:W("last_message_id"),messagesSinceSummary:Re("messages_since_summary").default(0),updated:W("updated").notNull()});function hG(e){return ui({url:e.url,schema:{conversations:pe,messages:Tn,summaryTracking:au},authToken:e.authToken,authTokenEnv:"CONVERSATION_DATABASE_AUTH_TOKEN"})}var oye=a.preprocess((e)=>{if(typeof e!=="string")return e;try{return JSON.parse(e)}catch{return}},a.record(a.string(),a.unknown())).catch({});function ha(e){return oye.parse(e)}var fv="conversation:messageAdded",aO="conversation:started",zg=a.object({identity:Yi,interfaceType:a.string(),role:Hp,displayName:a.string().optional(),username:a.string().optional(),isBot:a.boolean().optional()}),iye=a.preprocess(sye,zg);function sye(e){if(!jo(e)||"identity"in e)return e;let{actorId:t,interfaceType:n,role:r}=e;if(typeof t!=="string"||typeof n!=="string"||r!=="user"&&r!=="assistant")return e;let{userId:o,canonicalId:i}=e;return{identity:yG({actorId:t,interfaceType:n,role:r,...typeof o==="string"?{userId:o}:{},...typeof i==="string"?{canonicalId:i}:{}}),interfaceType:n,role:r,...typeof e.displayName==="string"?{displayName:e.displayName}:{},...typeof e.username==="string"?{username:e.username}:{},...typeof e.isBot==="boolean"?{isBot:e.isBot}:{}}}var jg=a.object({messageId:a.string().optional(),channelId:a.string().optional(),channelName:a.string().optional(),threadId:a.string().optional(),metadata:a.record(a.string(),a.unknown()).optional()}),bG=a.looseObject({actor:iye.optional(),source:jg.optional()});function xG(e){if(typeof e==="string")try{let t=JSON.parse(e);return jo(t)?t:null}catch{return null}return jo(e)?e:null}function aye(e){if(e.role!=="assistant")return!1;if(e.content.trim().length===0)return!1;let t=xG(e.metadata),n=t?.entityMemoryRefs;if(Array.isArray(n)&&n.length>0)return!1;let r=t?.cards;if(!Array.isArray(r))return!0;return!r.some((o)=>{if(!jo(o))return!1;if(o.kind==="tool-approval")return!0;return o.kind==="actions"&&o.id==="actions:upload-intent"})}var cye=a.object({id:a.string(),conversationId:a.string(),role:a.string(),content:a.string(),timestamp:a.string(),metadata:a.string().nullable()}),SG=a.object({conversationId:a.string(),messageCount:a.number(),messages:a.array(cye),windowStart:a.number(),windowEnd:a.number(),windowSize:a.number(),timestamp:a.string()});var mi=b`strftime('%Y-%m-%dT%H:%M:%fZ', 'now')`;function cO(){return CG(!1)}function TG(){return CG(!0)}function CG(e){let t=vG.shape.maxAgeSeconds.maxValue,n=b`(
|
|
127
|
+
5. Structure your response clearly and concisely`,dataSourceId:"shell:ai-content",requiredPermission:"public",useKnowledgeContext:!0,schema:uv,formatter:new Pg};var yhe=a.object({type:a.string().describe("Type of source (e.g., note, article)"),title:a.string().describe("Title or identifier of the source"),relevance:a.number().min(0).max(1).describe("Relevance score")}),JV=a.object({answer:a.string().describe("The answer to the user's query"),sources:a.array(yhe).optional().describe("Sources used to generate the answer"),confidence:a.enum(["high","medium","low"]).optional().describe("Confidence level of the answer"),suggestions:a.array(a.string()).optional().describe("Related topics or follow-up questions")});function ma(e,t){return e.parse(t)}class fa{callback;heartbeatInterval;constructor(e){this.callback=e}static from(e){if(!e)return;return new fa(e)}static noop(){return new fa(async()=>{})}createSub(e){let{scale:t}=e??{};if(t){let{start:n,end:r}=t,o=r-n;return new fa(async(i)=>{let s=n+i.progress/(i.total??100)*o;await this.callback({...i,progress:s,total:100})})}return new fa(this.callback)}async report(e){await this.callback(e)}startHeartbeat(e,t=5000){this.stopHeartbeat(),this.heartbeatInterval=setInterval(()=>{this.report({message:e,progress:0}).catch(()=>{})},t)}stopHeartbeat(){if(this.heartbeatInterval)clearInterval(this.heartbeatInterval),this.heartbeatInterval=void 0}toCallback(){return this.callback}}var xhe=a.object({enabled:a.boolean().describe("Whether the plugin is enabled"),debug:a.boolean().describe("Enable debug logging for this plugin")});function She(e){return e.map((t)=>`${t.path||"<root>"}: ${t.message}`).join("; ")}class Ag extends Error{pluginId;issues;constructor(e,t){super(`Invalid plugin config for ${e} at ${She(t)}; correct the listed fields in brain.yaml or the package's use() configuration`);this.name="PluginConfigValidationError",this.pluginId=e,this.issues=t}}var vhe=a.object({toolName:a.string(),args:a.unknown(),progressToken:a.union([a.string(),a.number()]).optional(),hasProgress:a.boolean().optional(),interfaceType:a.string(),actor:Yi,displayName:a.string().optional(),conversationId:a.string().optional(),channelId:a.string().optional(),channelName:a.string().optional(),runId:a.string().optional(),toolCallId:a.string().optional(),userPermissionLevel:a.enum(["admin","trusted","public"]).optional(),isAnchor:a.boolean().optional(),signal:a.custom((e)=>e instanceof AbortSignal).optional()}),The=a.object({resourceUri:a.string()});class iu{id;version;description;packageName;config;context;get logger(){return this.context?.logger??Fo.createFresh({context:this.id})}constructor(e,t,n,r){this.id=e,this.packageName=t.name,this.version=t.version,this.description=t.description??`${t.name} plugin`;let o=r.safeParse(n);if(!o.success)throw new Ag(e,o.error.issues.map((i)=>({path:i.path.map(String).join("."),code:i.code,message:i.message})));this.config=o.data}setupMessageHandlers(e){e.messaging.subscribe(Og.toolExecute(this.id),async(t)=>{try{let n=vhe.safeParse(t.payload);if(!n.success)return{success:!1,error:"Invalid tool execution request format"};let{toolName:r,args:o,progressToken:i,hasProgress:s,interfaceType:c,actor:l,displayName:u,conversationId:d,channelId:m,channelName:g,runId:h,toolCallId:x,userPermissionLevel:v,isAnchor:E,signal:H}=n.data,Q=(await this.getTools()).find((de)=>de.name===r);if(!Q)return{success:!1,error:`Tool not found: ${r}`};let ue={interfaceType:c,actor:l,...u&&{displayName:u},...d&&{conversationId:d},...m&&{channelId:m},...g&&{channelName:g},...h&&{runId:h},...x&&{toolCallId:x},...v&&{userPermissionLevel:v},...E!==void 0&&{isAnchor:E},...H&&{signal:H},...s&&i!==void 0&&{progressToken:i,sendProgress:async(de)=>{await e.messaging.send({type:Og.progress(this.id),payload:{progressToken:i,notification:de}})}}};return{success:!0,data:await Q.handler(o,ue)}}catch(n){return this.logger.error("Tool execution error",n),{success:!1,error:qe(n)}}}),e.messaging.subscribe(Og.resourceGet(this.id),async(t)=>{try{let n=The.safeParse(t.payload);if(!n.success)return{success:!1,error:"Invalid resource get request format"};let{resourceUri:r}=n.data,i=(await this.getResources()).find((c)=>c.uri===r);if(!i)return{success:!1,error:`Resource not found: ${r}`};return{success:!0,data:await i.handler()}}catch(n){return this.logger.error("Resource fetch error",n),{success:!1,error:qe(n)}}})}async onRegister(e){}async onRegistrationComplete(e){}async finalizeRegistration(){await this.onRegistrationComplete(this.getContext())}async onReady(e){}async ready(){await this.onReady(this.getContext())}async getCapabilities(){let e=await this.getInstructions();return{tools:await this.getTools(),resources:await this.getResources(),...e&&{instructions:e}}}async getTools(){return[]}async getResources(){return[]}async getInstructions(){return}async shutdown(){await this.onShutdown()}async onShutdown(){}getContext(){if(!this.context)throw Error(`Plugin ${this.id}: Plugin not registered yet`);return this.context}determineUserPermissionLevel(e){return"public"}createProgressBridge(e){if(!e)return;let t=this.context;if(!t)return;let n=this.id;return fa.from(async(r)=>{await t.messaging.send({type:Og.progress(n),payload:{progressToken:e,notification:{progress:r.progress,total:r.total,message:r.message}}})})}}var ZV=a.object({id:a.string(),template:a.string(),content:a.unknown().optional(),dataQuery:a.looseObject({entityType:a.string().optional(),template:a.string().optional(),query:a.looseObject({id:a.string().optional(),limit:a.number().optional(),offset:a.number().optional()}).optional()}).optional(),order:a.number().optional()}),UA=["primary","secondary"],VV=a.object({show:a.boolean().default(!1),label:a.string().optional(),slot:a.enum(UA).default("primary"),priority:a.number().min(0).max(100).default(50)}).optional(),WA=a.object({id:a.string(),path:a.string(),title:a.string().default(""),pageLabel:a.string().optional(),description:a.string().default(""),sections:a.array(ZV).default([]),layout:a.string().default("default"),fullscreen:a.boolean().optional(),pluginId:a.string().optional(),sourceEntityType:a.string().optional(),external:a.boolean().optional(),navigation:VV}),GV=a.object({routes:a.array(WA),pluginId:a.string()}),QV=a.object({paths:a.array(a.string()).optional(),pluginId:a.string().optional()}),KV=a.object({pluginId:a.string().optional()}),YV=a.object({path:a.string()}),pv=a.object({label:a.string(),href:a.string(),priority:a.number()});var Che="site:metadata:get",Ehe="site:metadata:updated",HA=a.object({heading:a.string().describe("Main CTA heading text"),buttonText:a.string().describe("Call-to-action button text"),buttonLink:a.string().describe("URL or anchor for the CTA button")}),XV=a.object({blurb:a.string().optional().describe("Short italic subtitle under the section title")}),dv=a.object({represents:a.enum(["brain","anchor"]).default("anchor").describe("Identity represented by the site"),title:a.string().describe("The site's title"),description:a.string().describe("The site's description"),url:a.string().optional().describe("Canonical site URL"),copyright:a.string().optional().describe("Copyright notice text"),logo:a.boolean().optional().describe("Whether to display logo instead of title text in header"),themeMode:a.enum(["light","dark"]).optional().describe("Default theme mode"),analyticsScript:a.string().optional().describe("Analytics script HTML"),cta:HA.optional().describe("Call-to-action configuration"),sections:a.record(a.string(),XV).optional().describe("Optional per-section blurbs, keyed by section id (e.g. 'essays', 'presentations', 'about'). Used by homepage templates that render editorial section headers.")});var whe=a.object({platform:a.enum(["github","instagram","linkedin","email","website"]).describe("Social media platform"),url:a.string().describe("Profile or contact URL"),label:a.string().optional().describe("Optional display label")}),Ihe=dv.extend({copyright:a.string(),navigation:a.object({primary:a.array(pv),secondary:a.array(pv)}),socialLinks:a.array(whe).optional().describe("Social media links from profile metadata")});function Dg(e,t){return t?e.nullable().default(null):e}function ZA(e){switch(e.type){case"string":return Dg(a.string(),e.optional);case"number":return Dg(a.number(),e.optional);case"enum":return Dg(a.enum(e.options),e.optional);case"object":{let t={};for(let[n,r]of Object.entries(e.fields))t[n]=ZA(r);return Dg(a.object(t),e.optional)}case"array":{let t=a.array(Rhe(e));if(e.minItems!==void 0)t=t.min(e.minItems);if(e.length!==void 0)t=t.length(e.length);return Dg(t,e.optional)}}}function Rhe(e){let{items:t}=e;switch(t.type){case"string":return a.string();case"number":return a.number();case"enum":return a.enum(t.options);case"object":{let n={};for(let[r,o]of Object.entries(t.fields))n[r]=ZA(o);return a.object(n)}}}function JA(e,t){switch(t.type){case"string":case"enum":return{key:e,label:t.label,type:"string"};case"number":return{key:e,label:t.label,type:"number"};case"object":return{key:e,label:t.label,type:"object",children:Object.entries(t.fields).map(([n,r])=>JA(n,r))};case"array":{let n={key:e,label:t.label,type:"array"};switch(t.items.type){case"string":case"enum":return n.itemType="string",n;case"number":return n.itemType="number",n;case"object":return n.itemType="object",n.itemMappings=Object.entries(t.items.fields).map(([r,o])=>JA(r,o)),n}}}}function eG(e,t){let n={};for(let[i,s]of Object.entries(t.fields))n[i]=ZA(s);let r=a.object(n),o=new ld(r,{title:t.title,mappings:Object.entries(t.fields).map(([i,s])=>JA(i,s))});return{name:e,description:t.description,schema:r,formatter:o,requiredPermission:t.requiredPermission??"public",layout:{component:t.layout,...t.fullscreen!==void 0?{fullscreen:t.fullscreen}:{}},...t.runtimeScripts?{runtimeScripts:t.runtimeScripts}:{}}}function khe(e){let t={};for(let[n,r]of Object.entries(e.sections))t[n]=eG(n,r);return t}var Phe=dv.omit({url:!0,analyticsScript:!0}),tG=Phe.extend({title:a.string().optional().describe("Optional site title override"),description:a.string().optional().describe("Optional site description override")});function nG(e){return tG.parse(Mg(e).frontmatter)}async function Ahe(e){let n=(await e.listEntities({entityType:"site-info",options:{limit:1}}))[0];if(!n)throw Error("Site info not found \u2014 create a site-info entity");return nG(n.content)}function VA(e,t={}){let n=rG(e),r=rG(t.sharedDomain??"rizom.ai").replace(/^\./,""),o=`.${r}`;if(n.endsWith(o)){let i=n.slice(0,-o.length);if(i.length>0&&!i.includes("."))return`${i}-preview.${r}`}return`preview.${n}`}function rG(e){return e.trim().replace(/^https?:\/\//i,"").replace(/\/$/,"").toLowerCase()}class ud{static instance=null;entityDisplay;constructor(){}static getInstance(){return ud.instance??=new ud,ud.instance}configure(e){this.entityDisplay=e}static resetInstance(){ud.instance=null}hasRoute(e){return this.entityDisplay?.[e]!==void 0}generateUrl(e,t){let n=this.entityDisplay?.[e];if(n)return`/${n.pluralName??n.label.toLowerCase()+"s"}/${t}`;return`/${PT(e)}/${t}`}}var iG=["primary","secondary"];var Ohe=a.custom((e)=>typeof e==="function","Expected a React component"),Dhe=a.strictObject({show:a.boolean().optional(),label:a.string().min(1).optional(),slot:a.enum(iG).optional(),priority:a.number().optional()}),Mhe=a.strictObject({id:a.string().min(1),template:a.string().min(1),content:a.unknown().optional(),dataQuery:a.looseObject({entityType:a.string().optional(),template:a.string().optional(),query:a.record(a.string(),a.unknown()).optional()}).optional(),order:a.number().optional()}),_he=a.strictObject({id:a.string().min(1),path:a.string().startsWith("/"),title:a.string().optional(),pageLabel:a.string().optional(),description:a.string().optional(),sections:a.array(Mhe).optional(),layout:a.string().min(1).optional(),fullscreen:a.boolean().optional(),pluginId:a.string().optional(),sourceEntityType:a.string().optional(),external:a.boolean().optional(),navigation:Dhe.optional()}),Nhe=a.strictObject({label:a.string().min(1),pluralName:a.string().min(1).optional(),layout:a.string().min(1).optional(),paginate:a.boolean().optional(),pageSize:a.number().int().positive().optional(),navigation:a.strictObject({show:a.boolean().optional(),slot:a.enum(iG).optional(),priority:a.number().optional()}).optional()}),Fhe=a.strictObject({schema:a.custom((e)=>e instanceof a.ZodType,"Expected a Zod schema"),component:a.custom((e)=>typeof e==="function","Expected a React component"),title:a.string().min(1),description:a.string(),requiredPermission:a.enum(["admin","trusted","public"]).optional(),fullscreen:a.boolean().optional()}),oG=a.strictObject({namespace:a.string().min(1),sections:a.record(a.string(),Fhe)}),zhe=a.record(a.string(),a.json()),jhe=a.record(a.string(),a.record(a.string(),zhe)),sG={layouts:a.record(a.string(),Ohe).refine((e)=>typeof e.default==="function",{message:'Site layouts must include a "default" component'}),routes:a.array(_he),content:jhe.optional(),sections:a.union([oG,a.array(oG)]).optional(),themeOverride:a.string().optional(),headScripts:a.array(a.string()).optional(),entityDisplay:a.record(a.string(),Nhe),staticAssets:a.record(a.string(),a.string()).optional()},HWe=a.strictObject(sG).partial();var aG=a.strictObject(sG).superRefine((e,t)=>{let n=new Set;for(let[i,s]of e.routes.entries()){if(n.has(s.id))t.addIssue({code:"custom",path:["routes",i,"id"],message:`Duplicate route id "${s.id}"`});n.add(s.id);let c=s.layout??"default";if(!e.layouts[c])t.addIssue({code:"custom",path:["routes",i,"layout"],message:`Unknown layout "${c}"`})}let r=Array.isArray(e.sections)?e.sections:e.sections?[e.sections]:[],o=new Map(r.map((i)=>[i.namespace,i]));if(o.size!==r.length)t.addIssue({code:"custom",path:["sections"],message:"Section group namespaces must be unique"});for(let[i,s]of Object.entries(e.content??{})){let c=o.get(i);if(!c){t.addIssue({code:"custom",path:["content",i],message:`Content namespace "${i}" has no section group`});continue}for(let[l,u]of Object.entries(s)){let d=c.sections[l];if(!d){t.addIssue({code:"custom",path:["content",i,l],message:`Content section "${i}.${l}" is not defined`});continue}let m=d.schema.safeParse(u);if(!m.success)t.addIssue({code:"custom",path:["content",i,l],message:`Content does not satisfy the "${i}.${l}" schema: ${a.prettifyError(m.error)}`})}}});var Bhe=a.string(),Lhe=a.custom((e)=>{if(!jo(e))return!1;let{plugin:t,...n}=e;if(t!==void 0&&typeof t!=="function")return!1;return aG.safeParse(n).success});var GA=a.enum(["file_operations","content_operations","data_processing","batch_processing"]),qhe=a.looseObject({pluginId:a.string().optional(),progressToken:a.union([a.string(),a.number()]).optional(),operationType:GA,operationTarget:a.string().optional(),interfaceType:a.string().optional(),conversationId:a.string().optional(),channelId:a.string().optional(),requestedByActor:Yi.optional(),requestedByUserId:a.string().optional(),requestedByInterface:a.string().optional(),silent:a.boolean().optional(),provenance:es.optional()}),su=a.looseObject({pluginId:a.string().optional(),progressToken:a.union([a.string(),a.number()]).optional(),operationType:GA,operationTarget:a.string().optional(),interfaceType:a.string().optional(),conversationId:a.string().optional(),channelId:a.string().optional(),requestedByActor:Yi.optional(),requestedByUserId:a.string().optional(),requestedByInterface:a.string().optional(),silent:a.boolean().optional(),provenance:es.optional(),rootJobId:a.string()}),d1e=a.enum(["none","skip","replace","coalesce"]);var $he=a.object({id:a.string(),type:a.string(),data:a.string(),status:a.enum(["pending","processing","completed","failed"]),source:a.string().nullable(),priority:a.number(),retryCount:a.number(),maxRetries:a.number(),lastError:a.string().nullable(),createdAt:a.number(),scheduledFor:a.number(),startedAt:a.number().nullable(),completedAt:a.number().nullable(),attemptId:a.string().nullable(),workerSlotId:a.string().nullable(),workerSessionId:a.string().nullable(),leaseExpiresAt:a.number().nullable(),attemptHeartbeatAt:a.number().nullable(),runtimeUpdatedAt:a.number().nullable(),metadata:su,progress:a.custom((e)=>typeof e==="object"&&e!==null&&("progress"in e)&&typeof e.progress==="number").nullable(),result:a.unknown().nullable().optional()}),ga=15000;var QA=a.enum(["pending","processing","completed","failed"]),cG=a.enum(["completed","failed"]),xe={PENDING:"pending",PROCESSING:"processing",COMPLETED:"completed",FAILED:"failed"},Uhe=a.object({id:a.string(),type:a.string(),status:QA,data:a.unknown(),result:a.unknown().optional(),lastError:a.string().optional().nullable(),attempts:a.number(),maxRetries:a.number(),priority:a.number(),createdAt:a.date(),updatedAt:a.date(),processedAt:a.date().optional().nullable(),completedAt:a.date().optional().nullable(),failedAt:a.date().optional().nullable()}),Whe=a.object({jobId:a.string(),type:a.string(),status:cG,result:a.unknown().optional(),error:a.string().optional()}),KA=a.object({success:a.literal(!1),error:a.string().optional()}),mv=a.object({id:a.string(),type:a.enum(["job","batch"]),status:QA,message:a.string().optional(),progress:a.object({current:a.number(),total:a.number(),percentage:a.number()}).optional(),aggregationKey:a.string().optional(),batchDetails:a.object({totalOperations:a.number(),completedOperations:a.number(),failedOperations:a.number(),currentOperation:a.string().optional(),errors:a.array(a.string()).optional()}).optional(),jobDetails:a.object({jobType:a.string(),priority:a.number(),retryCount:a.number()}).optional(),metadata:su});var P=wt("job_queue",{id:W("id").primaryKey().$defaultFn(()=>gt()),type:W("type").notNull(),data:W("data").notNull(),result:W("result",{mode:"json"}),progress:W("progress",{mode:"json"}).$type(),source:W("source"),metadata:W("metadata",{mode:"json"}).$type().notNull(),status:W("status",{enum:["pending","processing","completed","failed"]}).notNull().default("pending"),priority:Re("priority").notNull().default(0),retryCount:Re("retryCount").notNull().default(0),maxRetries:Re("maxRetries").notNull().default(3),lastError:W("lastError"),createdAt:Re("createdAt").notNull().$defaultFn(()=>Date.now()),scheduledFor:Re("scheduledFor").notNull().$defaultFn(()=>Date.now()),startedAt:Re("startedAt"),completedAt:Re("completedAt"),attemptId:W("attemptId"),workerSlotId:W("workerSlotId"),workerSessionId:W("workerSessionId"),leaseExpiresAt:Re("leaseExpiresAt"),attemptHeartbeatAt:Re("attemptHeartbeatAt"),runtimeUpdatedAt:Re("runtimeUpdatedAt")},(e)=>({queueReadyIdx:vt("idx_job_queue_ready").on(e.status,e.priority,e.scheduledFor),jobTypeIdx:vt("idx_job_queue_type").on(e.type,e.status),runtimeUpdatesIdx:vt("idx_job_queue_runtime_updates").on(e.runtimeUpdatedAt,e.id),jobSourceIdx:vt("idx_job_queue_source").on(e.source)})),tt=wt("job_worker_sessions",{slotId:W("slotId").primaryKey(),sessionId:W("sessionId").notNull().unique(),startedAt:Re("startedAt").notNull(),heartbeatAt:Re("heartbeatAt").notNull(),expiresAt:Re("expiresAt").notNull().default(0)},(e)=>({heartbeatIdx:vt("idx_job_worker_sessions_heartbeat").on(e.heartbeatAt),expiresIdx:vt("idx_job_worker_sessions_expires").on(e.expiresAt)}));function lG(e){return ui({url:e.url,schema:{jobQueue:P,jobWorkerSessions:tt},authToken:e.authToken,authTokenEnv:"JOB_QUEUE_DATABASE_AUTH_TOKEN"})}class YA{declarations=new Map;handlers=new Map;validators=new Map;logger;mode;finalizedRegistrations;constructor(e,t){this.logger=e.child("HandlerRegistry"),this.mode=t}registerHandler(e,t,n){if(this.finalizedRegistrations)throw Error("Job handler registrations are finalized");if(this.declarations.has(e))throw Error(`Job handler is already registered for type: ${e}`);if(this.declarations.set(e,{handler:t,pluginId:n}),this.validators.set(e,t),this.mode!=="validation-only")this.handlers.set(e,t);this.logger.debug("Registered job execution declaration",{type:e,pluginId:n,mode:this.mode})}unregisterHandler(e){this.declarations.delete(e),this.handlers.delete(e),this.validators.delete(e),this.logger.debug("Unregistered job handler",{type:e})}unregisterPluginHandlers(e){let t=[...this.declarations.entries()].filter(([,n])=>n.pluginId===e).map(([n])=>n);for(let n of t)this.declarations.delete(n),this.handlers.delete(n),this.validators.delete(n);if(t.length>0)this.logger.debug("Unregistered plugin handlers",{pluginId:e,count:t.length,types:t})}finalizeRegistrations(){return this.finalizedRegistrations??=Object.freeze([...this.declarations.entries()].sort(([e],[t])=>e.localeCompare(t)).map(([e,t])=>Object.freeze({type:e,pluginId:t.pluginId}))),this.finalizedRegistrations}getExecutionRegistrations(){if(!this.finalizedRegistrations)throw Error("Job handler registrations are not finalized");return this.finalizedRegistrations}getRegisteredTypes(){return[...this.handlers.keys()]}getHandler(e){return this.handlers.get(e)}getValidator(e){return this.validators.get(e)}}var Hhe=a.looseObject({deduplicationKey:a.string().optional()});class XA{findDuplicate(e,t,n){if(!t||t==="none")return null;let r=this.filterByDeduplicationKey(e,n).sort((i,s)=>s.createdAt-i.createdAt||s.id.localeCompare(i.id)),o=r.find((i)=>i.status===xe.PENDING)??null;if(t==="skip"||t==="replace")return o;return o??r[0]??null}filterByDeduplicationKey(e,t){if(!t)return e;return e.filter((n)=>{let r=Hhe.safeParse(n.metadata);return r.success&&r.data.deduplicationKey===t})}}var Jhe=2000,Zhe=5,Vhe=40,Ghe=new ZP;class eO{db;transactionClient;databaseUrl;logger;deduplicator=new XA;writeRetryBudgetMs;constructor(e,t,n,r,o){this.db=e,this.transactionClient=t,this.databaseUrl=n,this.logger=r.child("JobQueueRepository"),this.writeRetryBudgetMs=o?.writeRetryBudgetMs??Jhe}async insert(e){await this.db.insert(P).values(e)}async enqueueAtomic(e){return Ghe.run(this.databaseUrl,async()=>{let t=Date.now()+this.writeRetryBudgetMs,n=1;for(;;){let r=await this.acquireWriteTransaction(e,t),o={prepared:!1},i=!1;try{let s=await this.decideEnqueue(r,e,()=>{o.prepared=!0});return i=!0,await r.commit(),s}catch(s){let c=i&&this.isSerializationConflict(s)&&!r.closed,l=!0;if(!r.closed)try{await r.rollback()}catch(u){l=!1,this.logger.error("Failed to roll back atomic enqueue",{type:e.jobData.type,rollbackError:u})}if(o.prepared)e.onInsertRollback?.();if(!c||!l)throw s;await this.waitForConflictRetry("commit",e,t,n,s),n++}finally{r.close()}}})}async decideEnqueue(e,t,n){let{jobData:r,strategy:o,deduplicationKey:i,beforeInsert:s}=t,c=o??"none",l=async()=>{await s?.(),n()},u=async()=>{await l(),await this.insertJob(e,r)};if(c==="none")return await u(),{kind:"inserted",jobId:r.id};let d=await this.getActiveDeduplicationCandidates(e,r.type),m=this.deduplicator.findDuplicate(d,c,i);if(!m)return await u(),{kind:"inserted",jobId:r.id};if(c==="skip")return{kind:"skipped",jobId:m.id};if(c==="coalesce"){if((await e.execute({sql:"UPDATE `job_queue` SET `scheduledFor` = ? WHERE `id` = ? AND `status` = ?",args:[Date.now(),m.id,m.status]})).rowsAffected!==1)throw Error(`Atomic coalesce lost selected job ${m.id}`);return{kind:"coalesced",jobId:m.id}}await l();let g=Date.now();if((await e.execute({sql:"UPDATE `job_queue`\n SET `status` = ?,\n `lastError` = ?,\n `completedAt` = ?,\n `runtimeUpdatedAt` = max(?, coalesce((SELECT max(`runtimeUpdatedAt`) FROM `job_queue`), 0) + 1)\n WHERE `id` = ? AND `status` = ?",args:[xe.FAILED,"Replaced by newer job",g,g,m.id,xe.PENDING]})).rowsAffected!==1)throw Error(`Atomic replace lost selected job ${m.id}`);return await this.insertJob(e,r),{kind:"replaced",jobId:r.id,replacedJobId:m.id}}async getActiveDeduplicationCandidates(e,t){return(await e.execute({sql:"SELECT `id`, `status`, `createdAt`, `metadata`\n FROM `job_queue`\n WHERE `type` = ? AND `status` IN (?, ?)",args:[t,xe.PENDING,xe.PROCESSING]})).rows.map((r)=>this.parseDeduplicationCandidate(r))}parseDeduplicationCandidate(e){let{id:t,status:n,createdAt:r,metadata:o}=e;if(typeof t!=="string"||n!==xe.PENDING&&n!==xe.PROCESSING||typeof r!=="number"&&typeof r!=="bigint"||typeof o!=="string")throw Error("Invalid active job row returned during atomic enqueue");let i=JSON.parse(o);return{id:t,status:n,createdAt:Number(r),metadata:i}}async insertJob(e,t){if((await e.execute({sql:"INSERT INTO `job_queue` (\n `id`, `type`, `data`, `result`, `source`, `metadata`,\n `status`, `priority`, `retryCount`, `maxRetries`,\n `lastError`, `createdAt`, `scheduledFor`, `startedAt`,\n `completedAt`\n ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",args:[t.id,t.type,t.data,this.serializeJson(t.result),t.source,JSON.stringify(t.metadata),t.status,t.priority,t.retryCount,t.maxRetries,t.lastError,t.createdAt,t.scheduledFor,t.startedAt,t.completedAt]})).rowsAffected!==1)throw Error(`Atomic enqueue did not insert job ${t.id}`)}serializeJson(e){if(e===void 0||e===null)return null;return JSON.stringify(e)}acquireWriteTransaction(e,t){return this.retryOnConflict("acquire",e,()=>this.transactionClient.transaction("write"),(n)=>this.isSerializationConflict(n),t)}async waitForConflictRetry(e,t,n,r,o){let i=Math.min(Zhe*2**(r-1),Vhe),s=i/2+Math.random()*(i/2);if(Date.now()+s>=n)throw this.transactionConflictError(e,t,r,o);await new Promise((c)=>setTimeout(c,s))}async retryOnConflict(e,t,n,r,o=Date.now()+this.writeRetryBudgetMs,i=1){try{return await n()}catch(s){if(!r(s))throw s;return await this.waitForConflictRetry(e,t,o,i,s),this.retryOnConflict(e,t,n,r,o,i+1)}}transactionConflictError(e,t,n,r){let o=t.strategy??"none",i=t.deduplicationKey?"present":"absent";return Error(`Failed to ${e} atomic enqueue transaction for type "${t.jobData.type}" within ${this.writeRetryBudgetMs}ms after ${n} attempts (strategy: ${o}, key: ${i})`,{cause:r})}isSerializationConflict(e){for(let t=e;t!==void 0;){let n=typeof t==="object"&&t!==null&&"code"in t?String(t.code):"",r=qe(t,"");if(/SQLITE_(?:BUSY|LOCKED)/u.test(n)||/SQLITE_(?:BUSY|LOCKED)|database is locked|transaction (?:busy|conflict)/iu.test(r))return!0;t=t instanceof Error?t.cause:void 0}return!1}async startWorkerSession(e,t,n=Date.now(),r=ga){let o=n+r;await this.db.insert(tt).values({slotId:e,sessionId:t,startedAt:n,heartbeatAt:n,expiresAt:o}).onConflictDoUpdate({target:tt.slotId,set:{sessionId:t,startedAt:n,heartbeatAt:n,expiresAt:o}})}async heartbeatWorkerSession(e,t,n=Date.now(),r=ga){return(await this.db.update(tt).set({heartbeatAt:n,expiresAt:n+r}).where(ee(C(tt.slotId,e),C(tt.sessionId,t))).returning({slotId:tt.slotId})).length===1}async endWorkerSession(e,t){return(await this.db.delete(tt).where(ee(C(tt.slotId,e),C(tt.sessionId,t))).returning({slotId:tt.slotId})).length===1}async complete(e,t,n){let r=Date.now(),i=(await this.db.update(P).set({status:xe.COMPLETED,result:t,lastError:null,completedAt:r,runtimeUpdatedAt:this.nextRuntimeUpdatedAt(r)}).where(this.attemptWriteGuard(e,n)).returning({id:P.id})).length===1;if(i)this.logger.debug("Job completed",{jobId:e,hasResult:t!==void 0});return i}async update(e,t,n){let o=(await this.db.update(P).set({data:JSON.stringify(t)}).where(this.attemptWriteGuard(e,n)).returning({id:P.id})).length===1;if(o)this.logger.debug("Job data updated",{jobId:e});return o}async recordAttemptProgress(e,t,n,r=Date.now()){return(await this.db.update(P).set({attemptHeartbeatAt:r,runtimeUpdatedAt:this.nextRuntimeUpdatedAt(r),progress:n}).where(this.attemptWriteGuard(e,t)).returning({id:P.id})).length===1}async renewAttemptLease(e,t,n,r){return(await this.db.update(P).set({attemptHeartbeatAt:n,leaseExpiresAt:n+r}).where(this.attemptWriteGuard(e,t)).returning({id:P.id})).length===1}async fail(e,t,n,r=Date.now()){let i=(await this.db.select({retryCount:P.retryCount,maxRetries:P.maxRetries,type:P.type,scheduledFor:P.scheduledFor,startedAt:P.startedAt,runtimeUpdatedAt:P.runtimeUpdatedAt}).from(P).where(this.attemptWriteGuard(e,n)).limit(1))[0];if(!i)return!1;let s=i.retryCount<i.maxRetries,c=s?i.retryCount+1:i.retryCount,l=Math.min(1000*2**i.retryCount,60000),u=s?r+l:i.scheduledFor;if((await this.db.update(P).set({status:s?xe.PENDING:xe.FAILED,retryCount:c,lastError:t.message,scheduledFor:u,completedAt:s?null:r,runtimeUpdatedAt:s?i.runtimeUpdatedAt:this.nextRuntimeUpdatedAt(r),startedAt:s?null:i.startedAt,attemptId:null,workerSlotId:null,workerSessionId:null,leaseExpiresAt:null,attemptHeartbeatAt:null}).where(ee(this.attemptWriteGuard(e,n),C(P.retryCount,i.retryCount))).returning({id:P.id})).length!==1)return!1;if(s)this.logger.debug("Job scheduled for retry",{jobId:e,retryCount:c,backoffMs:l,scheduledFor:new Date(u).toISOString()});else this.logger.error("Job failed after max retries",{jobId:e,type:i.type,retryCount:i.retryCount,error:t.message});return!0}async retireUnownedActiveJob(e){let t=e.reason.trim();if(t.length===0)throw Error("Retired job reason must not be empty");let r=(await this.db.update(P).set({status:xe.FAILED,lastError:t,completedAt:e.now,runtimeUpdatedAt:this.nextRuntimeUpdatedAt(e.now)}).where(ee(C(P.id,e.jobId),C(P.type,e.expectedType),Sr(C(P.status,xe.PENDING),C(P.status,xe.PROCESSING)),Hn(P.attemptId),Hn(P.workerSlotId),Hn(P.workerSessionId),Hn(P.leaseExpiresAt),Hn(P.attemptHeartbeatAt),Hn(P.progress),Hn(P.result))).returning())[0]??null;if(r)this.logger.warn("Retired unowned legacy job",{jobId:r.id,type:r.type,reason:t});return r}async getStatus(e){return(await this.db.select().from(P).where(C(P.id,e)).limit(1))[0]??null}async getJobsByRootJobId(e){return this.db.select().from(P).where(b`json_extract(${P.metadata}, '$.rootJobId') = ${e}`).orderBy(lt(P.createdAt),lt(P.id))}async getStatusByEntityId(e){return(await this.db.select().from(P).where(b`json_extract(${P.data}, '$.id') = ${e}`).orderBy(un(P.createdAt)).limit(1))[0]??null}async getStats(){let e=await this.db.select({status:P.status,count:b`count(*)`}).from(P).groupBy(P.status),t={pending:0,processing:0,failed:0,completed:0,total:0};for(let n of e){let r=Number(n.count);t[n.status]=r,t.total+=r}return t}async getDiagnostics(e=Date.now()){let[t,n,r]=await Promise.all([this.db.select({type:P.type,status:P.status,count:b`count(*)`}).from(P).groupBy(P.type,P.status),this.db.select({oldestPendingAt:b`min(case when ${P.status} = ${xe.PENDING} then ${P.createdAt} end)`,duePending:b`coalesce(sum(case when ${P.status} = ${xe.PENDING} and ${P.scheduledFor} <= ${e} then 1 else 0 end), 0)`,oldestDuePendingAt:b`min(case when ${P.status} = ${xe.PENDING} and ${P.scheduledFor} <= ${e} then ${P.scheduledFor} end)`,latestClaimAt:b`max(${P.startedAt})`,oldestProcessingAt:b`min(case when ${P.status} = ${xe.PROCESSING} then ${P.startedAt} end)`,staleLeaseCount:b`coalesce(sum(case when ${P.status} = ${xe.PROCESSING} and ${P.leaseExpiresAt} is not null and ${P.leaseExpiresAt} <= ${e} then 1 else 0 end), 0)`}).from(P),this.db.select({total:b`count(*)`,active:b`coalesce(sum(case when ${tt.expiresAt} > ${e} then 1 else 0 end), 0)`,stale:b`coalesce(sum(case when ${tt.expiresAt} <= ${e} then 1 else 0 end), 0)`,latestHeartbeatAt:b`max(${tt.heartbeatAt})`}).from(tt)]),o={pending:0,processing:0,completed:0,failed:0},i=t.map((u)=>{let d=Number(u.count);return o[u.status]+=d,{type:u.type,status:u.status,count:d}}),s=n[0],c=r[0],l=(u)=>u===null||u===void 0?null:Math.max(0,e-Number(u));return{totals:o,byType:i,oldestPendingAgeMs:l(s?.oldestPendingAt),duePending:Number(s?.duePending??0),oldestDuePendingAgeMs:l(s?.oldestDuePendingAt),latestClaimAgeMs:l(s?.latestClaimAt),oldestProcessingAgeMs:l(s?.oldestProcessingAt),staleLeaseCount:Number(s?.staleLeaseCount??0),workerSessions:{total:Number(c?.total??0),active:Number(c?.active??0),stale:Number(c?.stale??0),latestHeartbeatAgeMs:l(c?.latestHeartbeatAt)}}}async getRuntimeUpdates(e,t){return(await this.db.select().from(P).where(b`(${P.runtimeUpdatedAt}, ${P.id}) > (${e.updatedAt}, ${e.jobId})`).orderBy(lt(P.runtimeUpdatedAt),lt(P.id)).limit(t)).map((r)=>({job:r,cursor:{updatedAt:r.runtimeUpdatedAt??0,jobId:r.id}}))}async cleanup(e){let t=Date.now()-e;return(await this.db.delete(P).where(ee(Sr(C(P.status,xe.COMPLETED),C(P.status,xe.FAILED)),vr(P.completedAt,t)))).rowsAffected}async getActiveJobs(e){let t=Sr(C(P.status,xe.PENDING),C(P.status,xe.PROCESSING)),n=e&&e.length>0?ee(t,Et(P.type,e)):t;return this.db.select().from(P).where(n).orderBy(un(P.createdAt))}async getRecentJobs(e,t=20){let n=e&&e.length>0?Et(P.type,e):void 0;return this.db.select().from(P).where(n).orderBy(un(P.createdAt)).limit(t)}async getFailedJobs(e){let t=C(P.status,xe.FAILED),n=e&&e.length>0?ee(t,Et(P.type,e)):t;return this.db.select().from(P).where(n).orderBy(un(P.createdAt))}async claimNextReady(e){let{now:t,attemptId:n,workerSlotId:r,workerSessionId:o,leaseDurationMs:i,executableTypes:s}=e,c=this.db.select({slotId:tt.slotId}).from(tt).where(ee(C(tt.slotId,r),C(tt.sessionId,o),Gp(tt.expiresAt,t))),l=this.db.select({slotId:tt.slotId}).from(tt).where(ee(C(tt.slotId,P.workerSlotId),C(tt.sessionId,P.workerSessionId))),u=this.db.select({slotId:tt.slotId}).from(tt).where(ee(C(tt.slotId,P.workerSlotId),C(tt.sessionId,P.workerSessionId),vr(tt.expiresAt,t))),d=ee(C(P.status,xe.PROCESSING),Sr(Hn(P.attemptId),LS(l),ee(vr(P.leaseExpiresAt,t),Ic(u)))),m=b`${P.status} = ${xe.PROCESSING} AND ${P.retryCount} + 1 > ${P.maxRetries}`,g=this.db.select({id:P.id}).from(P).where(ee(Et(P.type,s),Sr(ee(C(P.status,xe.PENDING),vr(P.scheduledFor,t)),d))).orderBy(lt(P.priority),lt(P.createdAt)).limit(1),x=(await this.db.update(P).set({status:b`CASE WHEN ${m} THEN ${xe.FAILED} ELSE ${xe.PROCESSING} END`,retryCount:b`CASE WHEN ${P.status} = ${xe.PROCESSING} THEN ${P.retryCount} + 1 ELSE ${P.retryCount} END`,lastError:b`CASE WHEN ${P.status} = ${xe.PROCESSING} THEN 'Attempt lease expired' ELSE ${P.lastError} END`,startedAt:b`CASE WHEN ${m} THEN ${P.startedAt} ELSE ${t} END`,completedAt:b`CASE WHEN ${m} THEN ${t} ELSE NULL END`,attemptId:b`CASE WHEN ${m} THEN ${P.attemptId} ELSE ${n} END`,workerSlotId:b`CASE WHEN ${m} THEN ${P.workerSlotId} ELSE ${r} END`,workerSessionId:b`CASE WHEN ${m} THEN ${P.workerSessionId} ELSE ${o} END`,leaseExpiresAt:b`CASE WHEN ${m} THEN ${P.leaseExpiresAt} ELSE ${t+i} END`,attemptHeartbeatAt:b`CASE WHEN ${m} THEN ${P.attemptHeartbeatAt} ELSE ${t} END`,runtimeUpdatedAt:b`CASE WHEN ${m} THEN ${this.nextRuntimeUpdatedAt(t)} ELSE ${P.runtimeUpdatedAt} END`}).where(ee(Et(P.id,g),Ic(c))).returning())[0];if(x?.status!==xe.PROCESSING)return null;return this.logger.debug("Job claimed",{jobId:x.id,attemptId:x.attemptId,workerSlotId:r,workerSessionId:o}),x}nextRuntimeUpdatedAt(e){return b`max(${e}, coalesce((select max(${P.runtimeUpdatedAt}) from ${P}), 0) + 1)`}attemptWriteGuard(e,t){return t?ee(C(P.id,e),C(P.status,xe.PROCESSING),C(P.attemptId,t)):ee(C(P.id,e),Hn(P.attemptId),Sr(C(P.status,xe.PENDING),C(P.status,xe.PROCESSING)))}}import{AsyncLocalStorage as Qhe}from"async_hooks";class _c{storage=new Qhe;static createFresh(){return new _c}constructor(){}current(){return this.storage.getStore()}run(e,t,n){if(t.length===0)throw Error("Operation ID must not be empty");let r=es.parse(e),o=Khe(r);return this.storage.run(Object.freeze({provenance:o,operationId:t}),n)}}function Khe(e){if(Object.freeze(e.projectionLineage),e.sourceEntity)Object.freeze(e.sourceEntity);return Object.freeze(e)}class tO{client;logger;handlerRegistry;repository;walInitialization=null;walInitializationSettled=!1;closeRequested=!1;clientClosed=!1;inFlightEnqueues=0;databaseUrl;operationContext;projectionAdmission;directWorkerSlotId=`direct:${gt()}`;directWorkerSessionId=gt();directLeaseDurationMs;directSessionStart=null;close(){this.closeRequested=!0,this.closeClientWhenReady()}static createFresh(e,t,n){return new tO(e,t??Fo.getInstance(),n)}constructor(e,t,n){let{db:r,client:o,url:i}=lG(e);this.client=o,this.databaseUrl=i,this.logger=t.child("JobQueueService"),this.operationContext=n?.operationContext??_c.createFresh(),this.projectionAdmission=n?.projectionAdmission,this.handlerRegistry=new YA(this.logger,n?.handlerRegistrationMode??"combined"),this.repository=new eO(r,o,i,this.logger),this.directLeaseDurationMs=e.claimTimeoutMs??300000}initialize(){if(this.closeRequested)return Promise.resolve();return this.walInitialization??=this.initializeWALMode(),this.walInitialization}async initializeWALMode(){try{await pi(this.client,this.databaseUrl)}catch(e){this.logger.warn("Failed to enable WAL mode (non-fatal)",e)}finally{this.walInitializationSettled=!0,this.closeClientWhenReady()}}closeClientWhenReady(){if(!this.closeRequested||this.inFlightEnqueues>0||this.walInitialization!==null&&!this.walInitializationSettled)return;this.closeClient()}closeClient(){if(this.clientClosed)return;this.clientClosed=!0,this.client.close()}registerHandler(e,t,n){this.handlerRegistry.registerHandler(e,t,n)}unregisterHandler(e){this.handlerRegistry.unregisterHandler(e)}unregisterPluginHandlers(e){this.handlerRegistry.unregisterPluginHandlers(e)}getRegisteredTypes(){return this.handlerRegistry.getRegisteredTypes()}getHandler(e){return this.handlerRegistry.getHandler(e)}getValidator(e){return this.handlerRegistry.getValidator(e)}finalizeHandlerRegistrations(){return this.handlerRegistry.finalizeRegistrations()}getExecutionRegistrations(){return this.handlerRegistry.getExecutionRegistrations()}async enqueue(e){if(this.closeRequested)throw Error("Cannot enqueue a job after the queue service is closed");this.inFlightEnqueues++;try{return await this.enqueueValidated(e)}finally{this.inFlightEnqueues--,this.closeClientWhenReady()}}async enqueueValidated(e){let{type:t,data:n,options:r}=e,o=this.handlerRegistry.getValidator(t);if(!o)throw Error(`No job type declared: ${t}`);let i=o.validateAndParse(n);if(i===null)throw Error(`Invalid job data for type: ${t}`);let s=Date.now(),c=gt(),l=r?.rootJobId??this.operationContext.current()?.provenance.rootJobId??c,u=this.createJobProvenance(c,l,r),d=r?.metadata??{operationType:"data_processing"},{provenance:m,...g}=d,h={id:c,type:t,data:JSON.stringify(i),status:xe.PENDING,priority:r?.priority??0,maxRetries:r?.maxRetries??3,retryCount:0,source:r?.source??null,metadata:{...g,...r?.deduplicationKey&&{deduplicationKey:r.deduplicationKey},rootJobId:l,provenance:u},createdAt:s,scheduledFor:r?.delayMs?s+r.delayMs:s,result:null,lastError:null,startedAt:null,completedAt:null},x,v=()=>{x?.rollback(),x=void 0};try{let E=await this.repository.enqueueAtomic({jobData:h,strategy:r?.deduplication,deduplicationKey:r?.deduplicationKey,beforeInsert:async()=>{x=await this.projectionAdmission?.reserveJobAdmission(u)},onInsertRollback:v});if(x?.commit(),x=void 0,E.kind==="skipped")this.logger.debug("Skipping duplicate job (already pending)",{type:t,existingJobId:E.jobId});else if(E.kind==="coalesced")this.logger.debug("Coalescing with existing job",{type:t,existingJobId:E.jobId});else{if(E.kind==="replaced")this.logger.debug("Replacing duplicate job",{type:t,oldJobId:E.replacedJobId});this.logger.debug("Job enqueued",{id:E.jobId,type:t,priority:h.priority,rootJobId:h.metadata.rootJobId})}return E.jobId}catch(E){throw v(),this.logger.error("Failed to enqueue job",{type:t,error:qe(E)}),E}}createJobProvenance(e,t,n){let r=this.operationContext.current(),o=n?.metadata.provenance??r?.provenance,i=o?.rootJobId===t?o:void 0,s=r?.provenance.rootJobId===t?r.operationId:void 0,c=n?.projection,l=c?[...i?.projectionLineage??[],c.id]:[...i?.projectionLineage??[]],u=c?.id??i?.projectionId;return es.parse({rootJobId:t,causationId:s??i?.causationId??e,...u?{projectionId:u}:{},projectionLineage:l,...c?.sourceEntity?{sourceEntity:c.sourceEntity}:i?.sourceEntity?{sourceEntity:i.sourceEntity}:{},derivationDepth:l.length})}async dequeue(e){let t=this.handlerRegistry.getRegisteredTypes();if(t.length===0)return null;let n=e??await this.getDirectClaimOptions(),r=Date.now(),o=await this.repository.claimNextReady({...n,now:r,attemptId:gt(),executableTypes:t});if(!o)return null;return this.logger.debug("Job dequeued",{id:o.id,type:o.type,priority:o.priority,retryCount:o.retryCount,attemptId:o.attemptId,workerSlotId:o.workerSlotId,workerSessionId:o.workerSessionId}),o}async startWorkerSession(e,t,n=ga){await this.repository.startWorkerSession(e,t,Date.now(),n)}heartbeatWorkerSession(e,t,n=ga){return this.repository.heartbeatWorkerSession(e,t,Date.now(),n)}endWorkerSession(e,t){return this.repository.endWorkerSession(e,t)}renewAttemptLease(e,t,n){return this.repository.renewAttemptLease(e,t,Date.now(),n)}recordAttemptProgress(e,t,n){return this.repository.recordAttemptProgress(e,t,n)}complete(e,t,n){return this.repository.complete(e,t,n)}update(e,t,n){return this.repository.update(e,t,n)}fail(e,t,n){return this.repository.fail(e,t,n)}retireUnownedActiveJob(e){return this.repository.retireUnownedActiveJob(e)}async getDirectClaimOptions(){return this.directSessionStart??=this.repository.startWorkerSession(this.directWorkerSlotId,this.directWorkerSessionId,Date.now(),this.directLeaseDurationMs),await this.directSessionStart,{workerSlotId:this.directWorkerSlotId,workerSessionId:this.directWorkerSessionId,leaseDurationMs:this.directLeaseDurationMs}}async getStatus(e){return this.repository.getStatus(e)}async getJobsByRootJobId(e){return this.repository.getJobsByRootJobId(e)}async getStatusByEntityId(e){return this.repository.getStatusByEntityId(e)}async getStats(){return this.repository.getStats()}getDiagnostics(e){return this.repository.getDiagnostics(e)}async waitForIdle(e={}){let t=e.quietMs??250,n=e.pollIntervalMs??25,r=Date.now()+(e.timeoutMs??30000),o=async(i)=>{e.signal?.throwIfAborted();let{totals:s}=await this.getDiagnostics(),l=s.pending===0&&s.processing===0?i??Date.now():null;if(l!==null&&Date.now()-l>=t)return;if(Date.now()>=r)throw Error(`Timed out waiting for the job queue to settle: ${s.pending} pending, ${s.processing} processing`);return await Bun.sleep(n),o(l)};return o(null)}getRuntimeUpdates(e,t=1000){return this.repository.getRuntimeUpdates(e,t)}async cleanup(e){let t=await this.repository.cleanup(e);if(t>0)this.logger.info("Cleaned up old jobs",{deletedCount:t,olderThanMs:e});return t}async getActiveJobs(e){return this.repository.getActiveJobs(e)}async getRecentJobs(e,t){return this.repository.getRecentJobs(e,t)}async getFailedJobs(e){return this.repository.getFailedJobs(e)}}class uG extends Error{constructor(e,t){super(`Job ${e} exceeded its ${t}ms execution deadline`);this.name="JobDeadlineExceededError"}}class nO{logger;jobQueueService;progressMonitor;config;isRunning=!1;shouldStop=!1;activeJobs=new Set;stats;startTime=0;pollFiber=null;currentPoll=null;workerScope=null;jobFibers=null;activeTransition=null;transitionQueue=[];clock;operationContext;workerSessionId=null;workerHeartbeatStop=null;static createFresh(e,t,n,r,o){return new nO(e,t,n,r,o)}constructor(e,t,n,r,o){if(this.logger=n.child("JobQueueWorker"),this.jobQueueService=e,this.progressMonitor=t,this.clock=o?.clock,this.operationContext=o?.operationContext??_c.createFresh(),this.config={concurrency:r?.concurrency??1,pollInterval:r?.pollInterval??1000,maxJobs:r?.maxJobs??0,autoStart:r?.autoStart??!1,workerSlotId:r?.workerSlotId??process.env.BRAIN_JOB_WORKER_SLOT_ID??"default",defaultExecutionTimeoutMs:r?.defaultExecutionTimeoutMs??300000,cancellationGraceMs:r?.cancellationGraceMs??5000,errorCallbackTimeoutMs:r?.errorCallbackTimeoutMs??1e4,leaseDurationMs:r?.leaseDurationMs??30000,attemptHeartbeatIntervalMs:r?.attemptHeartbeatIntervalMs??1e4,workerHeartbeatIntervalMs:r?.workerHeartbeatIntervalMs??5000,workerSessionTimeoutMs:r?.workerSessionTimeoutMs??ga,onUnhealthy:r?.onUnhealthy??(()=>{return})},this.stats={processedJobs:0,failedJobs:0,activeJobs:0,uptime:0,isRunning:!1,isHealthy:!0},this.logger.debug("JobQueueWorker initialized",{concurrency:this.config.concurrency,pollInterval:this.config.pollInterval,maxJobs:this.config.maxJobs,autoStart:this.config.autoStart}),this.config.autoStart)this.start().catch((i)=>{this.logger.error("Failed to auto-start JobQueueWorker",{error:i})})}start(){return this.requestTransition("start",!0)}async startWorker(){if(this.isRunning){this.logger.warn("Worker is already running");return}this.logger.debug("Starting JobQueueWorker");let e=gt();await this.jobQueueService.startWorkerSession(this.config.workerSlotId,e,this.config.workerSessionTimeoutMs),this.workerSessionId=e,this.isRunning=!0,this.shouldStop=!1,this.startTime=Date.now(),this.stats.isRunning=!0,this.stats.isHealthy=!0,delete this.stats.unhealthyReason,this.startWorkerHeartbeat(),this.workerScope=G.runSync(Bt.make()),this.jobFibers=G.runSync(Bt.extend(xr.make(),this.workerScope)),this.pollFiber=G.runFork(this.runPollingLoop())}stop(){return this.requestTransition("stop",!0)}async stopWorker(e){if(!this.isRunning){this.logger.warn("Worker is not running");return}if(this.logger.debug("Stopping JobQueueWorker"),this.shouldStop=!0,e.awaitInFlightPoll&&this.pollFiber){let n=this.pollFiber;await G.runPromise(Ao.interrupt(n)),this.pollFiber=null}if(e.awaitInFlightPoll&&this.currentPoll)await this.currentPoll,this.currentPoll=null;if(this.jobFibers)this.logger.debug("Waiting for active jobs to complete",{activeJobs:this.activeJobs.size}),await G.runPromise(xr.awaitEmpty(this.jobFibers));await this.closeWorkerScope(),await this.stopWorkerHeartbeat();let t=this.workerSessionId;if(this.workerSessionId=null,t)await this.jobQueueService.endWorkerSession(this.config.workerSlotId,t);this.isRunning=!1,this.stats.isRunning=!1,this.logger.debug("JobQueueWorker stopped")}getStats(){return{...this.stats,activeJobs:this.activeJobs.size,uptime:this.isRunning?Date.now()-this.startTime:0}}isWorkerRunning(){return this.isRunning}isStopRequested(){return this.shouldStop}async processAvailableJobs(){if(!this.isRunning||this.shouldStop)return;try{let e=this.config.concurrency-this.activeJobs.size;if(e<=0)return;if(this.config.maxJobs>0){let n=this.stats.processedJobs+this.stats.failedJobs,r=this.config.maxJobs-n-this.activeJobs.size;if(r<=0){this.logger.debug("Maximum job limit reached, stopping worker",{maxJobs:this.config.maxJobs,processedJobs:this.stats.processedJobs,failedJobs:this.stats.failedJobs}),await this.requestTransition("stop",!1);return}e=Math.min(e,r)}let t=this.jobFibers;if(!t)throw Error("Worker job fiber scope is not available");for(let n=0;n<e;n++){if(this.isStopRequested())break;let r=this.workerSessionId;if(!r)throw Error("Worker session is not available");let o=await this.jobQueueService.dequeue({workerSlotId:this.config.workerSlotId,workerSessionId:r,leaseDurationMs:this.config.leaseDurationMs});if(!o)break;this.activeJobs.add(o.id),await G.runPromise(xr.run(t,o.id,G.promise(()=>this.processJobWrapper(o))))}}catch(e){this.logger.error("Error processing available jobs",{error:e}),this.stats.lastError=qe(e)}}async processJobWrapper(e){let t=e.id;try{this.logger.debug("Processing job",{jobId:t,type:e.type,priority:e.priority,retryCount:e.retryCount});let n=await this.processJob(e);if(n.status==="completed")this.stats.processedJobs++,this.logger.debug("Job completed successfully",{jobId:t,type:n.type});else this.stats.failedJobs++,this.logger.warn("Job failed",{jobId:t,type:n.type,error:n.error})}catch(n){this.stats.failedJobs++,this.logger.error("Error processing job",{jobId:t,type:e.type,error:n}),this.stats.lastError=qe(n)}finally{this.activeJobs.delete(t)}}runPollingLoop(){let t=G.suspend(()=>{if(!this.isWorkerRunning()||this.isStopRequested())return G.interrupt;return this.currentPoll=this.processAvailableJobs(),G.promise(()=>this.currentPoll??Promise.resolve()).pipe(G.andThen(G.suspend(()=>(this.currentPoll=null,!this.isWorkerRunning()||this.isStopRequested()?G.interrupt:G.void))))}).pipe(G.schedule($i.spaced(this.config.pollInterval)),G.asVoid);return(this.clock?G.withClock(t,this.clock):t).pipe(G.ensuring(G.sync(()=>{this.pollFiber=null})))}requestTransition(e,t){let n=this.transitionQueue.at(-1)??this.activeTransition;if(n?.kind===e)return n.promise;let r=()=>{return},o=()=>{return},i=new Promise((c,l)=>{r=c,o=l}),s={kind:e,awaitInFlightPoll:t,promise:i,resolve:r,reject:o};return this.transitionQueue.push(s),this.runNextTransition(),i}runNextTransition(){if(this.activeTransition)return;let e=this.transitionQueue.shift();if(!e)return;this.activeTransition=e,(e.kind==="start"?this.startWorker():this.stopWorker({awaitInFlightPoll:e.awaitInFlightPoll})).then(()=>this.completeTransition(e,!0),(n)=>this.completeTransition(e,!1,n))}completeTransition(e,t,n){if(this.activeTransition!==e)return;if(this.activeTransition=null,t)e.resolve();else e.reject(n);queueMicrotask(()=>this.runNextTransition())}async closeWorkerScope(){let e=this.workerScope;if(this.workerScope=null,this.jobFibers=null,e)await G.runPromise(Bt.close(e,Ct.void))}startHeartbeatLoop(e){let t=null,n=!1,r=setInterval(()=>{if(n||t)return;t=e.beat().then((o)=>{if(!o)e.onStale()}).catch(e.onError).finally(()=>{t=null})},Math.max(1,e.intervalMs));return async()=>{if(n)return;n=!0,clearInterval(r),await t}}startWorkerHeartbeat(){this.workerHeartbeatStop=this.startHeartbeatLoop({intervalMs:this.config.workerHeartbeatIntervalMs,beat:async()=>{let e=this.workerSessionId;if(!e)return!0;return this.jobQueueService.heartbeatWorkerSession(this.config.workerSlotId,e,this.config.workerSessionTimeoutMs)},onStale:()=>this.markUnhealthy("Worker session was superseded"),onError:(e)=>this.markUnhealthy(`Worker session heartbeat failed: ${qe(e)}`)})}async stopWorkerHeartbeat(){await this.workerHeartbeatStop?.(),this.workerHeartbeatStop=null}startAttemptHeartbeat(e,t){let n=e.attemptId;if(!n)return async()=>{return};return this.startHeartbeatLoop({intervalMs:this.config.attemptHeartbeatIntervalMs,beat:()=>this.jobQueueService.renewAttemptLease(e.id,n,this.config.leaseDurationMs),onStale:()=>{let r=Error("Job attempt was superseded");t.abort(r),this.markUnhealthy(r.message)},onError:(r)=>{let o=pd(r);t.abort(o),this.markUnhealthy(`Attempt lease heartbeat failed: ${o.message}`)}})}markUnhealthy(e){if(!this.stats.isHealthy)return;this.stats.isHealthy=!1,this.stats.unhealthyReason=e,this.stats.lastError=e,this.shouldStop=!0,this.logger.error("Job queue worker is unhealthy",{reason:e});try{this.config.onUnhealthy(e)}catch(t){this.logger.error("Job queue worker unhealthy callback failed",{reason:e,error:qe(t)})}}async raceOutcome(e,t){let n,r=new Promise((o)=>{n=setTimeout(()=>o({kind:"timeout"}),Math.max(1,t))});try{return await Promise.race([e,r])}finally{if(n)clearTimeout(n)}}async executeWithDeadline(e,t,n,r){let o=Promise.resolve().then(r).then((l)=>({kind:"success",value:l}),(l)=>({kind:"failure",error:l})),i=await this.raceOutcome(o,t);if(i.kind!=="timeout"){if(i.kind==="failure")throw i.error;return i.value}let s=new uG(e,t);if(n.abort(s),(await this.raceOutcome(o,this.config.cancellationGraceMs)).kind!=="timeout")throw s;throw this.markUnhealthy(`${s.message}; handler ignored cancellation grace`),await o,s}processJob(e){let t=e.metadata.provenance??{rootJobId:e.metadata.rootJobId,causationId:e.id,projectionLineage:[],derivationDepth:0};return this.operationContext.run(t,e.id,()=>this.processJobWithinContext(e))}async processJobWithinContext(e){let t=e.attemptId;if(!t){let c=Error(`Claimed job ${e.id} has no attempt fencing token`);return this.markUnhealthy(c.message),{jobId:e.id,type:e.type,status:xe.FAILED,error:c.message}}let n=this.jobQueueService.getHandler(e.type);if(!n){let c=Error(`No handler registered for job type: ${e.type}`);return await this.jobQueueService.fail(e.id,c,t),{jobId:e.id,type:e.type,status:xe.FAILED,error:c.message}}let r=new AbortController,o=this.startAttemptHeartbeat(e,r),i=!1,s=async()=>{if(i)return;i=!0,await o()};try{this.logger.debug("Processing job",{jobId:e.id,type:e.type,attemptId:t});let c=JSON.parse(e.data),l=n.validateAndParse(c);if(l===null)throw Error(`Invalid job data for type: ${e.type}`);let u=this.progressMonitor.createProgressReporter(e.id,t),d=n.executionTimeoutMs??this.config.defaultExecutionTimeoutMs,m=await this.executeWithDeadline(e.type,d,r,()=>n.process(l,e.id,u,r.signal));await s();let g=KA.safeParse(m);if(g.success){let x=g.data.error??"Handler returned failure",v=Error(x);if(await this.jobQueueService.fail(e.id,v,t))await this.emitTerminalFailure(e,v,n,t);return{jobId:e.id,type:e.type,status:xe.FAILED,error:x}}if(!await this.jobQueueService.complete(e.id,m,t))return{jobId:e.id,type:e.type,status:xe.FAILED,error:"Job attempt no longer owns the claim"};return await this.runHandlerSuccessCallback(n,e,t),await this.progressMonitor.handleJobStatusChange(e.id,"completed",e.metadata),{jobId:e.id,type:e.type,status:xe.COMPLETED,result:m}}catch(c){let l=pd(c);if(await s(),await this.runHandlerErrorCallback("onError",n,e,l,t),await this.jobQueueService.fail(e.id,l,t))await this.emitTerminalFailure(e,l,n,t);return{jobId:e.id,type:e.type,status:xe.FAILED,error:l.message}}}async runHandlerSuccessCallback(e,t,n){let r=e.onTerminalSuccess;if(!r)return;try{let o=e.validateAndParse(JSON.parse(t.data));if(o===null)return;let i=this.progressMonitor.createProgressReporter(t.id,n),s=new AbortController;await this.executeWithDeadline(`${t.type}:onTerminalSuccess`,this.config.errorCallbackTimeoutMs,s,()=>r.call(e,o,t.id,i,s.signal))}catch(o){this.logger.error("Terminal job success callback failed",{jobId:t.id,type:t.type,error:o})}}async emitTerminalFailure(e,t,n,r){if((await this.jobQueueService.getStatus(e.id))?.status!==xe.FAILED)return;await this.runHandlerErrorCallback("onTerminalError",n,e,t,r),await this.progressMonitor.handleJobStatusChange(e.id,"failed",e.metadata)}async runHandlerErrorCallback(e,t,n,r,o){let i=t[e];if(!i)return;try{let s=t.validateAndParse(JSON.parse(n.data));if(s===null)return;let c=this.progressMonitor.createProgressReporter(n.id,o),l=new AbortController;await this.executeWithDeadline(`${n.type}:${e}`,this.config.errorCallbackTimeoutMs,l,()=>i.call(t,r,s,n.id,c,l.signal))}catch(s){this.logger.error(e==="onError"?"Job handler error callback failed":"Job handler terminal error callback failed",{jobId:n.id,error:s})}}}var Yhe=86400000,pG=3600000;class rO{jobQueue;logger;batches=new Map;cleanupFiber=null;cleanupSupervisor=null;inFlightCleanups=new Set;activeTransition=null;transitionQueue=[];acceptingCleanup=!0;clock;static createFresh(e,t,n){return new rO(e,t,n)}constructor(e,t,n){this.jobQueue=e,this.logger=t,this.clock=n?.clock}start(e=pG){return this.requestTransition("start",e)}stop(){return this.requestTransition("stop",pG)}async startCleanup(e){if(this.acceptingCleanup=!0,this.cleanupFiber)return;this.cleanupFiber=G.runFork(this.runCleanupLoop(e))}runCleanupLoop(e){let t=this.cleanupTerminalBatchMetadata().pipe(G.schedule($i.spaced(e)),G.asVoid);return this.clock?G.withClock(t,this.clock):t}scheduleTerminalBatchCleanup(){if(!this.acceptingCleanup)return;this.cleanupSupervisor??=this.createCleanupSupervisor();let e=G.runFork(this.cleanupTerminalBatchMetadata());Gl.unsafeAdd(this.cleanupSupervisor.fibers,e)}async stopCleanup(){this.acceptingCleanup=!1;let e=this.cleanupFiber;if(this.cleanupFiber=null,e)await G.runPromise(Ao.interrupt(e));let t=this.cleanupSupervisor;if(t)await G.runPromise(Gl.awaitEmpty(t.fibers));while(this.inFlightCleanups.size>0)await Promise.allSettled(this.inFlightCleanups);if(t)await G.runPromise(Bt.close(t.scope,Ct.void)),this.cleanupSupervisor=null}requestTransition(e,t){let n=this.transitionQueue.at(-1)??this.activeTransition;if(n?.kind===e)return n.promise;let r=()=>{return},o=()=>{return},i=new Promise((c,l)=>{r=c,o=l}),s={kind:e,intervalMs:t,promise:i,resolve:r,reject:o};return this.transitionQueue.push(s),this.runNextTransition(),i}runNextTransition(){if(this.activeTransition)return;let e=this.transitionQueue.shift();if(!e)return;this.activeTransition=e,(e.kind==="start"?this.startCleanup(e.intervalMs):this.stopCleanup()).then(()=>this.completeTransition(e,!0),(n)=>this.completeTransition(e,!1,n))}completeTransition(e,t,n){if(this.activeTransition!==e)return;if(this.activeTransition=null,t)e.resolve();else e.reject(n);queueMicrotask(()=>this.runNextTransition())}createCleanupSupervisor(){let e=G.runSync(Bt.make()),t=G.runSync(Bt.extend(Gl.make(),e));return{scope:e,fibers:t}}cleanupTerminalBatchMetadata(){return G.tryPromise({try:()=>{let e=this.cleanup(Yhe);return this.inFlightCleanups.add(e),e.then(()=>this.inFlightCleanups.delete(e),()=>this.inFlightCleanups.delete(e)),e},catch:(e)=>e}).pipe(G.asVoid,G.catchAll((e)=>G.sync(()=>{this.logger.warn("Failed to clean up terminal batch metadata",{error:e})})))}validateOperations(e){for(let t of e){let n=this.jobQueue.getValidator(t.type);if(!n)throw Error(`No job type declared: ${t.type}`);if(n.validateAndParse(t.data)===null)throw Error(`Invalid job data for type: ${t.type}`)}}async enqueueBatch(e,t,n,r){if(e.length===0)throw Error("Cannot enqueue empty batch");this.validateOperations(e);let o=[];this.batches.set(n,{jobIds:o,operations:e,source:t.source,startedAt:new Date().toISOString(),metadata:{...t.metadata,rootJobId:n}});try{for(let i of e){let s={...t,rootJobId:n,metadata:{...t.metadata,operationTarget:i.type}},c=await this.jobQueue.enqueue({type:i.type,data:i.data,options:s});o.push(c)}return this.logger.debug("Enqueued batch operations",{batchId:n,operationCount:e.length,jobIds:o,rootJobId:n}),this.scheduleTerminalBatchCleanup(),n}catch(i){throw this.batches.delete(n),this.logger.error("Failed to enqueue batch operations",{error:i,operationCount:e.length,enqueuedJobs:o.length}),i}}async getBatchStatus(e){let t=this.batches.get(e);if(!t)return null;try{let n=await Promise.all(t.jobIds.map((u)=>this.jobQueue.getStatus(u))),r=0,o=0,i=0,s=[];for(let[u,d]of n.entries()){if(!d){o++;let m=t.operations[u],g=t.jobIds[u]??"unknown";s.push(`Missing job ${g}${m?` for ${m.type}`:""}`);continue}switch(d.status){case"completed":r++;break;case"failed":if(o++,d.lastError)s.push(d.lastError);break;case"processing":case"pending":i++;break}}i+=t.operations.length-t.jobIds.length;let c;if(i>0)c=xe.PROCESSING;else if(o>0)c=xe.FAILED;else c=xe.COMPLETED;if(t.terminalAt===void 0&&(c===xe.COMPLETED||c===xe.FAILED))t.terminalAt=Date.now();let l;for(let u=0;u<t.jobIds.length;u++){let d=n[u];if(d&&d.status!=="completed"&&d.status!=="failed"){let m=t.operations[u];if(m)l=`Processing ${m.type}`;break}}return{batchId:e,totalOperations:t.operations.length,completedOperations:r,failedOperations:o,errors:s,status:c,currentOperation:l,metadata:t.metadata}}catch(n){throw this.logger.error("Failed to get batch status",{batchId:e,error:n}),n}}inspectRetention(e){let t=this.batches.get(e);return t?{terminalAt:t.terminalAt}:void 0}async cleanup(e){let t=Date.now()-e,n=0;for(let[r,o]of this.batches.entries()){if(o.terminalAt!==void 0){if(o.terminalAt<=t)this.batches.delete(r),n++;continue}if(new Date(o.startedAt).getTime()<=t){let s=await this.getBatchStatus(r);if(s&&(s.status===xe.COMPLETED||s.status===xe.FAILED))this.batches.delete(r),n++}}return this.logger.debug("Cleaned up batch metadata",{cleaned:n}),n}registerBatch(e,t,n,r,o){this.batches.set(e,{jobIds:t,operations:n,source:r,startedAt:new Date().toISOString(),metadata:o}),this.logger.debug("Registered batch metadata",{batchId:e,operationCount:n.length,jobIds:t})}async getActiveBatches(){let e=[];try{for(let[t,n]of this.batches){let r=await this.getBatchStatus(t);if(r&&(r.status==="pending"||r.status==="processing"))e.push({batchId:t,status:r,metadata:{operations:n.operations,source:n.source,startedAt:n.startedAt,metadata:n.metadata}})}return this.logger.debug("Retrieved active batches",{count:e.length}),e}catch(t){throw this.logger.error("Failed to get active batches",{error:t}),t}}}var Xhe=a.preprocess((e)=>{if(typeof e!=="string")return e;return JSON.parse(e)},a.record(a.string(),a.unknown()));class oO{jobQueueService;messageBus;batchJobManager;logger;mode;pollTimer;pollCursor={updatedAt:0,jobId:""};polling=!1;static createFresh(e,t,n,r,o="combined"){return new oO(e,t,n,r,o)}constructor(e,t,n,r,o){this.jobQueueService=e,this.messageBus=t,this.batchJobManager=n,this.logger=r,this.mode=o}start(){if(this.mode==="durable-reader"&&!this.pollTimer){this.pollCursor={updatedAt:Date.now(),jobId:""},this.pollTimer=setInterval(()=>{this.pollDurableUpdates()},250),this.pollTimer.unref(),this.logger.debug("Job progress monitor ready (durable polling mode)");return}this.logger.debug("Job progress monitor ready (event-driven mode)")}stop(){if(this.pollTimer)clearInterval(this.pollTimer);this.pollTimer=void 0,this.logger.debug("Job progress monitor stopped")}async pollDurableUpdates(){if(this.polling)return;this.polling=!0;try{let e=await this.jobQueueService.getRuntimeUpdates(this.pollCursor,100);for(let t of e)if(this.pollCursor=t.cursor,t.job.status==="processing"&&t.job.progress)await this.publishJobProgress(t.job,t.job.progress);else if(t.job.status==="completed"||t.job.status==="failed")await this.handleJobStatusChange(t.job.id,t.job.status,t.job.metadata)}catch(e){this.logger.error("Failed to poll durable job progress",{error:e})}finally{this.polling=!1}}createProgressReporter(e,t){let n=fa.from(async(r)=>{await this.emitJobProgress(e,r,t)});if(!n)throw Error("Failed to create ProgressReporter");return n}async emitBatchProgress(e,t,n){try{let r={totalOperations:t.totalOperations,completedOperations:t.completedOperations,failedOperations:t.failedOperations,currentOperation:t.currentOperation??"Processing batch...",errors:t.errors},o={id:e,type:"batch",status:t.status,metadata:n,batchDetails:r};if(t.totalOperations>0)o.progress={current:t.completedOperations,total:t.totalOperations,percentage:Math.round(t.completedOperations/t.totalOperations*100)};await this.messageBus.send({type:_g.progress,payload:o,sender:"job-progress-monitor",broadcast:!0}),this.logger.debug("Emitted batch progress update",{batchId:e,status:t.status,progress:`${t.completedOperations}/${t.totalOperations}`})}catch(r){this.logger.error("Error emitting batch progress update",{batchId:e,error:r})}}isBatchChild(e,t){return!!t&&t!==e}get publishesEvents(){return this.mode!=="durable-writer"}async broadcastEvent(e){await this.messageBus.send({type:_g.progress,payload:e,sender:"job-progress-monitor",broadcast:!0})}async emitJobProgress(e,t,n){try{if(n&&!await this.jobQueueService.recordAttemptProgress(e,n,t)){this.logger.debug("Discarding progress from obsolete job attempt",{jobId:e,attemptId:n});return}if(!this.publishesEvents)return;let r=await this.jobQueueService.getStatus(e);if(!r){this.logger.warn("Job not found for progress update",{jobId:e});return}await this.publishJobProgress(r,t)}catch(r){this.logger.error("Error emitting job progress",{jobId:e,error:r})}}async publishJobProgress(e,t){if(e.metadata.silent)return;if(this.isBatchChild(e.id,e.metadata.rootJobId))return;let n=t.total??0,r={id:e.id,type:"job",status:"processing",metadata:e.metadata,message:t.message};if(n>0)r.progress={current:t.progress,total:n,percentage:Math.round(t.progress/n*100)};await this.broadcastEvent(r)}async emitJobCompletion(e){await this.emitJobStatusEvent(e,"completed")}async emitJobFailure(e){await this.emitJobStatusEvent(e,"failed")}async emitJobStatusEvent(e,t){if(!this.publishesEvents)return;try{let n=await this.jobQueueService.getStatus(e);if(!n){this.logger.warn(`Cannot emit ${t} for unknown job`,{jobId:e});return}if(n.metadata.silent)return;if(this.isBatchChild(e,n.metadata.rootJobId)){this.logger.debug(`Skipping individual job ${t} for batch operation`,{jobId:e,rootJobId:n.metadata.rootJobId});return}let r={id:e,type:"job",status:t,message:this.extractStatusMessage(n,t),metadata:n.metadata,jobDetails:{jobType:n.type,priority:n.priority,retryCount:n.retryCount}};await this.broadcastEvent(r),this.logger.debug(`Emitted job ${t} event`,{jobId:e})}catch(n){this.logger.error(`Error emitting job ${t} event`,{jobId:e,error:n})}}extractStatusMessage(e,t){if(t==="failed")return e.lastError??void 0;if(!e.result)return;try{let n=Xhe.parse(e.result),r=n.message;if(r)return String(r);let o=n.routesBuilt;if(o!==void 0)return`${o} routes built`}catch{}return}getStats(){return{isRunning:!0}}async handleJobStatusChange(e,t,n){if(!this.publishesEvents)return;let r=n?su.safeParse(n):void 0,o=r?.success?r.data:void 0;if(o?.silent)return;try{if(await this.emitJobStatusEvent(e,t),o&&this.isBatchChild(e,o.rootJobId))try{let i=o.rootJobId,s=await this.batchJobManager.getBatchStatus(i);if(s){let c=s.metadata??o;await this.emitBatchProgress(i,s,c)}}catch(i){this.logger.warn("Failed to emit batch progress",{jobId:e,rootJobId:o.rootJobId,error:i})}}catch(i){this.logger.error("Failed to handle job status change",{jobId:e,status:t,error:i})}}}var eye=a.record(a.string(),a.unknown());class Ng{logger;schema;jobTypeName;executionTimeoutMs;constructor(e,t){this.logger=e,this.schema=t.schema,this.jobTypeName=t.jobTypeName,this.executionTimeoutMs=t.executionTimeoutMs}validateAndParse(e){if(!this.schema)throw Error(`${this.jobTypeName}: No schema provided. Override validateAndParse() or provide a schema.`);let t=this.schema.safeParse(e);if(!t.success)return this.logger.warn(`Invalid ${this.jobTypeName} job data`,{data:e,validationError:t.error.issues}),null;return this.logger.debug(`${this.jobTypeName} job data validation successful`,{data:this.summarizeDataForLog(t.data)}),t.data}async onError(e,t,n,r,o){this.logger.error(`${this.jobTypeName} job error handler triggered`,{jobId:n,errorMessage:e.message,errorStack:e.stack,data:this.summarizeDataForLog(t)})}async reportProgress(e,t){await e.report({progress:t.progress,total:t.total??100,message:t.message})}summarizeDataForLog(e){let t=eye.safeParse(e);return t.success?t.data:{}}}function Fg(e,t,n){return async(r)=>{let{type:o,data:i,toolContext:s=null,options:c,projection:l}=r,u=s?dG(s):void 0,{metadata:d,...m}=c??{},g={operationType:"data_processing",pluginId:t,...d,...s&&{interfaceType:s.interfaceType,conversationId:s.conversationId,channelId:s.channelId,requestedByActor:s.actor,...u?{requestedByUserId:u}:{},requestedByInterface:s.interfaceType,...s.progressToken!==void 0&&{progressToken:s.progressToken}}};if(s&&!u)delete g.requestedByUserId;let h={...m,source:t,...c?.rootJobId&&{rootJobId:c.rootJobId},...l&&{projection:l},metadata:g},x=n&&!o.includes(":")?`${t}:${o}`:o;return e.enqueue({type:x,data:i,options:h})}}function iO(e,t){return async(n,r)=>{let o=r?.rootJobId??gt(),i=n.map((c)=>({...c,type:c.type.includes(":")?c.type:`${t}:${c.type}`})),s={...r,source:t,rootJobId:o,metadata:{...r?.metadata,operationType:"batch_processing",pluginId:t}};return await e.enqueueBatch(i,s,o,t),o}}function sO(e,t){return(n,r)=>{let o=n.includes(":")?n:`${t}:${n}`;e.registerHandler(o,r,t)}}var tye=a.custom((e)=>typeof e==="object"&&e!==null&&("safeParse"in e)),nye=a.object({name:a.string(),schema:tye});function mG(e){return nye.safeParse(e).success}function rye(e){if(!e)return;return{status:e.status,message:e.message,lastCheck:e.lastCheck?.toISOString(),details:e.details}}function fG(e){return{model:e.model,version:e.version,uptime:e.uptime,entities:e.entities,entityCounts:e.entityCounts,embeddings:e.embeddings,ai:e.ai,daemons:e.daemons.map((t)=>({name:t.name,pluginId:t.pluginId,status:t.status,health:rye(t.health)})),endpoints:e.endpoints,interactions:e.interactions}}var gG={digest:"conversation:digest"};var pe=wt("conversations",{id:W("id").primaryKey(),sessionId:W("session_id").notNull(),interfaceType:W("interface_type").notNull(),channelId:W("channel_id").notNull(),personId:W("person_id"),started:W("started").notNull(),lastActive:W("last_active").notNull(),metadata:W("metadata"),created:W("created").notNull(),updated:W("updated").notNull()},(e)=>({sessionIdx:vt("idx_conversations_session").on(e.sessionId),channelIdx:vt("idx_conversations_channel").on(e.channelId),personIdx:vt("idx_conversations_person").on(e.personId),interfaceSessionIdx:vt("idx_conversations_interface_session").on(e.interfaceType,e.sessionId),interfaceChannelIdx:vt("idx_conversations_interface_channel").on(e.interfaceType,e.channelId)})),Tn=wt("messages",{id:W("id").primaryKey(),conversationId:W("conversation_id").notNull().references(()=>pe.id,{onDelete:"cascade"}),role:W("role").notNull(),content:W("content").notNull(),timestamp:W("timestamp").notNull(),metadata:W("metadata")},(e)=>({conversationIdx:vt("idx_messages_conversation").on(e.conversationId),timestampIdx:vt("idx_messages_timestamp").on(e.timestamp)})),au=wt("summary_tracking",{conversationId:W("conversation_id").primaryKey().references(()=>pe.id,{onDelete:"cascade"}),lastSummarizedAt:W("last_summarized_at"),lastMessageId:W("last_message_id"),messagesSinceSummary:Re("messages_since_summary").default(0),updated:W("updated").notNull()});function hG(e){return ui({url:e.url,schema:{conversations:pe,messages:Tn,summaryTracking:au},authToken:e.authToken,authTokenEnv:"CONVERSATION_DATABASE_AUTH_TOKEN"})}var oye=a.preprocess((e)=>{if(typeof e!=="string")return e;try{return JSON.parse(e)}catch{return}},a.record(a.string(),a.unknown())).catch({});function ha(e){return oye.parse(e)}var fv="conversation:messageAdded",aO="conversation:started",zg=a.object({identity:Yi,interfaceType:a.string(),role:Hp,displayName:a.string().optional(),username:a.string().optional(),isBot:a.boolean().optional()}),iye=a.preprocess(sye,zg);function sye(e){if(!jo(e)||"identity"in e)return e;let{actorId:t,interfaceType:n,role:r}=e;if(typeof t!=="string"||typeof n!=="string"||r!=="user"&&r!=="assistant")return e;let{userId:o,canonicalId:i}=e;return{identity:yG({actorId:t,interfaceType:n,role:r,...typeof o==="string"?{userId:o}:{},...typeof i==="string"?{canonicalId:i}:{}}),interfaceType:n,role:r,...typeof e.displayName==="string"?{displayName:e.displayName}:{},...typeof e.username==="string"?{username:e.username}:{},...typeof e.isBot==="boolean"?{isBot:e.isBot}:{}}}var jg=a.object({messageId:a.string().optional(),channelId:a.string().optional(),channelName:a.string().optional(),threadId:a.string().optional(),metadata:a.record(a.string(),a.unknown()).optional()}),bG=a.looseObject({actor:iye.optional(),source:jg.optional()});function xG(e){if(typeof e==="string")try{let t=JSON.parse(e);return jo(t)?t:null}catch{return null}return jo(e)?e:null}function aye(e){if(e.role!=="assistant")return!1;if(e.content.trim().length===0)return!1;let t=xG(e.metadata),n=t?.entityMemoryRefs;if(Array.isArray(n)&&n.length>0)return!1;let r=t?.cards;if(!Array.isArray(r))return!0;return!r.some((o)=>{if(!jo(o))return!1;if(o.kind==="tool-approval")return!0;return o.kind==="actions"&&o.id==="actions:upload-intent"})}var cye=a.object({id:a.string(),conversationId:a.string(),role:a.string(),content:a.string(),timestamp:a.string(),metadata:a.string().nullable()}),SG=a.object({conversationId:a.string(),messageCount:a.number(),messages:a.array(cye),windowStart:a.number(),windowEnd:a.number(),windowSize:a.number(),timestamp:a.string()});var mi=b`strftime('%Y-%m-%dT%H:%M:%fZ', 'now')`;function cO(){return CG(!1)}function TG(){return CG(!0)}function CG(e){let t=vG.shape.maxAgeSeconds.maxValue,n=b`(
|
|
128
128
|
CAST(round((julianday(${mi}) - julianday(${pe.started})) * 86400000) AS INTEGER) >= json_extract(${pe.metadata}, '$.guest.retention.maxAgeSeconds') * 1000
|
|
129
129
|
OR CAST(round((julianday(${mi}) - julianday(${pe.lastActive})) * 86400000) AS INTEGER) >= json_extract(${pe.metadata}, '$.guest.retention.idleSeconds') * 1000
|
|
130
130
|
)`;return b`CASE WHEN json_valid(${pe.metadata}) THEN coalesce(
|
|
@@ -164,5 +164,5 @@ Result:`);if(n===-1)return;let r=e.slice(n+9).trim();if(!r)return;try{return JSO
|
|
|
164
164
|
`)}function I6(e){return{identity:e.identity,interfaceType:e.interfaceType,role:e.role??"user",...e.displayName?{displayName:e.displayName}:{},...e.username?{username:e.username}:{},...e.isBot!==void 0?{isBot:Tve(e.isBot)}:{}}}function Tve(e){if(typeof e==="boolean")return e;return e.toLowerCase()==="true"}function R6(e){return{...e.messageId?{messageId:e.messageId}:{},...e.channelId?{channelId:e.channelId}:{},...e.channelName?{channelName:e.channelName}:{},...e.threadId?{threadId:e.threadId}:{},...e.metadata?{metadata:e.metadata}:{}}}function k6(e){if(e.skippedMessages.length===0)return{message:e.message};return{message:["Messages received while the previous response was still running (oldest first, for context only):",...e.skippedMessages.map(Cve),"","Latest message to answer:",e.message].join(`
|
|
165
165
|
`),metadata:{supersededMessageCount:e.skippedMessages.length,supersededMessageIds:e.skippedMessages.map((r)=>r.id).filter((r)=>r!==void 0)}}}function Cve(e){let t=e.text.trim(),n=e.authorName?.trim();return n?`- ${n}: ${t}`:`- ${t}`}async function Dve(e){let{entityType:t,title:n,deriveId:r,regeneratePrompt:o,context:i}=e,s=r(n),c=await i.entityService.getEntity({entityType:t,id:s});if(!c||c.metadata.status==="generating")return n;i.logger.debug(`Entity ID collision: ${t}/${s}, asking AI for a new title`);let l=a.object({title:a.string().max(80).describe("A short, unique title (2-6 words)")}),{object:u}=await i.ai.generateObject(`The title "${n}" is already taken. ${o}`,l),d=u.title;return i.logger.debug(`AI suggested new title: "${d}"`),d}class yT{tail=Promise.resolve();run(e){let t=this.tail.then(()=>e());return this.tail=t.then(()=>{return},()=>{return}),t}async settle(){await this.tail}}var Mve="current";class P6{store;schema;createEmpty;key;queue=new yT;statePromise;constructor(e){this.store=e.runtimeState.scoped({namespace:e.namespace,schema:e.schema}),this.schema=e.schema,this.createEmpty=e.createEmpty,this.key=e.key??Mve}mutate(e){return this.queue.run(async()=>{let t=await this.load(),n=await e(t);return await this.persist(t),n})}async snapshot(){return await this.settle(),structuredClone(await this.load())}settle(){return this.queue.settle()}load(){return this.statePromise??=this.store.get(this.key).then((e)=>e??this.createEmpty()),this.statePromise}async persist(e){await this.store.set(this.key,this.schema.parse(e))}}var zD=Mo.extend({id:a.literal("brain-character"),entityType:a.literal("brain-character")}),bT=a.object({name:a.string().describe("The brain's friendly display name"),role:a.string().describe("The brain's primary role"),purpose:a.string().describe("The brain's purpose and goals"),values:a.array(a.string()).describe("Core values that guide behavior")});var _ve=a.record(a.string(),a.unknown());class ah extends Sc{generateFrontMatter(e){let t=this.parseFrontmatter(e.content);return this.buildMarkdown("",_ve.parse(t))}}class xT extends ah{constructor(){super({entityType:"brain-character",purpose:"The brain's own identity, character, and purpose (singleton).",schema:zD,frontmatterSchema:bT,isSingleton:!0,hasBody:!1})}createCharacterContent(e){return this.buildMarkdown("",e)}parseCharacterBody(e){return this.parseFrontmatter(e)}toMarkdown(e){return this.generateFrontMatter(e)}fromMarkdown(e){return{content:e,entityType:"brain-character"}}extractMetadata(e){let t=this.parseFrontmatter(e.content);return{role:t.role,values:t.values}}}class ch extends sv{codec;constructor(e,t,n,r,o,i){super(e,t,n,r,Vi(o));this.codec=i}parseBody(e){return this.codec.parse(e)}createContent(e){return this.codec.create(e)}}class ST extends ch{static getDefaultCharacter(){return{name:"Brain",role:"Knowledge assistant",purpose:"Help organize, understand, and retrieve information from your knowledge base",values:["clarity","accuracy","helpfulness"]}}static createFresh(e,t,n){return new ST(e,t,n)}constructor(e,t,n){let r=new xT;super(e,t,"brain-character",n??ST.getDefaultCharacter(),"brain character is loaded at bootstrap before any user is in scope",{parse:(o)=>r.parseCharacterBody(o),create:(o)=>r.createCharacterContent(o)})}getCharacter(){return this.get()}getCharacterContent(){return this.getContent()}}var jD=Mo.extend({id:a.literal("anchor-profile"),entityType:a.literal("anchor-profile")}),A6=a.enum(["person","team","organization"]),uu=a.object({name:a.string().describe("Name of the anchor"),organization:a.string().optional().describe("Organization the anchor belongs to"),description:a.string().optional().describe("Short description or biography"),avatar:a.string().optional().describe("URL or asset path to avatar/logo"),website:a.string().optional().describe("Primary website URL"),email:a.string().optional().describe("Contact email"),socialLinks:a.array(a.object({platform:a.enum(["github","instagram","linkedin","email","website"]).describe("Social media platform"),url:a.string().describe("Profile or contact URL"),label:a.string().optional().describe("Optional display label")})).optional().describe("Social media and contact links")});class vT extends ah{constructor(){super({entityType:"anchor-profile",purpose:"The profile of the brain's Anchor (singleton).",schema:jD,frontmatterSchema:uu,isSingleton:!0,hasBody:!0})}createProfileContent(e){let t=uu.parse(e);return this.buildMarkdown("",t)}parseProfileBody(e,t){if(t){let{metadata:n,content:r}=ir(e,t);return r?{...n,story:r}:n}return this.parseFrontmatter(e)}fromMarkdown(e){return{content:e,entityType:"anchor-profile"}}extractMetadata(e){let t=this.parseFrontmatter(e.content);return{name:t.name,email:t.email,website:t.website}}}class lh extends ch{static getDefaultProfile(){return{name:"Unknown"}}static createFresh(e,t,n){return new lh(e,t,n)}constructor(e,t,n){let r=new vT;super(e,t,"anchor-profile",n??lh.getDefaultProfile(),"anchor profile is loaded at bootstrap before any user is in scope",{parse:(o)=>r.parseProfileBody(o),create:(o)=>r.createProfileContent(o)})}getProfile(){return this.get()}getProfileContent(){return this.getContent()}}var TT=a.enum(["person","team","organization"]),Nve=a.object({kind:a.string().trim().min(1),category:TT,labels:a.object({singular:a.string().trim().min(1),plural:a.string().trim().min(1)})});function Fve(e){if(typeof e!=="object"||e===null||!("shape"in e)||!("safeParse"in e)||typeof e.safeParse!=="function")throw Error("Profile kind fields must be a Zod object schema")}class O6{selectedKind;registrations=new Map;finalized=!1;resolved=null;selectedDefinition;constructor(e){let t=e?.trim();this.selectedKind=t===""?void 0:t}register(e,t){if(this.finalized)throw Error("Profile kind registration is closed");let n=Nve.parse(t);Fve(t.fields);let r=Object.freeze({...t,kind:n.kind,category:n.category,labels:Object.freeze({...n.labels})}),o=this.registrations.get(n.kind)??[];o.push({pluginId:e,definition:r}),this.registrations.set(n.kind,o)}unregisterPlugin(e){for(let[t,n]of this.registrations){let r=n.filter((o)=>o.pluginId!==e);if(r.length===0)this.registrations.delete(t);else this.registrations.set(t,r)}}finalize(){if(this.finalized)return this.resolved;let t=[...this.registrations.entries()].filter(([,r])=>r.length>1).sort(([r],[o])=>r.localeCompare(o))[0];if(t){let[r,o]=t,i=o.map((s)=>s.pluginId).sort().join(", ");throw Error(`Profile kind "${r}" is registered by multiple plugins: ${i}`)}if(!this.selectedKind)return this.finalized=!0,this.resolved=null,null;let n=this.registrations.get(this.selectedKind)?.[0];if(!n)throw Error(`Selected profile kind "${this.selectedKind}" is not registered`);return this.selectedDefinition=n.definition,this.resolved=Object.freeze({kind:n.definition.kind,category:n.definition.category,labels:Object.freeze({...n.definition.labels})}),this.finalized=!0,this.resolved}getResolved(){return this.assertFinalized(),this.resolved}getSelectedDefinition(){return this.assertFinalized(),this.selectedDefinition}isFinalized(){return this.finalized}assertFinalized(){if(!this.finalized)throw Error("Profile kind selection has not been finalized")}}var D6=30000;class LD{logger;resolver;links=[];actorIndex=new Map;negativeActorIndex=new Map;static createFresh(e,t){return new LD(e,t)}constructor(e,t){this.logger=e.child("CanonicalIdentityService"),this.resolver=t}async refreshCache(){this.links=[],this.actorIndex=new Map,this.negativeActorIndex=new Map,this.logger.debug("Canonical identity links refreshed",{linkCount:0,actorCount:0})}getLinks(){return this.links}resolveActor(e){let t=BD(e),n=this.actorIndex.get(t);if(!n)return null;if(n.expiresAt<=Date.now())return this.actorIndex.delete(t),null;return n.resolution}async enrichActor(e){if(e.identity.kind==="user"&&e.identity.canonicalId||e.role!=="user")return e;let t=this.resolveActor(e.identity);if(t)return this.enrichedActor(e,t);let n=BD(e.identity),r=this.negativeActorIndex.get(n);if(r&&r>Date.now())return e;this.negativeActorIndex.delete(n);let o=await this.resolver?.(e.identity);if(!o)return this.negativeActorIndex.set(n,Date.now()+D6),e;let i={identity:e.identity,...e.displayName?{label:e.displayName}:{}},s={...o,actors:[i],matchedActor:i};return this.actorIndex.set(n,{resolution:s,expiresAt:Date.now()+D6}),this.links=[...this.links.filter((c)=>c.userId!==s.userId),s],this.enrichedActor(e,s)}enrichedActor(e,t){return{...e,identity:{kind:"user",userId:t.userId,canonicalId:t.canonicalId},...t.displayName?{displayName:t.displayName}:{}}}}var M6="https://rizom.ai/ext/anchor-profile/v1",_6=a.looseObject({id:a.string(),description:a.string(),name:a.string().optional(),tags:a.array(a.string()).optional().default([])}),N6=uu.extend({kind:a.string().trim().min(1).optional(),category:TT.optional()}).superRefine((e,t)=>{if(e.kind===void 0!==(e.category===void 0))t.addIssue({code:"custom",message:"Anchor kind and category must be provided together"})}),zve=a.looseObject({uri:a.string(),params:a.record(a.string(),a.unknown()).optional()}),F6=a.looseObject({name:a.string(),url:a.string(),description:a.string().optional(),skills:a.array(_6).optional().default([]),capabilities:a.looseObject({extensions:a.array(zve).optional().default([])}).optional()});function jve(e){let t=F6.safeParse(e);if(!t.success)return null;let n=t.data,o=(n.capabilities?.extensions??[]).find((s)=>s.uri===M6),i=null;if(o?.params){let s=N6.safeParse(o.params);if(s.success)i=s.data}return{brainName:n.name,url:n.url,description:n.description??"",skills:n.skills.map((s)=>({id:s.id,name:s.name??s.id,description:s.description,tags:s.tags})),anchor:i}}import{EventEmitter as B6}from"events";var Ht={REGISTERED:"registered",INITIALIZED:"initialized",ERROR:"error",DISABLED:"disabled"},qo={REGISTERED:"plugin:registered",BEFORE_INITIALIZE:"plugin:before_initialize",INITIALIZED:"plugin:initialized",ERROR:"plugin:error",DISABLED:"plugin:disabled"};class $o extends Error{pluginId;constructor(e,t){super(`Plugin ${e}: ${t}`);this.name="PluginError",this.pluginId=e}}function ns(e,t){return Reflect.get(e,t,e)}function rs(e,t,n){if(typeof e!=="function")throw TypeError("Cannot apply a non-callable trapped member");return Reflect.apply(e,t,n)}class qD{scope;ingress=new Set;closePromise=null;closed=!1;constructor(){this.scope=G.runSync(Bt.make())}addFinalizer(e){if(this.closed)throw Error("Cannot register a resource after plugin teardown");G.runSync(Bt.addFinalizer(this.scope,G.promise(async()=>{await e()})))}addIngress(e){if(this.closed)throw Error("Cannot register ingress after plugin teardown");this.ingress.add(e)}close(e=Ct.void){return this.closed=!0,this.closePromise??=this.closeScope(e),this.closePromise}async closeScope(e){let t,n=!1,r=[...this.ingress].reverse();for(let c of r)try{c.stopAdmission()}catch(l){if(!n)t=l;n=!0}let o=await Promise.allSettled(r.map((c)=>Promise.resolve().then(()=>c.drain())));this.ingress.clear();let i=o.find((c)=>c.status==="rejected");if(!n&&i)t=i.reason,n=!0;let s=await G.runPromiseExit(Bt.close(this.scope,e));if(!n&&Ct.isFailure(s))t=Po.squash(s.cause),n=!0;if(n)throw t}}function z6(e,t){let n=e.getMessageBus(),r=new Set,o={send:(oe)=>n.send(oe),hasHandlers:(oe)=>n.hasHandlers?.(oe)??!1,subscribe:(oe,ie,te)=>{let Te=!0,Pe=new Set,ze=(Kt)=>{if(!Te)return{noop:!0};let fi,wr=new Promise((Ir)=>{fi=Ir});Pe.add(wr);let $r=()=>{Pe.delete(wr),fi()},Ta;try{Ta=Promise.resolve(ie(Kt))}catch(Ir){throw $r(),Ir}return Ta.then((Ir)=>($r(),Ir),(Ir)=>{throw $r(),Ir})},le=n.subscribe(oe,ze,te),It={type:oe,originalHandler:ie,stopAdmission:()=>{if(!Te)return;Te=!1,le(),r.delete(It)}};r.add(It);try{t.addIngress({stopAdmission:It.stopAdmission,drain:async()=>{await Promise.all(Pe)}})}catch(Kt){throw It.stopAdmission(),Kt}return It.stopAdmission},unsubscribe:(oe,ie)=>{let te=[...r].filter((Te)=>Te.type===oe&&Te.originalHandler===ie);if(te.length===0){n.unsubscribe(oe,ie);return}for(let Te of te)Te.stopAdmission()},collect:(oe)=>n.collect(oe),validateMessage:(oe,ie)=>n.validateMessage(oe,ie),getHandlerCount:(oe)=>n.getHandlerCount(oe),getTargetedHandlerCount:(oe,ie)=>n.getTargetedHandlerCount(oe,ie),clearHandlers:(oe)=>n.clearHandlers(oe),clearAllHandlers:()=>n.clearAllHandlers()},i=e.getAttachmentRegistry(),s={...i,register:(oe,ie,te)=>{let Te=!0,Pe=i.register(oe,ie,te),ze=()=>{if(!Te)return;Te=!1,Pe()};return t.addFinalizer(ze),ze}},c=e.getEntityRegistry(),l=new Proxy(c,{get(oe,ie){let te=ns(oe,ie);if(ie==="registerEntityType"&&typeof te==="function")return(...Te)=>{let Pe=rs(te,oe,Te),ze=Te[0];if(typeof ze==="string")t.addFinalizer(()=>oe.unregisterEntityType(ze));return Pe};return typeof te==="function"?te.bind(oe):te}}),u=e.getProfileKindRegistry(),d=new Proxy(u,{get(oe,ie){let te=ns(oe,ie);if(ie==="register"&&typeof te==="function")return(...Te)=>{let Pe=rs(te,oe,Te),ze=Te[0];if(typeof ze==="string")t.addFinalizer(()=>oe.unregisterPlugin(ze));return Pe};return typeof te==="function"?te.bind(oe):te}}),m=e.getChannelRegistry(),g=new Proxy(m,{get(oe,ie){let te=ns(oe,ie);if((ie==="registerDescriptor"||ie==="registerDeliveryProvider")&&typeof te==="function")return(...Te)=>{let Pe=rs(te,oe,Te),ze=Te[0];if(typeof ze==="string")t.addFinalizer(()=>oe.unregisterPlugin(ze));return Pe};return typeof te==="function"?te.bind(oe):te}}),h=e.getInboxRegistry(),x=new Proxy(h,{get(oe,ie){let te=ns(oe,ie);if(ie==="registerSource"&&typeof te==="function")return(...Te)=>{let Pe=rs(te,oe,Te),ze=Te[0];if(typeof ze==="string")t.addFinalizer(()=>oe.unregisterPlugin(ze));return Pe};return typeof te==="function"?te.bind(oe):te}}),v=e.getInboxFollowUpRegistry(),E=new Proxy(v,{get(oe,ie){let te=ns(oe,ie);if(ie==="registerKind"&&typeof te==="function")return(...Te)=>{let Pe=rs(te,oe,Te),ze=Te[0];if(typeof ze==="string")t.addFinalizer(()=>oe.unregisterPlugin(ze));return Pe};return typeof te==="function"?te.bind(oe):te}}),H=e.getAccountSettingsRegistry(),q=new Proxy(H,{get(oe,ie){let te=ns(oe,ie);if(ie==="register"&&typeof te==="function")return(...Te)=>{let Pe=rs(te,oe,Te);return t.addFinalizer(()=>{rs(oe.unregister,oe,[Pe])}),Pe};return typeof te==="function"?te.bind(oe):te}}),Q=e.getOperationalHealthRegistry(),ue=new Proxy(Q,{get(oe,ie){let te=ns(oe,ie);if(ie==="register"&&typeof te==="function")return(...Te)=>{let Pe=rs(te,oe,Te),ze=Te[0];if(typeof ze==="string")t.addFinalizer(()=>oe.unregisterPlugin(ze));return Pe};return typeof te==="function"?te.bind(oe):te}}),Oe=e.getDataSourceRegistry(),de=new Proxy(Oe,{get(oe,ie){let te=ns(oe,ie);if(ie==="register"&&typeof te==="function")return(...Te)=>{let Pe=rs(te,oe,Te),ze=Te[0];if(typeof ze==="object"&&ze!==null&&"id"in ze&&typeof ze.id==="string"){let le=ze.id.includes(":")?ze.id:`shell:${ze.id}`;t.addFinalizer(()=>oe.unregister(le))}return Pe};return typeof te==="function"?te.bind(oe):te}}),_e=e.getInsightsRegistry(),Ne=new Proxy(_e,{get(oe,ie){let te=ns(oe,ie);if(ie==="register"&&typeof te==="function")return(...Te)=>{let Pe=rs(te,oe,Te),ze=Te[0];if(typeof ze==="string")t.addFinalizer(()=>oe.unregister(ze));return Pe};return typeof te==="function"?te.bind(oe):te}}),nt=new Proxy(e,{get(oe,ie){if(ie==="getMessageBus")return()=>o;if(ie==="getAttachmentRegistry")return()=>s;if(ie==="getEntityRegistry")return()=>l;if(ie==="getDataSourceRegistry")return()=>de;if(ie==="getProfileKindRegistry")return()=>d;if(ie==="getChannelRegistry")return()=>g;if(ie==="getInboxRegistry")return()=>x;if(ie==="getInboxFollowUpRegistry")return()=>E;if(ie==="getOperationalHealthRegistry")return()=>ue;if(ie==="getAccountSettingsRegistry")return()=>q;if(ie==="getInsightsRegistry")return()=>Ne;let te=ns(oe,ie);return typeof te==="function"?te.bind(oe):te}});return CK(e,nt),nt}class $D{plugins;events;daemonRegistry;logger;projectionRegistry;resourceScopes=new Map;releasePromises=new Map;constructor(e,t,n,r,o){this.plugins=e,this.events=t,this.daemonRegistry=n,this.projectionRegistry=r,this.logger=o.child("PluginLifecycle")}async initializePlugin(e,t,n){let r=this.plugins.get(e);if(!r)throw new $o(e,"Registration failed: Plugin is not registered");let o=r.plugin,i=new qD;i.addFinalizer(()=>t.unregisterPluginCapabilities?.(e)),i.addFinalizer(()=>t.getJobQueueService().unregisterPluginHandlers(e)),i.addFinalizer(()=>this.projectionRegistry.unregisterPlugin(e)),this.resourceScopes.set(e,i),this.releasePromises.delete(e),this.logger.debug(`Initializing plugin: ${e}`);try{this.events.emit(qo.BEFORE_INITIALIZE,e,o);let s=await o.register(z6(t,i),n);return r.status=Ht.INITIALIZED,this.logger.debug(`Initialized plugin: ${e}`),this.events.emit(qo.INITIALIZED,e,o),s}catch(s){throw this.logger.error(`Error initializing plugin ${e}: ${qe(s)}`),await this.failPluginInitialization(e,s),s}}async finalizePluginRegistration(e){let t=this.plugins.get(e);if(!t)throw new $o(e,"Registration finalization failed: Plugin is not registered");if(t.status!==Ht.INITIALIZED)return;try{await t.plugin.finalizeRegistration?.(),this.logger.debug(`Registration finalized for plugin: ${e}`)}catch(n){throw await this.failPluginInitialization(e,n),n}}async readyPlugin(e){let t=this.plugins.get(e);if(!t)throw new $o(e,"Ready failed: Plugin is not registered");if(t.status!==Ht.INITIALIZED){this.logger.debug(`Skipping ready hook for non-initialized plugin: ${e}`);return}try{await t.plugin.ready?.(),this.logger.debug(`Ready hook completed for plugin: ${e}`)}catch(n){let r=pd(n);t.status=Ht.ERROR,t.error=r;try{this.events.emit(qo.ERROR,e,r)}catch(o){this.logger.error(`Plugin error listener failed for ${e}`,o)}throw r}}async startPluginDaemons(e){let t=this.plugins.get(e);if(t?.status!==Ht.INITIALIZED)return;try{await this.daemonRegistry.startPlugin(e),this.logger.debug(`Started daemons for plugin: ${e}`)}catch(n){if(t.plugin.requiresDaemonStartup?.())throw n;this.logger.warn(`Daemon ${e} failed to start: ${qe(n)}`)}}async failPluginInitialization(e,t){let n=this.plugins.get(e);if(!n)return;let r=n.status!==Ht.ERROR,o=pd(t);if(n.status=Ht.ERROR,n.error=o,await this.releasePluginResources(e,Ct.fail(t)),r)try{this.events.emit(qo.ERROR,e,o)}catch(i){this.logger.error(`Plugin error listener failed for ${e}`,i)}}async disablePlugin(e){let t=this.plugins.get(e);if(!t){this.logger.warn(`Cannot disable plugin ${e}: not registered`);return}if(t.status===Ht.DISABLED)return;this.logger.debug(`Disabling plugin: ${e}`);let n=t.status===Ht.ERROR;await this.releasePluginResources(e,Ct.void);let r=this.plugins.get(e);if(!n&&r&&r.status!==Ht.DISABLED)r.status=Ht.DISABLED,this.events.emit(qo.DISABLED,e,r.plugin);this.logger.debug(`Disabled plugin: ${e}`)}releasePluginResources(e,t){let n=this.releasePromises.get(e);if(n)return n;let r=this.releasePluginResourcesOnce(e,t);return this.releasePromises.set(e,r),r}async releasePluginResourcesOnce(e,t){let n=this.plugins.get(e);if(!n)return;try{await this.daemonRegistry.stopPlugin(e),this.logger.debug(`Stopped daemons for plugin: ${e}`)}catch(o){this.logger.error(`Failed to stop daemons for plugin: ${e}`,o)}let r=this.resourceScopes.get(e);if(this.resourceScopes.delete(e),r)try{await r.close(t)}catch(o){this.logger.error(`Failed to close resources for plugin ${e}`,o)}if(n.plugin.shutdown)try{await n.plugin.shutdown(),this.logger.debug(`Shutdown completed for plugin: ${e}`)}catch(o){this.logger.error(`Plugin shutdown failed for ${e}:`,o)}for(let o of this.daemonRegistry.getByPlugin(e))try{await this.daemonRegistry.unregister(o.name)}catch(i){this.logger.error(`Failed to unregister daemon ${o.name} for plugin ${e}`,i)}}}class UD{plugins;events;logger;constructor(e,t,n){this.plugins=e,this.events=t,this.logger=n.child("DependencyResolver")}async resolveInitializationOrder(e){this.logger.debug("Resolving plugin initialization order...");let t=Array.from(this.plugins.keys()),n=new Set,r=!0;while(r&&n.size<t.length){r=!1;for(let s of t){if(n.has(s))continue;if(!this.plugins.get(s))continue;if(this.getUnmetDependencies(s).length===0)try{await e(s),n.add(s),r=!0}catch(u){let d=qe(u);this.logger.error(`Failed to initialize plugin ${s}: ${d}`),n.add(s),r=!0}}}let o=t.filter((s)=>!n.has(s));if(o.length>0){let s=o.join(", ");this.logger.error(`Failed to initialize plugins due to dependency issues: ${s}`);for(let c of o){let l=this.getUnmetDependencies(c);this.logger.error(`Plugin ${c} has unmet dependencies: ${l.join(", ")}`);let u=this.plugins.get(c);if(u)u.status=Ht.ERROR,u.error=new $o(c,`Unmet dependencies: ${l.join(", ")}`);this.events.emit(qo.ERROR,c,u?.error)}}let i=new Set;for(let[s,c]of this.plugins)if(c.status===Ht.INITIALIZED)i.add(s);return this.logger.debug(`Resolved ${i.size} of ${t.length} plugins`),{initialized:i,failed:o}}getUnmetDependencies(e){let t=this.plugins.get(e);if(!t)return[];let{dependencies:n}=t,r=[];for(let o of n){let i=this.plugins.get(o);if(!i){r.push(o);continue}if(i.status!==Ht.INITIALIZED)r.push(o)}return r}}class WD{logger;projectionRegistry;constructor(e,t){this.logger=e.child("CapabilityRegistrar"),this.projectionRegistry=t}async registerCapabilities(e,t,n,r){if(!r?.executionOnly&&n.tools.length>0)e.registerTools(t,n.tools),this.logger.debug(`Registered ${n.tools.length} tools from ${t}`);if(!r?.executionOnly&&n.resources.length>0)e.registerResources(t,n.resources),this.logger.debug(`Registered ${n.resources.length} resources from ${t}`);if(!r?.executionOnly&&n.instructions)e.registerInstructions(t,n.instructions),this.logger.debug(`Registered instructions from ${t}`);let o=n.projectionRules??[];try{for(let i of o)this.projectionRegistry.registerRule(t,i)}catch(i){throw this.projectionRegistry.unregisterPlugin(t),i}if(o.length>0)this.logger.debug(`Registered ${o.length} projection rules from ${t}`)}}class CT{projections=new Map;rules=new Map;static createFresh(){return new CT}constructor(){}registerRule(e,t){if(!Object.isFrozen(t))throw Error(`Projection rule "${t.id}" must be created with defineProjectionRule`);let n=this.projections.get(t.id);if(n)throw Error(`Projection "${t.id}" is already registered by "${n.pluginId}"`);let r={id:t.id,pluginId:e,targetType:t.targetType,sources:t.sources.map((i)=>({kind:i.kind,types:[...i.types],...i.excludeTypes?{excludeTypes:[...i.excludeTypes]}:{}}))};this.projections.set(t.id,r),this.rules.set(t.id,t);let o=!0;return()=>{if(!o)return;if(o=!1,this.rules.get(t.id)===t)this.rules.delete(t.id);if(this.projections.get(t.id)===r)this.projections.delete(t.id)}}unregisterPlugin(e){for(let[t,n]of this.projections)if(n.pluginId===e)this.projections.delete(t),this.rules.delete(t)}list(){return Array.from(this.projections.values()).sort((e,t)=>e.id.localeCompare(t.id)).map(qve)}listRules(){return[...this.rules.values()].sort((e,t)=>e.id.localeCompare(t.id))}validate(e){let t=this.list(),n=new Set(e.map(({type:s})=>s));for(let s of t)if(!n.has(s.targetType))throw Error(`Projection "${s.id}" targets unregistered entity type "${s.targetType}"`);let r=e.filter(({projectionSource:s})=>s).map(({type:s})=>s).sort(),o=$ve(t,r),i=Wve(t,o)[0];if(i){let s=Hve(i,o);throw Error(`Projection cycle is not supported: ${[...s,s[0]].join(" -> ")}`)}return Lve({projections:t,edges:o,unknownSourceTypes:Bve(t,n)})}}function Bve(e,t){let n=[];for(let r of e){let o=[...new Set(r.sources.flatMap((i)=>[...i.types,...i.excludeTypes??[]]).filter((i)=>i!=="*"&&!t.has(i)))].sort();if(o.length>0)n.push({projectionId:r.id,types:o})}return n}function Lve(e){for(let t of e.projections){for(let n of t.sources){if(Object.freeze(n.types),n.excludeTypes)Object.freeze(n.excludeTypes);Object.freeze(n)}Object.freeze(t.sources),Object.freeze(t)}for(let t of e.edges)Object.freeze(t.causes),Object.freeze(t);for(let t of e.unknownSourceTypes)Object.freeze(t.types),Object.freeze(t);return Object.freeze(e.unknownSourceTypes),Object.freeze(e.projections),Object.freeze(e.edges),Object.freeze(e)}function qve(e){return{...e,sources:e.sources.map((t)=>({...t,types:[...t.types],...t.excludeTypes?{excludeTypes:[...t.excludeTypes]}:{}}))}}function $ve(e,t){let n=new Map;for(let r of e)for(let o of e){let i=Uve(r,o,t);if(i.length===0)continue;n.set(`${r.id}\x00${o.id}`,new Set(i))}return Array.from(n,([r,o])=>{let[i="",s=""]=r.split("\x00");return{from:i,to:s,causes:[...o].sort()}}).sort((r,o)=>r.from.localeCompare(o.from)||r.to.localeCompare(o.to))}function Uve(e,t,n){let r=[];for(let o of t.sources){let i=new Set(o.excludeTypes??[]);if((o.types.includes("*")?[...o.types.filter((c)=>c!=="*"),...n]:o.types).includes(e.targetType)&&!i.has(e.targetType))r.push(`entity:${e.targetType}`)}return[...new Set(r)]}function Wve(e,t){let n=e.map(({id:m})=>m).sort(),r=j6(n,t),o=new Map,i=new Map,s=[],c=new Set,l=[],u=0,d=(m)=>{o.set(m,u),i.set(m,u),u++,s.push(m),c.add(m);for(let v of r.get(m)??[])if(!o.has(v))d(v),i.set(m,Math.min(i.get(m)??0,i.get(v)??0));else if(c.has(v))i.set(m,Math.min(i.get(m)??0,o.get(v)??0));if(i.get(m)!==o.get(m))return;let g=[],h;do{if(h=s.pop(),!h)break;c.delete(h),g.push(h)}while(h!==m);let x=r.get(m)?.includes(m)??!1;if(g.length>1||x)l.push(g.sort())};for(let m of n)if(!o.has(m))d(m);return l.sort((m,g)=>(m[0]??"").localeCompare(g[0]??""))}function Hve(e,t){let n=new Set(e),r=j6(e,t),o=[...e].sort()[0];if(!o)return[];if(r.get(o)?.includes(o))return[o];let i=(s,c)=>{for(let l of r.get(s)??[]){if(!n.has(l))continue;if(l===o)return c;if(c.includes(l))continue;let u=i(l,[...c,l]);if(u)return u}return};return i(o,[o])??[...e].sort()}function j6(e,t){let n=new Map;for(let r of e)n.set(r,[]);for(let r of t){let o=n.get(r.from);if(o&&!o.includes(r.to))o.push(r.to)}for(let r of n.values())r.sort();return n}async function L6(e){let n=(await G.runPromise(G.all(e.map((r)=>G.either(G.tryPromise({try:r,catch:(o)=>o}))),{concurrency:"unbounded"}))).find(ur.isLeft);if(n)throw n.left}class ET{plugins=new Map;logger;events=new B6;daemonRegistry;shell=null;initializedPluginIds=[];pluginLifecycle;dependencyResolver;capabilityRegistrar;projectionRegistry=CT.createFresh();projectionGraph;static createFresh(e,t){return new ET(e,t)}setShell(e){this.shell=e}constructor(e,t){this.logger=e.child("PluginManager"),this.events=new B6,this.daemonRegistry=t,this.pluginLifecycle=new $D(this.plugins,this.events,this.daemonRegistry,this.projectionRegistry,e),this.dependencyResolver=new UD(this.plugins,this.events,e),this.capabilityRegistrar=new WD(e,this.projectionRegistry)}registerPlugin(e){if(!e.id)throw new $o("unknown","Registration failed: Plugin must have an id");if(this.logger.debug(`Registering plugin: ${e.id} (${e.version})`),this.plugins.has(e.id)){let o=this.plugins.get(e.id)?.plugin.version;throw new $o(e.id,`Registration failed: Plugin is already registered with version ${o}`)}let t=e.dependencies??[],n={plugin:e,status:Ht.REGISTERED,dependencies:t};this.plugins.set(e.id,n),this.logger.debug(`Registered plugin: ${e.id} (${e.version})`),this.events.emit(qo.REGISTERED,e.id,e)}async initializePlugins(e){this.logger.debug("Initializing plugins..."),this.initializedPluginIds=[];let t=await this.dependencyResolver.resolveInitializationOrder(async(n)=>{await this.initializePlugin(n,e)});this.logger.debug(`Initialized ${t.initialized.size} of ${this.plugins.size} plugins`)}async initializePlugin(e,t){if(!this.shell)throw new $o(e,"Cannot initialize plugin: Shell not set. Call setShell() first.");let n=this.shell;try{let r=await this.pluginLifecycle.initializePlugin(e,n,t);await this.capabilityRegistrar.registerCapabilities(n,e,r,{executionOnly:t?.executionOnly}),this.initializedPluginIds.push(e)}catch(r){throw await this.pluginLifecycle.failPluginInitialization(e,r),r}}async finalizePluginRegistrations(){this.logger.debug("Finalizing plugin registrations...");for(let n of this.initializedPluginIds)await this.pluginLifecycle.finalizePluginRegistration(n);if(!this.shell)throw Error("Cannot validate projections before the shell is set");let e=this.shell.getEntityRegistry(),t=this.projectionRegistry.validate(e.getAllEntityTypes().map((n)=>{let r=e.getEntityTypeConfig(n);return{type:n,projectionSource:r.projectionSource!==!1&&r.projectionSourceRole!=="excluded"}}));this.projectionGraph=t;for(let n of t.unknownSourceTypes)this.logger.warn("Projection declares entity source types no installed plugin registers",{projectionId:n.projectionId,types:n.types});this.logger.debug("Validated projection graph",{projections:t.projections.length,edges:t.edges.length})}getProjectionGraphSnapshot(){if(!this.projectionGraph)throw Error("Projection graph has not been finalized");return this.projectionGraph}getProjectionRulesSnapshot(){if(!this.projectionGraph)throw Error("Projection graph has not been finalized");return Object.freeze(this.projectionRegistry.listRules())}async readyPlugins(){this.logger.debug("Dispatching plugin ready hooks...");try{await L6(this.initializedPluginIds.map((e)=>()=>this.pluginLifecycle.readyPlugin(e)))}catch(e){for(let t of this.initializedPluginIds){let n=this.plugins.get(t);if(n?.status===Ht.ERROR)await this.pluginLifecycle.failPluginInitialization(t,n.error??e)}throw e}}async startPluginDaemons(){this.logger.debug("Starting plugin daemons..."),await L6(this.initializedPluginIds.map((e)=>()=>this.pluginLifecycle.startPluginDaemons(e)))}getPlugin(e){return this.plugins.get(e)?.plugin}getPluginStatus(e){return this.plugins.get(e)?.status}hasPlugin(e){return this.plugins.has(e)}isPluginInitialized(e){return this.plugins.get(e)?.status===Ht.INITIALIZED}getAllPluginIds(){return Array.from(this.plugins.keys())}getAllPlugins(){return new Map(this.plugins)}getFailedPlugins(){return Array.from(this.plugins.entries()).filter((e)=>e[1].status===Ht.ERROR&&e[1].error!==void 0).map(([e,t])=>({id:e,error:t.error}))}getPluginPackageName(e){return this.plugins.get(e)?.plugin.packageName}async disablePlugin(e){await this.pluginLifecycle.disablePlugin(e)}async shutdownPlugins(){let e=new Set;for(let t of[...this.initializedPluginIds].reverse())await this.disablePlugin(t),e.add(t);for(let t of[...this.plugins.keys()].reverse())if(!e.has(t))await this.disablePlugin(t)}on(e,t){this.events.on(e,t)}once(e,t){this.events.once(e,t)}off(e,t){this.events.off(e,t)}getEventEmitter(){return this.events}}var q6={public:0,trusted:1,admin:2},Jve=[{id:"dashboard",pluginId:"dashboard",label:"Dashboard",visibility:"public",requiresActiveSession:!1},{id:"web-chat",pluginId:"web-chat",label:"Chat",visibility:"trusted",requiresActiveSession:!0},{id:"studio",pluginId:"studio",label:"Studio",visibility:"public",requiresActiveSession:!0}];function Zve(e,t){let n=q6[t.permissionLevel??"public"],r=[];for(let{id:o,pluginId:i,label:s,visibility:c,requiresActiveSession:l}of Jve){let u=t.self?.id===o;if(!u&&(n<q6[c]||l&&t.hasActiveSession!==!0))continue;let d=e.filter((h)=>h.pluginId===i&&!(o==="studio"&&h.fullPath==="/chat")).map((h)=>h.fullPath).sort((h,x)=>h.length-x.length),m=o==="web-chat"&&d.length>0?e.find((h)=>h.pluginId==="studio"&&h.fullPath==="/chat")?.fullPath:void 0,g=u?t.self?.href:m??d[0];if(g!==void 0)r.push({id:o,label:s,href:g,isActive:o===t.activeId,...l?{requiresActiveSession:!0}:{}})}return r}export{fa as sa,Ag as ta,UA as ua,WA as va,GV as wa,QV as xa,KV as ya,YV as za,Che as Aa,Ehe as Ba,dv as Ca,Ihe as Da,cd as Ea,ld as Fa,ahe as Ga,che as Ha,khe as Ia,tG as Ja,Ahe as Ka,kd as La,Vve as Ma,Gve as Na,PT as Oa,Qve as Pa,Kve as Qa,Yve as Ra,Xve as Sa,eTe as Ta,tTe as Ua,nTe as Va,rTe as Wa,ud as Xa,HWe as Ya,jo as Za,Lhe as _a,gt as $a,kBe as ab,mv as bb,b as cb,ug as db,C as eb,Ec as fb,ee as gb,Sr as hb,Gp as ib,iZ as jb,vr as kb,Et as lb,Hn as mb,wc as nb,Ic as ob,LS as pb,lt as qb,un as rb,mg as sb,Re as tb,W as ub,wt as vb,kc as wb,vt as xb,pP as yb,so as zb,n2 as Ab,XS as Bb,ui as Cb,pi as Db,m2 as Eb,oge as Fb,ige as Gb,P as Hb,tt as Ib,JP as Jb,ZP as Kb,_c as Lb,tO as Mb,ur as Nb,mt as Ob,gn as Pb,Po as Qb,Rl as Rb,Ct as Sb,Bt as Tb,Ao as Ub,G as Vb,xr as Wb,Gl as Xb,eg as Yb,$i as Zb,aMe as _b,nO as $b,rO as ac,oO as bc,Ng as cc,Fg as dc,iO as ec,sO as fc,pe as gc,Tn as hc,au as ic,ha as jc,bG as kc,xG as lc,aye as mc,hv as nc,Fk as oc,wfe as pc,Ife as qc,zk as rc,jk as sc,Bg as tc,bv as uc,uO as vc,dye as wc,dO as xc,vv as yc,pO as zc,mO as Ac,vn as Bc,A as Cc,pn as Dc,bt as Ec,ao as Fc,ca as Gc,it as Hc,zo as Ic,f2 as Jc,Vi as Kc,vc as Lc,Wi as Mc,DS as Nc,Hi as Oc,Zp as Pc,Mo as Qc,kJ as Rc,bMe as Sc,xMe as Tc,oa as Uc,ir as Vc,kS as Wc,Ql as Xc,IJ as Yc,nd as Zc,pa as _c,jP as $c,di as ad,YP as bd,XP as cd,F2 as dd,Sc as ed,qk as fd,qge as gd,z2 as hd,av as id,eA as jd,j2 as kd,nA as ld,B2 as md,gye as nd,Tv as od,hye as pd,wv as qd,J2 as rd,X2 as sd,dA as td,bA as ud,HV as vd,Nv as wd,hO as xd,Lg as yd,bO as zd,Vxe as Ad,SO as Bd,Gxe as Cd,Qxe as Dd,Kxe as Ed,rxe as Fd,vd as Gd,d3 as Hd,h3 as Id,fD as Jd,Er as Kd,Yv as Ld,b3 as Md,yD as Nd,E3 as Od,th as Pd,w3 as Qd,Cd as Rd,I3 as Sd,pSe as Td,R3 as Ud,k3 as Vd,TSe as Wd,A3 as Xd,RSe as Yd,kSe as Zd,PSe as _d,ASe as $d,xD as ae,Sa as be,zSe as ce,SD as de,ED as ee,BSe as fe,jn as ge,Cye as he,Eye as ie,wye as je,Rye as ke,rQ as le,sQ as me,IO as ne,Pv as oe,SQ as pe,VZe as qe,RO as re,GZe as se,QZe as te,KZe as ue,MO as ve,cQ as we,cK as xe,Zbe as ye,Kbe as ze,uQ as Ae,dQ as Be,wO as Ce,fQ as De,nxe as Ee,iVe as Fe,yK as Ge,jv as He,VO as Ie,GO as Je,AK as Ke,Td as Le,qv as Me,$v as Ne,Kg as Oe,Uv as Pe,jK as Qe,Yg as Re,hxe as Se,yxe as Te,bxe as Ue,xxe as Ve,Sxe as We,Xg as Xe,eh as Ye,qSe as Ze,L3 as _e,J3 as $e,Nxe as af,Bxe as bf,Vv as cf,GK as df,QK as ef,Lxe as ff,Z3 as gf,Qv as hf,pD as if,Zxe as jf,V3 as kf,Ed as lf,Y3 as mf,X3 as nf,e6 as of,t6 as pf,r6 as qf,RD as rf,kD as sf,a6 as tf,PD as uf,aT as vf,u6 as wf,cT as xf,AD as yf,p6 as zf,d6 as Af,f6 as Bf,g6 as Cf,lT as Df,b6 as Ef,x6 as Ff,pT as Gf,oh as Hf,ih as If,S6 as Jf,v6 as Kf,T6 as Lf,FD as Mf,sh as Nf,E6 as Of,w6 as Pf,I6 as Qf,R6 as Rf,k6 as Sf,Dve as Tf,yT as Uf,P6 as Vf,bT as Wf,xT as Xf,ST as Yf,A6 as Zf,uu as _f,vT as $f,lh as ag,O6 as bg,LD as cg,M6 as dg,jve as eg,$o as fg,ET as gg,Zve as hg};
|
|
166
166
|
|
|
167
|
-
//# debugId=
|
|
168
|
-
//# sourceMappingURL=index-
|
|
167
|
+
//# debugId=16D0B68B321DE7AA64756E2164756E21
|
|
168
|
+
//# sourceMappingURL=index-5kpm747w.js.map
|