@north-light/cli 0.3.566 → 0.3.567
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/contract.d.ts +1 -1
- package/dist/api/contract.js +1 -1
- package/dist/clients/attach/viewer.js +440 -440
- package/dist/core/config.js +1 -1
- package/dist/core/directory/issuer.d.ts +5 -0
- package/dist/core/directory/issuer.js +1 -0
- package/dist/core/graph/objects.d.ts +3 -0
- package/dist/core/graph/objects.js +8 -8
- package/dist/core/graph/reader.js +3 -3
- package/dist/core/ledger/charges.d.ts +2 -4
- package/dist/core/ledger/charges.js +1 -1
- package/dist/core/ledger/index.d.ts +1 -1
- package/dist/core/ledger/index.js +1 -1
- package/dist/core/ledger/infra-allowance.d.ts +0 -2
- package/dist/core/ledger/infra-allowance.js +1 -1
- package/dist/core/ledger/rates.d.ts +24 -0
- package/dist/core/ledger/rates.js +1 -0
- package/dist/core/ledger/read.d.ts +5 -2
- package/dist/core/ledger/read.js +2 -2
- package/dist/core/peer/client.js +1 -1
- package/dist/core/peer/directory.d.ts +0 -2
- package/dist/core/peer/directory.js +1 -1
- package/dist/core/peer/home.js +2 -2
- package/dist/core/providers/audit.d.ts +2 -0
- package/dist/core/providers/audit.js +2 -2
- package/dist/core/providers/bundles.js +2 -2
- package/dist/core/providers/call.js +1 -1
- package/dist/core/providers/mint.d.ts +1 -1
- package/dist/core/providers/mint.js +1 -1
- package/dist/core/runs/operations.d.ts +4 -0
- package/dist/core/runs/operations.js +7 -7
- package/dist/core/storage/client.js +2 -2
- package/dist/core/user-settings.d.ts +0 -4
- package/dist/core/user-settings.js +1 -1
- package/dist/daemon/api/app-listener.d.ts +8 -0
- package/dist/daemon/api/app-listener.js +13 -13
- package/dist/daemon/api/handlers/charges.js +1 -1
- package/dist/daemon/api/handlers/plugin-app-token.js +1 -1
- package/dist/daemon/api/handlers/providers.js +1 -1
- package/dist/daemon/api/handlers/runs.js +1 -1
- package/dist/daemon/api/handlers/transfer.js +1 -1
- package/dist/daemon/api/reader.js +1 -1
- package/dist/daemon/api/server.js +1 -1
- package/dist/daemon/cron/authority.js +1 -1
- package/dist/daemon/crtrd.js +10 -10
- package/dist/daemon/peer/relay-service.js +1 -1
- package/dist/daemon/readiness.d.ts +2 -1
- package/dist/daemon/readiness.js +1 -1
- package/dist/daemon/reconcilers/ledger-r2.js +5 -5
- package/dist/daemon/reconcilers/ledger-sandbox.d.ts +0 -1
- package/dist/daemon/reconcilers/ledger-sandbox.js +4 -4
- package/dist/daemon/reconcilers/ledger-storage.js +3 -3
- package/dist/types.d.ts +0 -16
- package/package.json +2 -2
- package/packages/crouter-identity/package.json +1 -1
- package/runtime.lock.json +13 -13
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var
|
|
1
|
+
var l=Object.defineProperty;var s=(i,n)=>l(i,"name",{value:n,configurable:!0});import{openDb as a}from"../canvas/db.js";import{runtimeId as h}from"../grants/sync.js";import{terminalGrant as m}from"../grants/mirror.js";async function b(i){const{caller:n}=i,e=n.sub??(n.class==="person"?(await m())?.sub??null:null),t=n.grantee??e,u=e&&t?[e,t,`runtime:${h()}`]:null;await(await a()).prepare(`INSERT INTO audit_rows
|
|
2
2
|
(request_id, time, grantee, sub, client_id, class, operation, scope_checked,
|
|
3
3
|
outcome, node_id, run_id, resource, initiator_chain, provider, tool, jti, receipt_id, responder, question_id)
|
|
4
|
-
VALUES (?, ?, ?, ?, ?, ?, 'provider.call', ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(i.request_id,new Date().toISOString(),t,e,n.client_id,n.class,i.scope_checked??null,i.outcome,n.node_id,n.run_id,`${i.provider} ${i.tool}`,
|
|
4
|
+
VALUES (?, ?, ?, ?, ?, ?, 'provider.call', ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`).run(i.request_id,new Date().toISOString(),t,e,n.client_id,n.class,i.scope_checked??null,i.outcome,n.node_id,n.run_id,`${i.provider} ${i.tool}`,u?JSON.stringify(u):null,i.provider,i.tool,i.jti??null,i.receipt_id??null,i.responder??null,i.question_id??null)}s(b,"writeProviderAudit");async function E(i,n){const e=[],t=[];i!==null&&(e.push("grantee = ?"),t.push(i)),n.sub!==void 0&&(e.push("sub = ?"),t.push(n.sub)),n.after!==void 0&&(e.push("id < ?"),t.push(n.after));for(const o of["operation","outcome","run_id"])n[o]!==void 0&&(e.push(`${o} = ?`),t.push(n[o]));n.since!==void 0&&(e.push("time >= ?"),t.push(n.since)),n.until!==void 0&&(e.push("time <= ?"),t.push(n.until));const u=await(await a()).prepareUncached(`SELECT * FROM audit_rows ${e.length?`WHERE ${e.join(" AND ")}`:""} ORDER BY id DESC LIMIT ?`).all(...t,n.limit+1),d=u.length>n.limit;d&&u.pop();const p=d?String(u.at(-1)?.id):null;return{rows:u.map(({id:o,initiator_chain:r,...c})=>({...c,initiator_chain:typeof r=="string"?JSON.parse(r):null})),next:p}}s(E,"listAudit");export{E as listAudit,b as writeProviderAudit};
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var ue=Object.defineProperty;var a=(e,n)=>ue(e,"name",{value:n,configurable:!0});import{existsSync as g,readdirSync as W,readFileSync as S,rmSync as $,statSync as k}from"node:fs";import{join as d}from"node:path";import{validateCommandManifest as de}from"../../api/command-manifest/manifest.js";import{crtrHome as z}from"../canvas/paths.js";import{withCanvasWrite as G}from"../canvas/db.js";import{bundleVersion as ce,isInstalledGeneration as fe,recordCheckedGeneration as le}from"../command-plugins/bundle.js";import{
|
|
2
|
-
`),$(d(e,"bundle.tar"),{force:!0}),$(d(e,"etag"),{force:!0})}a(Me,"retire");function ie(e,n){return new c("provider_version_retired",`provider "${e}" major ${n} is retired`,{param:"version"})}a(ie,"retiredError");async function O(e,n,r){const t=ee(e,n),o=d(t,"bundle.tar"),s=g(o),i=s&&r&&g(d(t,"etag"))?S(d(t,"etag"),"utf8"):void 0,f=await ne(e,{version:n,...i!==void 0?{ifNoneMatch:i}:{}});if(f.status===304)return"unchanged";if(f.status===410)throw Me(t),m({level:"info",event:"daemon.providers.major_retired",fields:{provider:e,major:n}}),ie(e,n);if(f.status===404)throw new c("not_found",`provider "${e}" never served major ${n}`,{param:"version"});if(f.status==="failed")throw new c("provider_unavailable",`provider "${e}" major ${n} bundle fetch failed: ${f.message}`,{cause:f.cause});try{await ae(e,n,f.raw)}catch(l){D(e,n,l);const w=new c(s?"provider_unavailable":"not_found",l instanceof Error?l.message:String(l),{param:"version"});throw I.add(w),w}T(t),$(d(t,"retired"),{force:!0});const u=s&&Buffer.from(f.raw).equals(S(o));return u||x(o,f.raw),f.etag!==void 0?x(d(t,"etag"),f.etag):$(d(t,"etag"),{force:!0}),u?"unchanged":s?"updated":"installed"}a(O,"refreshPinned");function ke(){const e=[],n=R();if(!g(n))return e;for(const r of W(n)){if(!Q.test(r))continue;let t;try{t=W(d(n,r))}catch{continue}for(const o of t){const s=/^v([1-9][0-9]*)$/.exec(o);s&&g(d(n,r,o,"bundle.tar"))&&e.push([r,Number(s[1])])}}return e}a(ke,"cachedMajors");function xe(e){const n=de(e,{transport:"http",reservedCoreNames:new Set});if(n.manifest===void 0)throw new c("not_found","the provider bundle's commands.json no longer validates");return n.manifest}a(xe,"readCommands");const _=new Map,H=new Map;function Te(e,n){const r=k(n),t=`${r.ino}:${r.mtimeMs}:${r.size}`,o=H.get(e);if(o?.stamp===t)return o.commands;const s=xe(JSON.parse(S(n,"utf8")));return H.set(e,{stamp:t,commands:s}),s}a(Te,"installedCommands");async function
|
|
1
|
+
var ue=Object.defineProperty;var a=(e,n)=>ue(e,"name",{value:n,configurable:!0});import{existsSync as g,readdirSync as W,readFileSync as S,rmSync as $,statSync as k}from"node:fs";import{join as d}from"node:path";import{validateCommandManifest as de}from"../../api/command-manifest/manifest.js";import{crtrHome as z}from"../canvas/paths.js";import{withCanvasWrite as G}from"../canvas/db.js";import{bundleVersion as ce,isInstalledGeneration as fe,recordCheckedGeneration as le}from"../command-plugins/bundle.js";import{readState as pe,updateConfig as me,updateState as ve}from"../config.js";import{directoryIssuer as q}from"../directory/issuer.js";import{emitEvent as m}from"../events/emit.js";import{describeOutboundFailure as he,outboundFetch as we,outboundRefusal as V,OutboundError as ge}from"../events/outbound.js";import{withExclusiveDirectoryLockAsync as Z}from"../exclusive-lock.js";import{atomicWriteText as x,ensureDir as T,pathExists as $e}from"../fs-utils.js";import{reconcilePackages as L}from"../graph/package-reconcile.js";import{readPluginManifest as C}from"../manifest.js";import{bundleSwapLockPath as J}from"../plugin-swap-lock.js";import{pluginsDir as ye,userScopeRoot as K}from"../scope.js";import{listInstalledPlugins as be}from"../resolver.js";import{localGrants as j}from"../grants/mirror.js";import{ProviderError as c}from"./errors.js";const A="[A-Za-z0-9_-]{1,64}",_e=new RegExp(`^(${A}):(${A})$`),Q=new RegExp(`^${A}$`),Pe=3e4,X=3e4;function Y(e){const n=new Set;for(const r of e)if(r.status==="active")for(const{scope:t}of r.resolved_scopes){const o=_e.exec(t);o&&o[1]!=="crtr"&&n.add(o[1])}return[...n].sort()}a(Y,"providerIdsFromGrants");function v(e){return d(ye("user"),e)}a(v,"pluginRoot");function R(){return d(z(),"providers")}a(R,"providersRoot");function ee(e,n){return d(R(),e,`v${n}`)}a(ee,"majorDir");function B(e){if(!Q.test(e))throw new c("not_found",`"${e}" is not a provider id`,{param:"provider"})}a(B,"assertId");function E(){const e=q();if(!e)throw new c("not_found","provider bundles need a directory-connected runtime");return e}a(E,"directoryBase");async function ne(e,n){const r=`${E()}/providers/${encodeURIComponent(e)}/plugin${n.version!==void 0?`?version=${n.version}`:""}`;let t;try{t=await we("bundle_fetch",r,{headers:{Accept:"application/x-tar",...n.ifNoneMatch!==void 0?{"If-None-Match":n.ifNoneMatch}:{}},signal:AbortSignal.timeout(Pe)})}catch(i){return{status:"failed",message:`could not reach ${r}: ${i instanceof Error?i.message:String(i)}`,cause:i}}if(t.status===304){if(n.ifNoneMatch===void 0){const i=`HTTP 304 from ${r} without a conditional request`;return{status:"failed",message:i,cause:V("bundle_fetch",r,i)}}return{status:304}}if(t.status===404||t.status===410)return await t.body?.cancel().catch(()=>{}),{status:t.status===404?404:410,message:`HTTP ${t.status} from ${r}`};if(t.status<200||t.status>=300){await t.body?.cancel().catch(()=>{});{const i=`HTTP ${t.status} from ${r}`;return{status:"failed",message:i,cause:V("bundle_fetch",r,i)}}}let o;try{o=new Uint8Array(await t.arrayBuffer())}catch(i){return{status:"failed",message:`reading ${r} failed: ${i instanceof Error?i.message:String(i)}`,cause:new ge("bundle_fetch",r,i)}}const s=t.headers.get("etag");return{status:200,raw:o,...s!==null?{etag:s}:{}}}a(ne,"fetchProviderBundle");const I=new WeakSet;class M extends Error{static{a(this,"BundleInvalid")}issues;constructor(n,r){super(n),this.issues=r}}function re(e,n,r){if(r.provider===void 0)return"the archive carries no provider block";if(r.provider.id!==e)return`the archive is provider "${r.provider.id}", not "${e}"`;if(n!==void 0&&r.provider.major!==n)return`the archive is major ${r.provider.major}, not ${n}`;const t=["hooks","kinds","page_components","memory_extensions"].filter(o=>r[o]!==void 0);if(t.length>0)return`a provider bundle may not carry ${t.join(", ")}`}a(re,"wrongBundle");function D(e,n,r){m({level:"error",event:"daemon.providers.bundle_invalid",fields:{provider:e,...n!==void 0?{major:n}:{},...r instanceof M?{issues:r.issues}:{}},error:r})}a(D,"logInvalid");function te(e,n,r){m({level:"warn",event:"daemon.providers.bundle_fetch_failed",fields:{provider:e,...n!==void 0?{major:n}:{},message:r instanceof Error?r.message:String(r),...he(r instanceof Error?r.cause:void 0)}})}a(te,"logFailure");async function oe(){return import("../../commands/pkg/plugin-manage.js")}a(oe,"pluginManage");const y=new Map,b=a(e=>`${z()}\0${e}`,"installKey");function Se(e){const n=e,r=n?.code??n?.cause?.code;return typeof r=="string"&&/^[A-Z][A-Z0-9_]{1,30}$/.test(r)?`${r} on provider install directory`:e instanceof c&&e.message.includes("HTTP 404")?"directory returned HTTP 404":e instanceof c&&e.message.includes("HTTP 410")?"directory returned HTTP 410":"provider bundle could not be installed"}a(Se,"publicInstallCause");function Ee(e){if(h(e)===void 0)return y.get(b(e))??{status:"installing"}}a(Ee,"providerInstallState");function Ie(e){return new c("provider_unavailable",`provider "${e}" unavailable: ${Ee(e)?.error??"bundle installation pending"}`)}a(Ie,"unavailableProviderError");function h(e){const n=C(v(e));if(!(n?.provider===void 0||n.transport?.kind!=="http"&&n.transport?.kind!=="machine")&&$e(d(v(e),"commands.json"))){try{if(k(d(v(e),"commands.json")).size===0)return}catch{return}return{provider:n.provider,transport:n.transport.kind==="machine"?{kind:"machine"}:{kind:"http",endpoint:n.transport.endpoint}}}}a(h,"installedManifest");async function N(e,n,r=!1){const t=K();h(e)===void 0&&y.set(b(e),{status:"installing"});try{return T(d(t,"tmp")),await Z(J(t,e),async()=>{const o=v(e),s=C(o);if(s!==null&&s.provider===void 0)throw new c("provider_unavailable",`plugin "${e}" is installed and is not the directory's provider bundle`);const i=h(e)!==void 0;if(i&&r)return"unchanged";const f=i&&n?pe("user").plugins[e]?.etag:void 0,u=await ne(e,f!==void 0?{ifNoneMatch:f}:{});if(u.status===304)return"unchanged";if(u.status===404||u.status===410)throw new c("not_found",`the directory serves no provider "${e}" (${u.message})`,{param:"provider"});if(u.status==="failed")throw new c("provider_unavailable",`provider "${e}" bundle fetch failed: ${u.message}`,{cause:u.cause});const l=ce(u.raw);if(i&&fe(e,"user",o,l))return await le("user",e,u.etag,{swapped:!1}),"unchanged";const{installPluginArchive:w}=await oe();try{await w(e,u.raw,{scope:"user",scopeRootPath:t,root:o,version:l,etag:u.etag,enable:!i,bundle:{endpoint:`${E()}/providers/${encodeURIComponent(e)}/plugin`},transport:{kind:"http",endpoint:E()},accept:a(p=>re(e,void 0,p),"accept")})}catch(p){D(e,void 0,p);const U=new c("not_found",`provider "${e}" served an invalid bundle: ${p instanceof Error?p.message:String(p)}`,{param:"provider"});throw I.add(U),U}try{await G(async p=>await L(p))}catch(p){m({level:"error",event:"daemon.providers.docs_reconcile_failed",fields:{provider:e},error:p})}return m({level:"info",event:"daemon.providers.bundle_installed",fields:{provider:e,version:l,replaced:i}}),y.delete(b(e)),i?"updated":"installed"},{timeoutMs:X,timeoutError:a(()=>new c("provider_unavailable",`timed out waiting for another process replacing plugin "${e}"`),"timeoutError")})}catch(o){throw h(e)===void 0&&y.set(b(e),{status:"install_failed",error:Se(o)}),o instanceof c?o:(m({level:"error",event:"daemon.providers.bundle_install_failed",fields:{provider:e},error:o}),Ie(e))}}a(N,"refreshInstalled");async function nn(e){B(e),h(e)===void 0&&await N(e,!1,!0)}a(nn,"ensureProviderBundle");async function rn(e,n){return B(e),n.version!==void 0&&h(e)?.provider.major!==n.version?O(e,n.version,n.conditional):N(e,n.conditional)}a(rn,"refreshProviderBundle");async function ae(e,n,r){const{validatePluginArchive:t}=await oe(),o=await t(r);if(o.bundle===void 0)throw new M(`provider "${e}" major ${n} bundle is invalid: ${o.issues.map(i=>i.message).join("; ")}`,o.issues);const s=re(e,n,o.bundle);if(s!==void 0)throw new M(`provider "${e}" major ${n} bundle is invalid: ${s}`,[]);if(o.bundle.transport===void 0)throw new M(`provider "${e}" major ${n} bundle declares no transport`,[]);return o.bundle}a(ae,"validateArchive");function Me(e){T(e),x(d(e,"retired"),`${new Date().toISOString()}
|
|
2
|
+
`),$(d(e,"bundle.tar"),{force:!0}),$(d(e,"etag"),{force:!0})}a(Me,"retire");function ie(e,n){return new c("provider_version_retired",`provider "${e}" major ${n} is retired`,{param:"version"})}a(ie,"retiredError");async function O(e,n,r){const t=ee(e,n),o=d(t,"bundle.tar"),s=g(o),i=s&&r&&g(d(t,"etag"))?S(d(t,"etag"),"utf8"):void 0,f=await ne(e,{version:n,...i!==void 0?{ifNoneMatch:i}:{}});if(f.status===304)return"unchanged";if(f.status===410)throw Me(t),m({level:"info",event:"daemon.providers.major_retired",fields:{provider:e,major:n}}),ie(e,n);if(f.status===404)throw new c("not_found",`provider "${e}" never served major ${n}`,{param:"version"});if(f.status==="failed")throw new c("provider_unavailable",`provider "${e}" major ${n} bundle fetch failed: ${f.message}`,{cause:f.cause});try{await ae(e,n,f.raw)}catch(l){D(e,n,l);const w=new c(s?"provider_unavailable":"not_found",l instanceof Error?l.message:String(l),{param:"version"});throw I.add(w),w}T(t),$(d(t,"retired"),{force:!0});const u=s&&Buffer.from(f.raw).equals(S(o));return u||x(o,f.raw),f.etag!==void 0?x(d(t,"etag"),f.etag):$(d(t,"etag"),{force:!0}),u?"unchanged":s?"updated":"installed"}a(O,"refreshPinned");function ke(){const e=[],n=R();if(!g(n))return e;for(const r of W(n)){if(!Q.test(r))continue;let t;try{t=W(d(n,r))}catch{continue}for(const o of t){const s=/^v([1-9][0-9]*)$/.exec(o);s&&g(d(n,r,o,"bundle.tar"))&&e.push([r,Number(s[1])])}}return e}a(ke,"cachedMajors");function xe(e){const n=de(e,{transport:"http",reservedCoreNames:new Set});if(n.manifest===void 0)throw new c("not_found","the provider bundle's commands.json no longer validates");return n.manifest}a(xe,"readCommands");const _=new Map,H=new Map;function Te(e,n){const r=k(n),t=`${r.ino}:${r.mtimeMs}:${r.size}`,o=H.get(e);if(o?.stamp===t)return o.commands;const s=xe(JSON.parse(S(n,"utf8")));return H.set(e,{stamp:t,commands:s}),s}a(Te,"installedCommands");async function tn(e,n){B(e);const r=h(e);if(n===void 0||r?.provider.major===n){if(r===void 0)throw new c("not_found",`provider "${e}" has no installed bundle`,{param:"provider"});const l=v(e),w=Te(e,d(l,"commands.json"));return{id:e,major:r.provider.major,provider:r.provider,commands:w,transport:r.transport,source:"installed",root:l}}if(!Number.isInteger(n)||n<1)throw new c("invalid_request","version must be an integer of at least 1",{param:"version"});const t=ee(e,n);if(g(d(t,"retired")))throw ie(e,n);const o=d(t,"bundle.tar");g(o)||await O(e,n,!1);const s=`${e}/${n}`,i=k(o),f=`${i.mtimeMs}:${i.size}`;let u=_.get(s)?.stamp===f?_.get(s).bundle:void 0;if(u===void 0){try{u=await ae(e,n,new Uint8Array(S(o)))}catch(l){throw D(e,n,l),new c("not_found",`provider "${e}" has no valid bundle for major ${n}`,{param:"version"})}_.set(s,{stamp:f,bundle:u})}return{id:e,major:n,provider:u.provider,commands:u.commands,transport:u.transport.kind==="machine"?{kind:"machine"}:{kind:"http",endpoint:u.transport.endpoint},source:"pinned"}}a(tn,"resolveProviderBundle");let P=null,F=!1;function Ce(e,n){return e?.provider?.id===n&&e.bundle?.endpoint===`${E()}/providers/${encodeURIComponent(n)}/plugin`}a(Ce,"isDirectoryBundle");async function se(e){return Y(await j()).includes(e)}a(se,"grantNames");async function je(e){await Z(J(K(),e),async()=>{if(!(await se(e)||!Ce(C(v(e)),e))){$(v(e),{recursive:!0,force:!0}),await me("user",n=>{delete n.plugins[e]}),await ve("user",n=>{delete n.plugins[e]}),$(d(R(),e),{recursive:!0,force:!0}),H.delete(e),y.delete(b(e));for(const n of[..._.keys()])n.startsWith(`${e}/`)&&_.delete(n);try{await G(async n=>await L(n))}catch(n){m({level:"error",event:"daemon.providers.docs_reconcile_failed",fields:{provider:e},error:n})}m({level:"info",event:"daemon.providers.bundle_uninstalled",fields:{provider:e}})}},{timeoutMs:X,timeoutError:a(()=>new c("provider_unavailable",`timed out waiting for another process replacing plugin "${e}"`),"timeoutError")})}a(je,"uninstallProvider");async function Ae(){if(!(await j()).every(e=>e.status!=="active")){for(const e of be("user"))if(!(e.manifest.provider===void 0||await se(e.name)))try{await je(e.name)}catch(n){m({level:"error",event:"daemon.providers.bundle_uninstall_failed",fields:{provider:e.name},error:n})}}}a(Ae,"uninstallDisconnected");async function Re(){if(!q())return;const e=Y(await j());for(const n of e)try{await N(n,!0)}catch(r){r instanceof Object&&I.has(r)||te(n,void 0,r)}await Ae();for(const[n,r]of ke())try{await O(n,r,!0)}catch(t){if(t instanceof c&&t.code==="provider_version_retired"||t instanceof Object&&I.has(t))continue;te(n,r,t)}}a(Re,"syncOnce");function on(){return P!==null?(F=!0,P):(P=(async()=>{try{do F=!1,await Re();while(F)}finally{P=null}})(),P)}a(on,"syncProviderBundles");export{nn as ensureProviderBundle,Y as providerIdsFromGrants,Ee as providerInstallState,rn as refreshProviderBundle,tn as resolveProviderBundle,on as syncProviderBundles,Ie as unavailableProviderError};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var ie=Object.defineProperty;var g=(e,r)=>ie(e,"name",{value:r,configurable:!0});import{validateDeclaredResult as J}from"../../api/command-manifest/result.js";import{callerAllows as ae,requireGroup as se}from"../../daemon/api/handlers/providers.js";import{terminalGrant as de}from"../grants/mirror.js";import{findRefusal as ue,payerOf as le,refusalError as pe,refusedMark as ce,writeCharge as fe}from"../ledger/index.js";import{listInstalledPlugins as me}from"../resolver.js";import{ProviderError as l}from"./errors.js";import{resolveProviderRef as ge}from"./roots.js";import{providerToolPath as ve}from"../plugin-objects-manifest.js";import{ensureProviderBundle as he,refreshProviderBundle as we,resolveProviderBundle as H,unavailableProviderError as ye}from"./bundles.js";import{prepareFileCall as be,resignForRetry as K,resolveFileResult as W}from"./files.js";import{consumeApproval as _e,requireProviderApproval as Ae}from"./approval.js";import{outboundToken as je}from"./mint.js";import{discardFile as ke}from"./token-cache.js";import{registerProviderCall as Pe}from"./inflight.js";import{buildRequestPlan as $e}from"../command-plugins/transport/http-plan.js";import{newTraceId as qe}from"../../shared/traceparent.js";import{sendProviderRequest as Ce,ProviderTransportError as Ee}from"./request.js";import{acceptProviderReceipt as Re}from"./receipts.js";import{writeProviderAudit as Ie}from"./audit.js";import{selectDevice as Te,sendDeviceCall as Me,deviceFailure as Se,deviceUnreachable as X,DEFAULT_DEVICE_REQUEST_MS as Be}from"./device.js";import{isLibsSearch as Y,wantsBundling as Ne,callLibsSearch as Oe,bundleExec as Fe,mapLibOutcome as De,reportLibCalls as Ue}from"./device-libs.js";import{directoryIssuer as Le,ownMachineId as Je}from"../peer/directory.js";import{formatCrtrCaller as Z}from"../command-plugins/caller-header.js";import{getNode as He}from"../canvas/canvas.js";import{envelopeForProviderCaller as Ge}from"../peer/envelope.js";const xe="app:terminal";function ee(e){const r=[],i=g((c,t,n)=>{const a=[...t,c.name],s=n||c.tier==="hidden";if(c.kind==="branch"){for(const v of c.children)i(v,a,s);return}const j=ve(e.roots.length,a);r.push({tool:j,leaf:c,hidden:s})},"walk");for(const c of e.roots)i(c,[],!1);return r}g(ee,"providerLeaves");function re(e){if(e.kind!=="branch")return null;const r=[];for(const h of e.children)if(h.kind==="branch"){const _=re(h);_&&r.push(_)}else if("group"in h&&h.group){const{kind:_,name:d,description:A,whenToUse:w,tier:y,summary:k,params:P,output:o,effects:p,group:m}=h;r.push({kind:_,name:d,description:A,whenToUse:w,...y===void 0?{}:{tier:y},summary:k,params:P,output:o,effects:p,group:m})}if(r.length===0)return null;const{kind:i,name:c,description:t,whenToUse:n,tier:a,summary:s,model:j,rootEntry:v}=e;return{kind:i,name:c,description:t,whenToUse:n,...a===void 0?{}:{tier:a},summary:s,...j===void 0?{}:{model:j},...v===void 0?{}:{rootEntry:v},children:r}}g(re,"providerHelpBranch");async function Pr(e,r){const i=await H(r),c=ee(i.commands),t=me("user").find(n=>n.name===r)?.manifest.description??r;return{provider:r,status:"available",major:i.major,display_name:t,transport:i.transport.kind,groups:i.provider.groups.filter(n=>ae(e,`${r}:${n.group}`)).map(n=>({group:n.group,leaves:c.filter(({leaf:a,hidden:s})=>!s&&a.group===n.group).map(({tool:a,leaf:s})=>({tool:a,description:s.description,summary:s.summary,params:s.params,output:s.output}))})),commands:i.commands.roots.flatMap(n=>{const a=re(n);return a?[a]:[]})}}g(Pr,"providerTools");async function ze(e){return await Re(e.headers["crtr-receipt"],e)}g(ze,"onProviderResponse");async function Qe(e){if(e.class==="person"){const r=(await de())?.sub;if(!r)throw new l("grant_revoked","This machine has no active Northlight grant for your terminal. Run `crtr sys join` again from /account/machines.");return{sub:r,grantee:r}}if(!e.sub||!e.grantee)throw new l("grant_revoked","the caller has no active grant");return{sub:e.sub,grantee:e.grantee}}g(Qe,"identity");function Ve(e,r){return[`${e.id}:${r.group}`]}g(Ve,"callScope");function Ke(e,r){const i=ee(e.commands).find(c=>c.tool===r);if(!i)throw new l("not_found",`tool "${r}" is not in provider "${e.id}"`,{param:"tool"});if(!i.leaf.group)throw new l("not_found",`tool "${r}" has no group`,{param:"tool"});return i.leaf}g(Ke,"leafFor");function G(e){if(!e||typeof e!="object"||Array.isArray(e))return{};const r=e.error;return!r||typeof r!="object"||Array.isArray(r)?{}:r}g(G,"errorBody");function We(e){const r=Array.isArray(e)?e[0]:e;if(!r)return;const i=Number(r);if(Number.isFinite(i)&&i>=0)return i;const c=Date.parse(r);return Number.isFinite(c)?Math.max(0,Math.ceil((c-Date.now())/1e3)):void 0}g(We,"retryAfter");function N(e,r,i,c=!1){const t=G(r),n=typeof t.code=="string"?t.code:void 0,a=typeof t.message=="string"?t.message:`provider answered HTTP ${e}`,s=typeof t.field=="string"?t.field:void 0,v={origin:"provider",details:{code:n??null,message:a,...s?{field:s}:{},...typeof t.next=="string"?{next:t.next}:{},...t.received!==void 0?{received:t.received}:{},status:e},...s?{param:s}:{}};return e===429?new l("provider_rate_limited",a,{...v,retry_after_s:We(i["retry-after"])}):e===401||e>=500?new l("provider_unavailable",a,v):e===403&&n==="provider_refused"?new l("provider_refused",a,v):e===403&&n==="approval_required"?new l("provider_error",c?"provider asked for approval again":"provider approval question is invalid",{...v,status:e}):new l("provider_error",a,{...v,status:e})}g(N,"mapProviderResponse");function te(e,r){return JSON.stringify({major:e.major,endpoint:e.transport.kind==="http"?e.transport.endpoint:null,baseUrl:e.commands.baseUrl??null,rest:r.rest,params:r.params,output:r.output})}g(te,"approvalShape");async function Xe(e){const r=e.origin!==void 0?Z({node:e.origin.node??void 0,run:e.origin.run??void 0,machine:e.origin.machine}):Z({node:e.node_id??void 0,run:e.run_id??void 0,profile:e.node_id?(await He(e.node_id))?.profile_id??void 0:void 0,machine:Le()!==null?Je():void 0});return r===""?{}:{"Crtr-Caller":r}}g(Xe,"crtrCallerHeader");async function $r(e,r,i){const c=ge(r.provider);if(c===null)throw new l("not_found",`provider "${r.provider}" is not available`,{param:"provider"});const t={...r,provider:c},n=new AbortController,a=g(()=>n.abort(i.signal.reason),"abort");i.signal.aborted?a():i.signal.addEventListener("abort",a,{once:!0});let s=i.requestId;const j=i.traceId??qe(),v=Pe({request_id:s,run_id:e.run_id,node_id:e.node_id,controller:n});let h,_,d,A,w,y,k,P="allowed";try{try{await he(t.provider)}catch{throw ye(t.provider)}let o=await H(t.provider,t.version),p=!1,m,O,$,x=!1,z=!1,F,Q=0;for(;;){const b=Ke(o,t.tool);if(d=`${o.id}:${b.group}`,se(e,o.id,b.group),o.transport.kind!=="machine"&&t.machine!==void 0)throw new l("invalid_argument",`provider "${o.id}" is not served by a device, so it takes no machine`,{param:"machine"});o.transport.kind==="machine"&&F===void 0&&(F=await Te(t.machine,void 0,{newest:Y(o.major,t.tool)}),Q=Date.now()+(o.commands.timeouts?.requestMs??Be));let D=null;if(t.approval&&!x){const u=await _e(e,t,te(o,b));$=u.option,D=u.prepared,k=t.approval,s=u.requestId,x=!0}const I={params:b.params.filter(u=>"type"in u&&u.type==="file").map(u=>u.name),output:b.output.find(u=>u.type==="file")?.name??null},V=JSON.stringify(I);if(O!==void 0&&O!==V)throw new l("provider_bad_response","the refreshed manifest changed the tool file contract",{origin:"provider",details:{status:409,message:"manifest_stale changed the tool file contract"}});O=V,D&&(m=await K(e,I,t.arguments,D,{signal:n.signal})),m??=await be(e,I,t.arguments,{signal:n.signal});const{sub:q,grantee:T}=await Qe(e);if(o.transport.kind==="machine"){const u=await Ye(e,o,t,b,m,{sub:q,requestId:s,deadlineAt:Q,signal:n.signal,machine:F});return y=u.responder,h=u.cleanup,{status:200,body:u.result}}const C=await je({audience:o.transport.endpoint,sub:q,grantee:T,initiating_app:T,scope:Ve(o,b)},{signal:n.signal});A=C.jti;const U=e.class==="person"?xe:T,E=le({call:"tool",tokenPayer:C.payer,sub:q}),L=await ue({scope:"call",payer:E.payer,funding:E.funding,sub:q,grantee:U,provider:`app:${o.id}`});if(L!==null)throw await fe({request:s,kind:"tool",what:`${o.id}:${t.tool}`,usd:0,payer:E.payer,funding:E.funding,sub:q,grantee:U,node:e.node_id,run:e.run_id,provider:`app:${o.id}`,causedBy:i.causedBy??null,refused:ce(L)}),pe(L);const oe={registration:{name:o.id,endpoint:o.transport.endpoint},...o.commands.baseUrl?{baseUrl:o.commands.baseUrl}:{},...o.commands.timeouts?{timeouts:o.commands.timeouts}:{},params:b.params,rest:b.rest,output:b.output,commandPath:[o.id,...t.tool.split(" ")]},ne=$e(oe,m.arguments,void 0,{authorization:`Bearer ${C.access_token}`,requestId:s,traceId:j,fileMode:"pass-through",extraHeaders:{...i.causedBy?{"Crtr-Caused-By":i.causedBy}:{},...e.run_id?{"Crtr-Run-Id":e.run_id}:{},...await Xe(e),...$?{"Crtr-Approval":$}:{},...m.headers}});_??=Date.now()+(o.commands.timeouts?.requestMs??3e4);let f;try{if(f=await Ce(ne,{connectMs:o.commands.timeouts?.connectMs,requestMs:o.commands.timeouts?.requestMs,deadlineAt:_,signal:n.signal}),n.signal.aborted)throw n.signal.reason??new Error("provider call aborted")}catch(u){throw n.signal.aborted?n.signal.reason??u:u instanceof Ee?new l("provider_unavailable",u.message,{origin:"provider",details:{status:null,code:u.kind}}):u}if(w??=await ze({provider:o.id,tool:t.tool,request_id:s,run_id:e.run_id,sub:q,grantee:T,payer:C.payer,ledger_grantee:U,funding:E.funding,node_id:e.node_id,caused_by:i.causedBy??null,jti:C.jti,status:f.status,headers:f.headers}),y=f.headers["crtr-responder"],f.status===401&&ke(C.key),f.status>=200&&f.status<300){const u=f.body;if(!u||typeof u!="object"||Array.isArray(u))throw new l("provider_bad_response","provider result is not a JSON object",{origin:"provider",details:{status:f.status,message:"provider result is not a JSON object"}});let S;try{S=await W(e,m,u,{signal:n.signal})}catch(R){throw R instanceof l&&R.code==="provider_error"?new l("provider_bad_response",R.message,{origin:"provider",details:{status:f.status,message:R.message}}):R}h=S.cleanup;const B=J(b.output,S.result);if(B)throw new l("provider_bad_response",`provider result has an invalid output field "${B.field}"`,{origin:"provider",param:B.field,details:{status:f.status,...B}});if(n.signal.aborted)throw n.signal.reason??new Error("provider call aborted");return{status:200,body:S.result}}const M=G(f.body);if(f.status===403&&M.code==="approval_required"&&!$&&!z){z=!0;const u=await Ae(e,t,s,M.question,n.signal,te(o,b),m);if(k=u.questionId,$=u.option,m=await K(e,I,t.arguments,m,{signal:n.signal}),_=void 0,n.signal.aborted)throw new l("user_denied","the approval wait was canceled");continue}if(f.status===403&&M.code==="approval_required"&&$)throw N(f.status,f.body,f.headers,!0);if(f.status!==401&&M.manifest_stale===!0&&!p){p=!0,await we(o.id,{conditional:!1,...t.version===void 0?{}:{version:t.version}}),o=await H(o.id,t.version);continue}throw N(f.status,f.body,f.headers,!!$)}}catch(o){throw o instanceof l&&o.question_id&&(k=o.question_id),y===void 0&&o instanceof l&&typeof o.responder=="string"&&(y=o.responder),P=`refused:${o instanceof l?o.code:"server_error"}`,await h?.(),o}finally{try{await Ie({request_id:s,caller:e,provider:t.provider,tool:t.tool,scope_checked:d,outcome:P,jti:A,receipt_id:w,responder:y,question_id:k})}finally{v()}i.signal.removeEventListener("abort",a)}}g($r,"callProvider");async function Ye(e,r,i,c,t,n){const{machine:a}=n,s=await Ge(e,n.sub),j={machine:a,envelope:s,signal:n.signal,deadlineAt:n.deadlineAt,mapFailure:N};if(Y(r.major,i.tool)){const p=await Oe(j,t.arguments,r.major),m=J(c.output,p);if(m)throw new l("provider_bad_response",`the libraries result has an invalid output field "${m.field}"`,{origin:"provider",param:m.field,details:{status:200,...m}});return{result:p,responder:void 0,cleanup:void 0}}let v=t.arguments,h=null,_="";if(Ne(r.major,i.tool,t.arguments)){const p=await Fe(j,t.arguments,r.major);if(n.deadlineAt-Date.now()<=0)throw X(a,"timeout","");p!==null&&(v=p.arguments,h=p.services,_=p.release)}const d=await Me(a,{tool:i.tool,arguments:v,version:r.major,requestId:n.requestId,runId:e.run_id,deadlineAt:n.deadlineAt,upload:t.upload===null?null:{id:t.upload.upload_id,link:t.upload.upload_link}},s,n.signal);if(n.signal.aborted)throw n.signal.reason??new Error("provider call aborted");if("unreachable"in d)throw X(a,d.unreachable.reason,d.unreachable.message);const A=d.headers["crtr-responder"],w=G(d.body);if(d.status<200||d.status>=300){const p=Se(a,d.status,typeof w.code=="string"?w.code:void 0,typeof w.message=="string"?w.message:void 0,d.body),m=p===null&&d.status>=500&&typeof w.code=="string"?new l("provider_error",typeof w.message=="string"?w.message:`the device answered HTTP ${d.status}`,{origin:"runtime",status:d.status,details:{code:w.code,status:d.status}}):null;throw Object.assign(p??m??N(d.status,d.body,d.headers),{responder:A})}const y=d.body&&typeof d.body=="object"&&!Array.isArray(d.body)?d.body.result:void 0;if(!y||typeof y!="object"||Array.isArray(y))throw Object.assign(new l("provider_bad_response","the device result is not a JSON object",{origin:"provider",details:{status:d.status,message:"the device result is not a JSON object"}}),{responder:A});let k=y;if(h!==null){const p=De(k,h);if(Ue(a,s,_,p.calls),"error"in p)throw Object.assign(p.error,{responder:A});k=p.result}let P;try{P=await W(e,t,k,{signal:n.signal})}catch(p){throw p instanceof l&&p.code==="provider_error"?Object.assign(new l("provider_bad_response",p.message,{origin:"provider",details:{status:d.status,message:p.message}}),{responder:A}):p}const o=J(c.output,P.result);if(o)throw await P.cleanup?.(),Object.assign(new l("provider_bad_response",`the device result has an invalid output field "${o.field}"`,{origin:"provider",param:o.field,details:{status:d.status,...o}}),{responder:A});return{result:P.result,responder:A,cleanup:P.cleanup}}g(Ye,"callDevice");export{$r as callProvider,Xe as crtrCallerHeader,N as mapProviderResponse,ze as onProviderResponse,ee as providerLeaves,Pr as providerTools};
|
|
1
|
+
var ie=Object.defineProperty;var g=(e,r)=>ie(e,"name",{value:r,configurable:!0});import{validateDeclaredResult as J}from"../../api/command-manifest/result.js";import{callerAllows as ae,requireGroup as se}from"../../daemon/api/handlers/providers.js";import{terminalGrant as de}from"../grants/mirror.js";import{findRefusal as ue,payerOf as le,refusalError as pe,refusedMark as ce,writeCharge as fe}from"../ledger/index.js";import{listInstalledPlugins as me}from"../resolver.js";import{ProviderError as l}from"./errors.js";import{resolveProviderRef as ge}from"./roots.js";import{providerToolPath as ve}from"../plugin-objects-manifest.js";import{ensureProviderBundle as he,refreshProviderBundle as we,resolveProviderBundle as H,unavailableProviderError as ye}from"./bundles.js";import{prepareFileCall as be,resignForRetry as K,resolveFileResult as W}from"./files.js";import{consumeApproval as _e,requireProviderApproval as Ae}from"./approval.js";import{outboundToken as je}from"./mint.js";import{discardFile as ke}from"./token-cache.js";import{registerProviderCall as Pe}from"./inflight.js";import{buildRequestPlan as $e}from"../command-plugins/transport/http-plan.js";import{newTraceId as qe}from"../../shared/traceparent.js";import{sendProviderRequest as Ce,ProviderTransportError as Ee}from"./request.js";import{acceptProviderReceipt as Re}from"./receipts.js";import{writeProviderAudit as Ie}from"./audit.js";import{selectDevice as Te,sendDeviceCall as Me,deviceFailure as Se,deviceUnreachable as X,DEFAULT_DEVICE_REQUEST_MS as Be}from"./device.js";import{isLibsSearch as Y,wantsBundling as Ne,callLibsSearch as Oe,bundleExec as Fe,mapLibOutcome as De,reportLibCalls as Ue}from"./device-libs.js";import{ownMachineId as Le}from"../peer/directory.js";import{directoryIssuer as Je}from"../directory/issuer.js";import{formatCrtrCaller as Z}from"../command-plugins/caller-header.js";import{getNode as He}from"../canvas/canvas.js";import{envelopeForProviderCaller as Ge}from"../peer/envelope.js";const xe="app:terminal";function ee(e){const r=[],i=g((c,t,n)=>{const a=[...t,c.name],s=n||c.tier==="hidden";if(c.kind==="branch"){for(const v of c.children)i(v,a,s);return}const j=ve(e.roots.length,a);r.push({tool:j,leaf:c,hidden:s})},"walk");for(const c of e.roots)i(c,[],!1);return r}g(ee,"providerLeaves");function re(e){if(e.kind!=="branch")return null;const r=[];for(const h of e.children)if(h.kind==="branch"){const _=re(h);_&&r.push(_)}else if("group"in h&&h.group){const{kind:_,name:d,description:A,whenToUse:w,tier:y,summary:k,params:P,output:o,effects:p,group:m}=h;r.push({kind:_,name:d,description:A,whenToUse:w,...y===void 0?{}:{tier:y},summary:k,params:P,output:o,effects:p,group:m})}if(r.length===0)return null;const{kind:i,name:c,description:t,whenToUse:n,tier:a,summary:s,model:j,rootEntry:v}=e;return{kind:i,name:c,description:t,whenToUse:n,...a===void 0?{}:{tier:a},summary:s,...j===void 0?{}:{model:j},...v===void 0?{}:{rootEntry:v},children:r}}g(re,"providerHelpBranch");async function $r(e,r){const i=await H(r),c=ee(i.commands),t=me("user").find(n=>n.name===r)?.manifest.description??r;return{provider:r,status:"available",major:i.major,display_name:t,transport:i.transport.kind,groups:i.provider.groups.filter(n=>ae(e,`${r}:${n.group}`)).map(n=>({group:n.group,leaves:c.filter(({leaf:a,hidden:s})=>!s&&a.group===n.group).map(({tool:a,leaf:s})=>({tool:a,description:s.description,summary:s.summary,params:s.params,output:s.output}))})),commands:i.commands.roots.flatMap(n=>{const a=re(n);return a?[a]:[]})}}g($r,"providerTools");async function ze(e){return await Re(e.headers["crtr-receipt"],e)}g(ze,"onProviderResponse");async function Qe(e){if(e.class==="person"){const r=(await de())?.sub;if(!r)throw new l("grant_revoked","This machine has no active Northlight grant for your terminal. Run `crtr sys join` again from /account/machines.");return{sub:r,grantee:r}}if(!e.sub||!e.grantee)throw new l("grant_revoked","the caller has no active grant");return{sub:e.sub,grantee:e.grantee}}g(Qe,"identity");function Ve(e,r){return[`${e.id}:${r.group}`]}g(Ve,"callScope");function Ke(e,r){const i=ee(e.commands).find(c=>c.tool===r);if(!i)throw new l("not_found",`tool "${r}" is not in provider "${e.id}"`,{param:"tool"});if(!i.leaf.group)throw new l("not_found",`tool "${r}" has no group`,{param:"tool"});return i.leaf}g(Ke,"leafFor");function G(e){if(!e||typeof e!="object"||Array.isArray(e))return{};const r=e.error;return!r||typeof r!="object"||Array.isArray(r)?{}:r}g(G,"errorBody");function We(e){const r=Array.isArray(e)?e[0]:e;if(!r)return;const i=Number(r);if(Number.isFinite(i)&&i>=0)return i;const c=Date.parse(r);return Number.isFinite(c)?Math.max(0,Math.ceil((c-Date.now())/1e3)):void 0}g(We,"retryAfter");function N(e,r,i,c=!1){const t=G(r),n=typeof t.code=="string"?t.code:void 0,a=typeof t.message=="string"?t.message:`provider answered HTTP ${e}`,s=typeof t.field=="string"?t.field:void 0,v={origin:"provider",details:{code:n??null,message:a,...s?{field:s}:{},...typeof t.next=="string"?{next:t.next}:{},...t.received!==void 0?{received:t.received}:{},status:e},...s?{param:s}:{}};return e===429?new l("provider_rate_limited",a,{...v,retry_after_s:We(i["retry-after"])}):e===401||e>=500?new l("provider_unavailable",a,v):e===403&&n==="provider_refused"?new l("provider_refused",a,v):e===403&&n==="approval_required"?new l("provider_error",c?"provider asked for approval again":"provider approval question is invalid",{...v,status:e}):new l("provider_error",a,{...v,status:e})}g(N,"mapProviderResponse");function te(e,r){return JSON.stringify({major:e.major,endpoint:e.transport.kind==="http"?e.transport.endpoint:null,baseUrl:e.commands.baseUrl??null,rest:r.rest,params:r.params,output:r.output})}g(te,"approvalShape");async function Xe(e){const r=e.origin!==void 0?Z({node:e.origin.node??void 0,run:e.origin.run??void 0,machine:e.origin.machine}):Z({node:e.node_id??void 0,run:e.run_id??void 0,profile:e.node_id?(await He(e.node_id))?.profile_id??void 0:void 0,machine:Je()!==null?Le():void 0});return r===""?{}:{"Crtr-Caller":r}}g(Xe,"crtrCallerHeader");async function qr(e,r,i){const c=ge(r.provider);if(c===null)throw new l("not_found",`provider "${r.provider}" is not available`,{param:"provider"});const t={...r,provider:c},n=new AbortController,a=g(()=>n.abort(i.signal.reason),"abort");i.signal.aborted?a():i.signal.addEventListener("abort",a,{once:!0});let s=i.requestId;const j=i.traceId??qe(),v=Pe({request_id:s,run_id:e.run_id,node_id:e.node_id,controller:n});let h,_,d,A,w,y,k,P="allowed";try{try{await he(t.provider)}catch{throw ye(t.provider)}let o=await H(t.provider,t.version),p=!1,m,O,$,x=!1,z=!1,F,Q=0;for(;;){const b=Ke(o,t.tool);if(d=`${o.id}:${b.group}`,se(e,o.id,b.group),o.transport.kind!=="machine"&&t.machine!==void 0)throw new l("invalid_argument",`provider "${o.id}" is not served by a device, so it takes no machine`,{param:"machine"});o.transport.kind==="machine"&&F===void 0&&(F=await Te(t.machine,void 0,{newest:Y(o.major,t.tool)}),Q=Date.now()+(o.commands.timeouts?.requestMs??Be));let D=null;if(t.approval&&!x){const u=await _e(e,t,te(o,b));$=u.option,D=u.prepared,k=t.approval,s=u.requestId,x=!0}const I={params:b.params.filter(u=>"type"in u&&u.type==="file").map(u=>u.name),output:b.output.find(u=>u.type==="file")?.name??null},V=JSON.stringify(I);if(O!==void 0&&O!==V)throw new l("provider_bad_response","the refreshed manifest changed the tool file contract",{origin:"provider",details:{status:409,message:"manifest_stale changed the tool file contract"}});O=V,D&&(m=await K(e,I,t.arguments,D,{signal:n.signal})),m??=await be(e,I,t.arguments,{signal:n.signal});const{sub:q,grantee:T}=await Qe(e);if(o.transport.kind==="machine"){const u=await Ye(e,o,t,b,m,{sub:q,requestId:s,deadlineAt:Q,signal:n.signal,machine:F});return y=u.responder,h=u.cleanup,{status:200,body:u.result}}const C=await je({audience:o.transport.endpoint,sub:q,grantee:T,initiating_app:T,scope:Ve(o,b)},{signal:n.signal});A=C.jti;const U=e.class==="person"?xe:T,E=le({call:"tool",tokenPayer:C.payer,sub:q}),L=await ue({scope:"call",payer:E.payer,funding:E.funding,sub:q,grantee:U,provider:`app:${o.id}`});if(L!==null)throw await fe({request:s,kind:"tool",what:`${o.id}:${t.tool}`,usd:0,payer:E.payer,funding:E.funding,sub:q,grantee:U,node:e.node_id,run:e.run_id,provider:`app:${o.id}`,causedBy:i.causedBy??null,refused:ce(L)}),pe(L);const oe={registration:{name:o.id,endpoint:o.transport.endpoint},...o.commands.baseUrl?{baseUrl:o.commands.baseUrl}:{},...o.commands.timeouts?{timeouts:o.commands.timeouts}:{},params:b.params,rest:b.rest,output:b.output,commandPath:[o.id,...t.tool.split(" ")]},ne=$e(oe,m.arguments,void 0,{authorization:`Bearer ${C.access_token}`,requestId:s,traceId:j,fileMode:"pass-through",extraHeaders:{...i.causedBy?{"Crtr-Caused-By":i.causedBy}:{},...e.run_id?{"Crtr-Run-Id":e.run_id}:{},...await Xe(e),...$?{"Crtr-Approval":$}:{},...m.headers}});_??=Date.now()+(o.commands.timeouts?.requestMs??3e4);let f;try{if(f=await Ce(ne,{connectMs:o.commands.timeouts?.connectMs,requestMs:o.commands.timeouts?.requestMs,deadlineAt:_,signal:n.signal}),n.signal.aborted)throw n.signal.reason??new Error("provider call aborted")}catch(u){throw n.signal.aborted?n.signal.reason??u:u instanceof Ee?new l("provider_unavailable",u.message,{origin:"provider",details:{status:null,code:u.kind}}):u}if(w??=await ze({provider:o.id,tool:t.tool,request_id:s,run_id:e.run_id,sub:q,grantee:T,payer:C.payer,ledger_grantee:U,funding:E.funding,node_id:e.node_id,caused_by:i.causedBy??null,jti:C.jti,status:f.status,headers:f.headers}),y=f.headers["crtr-responder"],f.status===401&&ke(C.key),f.status>=200&&f.status<300){const u=f.body;if(!u||typeof u!="object"||Array.isArray(u))throw new l("provider_bad_response","provider result is not a JSON object",{origin:"provider",details:{status:f.status,message:"provider result is not a JSON object"}});let S;try{S=await W(e,m,u,{signal:n.signal})}catch(R){throw R instanceof l&&R.code==="provider_error"?new l("provider_bad_response",R.message,{origin:"provider",details:{status:f.status,message:R.message}}):R}h=S.cleanup;const B=J(b.output,S.result);if(B)throw new l("provider_bad_response",`provider result has an invalid output field "${B.field}"`,{origin:"provider",param:B.field,details:{status:f.status,...B}});if(n.signal.aborted)throw n.signal.reason??new Error("provider call aborted");return{status:200,body:S.result}}const M=G(f.body);if(f.status===403&&M.code==="approval_required"&&!$&&!z){z=!0;const u=await Ae(e,t,s,M.question,n.signal,te(o,b),m);if(k=u.questionId,$=u.option,m=await K(e,I,t.arguments,m,{signal:n.signal}),_=void 0,n.signal.aborted)throw new l("user_denied","the approval wait was canceled");continue}if(f.status===403&&M.code==="approval_required"&&$)throw N(f.status,f.body,f.headers,!0);if(f.status!==401&&M.manifest_stale===!0&&!p){p=!0,await we(o.id,{conditional:!1,...t.version===void 0?{}:{version:t.version}}),o=await H(o.id,t.version);continue}throw N(f.status,f.body,f.headers,!!$)}}catch(o){throw o instanceof l&&o.question_id&&(k=o.question_id),y===void 0&&o instanceof l&&typeof o.responder=="string"&&(y=o.responder),P=`refused:${o instanceof l?o.code:"server_error"}`,await h?.(),o}finally{try{await Ie({request_id:s,caller:e,provider:t.provider,tool:t.tool,scope_checked:d,outcome:P,jti:A,receipt_id:w,responder:y,question_id:k})}finally{v()}i.signal.removeEventListener("abort",a)}}g(qr,"callProvider");async function Ye(e,r,i,c,t,n){const{machine:a}=n,s=await Ge(e,n.sub),j={machine:a,envelope:s,signal:n.signal,deadlineAt:n.deadlineAt,mapFailure:N};if(Y(r.major,i.tool)){const p=await Oe(j,t.arguments,r.major),m=J(c.output,p);if(m)throw new l("provider_bad_response",`the libraries result has an invalid output field "${m.field}"`,{origin:"provider",param:m.field,details:{status:200,...m}});return{result:p,responder:void 0,cleanup:void 0}}let v=t.arguments,h=null,_="";if(Ne(r.major,i.tool,t.arguments)){const p=await Fe(j,t.arguments,r.major);if(n.deadlineAt-Date.now()<=0)throw X(a,"timeout","");p!==null&&(v=p.arguments,h=p.services,_=p.release)}const d=await Me(a,{tool:i.tool,arguments:v,version:r.major,requestId:n.requestId,runId:e.run_id,deadlineAt:n.deadlineAt,upload:t.upload===null?null:{id:t.upload.upload_id,link:t.upload.upload_link}},s,n.signal);if(n.signal.aborted)throw n.signal.reason??new Error("provider call aborted");if("unreachable"in d)throw X(a,d.unreachable.reason,d.unreachable.message);const A=d.headers["crtr-responder"],w=G(d.body);if(d.status<200||d.status>=300){const p=Se(a,d.status,typeof w.code=="string"?w.code:void 0,typeof w.message=="string"?w.message:void 0,d.body),m=p===null&&d.status>=500&&typeof w.code=="string"?new l("provider_error",typeof w.message=="string"?w.message:`the device answered HTTP ${d.status}`,{origin:"runtime",status:d.status,details:{code:w.code,status:d.status}}):null;throw Object.assign(p??m??N(d.status,d.body,d.headers),{responder:A})}const y=d.body&&typeof d.body=="object"&&!Array.isArray(d.body)?d.body.result:void 0;if(!y||typeof y!="object"||Array.isArray(y))throw Object.assign(new l("provider_bad_response","the device result is not a JSON object",{origin:"provider",details:{status:d.status,message:"the device result is not a JSON object"}}),{responder:A});let k=y;if(h!==null){const p=De(k,h);if(Ue(a,s,_,p.calls),"error"in p)throw Object.assign(p.error,{responder:A});k=p.result}let P;try{P=await W(e,t,k,{signal:n.signal})}catch(p){throw p instanceof l&&p.code==="provider_error"?Object.assign(new l("provider_bad_response",p.message,{origin:"provider",details:{status:d.status,message:p.message}}),{responder:A}):p}const o=J(c.output,P.result);if(o)throw await P.cleanup?.(),Object.assign(new l("provider_bad_response",`the device result has an invalid output field "${o.field}"`,{origin:"provider",param:o.field,details:{status:d.status,...o}}),{responder:A});return{result:P.result,responder:A,cleanup:P.cleanup}}g(Ye,"callDevice");export{qr as callProvider,Xe as crtrCallerHeader,N as mapProviderResponse,ze as onProviderResponse,ee as providerLeaves,$r as providerTools};
|
|
@@ -7,7 +7,7 @@ export declare const MINT_TIMEOUT_MS = 10000;
|
|
|
7
7
|
/** Waits before the second and third attempt at a token endpoint that answered 502, 503 or 504. */
|
|
8
8
|
export declare const MINT_RETRY_DELAYS_MS: number[];
|
|
9
9
|
export interface MintOptions {
|
|
10
|
-
/** The directory issuer; default
|
|
10
|
+
/** The directory issuer; default `directoryIssuer()`. */
|
|
11
11
|
issuer?: string;
|
|
12
12
|
/** The caller's signal: an abort rethrows its reason, not a mapped error. */
|
|
13
13
|
signal?: AbortSignal;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var E=Object.defineProperty;var c=(r,e)=>E(r,"name",{value:e,configurable:!0});import{createHash as M}from"node:crypto";import{
|
|
1
|
+
var E=Object.defineProperty;var c=(r,e)=>E(r,"name",{value:e,configurable:!0});import{createHash as M}from"node:crypto";import{directoryIssuer as j}from"../directory/issuer.js";import{emitEvent as $}from"../events/emit.js";import{OutboundError as A}from"../events/outbound.js";import{grantSyncStateFor as I}from"../grants/mirror.js";import{assertion as N,machineRevokedMessage as O,requestGrantSync as P,runtimeClient as L}from"../grants/sync.js";import{isUnsandboxedMachine as D}from"../runtime/unsandboxed.js";import{ProviderError as g}from"./errors.js";import{cacheKey as F,cachedToken as G,discardEpoch as U,storeToken as J}from"./token-cache.js";import{discardFile as le}from"./token-cache.js";const Y=1e4,B=[300,900];function C(r){const e=r.issuer??j();if(!e)throw new g("not_found","provider calls need a directory-connected runtime");return e}c(C,"issuerOf");function h(r,e,t){return new g(r,e,{origin:"directory",details:t})}c(h,"directoryError");function H(r,e,t,i){const n=typeof e.error=="string"?e.error:null,s=typeof e.error_description=="string"?e.error_description:void 0,o={directory_status:r,...n?{directory_error:n}:{},...s?{directory_description:s}:{}},d=s?`: ${s}`:"";switch(n){case"invalid_client":return D()?{error:h("machine_revoked",O(i),o),grantRefusal:!1}:{error:h("server_error",`the directory refused the outbound token request (${n})${d}`,o),grantRefusal:!1};case"invalid_request":return{error:h("server_error",`the directory refused the outbound token request (${n})${d}`,o),grantRefusal:!1};case"invalid_target":return{error:h("not_found",`the directory knows no provider at ${t.audience}${d}`,o),grantRefusal:!1};case"invalid_grant":return{error:h("grant_revoked",`the directory has no active grant for ${t.grantee}${d}`,o),grantRefusal:!0};case"provider_not_connected":return{error:h("provider_not_connected",s??"The user has not connected this provider.",o),grantRefusal:!1};case"invalid_scope":{const a=typeof e.scope=="string"&&e.scope?e.scope:t.scope.length===1?t.scope[0]:void 0,l=a?`missing scope ${a}`:`the grant does not cover ${t.scope.join(" ")}`;return{error:new g("scope_missing",l,{origin:"directory",details:o,...a?{scope:a}:{}}),grantRefusal:!0}}default:return{error:h("server_error",`the directory token endpoint answered ${r}${n?` ${n}`:""}${d}`,o),grantRefusal:!1}}}c(H,"refusal");function K(r){try{return JSON.parse(Buffer.from(r.split(".")[1]??"","base64url").toString("utf8"))}catch{return{}}}c(K,"claims");function z(r){const e=r.grant_rev,t=r.grant_status;return typeof e!="number"||!Number.isInteger(e)||e<0||typeof t!="string"?null:{rev:e,status:t}}c(z,"refusedGrantState");function Q(r,e){const t=c(i=>i.status==="active"?0:1,"phase");return r.rev>e.rev||r.rev===e.rev&&t(r)>t(e)}c(Q,"newer");async function V(r,e,t){if(!e)return;const i=await I(r.grantee,r.sub)??{rev:0,status:"removed"};if(!Q(e,i))return;const n=t.syncGrants??P;Promise.resolve().then(()=>n({fresh:!0})).catch(()=>{})}c(V,"syncIfNewer");async function W(r,e={}){const t=C(e),i=`${t}/token`,n=L(),s=c(async()=>{const u=new URLSearchParams({grant_type:"client_credentials",client_id:n.client_id,client_assertion_type:"urn:ietf:params:oauth:client-assertion-type:jwt-bearer",client_assertion:N(n,i),audience:r.audience,sub:r.sub,grantee:r.grantee,scope:[...new Set(r.scope)].sort().join(" "),initiating_app:r.initiating_app}),p=AbortSignal.timeout(Y),w=e.signal?AbortSignal.any([e.signal,p]):p,S=await(e.fetch??fetch)(i,{method:"POST",body:u,signal:w,headers:{Accept:"application/json"}});return{response:S,text:await S.text()}},"attempt");let o,d;try{for(let u=0;;u++){({response:o,text:d}=await s());const p=B[u];if(p===void 0||![502,503,504].includes(o.status))break;await new Promise(w=>setTimeout(w,p))}}catch(u){throw e.signal?.aborted?e.signal.reason:new g("server_error",`the directory token endpoint could not be reached: ${u instanceof Error?u.message:String(u)}`,{origin:"directory",cause:new A("directory_token",i,u)})}let a=null;try{a=d?JSON.parse(d):null}catch{a=null}const l=a&&typeof a=="object"&&!Array.isArray(a)?a:{};if(!o.ok){const{error:u,grantRefusal:p}=H(o.status,l,r,t);throw u.code==="machine_revoked"&&$({level:"error",event:"daemon.grants.machine_revoked",fields:{audience:r.audience}}),$({level:"info",event:"daemon.providers.mint_refused",fields:{audience:r.audience,grantee:r.grantee,code:u.code,directory_error:typeof l.error=="string"?l.error:null,status:o.status}}),p&&await V(r,z(l),e),u}const m=l.access_token;if(typeof m!="string"||!m)throw new g("server_error","the directory token response has no access_token",{origin:"directory"});const f=K(m),x=Math.floor((e.now?.()??Date.now())/1e3),y=l.expires_in,_=typeof y=="number"&&Number.isFinite(y)&&y>0?x+Math.floor(y):null,v=typeof f.exp=="number"?f.exp:null,b=_!==null&&v!==null?Math.min(_,v):_??v;if(b===null)throw new g("server_error","the directory token response names no expiry",{origin:"directory"});const R=typeof f.jti=="string"&&f.jti?f.jti:M("sha256").update(m).digest("hex"),T=typeof f.payer=="string"&&f.payer?f.payer:r.sub;return{access_token:m,jti:R,exp:b,payer:T}}c(W,"mintOutboundToken");const k=new Map;async function ce(r,e={}){const t=F(r),i=e.now??Date.now,n=G(t,i());if(n)return{...n,key:t};let s=k.get(t);if(!s){const d=U(t);s=W(r,{...e,signal:void 0}).then(a=>(J(t,a,d),a)).finally(()=>{k.delete(t)}),s.catch(()=>{}),k.set(t,s)}return{...e.signal?await X(s,e.signal):await s,key:t}}c(ce,"outboundToken");function X(r,e){return e.aborted?Promise.reject(e.reason):new Promise((t,i)=>{const n=c(()=>i(e.reason),"onAbort");e.addEventListener("abort",n,{once:!0}),r.then(t,i).finally(()=>e.removeEventListener("abort",n))})}c(X,"abortable");export{B as MINT_RETRY_DELAYS_MS,Y as MINT_TIMEOUT_MS,le as discardFile,W as mintOutboundToken,ce as outboundToken};
|
|
@@ -29,6 +29,9 @@ export declare function runObject(root: NodeMeta): Promise<Record<string, unknow
|
|
|
29
29
|
export declare const IDEMPOTENCY_WINDOW_MS = 86400000;
|
|
30
30
|
/** An `Idempotency-Key` header value: absent, or 1–255 characters. */
|
|
31
31
|
export declare function idempotencyKeyOf(header: unknown): string | undefined;
|
|
32
|
+
/** The person a cloud role's per-person rows and keys are cut to: undefined on a Mac (one person, nothing to cut); on a cloud role the caller's `sub`,
|
|
33
|
+
* and a caller without one is refused, so a missing `sub` can never read as "every person". */
|
|
34
|
+
export declare function cloudPersonScope(sub: string | null | undefined): string | undefined;
|
|
32
35
|
/** Delete keys past their window; returns how many were removed. */
|
|
33
36
|
export declare function pruneExpiredIdempotencyKeys(now?: number): Promise<number>;
|
|
34
37
|
/** Longest `run.start` deadline an app may set: 24 hours. The grammar is `crtr node new --deadline`'s (parts of `<int>[smhd]`, summed). */
|
|
@@ -53,6 +56,7 @@ export declare function listRuns(grantee: string | null, options: {
|
|
|
53
56
|
after?: string;
|
|
54
57
|
limit: number;
|
|
55
58
|
visible?: (runId: string) => Promise<boolean>;
|
|
59
|
+
sub?: string;
|
|
56
60
|
}): Promise<{
|
|
57
61
|
runs: Record<string, unknown>[];
|
|
58
62
|
next: string | null;
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
var Oe=Object.defineProperty;var
|
|
1
|
+
var Oe=Object.defineProperty;var c=(e,t)=>Oe(e,"name",{value:t,configurable:!0});import{coveredByAny as De}from"../../shared/env.js";import{createHash as Q}from"node:crypto";import{ApiError as Me}from"../../api/errors.js";import{CrtrError as Ae}from"../errors.js";import{isCloudRole as Ie}from"../canvas/person.js";import{isAbsolute as V,relative as Te,resolve as Le,sep as Ce,join as ke}from"node:path";import{SessionManager as xe}from"@earendil-works/pi-coding-agent";import{covers as P}from"@north-light/identity";import{openDb as B,withCanvasWrite as F}from"../canvas/db.js";import{deleteNodeWithOwned as We}from"../graph/deletion.js";import{getById as Fe}from"../graph/objects.js";import{repairRunConversations as Z}from"../canvas/sessions.js";import{getNode as O,nodeFiles as qe,removeNodeFiles as He,updateNode as Ue}from"../canvas/canvas.js";import{fullName as $e}from"../canvas/labels.js";import{renameWindow as Pe}from"../runtime/placement.js";import{liveExecutionForNode as K}from"../canvas/executions.js";import{conversationStore as ee,isConversationNotFound as Be}from"../conversation-store/index.js";import{PARKED_RESIDENT_SQL as je}from"../canvas/canvas.js";import{WAKE_MAIL_SQL as Je}from"../canvas/deliveries.js";import{readNodeRecap as Ye}from"../canvas/node-recap.js";import{enqueueNodeMail as Ge}from"../feed/messages.js";import{newestReportBody as Xe}from"../feed/reports.js";import{ensureAppProfile as ze,loadExactProfileManifest as Qe}from"../profiles/manifest.js";import{stopNodeSandboxes as te}from"../spaces/stop.js";import{BrokerUnreachableError as Ve}from"../runtime/broker-request.js";import{interruptLive as Ze}from"../runtime/interactive-deliver.js";import{isBrokerLive as ne}from"../runtime/model-swap.js";import{newNodeId as Ke}from"../runtime/nodes.js";import{reviveNode as j}from"../runtime/revive.js";import{spawnChildPrepared as et}from"../runtime/spawn.js";import{isPortableModelToken as tt}from"../runtime/launch.js";import{parseDurationMs as nt}from"../wake.js";import{expandModelCandidates as st,parseModelSpec as at}from"../model-routes.js";import{payerOfGrant as J}from"../grants/mirror.js";import{isolatedBrokerLauncherAvailable as it}from"../runtime/host.js";import{resolveRunKind as rt,resolveRunModel as ot}from"../runtime/launch-target.js";import{cycleAwareMessages as dt}from"../runtime/session-cycles.js";import{originFor as se}from"../runtime/stamp/protocol.js";import{readOutputRequest as ct,readOutputResult as ae}from"../runtime/output-result.js";import{admitLegacyStructuredOutput as ie}from"../../daemon/structured-requests/sidecar.js";import{runSchemaRepromptPending as ut}from"../runtime/stop-guard.js";import{toRunOutcomeDTO as mt}from"../../daemon/api/map.js";import{openAssistantMessageStartSequence as lt}from"../../daemon/runs/observer.js";import{closeNode as re}from"../runtime/close.js";import{parseScope as pt}from"@north-light/identity";import{appendRunEvent as oe,lockRunRoot as ft,subscribeRunEvents as _t}from"./events.js";import{runActivity as wt}from"./activity.js";import{cancelOpenQuestions as de,openNoticeIds as gt,openQuestionIds as ce}from"./questions.js";import{appSpace as Y}from"../layout.js";import{ensureAppSpace as Et}from"../spaces/space.js";import{assertUploadsUsable as ue,resolveStorageUrls as yt}from"../storage/attachments.js";import{storageClient as ht,storageConfig as Rt}from"../storage/client.js";import{deleteUploadRow as St,insertUploadUses as me,releaseRunUploads as Nt,runUsesPath as vt}from"../storage/tables.js";import{abortProviderCalls as le}from"../providers/inflight.js";import{filterAsync as pe,mapAsync as x}from"../async-array.js";const fe=c((e,t,s,n)=>yt(t,e,s,n?{taken:n}:{}),"defaultResolver"),bt=3e3;class R extends Error{static{c(this,"RunError")}status;code;param;details;scope;retryable;constructor(t,s,n,o,m,i,r=t===503){super(n),this.status=t,this.code=s,this.param=o,this.details=m,this.scope=i,this.retryable=r}}const N=c((e,t)=>new R(400,"invalid_request",e,t),"invalid"),G=c(()=>new R(404,"not_found","run not found"),"missing"),X=c(()=>({input_tokens:0,output_tokens:0,cache_read_tokens:0,cache_write_tokens:0,cost_usd:0}),"usage"),A=c(async()=>await B(),"db");async function q(e,t,s=!1){const n=await O(e);if(!n||n.parent!==null||n.run_id!==e||n.grantee!==t||!s&&n.deleting_at)throw G();return n}c(q,"ownedRun");const _e=["waiting_on_user","idle","settled"];async function C(e){if(e.status==="canceled"||e.status==="dead"||e.status==="done"&&e.intent!=="parked")return"settled";const t=await(await A()).prepare(`SELECT 1 FROM node_rows n WHERE n.run_id = ? AND n.status = 'active' AND
|
|
2
2
|
(n.last_settled_at IS NULL OR EXISTS (
|
|
3
3
|
SELECT 1 FROM run_events e WHERE e.run_id = ? AND e.node_id = n.node_id AND e.type = 'node.turn.started'
|
|
4
4
|
AND e.sequence_number > COALESCE((SELECT MAX(c.sequence_number) FROM run_events c
|
|
5
5
|
WHERE c.run_id = e.run_id AND c.node_id = e.node_id AND c.type = 'node.turn.completed'), 0)
|
|
6
|
-
)) LIMIT 1`).get(e.node_id,e.node_id),s=!e.last_settled_at&&e.status!=="done";return t||s||await
|
|
7
|
-
WHERE n.run_id = ? AND ${
|
|
8
|
-
AND (n.status IN ('active', 'idle') OR ${
|
|
9
|
-
WHERE run_id = node_id AND deleting_at IS NULL ${e===null?"":"AND grantee = ?"}
|
|
10
|
-
ORDER BY activity DESC, node_id DESC`).all(...e===null?[]:[e]),o=await
|
|
6
|
+
)) LIMIT 1`).get(e.node_id,e.node_id),s=!e.last_settled_at&&e.status!=="done";return t||s||await ut(e)?"running":(await ce(e.node_id)).length?"waiting_on_user":await(await A()).prepare(`SELECT 1 FROM deliveries d JOIN nodes n ON n.node_id = d.destination_id
|
|
7
|
+
WHERE n.run_id = ? AND ${Je("d","'armed', 'pending'")}
|
|
8
|
+
AND (n.status IN ('active', 'idle') OR ${je("n")}) LIMIT 1`).get(e.node_id)?"running":"idle"}c(C,"runStatus");async function kn(e){const t=await O(e);return t!==null&&await C(t)==="running"}c(kn,"runIsRunning");async function W(e){await Z(e.node_id),e=await O(e.node_id)??e;const t=await C(e),s=t==="settled"?[]:await ce(e.node_id),n=await Xe(e.node_id)||void 0,o=t==="settled"?await mt(e):null,m=o?.kind==="result"?await ae(e.node_id):void 0,i=Ye(e.node_id);return{run_id:e.node_id,name:e.name,status:t,...o?{outcome:o}:{},...m===void 0?{}:{result:m},...n!==void 0?{last_report:n}:{},...i?{recap:i}:{},pending_question_ids:s,open_notice_ids:t==="settled"?[]:await gt(e.node_id),...e.last_turn_error_json?{last_turn_error:JSON.parse(e.last_turn_error_json)}:{},usage:JSON.parse(e.usage_json??JSON.stringify(X())),payer:await J(e.grant_id),scopes:e.scopes,metadata:e.metadata_json?JSON.parse(e.metadata_json):{},created_at:e.created,...t==="settled"&&e.outcome_at?{settled_at:e.outcome_at}:{},latest_sequence:(e.event_cursor??1)-1,last_activity_at:e.last_activity_at,activity:await wt(e.node_id,t)}}c(W,"runObject");const z=864e5,we=255;function xn(e){if(e!==void 0){if(typeof e!="string"||!e.length||e.length>we)throw N(`Idempotency-Key must be 1-${we} characters`);return e}}c(xn,"idempotencyKeyOf");function Ot(e){if(Ie()){if(!e)throw new R(403,"permission_error","a cloud role serves this call only for a token that names a person");return e}}c(Ot,"cloudPersonScope");function k(e,t){const s=Ot(e);return s===void 0?t:`${s}:${t}`}c(k,"personKey");async function H(e,t,s,n){n&&await n.prepare("SELECT pg_advisory_xact_lock(hashtext(?))").get(`idempotency:${e}:${t}`),n??=await B();const o=await n.prepare("SELECT body_hash, run_id, response_json, created_at FROM idempotency_keys WHERE grantee = ? AND key = ?").get(e,t);if(!(!o||Date.now()-Date.parse(o.created_at)>=z)){if(o.body_hash!==s)throw new R(409,"idempotency_conflict","key used with a different request");return{run_id:o.run_id,response:JSON.parse(o.response_json)}}}c(H,"findIdempotent");async function ge(e,t,s,n,o,m,i){await e.prepare("DELETE FROM idempotency_keys WHERE grantee = ? AND key = ? AND created_at <= ?").run(t,s,new Date(Date.now()-z).toISOString()),await e.prepare("INSERT INTO idempotency_keys (grantee, key, body_hash, run_id, response_json, created_at) VALUES (?, ?, ?, ?, ?, ?)").run(t,s,n,o,JSON.stringify(m),i)}c(ge,"recordIdempotent");async function Wn(e=Date.now()){return Number((await(await B()).prepare("DELETE FROM idempotency_keys WHERE created_at <= ?").run(new Date(e-z).toISOString())).changes)}c(Wn,"pruneExpiredIdempotencyKeys");async function Ee(e,t,s,n,o){const m=n.text;let i=0;return{messageId:(await Ge(t,{kind:"message",label:m.slice(0,120),senderNodeId:"human",senderName:s,bodyJson:o?{body:m}:{body:m,start_turn:!1},urgency:o?"normal":"deferred",wake:o?1:0,withinEnqueue:c(async(u,l)=>{n.uses.length&&(await ue(s,n.uses,u),await me(n.uses.map(({upload_id:g,path:E,blob_key:y})=>({upload_id:g,path:E,blob_key:y,run_id:t})),u)),i=(await oe(u,t,t,"node.message.accepted",{message_id:l,start_turn:o})).sequence_number},"withinEnqueue")})).messageId,sequence:i}}c(Ee,"acceptRunMessage");class ye extends Error{static{c(this,"IdempotentReplay")}winner;constructor(t){super("idempotent replay"),this.winner=t}}const Dt=1440*60*1e3;function he(e){const t=typeof e=="string"?nt(e):null;if(t===null||!Number.isSafeInteger(t))throw N(`deadline '${String(e)}' is not a duration; use one or more <int>[smhd] parts such as 10m or 1h30m`,"deadline");if(t<=0)throw N("deadline must be greater than zero","deadline");if(t>Dt)throw N("deadline must be at most 24h","deadline");return t}c(he,"parseRunDeadlineMs");async function Fn(e,t,s,n=fe){if(t.isolated&&!it())throw new R(503,"isolated_unavailable","isolated runs require the Linux root launcher","isolated");t.deadline!==void 0&&he(t.deadline);const{causedBy:o,...m}=t,i=Q("sha256").update(JSON.stringify(m)).digest("hex");if(s){const a=await H(e.grantee,k(e.sub,s),i);if(a){const p=await q(a.run_id,e.grantee);return!p.pi_pid&&await C(p)==="running"&&(t.output_schema!==void 0&&!p.outcome_at&&await ct(p.node_id)===null&&await ae(p.node_id)===void 0&&await ie(p.node_id,"terminal",t.output_schema),await j(p.node_id,{resume:!0,capacity:"freeze"})),a.response}}await Et(e.grantee);const r=t.profile===void 0?await ze(e.grantee):Qe(t.profile),u=r.manifest.grantee??"app:terminal";if(u!==e.grantee){const a=`crtr:memory:rw:${u}:profile:${r.profileId}`;if(!e.resolved.some(p=>P(p,a))||t.scopes!==null&&!t.scopes.some(p=>P(p,a)))throw new R(403,"scope_missing",`missing scope ${a}`,"profile",void 0,a)}if(t.model!==void 0){const a=t.model;if(tt(a)){if(a.includes("/")&&await J(e.grant)!=="app"){const p=a.lastIndexOf("/"),D=a.slice(0,p),v=a.slice(p+1);if(["ultra","strong","medium","light"].includes(v)&&(await st({kind:"logical",family:D,strength:v,spec:a},Y(e.grantee).files,r.profileId)).every(S=>S.family!==D))throw N(`model '${a}' names a model family that is not configured in this daemon`,"model")}}else if(at(a)===void 0)throw N(`model '${a}' is not a strength (ultra, strong, medium, light), a family/strength, or a provider/model id`,"model")}const l=await Ke(),g=ke(Y(e.grantee).nodes,l);if(t.isolated&&t.cwd!==void 0){const a=Te(g,Le(t.cwd));if(!V(t.cwd)||a===".."||a.startsWith(`..${Ce}`)||V(a))throw N("cwd must be inside the isolated root node folder","cwd")}const E=await n(l,e.grantee,t.prompt),y=E.text,d=t.message===void 0?void 0:await n(l,e.grantee,t.message,E.uses.map(a=>a.path)),_=await J(e.grant);let h;try{const a=ot(r,t.model);await et({kind:rt(r),mode:"base",root:!0,rootLifecycle:"resident",readiness:"launch",cwd:t.isolated?t.cwd??g:Y(e.grantee).files,profile:r.profileId,prompt:y,nodeId:l,isolated:t.isolated??!1,...t.causedBy===void 0?{}:{causedBy:t.causedBy},...a===void 0?{}:{model:a},...t.deadline===void 0?{}:{deadlineAt:new Date(Date.now()+he(t.deadline)).toISOString()},...t.scopes===null?{}:{scopes:t.scopes},run:{grantee:e.grantee,sub:e.sub,grant_id:e.grant,client_id:e.client_id,metadata_json:JSON.stringify(t.metadata),run_id:l,event_cursor:1,usage_json:JSON.stringify(X())},withinCreate:c(async(p,D)=>{if(s){const S=await H(e.grantee,k(e.sub,s),i,p);if(S)throw new ye(S)}const v=E.uses;if(v.length&&(await ue(e.grantee,v,p),await me(v.map(({upload_id:S,path:I,blob_key:U})=>({upload_id:S,path:I,blob_key:U,run_id:l})),p)),h={run_id:l,node_id:l,grantee:e.grantee,grant:e.grant,rev:e.rev,scopes:t.scopes,payer:_,status:"running",created_at:D.created,metadata:t.metadata,sequence_number:0},await oe(p,l,l,"run.started",{scopes:t.scopes,payer:_,usage:X()}),d){const S=await Ee(p,l,e.grantee,d,!1);h.message={run_id:l,message_id:S.messageId,sequence_number:S.sequence}}s&&await ge(p,e.grantee,k(e.sub,s),i,l,h,D.created)},"withinCreate")},t.output_schema===void 0?void 0:async p=>{await ie(p,"terminal",t.output_schema)})}catch(a){if(a instanceof ye)return a.winner.response;if(t.model!==void 0&&a instanceof Ae&&a.code==="usage")throw N(a.message,"model");if(a instanceof Me&&(a.code==="isolated_run"||a.code==="invalid_request")){const p=a.details&&typeof a.details=="object"&&"param"in a.details&&typeof a.details.param=="string"?a.details.param:void 0;throw new R(a.status,a.code,a.message,p)}throw a}if(!h)throw new Error("run creation did not commit");return h}c(Fn,"startRun");async function qn(e,t){let s;if(t.after)try{const r=JSON.parse(Buffer.from(t.after,"base64url").toString());if(!r||typeof r!="object"||!("activity"in r)||typeof r.activity!="string"||!("id"in r)||typeof r.id!="string")throw new Error("invalid cursor");s={activity:r.activity,id:r.id}}catch{throw N("invalid list cursor","after")}const n=await(await A()).prepareUncached(`SELECT node_id, COALESCE(last_activity_at, created) AS activity FROM node_rows
|
|
9
|
+
WHERE run_id = node_id AND deleting_at IS NULL ${e===null?"":"AND grantee = ?"}${t.sub===void 0?"":" AND sub = ?"}
|
|
10
|
+
ORDER BY activity DESC, node_id DESC`).all(...e===null?[]:[e],...t.sub===void 0?[]:[t.sub]),o=await pe(await x((await pe(n,async({node_id:r})=>!t.visible||await t.visible(r))).filter(({activity:r,node_id:u})=>!s||r<s.activity||r===s.activity&&u<s.id),async r=>({root:await O(r.node_id),activity:r.activity})),async({root:r})=>!t.status||await C(r)===t.status),m=o.slice(0,t.limit),i=m.at(-1);return{runs:await x(m,async({root:r})=>await W(r)),next:o.length>t.limit&&i?Buffer.from(JSON.stringify({activity:i.activity,id:i.root.node_id})).toString("base64url"):null}}c(qn,"listRuns");async function Hn(e,t,s){const n=await q(e,t),o=c(async()=>await W(await q(e,t)),"read");return!s||_e.includes(await C(n))?await o():new Promise((m,i)=>{let r=c(()=>{},"unsubscribe");const u=c(()=>{clearTimeout(d),clearInterval(y),r()},"settle"),l=c(async()=>{u();try{m(await o())}catch(_){i(_)}},"finish"),g=c(async()=>{_e.includes(String((await o()).status))&&await l()},"check"),E=c(()=>{g().catch(_=>{u(),i(_)})},"run"),y=setInterval(E,250),d=setTimeout(()=>{l()},s*1e3);_t(e,E).then(_=>{r=_},_=>{u(),i(_)})})}c(Hn,"waitRun");const Mt=5;async function Un(e,t,s=fe,n=!0,o){const m=e.status==="canceled"||e.outcome_reason==="closed",i=e.grantee??"app:terminal",r=Q("sha256").update(JSON.stringify(["run.message",e.node_id,t,n])).digest("hex"),u=c(async g=>{const E=await O(e.node_id),y=await(await A()).prepare("SELECT 1 FROM deliveries WHERE message_id = ? AND state = 'pending' AND canceled_at IS NULL").get(String(g.message_id));return E&&!m&&n&&!E.pi_pid&&y&&await j(e.node_id,{resume:!0,capacity:"freeze"}),g},"replay");if(o){const g=await H(i,k(e.sub,o),r);if(g)return u(g.response)}if(m)throw new R(409,"run_settled","canceled run cannot receive a message");const l=n&&e.final_report&&!e.pi_pid?(await import("../runtime/reopen.js")).commitReopenResident:void 0;for(let g=1;;g++){const E=await s(e.node_id,i,t),y=await F(async d=>{if(o){const a=await H(i,k(e.sub,o),r,d);if(a)return{replayed:a.response}}if(E.uses.length){await ft(d,e.node_id);for(const a of E.uses)if(await vt(e.node_id,a.path,d))return"path_taken"}await l?.(e.node_id);const _=await Ee(d,e.node_id,i,E,n),h={run_id:e.node_id,message_id:_.messageId,sequence_number:_.sequence};return o&&await ge(d,i,k(e.sub,o),r,e.node_id,h,new Date().toISOString()),{result:h}});if(y==="path_taken"){if(g>=Mt)throw new R(503,"service_unavailable","attachments of concurrent messages kept taking each other's file names; retry");continue}return"replayed"in y?u(y.replayed):(n&&!e.pi_pid&&await j(e.node_id,{resume:!0,capacity:"freeze"}),y.result)}}c(Un,"messageRun");async function At(e){const t=c(()=>new R(503,"service_unavailable",`node ${e} broker was unavailable before the interrupt reached it`),"unavailable");for(let s=0;s<2;s++){const n=await O(e);if(!n)throw G();if(!ne(n)){if(n.streaming)throw t();return}const o=(await K(e))?.executionId;try{await Ze(e)==="turn"&&le({nodes:[e]});return}catch(m){if(!(m instanceof Ve))throw m;const i=await O(e);if(!i)throw G();if(!i.streaming)return;if(s===0&&ne(i)&&(await K(e))?.executionId!==o)continue;throw t()}}throw t()}c(At,"interruptNode");async function $n(e,t="stop"){const s=t==="stop"?(await(await A()).prepare("SELECT node_id FROM nodes WHERE run_id = ?").all(e.node_id)).map(({node_id:n})=>n):[e.node_id];return await Promise.all(s.map(n=>At(n))),await W(await O(e.node_id)??e)}c($n,"interruptRun");async function Pn(e,t={}){const s=(await(await A()).prepare("SELECT node_id FROM nodes WHERE run_id = ? ORDER BY created DESC").all(e.node_id)).map(i=>i.node_id);le({run:e.node_id});const n=[];if(await C(e)!=="settled")n.push(...(await re(e.node_id,{preserveEmpty:!0,stopReason:"run_canceled"})).closed);else for(const i of s){if(i===e.node_id)continue;const r=await O(i);r&&r.status!=="done"&&r.status!=="canceled"&&r.status!=="dead"&&n.push(...(await re(i,{preserveEmpty:!0,stopReason:"run_canceled"})).closed)}if(await de({run_id:e.node_id},"the run was canceled"),(await Promise.all([...new Set([e.node_id,...n])].map(i=>te(i,"run_canceled")))).some(i=>!i.confirmed))throw new R(500,"server_error","run process teardown could not be confirmed",void 0,void 0,void 0,!0);const m=await O(e.node_id);return await W(m??e)}c(Pn,"cancelRun");const Re=200;async function Bn(e,t){if(typeof t!="string"||!t.trim())throw N("name is required","name");const s=t.trim();if(s.length>Re)throw N(`name exceeds ${Re} characters`,"name");const n=await Ue(e.node_id,{name:s});return n.window&&Pe(n.window,$e(n)),await W(n)}c(Bn,"renameRun");async function jn(e,t={config:Rt,client:ht}){await de({run_id:e.node_id},"the run was deleted");const s=await F(async u=>(await u.prepare("UPDATE nodes SET deleting_at = COALESCE(deleting_at, ?) WHERE node_id = ?").run(new Date().toISOString(),e.node_id),(await u.prepare("SELECT node_id FROM nodes WHERE run_id = ? ORDER BY created DESC").all(e.node_id)).map(l=>l.node_id)));if((await Promise.all(s.map(u=>te(u,"run_deleted",{deleting:!0})))).some(u=>!u.confirmed))throw new R(500,"server_error","run process teardown could not be confirmed",void 0,void 0,void 0,!0);const o=await x(s,async u=>{const l=await qe(u);if(l.app===null)throw new Error(`run node missing during deletion: ${u}`);return l}),m=await(await A()).prepare("SELECT DISTINCT session_id FROM sessions WHERE session_id IS NOT NULL AND node_id IN (SELECT node_id FROM nodes WHERE run_id = ?)").all(e.node_id);for(const{session_id:u}of m)try{await ee().delete(u)}catch(l){if(!Be(l))throw l}const i=await F(async u=>{for(const y of s){const d=await Fe(u,y);d!==null&&d.deleted_at===null&&await We(u,d)}const l=await Nt([e.node_id],u);await u.prepare("DELETE FROM run_events WHERE run_id = ?").run(e.node_id),await u.prepare("DELETE FROM idempotency_keys WHERE run_id = ?").run(e.node_id);const g=s.map(()=>"?").join(","),E=await u.prepareUncached(`SELECT message_id FROM messages WHERE sender_node_id IN (${g}) UNION SELECT message_id FROM deliveries WHERE destination_id IN (${g})`).all(...s,...s);await u.prepareUncached(`DELETE FROM deliveries WHERE destination_id IN (${g})`).run(...s);for(const{message_id:y}of E)await u.prepare("DELETE FROM messages WHERE message_id = ? AND NOT EXISTS (SELECT 1 FROM deliveries WHERE message_id = ?)").run(y,y);return l});for(const u of o)await He(u);const{notifyRunDeleted:r}=await import("./events.js");return r(e.node_id),{uploads_pending:await It(i,t)}}c(jn,"deleteRun");async function It(e,t){if(!e.length||!t.config())return e.length;let s;try{s=t.client()}catch{return e.length}const n=new Set,o=e.map(i=>s.deleteUpload(i).then(async()=>{await St(i),n.add(i)},()=>{}));let m;return await Promise.race([Promise.all(o),new Promise(i=>{m=setTimeout(i,t.budgetMs??bt),m.unref?.()})]),clearTimeout(m),e.length-n.size}c(It,"deleteReleasedUploads");async function Jn(e,t,s){await q(e,t),await Z(e);const n=await F(async d=>{const _=await d.prepare("SELECT node_id, parent FROM nodes WHERE run_id = ? ORDER BY CASE WHEN node_id = ? THEN 0 ELSE 1 END, created, node_id").all(e,e),h=new Map;for(const S of _)h.set(S.node_id,(await d.prepare("SELECT session_id FROM sessions WHERE node_id = ? GROUP BY session_id ORDER BY min(created_at)").all(S.node_id)).map(I=>I.session_id));const p=(await d.prepare("SELECT event_cursor FROM nodes WHERE node_id = ?").get(e)).event_cursor-1,D=await d.prepare(`SELECT node_id, sequence_number FROM run_events
|
|
11
11
|
WHERE run_id = ? AND sequence_number <= ? AND type IN ('node.thinking.done', 'node.output_text.done', 'usage')
|
|
12
12
|
ORDER BY sequence_number`).all(e,p),v=await d.prepare(`SELECT node_id, sequence_number, type, body_json FROM run_events
|
|
13
13
|
WHERE run_id = ? AND sequence_number <= ? AND type IN ('node.thinking.delta', 'node.output_text.delta')
|
|
14
|
-
ORDER BY sequence_number`).all(e,p);return{nodes:
|
|
14
|
+
ORDER BY sequence_number`).all(e,p);return{nodes:_,sessionIds:h,latestSequence:p,completed:D,deltas:v}}),{nodes:o,sessionIds:m,latestSequence:i,completed:r,deltas:u}=n,l=await x(o,async d=>({node_id:d.node_id,parent_node_id:d.parent,conversations:await x(m.get(d.node_id)??[],async _=>{const{header:h,entries:a}=await ee().read(_);if(s==="entries")return{conversation_id:_,header:h,entries:a};const p=xe.inMemory(h.cwd,void 0,[h,...a]),D=dt(p)??[],v=new Map(a.map((w,b)=>[w.id,b])),S=a.filter(w=>w.type==="custom"&&w.customType==="crtr-system-prompt").map(w=>({id:w.id,message:{role:"custom",customType:"crtr-system-prompt",data:"data"in w?w.data:void 0,timestamp:w.timestamp}})),I=a.filter(w=>w.type==="custom_message"&&w.customType==="app_message").map(w=>({id:w.id,message:{role:"custom",customType:"app_message",content:"content"in w?w.content:"",timestamp:w.timestamp}})),U=d.node_id===e?a.find(w=>{if(w.type!=="message"||w.message.role!=="user")return!1;const b=se(a,w.message.timestamp);return b?.type==="runtime"&&b.kind==="kickoff"})?.id:void 0,Se=[...D.filter(({id:w})=>!I.some(b=>b.id===w)),...S,...I].sort((w,b)=>(v.get(w.id)??Number.MAX_SAFE_INTEGER)-(v.get(b.id)??Number.MAX_SAFE_INTEGER)).map(({id:w,message:b})=>{const f=b,T=f.usage,$=f.role==="user"?se(a,Number(f.timestamp)):null,Ne=$?.type==="human"||w===U,L=f.role==="toolResult"?"tool_result":f.role==="bashExecution"?"bash_execution":f.role==="compactionSummary"?"compaction_summary":f.role==="branchSummary"?"branch_summary":f.role==="custom"&&f.customType==="crtr-system-prompt"?"system":f.role==="user"?Ne?"user":"custom":f.role,ve=L==="custom"?f.role==="custom"?f.customType:$?.type==="runtime"?$.kind:"unknown":void 0,be=L==="system"&&f.customType==="crtr-system-prompt"?[{type:"text",text:f.data?.text??""}]:typeof f.content=="string"?[{type:"text",text:f.content}]:Array.isArray(f.content)?f.content.map(M=>M.type==="toolCall"?{type:"tool_call",tool_call_id:M.id,name:M.name,arguments:M.arguments}:M.type==="image"?{type:"image",mime_type:M.mimeType}:M.type==="thinking"?{type:"thinking",text:M.thinking}:M):[];return{entry_id:w,role:L,...L==="custom"?{custom_type:ve}:{},time:typeof f.timestamp=="string"?f.timestamp:new Date(Number(f.timestamp??Date.now())).toISOString(),content:be,...L==="assistant"?{model:f.model,provider:f.provider,stop_reason:f.stopReason,...f.errorMessage?{error_message:f.errorMessage}:{},...T?{usage:{input_tokens:T.input??0,output_tokens:T.output??0,cache_read_tokens:T.cacheRead??0,cache_write_tokens:T.cacheWrite??0,cost_usd:T.cost?.total??0}}:{}}:{},...L==="tool_result"?{tool_call_id:f.toolCallId,tool_name:f.toolName,is_error:f.isError}:{}}})??[];return{conversation_id:_,messages:Se}})})),g=new Map(await Promise.all(l.map(async d=>[d.node_id,await lt(d.node_id)])));for(const d of r){const _=g.get(d.node_id);_!=null&&d.sequence_number>=_&&g.set(d.node_id,null)}const E=new Map;for(const d of u){const _=g.get(d.node_id);if(_==null||d.sequence_number<_)continue;const h=JSON.parse(d.body_json),a=E.get(d.node_id)??{thinking:"",text:""};d.type==="node.thinking.delta"?a.thinking+=h.delta:a.text+=h.delta,E.set(d.node_id,a)}const y=l.map(d=>({...d,in_progress_message:g.get(d.node_id)==null?null:E.get(d.node_id)??{thinking:"",text:""}}));return{run_id:e,latest_sequence:i,nodes:y}}c(Jn,"traceRun");function Yn(e,t,s){if(t===void 0){if(!e.some(n=>P(n,"crtr:llm")))throw new R(403,"scope_missing","missing scope crtr:llm",void 0,void 0,"crtr:llm");return null}if(!Array.isArray(t)||t.some(n=>typeof n!="string"))throw N("scopes must be a list of scope strings","scopes");for(const n of t){try{pt(n)}catch{throw N(`invalid scope ${n}`,"scopes")}if(/^crtr:files:(?:read|rw):app:/.test(n)&&n.split(":")[4]===s.slice(4))throw N(`own-app files cannot narrow a run: ${n}`,"scopes");if(!(/^crtr:memory:(?:read|rw):app:/.test(n)&&n.split(":")[4]===s.slice(4))&&!De(e,n))throw new R(403,"scope_missing",`missing scope ${n}`,void 0,void 0,n)}if(!t.includes("crtr:llm"))throw new R(403,"scope_missing","missing scope crtr:llm",void 0,void 0,"crtr:llm");return t}c(Yn,"requestedScopes");export{z as IDEMPOTENCY_WINDOW_MS,Dt as RUN_DEADLINE_MAX_MS,bt as RUN_DELETE_STORAGE_BUDGET_MS,Re as RUN_NAME_MAX,R as RunError,Pn as cancelRun,Ot as cloudPersonScope,jn as deleteRun,xn as idempotencyKeyOf,$n as interruptRun,qn as listRuns,Un as messageRun,q as ownedRun,he as parseRunDeadlineMs,Wn as pruneExpiredIdempotencyKeys,Bn as renameRun,Yn as requestedScopes,kn as runIsRunning,W as runObject,Fn as startRun,Jn as traceRun,Hn as waitRun};
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
var
|
|
1
|
+
var x=Object.defineProperty;var s=(r,l)=>x(r,"name",{value:l,configurable:!0});import{createReadStream as S,read as v,statSync as $}from"node:fs";import{Readable as w}from"node:stream";import{promisify as T}from"node:util";import{readConfig as E}from"../config.js";import{directoryIssuer as C}from"../directory/issuer.js";import{RunError as m}from"../runs/operations.js";import{mintDirectoryToken as O,runtimeId as P}from"../grants/sync.js";const F=104857600;class b extends Error{static{s(this,"StorageRefused")}status;code;constructor(l,u,d){super(d),this.status=l,this.code=u}}const U=T(v);async function*j(r,l){let u=0;for(;u<l;){const d=Buffer.allocUnsafe(Math.min(1048576,l-u)),{bytesRead:f}=await U(r,d,0,d.length,u);if(f===0)throw new Error("file shrank while it was being copied");u+=f,yield d.subarray(0,f)}}s(j,"fdChunks");const i=s(r=>new m(503,"storage_unavailable",r,void 0,void 0,void 0,!0),"unavailable");function A(){const r=E("user").runtime?.storage;return!r?.service_url||!r.base_url?null:{service_url:r.service_url.replace(/\/$/,""),base_url:r.base_url.replace(/\/$/,"")}}s(A,"storageConfig");let _;function G(){const r=A(),l=C();if(!r||!l)throw i("file storage is not configured on this runtime");const u=`${l}
|
|
2
2
|
${r.service_url}
|
|
3
|
-
${r.base_url}`;return _?.key!==u&&(_={key:u,client:
|
|
3
|
+
${r.base_url}`;return _?.key!==u&&(_={key:u,client:L(r,()=>O(l,r.service_url),P())}),_.client}s(G,"storageClient");function J(){_=void 0}s(J,"resetStorageClient");function L(r,l,u){let d,f;const k=s(async()=>{if(d&&d.expires_at-6e4>Date.now())return d.access_token;f??=l().finally(()=>{f=void 0});try{d=await f}catch(t){throw i(`storage token could not be minted: ${t instanceof Error?t.message:String(t)}`)}return d.access_token},"bearer"),c=s(async(t,e,n={})=>{const p=[AbortSignal.timeout(n.timeoutMs??1e4),...n.signal?[n.signal]:[]];let a;try{a=await fetch(`${r.service_url}${e}`,{method:t,signal:AbortSignal.any(p),headers:{Authorization:`Bearer ${await k()}`,...n.body===void 0?{}:{"Content-Type":"application/json"}},...n.body===void 0?{}:{body:JSON.stringify(n.body)}})}catch(o){throw o instanceof m?o:i(`storage could not be reached: ${o instanceof Error?o.message:String(o)}`)}if(a.status===401&&(d=void 0),a.status===404||a.status===409){const o=await a.json().catch(()=>({})),g=o.error?.code??o.code??(a.status===404?"not_found":"not_uploaded");throw new b(a.status,g,o.error?.message??o.message??`storage answered ${a.status}`)}if(!a.ok)throw await a.body?.cancel().catch(()=>{}),i(`storage answered ${a.status} to ${t} ${e.split("?")[0]}`);return a},"call"),y=s(async t=>{try{return await t.json()}catch{throw i("storage answered with an invalid body")}},"json"),h=s(t=>encodeURIComponent(t),"id");return{config:r,runtimeId:u,async createUpload(t){const e=await y(await c("POST","/v1/uploads",{body:t}));if(typeof e.upload_id!="string"||typeof e.url!="string"||typeof e.upload_link!="string"||typeof e.expires_at!="string")throw i("storage answered with an invalid upload");return{upload_id:e.upload_id,url:e.url,upload_link:e.upload_link,expires_at:e.expires_at}},async fetchUpload(t,e){const n=await c("GET",`/v1/uploads/${h(t)}/content`,{...e?{signal:e}:{},timeoutMs:11e4});if(!n.body)throw i("storage answered with no body");const p=n.headers.get("content-length");return{body:w.fromWeb(n.body),size:p===null?null:Number(p),media_type:n.headers.get("content-type")}},async signDownload(t){const e=await y(await c("POST",`/v1/uploads/${h(t)}/download-link`));if(typeof e.url!="string"||typeof e.expires_at!="string")throw i("storage answered with an invalid link");return{url:e.url,expires_at:e.expires_at}},async deleteUpload(t){try{await c("DELETE",`/v1/uploads/${h(t)}`)}catch(e){if(!(e instanceof b&&e.status===404))throw e}},async createShare(t){const e=await y(await c("POST","/v1/shares",{body:t}));if(typeof e.share_id!="string"||typeof e.url!="string"||typeof e.upload_link!="string")throw i("storage answered with an invalid share");return{share_id:e.share_id,url:e.url,upload_link:e.upload_link,expires_at:e.expires_at??null}},async putShareBytes(t,e,n,p){if($(e).size!==n)throw new Error("shared file changed size while it was being copied");let a;try{a=await fetch(t,{method:"PUT",signal:AbortSignal.timeout(11e4),headers:{"Content-Type":p,"Content-Length":String(n)},body:w.toWeb(S(e)),duplex:"half"})}catch(o){throw i(`storage could not be reached: ${o instanceof Error?o.message:String(o)}`)}if(await a.body?.cancel().catch(()=>{}),!a.ok)throw i(`storage answered ${a.status} to the share upload`)},async deleteShare(t){try{await c("DELETE",`/v1/shares/${h(t)}`)}catch(e){if(!(e instanceof b&&e.status===404))throw e}},async createResultUpload(t){const e=await y(await c("POST","/v1/uploads",{body:{name:t.name,media_type:t.media_type,max_size:t.max_size}}));if(typeof e.upload_id!="string"||typeof e.url!="string"||typeof e.upload_link!="string"||typeof e.expires_at!="string")throw i("storage answered with an invalid upload");return{upload_id:e.upload_id,url:e.url,upload_link:e.upload_link,expires_at:e.expires_at}},async signUploadLink(t){const e=await y(await c("POST",`/v1/uploads/${h(t)}/upload-link`));if(typeof e.upload_link!="string"||typeof e.expires_at!="string")throw i("storage answered with an invalid upload link");return{upload_link:e.upload_link,expires_at:e.expires_at}},async createOutbound(t){const e=await y(await c("POST","/v1/outbound",{body:t}));if(typeof e.object_id!="string"||typeof e.upload_link!="string"||typeof e.url!="string"||typeof e.expires_at!="string")throw i("storage answered with an invalid outbound object");return{object_id:e.object_id,upload_link:e.upload_link,url:e.url,link_expires_at:e.link_expires_at,expires_at:e.expires_at}},async signOutbound(t){const e=await y(await c("POST",`/v1/outbound/${h(t)}/link`));if(typeof e.url!="string"||typeof e.expires_at!="string")throw i("storage answered with an invalid link");return{url:e.url,link_expires_at:e.link_expires_at,expires_at:e.expires_at}},async putFileBytes(t,e,n,p){const a=w.from(j(e,n));let o;try{o=await fetch(t,{method:"PUT",signal:AbortSignal.timeout(11e4),headers:{"Content-Type":p,"Content-Length":String(n)},body:w.toWeb(a),duplex:"half"})}catch(g){throw i(`storage could not be reached: ${g instanceof Error?g.message:String(g)}`)}finally{a.destroy()}if(await o.body?.cancel().catch(()=>{}),!o.ok)throw i(`storage answered ${o.status} to the upload`)}}}s(L,"createStorageClient");function X(r){return!r||Buffer.byteLength(r,"utf8")>255?"name must be 1-255 bytes":r==="."||r===".."?"name must not be . or ..":/[/\\\u0000-\u001f\u007f]/.test(r)?"name must not contain /, \\, or control characters":null}s(X,"invalidStorageName");export{b as StorageRefused,F as UPLOAD_MAX_BYTES,L as createStorageClient,X as invalidStorageName,J as resetStorageClient,G as storageClient,A as storageConfig};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
var v=Object.defineProperty;var n=(e,t)=>v(e,"name",{value:t,configurable:!0});import{CONDENSED_HISTORY_MODES as u,MOUSE_MODE_DEFAULTS as p,WHIP_MESSAGE_MODES as d}from"../types.js";function i(e,t,o){const s=e.indexOf(t),a=s>=0?s:0;return e[(a+o+e.length)%e.length]}n(i,"cycleChoice");function c(e,t,o){const s=e.indexOf(t);return s>=0?e[(s+o+e.length)%e.length]:o>=0?e.find(a=>a>t)??e[0]:[...e].reverse().find(a=>a<t)??e[e.length-1]}n(c,"cycleNumber");function r(e,t){return e==="true"?!0:e==="false"?!1:`${t} must be true or false`}n(r,"booleanFromString");function f(e,t){if(!/^\d+$/.test(e))return`${t} must be an integer >= 0`;const o=Number(e);return Number.isSafeInteger(o)?o:`${t} must be an integer >= 0`}n(f,"nonNegativeIntegerFromString");function _(e,t){const o=f(e,t);return typeof o=="string"||o<1?`${t} must be an integer >= 1`:o}n(_,"positiveIntegerFromString");const m=[!1,"notify","apply"],w=[0,1,6,12,24,48,72,168],b=[1,2,3,4,5,6,8,10,12],l="openai-codex";function g(e,t){const o=e.providerOptions[t];if(o!==void 0)return o;const s={};return e.providerOptions[t]=s,s}n(g,"providerOptionsFor");const x=[1,2,3,4,5,6],h={schema_version:{surface:"specialized",owner:"internal schema migration"},marketplaces:{surface:"specialized",owner:"Plugins and pkg market commands"},plugins:{surface:"specialized",owner:"Plugins tab and pkg plugin commands"},auto_update:{surface:"settings",settings:{crtr:{key:"auto_update.crtr",label:"crouter updates",description:"Notify about crouter releases, install them automatically, or turn checks off.",valueConstraint:"true|false|notify|apply; true stores notify",applies:"Applies on the next crouter command.",group:"updates",order:70,format:n(e=>e.auto_update.crtr===!1?"off":e.auto_update.crtr,"format"),cycle:n((e,t)=>{e.auto_update.crtr=i(m,e.auto_update.crtr,t)},"cycle"),setFromString:n((e,t)=>{const o=t==="true"?"notify":t;return o!=="notify"&&o!=="apply"&&o!=="false"?"auto_update.crtr must be notify, apply, or false":(e.auto_update.crtr=o==="false"?!1:o,null)},"setFromString")},content:{key:"auto_update.content",label:"Content updates",description:"Notify about plugin and marketplace updates, apply them automatically, or turn checks off.",valueConstraint:"false|notify|apply",applies:"Applies on the next crouter command.",group:"updates",order:80,format:n(e=>e.auto_update.content===!1?"off":e.auto_update.content,"format"),cycle:n((e,t)=>{e.auto_update.content=i(m,e.auto_update.content,t)},"cycle"),setFromString:n((e,t)=>t!=="notify"&&t!=="apply"&&t!=="false"?"auto_update.content must be notify, apply, or false":(e.auto_update.content=t==="false"?!1:t,null),"setFromString")},interval_hours:{key:"auto_update.interval_hours",label:"Update interval",description:"Minimum hours between automatic update checks. Zero checks on every command.",valueConstraint:"integer >= 0",applies:"Applies on the next crouter command.",group:"updates",order:90,format:n(e=>`${e.auto_update.interval_hours}h`,"format"),cycle:n((e,t)=>{e.auto_update.interval_hours=c(w,e.auto_update.interval_hours,t)},"cycle"),setFromString:n((e,t)=>{const o=f(t,"auto_update.interval_hours");return typeof o=="string"?o:(e.auto_update.interval_hours=o,null)},"setFromString")}}},max_panes_per_window:{surface:"settings",setting:{key:"max_panes_per_window",label:"Maximum panes",description:"Maximum human-review panes placed in one tmux window before using another window.",valueConstraint:"integer >= 1",applies:"Applies to the next pane placement.",group:"panes",order:20,format:n(e=>String(e.max_panes_per_window),"format"),cycle:n((e,t)=>{e.max_panes_per_window=c(b,e.max_panes_per_window,t)},"cycle"),setFromString:n((e,t)=>{const o=_(t,"max_panes_per_window");return typeof o=="string"?o:(e.max_panes_per_window=o,null)},"setFromString")}},auto_open_child_viewers:{surface:"settings",setting:{key:"auto_open_child_viewers",label:"Open child panes",description:"Open each managed child beside its watched parent. Off keeps new children running in the background.",valueConstraint:"true|false",applies:"Applies to the next managed child created; independent roots still open their attended viewer.",group:"panes",order:10,format:n(e=>e.auto_open_child_viewers?"on":"off","format"),cycle:n(e=>{e.auto_open_child_viewers=!e.auto_open_child_viewers},"cycle"),setFromString:n((e,t)=>{const o=r(t,"auto_open_child_viewers");return typeof o=="string"?o:(e.auto_open_child_viewers=o,null)},"setFromString")}},brokerThresholds:{surface:"specialized",owner:"Broker limits tab"},lifecycle:{surface:"specialized",owner:"sys config set lifecycle.unattendedParkMs"},completion_bell:{surface:"settings",setting:{key:"completion_bell",label:"Completion bell",description:"Ring a short sound when the node in an attached viewer finishes a turn.",valueConstraint:"true|false",applies:"Applies on the next turn end.",group:"display",order:41,format:n(e=>e.completion_bell?"on":"off","format"),cycle:n(e=>{e.completion_bell=!e.completion_bell},"cycle"),setFromString:n((e,t)=>{const o=r(t,"completion_bell");return typeof o=="string"?o:(e.completion_bell=o,null)},"setFromString")}},working_gerunds:{surface:"specialized",owner:"sys config set working_gerunds"},whip_mode:{surface:"settings",setting:{key:"whip_mode",label:"Whip mode",description:"Play the whip animation when you send a prompt and when a viewer opens for an agent with an initial prompt.",valueConstraint:"true|false",applies:"Applies on the next attach.",group:"display",order:39,format:n(e=>e.whip_mode?"on":"off","format"),cycle:n(e=>{e.whip_mode=!e.whip_mode},"cycle"),setFromString:n((e,t)=>{const o=r(t,"whip_mode");return typeof o=="string"?o:(e.whip_mode=o,null)},"setFromString")}},page_surface:{surface:"settings",setting:{key:"page_surface",label:"Page human surface",description:"This host reads pages in a browser rather than a terminal. Agents are told the page module runs as written, HTML pages are offered, and document review and live display leave the command tree.",valueConstraint:"true|false",applies:"Applies when human command help is assembled.",group:"display",order:37,format:n(e=>e.page_surface?"on":"off","format"),cycle:n(e=>{e.page_surface=!e.page_surface},"cycle"),setFromString:n((e,t)=>{const o=r(t,"page_surface");return typeof o=="string"?o:(e.page_surface=o,null)},"setFromString")}},whip_messages:{surface:"specialized",owner:"sys config set whip_messages"},whip_message_mode:{surface:"settings",setting:{key:"whip_message_mode",label:"Whip message",description:"What the whip action sends: a random line from whip_messages, or the fixed \u201CGo faster\u201D.",valueConstraint:d.join("|"),applies:"Applies on the next attach.",group:"display",order:40,format:n(e=>e.whip_message_mode==="go-faster"?"go faster":"random","format"),cycle:n((e,t)=>{e.whip_message_mode=i(d,e.whip_message_mode,t)},"cycle"),setFromString:n((e,t)=>d.includes(t)?(e.whip_message_mode=t,null):`whip_message_mode must be one of: ${d.join("|")}`,"setFromString")}},mouse_mode_default:{surface:"settings",setting:{key:"mouse_mode_default",label:"Default mouse mode",description:"Initial mouse wheel scrolling for each attached viewer.",valueConstraint:p.join("|"),applies:"Applies on the next attach.",group:"display",order:38,format:n(e=>e.mouse_mode_default==="tmux"?"follow tmux":e.mouse_mode_default,"format"),cycle:n((e,t)=>{e.mouse_mode_default=i(p,e.mouse_mode_default,t)},"cycle"),setFromString:n((e,t)=>p.includes(t)?(e.mouse_mode_default=t,null):`mouse_mode_default must be one of: ${p.join("|")}`,"setFromString")}},live_cycles:{surface:"settings",setting:{key:"live_cycles",label:"Live cycles",description:"Trailing refresh cycles rendered at full fidelity; older cycles condense to text.",valueConstraint:"integer >= 1",applies:"Applies on the next attach.",group:"display",order:50,format:n(e=>String(e.live_cycles),"format"),cycle:n((e,t)=>{e.live_cycles=c(x,e.live_cycles,t)},"cycle"),setFromString:n((e,t)=>{const o=_(t,"live_cycles");return typeof o=="string"?o:(e.live_cycles=o,null)},"setFromString")}},condensed_history:{surface:"settings",setting:{key:"condensed_history",label:"Condensed history",description:"Messages retained from condensed cycles. Tool calls are never kept.",valueConstraint:u.join("|"),applies:"Applies on the next attach.",group:"display",order:60,format:n(e=>e.condensed_history,"format"),cycle:n((e,t)=>{e.condensed_history=i(u,e.condensed_history,t)},"cycle"),setFromString:n((e,t)=>u.includes(t)?(e.condensed_history=t,null):`condensed_history must be one of: ${u.join("|")}`,"setFromString")}},bash_tool_purpose:{surface:"settings",setting:{key:"bash_tool_purpose",label:"Bash purpose field",description:"Expose the optional purpose label to agents in the bash tool schema. Off removes the field without disabling the bash valve.",valueConstraint:"true|false",applies:"Applies on the next node session.",group:"display",order:25,format:n(e=>e.bash_tool_purpose?"on":"off","format"),cycle:n(e=>{e.bash_tool_purpose=!e.bash_tool_purpose},"cycle"),setFromString:n((e,t)=>{const o=r(t,"bash_tool_purpose");return typeof o=="string"?o:(e.bash_tool_purpose=o,null)},"setFromString")}},fold_finished_tools:{surface:"settings",setting:{key:"fold_finished_tools",label:"Fold finished tools",description:"Fold every settled tool call to its call line. Toggle live with /fold-tools.",valueConstraint:"true|false",applies:"Applies on the next attach.",group:"display",order:30,format:n(e=>e.fold_finished_tools?"on":"off","format"),cycle:n(e=>{e.fold_finished_tools=!e.fold_finished_tools},"cycle"),setFromString:n((e,t)=>{const o=r(t,"fold_finished_tools");return typeof o=="string"?o:(e.fold_finished_tools=o,null)},"setFromString")}},summarize_tool_calls:{surface:"settings",setting:{key:"summarize_tool_calls",label:"Summarize tool calls",description:"Replace completed folded tool-call groups with a one-line broker summary when available.",valueConstraint:"true|false",applies:"Applies when the next visible message closes a tool-call group.",group:"display",order:35,format:n(e=>e.summarize_tool_calls?"on":"off","format"),cycle:n(e=>{e.summarize_tool_calls=!e.summarize_tool_calls},"cycle"),setFromString:n((e,t)=>{const o=r(t,"summarize_tool_calls");return typeof o=="string"?o:(e.summarize_tool_calls=o,null)},"setFromString")}},document_port:{surface:"settings",setting:{key:"document_port",label:"Document browser port",description:"Fixed localhost port where crtrd serves editable document pages.",valueConstraint:"1-65535",applies:"Applies after daemon handover and on the next attach.",group:"display",order:37.5,format:n(e=>String(e.document_port),"format"),cycle:n((e,t)=>{e.document_port=Math.max(1,Math.min(65535,e.document_port+t))},"cycle"),setFromString:n((e,t)=>{const o=Number(t);return!/^\d+$/.test(t)||!Number.isInteger(o)||o<1||o>65535?"document_port must be an integer from 1 to 65535":(e.document_port=o,null)},"setFromString")}},detailed_tool_recaps:{surface:"settings",setting:{key:"detailed_tool_recaps",label:"Detailed tool recaps",description:"Show each document read and edited file in folded tool recaps. Off shows a compact count line instead.",valueConstraint:"true|false",applies:"Applies on the next attach.",group:"display",order:36,format:n(e=>e.detailed_tool_recaps?"on":"off","format"),cycle:n(e=>{e.detailed_tool_recaps=!e.detailed_tool_recaps},"cycle"),setFromString:n((e,t)=>{const o=r(t,"detailed_tool_recaps");return typeof o=="string"?o:(e.detailed_tool_recaps=o,null)},"setFromString")}},consolidate_replies:{surface:"settings",setting:{key:"consolidate_replies",label:"Consolidate replies",description:"Experiment: show one rewritten agent reply per message you type, with the working folded behind it (/show-working).",valueConstraint:"true|false",applies:"Applies on the next attach; the broker reads it per turn.",group:"display",order:36.5,format:n(e=>e.consolidate_replies?"on":"off","format"),cycle:n(e=>{e.consolidate_replies=!e.consolidate_replies},"cycle"),setFromString:n((e,t)=>{const o=r(t,"consolidate_replies");return typeof o=="string"?o:(e.consolidate_replies=o,null)},"setFromString")}},keybindings:{surface:"specialized",owner:"Keybindings tab"},tmux_passthrough:{surface:"specialized",owner:"Keybindings tab"},providerOptions:{surface:"settings",settings:{"openai-codex.fastMode":{key:`providerOptions.${l}.fastMode`,label:"Codex fast mode",description:"Serve Codex turns at the ChatGPT priority tier: about 1.5x faster generation for about 2x the credits. Displayed cost does not reflect the premium.",valueConstraint:"true|false",applies:"Applies on each node's next turn.",group:"providers",order:40,format:n(e=>e.providerOptions[l]?.fastMode?"on":"off","format"),cycle:n(e=>{const t=g(e,l);t.fastMode=!t.fastMode},"cycle"),setFromString:n((e,t)=>{const o=r(t,`providerOptions.${l}.fastMode`);return typeof o=="string"?o:(g(e,l).fastMode=o,null)},"setFromString")}}},modelLadders:{surface:"specialized",owner:"Models tab"},modelRoutes:{surface:"specialized",owner:"Models route declarations"},modelRouting:{surface:"specialized",owner:"Models route declarations"},kinds:{surface:"specialized",owner:"Models tab and kind registry"},page_components:{surface:"specialized",owner:"Page component catalog: product-registered page component kinds"},remoteCanvas:{surface:"specialized",owner:"canvas config commands"},api:{surface:"specialized",owner:"sys connect"},paths:{surface:"specialized",owner:"runtime layout"},ledger:{surface:"specialized",owner:"money ledger (take_pct, sandbox rates)"},store:{surface:"specialized",owner:"daemon conversation store"},runtime:{surface:"specialized",owner:"app-facing listener"},spawnEnv:{surface:"specialized",owner:"spawn environment allow-list"},bin:{surface:"specialized",owner:"bare-binary contributions on every node PATH"},humanActions:{surface:"specialized",owner:"scope-configured human completion actions"}},O=Object.keys(h);function S(){const e=[];for(const t of Object.values(h))t.surface==="settings"&&("setting"in t?e.push(t.setting):e.push(...Object.values(t.settings)));return e.sort((t,o)=>t.order-o.order)}n(S,"collectUserSettings");const y=S();function A(e){return y.find(t=>t.key===e)}n(A,"findUserSetting");function z(e){return y.filter(t=>t.group===e)}n(z,"userSettingsInGroup");export{h as CONFIG_SETTINGS_COVERAGE,O as SCOPE_CONFIG_KEYS,y as USER_SETTINGS,A as findUserSetting,z as userSettingsInGroup};
|
|
1
|
+
var v=Object.defineProperty;var n=(e,t)=>v(e,"name",{value:t,configurable:!0});import{CONDENSED_HISTORY_MODES as u,MOUSE_MODE_DEFAULTS as p,WHIP_MESSAGE_MODES as d}from"../types.js";function i(e,t,o){const s=e.indexOf(t),a=s>=0?s:0;return e[(a+o+e.length)%e.length]}n(i,"cycleChoice");function c(e,t,o){const s=e.indexOf(t);return s>=0?e[(s+o+e.length)%e.length]:o>=0?e.find(a=>a>t)??e[0]:[...e].reverse().find(a=>a<t)??e[e.length-1]}n(c,"cycleNumber");function r(e,t){return e==="true"?!0:e==="false"?!1:`${t} must be true or false`}n(r,"booleanFromString");function f(e,t){if(!/^\d+$/.test(e))return`${t} must be an integer >= 0`;const o=Number(e);return Number.isSafeInteger(o)?o:`${t} must be an integer >= 0`}n(f,"nonNegativeIntegerFromString");function _(e,t){const o=f(e,t);return typeof o=="string"||o<1?`${t} must be an integer >= 1`:o}n(_,"positiveIntegerFromString");const m=[!1,"notify","apply"],w=[0,1,6,12,24,48,72,168],b=[1,2,3,4,5,6,8,10,12],l="openai-codex";function g(e,t){const o=e.providerOptions[t];if(o!==void 0)return o;const s={};return e.providerOptions[t]=s,s}n(g,"providerOptionsFor");const x=[1,2,3,4,5,6],h={schema_version:{surface:"specialized",owner:"internal schema migration"},marketplaces:{surface:"specialized",owner:"Plugins and pkg market commands"},plugins:{surface:"specialized",owner:"Plugins tab and pkg plugin commands"},auto_update:{surface:"settings",settings:{crtr:{key:"auto_update.crtr",label:"crouter updates",description:"Notify about crouter releases, install them automatically, or turn checks off.",valueConstraint:"true|false|notify|apply; true stores notify",applies:"Applies on the next crouter command.",group:"updates",order:70,format:n(e=>e.auto_update.crtr===!1?"off":e.auto_update.crtr,"format"),cycle:n((e,t)=>{e.auto_update.crtr=i(m,e.auto_update.crtr,t)},"cycle"),setFromString:n((e,t)=>{const o=t==="true"?"notify":t;return o!=="notify"&&o!=="apply"&&o!=="false"?"auto_update.crtr must be notify, apply, or false":(e.auto_update.crtr=o==="false"?!1:o,null)},"setFromString")},content:{key:"auto_update.content",label:"Content updates",description:"Notify about plugin and marketplace updates, apply them automatically, or turn checks off.",valueConstraint:"false|notify|apply",applies:"Applies on the next crouter command.",group:"updates",order:80,format:n(e=>e.auto_update.content===!1?"off":e.auto_update.content,"format"),cycle:n((e,t)=>{e.auto_update.content=i(m,e.auto_update.content,t)},"cycle"),setFromString:n((e,t)=>t!=="notify"&&t!=="apply"&&t!=="false"?"auto_update.content must be notify, apply, or false":(e.auto_update.content=t==="false"?!1:t,null),"setFromString")},interval_hours:{key:"auto_update.interval_hours",label:"Update interval",description:"Minimum hours between automatic update checks. Zero checks on every command.",valueConstraint:"integer >= 0",applies:"Applies on the next crouter command.",group:"updates",order:90,format:n(e=>`${e.auto_update.interval_hours}h`,"format"),cycle:n((e,t)=>{e.auto_update.interval_hours=c(w,e.auto_update.interval_hours,t)},"cycle"),setFromString:n((e,t)=>{const o=f(t,"auto_update.interval_hours");return typeof o=="string"?o:(e.auto_update.interval_hours=o,null)},"setFromString")}}},max_panes_per_window:{surface:"settings",setting:{key:"max_panes_per_window",label:"Maximum panes",description:"Maximum human-review panes placed in one tmux window before using another window.",valueConstraint:"integer >= 1",applies:"Applies to the next pane placement.",group:"panes",order:20,format:n(e=>String(e.max_panes_per_window),"format"),cycle:n((e,t)=>{e.max_panes_per_window=c(b,e.max_panes_per_window,t)},"cycle"),setFromString:n((e,t)=>{const o=_(t,"max_panes_per_window");return typeof o=="string"?o:(e.max_panes_per_window=o,null)},"setFromString")}},auto_open_child_viewers:{surface:"settings",setting:{key:"auto_open_child_viewers",label:"Open child panes",description:"Open each managed child beside its watched parent. Off keeps new children running in the background.",valueConstraint:"true|false",applies:"Applies to the next managed child created; independent roots still open their attended viewer.",group:"panes",order:10,format:n(e=>e.auto_open_child_viewers?"on":"off","format"),cycle:n(e=>{e.auto_open_child_viewers=!e.auto_open_child_viewers},"cycle"),setFromString:n((e,t)=>{const o=r(t,"auto_open_child_viewers");return typeof o=="string"?o:(e.auto_open_child_viewers=o,null)},"setFromString")}},brokerThresholds:{surface:"specialized",owner:"Broker limits tab"},lifecycle:{surface:"specialized",owner:"sys config set lifecycle.unattendedParkMs"},completion_bell:{surface:"settings",setting:{key:"completion_bell",label:"Completion bell",description:"Ring a short sound when the node in an attached viewer finishes a turn.",valueConstraint:"true|false",applies:"Applies on the next turn end.",group:"display",order:41,format:n(e=>e.completion_bell?"on":"off","format"),cycle:n(e=>{e.completion_bell=!e.completion_bell},"cycle"),setFromString:n((e,t)=>{const o=r(t,"completion_bell");return typeof o=="string"?o:(e.completion_bell=o,null)},"setFromString")}},working_gerunds:{surface:"specialized",owner:"sys config set working_gerunds"},whip_mode:{surface:"settings",setting:{key:"whip_mode",label:"Whip mode",description:"Play the whip animation when you send a prompt and when a viewer opens for an agent with an initial prompt.",valueConstraint:"true|false",applies:"Applies on the next attach.",group:"display",order:39,format:n(e=>e.whip_mode?"on":"off","format"),cycle:n(e=>{e.whip_mode=!e.whip_mode},"cycle"),setFromString:n((e,t)=>{const o=r(t,"whip_mode");return typeof o=="string"?o:(e.whip_mode=o,null)},"setFromString")}},page_surface:{surface:"settings",setting:{key:"page_surface",label:"Page human surface",description:"This host reads pages in a browser rather than a terminal. Agents are told the page module runs as written, HTML pages are offered, and document review and live display leave the command tree.",valueConstraint:"true|false",applies:"Applies when human command help is assembled.",group:"display",order:37,format:n(e=>e.page_surface?"on":"off","format"),cycle:n(e=>{e.page_surface=!e.page_surface},"cycle"),setFromString:n((e,t)=>{const o=r(t,"page_surface");return typeof o=="string"?o:(e.page_surface=o,null)},"setFromString")}},whip_messages:{surface:"specialized",owner:"sys config set whip_messages"},whip_message_mode:{surface:"settings",setting:{key:"whip_message_mode",label:"Whip message",description:"What the whip action sends: a random line from whip_messages, or the fixed \u201CGo faster\u201D.",valueConstraint:d.join("|"),applies:"Applies on the next attach.",group:"display",order:40,format:n(e=>e.whip_message_mode==="go-faster"?"go faster":"random","format"),cycle:n((e,t)=>{e.whip_message_mode=i(d,e.whip_message_mode,t)},"cycle"),setFromString:n((e,t)=>d.includes(t)?(e.whip_message_mode=t,null):`whip_message_mode must be one of: ${d.join("|")}`,"setFromString")}},mouse_mode_default:{surface:"settings",setting:{key:"mouse_mode_default",label:"Default mouse mode",description:"Initial mouse wheel scrolling for each attached viewer.",valueConstraint:p.join("|"),applies:"Applies on the next attach.",group:"display",order:38,format:n(e=>e.mouse_mode_default==="tmux"?"follow tmux":e.mouse_mode_default,"format"),cycle:n((e,t)=>{e.mouse_mode_default=i(p,e.mouse_mode_default,t)},"cycle"),setFromString:n((e,t)=>p.includes(t)?(e.mouse_mode_default=t,null):`mouse_mode_default must be one of: ${p.join("|")}`,"setFromString")}},live_cycles:{surface:"settings",setting:{key:"live_cycles",label:"Live cycles",description:"Trailing refresh cycles rendered at full fidelity; older cycles condense to text.",valueConstraint:"integer >= 1",applies:"Applies on the next attach.",group:"display",order:50,format:n(e=>String(e.live_cycles),"format"),cycle:n((e,t)=>{e.live_cycles=c(x,e.live_cycles,t)},"cycle"),setFromString:n((e,t)=>{const o=_(t,"live_cycles");return typeof o=="string"?o:(e.live_cycles=o,null)},"setFromString")}},condensed_history:{surface:"settings",setting:{key:"condensed_history",label:"Condensed history",description:"Messages retained from condensed cycles. Tool calls are never kept.",valueConstraint:u.join("|"),applies:"Applies on the next attach.",group:"display",order:60,format:n(e=>e.condensed_history,"format"),cycle:n((e,t)=>{e.condensed_history=i(u,e.condensed_history,t)},"cycle"),setFromString:n((e,t)=>u.includes(t)?(e.condensed_history=t,null):`condensed_history must be one of: ${u.join("|")}`,"setFromString")}},bash_tool_purpose:{surface:"settings",setting:{key:"bash_tool_purpose",label:"Bash purpose field",description:"Expose the optional purpose label to agents in the bash tool schema. Off removes the field without disabling the bash valve.",valueConstraint:"true|false",applies:"Applies on the next node session.",group:"display",order:25,format:n(e=>e.bash_tool_purpose?"on":"off","format"),cycle:n(e=>{e.bash_tool_purpose=!e.bash_tool_purpose},"cycle"),setFromString:n((e,t)=>{const o=r(t,"bash_tool_purpose");return typeof o=="string"?o:(e.bash_tool_purpose=o,null)},"setFromString")}},fold_finished_tools:{surface:"settings",setting:{key:"fold_finished_tools",label:"Fold finished tools",description:"Fold every settled tool call to its call line. Toggle live with /fold-tools.",valueConstraint:"true|false",applies:"Applies on the next attach.",group:"display",order:30,format:n(e=>e.fold_finished_tools?"on":"off","format"),cycle:n(e=>{e.fold_finished_tools=!e.fold_finished_tools},"cycle"),setFromString:n((e,t)=>{const o=r(t,"fold_finished_tools");return typeof o=="string"?o:(e.fold_finished_tools=o,null)},"setFromString")}},summarize_tool_calls:{surface:"settings",setting:{key:"summarize_tool_calls",label:"Summarize tool calls",description:"Replace completed folded tool-call groups with a one-line broker summary when available.",valueConstraint:"true|false",applies:"Applies when the next visible message closes a tool-call group.",group:"display",order:35,format:n(e=>e.summarize_tool_calls?"on":"off","format"),cycle:n(e=>{e.summarize_tool_calls=!e.summarize_tool_calls},"cycle"),setFromString:n((e,t)=>{const o=r(t,"summarize_tool_calls");return typeof o=="string"?o:(e.summarize_tool_calls=o,null)},"setFromString")}},document_port:{surface:"settings",setting:{key:"document_port",label:"Document browser port",description:"Fixed localhost port where crtrd serves editable document pages.",valueConstraint:"1-65535",applies:"Applies after daemon handover and on the next attach.",group:"display",order:37.5,format:n(e=>String(e.document_port),"format"),cycle:n((e,t)=>{e.document_port=Math.max(1,Math.min(65535,e.document_port+t))},"cycle"),setFromString:n((e,t)=>{const o=Number(t);return!/^\d+$/.test(t)||!Number.isInteger(o)||o<1||o>65535?"document_port must be an integer from 1 to 65535":(e.document_port=o,null)},"setFromString")}},detailed_tool_recaps:{surface:"settings",setting:{key:"detailed_tool_recaps",label:"Detailed tool recaps",description:"Show each document read and edited file in folded tool recaps. Off shows a compact count line instead.",valueConstraint:"true|false",applies:"Applies on the next attach.",group:"display",order:36,format:n(e=>e.detailed_tool_recaps?"on":"off","format"),cycle:n(e=>{e.detailed_tool_recaps=!e.detailed_tool_recaps},"cycle"),setFromString:n((e,t)=>{const o=r(t,"detailed_tool_recaps");return typeof o=="string"?o:(e.detailed_tool_recaps=o,null)},"setFromString")}},consolidate_replies:{surface:"settings",setting:{key:"consolidate_replies",label:"Consolidate replies",description:"Experiment: show one rewritten agent reply per message you type, with the working folded behind it (/show-working).",valueConstraint:"true|false",applies:"Applies on the next attach; the broker reads it per turn.",group:"display",order:36.5,format:n(e=>e.consolidate_replies?"on":"off","format"),cycle:n(e=>{e.consolidate_replies=!e.consolidate_replies},"cycle"),setFromString:n((e,t)=>{const o=r(t,"consolidate_replies");return typeof o=="string"?o:(e.consolidate_replies=o,null)},"setFromString")}},keybindings:{surface:"specialized",owner:"Keybindings tab"},tmux_passthrough:{surface:"specialized",owner:"Keybindings tab"},providerOptions:{surface:"settings",settings:{"openai-codex.fastMode":{key:`providerOptions.${l}.fastMode`,label:"Codex fast mode",description:"Serve Codex turns at the ChatGPT priority tier: about 1.5x faster generation for about 2x the credits. Displayed cost does not reflect the premium.",valueConstraint:"true|false",applies:"Applies on each node's next turn.",group:"providers",order:40,format:n(e=>e.providerOptions[l]?.fastMode?"on":"off","format"),cycle:n(e=>{const t=g(e,l);t.fastMode=!t.fastMode},"cycle"),setFromString:n((e,t)=>{const o=r(t,`providerOptions.${l}.fastMode`);return typeof o=="string"?o:(g(e,l).fastMode=o,null)},"setFromString")}}},modelLadders:{surface:"specialized",owner:"Models tab"},modelRoutes:{surface:"specialized",owner:"Models route declarations"},modelRouting:{surface:"specialized",owner:"Models route declarations"},kinds:{surface:"specialized",owner:"Models tab and kind registry"},page_components:{surface:"specialized",owner:"Page component catalog: product-registered page component kinds"},remoteCanvas:{surface:"specialized",owner:"canvas config commands"},api:{surface:"specialized",owner:"sys connect"},paths:{surface:"specialized",owner:"runtime layout"},store:{surface:"specialized",owner:"daemon conversation store"},runtime:{surface:"specialized",owner:"app-facing listener"},spawnEnv:{surface:"specialized",owner:"spawn environment allow-list"},bin:{surface:"specialized",owner:"bare-binary contributions on every node PATH"},humanActions:{surface:"specialized",owner:"scope-configured human completion actions"}},O=Object.keys(h);function S(){const e=[];for(const t of Object.values(h))t.surface==="settings"&&("setting"in t?e.push(t.setting):e.push(...Object.values(t.settings)));return e.sort((t,o)=>t.order-o.order)}n(S,"collectUserSettings");const y=S();function A(e){return y.find(t=>t.key===e)}n(A,"findUserSetting");function z(e){return y.filter(t=>t.group===e)}n(z,"userSettingsInGroup");export{h as CONFIG_SETTINGS_COVERAGE,O as SCOPE_CONFIG_KEYS,y as USER_SETTINGS,A as findUserSetting,z as userSettingsInGroup};
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { type IncomingMessage, type ServerResponse } from 'node:http';
|
|
2
|
+
import { AppPrincipalResolver } from './principal.js';
|
|
2
3
|
import { type RequestPrincipal } from './router.js';
|
|
3
4
|
import { type DeferHeadOptions } from './deferred-head.js';
|
|
4
5
|
import type { AppPrincipal } from './principal.js';
|
|
6
|
+
import type { CallToken } from '@north-light/identity';
|
|
5
7
|
import type { ScopeConfig } from '../../types.js';
|
|
6
8
|
import type { GrantSync } from '../../core/grants/sync.js';
|
|
7
9
|
export declare function cursor(req: IncomingMessage, query: URLSearchParams): number;
|
|
@@ -13,6 +15,12 @@ export interface RunStreamOptions {
|
|
|
13
15
|
isRunning?: (runId: string) => Promise<boolean>;
|
|
14
16
|
}
|
|
15
17
|
export declare function streamRunEvents(req: IncomingMessage, res: ServerResponse, id: string, principal: AppPrincipal | RequestPrincipal, after: number, requestId: string, framing: 'sse' | 'ndjson', options?: RunStreamOptions, traceId?: string): Promise<void>;
|
|
18
|
+
/** The app call path as one request handler: version gates, call-token verification (or a `verified` token the caller already checked),
|
|
19
|
+
* the peer ingress, and every `/v1` operation an app may call. The app listener and a cloud role's TCP listener both serve through it. */
|
|
20
|
+
export declare function createAppRequestHandler(principal: AppPrincipalResolver, grantsReady: () => Promise<boolean>, syncGrants: GrantSync, listenerOptions?: {
|
|
21
|
+
deferHead?: DeferHeadOptions;
|
|
22
|
+
stream?: RunStreamOptions;
|
|
23
|
+
}): (req: IncomingMessage, res: ServerResponse, verified?: CallToken) => Promise<void>;
|
|
16
24
|
export declare function createAppListener(config: NonNullable<ScopeConfig['runtime']>, grantsReady: () => Promise<boolean>, syncGrants: GrantSync, listenerOptions?: {
|
|
17
25
|
deferHead?: DeferHeadOptions;
|
|
18
26
|
stream?: RunStreamOptions;
|