@synadia-ai/agent-fabric-pi 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/BUILD +4 -0
- package/README.md +43 -263
- package/dist/channel.js +6 -0
- package/dist/chunk-sjpe67s3.js +37 -0
- package/dist/fabric.js +5 -0
- package/dist/nats-channel.js +6 -0
- package/package.json +31 -69
- package/CHANGELOG.md +0 -17
- package/dist/index.cjs +0 -154
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -28
- package/dist/index.d.ts +0 -28
- package/dist/index.js +0 -108
- package/dist/index.js.map +0 -1
package/dist/fabric.js
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import{a as Tt,f as It,g as Me,i as Ue,j as oe,v as He,w as X}from"./chunk-sjpe67s3.js";import{AsyncLocalStorage as Ot}from"node:async_hooks";var $t=Tt(It(),1);import{execFile as Nt}from"node:child_process";import{createHash as Ge,randomUUID as Se}from"node:crypto";import{mkdir as jt,realpath as Pt}from"node:fs/promises";import{tmpdir as Lt,platform as Be,arch as Re,homedir as xe}from"node:os";import{join as ie,resolve as qt}from"node:path";import{mkdirSync as Mt,readFileSync as Ut,writeFileSync as Ht,renameSync as Gt,lstatSync as Xn,realpathSync as zn,openSync as Jn,constants as Wn,fsyncSync as Yn,closeSync as Kn}from"node:fs";var Vt=1,Ve="TRACE.edges",Xe="thread_id",ze="root_id",Xt="X-Synadia-Thread-ID",zt="X-Synadia-Root-ID",Jt=/[\u0000-\u0020\u007f\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]/;function Wt(e){if(e===void 0)return;let t=e.edgeSubject;if(t===void 0||t===null)return;let r=(n)=>{throw new Me(`trace.edgeSubject ${JSON.stringify(t)}: ${n}`)};if(typeof t!=="string")r("must be a string or null");if(t.length===0)r("must not be empty");for(let n of t.split(".")){if(n.length===0)r("must not contain an empty token");if(Jt.test(n))r("must not contain whitespace or control characters");if(n.includes("*")||n.includes(">"))r("must not contain wildcards")}}var Yt=Symbol.for("@synadia-ai/agent-fabric:trace-record-counts"),Z=(()=>{let e=globalThis;return e[Yt]??={published:0,dropped:0}})();function Kt(){Z.published+=1}function ke(){Z.dropped+=1}function Zt(){return Object.freeze({published:Z.published,dropped:Z.dropped})}var Qt=Symbol.for("@synadia-ai/agent-fabric:trace-scope"),Je=(()=>{let e=globalThis;return e[Qt]??=new Ot})();function J(e,t){return Je.run(e,t)}function N(){return Je.getStore()}function We(){let e=N();if(e===void 0)return{};return e.turnCountHint+=1,{[Xt]:e.threadId,[zt]:e.rootId}}var fe=32,er=new RegExp(`^[0-9a-f]{${fe}}$`);function ce(e){return er.test(e)}function he(){let e=new Uint8Array(fe/2);crypto.getRandomValues(e);let t="";for(let r of e)t+=r.toString(16).padStart(2,"0");return t}var tr=256,rr=/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/;function pe(e){if(rr.test(e))return!1;let t=Array.from(e).length;return t>0&&t<=tr}function nr(e,t,r,n,o,i){let a=he(),s={version:Vt,kind:"edge",record_id:a,ts:Math.floor(Date.now()/1000),agent:e,thread_id:t,parent_id:r,root_id:n,tool_call_id:o,turn_count_hint:i};return{recordId:a,payload:new TextEncoder().encode(JSON.stringify(s))}}var or="toolCallId";function Ye(e={}){Wt(e);let t=e.edgeSubject===void 0?Ve:e.edgeSubject;return{promptInterceptor:ir(t),requestInterceptor:cr,heartbeatExtras:t===null?()=>({}):()=>{let r=Zt();return{records_published:r.published,records_dropped:r.dropped}}}}function ir(e){return{beforePrompt(t){let r=t.context[or],n=typeof r==="string"&&pe(r)?r:null,o={...ar(),toolCallId:n};return{fields:{[Xe]:o.threadId,[ze]:o.rootId},state:o}},async beforePublish(t,r){let n=r?.state;if(e===null||n===void 0)return;await sr(t,e,n)}}}function ar(){let e=he(),t=N();if(t===void 0)return{threadId:e,parentId:null,rootId:e,turnCountHint:0};return{threadId:e,parentId:t.threadId,rootId:t.rootId,turnCountHint:t.turnCountHint}}async function sr(e,t,r){if(!e.identity.canSign){ur(e.connection),ke();return}try{let n=await e.identity.selfId(),o=nr(n,r.threadId,r.parentId,r.rootId,r.toolCallId,r.turnCountHint);await e.identity.publishSigned(t,o.payload,{nonce:o.recordId}),Kt()}catch(n){ke(),console.warn(`@synadia-ai/agent-fabric: failed to publish edge record on ${t}`,n)}}var Te=new WeakSet;function ur(e){if(Te.has(e))return;Te.add(e),console.warn("@synadia-ai/agent-fabric: tracing is enabled but no identity signer is configured; edge records are not published (consumers ignore unsigned records). Pass identity: { signer } to sign them.")}var cr={async aroundRequest(e,t){await J(lr(e.envelope.extras??{}),t)}},dr="envelope `thread_id` and `root_id` must be given together";function lr(e){let t=Ie(e,Xe),r=Ie(e,ze);if(t===void 0!==(r===void 0))throw new X(400,dr);if(t!==void 0&&r!==void 0)return{threadId:t,rootId:r,turnCountHint:0};let n=he();return{threadId:n,rootId:n,turnCountHint:0}}function Ie(e,t){let r=Object.hasOwn(e,t)?e[t]:void 0;if(r===void 0||r===null)return;if(typeof r!=="string")throw new X(400,`envelope \`${t}\` must be a string`);if(r==="")return;if(!ce(r))throw new X(400,`envelope \`${t}\` must be ${fe} lowercase hex characters`);return r}var Q="sp-ref:";var Ke=/sp-(?:ref|r1):[A-Za-z0-9_-]+/g,De="scratchpad_refs_ok";function ee(e){return e.match(Ke)??[]}function Oe(e,t){return e.replace(Ke,(r)=>t===void 0||t.includes(r)?"":r).replace(/[ \t]+$/gm,"").replace(/\n{3,}/g,`
|
|
2
|
+
|
|
3
|
+
`).trim()}function fr(e){if(!e.startsWith(Q))return;let t;try{t=JSON.parse(Buffer.from(e.slice(Q.length),"base64url").toString("utf8"))}catch{return}if(typeof t!=="object"||t===null)return;let r=t.creator;return typeof r==="string"&&r!==""?r:void 0}function de(e){return e[De]==="true"}function z(e){let t=e.indexOf(".");if(t<=0||t===e.length-1)throw Error(`not an agent identity: ${e}`);return{account:e.slice(0,t),user:e.slice(t+1)}}var Ze="sp-grant",hr=1e4,se="agents.prompt.",pr=`agents.${Ze}.`;function Qe(e){if(!e.startsWith(se)||e===se)throw Error(`not a prompt address: ${e}`);return pr+e.slice(se.length)}function Dr(e){let{trace:t}=e;return JSON.stringify({reference:e.reference,grantee:e.grantee,...t!==void 0?{trace:{thread_id:t.thread_id,root_id:t.root_id,...t.tool_call_id!==void 0?{tool_call_id:t.tool_call_id}:{}}}:{}})}function gr(e){return JSON.stringify(e.granted?{granted:!0}:{granted:!1,reason:e.reason})}async function mr(e,t,r,n={}){let o;try{let s=await e.requestSigned(Qe(t),Dr(r),{timeoutMs:n.timeoutMs??hr});o=JSON.parse(s.string())}catch(s){return R(`no answer from ${t}: ${te(s)}`)}if(typeof o!=="object"||o===null)return R("refused without a reason");let{granted:i,reason:a}=o;if(i===!0)return{granted:!0};return R(typeof a==="string"?a:"refused without a reason")}async function vr(e,t,r,n=oe){let o=yr(t);if(o===void 0)return R("not a grant request");let i,a;try{i=z(e),a=z(o.grantee)}catch{return R("grantee is not an agent identity")}let s=o.trace,h=s!==void 0?{threadId:s.thread_id,rootId:s.root_id}:void 0,l=!1;try{l=await r.owns(o.reference)}catch{}if(!l)return R("the reference does not point into this agent's volume");let p;try{p=await r.granted(o.reference,i)}catch(g){return n.error("grant request: the ledger could not be read",{error:te(g)}),R("the grant could not be made")}if(p===void 0)return R("this agent holds no live read grant it made to the requester on that reference");if(p!=="first-hand")return R("the requester's own grant was made at another agent's request; only an agent this agent handed the reference itself may ask for another");if(a.account===i.account&&a.user===i.user)return R("a grant request is for another agent, not for the requester");try{await r.grantRead(o.reference,a,h,s?.tool_call_id,"on-request")}catch(g){return n.error("grant request: the grant failed",{error:te(g)}),R("the grant could not be made")}return n.info("grant request: granted",{grantee:o.grantee,requester:e}),{granted:!0}}function Fr(e){let{scratchPad:t}=e,r=e.logger??oe,n=new He({minSenderTrust:"signed",logger:r});async function o(i){let a=await n.admitPrompt(i);if(!a.ok)return R(a.description);let s=a.sender;if(s?.trust!=="verified")return R("a grant request must be signed");return vr(s.id,i.string(),t,r)}return{name:Ze,subject:Qe(e.promptAddress),queue:"agents",handler:(i,a)=>{if(i)return;o(a).catch((s)=>(r.error("grant request failed",{error:te(s)}),R("the grant could not be made"))).then((s)=>{if(!s.granted)r.info("grant request refused",{reason:s.reason});a.respond(gr(s))})}}}function yr(e){let t;try{t=JSON.parse(e)}catch{return}if(typeof t!=="object"||t===null||Array.isArray(t))return;let{reference:r,grantee:n,trace:o}=t;if(typeof r!=="string"||typeof n!=="string")return;if(typeof o!=="object"||o===null)return{reference:r,grantee:n};let{thread_id:i,root_id:a,tool_call_id:s}=o;if(typeof i!=="string"||typeof a!=="string"||!ce(i)||!ce(a))return{reference:r,grantee:n};return{reference:r,grantee:n,trace:{thread_id:i,root_id:a,...typeof s==="string"&&pe(s)?{tool_call_id:s}:{}}}}function R(e){return{granted:!1,reason:e}}function te(e){return e instanceof Error?e.message:String(e)}var et="reads_scratchpad_references",Er=class{requestInterceptor;#e;#t;#r;#o;#i=new Set;#n=new Map;constructor(e){this.#e=e.scratchPad,this.#t=e.agents,this.#r=e.discoverTimeoutMs,this.#o=e.grantRequestTimeoutMs,this.requestInterceptor={aroundRequest:(t,r)=>(this.remember(t.envelope.prompt),r())}}remember(e){for(let t of ee(e))this.#i.add(t)}async grantCaller(e,t){if(this.remember(e),t?.trust!=="verified")return!1;if(!await this.#e.owns(e))throw Error("the reference points into another agent's volume; only its creator grants");return await this.#e.grantRead(e,z(t.id),Ne(),void 0,"first-hand"),!0}discoveryFields(e){return this.#a(e),{[et]:de(e.metadata)}}async beforePrompt(e){let{address:t,target:r}=e,n=ee(e.prompt);if(n.length===0)return;if(!de(r.metadata)){let f=Oe(e.prompt);if(f==="")return{error:`the prompt was not sent: "${t}" does not read ScratchPad references (discover_agents: reads_scratchpad_references is false), and the prompt held nothing but references; put the content they point at into the prompt itself`};return{prompt:f,fields:{references_removed:n.length,note:`"${t}" does not read ScratchPad references: ${n.length} reference(s) were removed from your prompt, it got only the text, and nothing was granted`}}}let o=[...new Set(n)],i=o.filter((f)=>!this.#i.has(f));if(i.length>0)return{error:`the prompt was not sent: ${i.length} of its ScratchPad references (${i[0].slice(0,24)}…) is not one you were given. Copy each reference exactly as you received it, the whole token, or leave it out.`};if(r.identity===void 0||!r.idSigVerified)return{error:`cannot hand a ScratchPad reference to "${t}": its identity is not verified, so no read grant can be issued; put the content in the prompt instead`};let a=z(r.identity),s=Ne(),h=e.toolCallId!==void 0&&pe(e.toolCallId)?e.toolCallId:void 0,l=[],p="";for(let f of o){try{if(await this.#e.owns(f)){await this.#e.grantRead(f,a,s,h,"first-hand");continue}}catch(b){return{error:`could not grant "${t}" read on ${f.slice(0,32)}…: ${wr(b)}; the prompt was not sent`}}let F=await this.#s(f,t,r.identity,s,h);if(!F.granted)l.push(f),p=F.reason}if(l.length===0)return;let g=n.filter((f)=>l.includes(f)).length,v=Oe(e.prompt,l);if(v==="")return{error:`the prompt was not sent: it held nothing but references, and their creator did not grant "${t}" read (${p}); put the content they point at into the prompt itself`};return{prompt:v,fields:{references_removed:g,note:`${g} reference(s) were removed from your prompt, and "${t}" got only the text: you did not create that content, and its creator did not grant "${t}" read (${p}). If it needs the content, put the content itself in a prompt`}}}afterReply(e){this.remember(e.text)}async#s(e,t,r,n,o){let i=fr(e);if(i===void 0&&this.#e.resolveReference)try{i=(await this.#e.resolveReference(e,n)).creator}catch{return{granted:!1,reason:"the reference could not be resolved"}}if(i===void 0)return{granted:!1,reason:"the reference does not name its creator"};if(i===t)return{granted:!0};let a=await this.#u(i);if(a===void 0||!a.idSigVerified)return{granted:!1,reason:`its creator, ${i}, is not on the fabric with a verified identity`};let s={reference:e,grantee:r,...n!==void 0?{trace:{thread_id:n.threadId,root_id:n.rootId,...o!==void 0?{tool_call_id:o}:{}}}:{}};return mr(this.#t,i,s,this.#o!==void 0?{timeoutMs:this.#o}:{})}async#u(e){let t=this.#n.get(e);if(t!==void 0)return t;try{let r=await this.#t.discover(this.#r!==void 0?{timeoutMs:this.#r}:{});for(let n of r)this.#a(n)}catch{}return this.#n.get(e)}#a(e){let t=this.#n.get(e.promptSubject);if(t===void 0||e.idSigVerified||!t.idSigVerified)this.#n.set(e.promptSubject,e)}};function br(e){return new Er(e)}function Ne(){let e=N();return e!==void 0?{threadId:e.threadId,rootId:e.rootId}:void 0}function wr(e){return e instanceof Error?e.message:String(e)}var Ar=class extends Error{code;unknown;local;constructor(e,t,r={}){super(t,r.cause===void 0?void 0:{cause:r.cause});this.name="NativeScratchPadError",this.code=e,this.unknown=r.unknown??!1,this.local=r.local??!1}};function Cr(e,t){return new Ar("invalid",e,{local:!0,cause:t})}var _r=/[\u0378\u0379\u0380-\u0383\u038B\u038D\u03A2\u0530\u0557\u0558\u058B\u058C\u0590\u05C8-\u05CF\u05EB-\u05EE\u05F5-\u05FF\u070E\u074B\u074C\u07B2-\u07BF\u07FB\u07FC\u082E\u082F\u083F\u085C\u085D\u085F\u086B-\u086F\u088F\u0892-\u0897\u0984\u098D\u098E\u0991\u0992\u09A9\u09B1\u09B3-\u09B5\u09BA\u09BB\u09C5\u09C6\u09C9\u09CA\u09CF-\u09D6\u09D8-\u09DB\u09DE\u09E4\u09E5\u09FF\u0A00\u0A04\u0A0B-\u0A0E\u0A11\u0A12\u0A29\u0A31\u0A34\u0A37\u0A3A\u0A3B\u0A3D\u0A43-\u0A46\u0A49\u0A4A\u0A4E-\u0A50\u0A52-\u0A58\u0A5D\u0A5F-\u0A65\u0A77-\u0A80\u0A84\u0A8E\u0A92\u0AA9\u0AB1\u0AB4\u0ABA\u0ABB\u0AC6\u0ACA\u0ACE\u0ACF\u0AD1-\u0ADF\u0AE4\u0AE5\u0AF2-\u0AF8\u0B00\u0B04\u0B0D\u0B0E\u0B11\u0B12\u0B29\u0B31\u0B34\u0B3A\u0B3B\u0B45\u0B46\u0B49\u0B4A\u0B4E-\u0B54\u0B58-\u0B5B\u0B5E\u0B64\u0B65\u0B78-\u0B81\u0B84\u0B8B-\u0B8D\u0B91\u0B96-\u0B98\u0B9B\u0B9D\u0BA0-\u0BA2\u0BA5-\u0BA7\u0BAB-\u0BAD\u0BBA-\u0BBD\u0BC3-\u0BC5\u0BC9\u0BCE\u0BCF\u0BD1-\u0BD6\u0BD8-\u0BE5\u0BFB-\u0BFF\u0C0D\u0C11\u0C29\u0C3A\u0C3B\u0C45\u0C49\u0C4E-\u0C54\u0C57\u0C5B\u0C5C\u0C5E\u0C5F\u0C64\u0C65\u0C70-\u0C76\u0C8D\u0C91\u0CA9\u0CB4\u0CBA\u0CBB\u0CC5\u0CC9\u0CCE-\u0CD4\u0CD7-\u0CDC\u0CDF\u0CE4\u0CE5\u0CF0\u0CF4-\u0CFF\u0D0D\u0D11\u0D45\u0D49\u0D50-\u0D53\u0D64\u0D65\u0D80\u0D84\u0D97-\u0D99\u0DB2\u0DBC\u0DBE\u0DBF\u0DC7-\u0DC9\u0DCB-\u0DCE\u0DD5\u0DD7\u0DE0-\u0DE5\u0DF0\u0DF1\u0DF5-\u0E00\u0E3B-\u0E3E\u0E5C-\u0E80\u0E83\u0E85\u0E8B\u0EA4\u0EA6\u0EBE\u0EBF\u0EC5\u0EC7\u0ECF\u0EDA\u0EDB\u0EE0-\u0EFF\u0F48\u0F6D-\u0F70\u0F98\u0FBD\u0FCD\u0FDB-\u0FFF\u10C6\u10C8-\u10CC\u10CE\u10CF\u1249\u124E\u124F\u1257\u1259\u125E\u125F\u1289\u128E\u128F\u12B1\u12B6\u12B7\u12BF\u12C1\u12C6\u12C7\u12D7\u1311\u1316\u1317\u135B\u135C\u137D-\u137F\u139A-\u139F\u13F6\u13F7\u13FE\u13FF\u169D-\u169F\u16F9-\u16FF\u1716-\u171E\u1737-\u173F\u1754-\u175F\u176D\u1771\u1774-\u177F\u17DE\u17DF\u17EA-\u17EF\u17FA-\u17FF\u181A-\u181F\u1879-\u187F\u18AB-\u18AF\u18F6-\u18FF\u191F\u192C-\u192F\u193C-\u193F\u1941-\u1943\u196E\u196F\u1975-\u197F\u19AC-\u19AF\u19CA-\u19CF\u19DB-\u19DD\u1A1C\u1A1D\u1A5F\u1A7D\u1A7E\u1A8A-\u1A8F\u1A9A-\u1A9F\u1AAE\u1AAF\u1ACF-\u1AFF\u1B4D-\u1B4F\u1B7F\u1BF4-\u1BFB\u1C38-\u1C3A\u1C4A-\u1C4C\u1C89-\u1C8F\u1CBB\u1CBC\u1CC8-\u1CCF\u1CFB-\u1CFF\u1F16\u1F17\u1F1E\u1F1F\u1F46\u1F47\u1F4E\u1F4F\u1F58\u1F5A\u1F5C\u1F5E\u1F7E\u1F7F\u1FB5\u1FC5\u1FD4\u1FD5\u1FDC\u1FF0\u1FF1\u1FF5\u1FFF\u2065\u2072\u2073\u208F\u209D-\u209F\u20C1-\u20CF\u20F1-\u20FF\u218C-\u218F\u2427-\u243F\u244B-\u245F\u2B74\u2B75\u2B96\u2CF4-\u2CF8\u2D26\u2D28-\u2D2C\u2D2E\u2D2F\u2D68-\u2D6E\u2D71-\u2D7E\u2D97-\u2D9F\u2DA7\u2DAF\u2DB7\u2DBF\u2DC7\u2DCF\u2DD7\u2DDF\u2E5E-\u2E7F\u2E9A\u2EF4-\u2EFF\u2FD6-\u2FEF\u2FFC-\u2FFF\u3040\u3097\u3098\u3100-\u3104\u3130\u318F\u31E4-\u31EF\u321F\uA48D-\uA48F\uA4C7-\uA4CF\uA62C-\uA63F\uA6F8-\uA6FF\uA7CB-\uA7CF\uA7D2\uA7D4\uA7DA-\uA7F1\uA82D-\uA82F\uA83A-\uA83F\uA878-\uA87F\uA8C6-\uA8CD\uA8DA-\uA8DF\uA954-\uA95E\uA97D-\uA97F\uA9CE\uA9DA-\uA9DD\uA9FF\uAA37-\uAA3F\uAA4E\uAA4F\uAA5A\uAA5B\uAAC3-\uAADA\uAAF7-\uAB00\uAB07\uAB08\uAB0F\uAB10\uAB17-\uAB1F\uAB27\uAB2F\uAB6C-\uAB6F\uABEE\uABEF\uABFA-\uABFF\uD7A4-\uD7AF\uD7C7-\uD7CA\uD7FC-\uD7FF\uFA6E\uFA6F\uFADA-\uFAFF\uFB07-\uFB12\uFB18-\uFB1C\uFB37\uFB3D\uFB3F\uFB42\uFB45\uFBC3-\uFBD2\uFD90\uFD91\uFDC8-\uFDCE\uFDD0-\uFDEF\uFE1A-\uFE1F\uFE53\uFE67\uFE6C-\uFE6F\uFE75\uFEFD\uFEFE\uFF00\uFFBF-\uFFC1\uFFC8\uFFC9\uFFD0\uFFD1\uFFD8\uFFD9\uFFDD-\uFFDF\uFFE7\uFFEF-\uFFF8\uFFFE\uFFFF]|\uD800[\uDC0C\uDC27\uDC3B\uDC3E\uDC4E\uDC4F\uDC5E-\uDC7F\uDCFB-\uDCFF\uDD03-\uDD06\uDD34-\uDD36\uDD8F\uDD9D-\uDD9F\uDDA1-\uDDCF\uDDFE-\uDE7F\uDE9D-\uDE9F\uDED1-\uDEDF\uDEFC-\uDEFF\uDF24-\uDF2C\uDF4B-\uDF4F\uDF7B-\uDF7F\uDF9E\uDFC4-\uDFC7\uDFD6-\uDFFF]|\uD801[\uDC9E\uDC9F\uDCAA-\uDCAF\uDCD4-\uDCD7\uDCFC-\uDCFF\uDD28-\uDD2F\uDD64-\uDD6E\uDD7B\uDD8B\uDD93\uDD96\uDDA2\uDDB2\uDDBA\uDDBD-\uDDFF\uDF37-\uDF3F\uDF56-\uDF5F\uDF68-\uDF7F\uDF86\uDFB1\uDFBB-\uDFFF]|\uD802[\uDC06\uDC07\uDC09\uDC36\uDC39-\uDC3B\uDC3D\uDC3E\uDC56\uDC9F-\uDCA6\uDCB0-\uDCDF\uDCF3\uDCF6-\uDCFA\uDD1C-\uDD1E\uDD3A-\uDD3E\uDD40-\uDD7F\uDDB8-\uDDBB\uDDD0\uDDD1\uDE04\uDE07-\uDE0B\uDE14\uDE18\uDE36\uDE37\uDE3B-\uDE3E\uDE49-\uDE4F\uDE59-\uDE5F\uDEA0-\uDEBF\uDEE7-\uDEEA\uDEF7-\uDEFF\uDF36-\uDF38\uDF56\uDF57\uDF73-\uDF77\uDF92-\uDF98\uDF9D-\uDFA8\uDFB0-\uDFFF]|\uD803[\uDC49-\uDC7F\uDCB3-\uDCBF\uDCF3-\uDCF9\uDD28-\uDD2F\uDD3A-\uDE5F\uDE7F\uDEAA\uDEAE\uDEAF\uDEB2-\uDEFC\uDF28-\uDF2F\uDF5A-\uDF6F\uDF8A-\uDFAF\uDFCC-\uDFDF\uDFF7-\uDFFF]|\uD804[\uDC4E-\uDC51\uDC76-\uDC7E\uDCC3-\uDCCC\uDCCE\uDCCF\uDCE9-\uDCEF\uDCFA-\uDCFF\uDD35\uDD48-\uDD4F\uDD77-\uDD7F\uDDE0\uDDF5-\uDDFF\uDE12\uDE42-\uDE7F\uDE87\uDE89\uDE8E\uDE9E\uDEAA-\uDEAF\uDEEB-\uDEEF\uDEFA-\uDEFF\uDF04\uDF0D\uDF0E\uDF11\uDF12\uDF29\uDF31\uDF34\uDF3A\uDF45\uDF46\uDF49\uDF4A\uDF4E\uDF4F\uDF51-\uDF56\uDF58-\uDF5C\uDF64\uDF65\uDF6D-\uDF6F\uDF75-\uDFFF]|\uD805[\uDC5C\uDC62-\uDC7F\uDCC8-\uDCCF\uDCDA-\uDD7F\uDDB6\uDDB7\uDDDE-\uDDFF\uDE45-\uDE4F\uDE5A-\uDE5F\uDE6D-\uDE7F\uDEBA-\uDEBF\uDECA-\uDEFF\uDF1B\uDF1C\uDF2C-\uDF2F\uDF47-\uDFFF]|\uD806[\uDC3C-\uDC9F\uDCF3-\uDCFE\uDD07\uDD08\uDD0A\uDD0B\uDD14\uDD17\uDD36\uDD39\uDD3A\uDD47-\uDD4F\uDD5A-\uDD9F\uDDA8\uDDA9\uDDD8\uDDD9\uDDE5-\uDDFF\uDE48-\uDE4F\uDEA3-\uDEAF\uDEF9-\uDEFF\uDF0A-\uDFFF]|\uD807[\uDC09\uDC37\uDC46-\uDC4F\uDC6D-\uDC6F\uDC90\uDC91\uDCA8\uDCB7-\uDCFF\uDD07\uDD0A\uDD37-\uDD39\uDD3B\uDD3E\uDD48-\uDD4F\uDD5A-\uDD5F\uDD66\uDD69\uDD8F\uDD92\uDD99-\uDD9F\uDDAA-\uDEDF\uDEF9-\uDEFF\uDF11\uDF3B-\uDF3D\uDF5A-\uDFAF\uDFB1-\uDFBF\uDFF2-\uDFFE]|\uD808[\uDF9A-\uDFFF]|\uD809[\uDC6F\uDC75-\uDC7F\uDD44-\uDFFF]|[\uD80A\uD80E-\uD810\uD812-\uD819\uD824-\uD82A\uD82D\uD82E\uD830-\uD832\uD83F\uD87B-\uD87D\uD87F\uD889-\uDB3F\uDB41-\uDB7F][\uDC00-\uDFFF]|\uD80B[\uDC00-\uDF8F\uDFF3-\uDFFF]|\uD80D[\uDC56-\uDFFF]|\uD811[\uDE47-\uDFFF]|\uD81A[\uDE39-\uDE3F\uDE5F\uDE6A-\uDE6D\uDEBF\uDECA-\uDECF\uDEEE\uDEEF\uDEF6-\uDEFF\uDF46-\uDF4F\uDF5A\uDF62\uDF78-\uDF7C\uDF90-\uDFFF]|\uD81B[\uDC00-\uDE3F\uDE9B-\uDEFF\uDF4B-\uDF4E\uDF88-\uDF8E\uDFA0-\uDFDF\uDFE5-\uDFEF\uDFF2-\uDFFF]|\uD821[\uDFF8-\uDFFF]|\uD823[\uDCD6-\uDCFF\uDD09-\uDFFF]|\uD82B[\uDC00-\uDFEF\uDFF4\uDFFC\uDFFF]|\uD82C[\uDD23-\uDD31\uDD33-\uDD4F\uDD53\uDD54\uDD56-\uDD63\uDD68-\uDD6F\uDEFC-\uDFFF]|\uD82F[\uDC6B-\uDC6F\uDC7D-\uDC7F\uDC89-\uDC8F\uDC9A\uDC9B\uDCA4-\uDFFF]|\uD833[\uDC00-\uDEFF\uDF2E\uDF2F\uDF47-\uDF4F\uDFC4-\uDFFF]|\uD834[\uDCF6-\uDCFF\uDD27\uDD28\uDDEB-\uDDFF\uDE46-\uDEBF\uDED4-\uDEDF\uDEF4-\uDEFF\uDF57-\uDF5F\uDF79-\uDFFF]|\uD835[\uDC55\uDC9D\uDCA0\uDCA1\uDCA3\uDCA4\uDCA7\uDCA8\uDCAD\uDCBA\uDCBC\uDCC4\uDD06\uDD0B\uDD0C\uDD15\uDD1D\uDD3A\uDD3F\uDD45\uDD47-\uDD49\uDD51\uDEA6\uDEA7\uDFCC\uDFCD]|\uD836[\uDE8C-\uDE9A\uDEA0\uDEB0-\uDFFF]|\uD837[\uDC00-\uDEFF\uDF1F-\uDF24\uDF2B-\uDFFF]|\uD838[\uDC07\uDC19\uDC1A\uDC22\uDC25\uDC2B-\uDC2F\uDC6E-\uDC8E\uDC90-\uDCFF\uDD2D-\uDD2F\uDD3E\uDD3F\uDD4A-\uDD4D\uDD50-\uDE8F\uDEAF-\uDEBF\uDEFA-\uDEFE\uDF00-\uDFFF]|\uD839[\uDC00-\uDCCF\uDCFA-\uDFDF\uDFE7\uDFEC\uDFEF\uDFFF]|\uD83A[\uDCC5\uDCC6\uDCD7-\uDCFF\uDD4C-\uDD4F\uDD5A-\uDD5D\uDD60-\uDFFF]|\uD83B[\uDC00-\uDC70\uDCB5-\uDD00\uDD3E-\uDDFF\uDE04\uDE20\uDE23\uDE25\uDE26\uDE28\uDE33\uDE38\uDE3A\uDE3C-\uDE41\uDE43-\uDE46\uDE48\uDE4A\uDE4C\uDE50\uDE53\uDE55\uDE56\uDE58\uDE5A\uDE5C\uDE5E\uDE60\uDE63\uDE65\uDE66\uDE6B\uDE73\uDE78\uDE7D\uDE7F\uDE8A\uDE9C-\uDEA0\uDEA4\uDEAA\uDEBC-\uDEEF\uDEF2-\uDFFF]|\uD83C[\uDC2C-\uDC2F\uDC94-\uDC9F\uDCAF\uDCB0\uDCC0\uDCD0\uDCF6-\uDCFF\uDDAE-\uDDE5\uDE03-\uDE0F\uDE3C-\uDE3F\uDE49-\uDE4F\uDE52-\uDE5F\uDE66-\uDEFF]|\uD83D[\uDED8-\uDEDB\uDEED-\uDEEF\uDEFD-\uDEFF\uDF77-\uDF7A\uDFDA-\uDFDF\uDFEC-\uDFEF\uDFF1-\uDFFF]|\uD83E[\uDC0C-\uDC0F\uDC48-\uDC4F\uDC5A-\uDC5F\uDC88-\uDC8F\uDCAE\uDCAF\uDCB2-\uDCFF\uDE54-\uDE5F\uDE6E\uDE6F\uDE7D-\uDE7F\uDE89-\uDE8F\uDEBE\uDEC6-\uDECD\uDEDC-\uDEDF\uDEE9-\uDEEF\uDEF9-\uDEFF\uDF93\uDFCB-\uDFEF\uDFFA-\uDFFF]|\uD869[\uDEE0-\uDEFF]|\uD86D[\uDF3A-\uDF3F]|\uD86E[\uDC1E\uDC1F]|\uD873[\uDEA2-\uDEAF]|\uD87A[\uDFE1-\uDFFF]|\uD87E[\uDE1E-\uDFFF]|\uD884[\uDF4B-\uDF4F]|\uD888[\uDFB0-\uDFFF]|\uDB40[\uDC00\uDC02-\uDC1F\uDC80-\uDCFF\uDDF0-\uDFFF]|[\uDBBF\uDBFF][\uDFFE\uDFFF]/;var Sr=524288,tt=921600;var Br=8192,Rr=128,xr=16384,kr=131072;var Tr=Sr;var Ir=8,rt=8,Or=16,Nr=3600,jr="AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA";var Zn=Object.freeze({object_bytes:tt,read_bytes:Tr,control_bytes:xr,reply_bytes:kr,writers:Ir,retentions:rt,grants:Or,grant_seconds:Nr});function E(e,t){if(!e)throw Cr(t)}function ae(e,t,r=[]){E(typeof e==="object"&&e!==null&&!Array.isArray(e),"expected JSON object");let n=e;return E(t.every((o)=>Object.hasOwn(n,o)),"required field is absent"),E(Object.keys(n).every((o)=>t.includes(o)||r.includes(o)),"unknown field"),n}function U(e,t=Number.MAX_SAFE_INTEGER,r=0){E(typeof e==="number"&&Number.isSafeInteger(e)&&e>=r&&e<=t,"integer outside its bound")}function W(e,t,r=0){E(typeof e==="string"&&Buffer.from(e).toString("utf8")===e,"invalid Unicode text"),E(Buffer.byteLength(e)<=t&&Buffer.byteLength(e)>=r,"text outside its byte bound")}function nt(e){E(typeof e==="string"&&/^[A-Za-z0-9_-]{43}$/.test(e),"invalid content identity");let t=Buffer.from(e,"base64url");E(t.length===32&&t.toString("base64url")===e,"noncanonical content identity")}function Pr(e,t){E(typeof e==="string"&&/^[A-Z2-7]{56}$/.test(e),"invalid public NKEY");let r="ABCDEFGHIJKLMNOPQRSTUVWXYZ234567",n=0,o=0,i=[];for(let s of e)if(o=o<<5|r.indexOf(s),n+=5,n>=8)n-=8,i.push(o>>>n&255);E(i.length===35&&i[0]===(t==="account"?0:160),"wrong NKEY kind");let a=0;for(let s of i.slice(0,33)){a^=s<<8;for(let h=0;h<8;h++)a=(a<<1^(a&32768?4129:0))&65535}E(i[33]===(a&255)&&i[34]===a>>>8,"NKEY checksum differs")}function ot(e){W(e,255,1),E(e!=="."&&e!==".."&&!/[\x00-\x1f\x7f/]/.test(e),"forbidden entry name"),E(Lr(e)===e,"entry name is not NFC")}function Lr(e){let t="",r="";for(let n of e)if(_r.test(n))t+=r.normalize("NFC")+n,r="";else r+=n;return t+r.normalize("NFC")}function qr(e,t=4096){if(W(e,t,1),E(e.startsWith("/"),"path must be absolute"),e==="/")return;let r=e.slice(1).split("/");E(r.length<=Rr,"path exceeds its depth bound");for(let n of r)ot(n)}function $r(e){E(typeof e==="string"&&/^[0-9A-Za-z]{1,64}$/.test(e),"invalid volume name")}function it(e){let t=ae(e,["volume","creation_id"]);$r(t.volume),E(typeof t.creation_id==="string"&&/^[0-9a-f]{32}$/.test(t.creation_id),"invalid volume creation identity")}function Mr(e){let t=ae(e,["slot","generation"]);U(t.slot,rt-1),U(t.generation,void 0,1)}function at(e,t){if(e===t)return!0;if(!e||!t||typeof e!=="object"||typeof t!=="object")return!1;let r=e,n=t;return Object.keys(r).length===Object.keys(n).length&&Object.keys(r).every((o)=>Object.hasOwn(n,o)&&at(r[o],n[o]))}function Ur(e,t=!0){let r=JSON.stringify(e);return E(r!==void 0,"value cannot be encoded as JSON"),r=r.replace(/\u2028/g,"\\u2028").replace(/\u2029/g,"\\u2029"),t?r.replace(/</g,"\\u003c").replace(/>/g,"\\u003e").replace(/&/g,"\\u0026"):r}var Hr=class extends Error{constructor(e,t){super(t);this.reason=e,this.name="CodecError"}reason};function T(e,t){throw new Hr(e,t)}function Gr(e,t){return Ge("sha256").update(e).update("\x00").update(t).digest("base64url")}function Vr(e){return Gr("scratchpad:v1:tree",e)}function P(e,t){if(U(t),t<24)return Buffer.from([e<<5|t]);if(t<=255)return Buffer.from([e<<5|24,t]);if(t<=65535){let n=Buffer.alloc(3);return n[0]=e<<5|25,n.writeUInt16BE(t,1),n}if(t<=4294967295){let n=Buffer.alloc(5);return n[0]=e<<5|26,n.writeUInt32BE(t,1),n}let r=Buffer.alloc(9);return r[0]=e<<5|27,r.writeBigUInt64BE(BigInt(t),1),r}function Xr(e){return Buffer.concat([P(2,e.length),e])}function O(e){let t=Buffer.from(e);return Buffer.concat([P(3,t.length),t])}function zr(e){if(typeof e!=="string"||Buffer.from(e).toString("utf8")!==e)T("utf8","invalid entry name UTF-8");if(Buffer.byteLength(e)===0||Buffer.byteLength(e)>255)T("name-length","entry name length exceeds bound");if(e==="."||e===".."||/[\x00-\x1f\x7f/]/.test(e))T("name-forbidden","forbidden entry name");try{ot(e)}catch{T("not-nfc","entry name is not NFC")}}function Jr(e){if(zr(e.name),e.type==="symlink"){if(e.executable||e.object!==void 0&&e.object!==jr)T("type-invalid","symlink has file fields");let t=e.linkTarget??"";if(typeof t!=="string"||Buffer.from(t).toString("utf8")!==t)T("utf8","invalid symlink UTF-8");if(Buffer.byteLength(t)===0||Buffer.byteLength(t)>4096||t.includes("\x00"))T("target-invalid","invalid symlink target")}else{if(e.type!=="file"&&e.type!=="directory")T("type-invalid","unknown entry type");if(nt(e.object),e.linkTarget||e.type==="directory"&&e.executable)T("type-invalid","entry has fields of another type")}}function Wr(e){for(let o of e)Jr(o);let t=[...e].sort((o,i)=>Buffer.compare(Buffer.from(o.name),Buffer.from(i.name)));for(let o=1;o<t.length;o++)if(t[o].name===t[o-1].name)T("duplicate-name","duplicate tree entry");if(e.length>Br)T("entry-count","tree entry count exceeds bound");let r=[P(5,1),O("e"),P(4,e.length)],n=r.reduce((o,i)=>o+i.length,0);for(let o of t){let i=[P(5,o.executable?4:3)];if(o.type==="symlink")i.push(O("l"),O(o.linkTarget));else i.push(O("i"),Xr(Buffer.from(o.object,"base64url")));if(i.push(O("n"),O(o.name),O("t"),P(0,o.type==="file"?0:o.type==="directory"?1:2)),o.executable)i.push(O("x"),P(0,1));if(n+=i.reduce((a,s)=>a+s.length,0),n>tt)T("node-size","tree node byte count exceeds bound");r.push(...i)}return Buffer.concat(r)}Vr(Wr([]));function st(e){let t=ae(e,["version","creator","account","target","root","generation","path","retention","expires_at"]);E(t.version===2,"reference version must be two"),W(t.creator,512,1),Pr(t.account,"account"),it(t.target),nt(t.root),U(t.generation,void 0,1),qr(t.path,256),Mr(t.retention),U(t.expires_at,void 0,1)}function Yr(e){st(e);let t={version:2,creator:e.creator,account:e.account,target:{volume:e.target.volume,creation_id:e.target.creation_id},root:e.root,generation:e.generation,path:e.path,retention:{slot:e.retention.slot,generation:e.retention.generation},expires_at:e.expires_at},r="sp-ref:"+Buffer.from(Ur(t,!1)).toString("base64url");return E(Buffer.byteLength(r)<=16384,"reference exceeds byte bound"),r}var le="sp-r1:",re=66;function ut(e){W(e,re,re),E(/^sp-r1:[A-Za-z0-9_-]{60}$/.test(e),"malformed short reference");let t=Buffer.from(e.slice(le.length),"base64url");E(t.length===45&&t[32]<64,"invalid short reference slots");let r=Number(t.readBigUInt64BE(24));U(r,void 0,1);let n={route:t.subarray(0,8).toString("hex"),creation_id:t.subarray(8,24).toString("hex"),retention:{slot:t[32]>>3,generation:r},path_index:t[32]&7};return it({volume:"Reference",creation_id:n.creation_id}),n}function Kr(e,t){return Ge("sha256").update(`scratchpad-reference-volume-v1\x00${e}\x00${t}`).digest().subarray(0,8).toString("hex")}function Zr(e){let t=ae(e,["short","expanded"]);W(t.short,re,re);let r=ut(t.short);st(t.expanded),E(r.route===Kr(t.expanded.account,t.expanded.target.volume)&&r.creation_id===t.expanded.target.creation_id&&at(r.retention,t.expanded.retention),"short reference binding differs")}var Qr="sp",en=600,je=600,tn=5,Pe=16,rn=16384,ct=16777216,nn=Math.ceil(ct/3)*4+65536,on=262144,an=65536,dt=/^A[A-Z2-7]{55}$/,sn=/^[0-9A-Za-z]{1,64}$/,un=/^[0-9a-f]{32}$/,cn=/^[A-Za-z0-9_-]{43}$/,dn=/^[A-Za-z0-9_-]+$/,ln=/^[A-Za-z0-9+/]*={0,2}$/,m=class extends Error{constructor(e,t,r){super(e);this.code=t,this.unknown=r,this.name="ScratchPadError"}code;unknown},B=(e)=>typeof e==="object"&&e!==null&&!Array.isArray(e),ne=(e,t)=>Object.keys(e).length===t.length&&t.every((r)=>(r in e)),V=(e)=>Number.isSafeInteger(e)&&e>0,lt=(e)=>Buffer.byteLength(e,"utf8");function ft(e){return B(e)&&ne(e,["volume","creation_id"])&&typeof e.volume==="string"&&sn.test(e.volume)&&typeof e.creation_id==="string"&&un.test(e.creation_id)}function fn(e){if(typeof e!=="string"||!e.startsWith("/")||lt(e)>256)return!1;if(e==="/")return!0;return e.slice(1).split("/").every((t)=>t!==""&&t!=="."&&t!=="..")}function ue(e){let t=(a)=>{throw Error(`malformed ScratchPad reference: ${a}`)};if(typeof e!=="string"||!e.startsWith(Q))t("no sp-ref: prefix");if(e.length>rn)t("longer than 16 KiB");let r=e.slice(Q.length);if(!dn.test(r)||r.length%4===1)t("not unpadded base64url");let n;try{n=JSON.parse(Buffer.from(r,"base64url").toString("utf8"))}catch{t("not JSON")}let o=["version","creator","account","target","root","generation","path","retention","expires_at"];if(!B(n)||!ne(n,o))return t("not the version 2 fields");let i=n.retention;if(n.version!==2||typeof n.creator!=="string"||n.creator.length===0||lt(n.creator)>512||typeof n.account!=="string"||!dt.test(n.account)||!ft(n.target)||typeof n.root!=="string"||!cn.test(n.root)||!V(n.generation)||!fn(n.path)||!B(i)||!ne(i,["slot","generation"])||!Number.isSafeInteger(i.slot)||i.slot<0||i.slot>7||!V(i.generation)||!V(n.expires_at))t("a field is out of shape");return n}var j=()=>Math.floor(Date.now()/1000),Le=8,hn=16,pn=["close","apply","release","grant"],Dn=["workspace","not_found"],L=(e)=>Number.isSafeInteger(e)&&e>=0;function gn(e){let t=(l)=>{throw new m(`sp describe: ${l}`,"malformed_reply",!1)};if(!B(e)||!B(e.volume))return t("the reply names no volume");let{volume:r,control:n}=e,o;if(n!==null&&n!==void 0){if(!B(n)||typeof n.kind!=="string"||!pn.includes(n.kind))return t("the saved control request is out of shape");o=n.kind}if(typeof r.closed!=="boolean")return t("the volume names no closed state");let{retentions:i,grants:a}=r;if(!Array.isArray(i)||i.length!==Le)return t("not eight retention slots");if(!Array.isArray(a)||a.length!==hn)return t("not sixteen grant slots");let s=i.map((l)=>{if(!B(l)||!L(l.generation))return t("a retention slot is out of shape");let p=l.pin;if(p===void 0||p===null)return{generation:l.generation,until:void 0};if(!B(p)||!L(p.until)||typeof p.root!=="string")return t("a retention pin is out of shape");return{generation:l.generation,until:p.until}}),h=[];for(let l of a){if(!B(l)||!L(l.generation))return t("a grant slot is out of shape");let p=l.grant;if(p===void 0||p===null)continue;let g=B(p)?p.retention:void 0;if(!B(p)||!L(p.until)||!B(g)||!L(g.slot)||g.slot>=Le||!V(g.generation))return t("a grant is out of shape");h.push({slot:g.slot,generation:g.generation,until:p.until})}return{closed:r.closed,control:o,retentions:s,grants:h}}function mn(e){let t=(o)=>{throw new m(`sp spool-remove: ${o}`,"malformed_reply",!1)};if(!B(e)||typeof e.present!=="boolean")return t("the reply says no spool state");let r=e.present,n=["present","files","bytes","removable","applied"];if(r)n.push("phase");if(!ne(e,n)||r&&(typeof e.phase!=="string"||e.phase==="")||!L(e.files)||!L(e.bytes)||typeof e.removable!=="boolean"||typeof e.applied!=="boolean")return t("the spool state is out of shape");return{present:r,removable:e.removable,applied:e.applied}}function vn(e,t=j()){let r=e.control==="close"||e.control==="apply";if(e.closed&&!r)return"the volume is closed, and no cleanup of this agent's is saved";if(r)return;return e.retentions.some((o,i)=>o.until===void 0||o.until!==0&&o.until<=t&&!e.grants.some((a)=>a.slot===i&&a.generation===o.generation&&a.until>t))?void 0:"every retention slot holds a live pin"}function Fn(e){if(!("creds"in e.nats)||e.nats.creds===void 0)throw Error("ScratchPad: the sp CLI needs NATS_URL and NATS_CREDS; a NATS context or an nkey seed alone is not supported");let t=["--url",e.nats.url,"--creds",e.nats.creds],r=e.bin??Qr,n=e.dir??ie(Lt(),`scratchpad-${e.volume}`),o=Math.min(e.grantTtlS??je,je),i,a,s=Promise.resolve(),h=!0,l,p=new Map;function g(u){let d=s.then(u);return s=d.catch(()=>{return}),d}let v=new Map;async function f(u,d){if(!u.startsWith(le))return ue(u);ut(u);let c=v.get(u);if(c&&c.expires_at>j())return structuredClone(c);let D=await b("resolve",["--ref",u],{trace:d}),C={short:u,expanded:D?.reference};if(Zr(C),D.full_reference!==Yr(C.expanded))throw new m("sp resolve: expanded token differs from descriptor","malformed_reply",!1);let y=ue(D.full_reference);if(y.expires_at<=j())throw Error("the reference has expired");if(v.delete(u),v.set(u,y),v.size>64)v.delete(v.keys().next().value);return structuredClone(y)}async function F(){return i??=(async()=>(await jt(n,{recursive:!0,mode:448}),Pt(n)))(),i}async function b(u,d,c={}){let D=c.trace?["--thread-id",c.trace.threadId,"--root-id",c.trace.rootId]:[];if(c.trace&&c.toolCallId!==void 0)D.push("--tool-call-id",c.toolCallId);let C=["read","resolve"].includes(u)?[]:["--volume",e.volume],y=[u,...t,"--dir",await F(),...C,...d,...D],x=c.maxStdout??on,{code:k,stdout:_,stderr:I}=await new Promise((w)=>{Nt(r,y,{maxBuffer:Math.max(x,an),encoding:"utf8"},(Rt,xt,kt)=>{let M=Rt;w({code:M===null?0:typeof M.code==="number"?M.code:null,stdout:xt??"",stderr:kt||(M!==null&&typeof M.code==="string"?M.message:"")})}).stdin?.end(c.stdin??"")});if(k===null&&/^spawn .*(ENOENT|EACCES)/m.test(I))throw new m(`sp ${u}: ${I.trim()}`,"spawn_failed",!1);if(k===0&&_.length<=x)try{return JSON.parse(_)}catch{}let A={code:k===0?"malformed_reply":"failed",message:I.trim().slice(0,512)||`exit ${k??"by signal"}`,unknown:c.mutation===!0};if(k!==0)try{let w=JSON.parse(I).error;if(B(w)&&typeof w.code==="string")A={code:w.code,message:typeof w.message==="string"?w.message:"",unknown:w.unknown===!0||c.mutation===!0&&typeof w.unknown!=="boolean"}}catch{}throw new m(`sp ${u}: ${A.code}${A.unknown?" (outcome unknown)":""}: ${A.message}`,A.code,A.unknown)}function q(u,d){let c=u,D=c?.principal?.account;if(typeof D!=="string"||!dt.test(D)||!ft(c.target))throw new m(`sp ${d}: the reply names no principal and target`,"malformed_reply",!1);if(c.target.volume!==e.volume)throw new m(`sp ${d}: the workspace is bound to another volume`,"invalid",!1);return{account:D,target:{volume:c.target.volume,creation_id:c.target.creation_id}}}async function bt(u){return a??=q(await b("init",[],{trace:u,mutation:!0}),"init"),a}async function Ee(u){if(a!==void 0)return a;try{a=q(await b("describe",[],{trace:u}),"describe")}catch(d){if(d instanceof m&&Dn.includes(d.code))return;throw d}return a}let Y=(u,d)=>d!==void 0&&u.account===d.account&&u.target.volume===d.target.volume&&u.target.creation_id===d.target.creation_id,be=(u,d)=>JSON.stringify([u.account,u.target.volume,u.target.creation_id,u.root,u.path,d.account,d.user]);function wt(){let u=j();for(let[d,c]of p)if(Math.max(c["first-hand"]??0,c["on-request"]??0)<=u)p.delete(d)}function we(u,d,c){p.set(u,{...p.get(u),[d]:c})}function At(u,d){let c=u;if(!B(c)||!B(c.handle)||!V(c.expires_at))throw new m("sp grant: the reply names no handle and expiry","malformed_reply",!0);return Math.min(c.expires_at,d.expires_at)}async function Ae(u,d,c,D){return b("publish-file",["--source","-","--path",d,"--operation-id",c,"--creator",e.creator,"--ttl-seconds",String(en)],{trace:D,stdin:u,mutation:!0})}async function Ce(u){if(!h)return;try{await b("recover",[],{trace:u,mutation:!0})}catch(d){if(!(d instanceof m)||d.unknown)throw d}h=!1}async function Ct(u,d){let c;try{let D=mn(await b("spool-remove",["--apply"],{trace:d,mutation:!0}));if(!D.present||D.applied)return;c="the refused publication's spool is protected"}catch(D){if(D instanceof m&&D.unknown)throw D;c=`its spool was not removed: ${D.message}`}throw h=!0,new m(`${u.message}; cleanup not started: ${c}`,u.code,!1)}async function _t(u){return gn(await b("describe",[],{trace:u}))}async function St(u,d,c){if(e.creator===void 0)throw Error("ScratchPad: a reference names its creator; this ScratchPad was made without one");let D=await bt(c);await Ce(c);let C=Se(),y;try{y=await Ae(u,d,C,c)}catch(_){if(_ instanceof m&&_.unknown)h=!0;if(!(_ instanceof m)||_.code!=="capacity"||_.unknown)throw _;await Ct(_,c);let I;try{I=vn(await _t(c))}catch(A){throw new m(`${_.message}; cleanup not started: ${A.message}`,_.code,!1)}if(I!==void 0)throw new m(`${_.message}; cleanup not started: ${I}`,_.code,!1);try{await b("maintain",["--apply"],{trace:c,mutation:!0})}catch(A){h=!0;let w=!(A instanceof m)||A.unknown;throw new m(`${_.message}; cleanup: ${A.message}`,w&&A instanceof m?A.code:w?"failed":_.code,w)}try{y=await Ae(u,d,C,c)}catch(A){if(A instanceof m&&A.unknown)h=!0;throw A}}let x=y?.reference;if(typeof x!=="string"||!B(y.receipt))throw h=!0,new m("sp publish-file: the reply names no receipt and reference","malformed_reply",!0);let k=await f(x,c);if(!Y(k,D)||k.path!==d||k.creator!==e.creator)throw new m("sp publish-file: the reference names another volume, path or creator","malformed_reply",!1);return x}async function _e(u,d,c,D){return At(await b("grant",u,{trace:d,toolCallId:c,mutation:!0}),D)}async function Bt(u,d,c,D,C){let y=await f(u,c);if(!Y(y,await Ee(c)))throw Error("the reference points into another agent's volume; only its creator can grant read on it");if(await Ce(c),l!==void 0){let w=l;try{we(w.key,w.kind,await _e(w.args,void 0,void 0,w.ref)),l=void 0}catch(K){if(!(K instanceof m)||K.unknown)throw K;l=void 0}}let x=y.expires_at-j()-tn,k=Math.floor(Math.min(o,x));if(k<1)throw Error("the reference has expired, or is about to; there is nothing left to grant on");let _=be(y,d);if(wt(),!p.has(_)&&p.size>=Pe)throw Error(`this agent already holds ${Pe} live grants; try again when one expires`);let I=c?["--thread-id",c.threadId,"--root-id",c.rootId]:[];if(c&&D!==void 0)I.push("--tool-call-id",D);let A=["--ref",u,"--grantee-account",d.account,"--grantee-user",d.user,"--operation-id",Se(),"--ttl-seconds",String(k)];try{we(_,C,await _e(A,c,D,y))}catch(w){if(w instanceof m&&w.unknown)l={args:[...A,...I],key:_,kind:C,ref:y};throw w}}return{commit(u,d,c){return g(()=>St(u,d,c))},async read(u,d){if((await f(u,d)).expires_at<=j())throw Error("the reference has expired");let D=await b("read",["--ref",u],{trace:d,maxStdout:nn}),{data_base64:C,bytes:y}=D??{};if(typeof C!=="string"||!ln.test(C)||!Number.isSafeInteger(y)||y>ct)throw new m("sp read: the reply carries no data","malformed_reply",!1);let x=Buffer.from(C,"base64");if(x.length!==y||x.toString("base64")!==C)throw new m("sp read: the data does not match its length","malformed_reply",!1);try{return new TextDecoder("utf-8",{fatal:!0}).decode(x)}catch{throw Error("the referenced file is not UTF-8 text")}},resolveReference:f,async owns(u){let d;try{d=await f(u)}catch{return!1}return Y(d,await Ee(N()))},grantRead(u,d,c,D,C="first-hand"){return g(()=>Bt(u,d,c,D,C))},granted(u,d){let c=(D)=>{if(!Y(D,a))return;let C=p.get(be(D,d)),y=j();if((C?.["first-hand"]??0)>y)return"first-hand";if((C?.["on-request"]??0)>y)return"on-request";return};if(u.startsWith(le))return f(u).then(c,()=>{return});try{return c(ue(u))}catch{return}}}}var yn="SCRATCHPAD_VOLUME",En="SCRATCHPAD_BIN",bn="SCRATCHPAD_DIR";var wn=409;function An(e){return`the agent's model is waiting inside a prompt of this tree (root ${e}); a prompt of the same tree cannot be served until that call returns`}function Cn(e){if(typeof e!=="object"||e===null||Array.isArray(e))return;let t=e.open_calls;if(t===void 0)return 0;return typeof t==="number"&&Number.isInteger(t)&&t>=0?t:void 0}function _n(e){return(typeof e==="object"||typeof e==="function")&&e!==null&&typeof e.then==="function"}function ht(){let e=new Map,t=new Map,r=(o)=>{let i=t.get(o);if(i===void 0)return!1;for(let a of i)if(a.waiting)return!0;return!1},n=(o,i,a)=>{o.running-=1;let s=i?Cn(a):void 0;if(s===void 0)return;if(o.open=s,o.running===0&&o.open===0)o.waiting=!1};return{requestInterceptor:{async aroundRequest(o,i){let a=N();if(a===void 0){await i();return}let{rootId:s}=a;if(r(s))throw new X(wn,An(s));let h={rootId:s,waiting:!1,running:0,open:0};e.set(a,h);let l=t.get(s);if(l===void 0)t.set(s,l=new Set);l.add(h);try{await i()}finally{if(e.delete(a),l.delete(h),l.size===0)t.delete(s)}}},promptInterceptor:{beforePrompt(){let o=N(),i=o===void 0?void 0:e.get(o);if(i!==void 0)i.waiting=!0}},aroundToolCall(o,i){let a=o===void 0?void 0:e.get(o);if(a===void 0)return i();a.running+=1;let s;try{s=i()}catch(h){throw n(a,!1),h}if(_n(s))s.then((h)=>n(a,!0,h),()=>n(a,!1));else n(a,!0,s);return s},serving:(o)=>t.has(o),waiting:r}}var Sn=Symbol.for("synadia.fabric.scratchpad.workspace-owners.v1"),Bn=globalThis,Qn=Bn[Sn]??=new Set;var qe="edgeSubject",Rn="SYNADIA_FABRIC_EDGE_SUBJECT";function pt(e,t=process.env){if(Object.hasOwn(e,qe))return e[qe];let r=t[Rn];if(r!==void 0)return r;return Ve}var Dt="scratchpad",S={url:"SP_NATS_URL",creds:"SP_NATS_CREDS",dir:bn,volume:yn,creator:"SP_CREATOR",threadId:"SP_THREAD_ID",rootId:"SP_ROOT_ID",callerAccount:"SP_CALLER_ACCOUNT",callerUser:"SP_CALLER_USER",grants:"SP_GRANTS_FILE"};async function ge(e,t){let r=e.logger,n=e.options[Dt],o=n!==null&&typeof n==="object"?n:{},i=(g,v)=>{let f=o[g];if(typeof f==="string"&&f!=="")return f;let F=t[v];return F===void 0||F===""?void 0:F},a=i("volume",S.volume);if(a===void 0)return;let s=i("url","NATS_URL"),h=i("creds","NATS_CREDS");if(s===void 0||h===void 0){let g=t.NATS_CONTEXT||G(e.settings.config.context);if(g!==void 0)try{let{fields:v}=await Ue(g);s??=G(v.url),h??=G(v.creds)}catch(v){r.warn(`agent-fabric: ScratchPad is off: the NATS context "${g}" could not be read (${String(v)})`);return}}if(s??=G(e.settings.config.url),h??=G(e.settings.config.credentials),s===void 0||h===void 0){r.warn("agent-fabric: ScratchPad is off: sp needs a NATS URL and a credentials file (options.scratchpad, NATS_URL and NATS_CREDS, a NATS context with both, or url and credentials in the plugin's configuration)");return}let l=i("dir",S.dir);if(l===void 0&&e.settings.stateDir!==void 0)l=ie(e.settings.stateDir,"scratchpad");if(l!==void 0){l=qt($e(l));try{Mt(l,{recursive:!0,mode:448})}catch(g){r.warn(`agent-fabric: ScratchPad workspace ${l} could not be created (${String(g)})`)}}let p=l!==void 0?`${l}.grants`:void 0;if(p!==void 0)kn(p,r);return{url:s,creds:$e(h),volume:a,...l!==void 0?{dir:l}:{},...p!==void 0?{grants:p}:{}}}function me(e,t){if(t[S.url]=e.url,t[S.creds]=e.creds,t[S.volume]=e.volume,e.dir!==void 0)t[S.dir]=e.dir;if(e.grants!==void 0)t[S.grants]=e.grants}var ve=class{constructor(e){this.env=e}env;#e;enter(e,t){if(this.#t(),this.#e=e.id,t!==void 0)this.env[S.threadId]=t.threadId,this.env[S.rootId]=t.rootId;if(e.caller!==void 0)try{let r=z(e.caller);this.env[S.callerAccount]=r.account,this.env[S.callerUser]=r.user}catch{}}leave(e){if(this.#e===e.id)this.#t(),this.#e=void 0}#t(){delete this.env[S.threadId],delete this.env[S.rootId],delete this.env[S.callerAccount],delete this.env[S.callerUser]}};function gt(e,t){let r=e[En];if(r!==void 0&&r!=="")return r;let n=Be()==="darwin"?"darwin":Be()==="linux"?"linux":void 0,o=Re()==="arm64"?"arm64":Re()==="x64"?"amd64":void 0;if(n===void 0||o===void 0)return;return ie(t,"bin",`sp-${n}-${o}`)}var Fe=class{#e;#t;#r=[];requestInterceptor={aroundRequest:(e,t)=>{if(this.#e===void 0)this.#r.push(e.envelope.prompt);else this.#e.remember(e.envelope.prompt);return t()}};start(e){let{scratchPad:t,agents:r,service:n}=e;this.#t=t,this.#e=br({scratchPad:t,agents:r});for(let a of this.#r.splice(0))this.#e.remember(a);if(n===void 0)return;let o=e.logger??oe,i=Fr({promptAddress:n.subject.prompt,scratchPad:t,logger:o});try{n.service.addEndpoint(i.name,{subject:i.subject,...i.queue!==void 0?{queue:i.queue}:{},handler:i.handler})}catch(a){o.warn(`agent-fabric: grant requests are not answered: ${String(a)}`)}}discoveryFields(e){return this.#e?.discoveryFields(e)??{[et]:de(e.metadata)}}async beforePrompt(e){let t=this.#e,r=this.#t;if(t===void 0||r===void 0){if(ee(e.prompt).length===0)return;return{error:"the prompt was not sent: ScratchPad is not ready yet; try again in a moment"}}for(let n of new Set(ee(e.prompt)))if(await r.owns(n))t.remember(n);return t.beforePrompt(e)}afterReply(e){this.#e?.afterReply(e)}};function mt(e,t,r,n){let o=gt(r,n);if(o===void 0)return;let i=Fn({volume:e.volume,nats:{url:e.url,creds:e.creds},bin:o,creator:t,...e.dir!==void 0?{dir:e.dir}:{}});return e.grants!==void 0?Tn(i,e.grants):i}var xn=/^(\d+) (\S+) (\S+) (sp-(?:ref|r1):[A-Za-z0-9_-]+)$/;function vt(e){let t;try{t=Ut(e,"utf8")}catch{return[]}let r=[];for(let n of t.split(`
|
|
4
|
+
`)){let o=xn.exec(n);if(o===null)continue;r.push({expiresAt:Number(o[1]),grantee:{account:o[2],user:o[3]},reference:o[4]})}return r}function kn(e,t){let r=Math.floor(Date.now()/1000),n=vt(e).filter((o)=>o.expiresAt>r);try{let o=`${e}.${process.pid}.tmp`;Ht(o,n.map((i)=>`${i.expiresAt} ${i.grantee.account} ${i.grantee.user} ${i.reference}
|
|
5
|
+
`).join(""),{mode:384}),Gt(o,e)}catch(o){t.warn(`agent-fabric: ScratchPad grants file ${e} could not be written (${String(o)})`)}}function Tn(e,t,r=()=>Date.now()/1000){return{...e.resolveReference?{resolveReference:(n,o)=>e.resolveReference(n,o)}:{},owns:(n)=>e.owns(n),grantRead:(n,o,i,a,s)=>e.grantRead(n,o,i,a,s),async granted(n,o){let i=await e.granted(n,o);if(i==="first-hand")return i;let a=r();return vt(t).some((h)=>h.reference===n&&h.grantee.account===o.account&&h.grantee.user===o.user&&h.expiresAt>a)?"first-hand":i}}}function G(e){return typeof e==="string"&&e!==""?e:void 0}function $e(e){if(e==="~")return xe();if(e.startsWith("~/"))return ie(xe(),e.slice(2));return e}import{fileURLToPath as In}from"node:url";var On=In(new URL("../skill/scratchpad",import.meta.url));function Ft(e,t,r){return mt(e,t,r,On)}var H="agent-fabric",yt=`${H}: senderIdentity is off; trace records are signed, so none will be published and each counts as dropped on the heartbeat. Set senderIdentity to signed.`;async function ye(e,t=process.env){return Et(e,t,await ge(e,t))}function Et(e,t=process.env,r){let n=pt(e.options,t),o=Ye({edgeSubject:n}),i=ht(),a=e.logger,s=new Map,h=(f)=>f===void 0?void 0:s.get(f.id),l=!1,p=r!==void 0,g=new ve(t);if(r!==void 0)me(r,t);let v=r!==void 0?new Fe:void 0;return{name:H,requestInterceptors:[o.requestInterceptor,i.requestInterceptor,...v!==void 0?[v.requestInterceptor]:[]],promptInterceptors:[o.promptInterceptor,i.promptInterceptor],heartbeatExtras:o.heartbeatExtras,...v!==void 0?{toolExtensions:[v],metadata:{[De]:"true"}}:{},started({agents:f,service:F}){if(e.settings.senderIdentity!=="signed"&&!l)l=!0,a.warn(yt);if(a.info(`${H}: tracing ${F.subject.prompt}`+(n===null?" (propagate-only: lineage forwarded, no edge record published)":`, edge records on ${n}`)),r!==void 0&&v!==void 0){t[S.creator]=F.subject.prompt;let b=Ft(r,F.subject.prompt,t);if(b!==void 0)v.start({scratchPad:b,agents:f,service:F,logger:a});else a.warn(`${H}: no sp for this platform (set SCRATCHPAD_BIN); references in prompt_agent are not handed on, and grant requests not answered`);a.info(`${H}: ScratchPad volume ${r.volume}`+(r.dir!==void 0?`, workspace ${r.dir}`:", no workspace")+", for the skill's scripts/sp")}},events:{promptAccepted(f){let F=N();if(F!==void 0)s.set(f.id,F)},promptEnded(f){s.delete(f.id),g.leave(f)},aroundInject(f,F){let b=s.get(f.id);if(p)g.enter(f,b);return b===void 0?F():J(b,F)},providerHeaders(f){let F=s.get(f.id);return F===void 0?void 0:J(F,We)},aroundToolCall(f,F,b){let q=h(f);return q===void 0?b():J(q,()=>i.aroundToolCall(q,b))}}}}export{ye as default};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{a as Qe,b as Q,c as K,d as lt,e as Ut,h as ze,k as le,l as fe,m as be,n as Ke,o as Ve,p as qe,q as Me,r as Ye,s as de,t as Ge,u as ce,x as Je,y as Xe,z as We}from"./chunk-sjpe67s3.js";var z=Q(function(U){var ft=U&&U.__createBinding||(Object.create?function(e,t,n,r){if(r===void 0)r=n;var o=Object.getOwnPropertyDescriptor(t,n);if(!o||("get"in o?!t.__esModule:o.writable||o.configurable))o={enumerable:!0,get:function(){return t[n]}};Object.defineProperty(e,r,o)}:function(e,t,n,r){if(r===void 0)r=n;e[r]=t[n]}),pt=U&&U.__exportStar||function(e,t){for(var n in e)if(n!=="default"&&!Object.prototype.hasOwnProperty.call(t,n))ft(t,e,n)};Object.defineProperty(U,"__esModule",{value:!0});pt(lt(),U)});var Ee=Q(function(me){Object.defineProperty(me,"__esModule",{value:!0});me.version=void 0;me.version="3.4.0"});var we=Q(function(O){var gt=O&&O.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(O,"__esModule",{value:!0});O.NodeTransport=O.VERSION=void 0;O.nodeResolveHost=vt;var E=z(),yt=K("node:net"),re=K("node:tls"),mt=K("node:path"),Te=K("node:fs"),ht=gt(K("node:dns")),Et=Ee();O.VERSION=Et.version;var Tt="nats.js";class ve{socket;version;lang;yields=[];signal=(0,E.deferred)();closedNotification=(0,E.deferred)();options;connected=!1;tlsName="";done=!1;closeError;constructor(){this.lang=Tt,this.version=O.VERSION}async connect(e,t){this.tlsName=e.tlsName,this.options=t;let{tls:n}=this.options,{handshakeFirst:r}=n||{};try{if(r===!0)this.socket=await this.tlsFirst(e);else this.socket=await this.dial(e);if(this.done)this.socket?.destroy();let o=await this.peekInfo();(0,E.checkOptions)(o,t);let{tls_required:s,tls_available:f}=o,c=f===!0&&t.tls!==null;if(!r&&(s||c))this.socket=await this.startTLS();if(this.done)this.socket?.destroy();if(s&&this.socket.encrypted!==!0)throw E.errors.InvalidArgumentError.format("tls","is not available on this server");return this.connected=!0,this.setupHandlers(),this.signal.resolve(),Promise.resolve()}catch(o){let s=o;if(!s)s=new E.errors.ConnectionError("error connecting - node provided an undefined error");let{code:f}=s,c=f==="ECONNREFUSED"?new E.errors.ConnectionError("connection refused",{cause:s}):s;throw this.socket?.destroy(),c}}dial(e){let t=(0,E.deferred)(),n,r=(0,yt.createConnection)(e.port,e.hostname,()=>{t.resolve(r),r.removeAllListeners()});return r.on("error",(o)=>{n=o}),r.on("close",()=>{r.removeAllListeners(),t.reject(n)}),r.setNoDelay(!0),t}get isClosed(){return this.done}close(e){return this._closed(e,!1)}peekInfo(){let e=(0,E.deferred)(),t;return this.socket.on("data",(n)=>{this.yields.push(n);let r=E.DataBuffer.concat(...this.yields),o=(0,E.extractProtocolMessage)(r);if(o!=="")try{let s=E.INFO.exec(o);if(!s)throw Error("unexpected response from server");let f=JSON.parse(s[1]);e.resolve(f)}catch(s){e.reject(s)}finally{this.socket.removeAllListeners()}}),this.socket.on("error",(n)=>{t=n}),this.socket.on("close",()=>{this.socket.removeAllListeners(),e.reject(t)}),e}loadFile(e){if(!e)return Promise.resolve();let t=(0,E.deferred)();try{if(e=(0,mt.resolve)(e),!(0,Te.existsSync)(e))t.reject(Error(`${e} doesn't exist`));(0,Te.readFile)(e,(n,r)=>{if(n)return t.reject(n);t.resolve(r)})}catch(n){t.reject(n)}return t}async loadClientCerts(){let e={},{certFile:t,cert:n,caFile:r,ca:o,keyFile:s,key:f}=this.options.tls;try{if(t){let c=await this.loadFile(t);if(c)e.cert=c}else if(n)e.cert=n;if(s){let c=await this.loadFile(s);if(c)e.key=c}else if(f)e.key=f;if(r){let c=await this.loadFile(r);if(c)e.ca=[c]}else if(o)e.ca=o;return Promise.resolve(e)}catch(c){return Promise.reject(c)}}async tlsFirst(e){let t,n={servername:this.tlsName,rejectUnauthorized:!0};if(this.socket)n.socket=this.socket;if(typeof this.options.tls==="object")try{let o=await this.loadClientCerts()||{};n=(0,E.extend)(n,this.options.tls,o)}catch(o){return Promise.reject(new E.errors.ConnectionError(o.message,{cause:o}))}let r=(0,E.deferred)();try{let o=(0,re.connect)(e.port,e.hostname,n,()=>{o.removeAllListeners(),r.resolve(o)});o.on("error",(s)=>{t=s}),o.on("secureConnect",()=>{if(n.rejectUnauthorized===!1)return;if(!o.authorized)throw o.authorizationError}),o.on("close",()=>{r.reject(t),o.removeAllListeners()}),o.setNoDelay(!0)}catch(o){r.reject(new E.errors.ConnectionError(o.message,{cause:o}))}return r}async startTLS(){let e,t={socket:this.socket,servername:this.tlsName,rejectUnauthorized:!0};if(typeof this.options.tls==="object")try{let r=await this.loadClientCerts()||{};t=(0,E.extend)(t,this.options.tls,r)}catch(r){return Promise.reject(new E.errors.ConnectionError(r.message,{cause:r}))}let n=(0,E.deferred)();try{let r=(0,re.connect)(t,()=>{r.removeAllListeners(),n.resolve(r)});r.on("error",(o)=>{e=o}),r.on("secureConnect",()=>{if(t.rejectUnauthorized===!1)return;if(!r.authorized)throw r.authorizationError}),r.on("close",()=>{n.reject(e),r.removeAllListeners()})}catch(r){n.reject(new E.errors.ConnectionError(r.message,{cause:r}))}return n}setupHandlers(){let e;this.socket.on("data",(t)=>(this.yields.push(t),this.signal.resolve())),this.socket.on("error",(t)=>{e=t}),this.socket.on("end",()=>{if(this.socket?.destroyed)return;this.socket?.write(new Uint8Array(0),()=>{this.socket?.end()})}),this.socket.on("close",()=>{this._closed(e,!1)})}[Symbol.asyncIterator](){return this.iterate()}async*iterate(){while(!0){if(this.yields.length===0)await this.signal;let e=this.yields;this.yields=[];for(let t=0;t<e.length;t++){if(this.options.debug)console.info(`> ${(0,E.render)(e[t])}`);yield e[t]}if(this.done)break;else if(this.yields.length===0)e.length=0,this.yields=e,this.signal=(0,E.deferred)()}}discard(){if(this.done=!0,this.socket)try{this.socket.removeAllListeners(),this.socket.destroy()}catch{}}disconnect(){this._closed(void 0,!0).then().catch()}isEncrypted(){return this.socket instanceof re.TLSSocket}_send(e){if(this.isClosed||this.socket===void 0)return Promise.resolve();if(this.options.debug)console.info(`< ${(0,E.render)(e)}`);let t=(0,E.deferred)();try{this.socket.write(e,(n)=>{if(n){if(this.options.debug)console.error(`!!! ${(0,E.render)(e)}: ${n}`);return t.reject(n)}return t.resolve()})}catch(n){if(this.options.debug)console.error(`!!! ${(0,E.render)(e)}: ${n}`);t.reject(n)}return t}send(e){this._send(e).catch((n)=>{})}async _closed(e,t=!0){if(!this.connected)return;if(this.done){this.socket?.destroy();return}if(this.closeError=e,!e&&this.socket&&t)try{await this._send(new TextEncoder().encode(""))}catch(n){if(this.options.debug)console.log("transport close terminated with an error",n)}try{if(this.socket)this.socket.removeAllListeners(),this.socket?.destroy(),this.socket=void 0}catch(n){console.log(n)}this.done=!0,this.closedNotification.resolve(this.closeError)}closed(){return this.closedNotification}}O.NodeTransport=ve;function vt(e){let t=(0,E.deferred)();return ht.default.lookup(e,{all:!0},(n,r)=>{if(n){t.reject(n);return}let o=[];for(let s of r)o.push(s.address);if(o.length===0)o.push(e);t.resolve(o)}),t}});var _e=Q(function(Ne){Object.defineProperty(Ne,"__esModule",{value:!0});Ne.connect=wt;var Se=we(),Ae=z(),xe=z();function wt(e={}){if((0,xe.hasWsProtocol)(e))return Promise.reject(xe.errors.InvalidArgumentError.format("servers","node client doesn't support websockets, use the 'wsconnect' function instead"));return(0,Ae.setTransportFactory)({factory:()=>new Se.NodeTransport,dnsResolveFn:Se.nodeResolveHost}),Ae.NatsConnectionImpl.connect(e)}});var Pe=Q(function(M){var At=M&&M.__createBinding||(Object.create?function(e,t,n,r){if(r===void 0)r=n;var o=Object.getOwnPropertyDescriptor(t,n);if(!o||("get"in o?!t.__esModule:o.writable||o.configurable))o={enumerable:!0,get:function(){return t[n]}};Object.defineProperty(e,r,o)}:function(e,t,n,r){if(r===void 0)r=n;e[r]=t[n]}),xt=M&&M.__exportStar||function(e,t){for(var n in e)if(n!=="default"&&!Object.prototype.hasOwnProperty.call(t,n))At(t,e,n)};Object.defineProperty(M,"__esModule",{value:!0});M.connect=void 0;var Nt=_e();Object.defineProperty(M,"connect",{enumerable:!0,get:function(){return Nt.connect}});xt(z(),M)});var nt=Qe(Pe(),1),rt=Qe(Ut(),1);import{mkdirSync as Ze,readFileSync as et,rmSync as Ht,writeFileSync as tt}from"node:fs";import{homedir as Ft}from"node:os";import{basename as Bt,join as B}from"node:path";import{randomUUID as Qt}from"node:crypto";import{existsSync as se,readFileSync as _t,statSync as Pt}from"node:fs";import{isAbsolute as Rt,join as J}from"node:path";import{pathToFileURL as $t}from"node:url";var bt="SYNADIA_PI_EXTENSIONS",It="SYNADIA_AGENT_EXTENSIONS",oe=Object.freeze({});function F(e){return typeof e==="object"&&e!==null&&!Array.isArray(e)}function Ie(e,t=process.env,n=()=>{return}){for(let o of[bt,It]){let s=t[o];if(s===void 0)continue;let f=s.split(",").map((c)=>c.trim()).filter((c)=>c.length>0).map((c)=>({module:c,options:oe}));return{source:o,entries:f}}if(e===void 0||e===null)return{source:"none",entries:[]};if(!Array.isArray(e))return n("extensions: the config field must be an array of module specifiers or { module, options } objects; ignored"),{source:"none",entries:[]};let r=[];return e.forEach((o,s)=>{if(typeof o==="string"){let f=o.trim();if(f.length===0){n(`extensions[${s}]: empty specifier; ignored`);return}r.push({module:f,options:oe});return}if(F(o)&&typeof o.module==="string"){let f=o.module.trim();if(f.length===0){n(`extensions[${s}]: empty "module"; ignored`);return}let c=o.options;if(c!==void 0&&!F(c)){n(`extensions[${s}]: "options" must be an object; ignored`);return}r.push({module:f,options:c===void 0?oe:Object.freeze({...c})});return}n(`extensions[${s}]: expected a module specifier or { module, options }; ignored`)}),{source:"config",entries:r}}function kt(e){let t=e.trim();if(t.length===0)throw Error("empty module specifier");if(Rt(t)){if(!se(t))throw Error(`${t}: no such file or directory`);return $t(Pt(t).isDirectory()?Ct(t):t).href}if(t.startsWith(".")||t.startsWith("~")||/^[A-Za-z]:[\\/]/.test(t))throw Error(`${t}: relative paths are refused; name a package or give an absolute path`);return t}function Ct(e){let t=J(e,"package.json");if(!se(t))throw Error(`${e}: a directory must hold a package.json`);let n;try{n=JSON.parse(_t(t,"utf8"))}catch(o){throw Error(`${t}: ${o.message}`)}let r=jt(n.exports)??Ot(n.main);if(r!==void 0)return J(e,r);for(let o of["index.js","index.mjs","index.cjs"])if(se(J(e,o)))return J(e,o);throw Error(`${e}: package.json names no entry (exports or main)`)}function Ot(e){return typeof e==="string"&&e.length>0?e:void 0}function jt(e){if(e===void 0)return;let t=(n)=>{if(typeof n==="string")return n;if(!F(n))return;return t(n.import)??t(n.default)};if(typeof e==="string")return e;if(!F(e))return;if("."in e)return t(e["."]);return t(e)}async function ke(e,t,n){let r=[];for(let o of e)try{let c=(await import(kt(o.module))).default;if(typeof c!=="function")throw Error("the module has no default export function");let T=await c({...t,options:o.options});if(!F(T))throw Error("the factory returned no extension object");let w=typeof T.name==="string"&&T.name.length>0?T.name:o.module;r.push({module:o.module,name:w,extension:T})}catch(s){n.error(`extension "${o.module}" not loaded: ${H(s)}`)}return r}var qt=5000,Re=new Set(["agent","owner","protocol_version","session",...Object.values(be)]),Mt=/^[A-Za-z0-9_.-]+$/;class X extends Error{name="ExtensionMetadataError"}function H(e){return e instanceof Error?e.message:String(e)}function $e(e){return(typeof e==="object"||typeof e==="function")&&e!==null&&typeof e.then==="function"}function Lt(e,t,n){let r={},o=new Map;for(let s of e){let f=s.extension.metadata;if(f===void 0)continue;if(!F(f))throw new X(`extension "${s.name}": metadata must be an object of string values`);for(let[c,T]of Object.entries(f)){if(!Mt.test(c))throw new X(`extension "${s.name}": metadata key ${JSON.stringify(c)} is invalid; a key is one or more of A-Z, a-z, 0-9, "_", "-" and "."`);if(typeof T!=="string")throw new X(`extension "${s.name}": metadata ${JSON.stringify(c)} must be a string, got ${T===null?"null":typeof T}`);if(Re.has(c)||t.has(c)){n.warn(`extension "${s.name}": metadata ${JSON.stringify(c)} is set by the ${Re.has(c)?"protocol":"plugin"}; the extension's value is ignored`);continue}let w=o.get(c);if(w!==void 0)n.warn(`extension "${s.name}": metadata ${JSON.stringify(c)} replaces the value of extension "${w}"`);r[c]=T,o.set(c,s.name)}}return Object.freeze(r)}function ie(e,t,n={}){let r=n.hookTimeoutMs??qt,o=new Set,s=(a,l)=>{if(o.has(a))return;o.add(a),t.warn(l)},f=(a)=>e.filter((l)=>typeof l.extension.events?.[a]==="function"),c=(a,l)=>{for(let h of f(a))try{l(h.extension.events[a])}catch(g){s(`${h.name}:${a}`,`extension "${h.name}" ${a} failed: ${H(g)}`)}},T=(a,l,h,g)=>{let m=`${l.name}:${a}`,x=!1,S,k=!1,C,R=()=>{if(x){if(s(`${m}:twice`,`extension "${l.name}" ${a} called run more than once, or after the plugin had run the step itself; the extra call was ignored`),k)throw C;return S}x=!0;try{return S=g(),S}catch(N){throw k=!0,C=N,N}},v;try{v=h(R)}catch(N){if(k&&N===C)throw N;if(s(m,`extension "${l.name}" ${a} failed: ${H(N)}`),!x)return R();if(k)throw C;return S}if(k)throw C;if(!x)return s(m,`extension "${l.name}" ${a} returned without calling run; the plugin ran the step itself`),R();if(!$e(S)&&!$e(v)&&v!==S)s(`${m}:value`,`extension "${l.name}" ${a} did not return run's value; the plugin used run's`);return S},w=(a,l,h)=>{let g=h,m=f(a);for(let x=m.length-1;x>=0;x--){let S=m[x],k=g;g=()=>T(a,S,(C)=>l(S,C),k)}return g()},j=async(a,l,h)=>{let g;try{await Promise.race([Promise.resolve().then(h),new Promise((m)=>{g=setTimeout(()=>{s(`${a.name}:${l}:timeout`,`extension "${a.name}" ${l}() did not finish within ${r} ms; continuing without it`),m()},r),g.unref?.()})])}catch(m){s(`${a.name}:${l}`,`extension "${a.name}" ${l}() failed: ${H(m)}`)}finally{if(g!==void 0)clearTimeout(g)}},D=e.filter((a)=>typeof a.extension.heartbeatExtras==="function"),Y=D.length===0?void 0:()=>{let a={};for(let l of D)try{Object.assign(a,l.extension.heartbeatExtras())}catch(h){s(`${l.name}:heartbeatExtras`,`extension "${l.name}" heartbeatExtras failed: ${H(h)}`)}return a},q=Lt(e,new Set(n.pluginMetadataKeys??[]),t);return{loaded:e,names:e.map((a)=>a.name),promptInterceptors:e.flatMap((a)=>[...a.extension.promptInterceptors??[]]),requestInterceptors:e.flatMap((a)=>[...a.extension.requestInterceptors??[]]),heartbeatExtras:Y,toolExtensions:e.flatMap((a)=>[...a.extension.toolExtensions??[]]),metadata:q,async started(a){await Promise.all(e.filter((l)=>typeof l.extension.started==="function").map((l)=>j(l,"started",()=>l.extension.started(a))))},async stopping(){await Promise.all(e.filter((a)=>typeof a.extension.stopping==="function").map((a)=>j(a,"stopping",()=>a.extension.stopping())))},events:{promptAccepted(a){c("promptAccepted",(l)=>l(a))},promptEnded(a,l,h){c("promptEnded",(g)=>g(a,l,h))},aroundInject(a,l){return w("aroundInject",(h,g)=>h.extension.events.aroundInject(a,g),l)},providerHeaders(a){let l={};for(let h of f("providerHeaders"))try{let g=h.extension.events.providerHeaders(a);if(!g)continue;for(let[m,x]of Object.entries(g))if(typeof x==="string")l[m]=x}catch(g){s(`${h.name}:providerHeaders`,`extension "${h.name}" providerHeaders failed: ${H(g)}`)}return l},aroundToolCall(a,l,h){return w("aroundToolCall",(g,m)=>g.extension.events.aroundToolCall(a,l,m),h)}}}}class ae{#t=new Map;#n=[];#e=null;#o=0;get size(){return this.#t.size}get queuedCount(){return this.#n.filter((e)=>this.#t.has(e)).length}get active(){return this.#e===null?void 0:this.#t.get(this.#e)}enqueue(e,t,n=Date.now()){let r=String(++this.#o),o,s,f=new Promise((j,D)=>{o=j,s=D}),c=t.sender,T=Object.freeze({id:r,extras:Object.freeze({...e.extras??{}}),...c?.trust==="verified"?{caller:String(c.id)}:{}}),w={id:r,prompt:e.prompt,attachments:e.attachments??[],response:t,createdAt:n,completion:f,served:T,settled:!1,resolve:o,reject:s};return this.#t.set(r,w),this.#n.push(r),w}takeNext(){if(this.#e!==null)return;while(this.#n.length>0){let e=this.#n.shift(),t=this.#t.get(e);if(!t)continue;return this.#e=e,t}return}requeueActive(){if(this.#e===null)return;let e=this.#e;if(this.#e=null,this.#t.has(e))this.#n.unshift(e)}completeActive(){if(this.#e===null)return;let e=this.#t.get(this.#e);if(this.#t.delete(this.#e),this.#e=null,e)this.#s(e);return e}failActive(e){if(this.#e===null)return;let t=this.#t.get(this.#e);if(this.#t.delete(this.#e),this.#e=null,t)this.#r(t,e);return t}expireQueued(e){let t=[];for(let[n,r]of this.#t){if(n===this.#e||r.createdAt>=e)continue;this.#t.delete(n),this.#r(r,Error("PI prompt expired while waiting in the local queue")),t.push(r)}return t}failAll(e){let t=[...this.#t.values()];this.#t.clear(),this.#n.length=0,this.#e=null;for(let n of t)this.#r(n,Error(e));return t}#s(e){if(e.settled)return;e.settled=!0,e.resolve()}#r(e,t){if(e.settled)return;e.settled=!0,e.reject(t)}}function V(e){return e.replace(/[^a-zA-Z0-9_-]/g,"-").toLowerCase().replace(/^-+|-+$/g,"")}function Ce(...e){return V(e.find((t)=>t!=null)??"unknown")||"unknown"}var Oe=["blocking","all","off"],je="NATS_AGENT_TOOLS";function Le(e,t=process.env){let n=t[je]??e.agentTools;if(n===void 0||n==="")return"blocking";if(Oe.includes(n))return n;throw Error(`${je}/agentTools must be one of ${Oe.join(", ")}; got ${JSON.stringify(n)}`)}function De(e){switch(e){case"blocking":return Me;case"all":return qe;case"off":return}}function Dt(e){let t=e.replace(/_/g," ");return t.charAt(0).toUpperCase()+t.slice(1)}function Ue(e,t,n){let r=[];for(let o of t.definitions){let s=o.name;e.registerTool({name:s,label:Dt(s),description:o.description,parameters:o.parameters,async execute(f,c,T){let w=await n.aroundToolCall(n.activeRequest(),s,()=>t.execute(s,c,{toolCallId:f,...T?{signal:T}:{}}));return{content:[{type:"text",text:JSON.stringify(w)}],details:w}}}),r.push(s)}return r}var He="0.4.0",zt="@synadia-ai/nats-pi-channel",Kt=Vt();function Vt(){try{let e=JSON.parse(et(new URL("../package.json",import.meta.url),"utf8"));return typeof e.version==="string"?e.version:"unknown"}catch{return"unknown"}}var Yt=5,ue="pi",Gt=["cwd"],Jt=ze(Xe),Xt=20,Wt=1800000,Z=B(Ft(),".pi","agent"),ot=B(Z,"nats-channel.json"),Fe=B(Z,"attachments"),Zt="demo.nats.io";function W(e,t,n,r){if(t===void 0||t==="")return n;if(r.includes(t))return t;throw Error(`${e} must be one of ${r.join(", ")}; got ${JSON.stringify(t)}`)}function en(e,t=process.env){let n=t.NATS_CONTEXT??e.context,r=t.NATS_URL,o=t.NATS_CREDS||t.NATS_CREDENTIALS;if(!n&&o&&!r)throw Error("NATS_CREDS/NATS_CREDENTIALS is set without NATS_URL: set NATS_URL to the server the credentials are for");return{source:n?{context:n}:o?{url:r,creds:o}:{url:r||Zt},contextLabel:n??(r?"$NATS_URL":"default"),senderIdentity:W("NATS_SENDER_IDENTITY/senderIdentity",t.NATS_SENDER_IDENTITY??e.senderIdentity,"off",["off","signed"]),minSenderTrust:W("NATS_MIN_SENDER_TRUST/minSenderTrust",t.NATS_MIN_SENDER_TRUST??e.minSenderTrust,"any",["any","signed"])}}function Be(){try{return JSON.parse(et(ot,"utf8"))}catch{return{}}}function tn(e){Ze(Z,{recursive:!0}),tt(ot,`${JSON.stringify(e,null,2)}
|
|
2
|
+
`,"utf8")}function nn(e){let t=(n,r)=>r&&Object.keys(r).length>0?`NATS: ${n} ${JSON.stringify(r)}`:`NATS: ${n}`;return{debug:()=>{return},info:(n,r)=>e.ui.notify(t(n,r),"info"),warn:(n,r)=>e.ui.notify(t(n,r),"warning"),error:(n,r)=>e.ui.notify(t(n,r),"error")}}async function rn(e,t,n){let o=new rt.Svcm(e).client({strategy:"stall",maxWait:1000,maxMessages:50}),s=new Set;try{let T=await o.info(le);for await(let w of T)for(let j of w.endpoints??[])s.add(j.subject)}catch{}let f=t,c=2;while(s.has(fe.new(ue,n,f).prompt))f=`${t}-${c++}`;return f}function on(e){let t,n,r,o,s,f,c,T,w,j="off",D="any",Y=Jt,q,a,l,h,g,m,x,S,k="blocking",C=[],R,v=ie([],{debug:()=>{return},info:()=>{return},warn:()=>{return},error:()=>{return}}),N=!1,b=new ae,pe=setInterval(()=>{let p=Date.now();for(let i of b.expireQueued(p-Wt))v.events.promptEnded(i.served,"timeout",p)},60000);pe.unref();async function st(p,i){if(i.length===0)return;for(let u of Je(i,Y,{reserveBytes:256}))await p.response.send({type:"response",text:u})}function ee(){if(b.active)return;if(!T||!T.isIdle())return;while(b.queuedCount>0){let p=b.takeNext();if(!p)return;let i;try{i=it(p.prompt,p.attachments)}catch(u){let d=b.failActive(Error(`attachment staging failed: ${u.message}`));if(d)v.events.promptEnded(d.served,"error",Date.now());continue}try{v.events.aroundInject(p.served,()=>e.sendUserMessage(i));return}catch(u){if(b.requeueActive(),T.ui.notify(`NATS: deferred injection (${u.message})`,"warning"),q)clearTimeout(q);q=setTimeout(ee,250),q.unref?.();return}}}function it(p,i){if(i.length===0)return p;if(!s)throw Error("session not initialized");let u=B(Fe,s,Qt());Ze(u,{recursive:!0});let d=[];for(let A of i){let y=B(u,A.filename);tt(y,A.content),d.push(y)}return`[Attachments available at the following absolute paths]
|
|
3
|
+
${d.map((A)=>`- ${A}`).join(`
|
|
4
|
+
`)}
|
|
5
|
+
|
|
6
|
+
${p}`}async function at(p,i){try{for await(let u of p.status())switch(u.type){case"disconnect":i.ui.setStatus("nats","NATS: reconnecting…"),i.ui.notify(`NATS disconnected from ${u.server} — retrying…`,"warning");break;case"reconnect":if(o)i.ui.setStatus("nats",`NATS: ${o}`);i.ui.notify(`NATS reconnected to ${u.server}`,"info");break;case"error":i.ui.notify(`NATS error: ${u.error.message}`,"error");break;case"close":if(N)break;i.ui.setStatus("nats","NATS: disconnected"),i.ui.notify("NATS connection closed — agent is off-bus until restart","warning");break}}catch{}}function dt(){if(N)return Promise.resolve();return new Promise((p)=>{let i=!1,u=()=>{if(i)return;if(i=!0,a)clearTimeout(a);a=void 0,l=void 0,p()};l=u,a=setTimeout(u,2000),a.unref?.()})}async function G(p,i){try{await p.drain()}catch{try{await p.close()}catch{return!1}}return i.wipe(),!0}async function te(p={}){if(N=!0,l?.(),q)clearTimeout(q),q=void 0;if(p.waitForConnectTask!==!1)await h?.catch(()=>{return});let i=Date.now();for(let u of b.failAll("PI session shut down before the prompt completed"))v.events.promptEnded(u.served,"error",i);if(await Promise.resolve(),n)await v.stopping();if(t)try{await t.flush()}catch{}if(n){try{await n.stop()}catch{}n=void 0}if(S){try{await S.close()}catch{}S=void 0}if(C=[],x){try{await x.close()}catch{}x=void 0}if(t&&r){let u=t,d=r;if(await G(u,d)){if(t===u)t=void 0;if(r===d)r=void 0}}else if(t)try{await t.drain(),t=void 0}catch{}if(g&&m){let u=g,d=m;if(await G(u,d)){if(g===u)g=void 0;if(m===d)m=void 0}}else if(!g&&m&&!h)m.wipe(),m=void 0;if(clearInterval(pe),s)try{Ht(B(Fe,s),{recursive:!0,force:!0})}catch{}T?.ui.setStatus("nats",void 0)}async function ct(p,i,u){let d,P=!1;while(!N&&!d){let y;try{if(y=await de(p.source,{identity:p.senderIdentity}),N){y.wipe();return}m=y;let _=await nt.connect(Ge({...y.connectionOptions,name:`pi-${f}`,waitOnFirstConnect:!1,timeout:2000}));if(g=_,N){if(await G(_,y))g=void 0,m=void 0;return}if(d=_,t=_,r=y,g=void 0,m=void 0,d.info?.max_payload)Y=d.info.max_payload}catch(_){if(g&&m){if(!await G(g,m))return;g=void 0,m=void 0}else if(m)m.wipe(),m=void 0;if(N)return;if(!P)i.ui.notify(`NATS connection failed (${w}): ${_.message}; retrying`,"warning"),P=!0;i.ui.setStatus("nats","NATS: connecting…"),await dt()}}if(!d||N||t!==d)return;try{if(s=await rn(d,u,f),N||t!==d)return}catch(y){i.ui.notify(`NATS: session name resolution failed: ${y.message}`,"error"),await te({waitForConnectTask:!1});return}let A;try{let y=r?.signer;if(p.senderIdentity==="signed"&&!y)throw Error("signed sender identity resolved without a connection-bound signer");let _=fe.new(ue,f,s).prompt;x=new Ke({nc:d,...R?{logger:R}:{},...y?{identity:{signer:y}}:{},interceptors:v.promptInterceptors});let I=De(k);if(I)S=new Ye({agents:x,tools:I,selfAddress:_,extensions:v.toolExtensions,...R?{logger:R}:{}});let ne=[...v.requestInterceptors,...S?[S.requestInterceptor]:[]],L=new We({nc:d,agent:ue,owner:f,name:s,session:s,version:He,description:`PI agent (${s}) in ${i.cwd}`,attachmentsOk:!0,heartbeatIntervalS:Yt,keepaliveIntervalS:Xt,minSenderTrust:p.minSenderTrust,...y?{identity:{signer:y}}:{},...R?{logger:R}:{},interceptors:ne,...v.heartbeatExtras?{heartbeatExtras:v.heartbeatExtras}:{},extraMetadata:{...v.metadata,cwd:i.cwd}});if(A=L,L.onPrompt((ge,ut)=>{let ye=b.enqueue(ge,ut);return v.events.promptAccepted(ye.served),ee(),ye.completion}),await L.start(),N||t!==d){await L.stop();return}if(n=L,o=L.subject.prompt,c=L.instanceId,S)C=Ue(e,S,{activeRequest:()=>b.active?.served,aroundToolCall:v.events.aroundToolCall});await v.started({agents:x,service:L})}catch(y){try{await A?.stop()}catch{}i.ui.notify(`NATS: service registration failed: ${y.message}`,"error"),await te({waitForConnectTask:!1});return}i.ui.setStatus("nats",`NATS: ${o}`),i.ui.notify(`Connected to NATS (${w}) as ${o} (sender_identity=${p.senderIdentity}, min_sender_trust=${p.minSenderTrust}, agent_tools=${k}, extensions=${v.names.join(",")||"none"})`,"info"),at(d,i)}e.on("session_start",async(p,i)=>{T=i;let u=Be(),d;try{d=en(u)}catch(I){i.ui.notify(`NATS: ${I.message}`,"error"),i.ui.setStatus("nats","NATS: disconnected");return}w=d.contextLabel,j=d.senderIdentity,D=d.minSenderTrust;try{k=Le(u)}catch(I){i.ui.notify(`NATS: ${I.message}`,"error"),i.ui.setStatus("nats","NATS: disconnected");return}R=nn(i),f=Ce(process.env.SYNADIA_PI_OWNER,process.env.SYNADIA_OWNER,process.env.NATS_PI_OWNER,u.owner,process.env.USER);let P=V(process.env.SYNADIA_PI_NAME??process.env.SYNADIA_NAME??process.env.NATS_SESSION_NAME??u.sessionName??Bt(i.cwd))||"pi",A=Ie(u.extensions,process.env,(I)=>R.warn(I));if(A.entries.length>0){let I=await ke(A.entries,{harness:"pi",plugin:{name:zt,version:Kt},settings:{owner:f,name:P,senderIdentity:d.senderIdentity,minSenderTrust:d.minSenderTrust,stateDir:Z,config:Object.freeze({...u})},logger:R},R);try{v=ie(I,R,{pluginMetadataKeys:Gt})}catch(ne){i.ui.notify(`NATS: ${ne.message}`,"error"),i.ui.setStatus("nats","NATS: disconnected");return}if(N)return}i.ui.setStatus("nats","NATS: connecting…");let y=ct(d,i,P);h=y;let _=()=>{if(h===y)h=void 0};y.then(_,_)}),e.on("message_update",async(p)=>{if(!t)return;let i=p.assistantMessageEvent;if(i.type!=="text_delta"||!i.delta)return;let u=b.active;if(!u)return;try{await st(u,i.delta)}catch(d){T?.ui.notify(`NATS: publish failed: ${d.message}`,"warning")}}),e.on("agent_settled",async()=>{let p=b.completeActive();if(p)v.events.promptEnded(p.served,"ok",Date.now());if(await Promise.resolve(),t)try{await t.flush()}catch{}ee()}),e.on("before_provider_headers",(p)=>{let i=b.active;if(!i)return;let u=v.events.providerHeaders(i.served);for(let[d,P]of Object.entries(u))p.headers[d]=P}),e.on("session_shutdown",async()=>{await te()}),e.registerCommand("nats-status",{description:"Show NATS channel status",handler:async(p,i)=>{if(!t||!o){i.ui.notify("NATS: not connected","warning");return}let u=b.active,d=[`Connection: ${w}`,`Subject: ${o}`,`Service: ${le} v${He}`,`Protocol: ${ce.major}.${ce.minor}`,`Instance: ${c??"?"}`,`Session: ${s}`,`Owner: ${f}`,`Sender identity: ${j}${n?.identity?` (${n.identity})`:""}`,`Minimum sender trust: ${D}`,`Agent tools: ${k}${C.length>0?` (${C.join(", ")})`:""}`,`Extensions: ${v.names.length>0?v.names.join(", "):"none"}`,`Pending: ${b.size}`,`Queued: ${b.queuedCount}`,`Active: ${u?.id??"none"}`,`Active sender: ${u?Ve(u.response.sender):"none"}`].filter(Boolean).join(" • ");i.ui.notify(d,"info")}}),e.registerCommand("nats-configure",{description:"Show or update NATS channel configuration (usage: /nats-configure [ <context> | session <name|clear> | owner <name|clear> | identity <off|signed> | trust <any|signed> ])",handler:async(p,i)=>{let u=Be(),d=p.trim().split(/\s+/).filter(Boolean);if(d.length===0){let y=[`Context: ${u.context??"(default: demo.nats.io)"}`,`Owner: ${u.owner??"(default: $USER)"}`,`Session: ${u.sessionName??"(auto from cwd)"}`,`Sender identity: ${u.senderIdentity??"off"}`,`Minimum sender trust: ${u.minSenderTrust??"any"}`,`Agent tools: ${u.agentTools??"blocking"}`,`Extensions: ${Array.isArray(u.extensions)&&u.extensions.length>0?u.extensions.map((_)=>typeof _==="string"?_:_.module).join(", "):"(none)"}`];i.ui.notify(`NATS config — ${y.join(" • ")}`,"info");return}let P={...u},A=!1;if(d[0]==="session")if(d[1]==="clear")delete P.sessionName,A=!0;else if(d[1])P.sessionName=V(d[1]),A=!0;else{i.ui.notify("Usage: /nats-configure session <name|clear>","warning");return}else if(d[0]==="owner")if(d[1]==="clear")delete P.owner,A=!0;else if(d[1])P.owner=V(d[1]),A=!0;else{i.ui.notify("Usage: /nats-configure owner <name|clear>","warning");return}else if(d[0]==="identity"){if(!d[1]){i.ui.notify("Usage: /nats-configure identity <off|signed>","warning");return}try{P.senderIdentity=W("senderIdentity",d[1],"off",["off","signed"]),A=!0}catch(y){i.ui.notify(`NATS: ${y.message}`,"warning");return}}else if(d[0]==="trust"){if(!d[1]){i.ui.notify("Usage: /nats-configure trust <any|signed>","warning");return}try{P.minSenderTrust=W("minSenderTrust",d[1],"any",["any","signed"]),A=!0}catch(y){i.ui.notify(`NATS: ${y.message}`,"warning");return}}else{let y=d[0],_;try{_=await de({context:y})}catch(I){i.ui.notify(`NATS: ${I.message}`,"error");return}finally{_?.wipe()}P.context=y,A=!0}if(!A){i.ui.notify("NATS: no changes","info");return}try{tn(P)}catch(y){i.ui.notify(`NATS: failed to save config: ${y.message}`,"error");return}i.ui.notify("NATS config updated. Restart PI for changes to take effect.","info")}})}export{Yt as HEARTBEAT_INTERVAL_S,on as default,en as resolveConnectionSettings};
|
package/package.json
CHANGED
|
@@ -1,56 +1,16 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@synadia-ai/agent-fabric-pi",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
5
|
-
"type": "module",
|
|
6
|
-
"main": "./dist/index.cjs",
|
|
7
|
-
"module": "./dist/index.js",
|
|
8
|
-
"types": "./dist/index.d.ts",
|
|
9
|
-
"exports": {
|
|
10
|
-
".": {
|
|
11
|
-
"types": "./dist/index.d.ts",
|
|
12
|
-
"import": "./dist/index.js",
|
|
13
|
-
"require": "./dist/index.cjs",
|
|
14
|
-
"default": "./dist/index.js"
|
|
15
|
-
},
|
|
16
|
-
"./package.json": "./package.json"
|
|
17
|
-
},
|
|
18
|
-
"files": [
|
|
19
|
-
"dist",
|
|
20
|
-
"skill",
|
|
21
|
-
"README.md",
|
|
22
|
-
"CHANGELOG.md",
|
|
23
|
-
"LICENSE"
|
|
24
|
-
],
|
|
25
|
-
"sideEffects": false,
|
|
26
|
-
"engines": {
|
|
27
|
-
"node": ">=20.0.0"
|
|
28
|
-
},
|
|
29
|
-
"scripts": {
|
|
30
|
-
"build": "tsup",
|
|
31
|
-
"build:sp": "sh ../scratchpad-skill/install.sh",
|
|
32
|
-
"typecheck": "tsc --noEmit",
|
|
33
|
-
"lint": "eslint .",
|
|
34
|
-
"lint:fix": "eslint . --fix",
|
|
35
|
-
"format": "prettier --write .",
|
|
36
|
-
"format:check": "prettier --check .",
|
|
37
|
-
"test": "vitest run",
|
|
38
|
-
"test:unit": "vitest run test/unit",
|
|
39
|
-
"test:integration": "vitest run test/integration",
|
|
40
|
-
"test:watch": "vitest",
|
|
41
|
-
"check": "npm run typecheck && npm run lint && npm run format:check && npm run test",
|
|
42
|
-
"prepack": "npm run build:sp",
|
|
43
|
-
"prepublishOnly": "npm run build"
|
|
44
|
-
},
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "pi on the Synadia Agent Fabric: the NATS channel for pi with the fabric's tracing and ScratchPad, in one package",
|
|
45
5
|
"keywords": [
|
|
6
|
+
"pi-package",
|
|
7
|
+
"pi-agent",
|
|
46
8
|
"nats",
|
|
47
|
-
"
|
|
48
|
-
"
|
|
49
|
-
"agent-
|
|
50
|
-
"
|
|
51
|
-
"
|
|
52
|
-
"synadia",
|
|
53
|
-
"sdk"
|
|
9
|
+
"agent",
|
|
10
|
+
"channel",
|
|
11
|
+
"synadia-agent-protocol",
|
|
12
|
+
"synadia-agents",
|
|
13
|
+
"synadia-agent-fabric"
|
|
54
14
|
],
|
|
55
15
|
"license": "Apache-2.0",
|
|
56
16
|
"author": "Synadia Communications",
|
|
@@ -59,29 +19,31 @@
|
|
|
59
19
|
"url": "git+https://github.com/synadia-ai/agent-fabric-sdk.git",
|
|
60
20
|
"directory": "plugins/pi"
|
|
61
21
|
},
|
|
62
|
-
"
|
|
63
|
-
"
|
|
64
|
-
|
|
22
|
+
"type": "module",
|
|
23
|
+
"main": "./dist/fabric.js",
|
|
24
|
+
"exports": {
|
|
25
|
+
".": "./dist/fabric.js",
|
|
26
|
+
"./package.json": "./package.json"
|
|
27
|
+
},
|
|
28
|
+
"files": [
|
|
29
|
+
"dist",
|
|
30
|
+
"skill",
|
|
31
|
+
"BUILD",
|
|
32
|
+
"README.md",
|
|
33
|
+
"LICENSE"
|
|
34
|
+
],
|
|
35
|
+
"peerDependencies": {
|
|
36
|
+
"@earendil-works/pi-coding-agent": ">=0.84.0 <0.86.0"
|
|
65
37
|
},
|
|
66
38
|
"publishConfig": {
|
|
67
39
|
"access": "public"
|
|
68
40
|
},
|
|
69
|
-
"
|
|
70
|
-
"
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
"@nats-io/transport-node": "^3.4.0",
|
|
77
|
-
"@types/node": "^20.16.0",
|
|
78
|
-
"ajv": "^8.17.0",
|
|
79
|
-
"eslint": "^9.0.0",
|
|
80
|
-
"eslint-config-prettier": "^9.1.0",
|
|
81
|
-
"prettier": "3.9.5",
|
|
82
|
-
"tsup": "^8.3.0",
|
|
83
|
-
"typescript": "~5.6.0",
|
|
84
|
-
"typescript-eslint": "^8.10.0",
|
|
85
|
-
"vitest": "^3.2.0"
|
|
41
|
+
"pi": {
|
|
42
|
+
"extensions": [
|
|
43
|
+
"./dist/channel.js"
|
|
44
|
+
],
|
|
45
|
+
"skills": [
|
|
46
|
+
"./skill"
|
|
47
|
+
]
|
|
86
48
|
}
|
|
87
49
|
}
|
package/CHANGELOG.md
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
|
|
3
|
-
All notable changes to `@synadia-ai/agent-fabric-pi` are recorded here. The
|
|
4
|
-
format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and the
|
|
5
|
-
package follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
6
|
-
|
|
7
|
-
## [0.1.0] — unreleased
|
|
8
|
-
|
|
9
|
-
### Added
|
|
10
|
-
|
|
11
|
-
- The extension module for the PI channel plugin, named in `SYNADIA_PI_EXTENSIONS`: `fabricTracing()` on the plugin's service and agent-tools client.
|
|
12
|
-
- The `X-Synadia-Thread-ID` and `X-Synadia-Root-ID` headers on PI's own model calls, with each served request's scope bound at PI's events.
|
|
13
|
-
- The `409` loop guard in front of PI's handler.
|
|
14
|
-
- The edge subject setting: `options.edgeSubject`, `SYNADIA_FABRIC_EDGE_SUBJECT`, or `TRACE.edges`.
|
|
15
|
-
- ScratchPad: the shared skill with the sp command line for darwin and linux, its variables for `scripts/sp`, references in and out, and grant requests.
|
|
16
|
-
|
|
17
|
-
[0.1.0]: https://github.com/synadia-ai/agent-fabric-sdk/tree/main/plugins/pi
|
package/dist/index.cjs
DELETED
|
@@ -1,154 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
-
|
|
5
|
-
var agentFabric = require('@synadia-ai/agent-fabric');
|
|
6
|
-
var url = require('url');
|
|
7
|
-
|
|
8
|
-
// node_modules/tsup/assets/cjs_shims.js
|
|
9
|
-
var getImportMetaUrl = () => typeof document === "undefined" ? new URL(`file:${__filename}`).href : document.currentScript && document.currentScript.tagName.toUpperCase() === "SCRIPT" ? document.currentScript.src : new URL("main.js", document.baseURI).href;
|
|
10
|
-
var importMetaUrl = /* @__PURE__ */ getImportMetaUrl();
|
|
11
|
-
var SKILL_DIR = url.fileURLToPath(new URL("../skill/scratchpad", importMetaUrl));
|
|
12
|
-
function spBinary(env) {
|
|
13
|
-
return agentFabric.spBinary(env, SKILL_DIR);
|
|
14
|
-
}
|
|
15
|
-
function spPort(settings, creator, env) {
|
|
16
|
-
return agentFabric.spPort(settings, creator, env, SKILL_DIR);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
// src/extension.ts
|
|
20
|
-
var EXTENSION_NAME = "agent-fabric";
|
|
21
|
-
var IDENTITY_OFF_WARNING = `${EXTENSION_NAME}: senderIdentity is off; trace records are signed, so none will be published and each counts as dropped on the heartbeat. Set senderIdentity to signed.`;
|
|
22
|
-
async function fabricExtension(ctx, env = process.env) {
|
|
23
|
-
return createFabricExtension(ctx, env, await agentFabric.resolveScratchPad(ctx, env));
|
|
24
|
-
}
|
|
25
|
-
function createFabricExtension(ctx, env = process.env, scratchPad) {
|
|
26
|
-
const edgeSubject = agentFabric.resolveEdgeSubject(ctx.options, env);
|
|
27
|
-
const tracing = agentFabric.fabricTracing({ edgeSubject });
|
|
28
|
-
const guard = agentFabric.loopGuard();
|
|
29
|
-
const log = ctx.logger;
|
|
30
|
-
const scopes = /* @__PURE__ */ new Map();
|
|
31
|
-
const scopeOf = (request) => request === void 0 ? void 0 : scopes.get(request.id);
|
|
32
|
-
let warnedIdentityOff = false;
|
|
33
|
-
const scratchPadOn = scratchPad !== void 0;
|
|
34
|
-
const promptEnv = new agentFabric.ServedPromptEnv(env);
|
|
35
|
-
if (scratchPad !== void 0) agentFabric.exportScratchPad(scratchPad, env);
|
|
36
|
-
const handOn = scratchPad !== void 0 ? new agentFabric.ScratchPadHandOn() : void 0;
|
|
37
|
-
return {
|
|
38
|
-
name: EXTENSION_NAME,
|
|
39
|
-
// The service: tracing first, so the guard runs inside the scope tracing
|
|
40
|
-
// bound and a malformed pair is refused with 400 before the guard
|
|
41
|
-
// looks; the plugin appends its own (the tools' scope) after these.
|
|
42
|
-
// The ScratchPad extension's, last, remembers the references each
|
|
43
|
-
// served prompt brings, which PI may hand on.
|
|
44
|
-
requestInterceptors: [
|
|
45
|
-
tracing.requestInterceptor,
|
|
46
|
-
guard.requestInterceptor,
|
|
47
|
-
...handOn !== void 0 ? [handOn.requestInterceptor] : []
|
|
48
|
-
],
|
|
49
|
-
// The client PI's agent tools prompt through: the edge and the pair,
|
|
50
|
-
// then the waiting mark. Both read the ambient scope, so the order
|
|
51
|
-
// between them does not matter.
|
|
52
|
-
promptInterceptors: [tracing.promptInterceptor, guard.promptInterceptor],
|
|
53
|
-
heartbeatExtras: tracing.heartbeatExtras,
|
|
54
|
-
...handOn !== void 0 ? {
|
|
55
|
-
// References in PI's `prompt_agent`: granted to a receiver that
|
|
56
|
-
// reads them, removed with a note for any other.
|
|
57
|
-
toolExtensions: [handOn],
|
|
58
|
-
// So a caller's `prompt_agent` hands references to PI.
|
|
59
|
-
metadata: { [agentFabric.READS_REFERENCES_KEY]: "true" }
|
|
60
|
-
} : {},
|
|
61
|
-
// No `stopping`: an
|
|
62
|
-
// edge record is published before the prompt it describes and counted
|
|
63
|
-
// as it goes, so there is nothing to flush when the plugin stops.
|
|
64
|
-
started({ agents, service }) {
|
|
65
|
-
if (ctx.settings.senderIdentity !== "signed" && !warnedIdentityOff) {
|
|
66
|
-
warnedIdentityOff = true;
|
|
67
|
-
log.warn(IDENTITY_OFF_WARNING);
|
|
68
|
-
}
|
|
69
|
-
log.info(
|
|
70
|
-
`${EXTENSION_NAME}: tracing ${service.subject.prompt}` + (edgeSubject === null ? " (propagate-only: lineage forwarded, no edge record published)" : `, edge records on ${edgeSubject}`)
|
|
71
|
-
);
|
|
72
|
-
if (scratchPad !== void 0 && handOn !== void 0) {
|
|
73
|
-
env[agentFabric.SP_VARS.creator] = service.subject.prompt;
|
|
74
|
-
const port = spPort(scratchPad, service.subject.prompt, env);
|
|
75
|
-
if (port !== void 0) handOn.start({ scratchPad: port, agents, service, logger: log });
|
|
76
|
-
else
|
|
77
|
-
log.warn(
|
|
78
|
-
`${EXTENSION_NAME}: no sp for this platform (set SCRATCHPAD_BIN); references in prompt_agent are not handed on, and grant requests not answered`
|
|
79
|
-
);
|
|
80
|
-
log.info(
|
|
81
|
-
`${EXTENSION_NAME}: ScratchPad volume ${scratchPad.volume}` + (scratchPad.dir !== void 0 ? `, workspace ${scratchPad.dir}` : ", no workspace") + ", for the skill's scripts/sp"
|
|
82
|
-
);
|
|
83
|
-
}
|
|
84
|
-
},
|
|
85
|
-
events: {
|
|
86
|
-
promptAccepted(request) {
|
|
87
|
-
const scope = agentFabric.activeTrace();
|
|
88
|
-
if (scope !== void 0) scopes.set(request.id, scope);
|
|
89
|
-
},
|
|
90
|
-
promptEnded(request) {
|
|
91
|
-
scopes.delete(request.id);
|
|
92
|
-
promptEnv.leave(request);
|
|
93
|
-
},
|
|
94
|
-
aroundInject(request, run) {
|
|
95
|
-
const scope = scopes.get(request.id);
|
|
96
|
-
if (scratchPadOn) promptEnv.enter(request, scope);
|
|
97
|
-
return scope === void 0 ? run() : agentFabric.bindActiveTrace(scope, run);
|
|
98
|
-
},
|
|
99
|
-
providerHeaders(request) {
|
|
100
|
-
const scope = scopes.get(request.id);
|
|
101
|
-
return scope === void 0 ? void 0 : agentFabric.bindActiveTrace(scope, agentFabric.traceHeaders);
|
|
102
|
-
},
|
|
103
|
-
aroundToolCall(request, _toolName, run) {
|
|
104
|
-
const scope = scopeOf(request);
|
|
105
|
-
return scope === void 0 ? run() : agentFabric.bindActiveTrace(scope, () => guard.aroundToolCall(scope, run));
|
|
106
|
-
}
|
|
107
|
-
}
|
|
108
|
-
};
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
Object.defineProperty(exports, "EDGE_SUBJECT_OPTION", {
|
|
112
|
-
enumerable: true,
|
|
113
|
-
get: function () { return agentFabric.EDGE_SUBJECT_OPTION; }
|
|
114
|
-
});
|
|
115
|
-
Object.defineProperty(exports, "EDGE_SUBJECT_VAR", {
|
|
116
|
-
enumerable: true,
|
|
117
|
-
get: function () { return agentFabric.EDGE_SUBJECT_VAR; }
|
|
118
|
-
});
|
|
119
|
-
Object.defineProperty(exports, "LOOP_GUARD_CODE", {
|
|
120
|
-
enumerable: true,
|
|
121
|
-
get: function () { return agentFabric.LOOP_GUARD_CODE; }
|
|
122
|
-
});
|
|
123
|
-
Object.defineProperty(exports, "SCRATCHPAD_OPTION", {
|
|
124
|
-
enumerable: true,
|
|
125
|
-
get: function () { return agentFabric.SCRATCHPAD_OPTION; }
|
|
126
|
-
});
|
|
127
|
-
Object.defineProperty(exports, "SP_VARS", {
|
|
128
|
-
enumerable: true,
|
|
129
|
-
get: function () { return agentFabric.SP_VARS; }
|
|
130
|
-
});
|
|
131
|
-
Object.defineProperty(exports, "ScratchPadHandOn", {
|
|
132
|
-
enumerable: true,
|
|
133
|
-
get: function () { return agentFabric.ScratchPadHandOn; }
|
|
134
|
-
});
|
|
135
|
-
Object.defineProperty(exports, "loopGuard", {
|
|
136
|
-
enumerable: true,
|
|
137
|
-
get: function () { return agentFabric.loopGuard; }
|
|
138
|
-
});
|
|
139
|
-
Object.defineProperty(exports, "loopGuardDescription", {
|
|
140
|
-
enumerable: true,
|
|
141
|
-
get: function () { return agentFabric.loopGuardDescription; }
|
|
142
|
-
});
|
|
143
|
-
Object.defineProperty(exports, "resolveEdgeSubject", {
|
|
144
|
-
enumerable: true,
|
|
145
|
-
get: function () { return agentFabric.resolveEdgeSubject; }
|
|
146
|
-
});
|
|
147
|
-
exports.EXTENSION_NAME = EXTENSION_NAME;
|
|
148
|
-
exports.IDENTITY_OFF_WARNING = IDENTITY_OFF_WARNING;
|
|
149
|
-
exports.createFabricExtension = createFabricExtension;
|
|
150
|
-
exports.default = fabricExtension;
|
|
151
|
-
exports.fabricExtension = fabricExtension;
|
|
152
|
-
exports.spBinary = spBinary;
|
|
153
|
-
//# sourceMappingURL=index.cjs.map
|
|
154
|
-
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../node_modules/tsup/assets/cjs_shims.js","../src/scratchpad.ts","../src/extension.ts"],"names":["fileURLToPath","sharedSpBinary","sharedSpPort","resolveScratchPad","resolveEdgeSubject","fabricTracing","loopGuard","ServedPromptEnv","exportScratchPad","ScratchPadHandOn","READS_REFERENCES_KEY","SP_VARS","activeTrace","bindActiveTrace","traceHeaders"],"mappings":";;;;;;;;AAKA,IAAM,gBAAA,GAAmB,MACvB,OAAO,QAAA,KAAa,WAAA,GAChB,IAAI,GAAA,CAAI,CAAA,KAAA,EAAQ,UAAU,CAAA,CAAE,CAAA,CAAE,IAAA,GAC7B,QAAA,CAAS,aAAA,IAAiB,QAAA,CAAS,aAAA,CAAc,OAAA,CAAQ,WAAA,EAAY,KAAM,QAAA,GAC1E,QAAA,CAAS,aAAA,CAAc,GAAA,GACvB,IAAI,GAAA,CAAI,SAAA,EAAW,QAAA,CAAS,OAAO,CAAA,CAAE,IAAA;AAEtC,IAAM,gCAAgC,gBAAA,EAAiB;ACgBvD,IAAM,YAAYA,iBAAA,CAAc,IAAI,GAAA,CAAI,qBAAA,EAAuB,aAAe,CAAC,CAAA;AAG/E,SAAS,SAAS,GAAA,EAA6D;AACpF,EAAA,OAAOC,oBAAA,CAAe,KAAK,SAAS,CAAA;AACtC;AAGO,SAAS,MAAA,CACd,QAAA,EACA,OAAA,EACA,GAAA,EACwB;AACxB,EAAA,OAAOC,kBAAA,CAAa,QAAA,EAAU,OAAA,EAAS,GAAA,EAAK,SAAS,CAAA;AACvD;;;ACcO,IAAM,cAAA,GAAiB;AAGvB,IAAM,oBAAA,GACX,GAAG,cAAc,CAAA,uJAAA;AAanB,eAAsB,eAAA,CACpB,GAAA,EACA,GAAA,GAAyB,OAAA,CAAQ,GAAA,EACR;AACzB,EAAA,OAAO,sBAAsB,GAAA,EAAK,GAAA,EAAK,MAAMC,6BAAA,CAAkB,GAAA,EAAK,GAAG,CAAC,CAAA;AAC1E;AAMO,SAAS,qBAAA,CACd,GAAA,EACA,GAAA,GAAyB,OAAA,CAAQ,KACjC,UAAA,EACgB;AAChB,EAAA,MAAM,WAAA,GAAcC,8BAAA,CAAmB,GAAA,CAAI,OAAA,EAAS,GAAG,CAAA;AACvD,EAAA,MAAM,OAAA,GAAUC,yBAAA,CAAc,EAAE,WAAA,EAAa,CAAA;AAC7C,EAAA,MAAM,QAAQC,qBAAA,EAAU;AACxB,EAAA,MAAM,MAAM,GAAA,CAAI,MAAA;AAWhB,EAAA,MAAM,MAAA,uBAAa,GAAA,EAAwB;AAC3C,EAAA,MAAM,OAAA,GAAU,CAAC,OAAA,KACf,OAAA,KAAY,SAAY,MAAA,GAAY,MAAA,CAAO,GAAA,CAAI,OAAA,CAAQ,EAAE,CAAA;AAE3D,EAAA,IAAI,iBAAA,GAAoB,KAAA;AACxB,EAAA,MAAM,eAAe,UAAA,KAAe,MAAA;AACpC,EAAA,MAAM,SAAA,GAAY,IAAIC,2BAAA,CAAgB,GAAG,CAAA;AAEzC,EAAA,IAAI,UAAA,KAAe,MAAA,EAAWC,4BAAA,CAAiB,UAAA,EAAY,GAAG,CAAA;AAC9D,EAAA,MAAM,MAAA,GAAS,UAAA,KAAe,MAAA,GAAY,IAAIC,8BAAiB,GAAI,MAAA;AAEnE,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,cAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAMN,mBAAA,EAAqB;AAAA,MACnB,OAAA,CAAQ,kBAAA;AAAA,MACR,KAAA,CAAM,kBAAA;AAAA,MACN,GAAI,MAAA,KAAW,MAAA,GAAY,CAAC,MAAA,CAAO,kBAAkB,IAAI;AAAC,KAC5D;AAAA;AAAA;AAAA;AAAA,IAIA,kBAAA,EAAoB,CAAC,OAAA,CAAQ,iBAAA,EAAmB,MAAM,iBAAiB,CAAA;AAAA,IACvE,iBAAiB,OAAA,CAAQ,eAAA;AAAA,IACzB,GAAI,WAAW,MAAA,GACX;AAAA;AAAA;AAAA,MAGE,cAAA,EAAgB,CAAC,MAAM,CAAA;AAAA;AAAA,MAEvB,QAAA,EAAU,EAAE,CAACC,gCAAoB,GAAG,MAAA;AAAO,QAE7C,EAAC;AAAA;AAAA;AAAA;AAAA,IAKL,OAAA,CAAQ,EAAE,MAAA,EAAQ,OAAA,EAAQ,EAAG;AAC3B,MAAA,IAAI,GAAA,CAAI,QAAA,CAAS,cAAA,KAAmB,QAAA,IAAY,CAAC,iBAAA,EAAmB;AAClE,QAAA,iBAAA,GAAoB,IAAA;AACpB,QAAA,GAAA,CAAI,KAAK,oBAAoB,CAAA;AAAA,MAC/B;AACA,MAAA,GAAA,CAAI,IAAA;AAAA,QACF,CAAA,EAAG,cAAc,CAAA,UAAA,EAAa,OAAA,CAAQ,OAAA,CAAQ,MAAM,CAAA,CAAA,IACjD,WAAA,KAAgB,IAAA,GACb,gEAAA,GACA,CAAA,kBAAA,EAAqB,WAAW,CAAA,CAAA;AAAA,OACxC;AACA,MAAA,IAAI,UAAA,KAAe,MAAA,IAAa,MAAA,KAAW,MAAA,EAAW;AACpD,QAAA,GAAA,CAAIC,mBAAA,CAAQ,OAAO,CAAA,GAAI,OAAA,CAAQ,OAAA,CAAQ,MAAA;AACvC,QAAA,MAAM,OAAO,MAAA,CAAO,UAAA,EAAY,OAAA,CAAQ,OAAA,CAAQ,QAAQ,GAAG,CAAA;AAC3D,QAAA,IAAI,IAAA,KAAS,MAAA,EAAW,MAAA,CAAO,KAAA,CAAM,EAAE,UAAA,EAAY,IAAA,EAAM,MAAA,EAAQ,OAAA,EAAS,MAAA,EAAQ,GAAA,EAAK,CAAA;AAAA;AAErF,UAAA,GAAA,CAAI,IAAA;AAAA,YACF,GAAG,cAAc,CAAA,6HAAA;AAAA,WAEnB;AACF,QAAA,GAAA,CAAI,IAAA;AAAA,UACF,CAAA,EAAG,cAAc,CAAA,oBAAA,EAAuB,UAAA,CAAW,MAAM,CAAA,CAAA,IACtD,UAAA,CAAW,GAAA,KAAQ,MAAA,GAAY,CAAA,YAAA,EAAe,UAAA,CAAW,GAAG,KAAK,gBAAA,CAAA,GAClE;AAAA,SACJ;AAAA,MACF;AAAA,IACF,CAAA;AAAA,IAEA,MAAA,EAAQ;AAAA,MACN,eAAe,OAAA,EAAS;AAEtB,QAAA,MAAM,QAAQC,uBAAA,EAAY;AAC1B,QAAA,IAAI,UAAU,MAAA,EAAW,MAAA,CAAO,GAAA,CAAI,OAAA,CAAQ,IAAI,KAAK,CAAA;AAAA,MACvD,CAAA;AAAA,MACA,YAAY,OAAA,EAAS;AACnB,QAAA,MAAA,CAAO,MAAA,CAAO,QAAQ,EAAE,CAAA;AACxB,QAAA,SAAA,CAAU,MAAM,OAAO,CAAA;AAAA,MACzB,CAAA;AAAA,MACA,YAAA,CAAa,SAAS,GAAA,EAAK;AACzB,QAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,GAAA,CAAI,OAAA,CAAQ,EAAE,CAAA;AAGnC,QAAA,IAAI,YAAA,EAAc,SAAA,CAAU,KAAA,CAAM,OAAA,EAAS,KAAK,CAAA;AAChD,QAAA,OAAO,UAAU,MAAA,GAAY,GAAA,EAAI,GAAIC,2BAAA,CAAgB,OAAO,GAAG,CAAA;AAAA,MACjE,CAAA;AAAA,MACA,gBAAgB,OAAA,EAAS;AAIvB,QAAA,MAAM,KAAA,GAAQ,MAAA,CAAO,GAAA,CAAI,OAAA,CAAQ,EAAE,CAAA;AACnC,QAAA,OAAO,KAAA,KAAU,MAAA,GAAY,MAAA,GAAYA,2BAAA,CAAgB,OAAOC,wBAAY,CAAA;AAAA,MAC9E,CAAA;AAAA,MACA,cAAA,CAAe,OAAA,EAAS,SAAA,EAAW,GAAA,EAAK;AAGtC,QAAA,MAAM,KAAA,GAAQ,QAAQ,OAAO,CAAA;AAC7B,QAAA,OAAO,KAAA,KAAU,MAAA,GACb,GAAA,EAAI,GACJD,2BAAA,CAAgB,KAAA,EAAO,MAAM,KAAA,CAAM,cAAA,CAAe,KAAA,EAAO,GAAG,CAAC,CAAA;AAAA,MACnE;AAAA;AACF,GACF;AACF","file":"index.cjs","sourcesContent":["// Shim globals in cjs bundle\n// There's a weird bug that esbuild will always inject importMetaUrl\n// if we export it as `const importMetaUrl = ... __filename ...`\n// But using a function will not cause this issue\n\nconst getImportMetaUrl = () => \n typeof document === \"undefined\" \n ? new URL(`file:${__filename}`).href \n : (document.currentScript && document.currentScript.tagName.toUpperCase() === 'SCRIPT') \n ? document.currentScript.src \n : new URL(\"main.js\", document.baseURI).href;\n\nexport const importMetaUrl = /* @__PURE__ */ getImportMetaUrl()\n","// ScratchPad for PI's model (`docs/plugins.md` §9): the pieces every add-on\n// shares, from the fabric package (`plugin-scratchpad.ts` there), with this\n// package's copy of the skill (`skill/scratchpad`, installed by\n// `npm run build:sp` from `plugins/scratchpad-skill`). PI's bash tool passes\n// PI's process environment to every command it runs (measured on PI 0.85.1,\n// §9.4), and the plugin hands PI one prompt at a time, so the per-prompt\n// variables are sound; a command PI runs for local typing during a remote\n// turn gets the served prompt's (§7, \"PI's turn boundaries\").\n\nimport { fileURLToPath } from \"node:url\";\nimport {\n spBinary as sharedSpBinary,\n spPort as sharedSpPort,\n type ScratchPad,\n type ScratchPadSettings,\n} from \"@synadia-ai/agent-fabric\";\n\nexport {\n exportScratchPad,\n resolveScratchPad,\n SCRATCHPAD_OPTION,\n ScratchPadHandOn,\n ServedPromptEnv,\n SP_VARS,\n type ScratchPadSettings,\n} from \"@synadia-ai/agent-fabric\";\n\n/** This package's skill directory: `src/` in the tests, `dist/` when installed, one level below it. */\nexport const SKILL_DIR = fileURLToPath(new URL(\"../skill/scratchpad\", import.meta.url));\n\n/** The sp binary this package ships for this machine, or `SCRATCHPAD_BIN`. */\nexport function spBinary(env: Record<string, string | undefined>): string | undefined {\n return sharedSpBinary(env, SKILL_DIR);\n}\n\n/** The ScratchPad port over this package's sp, for the extension's grants. */\nexport function spPort(\n settings: ScratchPadSettings,\n creator: string,\n env: Record<string, string | undefined>,\n): ScratchPad | undefined {\n return sharedSpPort(settings, creator, env, SKILL_DIR);\n}\n","// The fabric add-on for the PI channel plugin: the factory the plugin calls\n// once at start, and the extension it returns (`docs/plugins.md` §2.3, §2.4,\n// §3.1, §3.2).\n//\n// What it does, in one screen. The fabric package's `fabricTracing()` gives\n// the three hooks the SDK takes; the plugin puts the request interceptor and\n// the heartbeat extras on its `AgentService` and the prompt interceptor on\n// the `Agents` client its agent tools prompt through. That alone makes PI\n// what an SDK-built agent is on the wire: the envelope's pair adopted or a\n// root minted per served prompt, an `edge` record before every prompt PI's\n// model sends, the record counts on the heartbeat. The harness piece is the\n// scope: PI's loop does not run in the handler's async context, so the\n// add-on keeps each served request's scope by the plugin's request id and\n// binds it where the plugin says the request is being worked on —\n// `aroundInject` around the hand-over to PI's loop, `aroundToolCall` around\n// every agent-tool call, and `providerHeaders`, which returns the fabric's\n// two headers for the request so the proxy files PI's own model calls on\n// the served thread. The `409` loop guard is its own two interceptors,\n// after tracing's, and its `aroundToolCall` inside the add-on's, which lifts\n// the mark once the request's calls have settled (`loopGuard`, from the\n// fabric package).\n//\n// ScratchPad (§9): when a volume is configured, the add-on sets the\n// environment the package's skill (`skill/scratchpad`, given to PI with\n// `--skill`) reads through `scripts/sp`: the connection, the workspace and\n// the volume before the plugin connects, the served prompt's trace and\n// caller from its hand-over to its end. It registers PI as reading\n// references, hands the references PI's model puts into `prompt_agent`\n// to the fabric package's ScratchPad extension (`scratchpad.ts`), and\n// answers grant requests for what PI published, by an SDK-built agent's\n// rule.\n\nimport {\n activeTrace,\n bindActiveTrace,\n fabricTracing,\n loopGuard,\n resolveEdgeSubject,\n traceHeaders,\n type AgentExtension,\n type AgentExtensionContext,\n type ServedRequest,\n type TraceScope,\n READS_REFERENCES_KEY,\n} from \"@synadia-ai/agent-fabric\";\nimport {\n exportScratchPad,\n resolveScratchPad,\n ScratchPadHandOn,\n ServedPromptEnv,\n SP_VARS,\n spPort,\n type ScratchPadSettings,\n} from \"./scratchpad.js\";\n\n/** The extension's name, as the plugin's status output lists it. */\nexport const EXTENSION_NAME = \"agent-fabric\";\n\n/** The warning logged once at start when the plugin's identity is off. */\nexport const IDENTITY_OFF_WARNING =\n `${EXTENSION_NAME}: senderIdentity is off; trace records are signed, so none will be ` +\n \"published and each counts as dropped on the heartbeat. Set senderIdentity to signed.\";\n\n/**\n * The factory: the module's default export. Called once by the plugin,\n * before it connects, with what it knows then. Resolves ScratchPad's\n * settings (which may read the plugin's NATS context) and builds the\n * extension with them. Throws `NatsAgentError` for an edge subject that can\n * never be published to.\n *\n * `env` is where the variables are read from, and where ScratchPad's are\n * set for PI's bash tool; a test passes its own.\n */\nexport async function fabricExtension(\n ctx: AgentExtensionContext,\n env: NodeJS.ProcessEnv = process.env,\n): Promise<AgentExtension> {\n return createFabricExtension(ctx, env, await resolveScratchPad(ctx, env));\n}\n\n/**\n * The extension, built synchronously from settings already resolved:\n * without `scratchPad`, tracing and the guard alone.\n */\nexport function createFabricExtension(\n ctx: AgentExtensionContext,\n env: NodeJS.ProcessEnv = process.env,\n scratchPad?: ScratchPadSettings,\n): AgentExtension {\n const edgeSubject = resolveEdgeSubject(ctx.options, env);\n const tracing = fabricTracing({ edgeSubject });\n const guard = loopGuard();\n const log = ctx.logger;\n\n // Each served request's scope, the one tracing bound around its handler,\n // by the plugin's request id: kept from `promptAccepted`, which the plugin\n // calls inside the handler, to `promptEnded`. `bindActiveTrace` runs its\n // function inside an `AsyncLocalStorage.run`, which *replaces* the\n // ambient context — as it must: PI's turn, its provider requests and the\n // tools it executes all run in the async context of whoever called\n // `pi.sendUserMessage()`, and when the plugin injects the next queued\n // prompt from the previous turn's settle hook that context is the\n // previous request's (measured on PI 0.85.1, `docs/plugins.md` §3.5 gap 3).\n const scopes = new Map<string, TraceScope>();\n const scopeOf = (request: ServedRequest | undefined): TraceScope | undefined =>\n request === undefined ? undefined : scopes.get(request.id);\n\n let warnedIdentityOff = false;\n const scratchPadOn = scratchPad !== undefined;\n const promptEnv = new ServedPromptEnv(env);\n // Set before the plugin connects, so a command PI runs at any time finds them.\n if (scratchPad !== undefined) exportScratchPad(scratchPad, env);\n const handOn = scratchPad !== undefined ? new ScratchPadHandOn() : undefined;\n\n return {\n name: EXTENSION_NAME,\n // The service: tracing first, so the guard runs inside the scope tracing\n // bound and a malformed pair is refused with 400 before the guard\n // looks; the plugin appends its own (the tools' scope) after these.\n // The ScratchPad extension's, last, remembers the references each\n // served prompt brings, which PI may hand on.\n requestInterceptors: [\n tracing.requestInterceptor,\n guard.requestInterceptor,\n ...(handOn !== undefined ? [handOn.requestInterceptor] : []),\n ],\n // The client PI's agent tools prompt through: the edge and the pair,\n // then the waiting mark. Both read the ambient scope, so the order\n // between them does not matter.\n promptInterceptors: [tracing.promptInterceptor, guard.promptInterceptor],\n heartbeatExtras: tracing.heartbeatExtras,\n ...(handOn !== undefined\n ? {\n // References in PI's `prompt_agent`: granted to a receiver that\n // reads them, removed with a note for any other.\n toolExtensions: [handOn],\n // So a caller's `prompt_agent` hands references to PI.\n metadata: { [READS_REFERENCES_KEY]: \"true\" },\n }\n : {}),\n // No `stopping`: an\n // edge record is published before the prompt it describes and counted\n // as it goes, so there is nothing to flush when the plugin stops.\n\n started({ agents, service }) {\n if (ctx.settings.senderIdentity !== \"signed\" && !warnedIdentityOff) {\n warnedIdentityOff = true;\n log.warn(IDENTITY_OFF_WARNING);\n }\n log.info(\n `${EXTENSION_NAME}: tracing ${service.subject.prompt}` +\n (edgeSubject === null\n ? \" (propagate-only: lineage forwarded, no edge record published)\"\n : `, edge records on ${edgeSubject}`),\n );\n if (scratchPad !== undefined && handOn !== undefined) {\n env[SP_VARS.creator] = service.subject.prompt;\n const port = spPort(scratchPad, service.subject.prompt, env);\n if (port !== undefined) handOn.start({ scratchPad: port, agents, service, logger: log });\n else\n log.warn(\n `${EXTENSION_NAME}: no sp for this platform (set SCRATCHPAD_BIN); ` +\n \"references in prompt_agent are not handed on, and grant requests not answered\",\n );\n log.info(\n `${EXTENSION_NAME}: ScratchPad volume ${scratchPad.volume}` +\n (scratchPad.dir !== undefined ? `, workspace ${scratchPad.dir}` : \", no workspace\") +\n \", for the skill's scripts/sp\",\n );\n }\n },\n\n events: {\n promptAccepted(request) {\n // In the handler's async context, inside the scope tracing bound.\n const scope = activeTrace();\n if (scope !== undefined) scopes.set(request.id, scope);\n },\n promptEnded(request) {\n scopes.delete(request.id);\n promptEnv.leave(request);\n },\n aroundInject(request, run) {\n const scope = scopes.get(request.id);\n // The hand-over to PI's loop: from here to its end this prompt is\n // the one PI works on, and the one `scripts/sp` works for.\n if (scratchPadOn) promptEnv.enter(request, scope);\n return scope === undefined ? run() : bindActiveTrace(scope, run);\n },\n providerHeaders(request) {\n // One call per provider request: `traceHeaders()` counts each\n // against the scope, so an edge PI's model spawns later says how\n // many calls came before it — retries included.\n const scope = scopes.get(request.id);\n return scope === undefined ? undefined : bindActiveTrace(scope, traceHeaders);\n },\n aroundToolCall(request, _toolName, run) {\n // The same binding as the injection's, for the case PI's tool\n // runner does not inherit it; a no-op rebind when it does.\n const scope = scopeOf(request);\n return scope === undefined\n ? run()\n : bindActiveTrace(scope, () => guard.aroundToolCall(scope, run));\n },\n },\n };\n}\n"]}
|
package/dist/index.d.cts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { AgentExtensionContext, ScratchPadSettings, AgentExtension } from '@synadia-ai/agent-fabric';
|
|
2
|
-
export { AgentExtension, AgentExtensionContext, AgentExtensionFactory, AgentExtensionHandles, AgentExtensionSettings, EDGE_SUBJECT_OPTION, EDGE_SUBJECT_VAR, PluginHarness as Harness, HarnessEvents, LOOP_GUARD_CODE, LoopGuard, Outcome, SCRATCHPAD_OPTION, SP_VARS, ScratchPadHandOn, ServedRequest, loopGuard, loopGuardDescription, resolveEdgeSubject } from '@synadia-ai/agent-fabric';
|
|
3
|
-
|
|
4
|
-
/** The sp binary this package ships for this machine, or `SCRATCHPAD_BIN`. */
|
|
5
|
-
declare function spBinary(env: Record<string, string | undefined>): string | undefined;
|
|
6
|
-
|
|
7
|
-
/** The extension's name, as the plugin's status output lists it. */
|
|
8
|
-
declare const EXTENSION_NAME = "agent-fabric";
|
|
9
|
-
/** The warning logged once at start when the plugin's identity is off. */
|
|
10
|
-
declare const IDENTITY_OFF_WARNING: string;
|
|
11
|
-
/**
|
|
12
|
-
* The factory: the module's default export. Called once by the plugin,
|
|
13
|
-
* before it connects, with what it knows then. Resolves ScratchPad's
|
|
14
|
-
* settings (which may read the plugin's NATS context) and builds the
|
|
15
|
-
* extension with them. Throws `NatsAgentError` for an edge subject that can
|
|
16
|
-
* never be published to.
|
|
17
|
-
*
|
|
18
|
-
* `env` is where the variables are read from, and where ScratchPad's are
|
|
19
|
-
* set for PI's bash tool; a test passes its own.
|
|
20
|
-
*/
|
|
21
|
-
declare function fabricExtension(ctx: AgentExtensionContext, env?: NodeJS.ProcessEnv): Promise<AgentExtension>;
|
|
22
|
-
/**
|
|
23
|
-
* The extension, built synchronously from settings already resolved:
|
|
24
|
-
* without `scratchPad`, tracing and the guard alone.
|
|
25
|
-
*/
|
|
26
|
-
declare function createFabricExtension(ctx: AgentExtensionContext, env?: NodeJS.ProcessEnv, scratchPad?: ScratchPadSettings): AgentExtension;
|
|
27
|
-
|
|
28
|
-
export { EXTENSION_NAME, IDENTITY_OFF_WARNING, createFabricExtension, fabricExtension as default, fabricExtension, spBinary };
|
package/dist/index.d.ts
DELETED
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import { AgentExtensionContext, ScratchPadSettings, AgentExtension } from '@synadia-ai/agent-fabric';
|
|
2
|
-
export { AgentExtension, AgentExtensionContext, AgentExtensionFactory, AgentExtensionHandles, AgentExtensionSettings, EDGE_SUBJECT_OPTION, EDGE_SUBJECT_VAR, PluginHarness as Harness, HarnessEvents, LOOP_GUARD_CODE, LoopGuard, Outcome, SCRATCHPAD_OPTION, SP_VARS, ScratchPadHandOn, ServedRequest, loopGuard, loopGuardDescription, resolveEdgeSubject } from '@synadia-ai/agent-fabric';
|
|
3
|
-
|
|
4
|
-
/** The sp binary this package ships for this machine, or `SCRATCHPAD_BIN`. */
|
|
5
|
-
declare function spBinary(env: Record<string, string | undefined>): string | undefined;
|
|
6
|
-
|
|
7
|
-
/** The extension's name, as the plugin's status output lists it. */
|
|
8
|
-
declare const EXTENSION_NAME = "agent-fabric";
|
|
9
|
-
/** The warning logged once at start when the plugin's identity is off. */
|
|
10
|
-
declare const IDENTITY_OFF_WARNING: string;
|
|
11
|
-
/**
|
|
12
|
-
* The factory: the module's default export. Called once by the plugin,
|
|
13
|
-
* before it connects, with what it knows then. Resolves ScratchPad's
|
|
14
|
-
* settings (which may read the plugin's NATS context) and builds the
|
|
15
|
-
* extension with them. Throws `NatsAgentError` for an edge subject that can
|
|
16
|
-
* never be published to.
|
|
17
|
-
*
|
|
18
|
-
* `env` is where the variables are read from, and where ScratchPad's are
|
|
19
|
-
* set for PI's bash tool; a test passes its own.
|
|
20
|
-
*/
|
|
21
|
-
declare function fabricExtension(ctx: AgentExtensionContext, env?: NodeJS.ProcessEnv): Promise<AgentExtension>;
|
|
22
|
-
/**
|
|
23
|
-
* The extension, built synchronously from settings already resolved:
|
|
24
|
-
* without `scratchPad`, tracing and the guard alone.
|
|
25
|
-
*/
|
|
26
|
-
declare function createFabricExtension(ctx: AgentExtensionContext, env?: NodeJS.ProcessEnv, scratchPad?: ScratchPadSettings): AgentExtension;
|
|
27
|
-
|
|
28
|
-
export { EXTENSION_NAME, IDENTITY_OFF_WARNING, createFabricExtension, fabricExtension as default, fabricExtension, spBinary };
|