@north-light/cli 0.3.503 → 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
|
-
|
|
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
|
|
2
|
-
`))>=0;){const
|
|
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
|
|
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};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@north-light/cli",
|
|
3
|
-
"version": "0.3.
|
|
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.
|
|
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",
|
package/runtime.lock.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@north-light/cli",
|
|
3
|
-
"version": "0.3.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
12137
|
+
"version": "0.3.504",
|
|
12138
12138
|
"license": "UNLICENSED",
|
|
12139
12139
|
"dependencies": {
|
|
12140
|
-
"@north-light/api": "0.3.
|
|
12141
|
-
"@north-light/identity": "0.3.
|
|
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.
|
|
12146
|
+
"version": "0.3.504",
|
|
12147
12147
|
"license": "UNLICENSED",
|
|
12148
12148
|
"dependencies": {
|
|
12149
|
-
"@north-light/api": "0.3.
|
|
12150
|
-
"@north-light/identity": "0.3.
|
|
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": {
|