@north-light/cli 0.3.511 → 0.3.512

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.
@@ -186,8 +186,8 @@ export declare const chartDataRowsSchema: z.ZodArray<z.ZodRecord<z.ZodString, z.
186
186
  export declare const chartConfigSchema: z.ZodObject<{
187
187
  kind: z.ZodEnum<{
188
188
  line: "line";
189
- bar: "bar";
190
189
  area: "area";
190
+ bar: "bar";
191
191
  }>;
192
192
  x: z.ZodString;
193
193
  y: z.ZodArray<z.ZodObject<{
@@ -1,3 +1,3 @@
1
- var ge=Object.defineProperty;var u=(e,t)=>ge(e,"name",{value:t,configurable:!0});import{randomUUID as be}from"node:crypto";import{streamSimple as ve}from"@earendil-works/pi-ai/compat";import{expandModelCandidates as re,parseModelSpec as se,probeRouteAvailability as we}from"../model-routes.js";import{readMergedLaunchConfig as ie}from"../config.js";import{openModelRegistry as xe}from"../runtime/model-registry.js";import{MAX_RATE_LIMIT_COOLDOWN_MS as ae,coolingUntilFor as de,isManagedProvider as H,markSubscriptionRateLimited as ke,markSubscriptionSuccess as je,readSubscriptionPool as Me,retryAfterMsFromHeaders as K,retryAfterMsFromError as qe,refreshSubscriptionCredential as Ae,subscriptionNeedsSuccessWrite as $e}from"../subscription-state.js";import{classifyRateLimit as Ie,describeRateLimitScope as le,rateLimitHeaders as Re}from"../rate-limit-scope.js";import{RunError as s}from"../runs/operations.js";import{recognizeProviderError as ce}from"../provider-error-recognition.js";import{isSafetyRefusal as Se}from"./refusal.js";import{assertUnderCap as Ce,recordModelUsage as ue}from"../usage/ledger.js";import{outboundToken as Le}from"../providers/mint.js";import{discardFile as Oe}from"../providers/token-cache.js";import{ProviderError as Fe}from"../providers/errors.js";import{appCandidates as Ne}from"./app-rungs.js";function De(e){return typeof e=="string"||e===null||Array.isArray(e)&&e.every(t=>t&&typeof t=="object"&&(t.type==="text"&&typeof t.text=="string"||t.type==="image_url"&&typeof t.image_url?.url=="string"&&/^data:image\/(png|jpeg|gif|webp);base64,[A-Za-z0-9+/]+={0,2}$/.test(t.image_url.url)))}u(De,"validContent");function fe(e){return Array.isArray(e)?e.map(t=>{if(t.type==="text")return t;const[,n,r]=/^data:(image\/(?:png|jpeg|gif|webp));base64,(.*)$/.exec(t.image_url.url);return{type:"image",mimeType:n,data:r}}):e??""}u(fe,"imageContent");function st(e){if(!e||typeof e!="object"||Array.isArray(e))throw new s(400,"invalid_request","body must be an object");const t=e;if(!Array.isArray(t.messages)||!t.messages.every(n=>n&&typeof n=="object"&&["system","user","assistant","tool"].includes(n.role)&&De(n.content)))throw new s(400,"invalid_request","messages must be chat messages","messages");if(t.messages.some(n=>["system","assistant"].includes(n.role)&&typeof n.content!="string"&&n.content!==null))throw new s(400,"invalid_request","system and assistant content must be text","messages");if(t.model!==void 0&&typeof t.model!="string")throw new s(400,"invalid_request","model must be a string","model");if(t.model_policy!==void 0&&!["exact","substitute"].includes(t.model_policy))throw new s(400,"invalid_request","invalid model_policy","model_policy");if(t.payer!==void 0&&!["user","app"].includes(t.payer))throw new s(400,"invalid_request","invalid payer","payer");if(t.reasoning_effort!==void 0&&!["minimal","low","medium","high","xhigh","max"].includes(t.reasoning_effort))throw new s(400,"invalid_request","invalid reasoning_effort","reasoning_effort");if(t.stream!==void 0&&typeof t.stream!="boolean")throw new s(400,"invalid_request","stream must be boolean","stream");if(t.tools!==void 0&&(!Array.isArray(t.tools)||!t.tools.every(n=>n?.type==="function"&&typeof n.function?.name=="string"&&n.function.name.length>0&&(n.function.description===void 0||typeof n.function.description=="string")&&(n.function.parameters===void 0||n.function.parameters!==null&&typeof n.function.parameters=="object"&&!Array.isArray(n.function.parameters)&&n.function.parameters.type==="object"))))throw new s(400,"invalid_request","invalid tools","tools");if(t.tool_choice!==void 0&&t.tool_choice!=="auto"&&t.tool_choice!=="none"&&t.tool_choice!=="required"&&(typeof t.tool_choice!="object"||t.tool_choice===null||t.tool_choice.type!=="function"||typeof t.tool_choice.function?.name!="string"))throw new s(400,"invalid_request","invalid tool_choice","tool_choice");if(t.messages.some(n=>n.role==="assistant"&&n.tool_calls!==void 0&&(!Array.isArray(n.tool_calls)||!n.tool_calls.every(r=>r&&typeof r.id=="string"&&typeof r.function?.name=="string"&&typeof r.function.arguments=="string"&&Ee(r.function.arguments)))))throw new s(400,"invalid_request","invalid assistant tool_calls","messages");if(t.stop!==void 0&&!(typeof t.stop=="string"||Array.isArray(t.stop)&&t.stop.every(n=>typeof n=="string")))throw new s(400,"invalid_request","invalid stop","stop");if(t.seed!==void 0&&!Number.isSafeInteger(t.seed))throw new s(400,"invalid_request","invalid seed","seed");for(const[n,r]of[["temperature",t.temperature],["top_p",t.top_p],["max_tokens",t.max_tokens]])if(r!==void 0&&(typeof r!="number"||!Number.isFinite(r)||n==="temperature"&&(r<0||r>2)||n==="top_p"&&(r<0||r>1)||n==="max_tokens"&&(!Number.isSafeInteger(r)||r<1)))throw new s(400,"invalid_request",`invalid ${n}`,n);if(t.response_format!==void 0){const n=t.response_format;if(!n||typeof n!="object"||Array.isArray(n)||!["text","json_object","json_schema"].includes(n.type)||n.type==="json_schema"&&(typeof n.json_schema?.name!="string"||!n.json_schema.name||!n.json_schema.schema||typeof n.json_schema.schema!="object"||Array.isArray(n.json_schema.schema)))throw new s(400,"invalid_request","invalid response_format","response_format")}if(t.metadata!==void 0&&Buffer.byteLength(JSON.stringify(t.metadata)??"")>4096)throw new s(400,"invalid_request","metadata exceeds 4 KB","metadata");return t}u(st,"parseLlmRequest");function Ee(e){try{const t=JSON.parse(e);return t!==null&&typeof t=="object"&&!Array.isArray(t)}catch{return!1}}u(Ee,"isJsonObject");function Pe(e){const t=Date.now(),n=e.messages.map(i=>i.role==="system"?{role:"system",content:i.content??"",timestamp:t}:i.role==="tool"?{role:"toolResult",toolCallId:i.tool_call_id??"",toolName:"",content:typeof i.content=="string"||i.content===null?[{type:"text",text:i.content??""}]:fe(i.content),isError:!1,timestamp:t}:i.role==="assistant"?{role:"assistant",content:[...i.content?[{type:"text",text:i.content}]:[],...(i.tool_calls??[]).map(g=>({type:"toolCall",id:g.id,name:g.function.name,arguments:JSON.parse(g.function.arguments)}))],api:"openai-completions",provider:"openai",model:e.model??"",usage:{input:0,output:0,cacheRead:0,cacheWrite:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}},stopReason:"stop",timestamp:t}:{role:"user",content:fe(i.content),timestamp:t}),r=n.findIndex(i=>i.role!=="system"),w=n.slice(0,r<0?n.length:r).map(i=>i.content),y=w.join(`
1
+ var ge=Object.defineProperty;var u=(e,t)=>ge(e,"name",{value:t,configurable:!0});import{randomUUID as be}from"node:crypto";import{streamSimple as ve}from"@earendil-works/pi-ai/compat";import{expandModelCandidates as re,parseModelSpec as ie,probeRouteAvailability as we}from"../model-routes.js";import{readMergedLaunchConfig as se}from"../config.js";import{openModelRegistry as xe}from"../runtime/model-registry.js";import{MAX_RATE_LIMIT_COOLDOWN_MS as ae,coolingUntilFor as de,isManagedProvider as H,markSubscriptionRateLimited as ke,markSubscriptionSuccess as je,readSubscriptionPool as Me,retryAfterMsFromHeaders as K,retryAfterMsFromError as Ae,refreshSubscriptionCredential as qe,subscriptionNeedsSuccessWrite as Re}from"../subscription-state.js";import{classifyRateLimit as $e,describeRateLimitScope as le,rateLimitHeaders as Ie}from"../rate-limit-scope.js";import{RunError as i}from"../runs/operations.js";import{recognizeProviderError as ce}from"../provider-error-recognition.js";import{isSafetyRefusal as Ce}from"./refusal.js";import{assertUnderCap as Oe,recordModelUsage as ue}from"../usage/ledger.js";import{outboundToken as Se}from"../providers/mint.js";import{discardFile as Le}from"../providers/token-cache.js";import{ProviderError as Ee}from"../providers/errors.js";import{appCandidates as Ne}from"./app-rungs.js";function De(e){return typeof e=="string"||e===null||Array.isArray(e)&&e.every(t=>t&&typeof t=="object"&&(t.type==="text"&&typeof t.text=="string"||t.type==="image_url"&&typeof t.image_url?.url=="string"&&/^data:image\/(png|jpeg|gif|webp);base64,[A-Za-z0-9+/]+={0,2}$/.test(t.image_url.url)))}u(De,"validContent");function fe(e){return Array.isArray(e)?e.map(t=>{if(t.type==="text")return t;const[,n,r]=/^data:(image\/(?:png|jpeg|gif|webp));base64,(.*)$/.exec(t.image_url.url);return{type:"image",mimeType:n,data:r}}):e??""}u(fe,"imageContent");function at(e){if(!e||typeof e!="object"||Array.isArray(e))throw new i(400,"invalid_request","body must be an object");const t=e;if(!Array.isArray(t.messages)||!t.messages.every(n=>n&&typeof n=="object"&&["system","user","assistant","tool"].includes(n.role)&&De(n.content)))throw new i(400,"invalid_request","messages must be chat messages","messages");if(t.messages.some(n=>["system","assistant"].includes(n.role)&&typeof n.content!="string"&&n.content!==null))throw new i(400,"invalid_request","system and assistant content must be text","messages");if(t.model!==void 0&&typeof t.model!="string")throw new i(400,"invalid_request","model must be a string","model");if(t.model_policy!==void 0&&!["exact","substitute"].includes(t.model_policy))throw new i(400,"invalid_request","invalid model_policy","model_policy");if(t.payer!==void 0&&!["user","app"].includes(t.payer))throw new i(400,"invalid_request","invalid payer","payer");if(t.reasoning_effort!==void 0&&!["minimal","low","medium","high","xhigh","max"].includes(t.reasoning_effort))throw new i(400,"invalid_request","invalid reasoning_effort","reasoning_effort");if(t.stream!==void 0&&typeof t.stream!="boolean")throw new i(400,"invalid_request","stream must be boolean","stream");if(t.tools!==void 0&&(!Array.isArray(t.tools)||!t.tools.every(n=>n?.type==="function"&&typeof n.function?.name=="string"&&n.function.name.length>0&&(n.function.description===void 0||typeof n.function.description=="string")&&(n.function.parameters===void 0||n.function.parameters!==null&&typeof n.function.parameters=="object"&&!Array.isArray(n.function.parameters)&&n.function.parameters.type==="object"))))throw new i(400,"invalid_request","invalid tools","tools");if(t.tool_choice!==void 0&&t.tool_choice!=="auto"&&t.tool_choice!=="none"&&t.tool_choice!=="required"&&(typeof t.tool_choice!="object"||t.tool_choice===null||t.tool_choice.type!=="function"||typeof t.tool_choice.function?.name!="string"))throw new i(400,"invalid_request","invalid tool_choice","tool_choice");if(t.messages.some(n=>n.role==="assistant"&&n.tool_calls!==void 0&&(!Array.isArray(n.tool_calls)||!n.tool_calls.every(r=>r&&typeof r.id=="string"&&typeof r.function?.name=="string"&&typeof r.function.arguments=="string"&&Fe(r.function.arguments)))))throw new i(400,"invalid_request","invalid assistant tool_calls","messages");if(t.stop!==void 0&&!(typeof t.stop=="string"||Array.isArray(t.stop)&&t.stop.every(n=>typeof n=="string")))throw new i(400,"invalid_request","invalid stop","stop");if(t.seed!==void 0&&!Number.isSafeInteger(t.seed))throw new i(400,"invalid_request","invalid seed","seed");for(const[n,r]of[["temperature",t.temperature],["top_p",t.top_p],["max_tokens",t.max_tokens]])if(r!==void 0&&(typeof r!="number"||!Number.isFinite(r)||n==="temperature"&&(r<0||r>2)||n==="top_p"&&(r<0||r>1)||n==="max_tokens"&&(!Number.isSafeInteger(r)||r<1)))throw new i(400,"invalid_request",`invalid ${n}`,n);if(t.response_format!==void 0){const n=t.response_format;if(!n||typeof n!="object"||Array.isArray(n)||!["text","json_object","json_schema"].includes(n.type)||n.type==="json_schema"&&(typeof n.json_schema?.name!="string"||!n.json_schema.name||!n.json_schema.schema||typeof n.json_schema.schema!="object"||Array.isArray(n.json_schema.schema)))throw new i(400,"invalid_request","invalid response_format","response_format")}if(t.metadata!==void 0&&Buffer.byteLength(JSON.stringify(t.metadata)??"")>4096)throw new i(400,"invalid_request","metadata exceeds 4 KB","metadata");return t}u(at,"parseLlmRequest");function Fe(e){try{const t=JSON.parse(e);return t!==null&&typeof t=="object"&&!Array.isArray(t)}catch{return!1}}u(Fe,"isJsonObject");function Te(e){const t=Date.now(),n=e.messages.map(s=>s.role==="system"?{role:"system",content:s.content??"",timestamp:t}:s.role==="tool"?{role:"toolResult",toolCallId:s.tool_call_id??"",toolName:"",content:typeof s.content=="string"||s.content===null?[{type:"text",text:s.content??""}]:fe(s.content),isError:!1,timestamp:t}:s.role==="assistant"?{role:"assistant",content:[...s.content?[{type:"text",text:s.content}]:[],...(s.tool_calls??[]).map(g=>({type:"toolCall",id:g.id,name:g.function.name,arguments:JSON.parse(g.function.arguments)}))],api:"openai-completions",provider:"openai",model:e.model??"",usage:{input:0,output:0,cacheRead:0,cacheWrite:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}},stopReason:"stop",timestamp:t}:{role:"user",content:fe(s.content),timestamp:t}),r=n.findIndex(s=>s.role!=="system"),w=n.slice(0,r<0?n.length:r).map(s=>s.content),y=w.join(`
2
2
 
3
- `),l=e.tools?.map(({function:i})=>({name:i.name,description:i.description??"",parameters:i.parameters??{type:"object",properties:{}}}));return{...y?{systemPrompt:y}:{},messages:n.slice(w.length),...l?{tools:l}:{}}}u(Pe,"contextOf");function me(e,t,n,r){if(!e){const y=ie(n,r),l=Object.values({...y.modelRoutes??{},...y.legacyModelRoutes??{}}),i=l.length?[y.modelLadders.defaultProvider,...y.modelRouting?.familyOrder??[],...l.map(g=>g.family)].find(g=>l.some(F=>F.family===g)):y.modelLadders.defaultProvider??"anthropic";return{kind:"logical",family:i,strength:"strong",spec:`${i}/strong`}}const w=/^([^/]+)\/(ultra|strong|medium|light)$/.exec(e);return w?{kind:"logical",family:w[1],strength:w[2],spec:e}:{kind:t==="exact"?"exact":"concrete",spec:e}}u(me,"requestFor");function Te(e,t){const{input:n,output:r,cacheRead:w,cacheWrite:y}=e.cost;return n===0&&r===0&&w===0&&y===0?null:Number.isFinite(t)&&t>=0?t:null}u(Te,"usdEquivalent");function Ue(e,t){return e.compat?.allowedFallbackModels?.find(r=>r.provider===e.provider&&r.model===t)}u(Ue,"allowedFallback");function it(e){return e?{payer:e.payer??"user",sub:e.sub,grantee:e.grantee,inference_endpoint:e.inference_endpoint??null}:void 0}u(it,"llmCallerOf");function Je(e){return e instanceof Fe?e.code==="server_error"?new s(503,"upstream_model_unavailable",e.message):new s(404,"model_unavailable",e.message):e}u(Je,"mintFailure");async function at(e,t,n,r,w,y){const l=y?.payer==="app"?y:void 0;if(e.payer==="app"&&!l)throw new s(403,"payer_not_app","this grant is not app-paid");if(e.payer==="user"&&l)throw new s(400,"invalid_request","this grant is app-paid; payer cannot be user","payer");if(l&&!l.inference_endpoint)throw new s(404,"model_unavailable",`${l.grantee} is app-paid but its grant carries no inference endpoint`);const i=l?.inference_endpoint??void 0;l||Ce(w);const g=await xe(),F=u(c=>c.routeId!=="concrete"&&c.routeId!=="exact","configured"),Y=u(c=>{const p=g.find(c.providerId,c.modelId);return p!==void 0&&(!e.reasoning_effort||p.reasoning)&&(e.seed===void 0&&e.response_format===void 0||p.api==="openai-completions")&&(e.stop===void 0||["openai-completions","anthropic-messages"].includes(p.api))},"matchesFeatures"),pe=u(()=>{const c=me(e.model,e.model_policy,r?.cwd,r?.profileId),p=re(c.kind==="exact"?{kind:"concrete",spec:c.spec}:c,r?.cwd,r?.profileId).filter(F);let a;if(c.kind==="logical")a=e.model_policy==="exact"?p.filter(m=>m.family===c.family&&m.strength===c.strength).slice(0,1):p;else{const m=se(c.spec),A=p.filter(j=>j.providerId===m?.providerId&&j.modelId===m.modelId&&(e.model_policy!=="exact"||j.thinkingLevel===m.thinkingLevel)&&Y(j));if(e.model_policy==="exact")a=A.slice(0,1);else if(A.length)a=A;else{const j=ie(r?.cwd,r?.profileId),x=[...Object.values(j.modelRoutes??{}).flatMap(v=>Object.entries(v.models)),...[j.modelLadders.anthropic,j.modelLadders.openai].flatMap(v=>Object.entries(v))].find(([,v])=>v===c.spec)?.[0],f=me(void 0,"substitute",r?.cwd,r?.profileId);a=x&&f.kind==="logical"?re({...f,strength:x,spec:c.spec},r?.cwd,r?.profileId).filter(v=>F(v)&&v.strength===x):[]}}return a},"ownerCandidates");let I;if(i?I=Ne(i,e.model,e.model_policy==="exact").flatMap((c,p)=>{const a=se(c.model);return a?[{routeId:"app",credentialSource:"app",family:"app",strength:c.strength,...a,rank:p}]:[]}):I=pe(),I=I.filter(Y),I.length===0)throw e.model_policy==="exact"?new s(400,"substitution_refused","no eligible model route is configured"):new s(404,"model_unavailable","no eligible model route is configured");const ee=`chatcmpl-${be()}`;let R=1/0,b,z;for(const c of I){if(!l&&!we(c,g).authenticated)continue;const p=g.find(c.providerId,c.modelId);if(!p)continue;const a=i?{...p,baseUrl:`${i.base_url}/${p.provider}`}:p,m=c.providerId,A=!l&&H(m)?Me(m).filter(x=>!x.authFailure):[],j=A.filter(x=>de(x,a.id)<=Date.now());if(A.length&&!j.length){const x=Math.min(...A.map(f=>de(f,a.id)));x<R&&(R=x,z=`${a.provider}/${a.id}`);continue}const te=l?[void 0,void 0]:A.length?j:[void 0];for(const[x,f]of te.entries()){const v=Date.now();let oe=f?.access;if(f&&f.expires<=Date.now()&&H(m)){const o=g.getProvider(m)?.auth.oauth;if(!o)throw new s(503,"upstream_model_unavailable",`no OAuth refresh for ${m}`,void 0,{served_model:`${a.provider}/${a.id}`});oe=(await Ae(m,f.label,async(k,ne)=>{const W=await o.refresh({type:"oauth",refresh:k,access:"",expires:0,...ne?{clientId:ne}:{}},t??new AbortController().signal),V=W.clientId;return{refresh:W.refresh,access:W.access,expires:W.expires,...typeof V=="string"&&V?{clientId:V}:{}}})).access}const he=Pe(e);let N;if(l&&i)try{N=await Le({audience:i.base_url,sub:l.sub,grantee:l.grantee,initiating_app:l.grantee,scope:["crtr:llm"]},{signal:t})}catch(o){throw Je(o)}const S=f||l?void 0:await g.getApiKeyAndHeaders(a);if(S&&!S.ok)continue;const h=`${a.provider}/${a.id}`,C=e.model??h;let q=!1,O,M=3e4,$;const B=[],X=[],D=[];let d,E;const P=u((o,_=null)=>({id:ee,object:"chat.completion.chunk",created:Math.floor(v/1e3),model:h,served_model:h,requested_model:C,substituted:C!==h&&!/^([^/]+)\/(ultra|strong|medium|light)$/.test(C),choices:[{index:0,delta:o,finish_reason:_}]}),"chunk"),T=u(o=>{B.push(o),n?.(o)},"emit"),_e=ve(a,he,{apiKey:N?.access_token??oe??(S?.ok?S.apiKey:void 0),...S?.ok?{headers:S.headers}:{},signal:t,reasoning:e.reasoning_effort??c.thinkingLevel,...e.temperature!==void 0?{temperature:e.temperature}:{},...e.max_tokens!==void 0?{maxTokens:e.max_tokens}:{},...e.top_p!==void 0?{samplingParams:{top_p:e.top_p}}:{},...e.tool_choice==="none"?{toolChoice:"none"}:{},onPayload:u(o=>{if(!o||typeof o!="object")return;const _=e.tool_choice,k=_==="required"?a.api==="anthropic-messages"?{type:"any"}:"required":typeof _=="object"&&_!==null?a.api==="anthropic-messages"?{type:"tool",name:_.function.name}:_:void 0;return{...o,...k?{tool_choice:k}:{},...e.stop!==void 0?{[a.api==="anthropic-messages"?"stop_sequences":"stop"]:typeof e.stop=="string"?[e.stop]:e.stop}:{},...e.seed!==void 0?{seed:e.seed}:{},...e.response_format!==void 0?{response_format:e.response_format}:{}}},"onPayload"),fetch:u(async(o,_)=>{const k=await fetch(o,_);return O=k.status,k.status===429&&(q=!0,$=k.headers,M=K(k.headers)??15e3),k},"fetch"),onResponse:u(o=>{o.status===429&&(q=!0,$=o.headers,M=K(o.headers)??15e3)},"onResponse")});try{for await(const o of _e)o.type==="text_delta"&&(X.push(o.delta),T(P({content:o.delta}))),o.type==="thinking_delta"&&(D.push(o.delta),T(P({reasoning_content:o.delta}))),o.type==="done"&&(d=o.message),o.type==="error"&&(d=o.error)}catch(o){const _=qe(o);$===void 0&&o&&typeof o=="object"&&"headers"in o&&Object.keys(Re(o.headers)).length&&($=o.headers);const k=ce({status:o&&typeof o=="object"&&"status"in o?o.status:void 0,message:o instanceof Error?o.message:String(o)});if(l)E=o;else{if(!q&&k.kind!=="rate-limit")throw B.length?new s(503,"upstream_model_unavailable",o instanceof Error?o.message:String(o),void 0,{served_model:h}):o;q=!0,M=_??M}}if(l){if(O===401){if(N&&Oe(N.key),x===0)continue;throw new s(404,"model_unavailable",`${i.base_url} refuses this runtime's tokens`,void 0,{served_model:h})}if(q&&K($)===void 0)throw new s(503,"upstream_model_unavailable",`${h} was rate-limited without a retry-after`,void 0,{served_model:h});if(!q&&(E!==void 0||O!==void 0&&O>=500))throw new s(503,"upstream_model_unavailable",E instanceof Error?E.message:d?.errorMessage??"inference endpoint failed",void 0,{served_model:h})}if(!q&&d?.stopReason==="error"&&ce({message:d.errorMessage}).kind==="rate-limit"&&(q=!0,M=15e3),q){const o=Ie($,a.id);if(K($)===void 0&&o.resetAt!==void 0&&(M=Math.max(M,o.resetAt-Date.now())),b={provider:m,model:a.id,...f?{account:f.label}:{},observation:o},console.error(`[llm] 429 from ${h}${f?` account "${f.label}"`:""}: scope=${le(o.scope)} retry_after_ms=${M} headers=${JSON.stringify(o.headers)}`),f&&H(m)&&await ke(m,f.label,M,v,Date.now(),o.scope),Date.now()+Math.min(M,ae)<R&&(R=Date.now()+Math.min(M,ae),z=h),X.length||D.length)throw new s(503,"service_unavailable","vendor rate limit after output began",void 0,{served_model:h});if(l)break;continue}const U=Se(d);if(O===400&&e.tool_choice!==void 0&&e.tool_choice!=="auto"&&e.tool_choice!=="none"&&/\btool[_ ]choice\b/i.test(d?.errorMessage??"")&&/not supported|does not support|unsupported|cannot|must be auto/i.test(d?.errorMessage??""))throw new s(400,"invalid_request",d.errorMessage,"tool_choice",{served_model:h});if(!d||d.stopReason==="error"&&!U||d.stopReason==="aborted")throw new s(503,"upstream_model_unavailable",d?.errorMessage??"model request failed",void 0,{served_model:h});f&&H(m)&&$e(f,a.id)&&await je(m,f.label,v,a.id);const Z=d.content.filter(o=>o.type==="toolCall").map(o=>({id:o.id,type:"function",function:{name:o.name,arguments:JSON.stringify(o.arguments)}})),G=U?"content_filter":d.stopReason==="toolUse"?"tool_calls":d.stopReason==="length"?"length":"stop",Q=d.responseModel?Ue(a,d.responseModel):void 0,L=Q?`${a.provider}/${Q.model}`:h,J={prompt_tokens:d.usage.input,completion_tokens:d.usage.output,total_tokens:d.usage.totalTokens,cache_read_tokens:d.usage.cacheRead,cache_write_tokens:d.usage.cacheWrite,usd_equivalent:Te(Q??a,d.usage.cost.total),served_model:L};l?ue(l.grantee,"app",L,d.usage,J.usd_equivalent):w&&ue(w.grantee,"user",L,d.usage,J.usd_equivalent);const ye={id:ee,object:"chat.completion",created:Math.floor(v/1e3),model:L,served_model:L,requested_model:C,substituted:C!==L&&!/^([^/]+)\/(ultra|strong|medium|light)$/.test(C),choices:[{index:0,message:{role:"assistant",content:X.join("")||null,...D.length?{reasoning_content:D.join("")}:{},...Z.length?{tool_calls:Z}:{},...U?{refusal:d.errorMessage??"Content filtered"}:{}},finish_reason:G}],usage:J,...e.metadata!==void 0?{metadata:e.metadata}:{}};for(const[o,_]of Z.entries())T(P({tool_calls:[{index:o,..._}]}));return T({...P({},G),...U?{choices:[{index:0,delta:{},finish_reason:G,message:{refusal:d.errorMessage??"Content filtered"}}]}:{},usage:J}),{completion:ye,chunks:B}}}throw R!==1/0?new s(429,"all_routes_exhausted","all eligible model routes are rate-limited",void 0,{retry_after_s:Math.max(1,Math.ceil((R-Date.now())/1e3)),served_model:b?`${b.provider}/${b.model}`:z,...b?{rate_limit:{provider:b.provider,model:b.model,...b.account?{account:b.account}:{},scope:le(b.observation.scope),...b.observation.claim?{claim:b.observation.claim}:{},headers:b.observation.headers}}:{}},void 0,!0):e.model_policy==="exact"?new s(400,"substitution_refused","the requested model is unavailable"):new s(404,"model_unavailable","no usable model route is available")}u(at,"runLlm");export{it as llmCallerOf,st as parseLlmRequest,at as runLlm};
3
+ `),l=e.tools?.map(({function:s})=>({name:s.name,description:s.description??"",parameters:s.parameters??{type:"object",properties:{}}}));return{...y?{systemPrompt:y}:{},messages:n.slice(w.length),...l?{tools:l}:{}}}u(Te,"contextOf");function me(e,t,n,r){if(!e){const y=se(n,r),l=Object.values({...y.modelRoutes??{},...y.legacyModelRoutes??{}}),s=l.length?[y.modelLadders.defaultProvider,...y.modelRouting?.familyOrder??[],...l.map(g=>g.family)].find(g=>l.some(E=>E.family===g)):y.modelLadders.defaultProvider??"anthropic";return{kind:"logical",family:s,strength:"strong",spec:`${s}/strong`}}const w=/^([^/]+)\/(ultra|strong|medium|light)$/.exec(e);return w?{kind:"logical",family:w[1],strength:w[2],spec:e}:{kind:t==="exact"?"exact":"concrete",spec:e}}u(me,"requestFor");function Pe(e,t){const{input:n,output:r,cacheRead:w,cacheWrite:y}=e.cost;return n===0&&r===0&&w===0&&y===0?null:Number.isFinite(t)&&t>=0?t:null}u(Pe,"usdEquivalent");function Ue(e,t){return e.compat?.allowedFallbackModels?.find(r=>r.provider===e.provider&&r.model===t)}u(Ue,"allowedFallback");function dt(e){return e?{payer:e.payer??"user",sub:e.sub,grantee:e.grantee,inference_endpoint:e.inference_endpoint??null}:void 0}u(dt,"llmCallerOf");function Je(e){return e instanceof Ee?e.code==="server_error"?new i(503,"upstream_model_unavailable",e.message):new i(404,"model_unavailable",e.message):e}u(Je,"mintFailure");const We=/\bmodel is not supported when using Codex with a ChatGPT account\b/i;function He(e,t,n){if(!(e!=="openai-codex"||t===void 0||!We.test(t)))return new i(404,"model_unavailable",t,void 0,{served_model:n})}u(He,"codexAccountModelRejection");async function lt(e,t,n,r,w,y){const l=y?.payer==="app"?y:void 0;if(e.payer==="app"&&!l)throw new i(403,"payer_not_app","this grant is not app-paid");if(e.payer==="user"&&l)throw new i(400,"invalid_request","this grant is app-paid; payer cannot be user","payer");if(l&&!l.inference_endpoint)throw new i(404,"model_unavailable",`${l.grantee} is app-paid but its grant carries no inference endpoint`);const s=l?.inference_endpoint??void 0;l||Oe(w);const g=await xe(),E=u(c=>c.routeId!=="concrete"&&c.routeId!=="exact","configured"),Y=u(c=>{const h=g.find(c.providerId,c.modelId);return h!==void 0&&(!e.reasoning_effort||h.reasoning)&&(e.seed===void 0&&e.response_format===void 0||h.api==="openai-completions")&&(e.stop===void 0||["openai-completions","anthropic-messages"].includes(h.api))},"matchesFeatures"),pe=u(()=>{const c=me(e.model,e.model_policy,r?.cwd,r?.profileId),h=re(c.kind==="exact"?{kind:"concrete",spec:c.spec}:c,r?.cwd,r?.profileId).filter(E);let a;if(c.kind==="logical")a=e.model_policy==="exact"?h.filter(m=>m.family===c.family&&m.strength===c.strength).slice(0,1):h;else{const m=ie(c.spec),q=h.filter(j=>j.providerId===m?.providerId&&j.modelId===m.modelId&&(e.model_policy!=="exact"||j.thinkingLevel===m.thinkingLevel)&&Y(j));if(e.model_policy==="exact")a=q.slice(0,1);else if(q.length)a=q;else{const j=se(r?.cwd,r?.profileId),x=[...Object.values(j.modelRoutes??{}).flatMap(v=>Object.entries(v.models)),...[j.modelLadders.anthropic,j.modelLadders.openai].flatMap(v=>Object.entries(v))].find(([,v])=>v===c.spec)?.[0],f=me(void 0,"substitute",r?.cwd,r?.profileId);a=x&&f.kind==="logical"?re({...f,strength:x,spec:c.spec},r?.cwd,r?.profileId).filter(v=>E(v)&&v.strength===x):[]}}return a},"ownerCandidates");let $;if(s?$=Ne(s,e.model,e.model_policy==="exact").flatMap((c,h)=>{const a=ie(c.model);return a?[{routeId:"app",credentialSource:"app",family:"app",strength:c.strength,...a,rank:h}]:[]}):$=pe(),$=$.filter(Y),$.length===0)throw e.model_policy==="exact"?new i(400,"substitution_refused","no eligible model route is configured"):new i(404,"model_unavailable","no eligible model route is configured");const ee=`chatcmpl-${be()}`;let I=1/0,b,z;for(const c of $){if(!l&&!we(c,g).authenticated)continue;const h=g.find(c.providerId,c.modelId);if(!h)continue;const a=s?{...h,baseUrl:`${s.base_url}/${h.provider}`}:h,m=c.providerId,q=!l&&H(m)?Me(m).filter(x=>!x.authFailure):[],j=q.filter(x=>de(x,a.id)<=Date.now());if(q.length&&!j.length){const x=Math.min(...q.map(f=>de(f,a.id)));x<I&&(I=x,z=`${a.provider}/${a.id}`);continue}const te=l?[void 0,void 0]:q.length?j:[void 0];for(const[x,f]of te.entries()){const v=Date.now();let oe=f?.access;if(f&&f.expires<=Date.now()&&H(m)){const o=g.getProvider(m)?.auth.oauth;if(!o)throw new i(503,"upstream_model_unavailable",`no OAuth refresh for ${m}`,void 0,{served_model:`${a.provider}/${a.id}`});oe=(await qe(m,f.label,async(k,ne)=>{const W=await o.refresh({type:"oauth",refresh:k,access:"",expires:0,...ne?{clientId:ne}:{}},t??new AbortController().signal),V=W.clientId;return{refresh:W.refresh,access:W.access,expires:W.expires,...typeof V=="string"&&V?{clientId:V}:{}}})).access}const he=Te(e);let N;if(l&&s)try{N=await Se({audience:s.base_url,sub:l.sub,grantee:l.grantee,initiating_app:l.grantee,scope:["crtr:llm"]},{signal:t})}catch(o){throw Je(o)}const C=f||l?void 0:await g.getApiKeyAndHeaders(a);if(C&&!C.ok)continue;const p=`${a.provider}/${a.id}`,O=e.model??p;let A=!1,L,M=3e4,R;const B=[],X=[],D=[];let d,F;const T=u((o,_=null)=>({id:ee,object:"chat.completion.chunk",created:Math.floor(v/1e3),model:p,served_model:p,requested_model:O,substituted:O!==p&&!/^([^/]+)\/(ultra|strong|medium|light)$/.test(O),choices:[{index:0,delta:o,finish_reason:_}]}),"chunk"),P=u(o=>{B.push(o),n?.(o)},"emit"),_e=ve(a,he,{apiKey:N?.access_token??oe??(C?.ok?C.apiKey:void 0),...C?.ok?{headers:C.headers}:{},signal:t,reasoning:e.reasoning_effort??c.thinkingLevel,...e.temperature!==void 0?{temperature:e.temperature}:{},...e.max_tokens!==void 0?{maxTokens:e.max_tokens}:{},...e.top_p!==void 0?{samplingParams:{top_p:e.top_p}}:{},...e.tool_choice==="none"?{toolChoice:"none"}:{},onPayload:u(o=>{if(!o||typeof o!="object")return;const _=e.tool_choice,k=_==="required"?a.api==="anthropic-messages"?{type:"any"}:"required":typeof _=="object"&&_!==null?a.api==="anthropic-messages"?{type:"tool",name:_.function.name}:_:void 0;return{...o,...k?{tool_choice:k}:{},...e.stop!==void 0?{[a.api==="anthropic-messages"?"stop_sequences":"stop"]:typeof e.stop=="string"?[e.stop]:e.stop}:{},...e.seed!==void 0?{seed:e.seed}:{},...e.response_format!==void 0?{response_format:e.response_format}:{}}},"onPayload"),fetch:u(async(o,_)=>{const k=await fetch(o,_);return L=k.status,k.status===429&&(A=!0,R=k.headers,M=K(k.headers)??15e3),k},"fetch"),onResponse:u(o=>{o.status===429&&(A=!0,R=o.headers,M=K(o.headers)??15e3)},"onResponse")});try{for await(const o of _e)o.type==="text_delta"&&(X.push(o.delta),P(T({content:o.delta}))),o.type==="thinking_delta"&&(D.push(o.delta),P(T({reasoning_content:o.delta}))),o.type==="done"&&(d=o.message),o.type==="error"&&(d=o.error)}catch(o){const _=Ae(o);R===void 0&&o&&typeof o=="object"&&"headers"in o&&Object.keys(Ie(o.headers)).length&&(R=o.headers);const k=ce({status:o&&typeof o=="object"&&"status"in o?o.status:void 0,message:o instanceof Error?o.message:String(o)});if(l)F=o;else{if(!A&&k.kind!=="rate-limit")throw B.length?new i(503,"upstream_model_unavailable",o instanceof Error?o.message:String(o),void 0,{served_model:p}):o;A=!0,M=_??M}}if(l){if(L===401){if(N&&Le(N.key),x===0)continue;throw new i(404,"model_unavailable",`${s.base_url} refuses this runtime's tokens`,void 0,{served_model:p})}if(A&&K(R)===void 0)throw new i(503,"upstream_model_unavailable",`${p} was rate-limited without a retry-after`,void 0,{served_model:p});if(!A&&(F!==void 0||L!==void 0&&L>=500))throw new i(503,"upstream_model_unavailable",F instanceof Error?F.message:d?.errorMessage??"inference endpoint failed",void 0,{served_model:p})}if(!A&&d?.stopReason==="error"&&ce({message:d.errorMessage}).kind==="rate-limit"&&(A=!0,M=15e3),A){const o=$e(R,a.id);if(K(R)===void 0&&o.resetAt!==void 0&&(M=Math.max(M,o.resetAt-Date.now())),b={provider:m,model:a.id,...f?{account:f.label}:{},observation:o},console.error(`[llm] 429 from ${p}${f?` account "${f.label}"`:""}: scope=${le(o.scope)} retry_after_ms=${M} headers=${JSON.stringify(o.headers)}`),f&&H(m)&&await ke(m,f.label,M,v,Date.now(),o.scope),Date.now()+Math.min(M,ae)<I&&(I=Date.now()+Math.min(M,ae),z=p),X.length||D.length)throw new i(503,"service_unavailable","vendor rate limit after output began",void 0,{served_model:p});if(l)break;continue}const U=Ce(d);if(L===400&&e.tool_choice!==void 0&&e.tool_choice!=="auto"&&e.tool_choice!=="none"&&/\btool[_ ]choice\b/i.test(d?.errorMessage??"")&&/not supported|does not support|unsupported|cannot|must be auto/i.test(d?.errorMessage??""))throw new i(400,"invalid_request",d.errorMessage,"tool_choice",{served_model:p});if(d?.stopReason==="error"){const o=He(a.provider,d.errorMessage,p);if(o)throw o}if(!d||d.stopReason==="error"&&!U||d.stopReason==="aborted")throw new i(503,"upstream_model_unavailable",d?.errorMessage??"model request failed",void 0,{served_model:p});f&&H(m)&&Re(f,a.id)&&await je(m,f.label,v,a.id);const G=d.content.filter(o=>o.type==="toolCall").map(o=>({id:o.id,type:"function",function:{name:o.name,arguments:JSON.stringify(o.arguments)}})),Z=U?"content_filter":d.stopReason==="toolUse"?"tool_calls":d.stopReason==="length"?"length":"stop",Q=d.responseModel?Ue(a,d.responseModel):void 0,S=Q?`${a.provider}/${Q.model}`:p,J={prompt_tokens:d.usage.input,completion_tokens:d.usage.output,total_tokens:d.usage.totalTokens,cache_read_tokens:d.usage.cacheRead,cache_write_tokens:d.usage.cacheWrite,usd_equivalent:Pe(Q??a,d.usage.cost.total),served_model:S};l?ue(l.grantee,"app",S,d.usage,J.usd_equivalent):w&&ue(w.grantee,"user",S,d.usage,J.usd_equivalent);const ye={id:ee,object:"chat.completion",created:Math.floor(v/1e3),model:S,served_model:S,requested_model:O,substituted:O!==S&&!/^([^/]+)\/(ultra|strong|medium|light)$/.test(O),choices:[{index:0,message:{role:"assistant",content:X.join("")||null,...D.length?{reasoning_content:D.join("")}:{},...G.length?{tool_calls:G}:{},...U?{refusal:d.errorMessage??"Content filtered"}:{}},finish_reason:Z}],usage:J,...e.metadata!==void 0?{metadata:e.metadata}:{}};for(const[o,_]of G.entries())P(T({tool_calls:[{index:o,..._}]}));return P({...T({},Z),...U?{choices:[{index:0,delta:{},finish_reason:Z,message:{refusal:d.errorMessage??"Content filtered"}}]}:{},usage:J}),{completion:ye,chunks:B}}}throw I!==1/0?new i(429,"all_routes_exhausted","all eligible model routes are rate-limited",void 0,{retry_after_s:Math.max(1,Math.ceil((I-Date.now())/1e3)),served_model:b?`${b.provider}/${b.model}`:z,...b?{rate_limit:{provider:b.provider,model:b.model,...b.account?{account:b.account}:{},scope:le(b.observation.scope),...b.observation.claim?{claim:b.observation.claim}:{},headers:b.observation.headers}}:{}},void 0,!0):e.model_policy==="exact"?new i(400,"substitution_refused","the requested model is unavailable"):new i(404,"model_unavailable","no usable model route is available")}u(lt,"runLlm");export{dt as llmCallerOf,at as parseLlmRequest,lt as runLlm};
@@ -1,2 +1,2 @@
1
- var W=Object.defineProperty;var d=(e,t)=>W(e,"name",{value:t,configurable:!0});import{setTimeout as j}from"node:timers/promises";import{createAssistantMessageEventStream as J,getCurrentSystemPrompt as Y,getCurrentTools as z}from"@earendil-works/pi-ai";import{socketFetch as X}from"../../../api/node-transport.js";import{apiSocketPath as G}from"../../canvas/paths.js";import{currentNodeToken as H}from"./node-token.js";import{envModelExact as $,envModelIntent as K}from"../../../shared/env.js";import{MODEL_CONTEXT_BODY_MAX_BYTES as v}from"../../llm/body-limits.js";import{modelRequestFromConfig as V}from"../../model-routes.js";import{parseProviderRateLimit as Q,providerFailureDiagnostic as E}from"../../provider-failure.js";import{UPSTREAM_MODEL_UNAVAILABLE as b}from"../../fault-classifier.js";function me(e,t){e.checkAuth=async n=>e.getProvider(n)?{type:"api_key"}:void 0,e.getAvailable=async n=>e.getModels(n),e.getAvailableSnapshot=()=>e.getModels(),e.streamSimple=(n,c,r)=>ne(n,c,r,t)}d(me,"configureBrokerModelRuntime");const Z=300,C="crtr:llm-refusal";class R extends Error{static{d(this,"LlmRefusalError")}retryAt;rateLimit;code;status;constructor(t,n,c,r,o){super(t),this.retryAt=n,this.rateLimit=c,this.code=r,this.status=o}}class S extends Error{static{d(this,"UpstreamModelUnavailableError")}}function N(e,t){const n=e===void 0?"the request body":`the request body (${e} bytes)`;return new Error(`request_too_large: ${n} exceeds the ${t}-byte model request limit; compact the conversation to shrink the context`)}d(N,"contextTooLargeError");function D(e){const t=e.details?.rate_limit;if(!t||typeof t!="object")return;const n=Q(t);if(n===void 0)return;const{provider:c,model:r}=t;return typeof c=="string"&&c!==""&&typeof r=="string"&&r!==""?{...n,model:`${c}/${r}`}:n}d(D,"refusalRateLimit");function he(e){for(const t of e.diagnostics??[]){if(t.type!==C)continue;const n=t.details?.retryAt;if(typeof n=="number"&&Number.isFinite(n)&&n>0)return n}}d(he,"refusalRetryAt");class q extends Error{static{d(this,"ContentFilteredError")}}function B(e){return typeof e=="string"?e:e.map(t=>t.type==="text"?{type:"text",text:t.text}:{type:"image_url",image_url:{url:`data:${t.mimeType};base64,${t.data}`}})}d(B,"wireContent");function ee(e){const t=d(r=>r.role==="assistant"&&(r.stopReason==="error"||r.stopReason==="aborted"),"incomplete"),n=e.some(t)?e.filter(r=>!t(r)):e;let c=n.length;for(;c>0&&n[c-1]?.role==="assistant";)c--;return c===n.length?n:n.slice(0,c)}d(ee,"wireHistory");function te(e,t,n,c){const r=[],o=Y(t.messages),i=z(t.messages);o?r.push({role:"system",content:o}):t.systemPrompt&&r.push({role:"system",content:t.systemPrompt});for(const p of ee(t.messages))p.role==="user"?r.push({role:"user",content:B(p.content)}):p.role==="toolResult"?r.push({role:"tool",content:B(p.content),tool_call_id:p.toolCallId}):p.role==="assistant"&&r.push({role:"assistant",content:p.content.filter(u=>u.type==="text").map(u=>u.text).join("")||null,tool_calls:p.content.filter(u=>u.type==="toolCall").map(u=>({id:u.id,type:"function",function:{name:u.name,arguments:JSON.stringify(u.arguments)}}))});const x=`${e.provider}/${e.id}`,_=c??K();return{model:V(x,_,$())?.kind==="logical"?_:x,model_policy:$()?"exact":"substitute",stream:!0,messages:r,...i.length?{tools:i.map(p=>({type:"function",function:{name:p.name,description:p.description,parameters:p.parameters}}))}:{},...n.reasoning?{reasoning_effort:n.reasoning}:{},...n.temperature!==void 0?{temperature:n.temperature}:{},...n.maxTokens!==void 0?{max_tokens:n.maxTokens}:{}}}d(te,"requestBody");function A(e,t){if(typeof t!="string")return!1;const n=t.indexOf("/");return n<1||n===t.length-1?!1:(e.provider=t.slice(0,n),e.model=t.slice(n+1),!0)}d(A,"applyServedModel");function F(e){if(e.details?.served_model!==void 0)return e.details.served_model;const t=e.details?.rate_limit;return typeof t?.provider=="string"&&typeof t.model=="string"?`${t.provider}/${t.model}`:void 0}d(F,"refusalRoute");function P(e){if(!e||typeof e!="object"||!("error"in e))throw new Error("llm returned an invalid response");const t=e.error;if(!t||typeof t.message!="string")throw new Error("llm returned an invalid refusal");return t}d(P,"parseRefusal");function ne(e,t,n={},c){const r=J(),o={role:"assistant",content:[],api:e.api,provider:e.provider,model:e.id,usage:{input:0,output:0,cacheRead:0,cacheWrite:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}},stopReason:"pending",timestamp:Date.now()};return(async()=>{const i=H();if(!i)throw new Error("llm requires a node token");const x=JSON.stringify(te(e,t,n,c)),_=Buffer.byteLength(x);if(_>v)throw N(_,v);let p=0;for(;;){n.signal?.throwIfAborted();const u=await X(G())("http://localhost/v1/llm",{method:"POST",headers:{authorization:`Bearer ${i}`,"content-type":"application/json"},body:x,signal:n.signal});if(!u.ok){const l=P(await u.json());if(u.status===413||l.code==="payload_too_large")throw N(_,v);if(A(o,F(l)),l.retryable!==!0)throw new R(l.message,void 0,D(l),l.code,u.status);const s=l.retry_after_s;if(typeof s!="number"||!Number.isFinite(s)||s<=0)throw l.code===b?new S(l.message):new Error(l.message);const m=Z-p;if(s>m){const f=Date.now()+s*1e3;throw new R(`${l.message} (retry after ${s}s, at ${new Date(f).toISOString()})`,f,D(l))}await j(s*1e3,void 0,{signal:n.signal}),p+=s;continue}if(!u.body)throw new Error("llm returned no stream");r.push({type:"start",partial:o});const U=u.body.getReader(),L=new TextDecoder;let g="",w="stop",I,M=!1,T=!1;const O=d(l=>{const s=JSON.parse(l);if(s.error){const a=P(s);throw A(o,F(a)),a.code===b?new S(a.message):new Error(a.message)}if(s.served_model){if(T=!0,s.served_model.indexOf("/")<1)throw new Error("llm returned an invalid served_model");A(o,s.served_model)}const m=s.choices?.[0],f=m?.delta;if(f?.reasoning_content){const a=o.content.findIndex(k=>k.type==="thinking"),h=a<0?{type:"thinking",thinking:""}:o.content[a],y=a<0?o.content.push(h)-1:a;if(a<0&&r.push({type:"thinking_start",contentIndex:y,partial:o}),h.type!=="thinking")throw new Error("invalid thinking block");h.thinking+=f.reasoning_content,r.push({type:"thinking_delta",contentIndex:y,delta:f.reasoning_content,partial:o})}if(f?.content){const a=o.content.findIndex(k=>k.type==="text"),h=a<0?{type:"text",text:""}:o.content[a],y=a<0?o.content.push(h)-1:a;if(a<0&&r.push({type:"text_start",contentIndex:y,partial:o}),h.type!=="text")throw new Error("invalid text block");h.text+=f.content,r.push({type:"text_delta",contentIndex:y,delta:f.content,partial:o})}for(const a of f?.tool_calls??[]){const h={type:"toolCall",id:a.id,name:a.function.name,arguments:JSON.parse(a.function.arguments)},y=o.content.push(h)-1;r.push({type:"toolcall_start",contentIndex:y,partial:o}),r.push({type:"toolcall_end",contentIndex:y,toolCall:h,partial:o})}m?.finish_reason&&(w=m.finish_reason),m?.message?.refusal&&(I=m.message.refusal),s.usage&&(M=!0,o.usage={input:s.usage.prompt_tokens,output:s.usage.completion_tokens,cacheRead:s.usage.cache_read_tokens,cacheWrite:s.usage.cache_write_tokens,totalTokens:s.usage.total_tokens,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:typeof s.usage.usd_equivalent=="number"&&Number.isFinite(s.usage.usd_equivalent)?s.usage.usd_equivalent:0}})},"apply");for(;;){const{value:l,done:s}=await U.read();if(s)break;g+=L.decode(l,{stream:!0});let m;for(;(m=g.indexOf(`
2
- `))>=0;){const f=g.slice(0,m).trim();g=g.slice(m+1),f&&O(f)}}if(g+=L.decode(),g.trim()&&O(g.trim()),!M||!T)throw new Error("llm stream ended without usage or served_model");for(const[l,s]of o.content.entries())s.type==="text"&&r.push({type:"text_end",contentIndex:l,content:s.text,partial:o}),s.type==="thinking"&&r.push({type:"thinking_end",contentIndex:l,content:s.thinking,partial:o});if(w==="content_filter")throw new q(I??"Content filtered");if(!["stop","tool_calls","length"].includes(w))throw new Error(`llm returned unknown finish reason: ${w}`);o.stopReason=w==="tool_calls"?"toolUse":w==="length"?"length":"stop",r.push({type:"done",reason:o.stopReason,message:o}),r.end();return}})().catch(i=>{o.stopReason=n.signal?.aborted?"aborted":"error",o.errorMessage=i instanceof Error?i.message:String(i),i instanceof R&&(o.diagnostics=[{type:C,timestamp:Date.now(),...i.retryAt!==void 0?{details:{retryAt:i.retryAt}}:{}},...i.rateLimit!==void 0?[E({status:429,ratelimit:i.rateLimit})]:[],...i.rateLimit===void 0&&i.code==="cap_exhausted"?[E({status:i.status??402,code:i.code})]:[]]),i instanceof S&&(o.diagnostics=[E({status:503,code:b})]),i instanceof q&&o.stopReason==="error"&&(o.rawStopReason="content_filter"),r.push({type:"error",reason:o.stopReason,error:o}),r.end()}),r}d(ne,"streamBrokerModel");export{Z as LLM_BROKER_RETRY_WINDOW_S,C as LLM_REFUSAL_DIAGNOSTIC,me as configureBrokerModelRuntime,he as refusalRetryAt,te as requestBody,ne as streamBrokerModel,ee as wireHistory};
1
+ var W=Object.defineProperty;var d=(e,t)=>W(e,"name",{value:t,configurable:!0});import{setTimeout as j}from"node:timers/promises";import{createAssistantMessageEventStream as J,getCurrentSystemPrompt as Y,getCurrentTools as z}from"@earendil-works/pi-ai";import{socketFetch as X}from"../../../api/node-transport.js";import{apiSocketPath as G}from"../../canvas/paths.js";import{currentNodeToken as H}from"./node-token.js";import{envModelExact as C,envModelIntent as K}from"../../../shared/env.js";import{MODEL_CONTEXT_BODY_MAX_BYTES as E}from"../../llm/body-limits.js";import{modelRequestFromConfig as V}from"../../model-routes.js";import{parseProviderRateLimit as Q,providerFailureDiagnostic as b}from"../../provider-failure.js";import{UPSTREAM_MODEL_UNAVAILABLE as R}from"../../fault-classifier.js";function me(e,t){e.checkAuth=async n=>e.getProvider(n)?{type:"api_key"}:void 0,e.getAvailable=async n=>e.getModels(n),e.getAvailableSnapshot=()=>e.getModels(),e.streamSimple=(n,c,r)=>ne(n,c,r,t)}d(me,"configureBrokerModelRuntime");const Z=300,N="crtr:llm-refusal";class k extends Error{static{d(this,"LlmRefusalError")}retryAt;rateLimit;code;status;constructor(t,n,c,r,o){super(t),this.retryAt=n,this.rateLimit=c,this.code=r,this.status=o}}class S extends Error{static{d(this,"UpstreamModelUnavailableError")}}function D(e,t){const n=e===void 0?"the request body":`the request body (${e} bytes)`;return new Error(`request_too_large: ${n} exceeds the ${t}-byte model request limit; compact the conversation to shrink the context`)}d(D,"contextTooLargeError");function A(e){const t=e.details?.rate_limit;if(!t||typeof t!="object")return;const n=Q(t);if(n===void 0)return;const{provider:c,model:r}=t;return typeof c=="string"&&c!==""&&typeof r=="string"&&r!==""?{...n,model:`${c}/${r}`}:n}d(A,"refusalRateLimit");function he(e){for(const t of e.diagnostics??[]){if(t.type!==N)continue;const n=t.details?.retryAt;if(typeof n=="number"&&Number.isFinite(n)&&n>0)return n}}d(he,"refusalRetryAt");class q extends Error{static{d(this,"ContentFilteredError")}}function B(e){return typeof e=="string"?e:e.map(t=>t.type==="text"?{type:"text",text:t.text}:{type:"image_url",image_url:{url:`data:${t.mimeType};base64,${t.data}`}})}d(B,"wireContent");function ee(e){const t=d(r=>r.role==="assistant"&&(r.stopReason==="error"||r.stopReason==="aborted"),"incomplete"),n=e.some(t)?e.filter(r=>!t(r)):e;let c=n.length;for(;c>0&&n[c-1]?.role==="assistant";)c--;return c===n.length?n:n.slice(0,c)}d(ee,"wireHistory");function te(e,t,n,c){const r=[],o=Y(t.messages),a=z(t.messages);o?r.push({role:"system",content:o}):t.systemPrompt&&r.push({role:"system",content:t.systemPrompt});for(const p of ee(t.messages))p.role==="user"?r.push({role:"user",content:B(p.content)}):p.role==="toolResult"?r.push({role:"tool",content:B(p.content),tool_call_id:p.toolCallId}):p.role==="assistant"&&r.push({role:"assistant",content:p.content.filter(u=>u.type==="text").map(u=>u.text).join("")||null,tool_calls:p.content.filter(u=>u.type==="toolCall").map(u=>({id:u.id,type:"function",function:{name:u.name,arguments:JSON.stringify(u.arguments)}}))});const x=`${e.provider}/${e.id}`,_=c??K();return{model:V(x,_,C())?.kind==="logical"?_:x,model_policy:C()?"exact":"substitute",stream:!0,messages:r,...a.length?{tools:a.map(p=>({type:"function",function:{name:p.name,description:p.description,parameters:p.parameters}}))}:{},...n.reasoning?{reasoning_effort:n.reasoning}:{},...n.temperature!==void 0?{temperature:n.temperature}:{},...n.maxTokens!==void 0?{max_tokens:n.maxTokens}:{}}}d(te,"requestBody");function L(e,t){if(typeof t!="string")return!1;const n=t.indexOf("/");return n<1||n===t.length-1?!1:(e.provider=t.slice(0,n),e.model=t.slice(n+1),!0)}d(L,"applyServedModel");function F(e){if(e.details?.served_model!==void 0)return e.details.served_model;const t=e.details?.rate_limit;return typeof t?.provider=="string"&&typeof t.model=="string"?`${t.provider}/${t.model}`:void 0}d(F,"refusalRoute");function P(e){if(!e||typeof e!="object"||!("error"in e))throw new Error("llm returned an invalid response");const t=e.error;if(!t||typeof t.message!="string")throw new Error("llm returned an invalid refusal");return t}d(P,"parseRefusal");function ne(e,t,n={},c){const r=J(),o={role:"assistant",content:[],api:e.api,provider:e.provider,model:e.id,usage:{input:0,output:0,cacheRead:0,cacheWrite:0,totalTokens:0,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:0}},stopReason:"pending",timestamp:Date.now()};return(async()=>{const a=H();if(!a)throw new Error("llm requires a node token");const x=JSON.stringify(te(e,t,n,c)),_=Buffer.byteLength(x);if(_>E)throw D(_,E);let p=0;for(;;){n.signal?.throwIfAborted();const u=await X(G())("http://localhost/v1/llm",{method:"POST",headers:{authorization:`Bearer ${a}`,"content-type":"application/json"},body:x,signal:n.signal});if(!u.ok){const l=P(await u.json());if(u.status===413||l.code==="payload_too_large")throw D(_,E);if(L(o,F(l)),l.retryable!==!0)throw new k(l.message,void 0,A(l),l.code,u.status);const s=l.retry_after_s;if(typeof s!="number"||!Number.isFinite(s)||s<=0)throw l.code===R?new S(l.message):new Error(l.message);const m=Z-p;if(s>m){const f=Date.now()+s*1e3;throw new k(`${l.message} (retry after ${s}s, at ${new Date(f).toISOString()})`,f,A(l))}await j(s*1e3,void 0,{signal:n.signal}),p+=s;continue}if(!u.body)throw new Error("llm returned no stream");r.push({type:"start",partial:o});const U=u.body.getReader(),I=new TextDecoder;let g="",w="stop",M,T=!1,O=!1;const $=d(l=>{const s=JSON.parse(l);if(s.error){const i=P(s);throw L(o,F(i)),i.retryable!==!0?new k(i.message,void 0,A(i),i.code):i.code===R?new S(i.message):new Error(i.message)}if(s.served_model){if(O=!0,s.served_model.indexOf("/")<1)throw new Error("llm returned an invalid served_model");L(o,s.served_model)}const m=s.choices?.[0],f=m?.delta;if(f?.reasoning_content){const i=o.content.findIndex(v=>v.type==="thinking"),h=i<0?{type:"thinking",thinking:""}:o.content[i],y=i<0?o.content.push(h)-1:i;if(i<0&&r.push({type:"thinking_start",contentIndex:y,partial:o}),h.type!=="thinking")throw new Error("invalid thinking block");h.thinking+=f.reasoning_content,r.push({type:"thinking_delta",contentIndex:y,delta:f.reasoning_content,partial:o})}if(f?.content){const i=o.content.findIndex(v=>v.type==="text"),h=i<0?{type:"text",text:""}:o.content[i],y=i<0?o.content.push(h)-1:i;if(i<0&&r.push({type:"text_start",contentIndex:y,partial:o}),h.type!=="text")throw new Error("invalid text block");h.text+=f.content,r.push({type:"text_delta",contentIndex:y,delta:f.content,partial:o})}for(const i of f?.tool_calls??[]){const h={type:"toolCall",id:i.id,name:i.function.name,arguments:JSON.parse(i.function.arguments)},y=o.content.push(h)-1;r.push({type:"toolcall_start",contentIndex:y,partial:o}),r.push({type:"toolcall_end",contentIndex:y,toolCall:h,partial:o})}m?.finish_reason&&(w=m.finish_reason),m?.message?.refusal&&(M=m.message.refusal),s.usage&&(T=!0,o.usage={input:s.usage.prompt_tokens,output:s.usage.completion_tokens,cacheRead:s.usage.cache_read_tokens,cacheWrite:s.usage.cache_write_tokens,totalTokens:s.usage.total_tokens,cost:{input:0,output:0,cacheRead:0,cacheWrite:0,total:typeof s.usage.usd_equivalent=="number"&&Number.isFinite(s.usage.usd_equivalent)?s.usage.usd_equivalent:0}})},"apply");for(;;){const{value:l,done:s}=await U.read();if(s)break;g+=I.decode(l,{stream:!0});let m;for(;(m=g.indexOf(`
2
+ `))>=0;){const f=g.slice(0,m).trim();g=g.slice(m+1),f&&$(f)}}if(g+=I.decode(),g.trim()&&$(g.trim()),!T||!O)throw new Error("llm stream ended without usage or served_model");for(const[l,s]of o.content.entries())s.type==="text"&&r.push({type:"text_end",contentIndex:l,content:s.text,partial:o}),s.type==="thinking"&&r.push({type:"thinking_end",contentIndex:l,content:s.thinking,partial:o});if(w==="content_filter")throw new q(M??"Content filtered");if(!["stop","tool_calls","length"].includes(w))throw new Error(`llm returned unknown finish reason: ${w}`);o.stopReason=w==="tool_calls"?"toolUse":w==="length"?"length":"stop",r.push({type:"done",reason:o.stopReason,message:o}),r.end();return}})().catch(a=>{o.stopReason=n.signal?.aborted?"aborted":"error",o.errorMessage=a instanceof Error?a.message:String(a),a instanceof k&&(o.diagnostics=[{type:N,timestamp:Date.now(),...a.retryAt!==void 0?{details:{retryAt:a.retryAt}}:{}},...a.rateLimit!==void 0?[b({status:429,ratelimit:a.rateLimit})]:[],...a.rateLimit===void 0&&a.code==="cap_exhausted"?[b({status:a.status??402,code:a.code})]:[]]),a instanceof S&&(o.diagnostics=[b({status:503,code:R})]),a instanceof q&&o.stopReason==="error"&&(o.rawStopReason="content_filter"),r.push({type:"error",reason:o.stopReason,error:o}),r.end()}),r}d(ne,"streamBrokerModel");export{Z as LLM_BROKER_RETRY_WINDOW_S,N as LLM_REFUSAL_DIAGNOSTIC,me as configureBrokerModelRuntime,he as refusalRetryAt,te as requestBody,ne as streamBrokerModel,ee as wireHistory};
@@ -1 +1 @@
1
- var J=Object.defineProperty;var a=(e,t)=>J(e,"name",{value:t,configurable:!0});import{envHomeOverride as K,envRuntimeHomeOverride as X,INBOX_BETWEEN_TURNS_ENV as z,SCOPES_FILE_ENV as V,scopeAllowed as C}from"../../shared/env.js";import{isOwnMemoryScope as Y,validateScopes as Q}from"../scopes.js";import{activeGrant as B,terminalGrant as k}from"../grants/mirror.js";import{appendRunEvent as Z}from"../runs/events.js";import{readConfig as S}from"../config.js";import{InputError as T}from"../io.js";import{ApiError as w}from"../../api/errors.js";import{assertGranteeRunsHere as ee}from"./unsandboxed.js";import{randomBytes as ne}from"node:crypto";import{existsSync as P}from"node:fs";import{resolve as re,relative as te,isAbsolute as H,join as ie,sep as oe}from"node:path";import{appSpace as le}from"../layout.js";import{scopesFilePath as ae}from"../canvas/paths.js";import{createNode as se,assertRunNotDeleting as de,conversationOwner as ue,getNode as c,getRow as ce}from"../canvas/index.js";import{ensureAppSpace as fe}from"../spaces/space.js";import{LAUNCHER_SOCKET as L}from"../../launcher/spec.js";import{resolveInstallId as pe}from"../canvas/install-id.js";import{isAppRun as me}from"../canvas/app-run.js";import{canvasDbPath as _e,contextDir as ge}from"../canvas/paths.js";import{conversationIdFromPath as we}from"../conversation-store/index.js";import{usage as U}from"../errors.js";import{assertProfileAvailableForBirth as he}from"../profiles/deletion-reservation.js";import{loadExactProfileManifest as ve}from"../profiles/manifest.js";import{admitNodeCreate as Re}from"../command-hooks/lifecycle-create.js";import{getById as Ee,nodeObject as I,ownerForGrantee as ye}from"../graph/objects.js";import{recordActedOn as Ce}from"../graph/edges.js";import{recordWatch as Ie,copyWatchesForFork as Ne}from"../graph/watches.js";import{publish as ke}from"../graph/events.js";let O;const j=new Map;function cn(e){O=e}a(cn,"setInstallId");function Se(){if(O!==void 0)return O;const e=_e(),t=j.get(e);if(t!==void 0)return t;const o=pe();return j.set(e,o),o}a(Se,"installId");function Te(){return`${Date.now().toString(36)}-${ne(4).toString("hex")}`}a(Te,"newJobId");function Oe(){return`${Se()}-${Te()}`}a(Oe,"newNodeId");const x=128,xe=/^[a-z0-9-]+$/;class q extends Error{static{a(this,"NodeIdConflictError")}nodeId;constructor(t){super(`node already exists: ${t}`),this.nodeId=t,this.name="NodeIdConflictError"}}function D(e){if(e.length===0||e.length>x)throw U(`invalid --node-id '${e}': must be 1-${x} characters`,{next:`Pass an id-safe string (lowercase letters, digits, hyphens) of at most ${x} characters.`});if(!xe.test(e))throw U(`invalid --node-id '${e}': must contain only lowercase letters, digits, and hyphens (e.g. 'remote42', 'my-node-1')`,{next:"Use only lowercase letters, digits, and hyphens."})}a(D,"validateNodeIdFormat");function fn(e){if(D(e),c(e)!==null)throw new q(e)}a(fn,"preflightNodeId");function De(e){if(D(e),c(e)!==null)throw new q(e);return e}a(De,"validatedExplicitNodeId");function pn(e){let t=e;const o=new Set;for(;;){if(o.has(t))return t;o.add(t);const s=ce(t);if(s===null||s.parent==null)return t;t=s.parent}}a(pn,"rootOfSpine");function mn(){const e=process.env;return{nodeId:e.CRTR_NODE_ID??null,kind:e.CRTR_KIND??null,mode:e.CRTR_MODE??null}}a(mn,"currentNodeContext");function be(e){return me(e)}a(be,"inboxBetweenTurns");function _n(e){const t={CRTR_NODE_ID:e.node_id,CRTR_KIND:e.kind,CRTR_MODE:e.mode,CRTR_LIFECYCLE:e.lifecycle,CRTR_NODE_CWD:e.cwd,CRTR_CONTEXT_DIR:ge(e.node_id,e.grantee),CRTR_CYCLES:(e.cycles??0).toString(),CRTR_PROFILE_ID:e.profile_id??"",PI_CLAUDE_OAUTH_REINJECT_SCOPE:"never"};e.parent&&(t.CRTR_PARENT_NODE_ID=e.parent),e.run_id&&(t.CRTR_RUN_ID=e.run_id),be(e)&&(t[z]="1"),e.scopes!==null&&e.scopes!==void 0&&(t[V]=ae(e.node_id)),t.CRTR_GRANTEE=e.grantee??"app:terminal";const o=K();o!==void 0&&o!==""&&(t.CRTR_HOME=o);const s=X();s!==void 0&&s!==""&&(t.CRTR_RUNTIME_HOME=s);const f=process.env.CRTR_SUBTREE;return f!==void 0&&f!==""&&(t.CRTR_SUBTREE=f),{...t,...e.launch?.env??{}}}a(_n,"nodeEnv");function Ae(e){const t=we(e),o=t===null?null:ue(t);return o===null?null:c(o)}a(Ae,"forkSourceNode");async function gn(e){const t=e.nodeId!==void 0?(D(e.nodeId),e.nodeId):Oe(),o=e.parent??null,s=o===null,f=e.spawnedBy??o,m=e.creator??null,b=e.mode??"base",N=e.lifecycle??(s?"resident":"terminal"),h=e.run===void 0?k():null,n={node_id:t,name:e.name??e.kind,description:e.description,cycles:0,created:new Date().toISOString(),cwd:e.cwd,host_kind:"broker",profile_id:e.profile_id??null,kind:e.kind,mode:b,lifecycle:N,persona_ack:{kind:e.kind,mode:b,lifecycle:N},status:"active",parent:o,spawned_by:f,creator:m,fork_from:e.forkFrom,fork_source_file:e.forkSourceFile,review_binding:e.reviewBinding,model_override:e.modelOverride??null,scopes:e.scopes??null,isolated:e.isolated===!0,grantee:e.run?.grantee??"app:terminal",sub:e.run?.sub??h?.sub??null,grant_id:e.run?.grant_id??h?.id??null,client_id:e.run?.client_id??null,metadata_json:s?e.run?.metadata_json??null:null,run_id:s?t:e.run?.run_id??null,event_cursor:s?e.run?.event_cursor??1:null,usage_json:s?e.run?.usage_json??JSON.stringify({input_tokens:0,output_tokens:0,cache_read_tokens:0,cache_write_tokens:0,cost_usd:0}):null,passive_default:e.passiveDefault??!1,...e.managedWorktree!==void 0?{managed_worktree:e.managedWorktree}:{},intent:null,deadline_at:e.deadlineAt??null,pi_session_id:null,pi_session_file:null,launch:e.launch},E=e.scopes===void 0?void 0:Q(e.scopes),v=o===null?null:c(o);if(o!==null&&v===null)throw new Error(`cannot spawn under unknown parent node: ${o}`);if(v?.run_id&&c(v.run_id)?.deleting_at)throw new Error("run is deleting");const u=m===null?null:c(m);if(m!==null&&u===null)throw new Error(`cannot spawn from unknown creator node: ${m}`);if(u?.run_id&&c(u.run_id)?.deleting_at)throw new Error("run is deleting");const A=e.forkSourceFile==null?null:Ae(e.forkSourceFile),$=e.replaces==null?null:c(e.replaces),_=v??A??$??u??(f===null?null:c(f)),F=[v,u,A,$,f===null?null:c(f)].some(r=>r?.isolated===!0||r?.run_id!=null&&c(r.run_id)?.isolated===!0);if(F&&e.isolated===!1)throw new w(403,"isolated_run","isolation cannot be turned off under an isolated run",{param:"isolated"});if(n.isolated=F||e.isolated===!0,_!==null){const r=u??_;if(u&&_.grantee&&u.grantee&&u.grantee!==_.grantee)throw new w(403,"other_app_run","cannot create under another app's node");const i=u&&u!==_?[_,u]:[_],d=[],g=new Set;for(const l of i){l.scopes!==null&&l.scopes!==void 0&&d.push(l.scopes);const p=l.grantee==="app:terminal"?k():l.grant_id?B(l.grant_id):null;if(p){const R=[...p.resolved];g.add(R),d.push(R)}else if(!(l.grantee==="app:terminal"&&!S("user").runtime?.issuer)){const R=[];g.add(R),d.push(R)}}const y=a(l=>Y(l,r.grantee==="user:local"?"app:terminal":r.grantee??"app:terminal"),"ownMemory"),M=a((l,p)=>y(p)&&g.has(l)||C(l,p),"allowed");if(E!==void 0&&!E.every(l=>d.every(p=>M(p,l))))throw new T({error:"unknown_scope",message:"child scopes must be covered by the creating node, its source and their current grants",received:E,field:"scopes",next:"Request only scopes the creating node currently holds."});if(n.scopes=E??(i.every(l=>l.scopes==null)&&i.every(l=>l.grant_id===r.grant_id&&l.sub===r.sub)?null:i.length===1?_.scopes??null:[...new Set(d.flat().filter(l=>d.every(p=>M(p,l))))]),n.scopes?.includes("crtr:act")&&!C(n.scopes,"crtr:llm"))throw new T({error:"invalid_scope",message:"crtr:act requires crtr:llm",received:n.scopes,field:"scopes",next:"Include crtr:llm or omit crtr:act."});n.grantee=r.grantee==="user:local"?"app:terminal":r.grantee,n.sub=r.sub??(n.grantee==="app:terminal"?h?.sub:null)??null,n.grant_id=r.grant_id??(n.grantee==="app:terminal"?h?.id:null)??null,n.client_id=r.client_id,n.run_id=s?t:r.run_id??null}if(ee(n.grantee),e.run===void 0&&n.grantee==="app:terminal"&&S("user").runtime?.issuer&&h===null)throw new w(403,"scope_missing","terminal grant is not active");if(n.isolated){if(process.platform!=="linux"||!P(L))throw new w(400,"isolated_unavailable","isolated nodes require the Linux root launcher");if(e.managedWorktree!==void 0)throw new w(400,"invalid_request","isolated nodes cannot use a worktree",{param:"worktree"});const r=ie(le(n.grantee??"app:terminal").nodes,t),i=te(r,re(n.cwd));if(!H(n.cwd)||i===".."||i.startsWith(`..${oe}`)||H(i))throw new w(400,"invalid_request","isolated node cwd must be inside its own folder",{param:"cwd"})}if(n.profile_id){const r=ve(n.profile_id).manifest.grantee??"app:terminal";if(r!==n.grantee){const i=`crtr:memory:rw:${r}:profile:${n.profile_id}`,d=n.grantee==="app:terminal"?k():n.grant_id?B(n.grant_id):null;if(!(n.grantee==="app:terminal"&&!S("user").runtime?.issuer)&&(!d||d.grantee!==n.grantee||!C(d.resolved,i))||!C(n.scopes,i))throw new T({error:"scope_missing",message:`missing scope ${i}`,received:n.profile_id,field:"profile",next:"Select a profile covered by this run and its current grant."})}}if(he(n.profile_id??null),!n.grantee)throw new Error("node creation requires an app");const W=await Re({kind:n.kind,mode:n.mode,cwd:n.cwd,profile:n.profile_id??null,root:s,parentId:o,requestingNodeId:m,lifecycle:N,replaces:e.replaces??null},n.grantee),G=a((r,i)=>{const d=I(r,i.node_id),g=m??o??e.actor??f??null,y=g!==null&&Ee(r,g)?.type==="node"?I(r,g):ye(r,e.run===void 0?"user:local":i.grantee);Ce(r,y,d),o!==null&&e.subscribe!==!1&&Ie(r,I(r,o),d,"spawn"),e.forkSourceNode&&Ne(r,I(r,e.forkSourceNode),d),ke(r,{event:"created",object:d,actor:y,attrs:{name:i.name,kind:i.kind,creator:m??null}})},"recordBirth");try{e.nodeId!==void 0&&De(e.nodeId),await e.beforeCreate?.(),(process.platform!=="linux"||P(L))&&await fe(n.grantee??"app:terminal"),se(n,{outcomeDelivery:e.outcomeDelivery,withinCreate:a((r,i)=>{i.run_id&&i.run_id!==i.node_id&&de(r,i.run_id),s&&e.run===void 0&&Z(r,t,t,"run.started",{scopes:i.scopes??null,payer:"user",usage:JSON.parse(i.usage_json)}),e.withinCreate?.(r,i),G(r,i)},"withinCreate")})}finally{W()}return n}a(gn,"spawnNode");export{q as NodeIdConflictError,mn as currentNodeContext,Ae as forkSourceNode,be as inboxBetweenTurns,Te as newJobId,Oe as newNodeId,_n as nodeEnv,fn as preflightNodeId,pn as rootOfSpine,cn as setInstallId,gn as spawnNode};
1
+ var J=Object.defineProperty;var a=(e,t)=>J(e,"name",{value:t,configurable:!0});import{envHomeOverride as K,envRuntimeHomeOverride as X,INBOX_BETWEEN_TURNS_ENV as z,SCOPES_FILE_ENV as V,scopeAllowed as C}from"../../shared/env.js";import{isOwnMemoryScope as Y,validateScopes as Q}from"../scopes.js";import{activeGrant as B,terminalGrant as k}from"../grants/mirror.js";import{grantSnapshotMissing as Z}from"../../daemon/readiness.js";import{appendRunEvent as ee}from"../runs/events.js";import{readConfig as S}from"../config.js";import{InputError as T}from"../io.js";import{ApiError as w}from"../../api/errors.js";import{assertGranteeRunsHere as ne}from"./unsandboxed.js";import{randomBytes as re}from"node:crypto";import{existsSync as P}from"node:fs";import{resolve as te,relative as ie,isAbsolute as H,join as oe,sep as le}from"node:path";import{appSpace as ae}from"../layout.js";import{scopesFilePath as se}from"../canvas/paths.js";import{createNode as de,assertRunNotDeleting as ue,conversationOwner as ce,getNode as c,getRow as fe}from"../canvas/index.js";import{ensureAppSpace as pe}from"../spaces/space.js";import{LAUNCHER_SOCKET as L}from"../../launcher/spec.js";import{resolveInstallId as me}from"../canvas/install-id.js";import{isAppRun as _e}from"../canvas/app-run.js";import{canvasDbPath as ge,contextDir as we}from"../canvas/paths.js";import{conversationIdFromPath as he}from"../conversation-store/index.js";import{usage as U}from"../errors.js";import{assertProfileAvailableForBirth as ve}from"../profiles/deletion-reservation.js";import{loadExactProfileManifest as Re}from"../profiles/manifest.js";import{admitNodeCreate as Ee}from"../command-hooks/lifecycle-create.js";import{getById as ye,nodeObject as I,ownerForGrantee as Ce}from"../graph/objects.js";import{recordActedOn as Ie}from"../graph/edges.js";import{recordWatch as Ne,copyWatchesForFork as ke}from"../graph/watches.js";import{publish as Se}from"../graph/events.js";let O;const j=new Map;function pn(e){O=e}a(pn,"setInstallId");function Te(){if(O!==void 0)return O;const e=ge(),t=j.get(e);if(t!==void 0)return t;const o=me();return j.set(e,o),o}a(Te,"installId");function Oe(){return`${Date.now().toString(36)}-${re(4).toString("hex")}`}a(Oe,"newJobId");function xe(){return`${Te()}-${Oe()}`}a(xe,"newNodeId");const x=128,De=/^[a-z0-9-]+$/;class q extends Error{static{a(this,"NodeIdConflictError")}nodeId;constructor(t){super(`node already exists: ${t}`),this.nodeId=t,this.name="NodeIdConflictError"}}function D(e){if(e.length===0||e.length>x)throw U(`invalid --node-id '${e}': must be 1-${x} characters`,{next:`Pass an id-safe string (lowercase letters, digits, hyphens) of at most ${x} characters.`});if(!De.test(e))throw U(`invalid --node-id '${e}': must contain only lowercase letters, digits, and hyphens (e.g. 'remote42', 'my-node-1')`,{next:"Use only lowercase letters, digits, and hyphens."})}a(D,"validateNodeIdFormat");function mn(e){if(D(e),c(e)!==null)throw new q(e)}a(mn,"preflightNodeId");function be(e){if(D(e),c(e)!==null)throw new q(e);return e}a(be,"validatedExplicitNodeId");function _n(e){let t=e;const o=new Set;for(;;){if(o.has(t))return t;o.add(t);const s=fe(t);if(s===null||s.parent==null)return t;t=s.parent}}a(_n,"rootOfSpine");function gn(){const e=process.env;return{nodeId:e.CRTR_NODE_ID??null,kind:e.CRTR_KIND??null,mode:e.CRTR_MODE??null}}a(gn,"currentNodeContext");function Ae(e){return _e(e)}a(Ae,"inboxBetweenTurns");function wn(e){const t={CRTR_NODE_ID:e.node_id,CRTR_KIND:e.kind,CRTR_MODE:e.mode,CRTR_LIFECYCLE:e.lifecycle,CRTR_NODE_CWD:e.cwd,CRTR_CONTEXT_DIR:we(e.node_id,e.grantee),CRTR_CYCLES:(e.cycles??0).toString(),CRTR_PROFILE_ID:e.profile_id??"",PI_CLAUDE_OAUTH_REINJECT_SCOPE:"never"};e.parent&&(t.CRTR_PARENT_NODE_ID=e.parent),e.run_id&&(t.CRTR_RUN_ID=e.run_id),Ae(e)&&(t[z]="1"),e.scopes!==null&&e.scopes!==void 0&&(t[V]=se(e.node_id)),t.CRTR_GRANTEE=e.grantee??"app:terminal";const o=K();o!==void 0&&o!==""&&(t.CRTR_HOME=o);const s=X();s!==void 0&&s!==""&&(t.CRTR_RUNTIME_HOME=s);const f=process.env.CRTR_SUBTREE;return f!==void 0&&f!==""&&(t.CRTR_SUBTREE=f),{...t,...e.launch?.env??{}}}a(wn,"nodeEnv");function Me(e){const t=he(e),o=t===null?null:ce(t);return o===null?null:c(o)}a(Me,"forkSourceNode");async function hn(e){const t=e.nodeId!==void 0?(D(e.nodeId),e.nodeId):xe(),o=e.parent??null,s=o===null,f=e.spawnedBy??o,m=e.creator??null,b=e.mode??"base",N=e.lifecycle??(s?"resident":"terminal"),h=e.run===void 0?k():null,n={node_id:t,name:e.name??e.kind,description:e.description,cycles:0,created:new Date().toISOString(),cwd:e.cwd,host_kind:"broker",profile_id:e.profile_id??null,kind:e.kind,mode:b,lifecycle:N,persona_ack:{kind:e.kind,mode:b,lifecycle:N},status:"active",parent:o,spawned_by:f,creator:m,fork_from:e.forkFrom,fork_source_file:e.forkSourceFile,review_binding:e.reviewBinding,model_override:e.modelOverride??null,scopes:e.scopes??null,isolated:e.isolated===!0,grantee:e.run?.grantee??"app:terminal",sub:e.run?.sub??h?.sub??null,grant_id:e.run?.grant_id??h?.id??null,client_id:e.run?.client_id??null,metadata_json:s?e.run?.metadata_json??null:null,run_id:s?t:e.run?.run_id??null,event_cursor:s?e.run?.event_cursor??1:null,usage_json:s?e.run?.usage_json??JSON.stringify({input_tokens:0,output_tokens:0,cache_read_tokens:0,cache_write_tokens:0,cost_usd:0}):null,passive_default:e.passiveDefault??!1,...e.managedWorktree!==void 0?{managed_worktree:e.managedWorktree}:{},intent:null,deadline_at:e.deadlineAt??null,pi_session_id:null,pi_session_file:null,launch:e.launch},E=e.scopes===void 0?void 0:Q(e.scopes),v=o===null?null:c(o);if(o!==null&&v===null)throw new Error(`cannot spawn under unknown parent node: ${o}`);if(v?.run_id&&c(v.run_id)?.deleting_at)throw new Error("run is deleting");const u=m===null?null:c(m);if(m!==null&&u===null)throw new Error(`cannot spawn from unknown creator node: ${m}`);if(u?.run_id&&c(u.run_id)?.deleting_at)throw new Error("run is deleting");const A=e.forkSourceFile==null?null:Me(e.forkSourceFile),M=e.replaces==null?null:c(e.replaces),_=v??A??M??u??(f===null?null:c(f)),$=[v,u,A,M,f===null?null:c(f)].some(r=>r?.isolated===!0||r?.run_id!=null&&c(r.run_id)?.isolated===!0);if($&&e.isolated===!1)throw new w(403,"isolated_run","isolation cannot be turned off under an isolated run",{param:"isolated"});if(n.isolated=$||e.isolated===!0,_!==null){const r=u??_;if(u&&_.grantee&&u.grantee&&u.grantee!==_.grantee)throw new w(403,"other_app_run","cannot create under another app's node");const i=u&&u!==_?[_,u]:[_],d=[],g=new Set;for(const l of i){l.scopes!==null&&l.scopes!==void 0&&d.push(l.scopes);const p=l.grantee==="app:terminal"?k():l.grant_id?B(l.grant_id):null;if(p){const R=[...p.resolved];g.add(R),d.push(R)}else if(!(l.grantee==="app:terminal"&&!S("user").runtime?.issuer)){const R=[];g.add(R),d.push(R)}}const y=a(l=>Y(l,r.grantee==="user:local"?"app:terminal":r.grantee??"app:terminal"),"ownMemory"),F=a((l,p)=>y(p)&&g.has(l)||C(l,p),"allowed");if(E!==void 0&&!E.every(l=>d.every(p=>F(p,l))))throw new T({error:"unknown_scope",message:"child scopes must be covered by the creating node, its source and their current grants",received:E,field:"scopes",next:"Request only scopes the creating node currently holds."});if(n.scopes=E??(i.every(l=>l.scopes==null)&&i.every(l=>l.grant_id===r.grant_id&&l.sub===r.sub)?null:i.length===1?_.scopes??null:[...new Set(d.flat().filter(l=>d.every(p=>F(p,l))))]),n.scopes?.includes("crtr:act")&&!C(n.scopes,"crtr:llm"))throw new T({error:"invalid_scope",message:"crtr:act requires crtr:llm",received:n.scopes,field:"scopes",next:"Include crtr:llm or omit crtr:act."});n.grantee=r.grantee==="user:local"?"app:terminal":r.grantee,n.sub=r.sub??(n.grantee==="app:terminal"?h?.sub:null)??null,n.grant_id=r.grant_id??(n.grantee==="app:terminal"?h?.id:null)??null,n.client_id=r.client_id,n.run_id=s?t:r.run_id??null}if(ne(n.grantee),e.run===void 0&&n.grantee==="app:terminal"&&S("user").runtime?.issuer&&h===null)throw Z()?new w(503,"runtime_starting","the first grant snapshot from the directory has not committed"):new w(403,"scope_missing","terminal grant is not active");if(n.isolated){if(process.platform!=="linux"||!P(L))throw new w(400,"isolated_unavailable","isolated nodes require the Linux root launcher");if(e.managedWorktree!==void 0)throw new w(400,"invalid_request","isolated nodes cannot use a worktree",{param:"worktree"});const r=oe(ae(n.grantee??"app:terminal").nodes,t),i=ie(r,te(n.cwd));if(!H(n.cwd)||i===".."||i.startsWith(`..${le}`)||H(i))throw new w(400,"invalid_request","isolated node cwd must be inside its own folder",{param:"cwd"})}if(n.profile_id){const r=Re(n.profile_id).manifest.grantee??"app:terminal";if(r!==n.grantee){const i=`crtr:memory:rw:${r}:profile:${n.profile_id}`,d=n.grantee==="app:terminal"?k():n.grant_id?B(n.grant_id):null;if(!(n.grantee==="app:terminal"&&!S("user").runtime?.issuer)&&(!d||d.grantee!==n.grantee||!C(d.resolved,i))||!C(n.scopes,i))throw new T({error:"scope_missing",message:`missing scope ${i}`,received:n.profile_id,field:"profile",next:"Select a profile covered by this run and its current grant."})}}if(ve(n.profile_id??null),!n.grantee)throw new Error("node creation requires an app");const W=await Ee({kind:n.kind,mode:n.mode,cwd:n.cwd,profile:n.profile_id??null,root:s,parentId:o,requestingNodeId:m,lifecycle:N,replaces:e.replaces??null},n.grantee),G=a((r,i)=>{const d=I(r,i.node_id),g=m??o??e.actor??f??null,y=g!==null&&ye(r,g)?.type==="node"?I(r,g):Ce(r,e.run===void 0?"user:local":i.grantee);Ie(r,y,d),o!==null&&e.subscribe!==!1&&Ne(r,I(r,o),d,"spawn"),e.forkSourceNode&&ke(r,I(r,e.forkSourceNode),d),Se(r,{event:"created",object:d,actor:y,attrs:{name:i.name,kind:i.kind,creator:m??null}})},"recordBirth");try{e.nodeId!==void 0&&be(e.nodeId),await e.beforeCreate?.(),(process.platform!=="linux"||P(L))&&await pe(n.grantee??"app:terminal"),de(n,{outcomeDelivery:e.outcomeDelivery,withinCreate:a((r,i)=>{i.run_id&&i.run_id!==i.node_id&&ue(r,i.run_id),s&&e.run===void 0&&ee(r,t,t,"run.started",{scopes:i.scopes??null,payer:"user",usage:JSON.parse(i.usage_json)}),e.withinCreate?.(r,i),G(r,i)},"withinCreate")})}finally{W()}return n}a(hn,"spawnNode");export{q as NodeIdConflictError,gn as currentNodeContext,Me as forkSourceNode,Ae as inboxBetweenTurns,Oe as newJobId,xe as newNodeId,wn as nodeEnv,mn as preflightNodeId,_n as rootOfSpine,pn as setInstallId,hn as spawnNode};
@@ -1,24 +1,24 @@
1
- var G=Object.defineProperty;var i=(e,r)=>G(e,"name",{value:r,configurable:!0});import{randomUUID as F}from"node:crypto";import{createServer as Y}from"node:http";import{Router as J}from"./router.js";import{toErrorBody as q}from"./map.js";import{objectRoutes as Q}from"./handlers/objects.js";import{customObjectRoutes as W}from"./handlers/custom-objects.js";import{docRoutes as K}from"./handlers/docs.js";import{OPERATIONS as Z}from"./operations.js";import{errorCodes as L}from"../../api/error-codes.js";import{MINIMUM_RUNTIME_VERSION_HEADER as ee,RUNTIME_VERSION_HEADER as te,minimumRuntimeRefusal as ne}from"../../api/runtime-version.js";import{CONTRACT_HEADER as re,CONTRACT_LEVEL as U,REQUIRED_CONTRACT_HEADER as ae,contractRefusal as oe}from"../../api/contract.js";import{crtrVersion as x}from"../../shared/crtr-version.js";import{AppPrincipalResolver as ie}from"./principal.js";import{isDaemonRoute as se,runtimeOwner as ue,servePeer as V}from"../peer/ingress.js";import{applySyncNotice as de}from"./sync-notice.js";import{ownMachineId as ce}from"../../core/peer/directory.js";import{handleRunOperation as le,integer as fe}from"./handlers/runs.js";import{llmCallerOf as me,parseLlmRequest as pe,runLlm as he}from"../../core/llm/run.js";import{parseUsageMonth as we,usageFor as ye}from"../../core/usage/ledger.js";import{capFields as _e}from"./handlers/llm.js";import{CONTROL_BODY_MAX_BYTES as ge,MODEL_CONTEXT_BODY_MAX_BYTES as ve}from"../../core/llm/body-limits.js";import{RunError as l,runIsRunning as Oe}from"../../core/runs/operations.js";import{requireRun as j}from"./router.js";import{deferHead as Re}from"./deferred-head.js";import{readRunEvents as X,registerGrantStream as Ee,subscribeRunEvents as be}from"../../core/runs/events.js";import{activeGrant as $,payerOfGrant as Se}from"../../core/grants/mirror.js";function Te(e){if(Se(e)==="app")throw new l(401,"grant_revoked","this app-paid grant is no longer active");return null}i(Te,"appPaidGone");import{releaseGrantWaiters as Ae}from"../../core/grants/watch.js";import{runNotices as Ne}from"../run-notices.js";import{handleVendorSignIn as Ce,isVendorSignInPath as Pe}from"./vendor-signin.js";import{listAppProfiles as Ie}from"./handlers/app-profiles.js";import{handleTransferDownload as ke,handleTransferOperation as He,TRANSFER_OPERATIONS as Me}from"./handlers/transfer.js";import{handleQuestionOperation as De,QUESTION_OPERATIONS as xe}from"./handlers/questions.js";import{vendorStatus as je}from"./handlers/vendor-status.js";import{handleMemoryOperation as Be,MEMORY_OPERATIONS as Je}from"./handlers/memory.js";import{abortOnClose as Le,callerFromApp as Ue,handleProviderOperation as Ve,PROVIDER_OPERATIONS as Xe,providerFailure as $e}from"./handlers/providers.js";function ze(e){return Object.prototype.hasOwnProperty.call(L,e)?L[e]:void 0}i(ze,"fixedRow");function Ge(e){const r=ze(e);return r?r.type:e==="stream_gap"||e==="provider_error"||e==="runtime_version_unsupported"?"invalid_request_error":"server_error"}i(Ge,"errorType");function Fe(e){if(!e||typeof e!="object"||Array.isArray(e)||!("rate_limit"in e))return e;const{rate_limit:r,...o}=e;return o}i(Fe,"appDetails");function D(e,r,o){const f=Fe(e.details);return{error:{code:e.code,message:e.message,...f===void 0?{}:{details:f},type:Ge(e.code),...e.param?{param:e.param}:{},origin:"runtime",retryable:e.retryable||e.code==="stream_dropped",request_id:r,...o?{run_id:o}:{},...e.scope?{scope:e.scope}:{},...e.code==="unauthorized"?{user_action:"reconnect"}:{},..._e(e),...e.code==="all_routes_exhausted"?{retry_after_s:e.details.retry_after_s}:{}}}}i(D,"envelope");function Ye(e,r,o,f){const u=r instanceof l?r:new l(500,"server_failure","runtime request failed");if(r instanceof l||console.error("[app-listener]",r),e.headersSent&&!String(e.getHeader("Content-Type")??"").startsWith("text/event-stream")){e.destroy();return}if(e.headersSent){e.end(`event: error
1
+ var G=Object.defineProperty;var s=(e,r)=>G(e,"name",{value:r,configurable:!0});import{randomUUID as F}from"node:crypto";import{createServer as Y}from"node:http";import{Router as J}from"./router.js";import{toErrorBody as q}from"./map.js";import{objectRoutes as Q}from"./handlers/objects.js";import{customObjectRoutes as W}from"./handlers/custom-objects.js";import{docRoutes as K}from"./handlers/docs.js";import{OPERATIONS as Z}from"./operations.js";import{runtimeReadiness as ee}from"../readiness.js";import{errorCodes as L}from"../../api/error-codes.js";import{MINIMUM_RUNTIME_VERSION_HEADER as te,RUNTIME_VERSION_HEADER as ne,minimumRuntimeRefusal as re}from"../../api/runtime-version.js";import{CONTRACT_HEADER as ae,CONTRACT_LEVEL as U,REQUIRED_CONTRACT_HEADER as oe,contractRefusal as ie}from"../../api/contract.js";import{crtrVersion as j}from"../../shared/crtr-version.js";import{AppPrincipalResolver as se}from"./principal.js";import{isDaemonRoute as ue,runtimeOwner as de,servePeer as V}from"../peer/ingress.js";import{applySyncNotice as ce}from"./sync-notice.js";import{ownMachineId as le}from"../../core/peer/directory.js";import{handleRunOperation as fe,integer as me}from"./handlers/runs.js";import{llmCallerOf as pe,parseLlmRequest as he,runLlm as ye}from"../../core/llm/run.js";import{parseUsageMonth as we,usageFor as _e}from"../../core/usage/ledger.js";import{capFields as ge}from"./handlers/llm.js";import{CONTROL_BODY_MAX_BYTES as ve,MODEL_CONTEXT_BODY_MAX_BYTES as Re}from"../../core/llm/body-limits.js";import{RunError as l,runIsRunning as Oe}from"../../core/runs/operations.js";import{requireRun as x}from"./router.js";import{deferHead as Ee}from"./deferred-head.js";import{readRunEvents as X,registerGrantStream as be,subscribeRunEvents as Se}from"../../core/runs/events.js";import{activeGrant as $,payerOfGrant as Te}from"../../core/grants/mirror.js";function Ae(e){if(Te(e)==="app")throw new l(401,"grant_revoked","this app-paid grant is no longer active");return null}s(Ae,"appPaidGone");import{releaseGrantWaiters as Ne}from"../../core/grants/watch.js";import{runNotices as Ce}from"../run-notices.js";import{handleVendorSignIn as Pe,isVendorSignInPath as Ie}from"./vendor-signin.js";import{listAppProfiles as ke}from"./handlers/app-profiles.js";import{handleTransferDownload as He,handleTransferOperation as Me,TRANSFER_OPERATIONS as De}from"./handlers/transfer.js";import{handleQuestionOperation as je,QUESTION_OPERATIONS as xe}from"./handlers/questions.js";import{vendorStatus as Be}from"./handlers/vendor-status.js";import{handleMemoryOperation as Je,MEMORY_OPERATIONS as Le}from"./handlers/memory.js";import{abortOnClose as Ue,callerFromApp as Ve,handleProviderOperation as Xe,PROVIDER_OPERATIONS as $e,providerFailure as ze}from"./handlers/providers.js";function Ge(e){return Object.prototype.hasOwnProperty.call(L,e)?L[e]:void 0}s(Ge,"fixedRow");function Fe(e){const r=Ge(e);return r?r.type:e==="stream_gap"||e==="provider_error"||e==="runtime_version_unsupported"?"invalid_request_error":"server_error"}s(Fe,"errorType");function Ye(e){if(!e||typeof e!="object"||Array.isArray(e)||!("rate_limit"in e))return e;const{rate_limit:r,...o}=e;return o}s(Ye,"appDetails");function D(e,r,o){const f=Ye(e.details);return{error:{code:e.code,message:e.message,...f===void 0?{}:{details:f},type:Fe(e.code),...e.param?{param:e.param}:{},origin:"runtime",retryable:e.retryable||e.code==="stream_dropped",request_id:r,...o?{run_id:o}:{},...e.scope?{scope:e.scope}:{},...e.code==="unauthorized"?{user_action:"reconnect"}:{},...ge(e),...e.code==="all_routes_exhausted"?{retry_after_s:e.details.retry_after_s}:{}}}}s(D,"envelope");function qe(e,r,o,f){const u=r instanceof l?r:new l(500,"server_failure","runtime request failed");if(r instanceof l||console.error("[app-listener]",r),e.headersSent&&!String(e.getHeader("Content-Type")??"").startsWith("text/event-stream")){e.destroy();return}if(e.headersSent){e.end(`event: error
2
2
  data: ${JSON.stringify(D(u,o,f))}
3
3
 
4
- `);return}e.writeHead(u.status,{"Content-Type":"application/json; charset=utf-8","Request-Id":o,"X-Content-Type-Options":"nosniff",...u.code==="all_routes_exhausted"?{"Retry-After":String(u.details.retry_after_s)}:{}}),e.end(JSON.stringify(D(u,o,f)))}i(Ye,"fail");function z(e){return Array.isArray(e)?e[0]:e}i(z,"headerValue");function R(e,r,o){e.writeHead(r,{"Content-Type":"application/json; charset=utf-8"}),e.end(JSON.stringify(o))}i(R,"json");async function P(e,r=ge){const o=[];let f=0;for await(const u of e){if(f+=u.length,f>r)throw new l(400,"invalid_request","request body too large");o.push(u)}if(f)try{return JSON.parse(Buffer.concat(o).toString("utf8"))}catch{throw new l(400,"invalid_request","invalid JSON body")}}i(P,"bodyOf");function qe(e,r){const o=e.headers["last-event-id"]??r.get("after");if(Array.isArray(o))throw new l(400,"invalid_request","invalid cursor","after");return fe(o??null,"after",0,Number.MAX_SAFE_INTEGER,0)}i(qe,"cursor");function Qe(e){return`id: ${e.sequence_number}
4
+ `);return}e.writeHead(u.status,{"Content-Type":"application/json; charset=utf-8","Request-Id":o,"X-Content-Type-Options":"nosniff",...u.code==="all_routes_exhausted"?{"Retry-After":String(u.details.retry_after_s)}:{}}),e.end(JSON.stringify(D(u,o,f)))}s(qe,"fail");function z(e){return Array.isArray(e)?e[0]:e}s(z,"headerValue");function O(e,r,o){e.writeHead(r,{"Content-Type":"application/json; charset=utf-8"}),e.end(JSON.stringify(o))}s(O,"json");async function P(e,r=ve){const o=[];let f=0;for await(const u of e){if(f+=u.length,f>r)throw new l(400,"invalid_request","request body too large");o.push(u)}if(f)try{return JSON.parse(Buffer.concat(o).toString("utf8"))}catch{throw new l(400,"invalid_request","invalid JSON body")}}s(P,"bodyOf");function Qe(e,r){const o=e.headers["last-event-id"]??r.get("after");if(Array.isArray(o))throw new l(400,"invalid_request","invalid cursor","after");return me(o??null,"after",0,Number.MAX_SAFE_INTEGER,0)}s(Qe,"cursor");function We(e){return`id: ${e.sequence_number}
5
5
  event: ${e.type}
6
6
  data: ${JSON.stringify(e)}
7
7
 
8
- `}i(Qe,"frame");const We=6e4;function Ke(e,r,o,f,u,_,E,A={}){j(f,o);let g=X(o,u);if(u>g.latest_sequence)throw new l(400,"invalid_request","cursor is beyond the run","after");if(u<g.latest_sequence&&(g.earliest_sequence===null||u<g.earliest_sequence-1))throw new l(409,"stream_gap","events have expired",void 0,{earliest_sequence:g.earliest_sequence,latest_sequence:g.latest_sequence});if(r.destroyed||e.destroyed)return r.destroy(),Promise.resolve();r.writeHead(200,{"Content-Type":E==="sse"?"text/event-stream":"application/x-ndjson","Cache-Control":"no-cache","X-Accel-Buffering":"no"}),E==="sse"?r.write(`: connected
8
+ `}s(We,"frame");const Ke=6e4;function Ze(e,r,o,f,u,y,E,A={}){x(f,o);let g=X(o,u);if(u>g.latest_sequence)throw new l(400,"invalid_request","cursor is beyond the run","after");if(u<g.latest_sequence&&(g.earliest_sequence===null||u<g.earliest_sequence-1))throw new l(409,"stream_gap","events have expired",void 0,{earliest_sequence:g.earliest_sequence,latest_sequence:g.latest_sequence});if(r.destroyed||e.destroyed)return r.destroy(),Promise.resolve();r.writeHead(200,{"Content-Type":E==="sse"?"text/event-stream":"application/x-ndjson","Cache-Control":"no-cache","X-Accel-Buffering":"no"}),E==="sse"?r.write(`: connected
9
9
 
10
- `):r.flushHeaders();let w=u;const B=Ne().streamOpened(o);let n=!1,t=!1,h=!1,b;const N=new Promise(m=>{b=m}),y=i(()=>{n||(n=!0,B(w),clearInterval(d),clearInterval(O),I(),H(),r.off("close",y),r.off("drain",p),r.end(),b())},"end"),p=i(()=>{h=!1,a()},"onDrain"),v=i(m=>{n||r.write(E==="sse"?`event: error
11
- data: ${JSON.stringify(D(m,_,o))}
10
+ `):r.flushHeaders();let w=u;const B=Ce().streamOpened(o);let n=!1,t=!1,h=!1,b;const N=new Promise(m=>{b=m}),_=s(()=>{n||(n=!0,B(w),clearInterval(d),clearInterval(R),I(),H(),r.off("close",_),r.off("drain",p),r.end(),b())},"end"),p=s(()=>{h=!1,a()},"onDrain"),v=s(m=>{n||r.write(E==="sse"?`event: error
11
+ data: ${JSON.stringify(D(m,y,o))}
12
12
 
13
- `:`${JSON.stringify({type:"error",...D(m,_,o)})}
14
- `),y()},"error"),a=i(()=>{if(!(n||t)){t=!0;try{if(!T()){k();return}if(j(f,o),g=X(o,w),g.backlog_count>1e3||g.backlog_bytes>32*1024*1024){v(new l(503,"stream_dropped","stream reader fell behind",void 0,{last_sequence:w}));return}for(const m of g.events){if(h)break;h=!r.write(E==="sse"?Qe(m):`${JSON.stringify(m)}
15
- `),w=m.sequence_number}}catch(m){v(m instanceof l?m:new l(500,"server_failure","stream failed"))}finally{t=!1}}},"flush"),k=i(()=>v(new l(401,"grant_revoked","grant is not active")),"revoked"),T=i(()=>"class"in f||$(f.grant)!==null,"grantActive"),I=be(o,a),H="class"in f?()=>{}:Ee(f.grant,k),d=setInterval(()=>{!n&&!h&&E==="sse"&&r.write(`: keepalive
13
+ `:`${JSON.stringify({type:"error",...D(m,y,o)})}
14
+ `),_()},"error"),a=s(()=>{if(!(n||t)){t=!0;try{if(!T()){k();return}if(x(f,o),g=X(o,w),g.backlog_count>1e3||g.backlog_bytes>32*1024*1024){v(new l(503,"stream_dropped","stream reader fell behind",void 0,{last_sequence:w}));return}for(const m of g.events){if(h)break;h=!r.write(E==="sse"?We(m):`${JSON.stringify(m)}
15
+ `),w=m.sequence_number}}catch(m){v(m instanceof l?m:new l(500,"server_failure","stream failed"))}finally{t=!1}}},"flush"),k=s(()=>v(new l(401,"grant_revoked","grant is not active")),"revoked"),T=s(()=>"class"in f||$(f.grant)!==null,"grantActive"),I=Se(o,a),H="class"in f?()=>{}:be(f.grant,k),d=setInterval(()=>{!n&&!h&&E==="sse"&&r.write(`: keepalive
16
16
 
17
- `)},15e3),M=A.idleMs??We,s=A.isRunning??Oe;let S=Date.now(),c=w;const O=setInterval(()=>{if(n||E!=="sse")return;const m=Date.now();let C=!0;try{C=s(o)}catch{}if(C||w!==c){S=m,c=w;return}m-S<M||h||(r.write(`event: idle
17
+ `)},15e3),M=A.idleMs??Ke,i=A.isRunning??Oe;let S=Date.now(),c=w;const R=setInterval(()=>{if(n||E!=="sse")return;const m=Date.now();let C=!0;try{C=i(o)}catch{}if(C||w!==c){S=m,c=w;return}m-S<M||h||(r.write(`event: idle
18
18
  data: {}
19
19
 
20
- `),y())},A.idleCheckMs??1e3);return O.unref(),r.on("drain",p),r.on("close",y),a(),N}i(Ke,"streamRunEvents");function Dt(e,r,o,f={}){const u=e.listener;if(!e.issuer||!e.audience||!u?.address||!Number.isInteger(u.port)||u.port<1||u.port>65535)throw new Error("runtime issuer, audience and listener address/port are required");if(["0.0.0.0","::","[::]"].includes(u.address))throw new Error("runtime listener must bind a specific address");const _=new ie(e.issuer,e.audience,o,e.jwksUrl),E=new J,A=new Map;for(const n of Z.filter(t=>t.stage!==void 0)){const t=i(()=>({status:500}),"handler");E.register({method:n.method,pattern:n.path,handler:t}),A.set(t,n)}const g=new J().registerAll(Q).registerAll(W).registerAll(K),w=Y((n,t)=>{(async()=>{Re(n,t,f.deferHead);const h=F();t.setHeader("Request-Id",h),t.setHeader(te,x()),t.setHeader(re,U);let b;try{const N=z(n.headers[ee.toLowerCase()]),y=ne(N,x())??oe(z(n.headers[ae.toLowerCase()]),U,{legacyMinimum:N,runtimeVersion:x()});if(y!==null)throw y.status===400?new l(400,y.code,y.message,y.param):new l(426,y.code,y.message,void 0,y.details);const p=new URL(n.url??"/","http://runtime.local");if(Pe(p.pathname)){await Ce(n,t,p,_);return}const v=E.match(n.method??"GET",p.pathname),a=v?A.get(v.handler):void 0,k=a?.name==="runtime.sync-notice"||a?.name==="runtime.vendor-status";let T,I;if(!k&&n.headers.authorization!==void 0)try{T=await _.verifyCall(n.headers.authorization)}catch(s){I=s}const H={issuer:e.issuer,jwks:_.jwks,audience:i(()=>e.audience,"audience"),owner:ue,self:ce,syncGrants:o,ready:i(()=>_.isReady()&&r(),"ready")};if(T?.chain[0]?.sub.startsWith("runtime:")){await V(n,t,H,T);return}if(T===void 0&&a===void 0&&await se(n.method??"GET",p.pathname)){await V(n,t,H,{status:401,code:"unauthorized",message:I===void 0?"a machine token is required":"invalid machine token"});return}if((n.method!=="GET"||p.pathname!=="/v1/health")&&(!_.isReady()||!r()))throw new l(503,"runtime_starting","runtime_starting");if(!v||!a)throw new l(404,"not_found","unknown operation");if(b=v.params.run_id,a.name==="health"){R(t,200,{status:"ok",api_version:"2026-09-23"});return}if(a.name==="runtime.sync-notice"){await de(await _.verifySyncNotice(n.headers.authorization),o,h),t.writeHead(204),t.end();return}if(a.name==="runtime.vendor-status"){await _.verifyDirectoryRead(n.headers.authorization,"vendor_status"),R(t,200,je());return}if(T===void 0)throw I??new l(401,"unauthorized","a directory access token is required");const d=await _.resolveVerified(T,a.scope);if(t.setHeader("Request-Id",h),b&&j(d,b,["run.message","run.interrupt","run.cancel","run.rename","run.delete"].includes(a.name),a.name==="run.delete"),a.stage==="objects"){const s=g.match(a.method,p.pathname);if(!s)throw new l(404,"not_found","unknown operation");const S={method:a.method,path:p.pathname,params:s.params,query:p.searchParams,body:await P(n,s.maxBodyBytes),ceiling:d.resolved,principal:{class:"app",app:d.grantee,scopes:d.resolved},req:n,res:t};let c;try{c=await s.handler(S)}catch(O){const{status:m,body:C}=q(O);throw m>=500&&console.error("[app-listener]",O),new l(m,C.error.code,C.error.message,void 0,C.error.details)}if(t.headersSent)return;if(c.rawBody!==void 0||c.status===204||c.body===void 0){t.writeHead(c.status,c.headers??{}),t.end(c.rawBody);return}t.writeHead(c.status,{"Content-Type":"application/json; charset=utf-8",...c.headers??{}}),t.end(JSON.stringify(c.body));return}if(a.stream==="bytes"){await ke(n,t,d,p.searchParams);return}if(a.stream){Ke(n,t,b,d,qe(n,p.searchParams),h,"sse",f.stream);return}if(a.name==="llm"){const s=pe(await P(n,ve)),S=new AbortController,c=i(()=>S.abort(),"abort");t.on("close",c);try{const O=await he(s,S.signal,s.stream?m=>{t.headersSent||t.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache","X-Accel-Buffering":"no"}),t.write(`data: ${JSON.stringify(m)}
20
+ `),_())},A.idleCheckMs??1e3);return R.unref(),r.on("drain",p),r.on("close",_),a(),N}s(Ze,"streamRunEvents");function xt(e,r,o,f={}){const u=e.listener;if(!e.issuer||!e.audience||!u?.address||!Number.isInteger(u.port)||u.port<1||u.port>65535)throw new Error("runtime issuer, audience and listener address/port are required");if(["0.0.0.0","::","[::]"].includes(u.address))throw new Error("runtime listener must bind a specific address");const y=new se(e.issuer,e.audience,o,e.jwksUrl),E=new J,A=new Map;for(const n of Z.filter(t=>t.stage!==void 0)){const t=s(()=>({status:500}),"handler");E.register({method:n.method,pattern:n.path,handler:t}),A.set(t,n)}const g=new J().registerAll(Q).registerAll(W).registerAll(K),w=Y((n,t)=>{(async()=>{Ee(n,t,f.deferHead);const h=F();t.setHeader("Request-Id",h),t.setHeader(ne,j()),t.setHeader(ae,U);let b;try{const N=z(n.headers[te.toLowerCase()]),_=re(N,j())??ie(z(n.headers[oe.toLowerCase()]),U,{legacyMinimum:N,runtimeVersion:j()});if(_!==null)throw _.status===400?new l(400,_.code,_.message,_.param):new l(426,_.code,_.message,void 0,_.details);const p=new URL(n.url??"/","http://runtime.local");if(Ie(p.pathname)){await Pe(n,t,p,y);return}const v=E.match(n.method??"GET",p.pathname),a=v?A.get(v.handler):void 0,k=a?.name==="runtime.sync-notice"||a?.name==="runtime.vendor-status";let T,I;if(!k&&n.headers.authorization!==void 0)try{T=await y.verifyCall(n.headers.authorization)}catch(i){I=i}const H={issuer:e.issuer,jwks:y.jwks,audience:s(()=>e.audience,"audience"),owner:de,self:le,syncGrants:o,ready:s(()=>y.isReady()&&r(),"ready")};if(T?.chain[0]?.sub.startsWith("runtime:")){await V(n,t,H,T);return}if(T===void 0&&a===void 0&&await ue(n.method??"GET",p.pathname)){await V(n,t,H,{status:401,code:"unauthorized",message:I===void 0?"a machine token is required":"invalid machine token"});return}if(a?.name==="ready"){const i=ee({jwksReady:y.isReady(),grantsReady:r});O(t,i.ready?200:503,i);return}if((n.method!=="GET"||p.pathname!=="/v1/health")&&(!y.isReady()||!r()))throw new l(503,"runtime_starting","runtime_starting");if(!v||!a)throw new l(404,"not_found","unknown operation");if(b=v.params.run_id,a.name==="health"){O(t,200,{status:"ok",api_version:"2026-09-23"});return}if(a.name==="runtime.sync-notice"){await ce(await y.verifySyncNotice(n.headers.authorization),o,h),t.writeHead(204),t.end();return}if(a.name==="runtime.vendor-status"){await y.verifyDirectoryRead(n.headers.authorization,"vendor_status"),O(t,200,Be());return}if(T===void 0)throw I??new l(401,"unauthorized","a directory access token is required");const d=await y.resolveVerified(T,a.scope);if(t.setHeader("Request-Id",h),b&&x(d,b,["run.message","run.interrupt","run.cancel","run.rename","run.delete"].includes(a.name),a.name==="run.delete"),a.stage==="objects"){const i=g.match(a.method,p.pathname);if(!i)throw new l(404,"not_found","unknown operation");const S={method:a.method,path:p.pathname,params:i.params,query:p.searchParams,body:await P(n,i.maxBodyBytes),ceiling:d.resolved,principal:{class:"app",app:d.grantee,scopes:d.resolved},req:n,res:t};let c;try{c=await i.handler(S)}catch(R){const{status:m,body:C}=q(R);throw m>=500&&console.error("[app-listener]",R),new l(m,C.error.code,C.error.message,void 0,C.error.details)}if(t.headersSent)return;if(c.rawBody!==void 0||c.status===204||c.body===void 0){t.writeHead(c.status,c.headers??{}),t.end(c.rawBody);return}t.writeHead(c.status,{"Content-Type":"application/json; charset=utf-8",...c.headers??{}}),t.end(JSON.stringify(c.body));return}if(a.stream==="bytes"){await He(n,t,d,p.searchParams);return}if(a.stream){Ze(n,t,b,d,Qe(n,p.searchParams),h,"sse",f.stream);return}if(a.name==="llm"){const i=he(await P(n,Re)),S=new AbortController,c=s(()=>S.abort(),"abort");t.on("close",c);try{const R=await ye(i,S.signal,i.stream?m=>{t.headersSent||t.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache","X-Accel-Buffering":"no"}),t.write(`data: ${JSON.stringify(m)}
21
21
 
22
- `)}:void 0,void 0,{grantee:d.grantee,spend_cap:d.spend_cap},me($(d.grant)??Te(d.grant)));s.stream?(t.headersSent||t.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache","X-Accel-Buffering":"no"}),t.end(`data: [DONE]
22
+ `)}:void 0,void 0,{grantee:d.grantee,spend_cap:d.spend_cap},pe($(d.grant)??Ae(d.grant)));i.stream?(t.headersSent||t.writeHead(200,{"Content-Type":"text/event-stream","Cache-Control":"no-cache","X-Accel-Buffering":"no"}),t.end(`data: [DONE]
23
23
 
24
- `)):R(t,200,O.completion)}finally{t.off("close",c)}return}if(a.name==="usage.get"){R(t,200,ye(d.grantee,d.spend_cap,we(p.searchParams.get("month"))));return}if(a.name==="profile.list"){R(t,200,Ie(d));return}if(xe.has(a.name)){const s=await De(a.name,d,v.params.question_id,a.method==="POST"?await P(n):void 0);R(t,s.status,s.body);return}if(Xe.has(a.name)){const{signal:s,release:S}=Le(t);try{const c=await Ve(a.name,Ue(d),{params:v.params,body:a.method==="POST"?await P(n):void 0,query:p.searchParams},{requestId:h,signal:s});R(t,c.status,c.body)}catch(c){const O=$e(c,h,!0);t.writeHead(O.status,{"Content-Type":"application/json; charset=utf-8","X-Content-Type-Options":"nosniff",...O.headers}),t.end(JSON.stringify(O.body))}finally{S()}return}if(Je.has(a.name)){const s=Be(a.name,{class:"app",app:d.grantee,scopes:d.resolved},p.searchParams);R(t,s.status,s.body);return}if(Me.has(a.name)){const s=await He(a,d,v.params,p.searchParams,await P(n));R(t,s.status,s.body);return}const M=await le(a,d,b,p.searchParams,await P(n),n.headers["idempotency-key"]);R(t,M.status,M.body)}catch(N){Ye(t,N,h,b)}})()});return{ready:new Promise((n,t)=>{w.once("error",t),w.listen(u.port,u.address,()=>{w.off("error",t),n()})}),close:i(async()=>{_.close(),Ae(),w.closeAllConnections(),await new Promise((n,t)=>w.close(h=>h?t(h):n()))},"close")}}i(Dt,"createAppListener");export{We as RUN_STREAM_IDLE_MS,Dt as createAppListener,qe as cursor,Ke as streamRunEvents};
24
+ `)):O(t,200,R.completion)}finally{t.off("close",c)}return}if(a.name==="usage.get"){O(t,200,_e(d.grantee,d.spend_cap,we(p.searchParams.get("month"))));return}if(a.name==="profile.list"){O(t,200,ke(d));return}if(xe.has(a.name)){const i=await je(a.name,d,v.params.question_id,a.method==="POST"?await P(n):void 0);O(t,i.status,i.body);return}if($e.has(a.name)){const{signal:i,release:S}=Ue(t);try{const c=await Xe(a.name,Ve(d),{params:v.params,body:a.method==="POST"?await P(n):void 0,query:p.searchParams},{requestId:h,signal:i});O(t,c.status,c.body)}catch(c){const R=ze(c,h,!0);t.writeHead(R.status,{"Content-Type":"application/json; charset=utf-8","X-Content-Type-Options":"nosniff",...R.headers}),t.end(JSON.stringify(R.body))}finally{S()}return}if(Le.has(a.name)){const i=Je(a.name,{class:"app",app:d.grantee,scopes:d.resolved},p.searchParams);O(t,i.status,i.body);return}if(De.has(a.name)){const i=await Me(a,d,v.params,p.searchParams,await P(n));O(t,i.status,i.body);return}const M=await fe(a,d,b,p.searchParams,await P(n),n.headers["idempotency-key"]);O(t,M.status,M.body)}catch(N){qe(t,N,h,b)}})()});return{ready:new Promise((n,t)=>{w.once("error",t),w.listen(u.port,u.address,()=>{w.off("error",t),n()})}),close:s(async()=>{y.close(),Ne(),w.closeAllConnections(),await new Promise((n,t)=>w.close(h=>h?t(h):n()))},"close")}}s(xt,"createAppListener");export{Ke as RUN_STREAM_IDLE_MS,xt as createAppListener,Qe as cursor,Ze as streamRunEvents};
@@ -1,9 +1,9 @@
1
- var c=Object.defineProperty;var o=(e,t)=>c(e,"name",{value:t,configurable:!0});import{prepared as n}from"../../../core/sqlite-statements.js";import{openDb as r}from"../../../core/canvas/db.js";import{apiSocketPath as i}from"../../../core/canvas/paths.js";import{currentVersion as d}from"../../../core/self-update.js";import{API_VERSION as p}from"../../../api/index.js";import{DEFAULT_INTERVAL_MS as l}from"../../supervise-cadence.js";import{isPidPresent as _}from"../../../core/canvas/pid.js";import{boundDaemonControl as u}from"../../control.js";import{dueReport as m}from"../../due.js";const h=l;function a(){try{return n(r(),"SELECT 1 FROM nodes LIMIT 1").get(),!0}catch{return!1}}o(a,"canvasAccessible");function f(){const e={},t=n(r(),`
1
+ var i=Object.defineProperty;var o=(e,t)=>i(e,"name",{value:t,configurable:!0});import{prepared as r}from"../../../core/sqlite-statements.js";import{openDb as s}from"../../../core/canvas/db.js";import{apiSocketPath as c}from"../../../core/canvas/paths.js";import{currentVersion as d}from"../../../core/self-update.js";import{API_VERSION as p}from"../../../api/index.js";import{DEFAULT_INTERVAL_MS as l}from"../../supervise-cadence.js";import{isPidPresent as _}from"../../../core/canvas/pid.js";import{boundDaemonControl as u}from"../../control.js";import{dueReport as m}from"../../due.js";import{runtimeReadiness as h}from"../../readiness.js";const f=l;function a(){try{return r(s(),"SELECT 1 FROM nodes LIMIT 1").get(),!0}catch{return!1}}o(a,"canvasAccessible");function E(){const e={},t=r(s(),`
2
2
  SELECT status, COUNT(*) AS count
3
3
  FROM node_rows
4
4
  WHERE node_id NOT IN (SELECT node_id FROM warm_pool)
5
5
  GROUP BY status
6
- `).all();for(const s of t)e[s.status]=s.count;return e}o(f,"nodeCounts");function E(){return n(r(),`
6
+ `).all();for(const n of t)e[n.status]=n.count;return e}o(E,"nodeCounts");function T(){return r(s(),`
7
7
  SELECT pi_pid
8
8
  FROM node_rows
9
9
  WHERE node_id NOT IN (SELECT node_id FROM warm_pool)
@@ -11,4 +11,4 @@ var c=Object.defineProperty;var o=(e,t)=>c(e,"name",{value:t,configurable:!0});i
11
11
  AND pi_pid IS NOT NULL
12
12
  AND turn_open_at IS NOT NULL
13
13
  AND turn_closed_at IS NULL
14
- `).all().filter(t=>_(t.pi_pid)).length}o(E,"busyNodeCount");function N(){const e=a(),t=u()?.startupBlock()??null,s={ok:e&&t===null,daemon_up:!0,store_accessible:e,brokers_reconciled:t===null,startup_phase:t?.phase??"ready",...t===null?{}:{startup_blocked:t.message}};return{status:s.ok?200:503,body:s}}o(N,"handleHealthz");function T(e){if(!a())throw{status:503,code:"store_unavailable",message:"canvas store is inaccessible"};return{status:200,body:{daemon_pid:process.pid,tick_interval_ms:h,node_counts:f(),busy_node_count:E(),listeners:{socket_path:i(),tcp:e()},runtime_version:d(),api_version:p,startup_phase:u()?.startupBlock()?.phase??"ready"}}}o(T,"handleStatus");function b(){if(!a())throw{status:503,code:"store_unavailable",message:"canvas store is inaccessible"};return{status:200,body:m()}}o(b,"handleDue");function y(e){return[{method:"GET",pattern:"/healthz",handler:o(t=>N(),"handler")},{method:"GET",pattern:"/v1/status",handler:o(t=>T(e),"handler")},{method:"GET",pattern:"/v1/due",handler:o(t=>b(),"handler")}]}o(y,"healthRoutes");export{y as healthRoutes};
14
+ `).all().filter(t=>_(t.pi_pid)).length}o(T,"busyNodeCount");function b(){const e=a(),t=u()?.startupBlock()??null,n={ok:e&&t===null,daemon_up:!0,store_accessible:e,brokers_reconciled:t===null,startup_phase:t?.phase??"ready",...t===null?{}:{startup_blocked:t.message}};return{status:n.ok?200:503,body:n}}o(b,"handleHealthz");function N(){const e=h();return{status:e.ready?200:503,body:e}}o(N,"handleReady");function L(e){if(!a())throw{status:503,code:"store_unavailable",message:"canvas store is inaccessible"};return{status:200,body:{daemon_pid:process.pid,tick_interval_ms:f,node_counts:E(),busy_node_count:T(),listeners:{socket_path:c(),tcp:e()},runtime_version:d(),api_version:p,startup_phase:u()?.startupBlock()?.phase??"ready"}}}o(L,"handleStatus");function R(){if(!a())throw{status:503,code:"store_unavailable",message:"canvas store is inaccessible"};return{status:200,body:m()}}o(R,"handleDue");function F(e){return[{method:"GET",pattern:"/healthz",handler:o(t=>b(),"handler")},{method:"GET",pattern:"/v1/ready",handler:o(t=>N(),"handler")},{method:"GET",pattern:"/v1/status",handler:o(t=>L(e),"handler")},{method:"GET",pattern:"/v1/due",handler:o(t=>R(),"handler")}]}o(F,"healthRoutes");export{F as healthRoutes};