@inkandswitch/patchwork-pkg-base 0.0.72 → 0.0.74
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/module-settings-url +1 -1
- package/package.json +1 -1
- package/packages/chat/dist/{ChatRoot-BRiX2ym6.js → ChatRoot-BYmq4SXi.js} +3541 -6287
- package/packages/chat/dist/{context-tool-CAHkp64h.js → context-tool-Bob-FZ_T.js} +2 -2
- package/packages/chat/dist/{index-Bt9HfG9I.js → index-wkaHcVCz.js} +3 -3
- package/packages/chat/dist/index.js +1 -1
- package/packages/chat/dist/{tool-DoxHbcfW.js → tool-DCOdh_fx.js} +1 -1
- package/packages/chat/package.json +3 -3
- package/packages/isolation/dist/assets/{component-DA0d3480.js → component-Daum8ibW.js} +118 -240
- package/packages/isolation/dist/assets/component-Daum8ibW.js.map +1 -0
- package/packages/isolation/dist/index.js +1 -1
- package/packages/threepane/dist/IsolatedDocumentArea-54ZI7TNY.js +2 -0
- package/packages/threepane/dist/PatchworkFrame-REYVVXOP.js +2 -0
- package/packages/threepane/dist/PatchworkFrame-REYVVXOP.js.map +7 -0
- package/packages/threepane/dist/{chunk-FX3MJIE5.js → chunk-DV7PRUYR.js} +3 -3
- package/packages/threepane/dist/chunk-DV7PRUYR.js.map +7 -0
- package/packages/threepane/dist/chunk-ESMUVHPH.js +2 -0
- package/packages/threepane/dist/chunk-ESMUVHPH.js.map +7 -0
- package/packages/threepane/dist/{datatypes-WPL4KARJ.js → datatypes-5DFL6VIN.js} +2 -2
- package/packages/threepane/dist/index.js +1 -1
- package/packages/threepane/dist/index.js.map +2 -2
- package/plugin-registry-url +1 -1
- package/packages/chat/dist/assets/worker-CFUOJ0Hd.js +0 -9
- package/packages/isolation/dist/assets/component-DA0d3480.js.map +0 -1
- package/packages/threepane/dist/IsolatedDocumentArea-MSJE4GCW.js +0 -2
- package/packages/threepane/dist/PatchworkFrame-3XYJCU3F.js +0 -2
- package/packages/threepane/dist/PatchworkFrame-3XYJCU3F.js.map +0 -7
- package/packages/threepane/dist/chunk-2NJMYYSD.js +0 -2
- package/packages/threepane/dist/chunk-2NJMYYSD.js.map +0 -7
- package/packages/threepane/dist/chunk-FX3MJIE5.js.map +0 -7
- /package/packages/threepane/dist/{IsolatedDocumentArea-MSJE4GCW.js.map → IsolatedDocumentArea-54ZI7TNY.js.map} +0 -0
- /package/packages/threepane/dist/{datatypes-WPL4KARJ.js.map → datatypes-5DFL6VIN.js.map} +0 -0
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
(function(){"use strict";const le="https://cdn.jsdelivr.net/npm/@huggingface/transformers@4",ee=new Set;function M(e){for(const o of ee)try{o.postMessage(e)}catch{}}function ie(e){return(e/1048576).toFixed(0)+" MB"}function ge(){const e=self;if(e.__llmWeightsFetchPatched)return;e.__llmWeightsFetchPatched=!0;const o=self.fetch.bind(self),t=50*1024*1024;self.fetch=async(s,r)=>{const d=await o(s,r);try{const a=+(d.headers.get("content-length")||0),i=((d.url||(typeof s=="string"?s:s?.url||"")).split("?")[0].split("/").pop()||"").toLowerCase();if(d.ok&&d.body&&a>t&&!i.endsWith(".onnx"))return ke(d,a)}catch{}return d}}function ke(e,o){let t=0,s=-1;const r=e.body.getReader(),d=new ReadableStream({async pull(a){const{done:l,value:i}=await r.read();if(l){a.close();return}t+=i.byteLength;const n=o?Math.round(100*t/o):0;n!==s&&(s=n,M({type:"status",message:`Downloading model weights… ${n}% (${ie(t)} / ${ie(o)})`})),a.enqueue(i)},cancel(a){return r.cancel(a)}});return new Response(d,{status:e.status,statusText:e.statusText,headers:e.headers})}function L(...e){try{console.log("[llm worker]",...e)}catch{}M({type:"log",args:e.map(o=>{if(o==null||typeof o!="object")return o;try{return JSON.parse(JSON.stringify(o))}catch{return String(o)}})})}const F=new Map;self.addEventListener("error",e=>M({type:"status",message:"Worker error: "+(e.message||"")})),self.addEventListener("unhandledrejection",e=>M({type:"status",message:"Worker error: "+(e.reason?.message||e.reason||"")}));const ce=[{id:"LiquidAI/LFM2.5-2.6B-ONNX",name:"LFM2.5 2.6B",dtype:"q4f16"},{id:"onnx-community/Qwen3-4B-ONNX",name:"Qwen3 4B (best)",dtype:"q4f16"},{id:"onnx-community/Qwen3-1.7B-ONNX",name:"Qwen3 1.7B",dtype:"q4f16"},{id:"onnx-community/Qwen3-0.6B-ONNX",name:"Qwen3 0.6B (fast)",dtype:"q4f16"},{id:"onnx-community/Llama-3.2-1B-Instruct-ONNX",name:"Llama 3.2 1B",dtype:"q4f16"},{id:"onnx-community/Phi-3.5-mini-instruct-onnx-web",name:"Phi 3.5 Mini",dtype:"q4f16"},{id:"onnx-community/SmolLM2-1.7B-Instruct-ONNX",name:"SmolLM2 1.7B",dtype:"q4f16"}],G="onnx-community/Qwen3-0.6B-ONNX",te=256;let R=null,k=null,T=G,U=null,J=!1,X=null,B=null;function Q(e){const o=String(e&&(e.message||e)||"unknown error");return/bad_alloc|out of memory|can'?t create a session/i.test(o)?"Out of memory while loading this model. Big models can exceed the browser's WASM memory ceiling (~4GB — independent of your system RAM). Try a smaller model, or open in a normal (non-incognito) window so WebGPU can run it on the GPU instead. (raw: "+o+")":/memory access out of bounds|RuntimeError: Aborted/i.test(o)?"The WASM backend crashed running this model — usually an fp16 weight format (q4f16/fp16) the CPU backend can't execute, not a size problem. Use an integer quantization (q4/q8) for WASM, or open in a normal (non-incognito) window so WebGPU is available. (raw: "+o+")":/unaligned/i.test(o)?"The WASM backend hit an unaligned-access fault. Try a normal window so WebGPU is available, or a smaller model. (raw: "+o+")":/tensor shape is too large|failed to call OrtRun|op_kernel\.cc/i.test(o)?"The model produced a tensor too large for this backend during the forward pass. That usually means either a very long prompt, or a model that emits extra big outputs every step — e.g. an attention-export model (…-attn) meant for analysis/overlays, not chat generation. Use the standard (non-attention) model for chat, shorten the prompt, or open in a normal window for WebGPU. (raw: "+o+")":o}function we(e){switch(e){case"q4f16":return"q4";case"q8f16":return"q8";case"fp16":return"fp32";default:return e}}function E(){return B?"Model load failed: "+Q(B):"Model not loaded"}function K(){const e=k,o=T;return k=null,e?(async()=>{try{typeof e.dispose=="function"?await e.dispose():e.model&&typeof e.model.dispose=="function"&&await e.model.dispose(),L("releaseGenerator: disposed previous session",{model:o})}catch(t){L("releaseGenerator: dispose failed",{model:o,message:t?.message||String(t)})}})():Promise.resolve()}const de=new Set,oe=new Map;async function be(e){try{const o=await caches.open("transformers-cache"),t=await o.keys();let s=0;for(const r of t)r.url.includes(e+"/")&&(await o.delete(r),s++);s&&L("purged cached entries for local model",{id:e,n:s})}catch(o){L("purgeCachedModel failed",{id:e,message:o?.message||String(o)})}}function pe(){const e=self;if(e.__llmFetchPatched)return;e.__llmFetchPatched=!0;const o=self.fetch.bind(self);self.fetch=(t,s)=>{try{const r=typeof t=="string"?t:t?.url||"";for(const[d,a]of oe){const l="/"+d+"/resolve/",i=r.indexOf(l);if(i===-1)continue;const n=r.slice(i+l.length),p=n.substring(n.indexOf("/")+1),c=a.files.get(p)||a.files.get(p.split("/").pop()||"");return c?Promise.resolve(new Response(c,{status:200,headers:{"content-length":String(c.size)}})):(L("local model: 404",{id:d,rel:p,have:[...a.files.keys()]}),Promise.resolve(new Response("local model file not found: "+p,{status:404})))}}catch{}return o(t,s)}}function _e(e,o,t){return Promise.race([e,new Promise((s,r)=>setTimeout(()=>r(new Error(t+" timed out")),o))])}async function $(e,o){e=e||G;const t=o&&U&&o!==U;if(k&&(T!==e||t)&&(L("loadModel: switching model — releasing previous",{from:T,to:e,dtypeChanged:t}),await K()),k)return;if(J&&X)return X;T=e,J=!0;let s=()=>{};X=new Promise(c=>s=c),B=null;const r=oe.get(e);pe();const d=r?{dtype:r.dtype}:ce.find(c=>c.id===e)||{dtype:"q4f16"},a={...d,dtype:o||d.dtype};U=a.dtype,L("loadModel: start",{modelId:e,dtype:a.dtype});try{M({type:"status",message:"Loading transformers.js…"}),R=await import(le),R.env.allowLocalModels=!1,ge(),R.env.fetch=(c,f)=>self.fetch(c,f),R.env.useBrowserCache=!r,navigator.storage?.persist&&await navigator.storage.persist()}catch(c){B=c,console.error("[llm worker] failed to load transformers.js from",le,c),M({type:"status",message:"Failed to load transformers.js: "+(c?.message||c)}),J=!1,X=null,s();return}const l=!de.has(e);function i(c){const f=new Map;return u=>{if(u.status==="progress"&&u.progress!=null&&u.file){f.set(u.file,{loaded:u.loaded||0,total:u.total||0});const y=u.file.split("/").pop()||u.file;let m=0,w=0;for(const _ of f.values())m+=_.loaded,w+=_.total;const x=w>0?Math.round(100*m/w):Math.round(u.progress);M({type:"status",message:`Downloading ${y}… ${Math.round(u.progress)}% (overall ${x}%)`})}else u.status==="ready"&&M({type:"status",message:l?`⚠️ Compiling shaders for ${c} (first time — might freeze for a bit)…`:`Compiling shaders for ${c}…`})}}const n=typeof navigator<"u"&&!!navigator.gpu,p=[];n&&p.push({device:"webgpu",label:"WebGPU"}),p.push({device:void 0,label:"WASM"}),n||M({type:"status",message:"WebGPU unavailable (navigator.gpu missing — incognito or unsupported context); using WASM"}),L("loadModel: backends to try",{hasWebGPU:n,order:p.map(c=>c.label)});for(const c of p){const f=c.device?a.dtype:we(a.dtype);try{L("loadModel: trying backend",{backend:c.label,dtype:f,requested:a.dtype}),k=await _e(R.pipeline("text-generation",e,{dtype:f,device:c.device,progress_callback:i(c.label)}),18e4,c.label+" pipeline"),de.add(e),U=f;try{const u=k.model,y={},m=u?.sessions||{};for(const[w,x]of Object.entries(m)){const _=x?.outputNames||[];y[w]=_}M({type:"model-info",model:e,sessions:y,config:u?.config?{output_attentions:u.config.output_attentions,num_hidden_layers:u.config.num_hidden_layers,num_attention_heads:u.config.num_attention_heads,model_type:u.config.model_type}:null})}catch(u){M({type:"model-info",model:e,error:u.message})}L("loadModel: ready",{modelId:e,backend:c.label,dtype:a.dtype}),M({type:"status",message:`Model ready (${c.label})`}),M({type:"ready",model:e,device:c.label}),B=null;break}catch(u){B=u,L("loadModel: backend failed",{backend:c.label,modelId:e,message:u?.message||String(u)}),console.error(`[llm worker] ${c.label} load failed for ${e}:`,u),M({type:"status",message:`${c.label} failed: ${u?.message||u}`+(c.device?" — trying WASM…":"")})}}k||(L("loadModel: all backends failed",{modelId:e,message:B?.message||String(B)}),console.error(`[llm worker] all backends failed to load ${e}:`,B),M({type:"status",message:E()}),M({type:"load-error",model:e,message:E()})),J=!1,X=null,s()}function se(e,o,t){let s=-1/0;for(let l=0;l<o;l++)e[l]>s&&(s=e[l]);let r=0;const d=[],a=[];for(let l=0;l<o;l++){const i=e[l];if(r+=Math.exp(i-s),d.length<t)d.push(l),a.push(i);else{let n=0;for(let p=1;p<t;p++)a[p]<a[n]&&(n=p);i>a[n]&&(a[n]=i,d[n]=l)}}return d.map((l,i)=>({id:l,p:Math.exp(a[i]-s)/r})).sort((l,i)=>i.p-l.p)}function ne(e){if(e&&typeof e=="object")return e;if(typeof e!="string")return{};try{return JSON.parse(e)}catch{return{}}}function xe(e){const o={};return e.topK>0&&(o.top_k=e.topK),e.minP>0&&(o.min_p=e.minP),e.repetitionPenalty&&e.repetitionPenalty!==1&&(o.repetition_penalty=e.repetitionPenalty),e.frequencyPenalty&&(o.frequency_penalty=e.frequencyPenalty),e.presencePenalty&&(o.presence_penalty=e.presencePenalty),e.seed!=null&&e.seed!==""&&(o.seed=e.seed),o}function Me(e){let o="";for(const t of e){const s=typeof t.content=="string"?t.content:"";o+=`<|im_start|>${t.role||"user"}
|
|
2
|
-
${s}<|im_end|>
|
|
3
|
-
`}return o+`<|im_start|>assistant
|
|
4
|
-
`}async function Te(e,o,t){const s=k.tokenizer,r=typeof o=="string",d=t.temperature??.7,a=t.topk|0,l=t.maxNewTokens??2048,i=!r&&!s.chat_template;let n=i?Me(o):o,p=!r&&t.tools?.length?t.tools:void 0;if(p&&s.chat_template){const g=s.apply_chat_template(n,{tools:p,tokenize:!1,add_generation_prompt:!0});let v=!1;for(const N of p){const q=N?.function?.name||N?.name;if(q&&g.includes(q)){v=!0;break}}if(!v){const N=t.toolSystem;N&&(n=[...n],n[0]?.role==="system"?n[0]={...n[0],content:[N,n[0].content].filter(Boolean).join(`
|
|
5
|
-
|
|
6
|
-
`)}:n.unshift({role:"system",content:N})),p=void 0}}i&&(L("doGenerateLocal: NO CHAT TEMPLATE — falling back to ChatML",{model:T,warning:"output will be garbage unless this model is ChatML-native; check that tokenizer_config.json / chat_template.jinja loaded"}),M({type:"status",message:`⚠️ ${T} has no chat template — using ChatML. Output may be garbage.`}));const c=i?["<|im_end|>","<|im_start|>"]:[];let f=0;try{const g=typeof n=="string"?n:s.apply_chat_template(n,{tokenize:!1,add_generation_prompt:!0,...p?{tools:p}:{}});f=s.encode(g).length}catch(g){L("doGenerateLocal: prompt build/encode failed (continuing)",{model:T,hasChatTemplate:!!s.chat_template,usedFallback:i,message:g?.message||String(g)})}const u=performance.now();let y=0,m="",w=null,x=!1,_=0;const O=new R.TextStreamer(s,{skip_prompt:!0,skip_special_tokens:!0,callback_function:g=>{if(x)return;y||(y=performance.now(),w&&(clearInterval(w),w=null),L("doGenerateLocal: first token",{ttftMs:Math.round(y-u),promptTokens:f})),m+=g;let v=-1;for(const q of c){const I=m.indexOf(q);I!==-1&&(v===-1||I<v)&&(v=I)}v!==-1&&(m=m.slice(0,v),x=!0),e.fullText=m;const N=m.slice(_);_=m.length,N&&A(e,{type:"token",delta:N,text:m})}});let C=0;const j=a>0?[(g,v)=>{if(C<te)try{const N=v.dims.at(-1),q=v.data,I=se(q,N,a).map(({id:z,p:Z})=>({token:s.decode([z]),p:+Z.toFixed(4)}));let W=-1/0;for(let z=0;z<N;z++)q[z]>W&&(W=q[z]);let V=0;for(let z=0;z<N;z++)V+=Math.exp(q[z]-W);let H=0;for(let z=0;z<N;z++){const Z=Math.exp(q[z]-W)/V;Z>0&&(H-=Z*Math.log2(Z))}A(e,{type:"prediction",step:C,candidates:I,entropy:+H.toFixed(3)})}catch{}return C++,v}]:void 0;L("doGenerateLocal: generating",{model:T,dtype:U,promptTokens:f,maxNewTokens:l,temperature:d,inputKind:typeof n=="string"?"text":"messages"}),w=setInterval(()=>{if(y)return;const g=Math.round((performance.now()-u)/1e3);M({type:"status",message:`Generating… ${g}s (prefilling, no token yet)`}),L("doGenerateLocal: still prefilling",{elapsedS:g})},2e3);let h;try{h=await k(n,{...p?{tools:p}:{},max_new_tokens:l,do_sample:d>0,temperature:d,...t.topK>0?{top_k:t.topK}:{},repetition_penalty:t.repetitionPenalty??1.1,...t.noRepeatNgramSize>0?{no_repeat_ngram_size:t.noRepeatNgramSize}:{},streamer:O,logits_processor:j})}finally{w&&(clearInterval(w),w=null)}const S=m||h?.[0]?.generated_text?.at(-1)?.content||"";let b=0;try{b=s.encode(S).length}catch{}const P=performance.now();return A(e,{type:"stats",provider:"local",model:T,promptTokens:f,genTokens:b,ttftMs:y?Math.round(y-u):null,totalMs:Math.round(P-u),tokPerSec:y?+(b/((P-y)/1e3)).toFixed(1):null,decode:{greedy:!(d>0),temperature:d,top_k:t.topK>0?t.topK:null,repetition_penalty:t.repetitionPenalty??1.1,no_repeat_ngram_size:t.noRepeatNgramSize||0,maxNewTokens:l}}),{text:S,toolCalls:null,toolMode:p?"template":"text"}}const ue="You are a text-continuation engine inside a writing tool. Continue the user's text seamlessly from exactly where it ends, matching its voice, tense, and style. Output ONLY the continuation — no preamble, no commentary, no explanation, no quotation marks — and never restate or acknowledge the user's text. If it ends mid-word or mid-sentence, finish it.";async function Pe(e,o,t){const s=typeof o=="string",r=t.temperature??.7,d=t.topk|0,a={model:t.model||"anthropic/claude-sonnet-4",stream:!0,stream_options:{include_usage:!0},temperature:r};if(t.topP!=null&&(a.top_p=t.topP),Object.assign(a,xe(t)),a.messages=s?[{role:"system",content:ue},{role:"user",content:o}]:o,t.maxNewTokens)a.max_tokens=t.maxNewTokens;else if(t.contextLength){const h=Math.ceil(JSON.stringify(o).length/4),S=t.maxCompletionTokens||8192;a.max_tokens=Math.min(S,Math.max(1024,t.contextLength-h-256))}!!(t.tools&&t.tools.length)?(a.tools=t.tools,a.tool_choice="auto"):d>0&&(a.logprobs=!0,a.top_logprobs=Math.min(d,20));const i=await fetch("https://openrouter.ai/api/v1/chat/completions",{method:"POST",headers:{Authorization:"Bearer "+t.apiKey,"Content-Type":"application/json"},body:JSON.stringify(a),signal:e.abortController.signal});if(!i.ok)throw new Error("OpenRouter: "+await i.text());const n=performance.now();let p=0,c="",f=0,u=null;const y=i.body.getReader(),m=new TextDecoder;let w="";const x=new Map,_=h=>{if(!h.startsWith("data: "))return;const S=h.slice(6).trim();if(S==="[DONE]")return;let b;try{b=JSON.parse(S)}catch{return}b.usage&&(u=b.usage);const P=b.choices?.[0],g=P?.delta?.content;g&&(p||(p=performance.now()),c+=g,e.fullText=c,A(e,{type:"token",delta:g,text:c}));for(const v of P?.delta?.tool_calls||[]){const N=v.index??0;let q=x.get(N);q||(q={id:void 0,name:void 0,args:""},x.set(N,q)),v.id&&(q.id=v.id),v.function?.name&&(q.name=v.function.name),v.function?.arguments&&(q.args+=v.function.arguments)}if(d>0)for(const v of P?.logprobs?.content||[]){if(f>=te)break;const N=(v.top_logprobs||[]).map(q=>({token:q.token,p:+Math.exp(q.logprob).toFixed(4)}));N.length&&A(e,{type:"prediction",step:f,candidates:N}),f++}};for(;;){const{done:h,value:S}=await y.read();if(h)break;w+=m.decode(S,{stream:!0});const b=w.split(`
|
|
7
|
-
`);w=b.pop()||"";for(const P of b)_(P)}if(w.trim())for(const h of w.split(`
|
|
8
|
-
`))_(h);const O=performance.now(),C=u?.completion_tokens??null;A(e,{type:"stats",provider:"openrouter",model:t.model,promptTokens:u?.prompt_tokens??null,genTokens:C,ttftMs:p?Math.round(p-n):null,totalMs:Math.round(O-n),tokPerSec:p&&C?+(C/((O-p)/1e3)).toFixed(1):null,decode:{greedy:r===0,temperature:r}});const j=x.size?[...x.entries()].sort((h,S)=>h[0]-S[0]).map(([,h])=>({id:h.id,name:h.name,args:ne(h.args)})).filter(h=>h.name):[];return{text:c,toolCalls:j.length?j:null}}async function ve(e,o,t){const s=typeof o=="string",r=(t.url||"http://localhost:11434").replace(/\/$/,""),d={model:t.model||"llama3.2",stream:!0,options:{temperature:t.temperature??.7,...t.topP!=null?{top_p:t.topP}:{},...t.topK>0?{top_k:t.topK}:{},...t.minP>0?{min_p:t.minP}:{},...t.typicalP!=null&&t.typicalP<1?{typical_p:t.typicalP}:{},...t.repetitionPenalty&&t.repetitionPenalty!==1?{repeat_penalty:t.repetitionPenalty}:{},...t.frequencyPenalty?{frequency_penalty:t.frequencyPenalty}:{},...t.presencePenalty?{presence_penalty:t.presencePenalty}:{},...t.seed!=null&&t.seed!==""?{seed:t.seed}:{}}};if(s?d.prompt=o:d.messages=o,t.tools&&t.tools.length&&!s){d.tools=t.tools,d.stream=!1;const w=performance.now(),x=await fetch(r+"/api/chat",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(d),signal:e.abortController.signal});if(!x.ok)throw new Error("Ollama: "+await x.text());const _=await x.json(),O=_.message?.content||"";O&&A(e,{type:"token",delta:O,text:O}),e.fullText=O;const C=(_.message?.tool_calls||[]).map((j,h)=>({id:j.id||"call_"+h,name:j.function?.name,args:ne(j.function?.arguments)}));return A(e,{type:"stats",provider:"ollama",model:t.model,promptTokens:_.prompt_eval_count??null,genTokens:_.eval_count??null,ttftMs:null,totalMs:Math.round(performance.now()-w),tokPerSec:null,decode:{greedy:(t.temperature??.7)===0,temperature:t.temperature??.7}}),{text:O,toolCalls:C}}const a=await fetch(r+(s?"/api/generate":"/api/chat"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(d),signal:e.abortController.signal});if(!a.ok)throw new Error("Ollama: "+await a.text());const l=performance.now();let i=0,n="",p=null;const c=a.body.getReader(),f=new TextDecoder;let u="";for(;;){const{done:w,value:x}=await c.read();if(w)break;u+=f.decode(x,{stream:!0});const _=u.split(`
|
|
9
|
-
`);u=_.pop()||"";for(const O of _)if(O.trim())try{const C=JSON.parse(O);C.done&&(p=C);const j=s?C.response:C.message?.content;j&&(i||(i=performance.now()),n+=j,e.fullText=n,A(e,{type:"token",delta:j,text:n}))}catch{}}const y=performance.now(),m=p?.eval_count??null;return A(e,{type:"stats",provider:"ollama",model:t.model,promptTokens:p?.prompt_eval_count??null,genTokens:m,ttftMs:i?Math.round(i-l):null,totalMs:Math.round(y-l),tokPerSec:p?.eval_count&&p?.eval_duration?+(p.eval_count/(p.eval_duration/1e9)).toFixed(1):null,decode:{temperature:t.temperature??.7}}),{text:n,toolCalls:null}}async function Se(e,o){const t=Math.max(1,o.topk|0||10),s=k.tokenizer;let r=[];return await k(e||" ",{max_new_tokens:1,do_sample:!1,logits_processor:[(d,a)=>{if(!r.length)try{const l=a.dims.at(-1);r=se(a.data,l,t).map(({id:i,p:n})=>({token:s.decode([i]),p:+n.toFixed(4)}))}catch{}return a}]}),r}async function Ce(e,o,t){const s=k.tokenizer,r=s.encode(o),d=[];for(let n=0;n<r.length&&!e.abortController.signal.aborted;n++){const p=n===0?"":s.decode(r.slice(0,n),{skip_special_tokens:!0});let c=null;await k(p||" ",{max_new_tokens:1,do_sample:!1,logits_processor:[(f,u)=>{if(c)return u;const y=u.dims.at(-1),m=u.data,w=r[n];let x=-1/0;for(let b=0;b<y;b++)m[b]>x&&(x=m[b]);let _=0;for(let b=0;b<y;b++)_+=Math.exp(m[b]-x);const O=Math.exp(m[w]-x)/_;let C=1;const j=m[w];for(let b=0;b<y;b++)m[b]>j+1e-8&&C++;let h=0;for(let b=0;b<y;b++){const P=Math.exp(m[b]-x)/_;P>0&&(h-=P*Math.log2(P))}const S=se(m,y,10).map(({id:b,p:P})=>({token:s.decode([b]),p:+P.toFixed(4)}));return c={token:s.decode([w]),p:+O.toFixed(6),rank:C,entropy:+h.toFixed(3),topk:S},u}]}),c&&d.push(c),A(e,{type:"score-progress",step:n,total:r.length})}const a=[];let l=0;for(let n=0;n<r.length&&n<d.length;n++){const p=s.decode(r.slice(0,n+1),{skip_special_tokens:!0}),c=l,f=p.length;f>c&&a.push({from:c,to:f,index:n}),l=p.length}const i=s.decode(r,{skip_special_tokens:!0});A(e,{type:"token-scores",scores:d,spans:a,decoded:i})}async function Le(e,o,t){const s=k.model,r=k.tokenizer,d=r(o,{return_tensor:!0}),a=Array.from(d.input_ids.data),l=a.length;if(l<2){A(e,{type:"importance-scores",decoded:o,spans:[]});return}const i=s.config?.vocab_size||151936,n=(l-1)*i;function p(h){const S=new Float64Array(i);let b=-1/0;for(let g=0;g<i;g++){const v=h[n+g];v>b&&(b=v)}let P=0;for(let g=0;g<i;g++)S[g]=Math.exp(h[n+g]-b),P+=S[g];for(let g=0;g<i;g++)S[g]/=P;return S}function c(h,S){let b=0;for(let P=0;P<i;P++){const g=(h[P]+S[P])/2;g>0&&(h[P]>0&&(b+=h[P]*Math.log(h[P]/g)),S[P]>0&&(b+=S[P]*Math.log(S[P]/g)))}return b/2}M({type:"status",message:"Saliency: baseline…"});const f=await s(d),u=p(f.logits.data),y=new Float64Array(l),m=new BigInt64Array(d.input_ids.data);for(let h=0;h<l&&!e.abortController.signal.aborted;h++){M({type:"status",message:`Saliency: ${h+1}/${l}…`}),A(e,{type:"score-progress",step:h,total:l});const S=new BigInt64Array(m);S[h]=0n;const b={input_ids:new R.Tensor("int64",S,d.input_ids.dims),attention_mask:d.attention_mask},P=await s(b),g=p(P.logits.data);y[h]=c(u,g)}let w=1/0,x=-1/0;for(let h=0;h<l;h++)y[h]<w&&(w=y[h]),y[h]>x&&(x=y[h]);const _=x-w||1,O=[];let C=0;for(let h=0;h<a.length;h++){const S=r.decode(a.slice(0,h+1),{skip_special_tokens:!0}),b=C,P=S.length;P>b&&O.push({from:b,to:P,importance:(y[h]-w)/_}),C=S.length}const j=r.decode(a,{skip_special_tokens:!0});A(e,{type:"importance-scores",decoded:j,spans:O}),M({type:"status",message:""})}async function Oe(e,o,t){const s=k.model,r=k.tokenizer,d=r(o,{return_tensor:!0}),a=Array.from(d.input_ids.data),l=a.length;if(l<2){A(e,{type:"attention-weights",supported:!0,dims:{layers:0,heads:0,seq:l},received:new Float32Array(0),fromLast:new Float32Array(0),spans:[],tokens:[],decoded:o});return}L("computeAttentionWeights: forward pass",{model:T,seqLen:l}),M({type:"status",message:"Attention: forward pass…"});const i=await s(d),n=i.attentions;if(!n||!n.dims||n.dims.length!==5){const g=Object.keys(i||{});L("computeAttentionWeights: no usable attentions output",{model:T,outputKeys:g,attnDims:n?.dims||null}),console.warn(`[llm worker] ${T} has no usable attentions output. forward outputs:`,g,n?`(attentions dims: [${n.dims}])`:"(no `attentions` key)"),A(e,{type:"attention-weights",supported:!1,model:T,outputKeys:g,attnDims:n?.dims||null}),M({type:"status",message:""});return}const[,p,c,f,u]=n.dims,y=n.data,m=u,w=c*f*u,x=f*u,_=u,O=new Float32Array(p*c*m),C=new Float32Array(p*c*m),j=f-1;for(let g=0;g<p;g++)for(let v=0;v<c;v++){const N=g*w+v*x,q=(g*c+v)*m,I=N+j*_;for(let W=0;W<m;W++)C[q+W]=y[I+W];for(let W=0;W<m;W++){let V=0,H=0;for(let z=W;z<f;z++)V+=y[N+z*_+W],H++;O[q+W]=H?V/H:0}}const h=[],S=[];let b=0;for(let g=0;g<l;g++){const v=r.decode(a.slice(0,g+1),{skip_special_tokens:!0}),N=b,q=v.length;S.push(r.decode([a[g]])),q>N&&h.push({from:N,to:q,index:g}),b=v.length}const P=r.decode(a,{skip_special_tokens:!0});A(e,{type:"attention-weights",supported:!0,dims:{layers:p,heads:c,seq:m},received:O,fromLast:C,spans:h,tokens:S,decoded:P}),M({type:"status",message:""})}async function Ae(e,o,t){const s=Math.min(Math.max(1,o.topk|0||10),20),r=await fetch("https://openrouter.ai/api/v1/chat/completions",{method:"POST",headers:{Authorization:"Bearer "+o.apiKey,"Content-Type":"application/json"},body:JSON.stringify({model:o.model,messages:o.continuation?[{role:"system",content:ue},{role:"user",content:e||" "}]:[{role:"user",content:e||" "}],max_tokens:1,temperature:0,logprobs:!0,top_logprobs:s}),signal:t});if(!r.ok)throw new Error("OpenRouter predict: "+await r.text());const a=(await r.json()).choices?.[0]?.logprobs?.content?.[0]?.top_logprobs;return a?a.map(l=>({token:l.token,p:+Math.exp(l.logprob).toFixed(4)})).sort((l,i)=>i.p-l.p):[]}function Ne(e,o){const{id:t,text:s,config:r={}}=o,d=o.provider,a=o.sessionKey||t,l=new AbortController;F.set(a,{id:t,port:e,done:!1,fullText:"",abortController:l});const i=()=>F.delete(a),n=u=>{i(),e.postMessage({type:"predictions",id:t,candidates:u})},p=u=>{i(),l.signal.aborted||e.postMessage({type:"error",id:t,message:u})};if(d==="openrouter"){Ae(s,r,l.signal).then(n).catch(u=>p(u?.message||String(u)));return}if(d==="ollama"){n([]);return}if(d==="webllm"){Fe(s,r).then(n).catch(u=>p(u?.message||String(u)));return}const c=r.model||G,f=()=>Se(s,r).then(n).catch(u=>p(u?.message||String(u)));!k||T!==c?(T!==c&&(k=null),$(c,r.dtype).then(()=>k?f():p(E()))):f()}let Y=null,D=null,me=null;async function fe(e,o){if(e=e||"Qwen2.5-1.5B-Instruct-q4f16_1-MLC",Y||(M({type:"status",message:"Loading WebLLM…"}),Y=await import("https://esm.run/@mlc-ai/web-llm")),D&&me===e)return;if(D){try{await D.unload?.()}catch{}D=null}me=e;const t=(Array.isArray(o)?o:[]).filter(r=>r&&r.model_id&&r.model_lib).map(r=>({...r,model:r.model||"https://huggingface.co/"+r.model_id})),s=t.length?{...Y.prebuiltAppConfig,model_list:[...Y.prebuiltAppConfig.model_list,...t]}:void 0;D=await Y.CreateMLCEngine(e,{appConfig:s,initProgressCallback:r=>M({type:"status",message:r.text||"Loading… "+(typeof r.progress=="number"?Math.round(r.progress*100)+"%":"")})}),M({type:"status",message:"Model ready (WebLLM)"}),M({type:"ready",model:e,device:"WebGPU"})}async function qe(e,o,t){await fe(t.model,t.custom);const s=typeof o=="string";if(t.tools&&t.tools.length&&!s){const m=performance.now(),w=await D.chat.completions.create({messages:o,tools:t.tools,tool_choice:"auto",stream:!1,temperature:t.temperature??.7,...t.topP!=null?{top_p:t.topP}:{},...t.maxNewTokens?{max_tokens:t.maxNewTokens}:{}}),x=w.choices?.[0]?.message||{},_=x.content||"";_&&A(e,{type:"token",delta:_,text:_}),e.fullText=_;const O=(x.tool_calls||[]).map(C=>({id:C.id,name:C.function?.name,args:ne(C.function?.arguments)}));return A(e,{type:"stats",provider:"webllm",model:t.model,promptTokens:w.usage?.prompt_tokens??null,genTokens:w.usage?.completion_tokens??null,ttftMs:null,totalMs:Math.round(performance.now()-m),tokPerSec:null,decode:{temperature:t.temperature??.7}}),{text:_,toolCalls:O}}const r=t.temperature??.7,d=t.topk|0,a={stream:!0,stream_options:{include_usage:!0},temperature:r,...t.topP!=null?{top_p:t.topP}:{},...t.frequencyPenalty?{frequency_penalty:t.frequencyPenalty}:{},...t.presencePenalty?{presence_penalty:t.presencePenalty}:{},...t.seed!=null&&t.seed!==""?{seed:t.seed}:{},...t.maxNewTokens?{max_tokens:t.maxNewTokens}:{},...d>0?{logprobs:!0,top_logprobs:d}:{}},l=performance.now();let i=0,n="",p=null,c=0;const f=s?await D.completions.create({prompt:o,...a}):await D.chat.completions.create({messages:o,...a});for await(const m of f){if(e.abortController.signal.aborted)break;m.usage&&(p=m.usage);const w=m.choices?.[0],x=s?w?.text:w?.delta?.content,_=w?.logprobs?.content;if(_&&d>0)for(const O of _){if(c>=te)break;const C=(O.top_logprobs||[]).map(j=>({token:j.token,p:+Math.exp(j.logprob).toFixed(4)}));C.length&&A(e,{type:"prediction",step:c,candidates:C}),c++}x&&(i||(i=performance.now()),n+=x,e.fullText=n,A(e,{type:"token",delta:x,text:n}))}const u=performance.now(),y=p?.completion_tokens??null;return A(e,{type:"stats",provider:"webllm",model:t.model,promptTokens:p?.prompt_tokens??null,genTokens:y,ttftMs:i?Math.round(i-l):null,totalMs:Math.round(u-l),tokPerSec:i&&y?+(y/((u-i)/1e3)).toFixed(1):null,decode:{temperature:r,top_p:t.topP}}),{text:n,toolCalls:null}}async function Fe(e,o){await fe(o.model,o.custom);const t=Math.max(1,o.topk|0||10),r=(await D.completions.create({prompt:e||" ",max_tokens:1,temperature:0,logprobs:!0,top_logprobs:t,stream:!1})).choices?.[0]?.logprobs?.content?.[0]?.top_logprobs;return r?r.map(d=>({token:d.token,p:+Math.exp(d.logprob).toFixed(4)})).sort((d,a)=>a.p-d.p):[]}function A(e,o){try{e.port.postMessage({...o,id:e.id})}catch{}}function ye(e,o,t,s,r){o.done=!0,o.finalText=t;try{o.port.postMessage({type:"result",id:o.id,text:t,toolCalls:s||null,toolMode:r})}catch{}M({type:"status",message:""}),e&&setTimeout(()=>F.delete(e),5e3)}function re(e,o,t){try{o.port.postMessage({type:"error",id:o.id,message:t})}catch{}M({type:"status",message:""}),e&&F.delete(e)}async function ae(e,o,t,s,r){try{L("runGeneration: start",{provider:t,model:r.model||T,inputKind:typeof s=="string"?"text":"messages",messages:Array.isArray(s)?s.length:void 0}),M({type:"status",message:"Thinking…"});let d;t==="openrouter"?d=await Pe(o,s,r):t==="ollama"?d=await ve(o,s,r):t==="webllm"?d=await qe(o,s,r):d=await Te(o,s,r),L("runGeneration: done",{provider:t,chars:d.text?.length||0}),ye(e,o,d.text,d.toolCalls,"toolMode"in d&&typeof d.toolMode=="string"?d.toolMode:void 0)}catch(d){if(o.abortController.signal.aborted){L("runGeneration: aborted",{provider:t,chars:o.fullText?.length||0});return}L("runGeneration: error",{provider:t,model:T,message:d?.message||String(d)}),o.fullText?ye(e,o,o.fullText):re(e,o,Q(d))}}async function je(e,o){const t=k.model,s=k.tokenizer,r=s(o||" ",{return_tensor:!0}),d=Array.from(r.input_ids.data,Number),a=d.length;M({type:"status",message:"Extracting features (forward pass)…"});const l=await t(r),i=l.last_hidden_state,n=l.logits;if(!i||!n){A(e,{type:"features",supported:!1,outputKeys:Object.keys(l||{}),message:`${T} has no last_hidden_state output — needs a hidden-state export (onnx_hidden.py).`}),M({type:"status",message:""});return}const p=i.dims.at(-1),c=n.dims.at(-1),f=Float32Array.from(i.data),u=Float32Array.from(n.data),y=[];let m=0;for(let _=0;_<a;_++){const O=s.decode(d.slice(0,_+1),{skip_special_tokens:!0});O.length>m&&y.push({from:m,to:O.length,index:_}),m=O.length}const w=s.decode(d,{skip_special_tokens:!0}),x=d.map(_=>s.decode([_]));A(e,{type:"features",supported:!0,seq:a,H:p,V:c,ids:d,tokens:x,spans:y,decoded:w,hidden:f,logits:u}),M({type:"status",message:""})}async function ze(e,o){const t=k.model,s=k.tokenizer,r=s(o||" ",{return_tensor:!0}),d=Array.from(r.input_ids.data,Number),a=d.length;M({type:"status",message:"Extracting cut features (forward pass)…"});const l=await t(r),i=l.cut_hidden;if(!i){A(e,{type:"cut-features",supported:!1,outputKeys:Object.keys(l||{}),message:`${T} has no cut_hidden output — needs a cut-point export (onnx_block.py).`}),M({type:"status",message:""});return}const n=i.dims.at(-1),p=Float32Array.from(i.data),c=[];let f=0;for(let m=0;m<a;m++){const w=s.decode(d.slice(0,m+1),{skip_special_tokens:!0});w.length>f&&c.push({from:f,to:w.length,index:m}),f=w.length}const u=s.decode(d,{skip_special_tokens:!0}),y=d.map(m=>s.decode([m]));A(e,{type:"cut-features",supported:!0,seq:a,d:n,ids:d,tokens:y,spans:c,decoded:u,hidden:p}),M({type:"status",message:""})}function he(e,o){const{type:t,id:s}=o,r=o.sessionKey||s,d=o.config?.dtype;if(k&&!J&&d&&U&&d!==U&&(k=null),t==="list-local-models"){e.postMessage({type:"local-models",models:ce});return}if(t==="predict"){Ne(e,o);return}if(t==="score-tokens"){const{provider:a,config:l={}}=o;if(a!=="local"){e.postMessage({type:"token-scores",id:s,scores:[]});return}const i={id:s,port:e,fullText:"",done:!1,finalText:"",abortController:new AbortController};F.set(r,i);const n=l.model||G,p=()=>Ce(i,o.text).then(()=>{i.done=!0,F.delete(r)}).catch(c=>{i.abortController.signal.aborted||e.postMessage({type:"error",id:s,message:c?.message||String(c)}),F.delete(r)});!k||T!==n?(T!==n&&K(),$(n,l.dtype).then(()=>{if(!k){e.postMessage({type:"error",id:s,message:E()});return}p()})):p();return}if(t==="compute-importance"){const{provider:a,config:l={}}=o;if(a!=="local"){e.postMessage({type:"importance-scores",id:s,scores:[]});return}const i={id:s,port:e,fullText:"",done:!1,finalText:"",abortController:new AbortController};F.set(r,i);const n=l.model||G,p=()=>Le(i,o.text).then(()=>{i.done=!0,F.delete(r)}).catch(c=>{i.abortController.signal.aborted||e.postMessage({type:"error",id:s,message:c?.message||String(c)}),F.delete(r)});!k||T!==n?(T!==n&&K(),$(n,l.dtype).then(()=>{if(!k){e.postMessage({type:"error",id:s,message:E()});return}p()})):p();return}if(t==="compute-attention-weights"){const{provider:a,config:l={}}=o;if(a!=="local"){e.postMessage({type:"attention-weights",id:s,supported:!1});return}const i={id:s,port:e,fullText:"",done:!1,finalText:"",abortController:new AbortController};F.set(r,i);const n=l.model||G,p=()=>(L("compute-attention-weights: run",{model:n}),Oe(i,o.text).then(()=>{i.done=!0,F.delete(r)}).catch(c=>{const f=i.abortController.signal.aborted;L("compute-attention-weights: error",{model:n,aborted:f,message:c?.message||String(c)}),f||e.postMessage({type:"error",id:s,message:Q(c)}),F.delete(r)}));!k||T!==n?(T!==n&&K(),$(n,l.dtype).then(()=>{if(!k){e.postMessage({type:"error",id:s,message:E()});return}p()}).catch(c=>{L("compute-attention-weights: loadModel threw",{model:n,message:c?.message||String(c)}),e.postMessage({type:"error",id:s,message:Q(c)})})):p();return}if(t==="extract-features"){const{provider:a,config:l={}}=o;if(a!=="local"){e.postMessage({type:"features",id:s,supported:!1,message:"features require a local model"});return}const i={id:s,port:e,fullText:"",done:!1,finalText:"",abortController:new AbortController};F.set(r,i);const n=l.model||G,p=()=>(L("extract-features: run",{model:n}),je(i,o.text).then(()=>{i.done=!0,F.delete(r)}).catch(c=>{const f=i.abortController.signal.aborted;L("extract-features: error",{model:n,aborted:f,message:c?.message||String(c)}),f||e.postMessage({type:"error",id:s,message:Q(c)}),F.delete(r)}));!k||T!==n?(T!==n&&K(),$(n,l.dtype).then(()=>{if(!k){e.postMessage({type:"error",id:s,message:E()});return}p()}).catch(c=>{L("extract-features: loadModel threw",{model:n,message:c?.message||String(c)}),e.postMessage({type:"error",id:s,message:Q(c)})})):p();return}if(t==="extract-cut-features"){const{provider:a,config:l={}}=o;if(a!=="local"){e.postMessage({type:"cut-features",id:s,supported:!1,message:"features require a local model"});return}const i={id:s,port:e,fullText:"",done:!1,finalText:"",abortController:new AbortController};F.set(r,i);const n=l.model||G,p=()=>ze(i,o.text).then(()=>{i.done=!0,F.delete(r)}).catch(c=>{i.abortController.signal.aborted||e.postMessage({type:"error",id:s,message:c?.message||String(c)}),F.delete(r)});!k||T!==n?(T!==n&&K(),$(n,l.dtype).then(()=>{if(!k){e.postMessage({type:"error",id:s,message:E()});return}p()})):p();return}if(t==="decode-tokens"){const a=()=>{try{const i=k.tokenizer,n=(o.ids||[]).map(p=>i.decode([p]));e.postMessage({type:"decoded-tokens",id:s,strings:n})}catch(i){e.postMessage({type:"error",id:s,message:i?.message||String(i)})}},l=o.config?.model||G;!k||T!==l?(T!==l&&K(),$(l,o.config?.dtype).then(()=>k?a():e.postMessage({type:"error",id:s,message:E()}))):a();return}if(t==="probe-attention"){const a=async()=>{const i=k.model,n=k.tokenizer,p=o.text||"Hello world",c=n(p,{return_tensor:!0}),f={type:"probe-attention-result",id:s},u={};for(const[y,m]of Object.entries(i?.sessions||{}))u[y]={inputNames:m?.inputNames||[],outputNames:m?.outputNames||[]};f.sessions=u;try{const y=await i(c);f.outputKeys=Object.keys(y||{}),f.hasAttentions="attentions"in(y||{}),f.attentionKeys=Object.keys(y||{}).filter(m=>/attention|attn/i.test(m))}catch(y){f.forwardError=y.message}try{const y=await i.generate({...c,max_new_tokens:1,output_attentions:!0,return_dict_in_generate:!0});f.generateKeys=Object.keys(y||{}),f.generateHasAttentions="attentions"in(y||{})}catch(y){f.generateError=y.message}e.postMessage(f)},l=o.config?.model||G;!k||T!==l?$(l,o.config?.dtype).then(()=>k?a():e.postMessage({type:"probe-attention-result",id:s,error:E()})):a();return}if(t==="register-local-model"){const a=new Map((o.files||[]).map(l=>[l.path,l.blob]));oe.set(o.id,{files:a,dtype:o.dtype||"q4f16"}),pe(),T===o.id&&K(),be(o.id).then(()=>e.postMessage({type:"local-model-registered",id:o.id,count:a.size}));return}if(t==="preload"){o.provider==="local"?(!k&&!J&&$(o.config?.model,o.config?.dtype),k&&e.postMessage({type:"ready"})):e.postMessage({type:"ready"});return}if(t==="resume"){const a=o.sessionKey,l=F.get(a);l&&!l.done?(l.port=e,e.postMessage({type:"resumed",id:l.id,sessionKey:a,text:l.fullText})):l&&l.done?(e.postMessage({type:"resume-result",id:l.id,sessionKey:a,text:l.finalText}),F.delete(a)):e.postMessage({type:"no-active-generation",sessionKey:a});return}if(t==="abort"){const a=F.get(o.sessionKey);a&&!a.done&&(a.abortController.abort(),F.delete(o.sessionKey));return}if(t==="generate"){const{provider:a,config:l={}}=o,i=o.text!=null?o.text:o.messages,n={id:s,port:e,fullText:"",done:!1,finalText:"",abortController:new AbortController};if(F.set(r,n),a==="local"){const p=l.model||G;!k||T!==p?(T!==p&&K(),$(p,l.dtype).then(()=>{if(!k)return re(r,n,`Model "${p}" failed to load (still not ready after load). Try a different local model, or check the device has enough memory.`);ae(r,n,a,i,l)}).catch(c=>re(r,n,`Couldn't load local model "${p}": ${c?.message||c}`))):ae(r,n,a,i,l)}else ae(r,n,a,i,l)}}self.onconnect=e=>{const o=e.ports[0];ee.add(o),o.onmessage=t=>he(o,t.data),k&&o.postMessage({type:"ready"}),o.start()},typeof self.SharedWorkerGlobalScope>"u"&&(ee.add(self),self.onmessage=e=>he(self,e.data))})();
|