@north-light/cli 0.3.502 → 0.3.504

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.
@@ -2,7 +2,7 @@ import { type AssistantMessageEventStream, type Context, type Model, type Models
2
2
  import type { ModelRuntime } from '@earendil-works/pi-coding-agent';
3
3
  /** Pi uses availability and auth for its model controls; only the daemon can
4
4
  * decide whether a route has credentials. Keep the broker's metadata selectable. */
5
- export declare function configureBrokerModelRuntime(runtime: ModelRuntime): void;
5
+ export declare function configureBrokerModelRuntime(runtime: ModelRuntime, intent?: string): void;
6
6
  export declare const LLM_BROKER_RETRY_WINDOW_S = 300;
7
7
  export declare const LLM_REFUSAL_DIAGNOSTIC = "crtr:llm-refusal";
8
8
  /** The retry deadline (epoch ms) a final daemon refusal carried on its
@@ -19,6 +19,7 @@ export declare function refusalRetryAt(message: {
19
19
  * (Anthropic rejects assistant prefill with a 400), so trailing assistants go
20
20
  * too. */
21
21
  export declare function wireHistory(messages: Context['messages']): Context['messages'];
22
- export declare function requestBody(model: Model<any>, context: Context, options: ModelsSimpleStreamOptions): Record<string, unknown>;
22
+ export declare function requestBody(model: Model<any>, context: Context, options: ModelsSimpleStreamOptions, intentOverride?: string): Record<string, unknown>;
23
23
  /** One pi stream, backed exclusively by the authenticated daemon llm route. */
24
- export declare function streamBrokerModel(model: Model<any>, context: Context, options?: ModelsSimpleStreamOptions): AssistantMessageEventStream;
24
+ /** `intent` replaces the node's own `CRTR_MODEL_INTENT` for one stream: a background one-shot of an app-paid node asks for `app/light`, not the node's rung. */
25
+ export declare function streamBrokerModel(model: Model<any>, context: Context, options?: ModelsSimpleStreamOptions, intent?: string): AssistantMessageEventStream;
@@ -1,2 +1,2 @@
1
- var U=Object.defineProperty;var c=(t,e)=>U(t,"name",{value:e,configurable:!0});import{setTimeout as W}from"node:timers/promises";import{createAssistantMessageEventStream as j,getCurrentSystemPrompt as J,getCurrentTools as Y}from"@earendil-works/pi-ai";import{socketFetch as z}from"../../../api/node-transport.js";import{apiSocketPath as X}from"../../canvas/paths.js";import{currentNodeToken as G}from"./node-token.js";import{envModelExact as O,envModelIntent as H}from"../../../shared/env.js";import{MODEL_CONTEXT_BODY_MAX_BYTES as k}from"../../llm/body-limits.js";import{modelRequestFromConfig as K}from"../../model-routes.js";import{parseProviderRateLimit as V,providerFailureDiagnostic as v}from"../../provider-failure.js";import{UPSTREAM_MODEL_UNAVAILABLE as E}from"../../fault-classifier.js";function fe(t){t.checkAuth=async e=>t.getProvider(e)?{type:"api_key"}:void 0,t.getAvailable=async e=>t.getModels(e),t.getAvailableSnapshot=()=>t.getModels(),t.streamSimple=te}c(fe,"configureBrokerModelRuntime");const Q=300,$="crtr:llm-refusal";class b extends Error{static{c(this,"LlmRefusalError")}retryAt;rateLimit;code;status;constructor(e,o,r,n,i){super(e),this.retryAt=o,this.rateLimit=r,this.code=n,this.status=i}}class R extends Error{static{c(this,"UpstreamModelUnavailableError")}}function C(t,e){const o=t===void 0?"the request body":`the request body (${t} bytes)`;return new Error(`request_too_large: ${o} exceeds the ${e}-byte model request limit; compact the conversation to shrink the context`)}c(C,"contextTooLargeError");function N(t){const e=t.details?.rate_limit;if(!e||typeof e!="object")return;const o=V(e);if(o===void 0)return;const{provider:r,model:n}=e;return typeof r=="string"&&r!==""&&typeof n=="string"&&n!==""?{...o,model:`${r}/${n}`}:o}c(N,"refusalRateLimit");function me(t){for(const e of t.diagnostics??[]){if(e.type!==$)continue;const o=e.details?.retryAt;if(typeof o=="number"&&Number.isFinite(o)&&o>0)return o}}c(me,"refusalRetryAt");class D extends Error{static{c(this,"ContentFilteredError")}}function q(t){return typeof t=="string"?t:t.map(e=>e.type==="text"?{type:"text",text:e.text}:{type:"image_url",image_url:{url:`data:${e.mimeType};base64,${e.data}`}})}c(q,"wireContent");function Z(t){const e=c(n=>n.role==="assistant"&&(n.stopReason==="error"||n.stopReason==="aborted"),"incomplete"),o=t.some(e)?t.filter(n=>!e(n)):t;let r=o.length;for(;r>0&&o[r-1]?.role==="assistant";)r--;return r===o.length?o:o.slice(0,r)}c(Z,"wireHistory");function ee(t,e,o){const r=[],n=J(e.messages),i=Y(e.messages);n?r.push({role:"system",content:n}):e.systemPrompt&&r.push({role:"system",content:e.systemPrompt});for(const u of Z(e.messages))u.role==="user"?r.push({role:"user",content:q(u.content)}):u.role==="toolResult"?r.push({role:"tool",content:q(u.content),tool_call_id:u.toolCallId}):u.role==="assistant"&&r.push({role:"assistant",content:u.content.filter(d=>d.type==="text").map(d=>d.text).join("")||null,tool_calls:u.content.filter(d=>d.type==="toolCall").map(d=>({id:d.id,type:"function",function:{name:d.name,arguments:JSON.stringify(d.arguments)}}))});const w=`${t.provider}/${t.id}`,y=H();return{model:K(w,y,O())?.kind==="logical"?y:w,model_policy:O()?"exact":"substitute",stream:!0,messages:r,...i.length?{tools:i.map(u=>({type:"function",function:{name:u.name,description:u.description,parameters:u.parameters}}))}:{},...o.reasoning?{reasoning_effort:o.reasoning}:{},...o.temperature!==void 0?{temperature:o.temperature}:{},...o.maxTokens!==void 0?{max_tokens:o.maxTokens}:{}}}c(ee,"requestBody");function S(t,e){if(typeof e!="string")return!1;const o=e.indexOf("/");return o<1||o===e.length-1?!1:(t.provider=e.slice(0,o),t.model=e.slice(o+1),!0)}c(S,"applyServedModel");function B(t){if(t.details?.served_model!==void 0)return t.details.served_model;const e=t.details?.rate_limit;return typeof e?.provider=="string"&&typeof e.model=="string"?`${e.provider}/${e.model}`:void 0}c(B,"refusalRoute");function F(t){if(!t||typeof t!="object"||!("error"in t))throw new Error("llm returned an invalid response");const e=t.error;if(!e||typeof e.message!="string")throw new Error("llm returned an invalid refusal");return e}c(F,"parseRefusal");function te(t,e,o={}){const r=j(),n={role:"assistant",content:[],api:t.api,provider:t.provider,model:t.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=G();if(!i)throw new Error("llm requires a node token");const w=JSON.stringify(ee(t,e,o)),y=Buffer.byteLength(w);if(y>k)throw C(y,k);let u=0;for(;;){o.signal?.throwIfAborted();const d=await z(X())("http://localhost/v1/llm",{method:"POST",headers:{authorization:`Bearer ${i}`,"content-type":"application/json"},body:w,signal:o.signal});if(!d.ok){const l=F(await d.json());if(d.status===413||l.code==="payload_too_large")throw C(y,k);if(S(n,B(l)),l.retryable!==!0)throw new b(l.message,void 0,N(l),l.code,d.status);const s=l.retry_after_s;if(typeof s!="number"||!Number.isFinite(s)||s<=0)throw l.code===E?new R(l.message):new Error(l.message);const f=Q-u;if(s>f){const p=Date.now()+s*1e3;throw new b(`${l.message} (retry after ${s}s, at ${new Date(p).toISOString()})`,p,N(l))}await W(s*1e3,void 0,{signal:o.signal}),u+=s;continue}if(!d.body)throw new Error("llm returned no stream");r.push({type:"start",partial:n});const P=d.body.getReader(),A=new TextDecoder;let h="",_="stop",L,I=!1,M=!1;const T=c(l=>{const s=JSON.parse(l);if(s.error){const a=F(s);throw S(n,B(a)),a.code===E?new R(a.message):new Error(a.message)}if(s.served_model){if(M=!0,s.served_model.indexOf("/")<1)throw new Error("llm returned an invalid served_model");S(n,s.served_model)}const f=s.choices?.[0],p=f?.delta;if(p?.reasoning_content){const a=n.content.findIndex(x=>x.type==="thinking"),m=a<0?{type:"thinking",thinking:""}:n.content[a],g=a<0?n.content.push(m)-1:a;if(a<0&&r.push({type:"thinking_start",contentIndex:g,partial:n}),m.type!=="thinking")throw new Error("invalid thinking block");m.thinking+=p.reasoning_content,r.push({type:"thinking_delta",contentIndex:g,delta:p.reasoning_content,partial:n})}if(p?.content){const a=n.content.findIndex(x=>x.type==="text"),m=a<0?{type:"text",text:""}:n.content[a],g=a<0?n.content.push(m)-1:a;if(a<0&&r.push({type:"text_start",contentIndex:g,partial:n}),m.type!=="text")throw new Error("invalid text block");m.text+=p.content,r.push({type:"text_delta",contentIndex:g,delta:p.content,partial:n})}for(const a of p?.tool_calls??[]){const m={type:"toolCall",id:a.id,name:a.function.name,arguments:JSON.parse(a.function.arguments)},g=n.content.push(m)-1;r.push({type:"toolcall_start",contentIndex:g,partial:n}),r.push({type:"toolcall_end",contentIndex:g,toolCall:m,partial:n})}f?.finish_reason&&(_=f.finish_reason),f?.message?.refusal&&(L=f.message.refusal),s.usage&&(I=!0,n.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 P.read();if(s)break;h+=A.decode(l,{stream:!0});let f;for(;(f=h.indexOf(`
2
- `))>=0;){const p=h.slice(0,f).trim();h=h.slice(f+1),p&&T(p)}}if(h+=A.decode(),h.trim()&&T(h.trim()),!I||!M)throw new Error("llm stream ended without usage or served_model");for(const[l,s]of n.content.entries())s.type==="text"&&r.push({type:"text_end",contentIndex:l,content:s.text,partial:n}),s.type==="thinking"&&r.push({type:"thinking_end",contentIndex:l,content:s.thinking,partial:n});if(_==="content_filter")throw new D(L??"Content filtered");if(!["stop","tool_calls","length"].includes(_))throw new Error(`llm returned unknown finish reason: ${_}`);n.stopReason=_==="tool_calls"?"toolUse":_==="length"?"length":"stop",r.push({type:"done",reason:n.stopReason,message:n}),r.end();return}})().catch(i=>{n.stopReason=o.signal?.aborted?"aborted":"error",n.errorMessage=i instanceof Error?i.message:String(i),i instanceof b&&(n.diagnostics=[{type:$,timestamp:Date.now(),...i.retryAt!==void 0?{details:{retryAt:i.retryAt}}:{}},...i.rateLimit!==void 0?[v({status:429,ratelimit:i.rateLimit})]:[],...i.rateLimit===void 0&&i.code==="cap_exhausted"?[v({status:i.status??402,code:i.code})]:[]]),i instanceof R&&(n.diagnostics=[v({status:503,code:E})]),i instanceof D&&n.stopReason==="error"&&(n.rawStopReason="content_filter"),r.push({type:"error",reason:n.stopReason,error:n}),r.end()}),r}c(te,"streamBrokerModel");export{Q as LLM_BROKER_RETRY_WINDOW_S,$ as LLM_REFUSAL_DIAGNOSTIC,fe as configureBrokerModelRuntime,me as refusalRetryAt,ee as requestBody,te as streamBrokerModel,Z 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 $,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 +1 @@
1
- var j=Object.defineProperty;var a=(e,t)=>j(e,"name",{value:t,configurable:!0});import{envNodeCwd as F,envProfileId as D}from"../../shared/env.js";import{join as h}from"node:path";import{InMemoryCredentialStore as E}from"@earendil-works/pi-ai";import{PoolCredentialStore as L}from"../pool-credential-store.js";import{secretsDir as N}from"../layout.js";import{expandModelCandidates as O,modelRequestFromConfig as _,selectInitialModelRoute as B}from"../model-routes.js";import{configureBrokerModelRuntime as H}from"./broker/model-adapter.js";import{currentNodeToken as z}from"./broker/node-token.js";function G(e){for(let t=e.length-1;t>=0;t--){const i=e[t];if(i?.role!=="assistant")continue;if(typeof i.content=="string")return i.content.trim();if(!Array.isArray(i.content))continue;const r=i.content.map(l=>{const o=l;return o.type==="text"&&typeof o.text=="string"?o.text:""}).join("").trim();if(r!=="")return r}return""}a(G,"lastAssistantText");async function p(e,t,i){let r,l=!1,o=!1,g;const y=a(n=>{r===void 0||l||(l=!0,n&&r.abort().catch(()=>{}),r.dispose())},"disposeSession"),v=new Promise(n=>{g=setTimeout(()=>{o=!0,y(!0),n(t)},e.timeoutMs)}),R=(async()=>{try{const n=await import("@earendil-works/pi-coding-agent"),c=z()!==void 0;if(o)return t;const m=F()??process.cwd(),u=D(),x=n.getAgentDir(),w=await n.ModelRuntime.create({credentials:c?new E:new L(h(N(),"auth.json")),modelsPath:h(x,"models.json")});if(c&&H(w),o)return t;const M=await n.createAgentSessionServices({cwd:m,agentDir:x,modelRuntime:w,settingsManager:n.SettingsManager.inMemory(),resourceLoaderOptions:{noExtensions:!0,noContextFiles:!0,noSkills:!0,noPromptTemplates:!0,noThemes:!0,systemPrompt:e.systemPrompt,...c?{}:{extensionFactories:[(await import("../../builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js")).createProviderRotationExtension({modelIntent:e.modelIntent,nodeCwd:m,profileId:u})]}}});if(o)return t;const f=_(e.modelSpec,e.modelIntent,!1);if(f===void 0)return t;const S=new n.ModelRegistry(M.modelRuntime),T=c?O(f,m,u).map(d=>S.find(d.providerId,d.modelId)).find(d=>d!==void 0):B(f,S,{cwd:m,profileId:u}).selected?.model;if(T===void 0)return t;let I;const s=e.tool,C=s===void 0?void 0:n.defineTool({name:s.name,label:s.label,description:s.description,parameters:s.parameters,...s.constrainedSampling===void 0?{}:{constrainedSampling:s.constrainedSampling},async execute(d,A){return I=A,{content:[{type:"text",text:"Recorded."}],details:{recorded:!0},terminate:!0}}}),P=n.SessionManager.inMemory(m,e.sessionId===void 0?void 0:{id:e.sessionId});for(const d of e.seedMessages??[])P.appendMessage(d);return{session:r}=await n.createAgentSessionFromServices({services:M,sessionManager:P,model:T,thinkingLevel:"off",...s===void 0?e.toolPolicy==="builtin"?{}:{noTools:"all"}:{tools:[s.name],customTools:[C]}}),o||(await r.bindExtensions({}),o)?t:(await r.prompt(e.userPrompt),o?t:i(r,I))}catch{return t}finally{y(!1)}})();try{return await Promise.race([R,v])}finally{clearTimeout(g)}}a(p,"runHeadless");function $(e){return p(e,null,(t,i)=>i)}a($,"headlessToolCall");function b(e){return p(e,"",t=>G(t.messages))}a(b,"headlessText");function k(e){return p(e,"failed",()=>"completed")}a(k,"headlessTurn");export{b as headlessText,$ as headlessToolCall,k as headlessTurn};
1
+ var E=Object.defineProperty;var s=(e,t)=>E(e,"name",{value:t,configurable:!0});import{envModelIntent as _,envNodeCwd as N,envProfileId as O}from"../../shared/env.js";import{join as C}from"node:path";import{InMemoryCredentialStore as $}from"@earendil-works/pi-ai";import{PoolCredentialStore as B}from"../pool-credential-store.js";import{secretsDir as H}from"../layout.js";import{APP_FAMILY as g,expandModelCandidates as W,modelRequestFromConfig as A,selectInitialModelRoute as Y}from"../model-routes.js";import{defaultModelLaddersConfig as z}from"../../types.js";import{stripThinkingSuffix as G}from"./model-selection.js";import{configureBrokerModelRuntime as J}from"./broker/model-adapter.js";import{currentNodeToken as K}from"./broker/node-token.js";function Q(e){for(let t=e.length-1;t>=0;t--){const n=e[t];if(n?.role!=="assistant")continue;if(typeof n.content=="string")return n.content.trim();if(!Array.isArray(n.content))continue;const c=n.content.map(i=>{const l=i;return l.type==="text"&&typeof l.text=="string"?l.text:""}).join("").trim();if(c!=="")return c}return""}s(Q,"lastAssistantText");function U(e,t){const n=_();if(!(n===void 0||!n.startsWith(`${g}/`)))return t?{modelRequest:A(e.modelSpec,n,!1),intent:n}:{modelRequest:{kind:"logical",family:g,strength:"light",spec:G(z().anthropic.light)},intent:`${g}/light`}}s(U,"appPaidRequest");async function y(e,t,n,c){let i,l=!1,d=!1,x;const M=s(o=>{i===void 0||l||(l=!0,o&&i.abort().catch(()=>{}),i.dispose())},"disposeSession"),F=new Promise(o=>{x=setTimeout(()=>{d=!0,M(!0),o(t)},e.timeoutMs)}),j=(async()=>{try{const o=await import("@earendil-works/pi-coding-agent"),m=K()!==void 0;if(d)return t;const u=N()??process.cwd(),f=O(),h=o.getAgentDir(),w=await o.ModelRuntime.create({credentials:m?new $:new B(C(H(),"auth.json")),modelsPath:C(h,"models.json")}),S=m?U(e,n):void 0;if(m&&J(w,S?.intent),d)return t;const I=await o.createAgentSessionServices({cwd:u,agentDir:h,modelRuntime:w,settingsManager:o.SettingsManager.inMemory(),resourceLoaderOptions:{noExtensions:!0,noContextFiles:!0,noSkills:!0,noPromptTemplates:!0,noThemes:!0,systemPrompt:e.systemPrompt,...m?{}:{extensionFactories:[(await import("../../builtin-pi-packages/pi-crtr-extensions/extensions/provider-rotation.js")).createProviderRotationExtension({modelIntent:e.modelIntent,nodeCwd:u,profileId:f})]}}});if(d)return t;const p=S?.modelRequest??A(e.modelSpec,e.modelIntent,!1);if(p===void 0)return t;const P=new o.ModelRegistry(I.modelRuntime),R=m?W(p,u,f).map(a=>P.find(a.providerId,a.modelId)).find(a=>a!==void 0):Y(p,P,{cwd:u,profileId:f}).selected?.model;if(R===void 0)return t;let T;const r=e.tool,L=r===void 0?void 0:o.defineTool({name:r.name,label:r.label,description:r.description,parameters:r.parameters,...r.constrainedSampling===void 0?{}:{constrainedSampling:r.constrainedSampling},async execute(a,D){return T=D,{content:[{type:"text",text:"Recorded."}],details:{recorded:!0},terminate:!0}}}),v=o.SessionManager.inMemory(u,e.sessionId===void 0?void 0:{id:e.sessionId});for(const a of e.seedMessages??[])v.appendMessage(a);return{session:i}=await o.createAgentSessionFromServices({services:I,sessionManager:v,model:R,thinkingLevel:"off",...r===void 0?e.toolPolicy==="builtin"?{}:{noTools:"all"}:{tools:[r.name],customTools:[L]}}),d||(await i.bindExtensions({}),d)?t:(await i.prompt(e.userPrompt),d?t:c(i,T))}catch{return t}finally{M(!1)}})();try{return await Promise.race([j,F])}finally{clearTimeout(x)}}s(y,"runHeadless");function re(e){return y(e,null,!1,(t,n)=>n)}s(re,"headlessToolCall");function se(e){return y(e,"",!1,t=>Q(t.messages))}s(se,"headlessText");function de(e){return y(e,"failed",!0,()=>"completed")}s(de,"headlessTurn");export{se as headlessText,re as headlessToolCall,de as headlessTurn};
@@ -1,3 +1,3 @@
1
- var $e=Object.defineProperty;var c=(e,t)=>$e(e,"name",{value:t,configurable:!0});import{prepared as Se}from"../../../core/sqlite-statements.js";import{ApiError as y}from"../../../api/errors.js";import{PRIVACY_LEVELS_DTO as Ae}from"../../../api/dto/objects.js";import{openDb as T,withCanvasWrite as k}from"../../../core/canvas/db.js";import{actorOf as ee}from"../../../core/graph/documents.js";import{readerForObject as C,readerFor as Ie}from"../../../core/graph/reader.js";import{resolveName as Ne}from"../../../core/graph/names.js";import{canRead as te,customReachable as Fe,holdsObjectsScope as Le,mayActAs as ne}from"../../../core/graph/access.js";import{customObjectRef as re,authorizeCustom as oe,fenceArgv as D}from"./custom-objects.js";import{edgesOf as Pe}from"../../../core/graph/edges.js";import{publish as M}from"../../../core/graph/events.js";import{objectDTO as g}from"../../../core/graph/kinds/dto.js";import{isKind as We,kindNames as Ce,kindOf as G}from"../../../core/graph/kinds/registry.js";import{listObjects as De,searchObjects as ie}from"../../../core/graph/objects.js";import{checkoutsForCwd as Me}from"../../../core/graph/repo-sync/repos.js";import{recordWatch as P,unwatch as se,watchersOf as Ge,watchesOf as ze}from"../../../core/graph/watches.js";import{readerFor as v,resolveRef as z}from"../reader.js";import{readDelegationFor as ae,runReadLeaf as Ue}from"../../plugin-objects/read-leaf.js";import{invalidRequest as W,isRecord as R}from"./validate.js";import{callerNode as ue,callerStub as U,forwardVerb as ce,originates as le,queryWithoutMachine as V,relayError as B,remoteStub as Ve,unknownError as fe,forwarding as F,withMachine as H}from"../../peer/forward.js";import{getById as L,getByRowid as de}from"../../../core/graph/objects.js";import{ensureNodeStub as Be,isStub as me,stubOf as He,withKindDecl as $}from"../../../core/peer/stubs.js";import{isUnreachable as Ke}from"../../../core/peer/client.js";import{normalizeMachineId as S}from"../../../core/peer/directory.js";const A=c(e=>t=>Me(e,t),"reposFnFor");function he(e,t){return{...g(e,t),...G(e,t.type).listItem?.(e,t)}}c(he,"listItem");function Ze(e){return`no object named ${e} on this runtime; it may be on another runtime, or the name may be misspelled`}c(Ze,"remoteMessage");function pe(e,t,n){try{return q(e,t,n)}catch(r){if(r instanceof y&&r.code==="not_found"&&!r.details?.deleted)return null;throw r}}c(pe,"ownerFilter");function q(e,t,n){const r=z(e,t,n);if("remote"in r)throw new y(404,"not_found",Ze(r.remote),{next:"Check the name with `crtr canvas search`."});if("deleted"in r)throw new y(404,"not_found",`${r.deleted.name} is deleted`,{id:r.deleted.id,deleted:!0});return r}c(q,"liveRef");const _=c(e=>decodeURIComponent(e.params.ref),"refParam"),we=c(e=>{const t=e.trim().replace(/^\[\[(.*)\]\]$/,"$1").trim(),n=t.indexOf("/");return n>0?t.slice(0,n):t},"idOf");function ye(e){const t=L(T(),we(e));return t!==null&&me(T(),t)?t.id:null}c(ye,"stubIdOf");async function K(e,t,n,r){const o=ye(t);return o!==null?ce(e,o,n):r()?{kind:"local"}:le(e.principal)?ce(e,we(t),n):{kind:"local"}}c(K,"forwardRef");function Z(e,t){return k(n=>{try{return!("remote"in z(n,v(n,t),e))}catch{return!1}})}c(Z,"resolvesLocally");const J=c(e=>`/v1/objects/${encodeURIComponent(e)}`,"objectPath");function ge(e,t,n,r,o){const i=t?.object;!i?.id||!i.type||k(s=>{const a=ue(s,e);if(a===null)return;const l=Ve(s,i.id,i.type,n,{kind:i.kind??null,name:i.name??i.id,...i.preview===void 0?{}:{preview:i.preview},owner:i.owner??null,...i.kind_decl===void 0?{}:{kind_decl:i.kind_decl},...i.privacy===void 0?{}:{privacy:i.privacy}});P(s,a,l,r,o===void 0?{}:{patterns:o})})}c(ge,"watchRemote");async function Je(e){const t=_(e),n=["1","true"].includes(e.query.get("fields")??""),r=await K(e,t,{method:"GET",path:J(t),query:V(e)},()=>Z(t,e));if(r.kind==="unknown")return{state:"unknown",ref:t,unreachable:r.unreachable};if(r.kind==="remote"){if(r.status>=400)throw B(r.status,r.body);return ge(e,r.body,r.machine.id,"read"),H(r.body,r.machine)}const o=c(a=>{const l=U(a,e);return l===null?v(a,e):C(a,l,A(a))},"readerOf"),i=k(a=>{const l=o(a),u=z(a,l,t);if("remote"in u)return{state:"remote",remote:u.remote};if("deleted"in u)return{state:"deleted",deleted:g(a,u.deleted)};const f=ae(a,u);if(f!==null)return{delegate:f,hitId:u.id};const{data:m,text:b}=G(a,u.type).read(a,l,u,{fields:n,reposFn:A(a)});return{state:"object",type:u.type,object:$(a,u,g(a,u)),text:b,data:m}});if(!("delegate"in i))return i;const s=await Ue(i.delegate,e.principal);return k(a=>{const l=o(a),u=L(a,i.hitId);if(u===null)throw new y(404,"not_found","object not found");if(u.deleted_at!==null)return{state:"deleted",deleted:g(a,u)};if(!te(a,l,u))throw new y(404,"not_found","object not found");const{data:f,text:m}=G(a,u.type).read(a,l,u,{fields:n,reposFn:A(a)});return ae(a,u)===null?{state:"object",type:u.type,object:$(a,u,g(a,u)),text:m,data:f}:{state:"object",type:u.type,object:$(a,u,g(a,u)),text:"markdown"in s?s.markdown:`${m}
2
- content unavailable: ${s.unavailable}`,data:{...f,content:"markdown"in s?"live":"unavailable"}}})}c(Je,"read");function Q(e,t,n,r){if(e!=null){if(!n.includes(e)){r.push({field:t,problem:`must be one of ${n.join(", ")}`,received:e});return}return e}}c(Q,"oneOf");function be(e,t,n){if(t!=null){if(typeof t!="string"||!We(e,t)){n.push({field:"type",problem:`must be a kind: one of ${Ce(e).join(", ")}`,received:t});return}return t}}c(be,"kindName");function je(e,t,n,r){if(e==null)return r;const o=Number(e);return!Number.isInteger(o)||o<1||o>100?(n.push({field:t,problem:"must be an integer from 1 to 100",received:e}),r):o}c(je,"limitOf");function ke(e){const t=e.query,n=[],r=be(T(),t.get("type"),n),o=Q(t.get("privacy"),"privacy",Ae,n),i=je(t.get("limit"),"limit",n,50),s=t.get("cursor");s!==null&&!/^\d+$/.test(s)&&n.push({field:"cursor",problem:"is not a cursor from a previous page",received:s});const a=t.get("deleted");return a!==null&&!["0","1","true","false"].includes(a)&&n.push({field:"deleted",problem:"must be true or false",received:a}),n.length>0&&W("object list request",n),k(l=>{const u=v(l,e),f={...r?{type:r}:{},...o?{privacy:o}:{},...t.get("kind")!==null?{kind:t.get("kind")}:{},...a==="1"||a==="true"?{deleted:!0}:{}},m=t.get("owner");if(m!==null){const h=pe(l,u,m);if(h===null)return{items:[],next_cursor:null};f.owner=h}const b=t.get("name"),j=[];let p=s===null?0:Number(s),w=!0;for(;j.length<i&&w;){const h=De(l,u,f,{limit:100,after_rowid:p});w=h.length===100;for(const E of h)if(p=E.rowid,(b===null||E.name.startsWith(b))&&j.push(E),j.length===i)break}const d=j.at(-1);return{items:j.map(h=>he(l,h)),next_cursor:j.length===i&&d?String(d.rowid):null}})}c(ke,"listLocal");const Qe={ms:3e4},Ye="self",Y=c((e,t)=>e.map(n=>({...n,machine:t})),"labelItems");async function _e(e,t,n,r){const o=F.current;try{const i=await o.call(t.id,{method:"GET",path:"/v1/objects",query:n},o.envelope(e.principal),r);if(Ke(i))return{state:"unreachable",items:[],next:null};if(i.status===426)return{state:"too_old",items:[],next:null};const s=i.body;return i.status!==200||!Array.isArray(s?.items)?{state:"unreachable",items:[],next:null}:{state:"ok",items:Y(s.items,t),next:s.next_cursor??null}}catch{return{state:"unreachable",items:[],next:null}}}c(_e,"remotePage");async function Xe(e){const t=new Promise(n=>e.addEventListener("abort",()=>n(null),{once:!0}));return Promise.race([F.current.machines().catch(()=>null),t])}c(Xe,"machinesWithin");async function xe(e){const t=e.query.get("machine");if(!le(e.principal)||!F.current.joined()||t===Ye)return ke(ve(e));const r=F.current.self(),o=t!==null&&S(t)!==r,i=o?null:ke(ve(e)),s=new AbortController,a=setTimeout(()=>s.abort(),Qe.ms);a.unref?.();try{const l=await Xe(s.signal);if(l===null){if(o)throw new y(503,"runtime_unreachable",`The directory did not answer, so ${S(t)} cannot be listed.`,{machine:S(t)});return i}const u=c(d=>({id:d,name:l.find(h=>h.machine_id===d)?.name??d}),"labelOf"),f=u(r),m=l.filter(d=>d.machine_id!==r&&d.kind!=="device"),b=V(e);if(t!==null){if(!o)return{items:Y(i.items,f),next_cursor:i.next_cursor,machines:[{machine_id:r,name:f.name,state:"ok",more:i.next_cursor!==null}]};const d=S(t);if(!m.some(E=>E.machine_id===d))throw new y(404,"not_found",`no machine ${d} on your account`,{machine:d});const h=await _e(e,u(d),b,s.signal);return{items:h.items,next_cursor:h.next,machines:[{machine_id:d,name:u(d).name,state:h.state,more:h.next!==null}]}}const{cursor:j,...p}=b,w=await Promise.all(m.map(d=>_e(e,u(d.machine_id),p,s.signal)));return{items:[...Y(i.items,f),...w.flatMap(d=>d.items)],next_cursor:i.next_cursor,machines:[{machine_id:r,name:f.name,state:"ok",more:i.next_cursor!==null},...m.map((d,h)=>({machine_id:d.machine_id,name:d.name,state:w[h].state,more:w[h].next!==null}))]}}finally{clearTimeout(a)}}c(xe,"list");function ve(e){const t=new URLSearchParams(e.query);return t.delete("machine"),{...e,query:t}}c(ve,"withoutMachine");function et(e){const t=[],n=R(e.body)?e.body:{};R(e.body)||t.push({field:"body",problem:"must be an object",received:e.body});const r=n.text;(typeof r!="string"||r.trim()==="")&&t.push({field:"text",problem:"is required",received:r});const o=n.grep;if(o!==void 0)if(typeof o!="string")t.push({field:"grep",problem:"must be a regular expression string",received:o});else try{new RegExp(o)}catch(a){t.push({field:"grep",problem:`is not a valid regular expression: ${a.message}`,received:o})}n.body!==void 0&&typeof n.body!="boolean"&&t.push({field:"body",problem:"must be a boolean",received:n.body});const i=be(T(),n.type,t);n.kind!==void 0&&typeof n.kind!="string"&&t.push({field:"kind",problem:"must be a string",received:n.kind}),n.owner!==void 0&&typeof n.owner!="string"&&t.push({field:"owner",problem:"must be a string",received:n.owner});const s=je(n.limit,"limit",t,50);return t.length>0&&W("object search request",t),k(a=>{const l=v(a,e),u=typeof n.owner=="string"?pe(a,l,n.owner):null;if(typeof n.owner=="string"&&u===null)return{items:[]};const f=ie(a,l,{text:r,body:n.body===!0||typeof o=="string"}),m=new Set(f.map(p=>p.object.rowid));return{items:(typeof o=="string"?ie(a,l,{text:o,grep:!0}).filter(p=>m.has(p.object.rowid)):f).filter(p=>(!i||p.object.type===i)&&(n.kind===void 0||p.object.kind===n.kind)&&(!u||p.object.owner===u.rowid)).slice(0,s).map(p=>({object:he(a,p.object),...p.line!==void 0?{matches:[{line:p.line,text:p.text??""}]}:{}}))}})}c(et,"search");const Oe=["interrupt","steer","after-turn","next-turn"],tt=/^(\*|>|[A-Za-z0-9_-]+)(\.(\*|>|[A-Za-z0-9_-]+))*$/;function nt(e,t){if(e!==void 0){if(!Array.isArray(e)||e.length===0||e.some(n=>typeof n!="string"||!tt.test(n)||n.includes(">")&&!n.endsWith(">"))){t.push({field:"patterns",problem:"must be a non-empty list of event patterns (dot-separated words, `*` for one word, a final `>` for the rest)",received:e});return}return e}}c(nt,"patternsOf");function rt(e,t){if(e===void 0)return;if(!R(e)||Object.keys(e).length===0){t.push({field:"config",problem:"must map levels 1-10 to a delivery",received:e});return}const n=[];for(const[r,o]of Object.entries(e)){const i=Number(r);!Number.isInteger(i)||i<1||i>10?t.push({field:`config.${r}`,problem:"level must be an integer from 1 to 10"}):Oe.includes(o)?n.push({threshold:i,delivery:o}):t.push({field:`config.${r}`,problem:`delivery must be one of ${Oe.join(", ")}`,received:o})}return n.sort((r,o)=>o.threshold-r.threshold)}c(rt,"configOf");function Ee(e){const t=ye(e);if(t!==null)throw new y(400,"invalid_request",`${t} lives on another machine; an explicit watcher cannot watch it from here`,{id:t})}c(Ee,"refuseStubWatch");function X(e,t){const n=L(e,t)??(()=>{const r=Ne(e,Ie(e,{class:"person"},()=>[]),t);return"object"in r?r.object:null})();return n===null||n.deleted_at!==null||!(n.type.includes(".")||n.type==="node")?null:n}c(X,"findWatcher");const O=c(()=>{throw new y(404,"not_found","watcher not found")},"watcherNotFound");async function qe(e,t,n){if(typeof t!="string"||n===void 0||n===null)return null;if(typeof n!="string")throw new y(400,"invalid_request","invalid watcher_machine");if(X(e,t)!==null)return null;const r=F.current;let o;try{o=await r.machines()}catch{throw new y(503,"runtime_unreachable","The directory did not answer, so the watcher machine cannot be checked.")}const i=S(n);return(i===r.self()||!o.some(s=>S(s.machine_id)===i))&&O(),i}c(qe,"remoteWatcherMachine");function Te(e,t,n,r){if(t.publishToken||t.principal.class==="anonymous")return O();const o=v(e,t);if(o.class==="person")return O();let i;try{i=q(e,o,r)}catch{return O()}const s=i.owner===null?null:de(e,i.owner);return s===null||!ne(e,o,s)||!Le(e,o,"link",n)?O():(D(e,t,n),{actor:o.app,object:i})}c(Te,"linkWatcher");function Re(e,t,n){if(t.publishToken)return!0;if(t.principal.class==="anonymous"||!n.type.includes("."))return!1;const r=v(e,t),o=n.owner===null?null:de(e,n.owner);return o!==null&&ne(e,r,o)&&Fe(e,r,n)}c(Re,"ownsWatcher");async function ot(e){const t=_(e),n=R(e.body)?e.body:{};if(typeof n.watcher=="string"&&Ee(t),typeof n.watcher!="string"){const o=await K(e,t,{method:"POST",path:`${J(t)}/watch`,body:e.body},()=>Z(t,e));if(o.kind==="unknown")throw fe(t,o.unreachable);if(o.kind==="remote"){if(o.status>=400)throw B(o.status,o.body);const i=o.body.patterns;return ge(e,o.body,o.machine.id,"ask",i),H(o.body,o.machine)}}const r=await qe(T(),n.watcher,n.watcher_machine);return it(e,r)}c(ot,"watch");function it(e,t=null){const n=[],r=e.body===void 0?{}:R(e.body)?e.body:(n.push({field:"body",problem:"must be an object"}),{}),o=nt(r.patterns,n),i=rt(r.config,n);return r.filter!==void 0&&!R(r.filter)&&n.push({field:"filter",problem:"must be an object",received:r.filter}),r.watcher!==void 0&&typeof r.watcher!="string"&&n.push({field:"watcher",problem:"must be a custom-object ref",received:r.watcher}),r.watcher_machine!==void 0&&typeof r.watcher_machine!="string"&&n.push({field:"watcher_machine",problem:"must be a machine id",received:r.watcher_machine}),n.length>0&&W("watch request",n),k(s=>{const a=typeof r.watcher=="string";if((e.publishToken||e.principal.class==="anonymous")&&!a)throw new y(404,"not_found","watcher not found");const l=o??[">"],u={patterns:l,...i?{config:i}:{},...r.filter!==void 0?{filter:r.filter}:{}};if(a){const j=r.watcher,p=t===null?null:st(s,e,j,t),w=p??(e.publishToken?re(s,j):X(s,j));if(w===null)return O();if(p===null&&Re(s,e,w)){const E=oe(s,e,w);D(s,e,w);const x=C(s,w),N=q(s,x,_(e));if(!te(s,x,N))throw new y(404,"not_found","object not found");return P(s,w,N,"act",u),M(s,{event:"watched",object:N,actor:E,attrs:{}},A(s)),{object:$(s,N,g(s,N)),patterns:l}}const{actor:d,object:h}=Te(s,e,w,_(e));return P(s,w,h,"act",{...u,linkApp:d}),M(s,{event:"watched",object:h,actor:d,attrs:{}},A(s)),{object:$(s,h,g(s,h)),patterns:l}}const f=v(s,e),m=U(s,e)??ee(f),b=q(s,f,_(e));return P(s,m,b,"ask",u),M(s,{event:"watched",object:b,actor:m,attrs:{}},A(s)),{object:$(s,b,g(s,b)),patterns:l}})}c(it,"watchLocal");function st(e,t,n,r){return t.publishToken||t.principal.class==="anonymous"?O():Be(e,n,r)}c(st,"ensureNodeStubFor");async function at(e){const t=_(e);if(e.query.get("watcher")&&Ee(t),!e.query.get("watcher")){const r=await K(e,t,{method:"DELETE",path:`${J(t)}/watch`,query:V(e)},()=>Z(t,e));if(r.kind==="unknown")throw fe(t,r.unreachable);if(r.kind==="remote"){if(r.status>=400)throw B(r.status,r.body);const o=r.body.object?.id;return k(i=>{const s=ue(i,e),a=o===void 0?null:L(i,o);s!==null&&a!==null&&me(i,a)&&se(i,s,a,e.query.get("pattern")??void 0)}),H(r.body,r.machine)}}const n=await qe(T(),e.query.get("watcher")??void 0,e.query.get("watcher_machine")??void 0);return ut(e,n)}c(at,"unwatchRoute");function ut(e,t=null){const n=e.query.get("pattern"),r=e.query.get("watcher");return k(o=>{if((e.publishToken||e.principal.class==="anonymous")&&!r)throw new y(404,"not_found","watcher not found");const i=c((u,f)=>Se(o,`SELECT count(*) AS n FROM watch_subscriptions s JOIN watches w ON w.rowid = s.watch
3
- WHERE w.watcher = ? AND w.object = ?`).get(u.rowid,f.rowid).n,"count"),s=c((u,f)=>{const m=i(u,f);return se(o,u,f,n??void 0),{object:g(o,f),removed:m-i(u,f)}},"drop");if(r){const u=t===null?null:(()=>{const m=L(o,r);return m!==null&&He(o,m)!==null?m:null})();if(t!==null&&u===null)return O();const f=u??(e.publishToken?re(o,r):X(o,r));return f===null?O():u===null&&Re(o,e,f)?(oe(o,e,f),D(o,e,f),s(f,q(o,C(o,f),_(e)))):s(f,Te(o,e,f,_(e)).object)}const a=v(o,e),l=U(o,e)??ee(a);return s(l,q(o,a,_(e)))})}c(ut,"unwatchLocal");function ct(e){const t=[],n=Q(e.query.get("type"),"type",["acted-on","links-to","watches"],t),r=Q(e.query.get("direction"),"direction",["out","in"],t);return t.length>0&&W("edges request",t),k(o=>{const i=v(o,e),s=q(o,i,_(e)),a=[];if(n!=="watches")for(const l of Pe(o,i,s,{...n?{type:n}:{},direction:r??"both"}))a.push({type:l.type,src:g(o,l.src),dst:g(o,l.dst),...l.written_as?{written_as:l.written_as}:{}});if(n===void 0||n==="watches"){const l=[...r!=="in"?ze(o,i,s):[],...r!=="out"?Ge(o,i,s):[]];for(const u of l)a.push({type:"watches",src:g(o,u.watcher),dst:g(o,u.object)})}return{items:a}})}c(ct,"edges");const I=c(e=>async t=>({status:200,body:await e(t)}),"ok"),Lt=[{method:"POST",pattern:"/v1/objects/search",handler:I(et)},{method:"GET",pattern:"/v1/objects/:ref/edges",handler:I(ct)},{method:"POST",pattern:"/v1/objects/:ref/watch",handler:I(ot)},{method:"DELETE",pattern:"/v1/objects/:ref/watch",handler:I(at)},{method:"GET",pattern:"/v1/objects/:ref",handler:I(Je)},{method:"GET",pattern:"/v1/objects",handler:I(xe)}];export{Qe as listBudget,Lt as objectRoutes};
1
+ var Re=Object.defineProperty;var l=(e,t)=>Re(e,"name",{value:t,configurable:!0});import{prepared as $e}from"../../../core/sqlite-statements.js";import{ApiError as y}from"../../../api/errors.js";import{PRIVACY_LEVELS_DTO as Ie}from"../../../api/dto/objects.js";import{openDb as T,withCanvasWrite as _}from"../../../core/canvas/db.js";import{actorOf as ee}from"../../../core/graph/documents.js";import{readerForObject as D,readerFor as Se}from"../../../core/graph/reader.js";import{resolveName as Ae}from"../../../core/graph/names.js";import{canRead as te,customReachable as Ne,holdsObjectsScope as Fe,mayActAs as ne}from"../../../core/graph/access.js";import{customObjectRef as re,authorizeCustom as oe,fenceArgv as M}from"./custom-objects.js";import{edgesOf as Le}from"../../../core/graph/edges.js";import{publish as G}from"../../../core/graph/events.js";import{objectDTO as g}from"../../../core/graph/kinds/dto.js";import{isKind as We,kindNames as Pe,kindOf as z}from"../../../core/graph/kinds/registry.js";import{listObjects as Ce,searchObjects as ie}from"../../../core/graph/objects.js";import{checkoutsForCwd as De}from"../../../core/graph/repo-sync/repos.js";import{recordWatch as W,unwatch as Me,watchersOf as Ge,watchesOf as ze}from"../../../core/graph/watches.js";import{readerFor as v,resolveRef as H}from"../reader.js";import{readDelegationFor as se,runReadLeaf as He}from"../../plugin-objects/read-leaf.js";import{invalidRequest as P,isRecord as R}from"./validate.js";import{callerNode as ue,callerStub as U,forwardVerb as ae,originates as ce,queryWithoutMachine as V,relayError as C,remoteStub as Ue,unknownError as le,forwarding as F,withMachine as B}from"../../peer/forward.js";import{getById as L,getByRowid as fe}from"../../../core/graph/objects.js";import{ensureNodeStub as Ve,isStub as K,stubOf as Be,withKindDecl as $}from"../../../core/peer/stubs.js";import{isUnreachable as Ke}from"../../../core/peer/client.js";import{normalizeMachineId as I}from"../../../core/peer/directory.js";const S=l(e=>t=>De(e,t),"reposFnFor");function de(e,t){return{...g(e,t),...z(e,t.type).listItem?.(e,t)}}l(de,"listItem");function Ze(e){return`no object named ${e} on this runtime; it may be on another runtime, or the name may be misspelled`}l(Ze,"remoteMessage");function me(e,t,r){try{return q(e,t,r)}catch(n){if(n instanceof y&&n.code==="not_found"&&!n.details?.deleted)return null;throw n}}l(me,"ownerFilter");function q(e,t,r){const n=H(e,t,r);if("remote"in n)throw new y(404,"not_found",Ze(n.remote),{next:"Check the name with `crtr canvas search`."});if("deleted"in n)throw new y(404,"not_found",`${n.deleted.name} is deleted`,{id:n.deleted.id,deleted:!0});return n}l(q,"liveRef");const k=l(e=>decodeURIComponent(e.params.ref),"refParam"),he=l(e=>{const t=e.trim().replace(/^\[\[(.*)\]\]$/,"$1").trim(),r=t.indexOf("/");return r>0?t.slice(0,r):t},"idOf");function pe(e){const t=L(T(),he(e));return t!==null&&K(T(),t)?t.id:null}l(pe,"stubIdOf");function Je(e,t){const r=pe(e);return r!==null?{stub:r,hit:!0}:_(n=>{try{const o=H(n,v(n,t),e);if("remote"in o)return{stub:null,hit:!1};const i="deleted"in o?o.deleted:o;return{stub:K(n,i)?i.id:null,hit:!0}}catch{return{stub:null,hit:!1}}})}l(Je,"resolvedLocally");async function Z(e,t,r){const n=Je(t,e);return n.stub!==null?ae(e,n.stub,r):n.hit||!ce(e.principal)?{kind:"local"}:ae(e,he(t),r)}l(Z,"forwardRef");const J=l(e=>`/v1/objects/${encodeURIComponent(e)}`,"objectPath");function we(e,t,r,n,o){const i=t?.object;!i?.id||!i.type||_(s=>{const u=ue(s,e);if(u===null)return;const c=Ue(s,i.id,i.type,r,{kind:i.kind??null,name:i.name??i.id,...i.preview===void 0?{}:{preview:i.preview},owner:i.owner??null,...i.kind_decl===void 0?{}:{kind_decl:i.kind_decl},...i.privacy===void 0?{}:{privacy:i.privacy}});W(s,u,c,n,o===void 0?{}:{patterns:o})})}l(we,"watchRemote");async function Qe(e){const t=k(e),r=["1","true"].includes(e.query.get("fields")??""),n=await Z(e,t,{method:"GET",path:J(t),query:V(e)});if(n.kind==="unknown")return{state:"unknown",ref:t,unreachable:n.unreachable};if(n.kind==="remote"){if(n.status>=400)throw C(n.status,n.body);return we(e,n.body,n.machine.id,"read"),B(n.body,n.machine)}const o=l(u=>{const c=U(u,e);return c===null?v(u,e):D(u,c,S(u))},"readerOf"),i=_(u=>{const c=o(u),a=H(u,c,t);if("remote"in a)return{state:"remote",remote:a.remote};if("deleted"in a)return{state:"deleted",deleted:g(u,a.deleted)};const f=se(u,a);if(f!==null)return{delegate:f,hitId:a.id};const{data:p,text:b}=z(u,a.type).read(u,c,a,{fields:r,reposFn:S(u)});return{state:"object",type:a.type,object:$(u,a,g(u,a)),text:b,data:p}});if(!("delegate"in i))return i;const s=await He(i.delegate,e.principal);return _(u=>{const c=o(u),a=L(u,i.hitId);if(a===null)throw new y(404,"not_found","object not found");if(a.deleted_at!==null)return{state:"deleted",deleted:g(u,a)};if(!te(u,c,a))throw new y(404,"not_found","object not found");const{data:f,text:p}=z(u,a.type).read(u,c,a,{fields:r,reposFn:S(u)});return se(u,a)===null?{state:"object",type:a.type,object:$(u,a,g(u,a)),text:p,data:f}:{state:"object",type:a.type,object:$(u,a,g(u,a)),text:"markdown"in s?s.markdown:`${p}
2
+ content unavailable: ${s.unavailable}`,data:{...f,content:"markdown"in s?"live":"unavailable"}}})}l(Qe,"read");function Q(e,t,r,n){if(e!=null){if(!r.includes(e)){n.push({field:t,problem:`must be one of ${r.join(", ")}`,received:e});return}return e}}l(Q,"oneOf");function ye(e,t,r){if(t!=null){if(typeof t!="string"||!We(e,t)){r.push({field:"type",problem:`must be a kind: one of ${Pe(e).join(", ")}`,received:t});return}return t}}l(ye,"kindName");function ge(e,t,r,n){if(e==null)return n;const o=Number(e);return!Number.isInteger(o)||o<1||o>100?(r.push({field:t,problem:"must be an integer from 1 to 100",received:e}),n):o}l(ge,"limitOf");function be(e){const t=e.query,r=[],n=ye(T(),t.get("type"),r),o=Q(t.get("privacy"),"privacy",Ie,r),i=ge(t.get("limit"),"limit",r,50),s=t.get("cursor");s!==null&&!/^\d+$/.test(s)&&r.push({field:"cursor",problem:"is not a cursor from a previous page",received:s});const u=t.get("deleted");return u!==null&&!["0","1","true","false"].includes(u)&&r.push({field:"deleted",problem:"must be true or false",received:u}),r.length>0&&P("object list request",r),_(c=>{const a=v(c,e),f={...n?{type:n}:{},...o?{privacy:o}:{},...t.get("kind")!==null?{kind:t.get("kind")}:{},...u==="1"||u==="true"?{deleted:!0}:{}},p=t.get("owner");if(p!==null){const m=me(c,a,p);if(m===null)return{items:[],next_cursor:null};f.owner=m}const b=t.get("name"),j=[];let h=s===null?0:Number(s),w=!0;for(;j.length<i&&w;){const m=Ce(c,a,f,{limit:100,after_rowid:h});w=m.length===100;for(const E of m)if(h=E.rowid,(b===null||E.name.startsWith(b))&&j.push(E),j.length===i)break}const d=j.at(-1);return{items:j.map(m=>de(c,m)),next_cursor:j.length===i&&d?String(d.rowid):null}})}l(be,"listLocal");const Ye={ms:3e4},Xe="self",Y=l((e,t)=>e.map(r=>({...r,machine:t})),"labelItems");async function je(e,t,r,n){const o=F.current;try{const i=await o.call(t.id,{method:"GET",path:"/v1/objects",query:r},o.envelope(e.principal),n);if(Ke(i))return{state:"unreachable",items:[],next:null};if(i.status===426)return{state:"too_old",items:[],next:null};const s=i.body;return i.status!==200||!Array.isArray(s?.items)?{state:"unreachable",items:[],next:null}:{state:"ok",items:Y(s.items,t),next:s.next_cursor??null}}catch{return{state:"unreachable",items:[],next:null}}}l(je,"remotePage");async function xe(e){const t=new Promise(r=>e.addEventListener("abort",()=>r(null),{once:!0}));return Promise.race([F.current.machines().catch(()=>null),t])}l(xe,"machinesWithin");async function et(e){const t=e.query.get("machine");if(!ce(e.principal)||!F.current.joined()||t===Xe)return be(_e(e));const n=F.current.self(),o=t!==null&&I(t)!==n,i=o?null:be(_e(e)),s=new AbortController,u=setTimeout(()=>s.abort(),Ye.ms);u.unref?.();try{const c=await xe(s.signal);if(c===null){if(o)throw new y(503,"runtime_unreachable",`The directory did not answer, so ${I(t)} cannot be listed.`,{machine:I(t)});return i}const a=l(d=>({id:d,name:c.find(m=>m.machine_id===d)?.name??d}),"labelOf"),f=a(n),p=c.filter(d=>d.machine_id!==n&&d.kind!=="device"),b=V(e);if(t!==null){if(!o)return{items:Y(i.items,f),next_cursor:i.next_cursor,machines:[{machine_id:n,name:f.name,state:"ok",more:i.next_cursor!==null}]};const d=I(t);if(!p.some(E=>E.machine_id===d))throw new y(404,"not_found",`no machine ${d} on your account`,{machine:d});const m=await je(e,a(d),b,s.signal);return{items:m.items,next_cursor:m.next,machines:[{machine_id:d,name:a(d).name,state:m.state,more:m.next!==null}]}}const{cursor:j,...h}=b,w=await Promise.all(p.map(d=>je(e,a(d.machine_id),h,s.signal)));return{items:[...Y(i.items,f),...w.flatMap(d=>d.items)],next_cursor:i.next_cursor,machines:[{machine_id:n,name:f.name,state:"ok",more:i.next_cursor!==null},...p.map((d,m)=>({machine_id:d.machine_id,name:d.name,state:w[m].state,more:w[m].next!==null}))]}}finally{clearTimeout(u)}}l(et,"list");function _e(e){const t=new URLSearchParams(e.query);return t.delete("machine"),{...e,query:t}}l(_e,"withoutMachine");function tt(e){const t=[],r=R(e.body)?e.body:{};R(e.body)||t.push({field:"body",problem:"must be an object",received:e.body});const n=r.text;(typeof n!="string"||n.trim()==="")&&t.push({field:"text",problem:"is required",received:n});const o=r.grep;if(o!==void 0)if(typeof o!="string")t.push({field:"grep",problem:"must be a regular expression string",received:o});else try{new RegExp(o)}catch(u){t.push({field:"grep",problem:`is not a valid regular expression: ${u.message}`,received:o})}r.body!==void 0&&typeof r.body!="boolean"&&t.push({field:"body",problem:"must be a boolean",received:r.body});const i=ye(T(),r.type,t);r.kind!==void 0&&typeof r.kind!="string"&&t.push({field:"kind",problem:"must be a string",received:r.kind}),r.owner!==void 0&&typeof r.owner!="string"&&t.push({field:"owner",problem:"must be a string",received:r.owner});const s=ge(r.limit,"limit",t,50);return t.length>0&&P("object search request",t),_(u=>{const c=v(u,e),a=typeof r.owner=="string"?me(u,c,r.owner):null;if(typeof r.owner=="string"&&a===null)return{items:[]};const f=ie(u,c,{text:n,body:r.body===!0||typeof o=="string"}),p=new Set(f.map(h=>h.object.rowid));return{items:(typeof o=="string"?ie(u,c,{text:o,grep:!0}).filter(h=>p.has(h.object.rowid)):f).filter(h=>(!i||h.object.type===i)&&(r.kind===void 0||h.object.kind===r.kind)&&(!a||h.object.owner===a.rowid)).slice(0,s).map(h=>({object:de(u,h.object),...h.line!==void 0?{matches:[{line:h.line,text:h.text??""}]}:{}}))}})}l(tt,"search");const ke=["interrupt","steer","after-turn","next-turn"],nt=/^(\*|>|[A-Za-z0-9_-]+)(\.(\*|>|[A-Za-z0-9_-]+))*$/;function rt(e,t){if(e!==void 0){if(!Array.isArray(e)||e.length===0||e.some(r=>typeof r!="string"||!nt.test(r)||r.includes(">")&&!r.endsWith(">"))){t.push({field:"patterns",problem:"must be a non-empty list of event patterns (dot-separated words, `*` for one word, a final `>` for the rest)",received:e});return}return e}}l(rt,"patternsOf");function ot(e,t){if(e===void 0)return;if(!R(e)||Object.keys(e).length===0){t.push({field:"config",problem:"must map levels 1-10 to a delivery",received:e});return}const r=[];for(const[n,o]of Object.entries(e)){const i=Number(n);!Number.isInteger(i)||i<1||i>10?t.push({field:`config.${n}`,problem:"level must be an integer from 1 to 10"}):ke.includes(o)?r.push({threshold:i,delivery:o}):t.push({field:`config.${n}`,problem:`delivery must be one of ${ke.join(", ")}`,received:o})}return r.sort((n,o)=>o.threshold-n.threshold)}l(ot,"configOf");function ve(e){const t=pe(e);if(t!==null)throw new y(400,"invalid_request",`${t} lives on another machine; an explicit watcher cannot watch it from here`,{id:t})}l(ve,"refuseStubWatch");function X(e,t){const r=L(e,t)??(()=>{const n=Ae(e,Se(e,{class:"person"},()=>[]),t);return"object"in n?n.object:null})();return r===null||r.deleted_at!==null||!(r.type.includes(".")||r.type==="node")?null:r}l(X,"findWatcher");const O=l(()=>{throw new y(404,"not_found","watcher not found")},"watcherNotFound");async function Oe(e,t,r){if(typeof t!="string"||r===void 0||r===null)return null;if(typeof r!="string")throw new y(400,"invalid_request","invalid watcher_machine");if(X(e,t)!==null)return null;const n=F.current;let o;try{o=await n.machines()}catch{throw new y(503,"runtime_unreachable","The directory did not answer, so the watcher machine cannot be checked.")}const i=I(r);return(i===n.self()||!o.some(s=>I(s.machine_id)===i))&&O(),i}l(Oe,"remoteWatcherMachine");function Ee(e,t,r,n){if(t.publishToken||t.principal.class==="anonymous")return O();const o=v(e,t);if(o.class==="person")return O();let i;try{i=q(e,o,n)}catch{return O()}const s=i.owner===null?null:fe(e,i.owner);return s===null||!ne(e,o,s)||!Fe(e,o,"link",r)?O():(M(e,t,r),{actor:o.app,object:i})}l(Ee,"linkWatcher");function qe(e,t,r){if(t.publishToken)return!0;if(t.principal.class==="anonymous"||!r.type.includes("."))return!1;const n=v(e,t),o=r.owner===null?null:fe(e,r.owner);return o!==null&&ne(e,n,o)&&Ne(e,n,r)}l(qe,"ownsWatcher");async function it(e){const t=k(e),r=R(e.body)?e.body:{};if(typeof r.watcher=="string"&&ve(t),typeof r.watcher!="string"){const o=await Z(e,t,{method:"POST",path:`${J(t)}/watch`,body:e.body});if(o.kind==="unknown")throw le(t,o.unreachable);if(o.kind==="remote"){if(o.status>=400)throw C(o.status,o.body);const i=o.body.patterns;return we(e,o.body,o.machine.id,"ask",i),B(o.body,o.machine)}}const n=await Oe(T(),r.watcher,r.watcher_machine);return st(e,n)}l(it,"watch");function st(e,t=null){const r=[],n=e.body===void 0?{}:R(e.body)?e.body:(r.push({field:"body",problem:"must be an object"}),{}),o=rt(n.patterns,r),i=ot(n.config,r);return n.filter!==void 0&&!R(n.filter)&&r.push({field:"filter",problem:"must be an object",received:n.filter}),n.watcher!==void 0&&typeof n.watcher!="string"&&r.push({field:"watcher",problem:"must be a custom-object ref",received:n.watcher}),n.watcher_machine!==void 0&&typeof n.watcher_machine!="string"&&r.push({field:"watcher_machine",problem:"must be a machine id",received:n.watcher_machine}),r.length>0&&P("watch request",r),_(s=>{const u=typeof n.watcher=="string";if((e.publishToken||e.principal.class==="anonymous")&&!u)throw new y(404,"not_found","watcher not found");const c=o??[">"],a={patterns:c,...i?{config:i}:{},...n.filter!==void 0?{filter:n.filter}:{}};if(u){const j=n.watcher,h=t===null?null:ut(s,e,j,t),w=h??(e.publishToken?re(s,j):X(s,j));if(w===null)return O();if(h===null&&qe(s,e,w)){const E=oe(s,e,w);M(s,e,w);const x=D(s,w),N=q(s,x,k(e));if(!te(s,x,N))throw new y(404,"not_found","object not found");return W(s,w,N,"act",a),G(s,{event:"watched",object:N,actor:E,attrs:{}},S(s)),{object:$(s,N,g(s,N)),patterns:c}}const{actor:d,object:m}=Ee(s,e,w,k(e));return W(s,w,m,"act",{...a,linkApp:d}),G(s,{event:"watched",object:m,actor:d,attrs:{}},S(s)),{object:$(s,m,g(s,m)),patterns:c}}const f=v(s,e),p=U(s,e)??ee(f),b=q(s,f,k(e));return W(s,p,b,"ask",a),G(s,{event:"watched",object:b,actor:p,attrs:{}},S(s)),{object:$(s,b,g(s,b)),patterns:c}})}l(st,"watchLocal");function ut(e,t,r,n){return t.publishToken||t.principal.class==="anonymous"?O():Ve(e,r,n)}l(ut,"ensureNodeStubFor");function Te(e,t,r,n){const o=l(()=>$e(e,`SELECT count(*) AS n FROM watch_subscriptions s JOIN watches w ON w.rowid = s.watch
3
+ WHERE w.watcher = ? AND w.object = ?`).get(t.rowid,r.rowid).n,"count"),i=o();return Me(e,t,r,n??void 0),{object:g(e,r),removed:i-o()}}l(Te,"dropWatch");async function at(e){const t=k(e);if(e.query.get("watcher")&&ve(t),!e.query.get("watcher")){const n=await Z(e,t,{method:"DELETE",path:`${J(t)}/watch`,query:V(e)});if(n.kind==="unknown")throw le(t,n.unreachable);if(n.kind==="remote"){const o=n.status===404?n.body.error?.details:void 0,i=o?.deleted===!0?o.id:void 0;if(n.status>=400&&i===void 0)throw C(n.status,n.body);const s=i??n.body.object?.id,u=_(c=>{const a=ue(c,e),f=s===void 0?null:L(c,s);return a===null||f===null||!K(c,f)?null:Te(c,a,f,e.query.get("pattern"))});if(i!==void 0){if(u===null)throw C(n.status,n.body);return{...u,machine:n.machine}}return B(n.body,n.machine)}}const r=await Oe(T(),e.query.get("watcher")??void 0,e.query.get("watcher_machine")??void 0);return ct(e,r)}l(at,"unwatchRoute");function ct(e,t=null){const r=e.query.get("pattern"),n=e.query.get("watcher");return _(o=>{if((e.publishToken||e.principal.class==="anonymous")&&!n)throw new y(404,"not_found","watcher not found");const i=l((c,a)=>Te(o,c,a,r),"drop");if(n){const c=t===null?null:(()=>{const f=L(o,n);return f!==null&&Be(o,f)!==null?f:null})();if(t!==null&&c===null)return O();const a=c??(e.publishToken?re(o,n):X(o,n));return a===null?O():c===null&&qe(o,e,a)?(oe(o,e,a),M(o,e,a),i(a,q(o,D(o,a),k(e)))):i(a,Ee(o,e,a,k(e)).object)}const s=v(o,e),u=U(o,e)??ee(s);return i(u,q(o,s,k(e)))})}l(ct,"unwatchLocal");function lt(e){const t=[],r=Q(e.query.get("type"),"type",["acted-on","links-to","watches"],t),n=Q(e.query.get("direction"),"direction",["out","in"],t);return t.length>0&&P("edges request",t),_(o=>{const i=v(o,e),s=q(o,i,k(e)),u=[];if(r!=="watches")for(const c of Le(o,i,s,{...r?{type:r}:{},direction:n??"both"}))u.push({type:c.type,src:g(o,c.src),dst:g(o,c.dst),...c.written_as?{written_as:c.written_as}:{}});if(r===void 0||r==="watches"){const c=[...n!=="in"?ze(o,i,s):[],...n!=="out"?Ge(o,i,s):[]];for(const a of c)u.push({type:"watches",src:g(o,a.watcher),dst:g(o,a.object)})}return{items:u}})}l(lt,"edges");const A=l(e=>async t=>({status:200,body:await e(t)}),"ok"),Wt=[{method:"POST",pattern:"/v1/objects/search",handler:A(tt)},{method:"GET",pattern:"/v1/objects/:ref/edges",handler:A(lt)},{method:"POST",pattern:"/v1/objects/:ref/watch",handler:A(it)},{method:"DELETE",pattern:"/v1/objects/:ref/watch",handler:A(at)},{method:"GET",pattern:"/v1/objects/:ref",handler:A(Qe)},{method:"GET",pattern:"/v1/objects",handler:A(et)}];export{Ye as listBudget,Wt as objectRoutes};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@north-light/cli",
3
- "version": "0.3.502",
3
+ "version": "0.3.504",
4
4
  "description": "crtr — agent runtime with memory, plugins, and marketplaces",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -138,7 +138,7 @@
138
138
  },
139
139
  "license": "UNLICENSED",
140
140
  "dependencies": {
141
- "@north-light/identity": "0.3.502",
141
+ "@north-light/identity": "0.3.504",
142
142
  "@earendil-works/pi-agent-core": "1.1.0",
143
143
  "@earendil-works/pi-ai": "1.1.0",
144
144
  "@earendil-works/pi-coding-agent": "1.1.0",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@north-light/identity",
3
- "version": "0.3.502",
3
+ "version": "0.3.504",
4
4
  "description": "Northlight access-token verification and scope rules",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
package/runtime.lock.json CHANGED
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "@north-light/cli",
3
- "version": "0.3.502",
3
+ "version": "0.3.504",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "@north-light/cli",
9
- "version": "0.3.502",
9
+ "version": "0.3.504",
10
10
  "hasInstallScript": true,
11
11
  "license": "UNLICENSED",
12
12
  "workspaces": [
@@ -18,7 +18,7 @@
18
18
  "@earendil-works/pi-ai": "1.1.0",
19
19
  "@earendil-works/pi-coding-agent": "1.1.0",
20
20
  "@earendil-works/pi-tui": "1.1.0",
21
- "@north-light/identity": "0.3.502",
21
+ "@north-light/identity": "0.3.504",
22
22
  "cron-parser": "^5.6.0",
23
23
  "esbuild": "^0.27.7",
24
24
  "jose": "^6.2.12",
@@ -12116,17 +12116,17 @@
12116
12116
  },
12117
12117
  "packages/crouter-api": {
12118
12118
  "name": "@north-light/api",
12119
- "version": "0.3.502",
12119
+ "version": "0.3.504",
12120
12120
  "license": "UNLICENSED"
12121
12121
  },
12122
12122
  "packages/crouter-env-docker": {
12123
12123
  "name": "@north-light/env-docker",
12124
- "version": "0.3.502",
12124
+ "version": "0.3.504",
12125
12125
  "license": "UNLICENSED"
12126
12126
  },
12127
12127
  "packages/crouter-identity": {
12128
12128
  "name": "@north-light/identity",
12129
- "version": "0.3.502",
12129
+ "version": "0.3.504",
12130
12130
  "license": "UNLICENSED",
12131
12131
  "dependencies": {
12132
12132
  "jose": "^6.2.1"
@@ -12134,20 +12134,20 @@
12134
12134
  },
12135
12135
  "packages/crouter-plugin": {
12136
12136
  "name": "@north-light/plugin",
12137
- "version": "0.3.502",
12137
+ "version": "0.3.504",
12138
12138
  "license": "UNLICENSED",
12139
12139
  "dependencies": {
12140
- "@north-light/api": "0.3.502",
12141
- "@north-light/identity": "0.3.502"
12140
+ "@north-light/api": "0.3.504",
12141
+ "@north-light/identity": "0.3.504"
12142
12142
  }
12143
12143
  },
12144
12144
  "packages/crouter-sdk": {
12145
12145
  "name": "@north-light/sdk",
12146
- "version": "0.3.502",
12146
+ "version": "0.3.504",
12147
12147
  "license": "UNLICENSED",
12148
12148
  "dependencies": {
12149
- "@north-light/api": "0.3.502",
12150
- "@north-light/identity": "0.3.502",
12149
+ "@north-light/api": "0.3.504",
12150
+ "@north-light/identity": "0.3.504",
12151
12151
  "jose": "^6.2.1"
12152
12152
  },
12153
12153
  "bin": {