@degreesign/chat 0.0.0-stage → 0.1.1
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/LICENSE +28 -0
- package/README.md +374 -2
- package/dist/assets/wllama/LICENCE +21 -0
- package/dist/assets/wllama/compat/wllama.js +2 -0
- package/dist/assets/wllama/compat/wllama.wasm +0 -0
- package/dist/assets/wllama/wllama.wasm +0 -0
- package/dist/browser/chat.min.mjs +2 -0
- package/dist/browser/chat.min.mjs.LICENSE.txt +1 -0
- package/dist/browser/engine-wllama.min.mjs +2 -0
- package/dist/browser/engine-wllama.min.mjs.LICENSE.txt +1 -0
- package/dist/chat.d.ts +5 -0
- package/dist/engines/engine.d.ts +28 -0
- package/dist/engines/images.d.ts +8 -0
- package/dist/engines/wllama.d.ts +13 -0
- package/dist/enums.d.ts +35 -0
- package/dist/index.d.ts +3 -0
- package/dist/models.d.ts +9 -0
- package/dist/node/chat.node.min.js +2 -0
- package/dist/node/chat.node.min.js.LICENSE.txt +1 -0
- package/dist/node/chat.node.min.mjs +2 -0
- package/dist/node/chat.node.min.mjs.LICENSE.txt +1 -0
- package/dist/node/engine-wllama.node.min.js +2 -0
- package/dist/node/engine-wllama.node.min.js.LICENSE.txt +1 -0
- package/dist/node/engine-wllama.node.min.mjs +2 -0
- package/dist/node/engine-wllama.node.min.mjs.LICENSE.txt +1 -0
- package/dist/service.d.ts +4 -0
- package/dist/types.d.ts +270 -0
- package/package.json +71 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/*! MIT License. DegreeSign Chat SDK */
|
package/dist/chat.d.ts
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { CancelChat, ChatInput, Runtime } from './types';
|
|
2
|
+
/** Build a one-shot chat function over one runtime */
|
|
3
|
+
declare const createChatOn: (service: Runtime) => ((input: ChatInput) => CancelChat);
|
|
4
|
+
declare const createChat: (input: ChatInput) => CancelChat;
|
|
5
|
+
export { createChat, createChatOn };
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { ChatMessage, ChatModel, EngineMessage, EngineRunParams, LlmLimits, StreamReplyParams } from '../types';
|
|
2
|
+
/** Default token, prompt and thread budgets */
|
|
3
|
+
declare const defaultLlmLimits: LlmLimits;
|
|
4
|
+
/** Merge developer budgets over the defaults */
|
|
5
|
+
declare const resolveLlmLimits: (overrides?: Partial<LlmLimits>) => LlmLimits;
|
|
6
|
+
/** Sampling options shared by every engine stream */
|
|
7
|
+
declare const replyOptions: (limits: LlmLimits, reasoning: boolean) => {
|
|
8
|
+
stream: true;
|
|
9
|
+
temperature: number;
|
|
10
|
+
max_tokens: number;
|
|
11
|
+
};
|
|
12
|
+
declare const
|
|
13
|
+
/** Map the host messages to OpenAI-style turns, bounded for local context */
|
|
14
|
+
buildMessages: (messages: ChatMessage[], limits?: LlmLimits) => EngineMessage[],
|
|
15
|
+
/** Split inline reasoning markers out of the streamed content */
|
|
16
|
+
createThinkSplitter: (onReason: (text: string) => void, onText: (text: string) => void) => {
|
|
17
|
+
feed: (text: string) => void;
|
|
18
|
+
flush: () => void;
|
|
19
|
+
};
|
|
20
|
+
declare const
|
|
21
|
+
/** Log an engine chat call with all message text censored */
|
|
22
|
+
logChatCall: (model: ChatModel, messages: EngineMessage[]) => void,
|
|
23
|
+
/** Stream one reply, logging it and returning undefined when stopped */
|
|
24
|
+
streamReply: ({ model, logging, onReason, onText, start, stopped, }: StreamReplyParams) => Promise<string | undefined>;
|
|
25
|
+
declare const
|
|
26
|
+
/** Build the prompt and stream one reply through an engine */
|
|
27
|
+
runEngineChat: ({ model, params, start, stopped, }: EngineRunParams) => Promise<string | undefined>;
|
|
28
|
+
export { buildMessages, createThinkSplitter, logChatCall, runEngineChat, streamReply, replyOptions, defaultLlmLimits, resolveLlmLimits, };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { EngineMessage } from '../types';
|
|
2
|
+
/** Square image side sent to an engine, a multiple of 48 */
|
|
3
|
+
declare const imageSide = 288;
|
|
4
|
+
/** Center-crop one image URL to a square and resize it for an engine */
|
|
5
|
+
declare const resizeImageUrl: (url: string) => Promise<string>;
|
|
6
|
+
/** Center-crop and resize every image part before an engine sees it */
|
|
7
|
+
declare const resizeImages: (messages: EngineMessage[]) => Promise<EngineMessage[]>;
|
|
8
|
+
export { imageSide, resizeImageUrl, resizeImages, };
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { EngineMessage, LlmEngine, LlmRuntime, StartLlmParams, WllamaMessage } from '../types';
|
|
2
|
+
/** CPU threads after the hardware maximum and the caller cap */
|
|
3
|
+
declare const cpuThreads: (cores: number, maxThreads: number) => number;
|
|
4
|
+
declare const
|
|
5
|
+
/** Decode an image URL into bytes for wllama */
|
|
6
|
+
imageBuffer: (url: string) => Promise<ArrayBuffer>,
|
|
7
|
+
/** Map built messages to wllama turns */
|
|
8
|
+
toWllamaMessages: (messages: EngineMessage[]) => Promise<WllamaMessage[]>,
|
|
9
|
+
/** Whether any turn carries an image */
|
|
10
|
+
hasImages: (messages: EngineMessage[]) => boolean,
|
|
11
|
+
/** Start the CPU runtime, the unified engine entry */
|
|
12
|
+
startLLM: ({ model, limits, onProgress, signal, logging, assets: overrides, }: StartLlmParams) => Promise<LlmRuntime>, wllamaEngine: LlmEngine;
|
|
13
|
+
export { cpuThreads, hasImages, imageBuffer, startLLM, toWllamaMessages, wllamaEngine, };
|
package/dist/enums.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/** Who a chat message is from */
|
|
2
|
+
declare enum LlmRole {
|
|
3
|
+
system = "system",
|
|
4
|
+
user = "user",
|
|
5
|
+
assistant = "assistant"
|
|
6
|
+
}
|
|
7
|
+
/** Assistant availability derived from the engine */
|
|
8
|
+
declare enum ChatStatus {
|
|
9
|
+
online = 0,
|
|
10
|
+
away = 1,
|
|
11
|
+
offline = 2
|
|
12
|
+
}
|
|
13
|
+
/** On-device engine availability */
|
|
14
|
+
declare enum LlmStatus {
|
|
15
|
+
idle = 0,
|
|
16
|
+
downloading = 1,
|
|
17
|
+
ready = 2,
|
|
18
|
+
error = 3,
|
|
19
|
+
unsupported = 4
|
|
20
|
+
}
|
|
21
|
+
/** Which engine runs the model on this device */
|
|
22
|
+
declare enum LlmBackend {
|
|
23
|
+
cpu = "cpu",
|
|
24
|
+
none = "none"
|
|
25
|
+
}
|
|
26
|
+
/** Download or load-into-memory phase of a model load */
|
|
27
|
+
declare enum LlmPhase {
|
|
28
|
+
download = "download",
|
|
29
|
+
load = "load"
|
|
30
|
+
}
|
|
31
|
+
/** Catalog ids of the on-device models */
|
|
32
|
+
declare enum ChatModelId {
|
|
33
|
+
qwen3_vl_2b = "qwen3-vl-2b"
|
|
34
|
+
}
|
|
35
|
+
export { LlmRole, ChatStatus, LlmStatus, LlmBackend, LlmPhase, ChatModelId, };
|
package/dist/index.d.ts
ADDED
package/dist/models.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ChatModel } from './types';
|
|
2
|
+
declare const llmModels: ChatModel[],
|
|
3
|
+
/** Context window requested from the CPU engine, a 32k KV cache needs 3.5 GB */
|
|
4
|
+
cpuContextWindow = 8192,
|
|
5
|
+
/** Look up a catalog entry by id */
|
|
6
|
+
findLlmModel: (id?: string) => ChatModel | undefined,
|
|
7
|
+
/** Whether a model accepts images */
|
|
8
|
+
supportsImages: (model: ChatModel) => boolean;
|
|
9
|
+
export { llmModels, cpuContextWindow, findLlmModel, supportsImages, };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! For license information please see chat.node.min.js.LICENSE.txt */
|
|
2
|
+
(()=>{"use strict";var e={};const t={};function n(a){const o=t[a];if(void 0!==o)return o.exports;const r=t[a]={exports:{}};return e[a](r,r.exports,n),r.exports}n.m=e,n.d=(e,t)=>{for(var a in t)n.o(t,a)&&!n.o(e,a)&&Object.defineProperty(e,a,{enumerable:!0,get:t[a]})},n.f={},n.e=e=>{const t=[];return n.f.require(e,t),Promise.all(t)},n.u=e=>"engine-wllama.node.min.js",n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),n.r=e=>{Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},(()=>{const e={792:1};n.f.require=(t,a)=>{if(!e[t]){const a=require("./"+n.u(t));e[t]||(t=>{const a=t.modules,o=t.ids,r=t.runtime;for(var s in a)n.o(a,s)&&(n.m[s]=a[s]);r&&r(n);for(var i=0;i<o.length;i++)e[o[i]]=1})(a)}}})();let a={};var o,r,s,i,c,l;n.r(a),n.d(a,{ChatModelId:()=>l,ChatStatus:()=>r,LlmBackend:()=>i,LlmPhase:()=>c,LlmRole:()=>o,LlmStatus:()=>s,createChat:()=>D}),function(e){e.system="system",e.user="user",e.assistant="assistant"}(o||(o={})),function(e){e[e.online=0]="online",e[e.away=1]="away",e[e.offline=2]="offline"}(r||(r={})),function(e){e[e.idle=0]="idle",e[e.downloading=1]="downloading",e[e.ready=2]="ready",e[e.error=3]="error",e[e.unsupported=4]="unsupported"}(s||(s={})),function(e){e.cpu="cpu",e.none="none"}(i||(i={})),function(e){e.download="download",e.load="load"}(c||(c={})),function(e){e.qwen3_vl_2b="qwen3-vl-2b"}(l||(l={}));const d=[{id:l.qwen3_vl_2b,reasoning:!0,cpu:{repo:"Qwen/Qwen3-VL-2B-Thinking-GGUF",file:"Qwen3VL-2B-Thinking-Q4_K_M.gguf",mmproj:{file:"mmproj-Qwen3VL-2B-Thinking-Q8_0.gguf"}}}],g=e=>e?d.find(t=>t.id==e):void 0,u=e=>!!e.cpu.mmproj,m=require("node:path"),f=()=>{return e=(0,m.join)(__dirname,"../assets/wllama"),{wasm:(0,m.join)(e,"wllama.wasm"),compatWasm:(0,m.join)(e,"compat/wllama.wasm"),compatWorker:(0,m.join)(e,"compat/wllama.js")};var e},p=288,h=async e=>{if(!e||"function"!=typeof fetch||"function"!=typeof createImageBitmap)return e;try{const t=await fetch(e),n=await createImageBitmap(await t.blob()),a=Math.min(n.width,n.height),o=Math.floor((n.width-a)/2),r=Math.floor((n.height-a)/2),s=((e,t)=>{if("undefined"!=typeof OffscreenCanvas)return new OffscreenCanvas(e,t);if("undefined"==typeof document)return;const n=document.createElement("canvas");return n.width=e,n.height=t,n})(p,p),i=s?s.getContext("2d"):null;if(!s||!i||a<1)return n.close(),e;if(i.drawImage(n,o,r,a,a,0,0,p,p),n.close(),(e=>"undefined"!=typeof OffscreenCanvas&&e instanceof OffscreenCanvas)(s)){const t=await s.convertToBlob({type:"image/jpeg",quality:.85});return await(e=>new Promise(t=>{if("undefined"==typeof FileReader)return void t("");const n=new FileReader;n.onerror=()=>t(""),n.onload=()=>t(`${n.result}`),n.readAsDataURL(e)}))(t)||e}return s.toDataURL("image/jpeg",.85)}catch{return e}},y={maxReplyTokens:200,maxThinkingTokens:64,maxReasoningTokens:150,maxImages:2,maxContentLength:1e3,promptCharBudget:1e4,maxThreads:2},w=(e,t,n)=>"number"==typeof e&&Number.isFinite(e)&&e>=n?Math.floor(e):t,x=["<|channel>thought\n","<|channel>thought","..."],v=["<channel|>","..."],k=(e,t)=>t.length?[...e?[{type:"text",text:e}]:[],...t.map(e=>({type:"image",url:e}))]:e,b=e=>"string"==typeof e?e?[{type:"text",text:e}]:[]:e,T=(e,t)=>{if("string"==typeof e&&"string"==typeof t)return`${e}\n${t}`;const n=[];for(const a of[...b(e),{type:"text",text:"\n"},...b(t)]){const e=n[n.length-1];"text"==a.type&&"text"==e?.type?e.text+=a.text:n.push(a)}return n},M=async({model:e,logging:t,onReason:n,onText:a,start:o,stopped:r})=>{let s="",i="",c="";const l=((e,t)=>{let n="",a=!1;const o=(e,t)=>{let n=-1,a="";for(const o of t){const t=e.indexOf(o);t>=0&&(n<0||t<n)&&(n=t,a=o)}return{at:n,tag:a}},r=(e,t)=>{let n="";for(const a of t)for(let t=Math.min(e.length,a.length-1);t>n.length;t--)if(e.endsWith(a.slice(0,t))){n=e.slice(e.length-t);break}return n};return{feed:s=>{let i=n+s;for(n="";i;){if(a){const{at:t,tag:s}=o(i,v);if(t>=0){t&&e(i.slice(0,t)),i=i.slice(t+s.length),a=!1;continue}const c=r(i,v);e(i.slice(0,i.length-c.length)),n=c;break}{const{at:e,tag:s}=o(i,x);if(e>=0){e&&t(i.slice(0,e)),i=i.slice(e+s.length),i.startsWith("\n")&&(i=i.slice(1)),a=!0;continue}const c=r(i,x);t(i.slice(0,i.length-c.length)),n=c;break}}},flush:()=>{n&&(a?e(n):t(n),n="")}}})(e=>{i+=e,n(e)},e=>{s+=e,a(e)});try{const e=await o();for await(const t of e){if(r())break;const e=t?.choices?.[0],a=e?.delta,o="string"==typeof a?.reasoning_content?a.reasoning_content:"string"==typeof a?.reasoning?a.reasoning:"";e?.finish_reason&&(c=e.finish_reason),o&&(i+=o,n(o)),a?.content&&l.feed(a.content)}l.flush()}catch(e){t&&console.log("Local chat failed",e)}const d=r()?void 0:s||void 0;return t&&(console.log("Local chat reply",e.id,d?"****":""),console.log("Local chat finish",e.id,c||"none",s.length,i.length)),d},C=async({model:e,params:t,start:n,stopped:a})=>{const r=await(async e=>{const t=[];for(const n of e){if("string"==typeof n.content){t.push(n);continue}const e=[];for(const t of n.content)e.push("image"==t.type?{type:"image",url:await h(t.url)}:t);t.push({role:"user",content:e})}return t})(((e,t=y)=>{const n=t.maxContentLength,a=e.filter(e=>"string"==typeof e.content&&!!e.content.trim()||!(e.role!=o.user||!e.images?.length)),r=[],s=[];let i=0,c=t.maxImages;for(let e=a.length-1;e>=0;e--){const l=a[e],d=("string"==typeof l.content?l.content:"").slice(0,n),g=l.role==o.user?(l.images||[]).filter(e=>"string"==typeof e&&!!e).slice(0,Math.max(0,c)):[];if(d||g.length){if(d&&i+d.length>t.promptCharBudget)break;i+=d.length,c-=g.length,l.role==o.system?r.unshift(d):l.role==o.assistant?s.unshift({role:"assistant",content:d}):s.unshift({role:"user",content:k(d,g)})}}for(;s.length&&"user"!=s[0].role;)s.shift();const l=[];for(const e of s){const t=l[l.length-1];"assistant"==t?.role&&"assistant"==e.role?t.content=`${t.content}\n${e.content}`:"user"==t?.role&&"user"==e.role?t.content=T(t.content,e.content):"assistant"==e.role?l.push({role:"assistant",content:e.content}):l.push({role:"user",content:e.content})}const d=r.join("\n\n"),g=[];return d&&g.push({role:"system",content:d}),g.push(...l),g})(t.messages,t.limits));return t.logging&&((e,t)=>{console.log("Local chat call",e.id,t.map(({role:e,content:t})=>({role:e,content:"****",...Array.isArray(t)?{images:t.filter(e=>"image"==e.type).length}:{}})))})(e,r),await M({model:e,logging:t.logging,onReason:t.onReason,onText:t.onText,start:()=>n(r),stopped:a})};let _,L,j="",R=!1;const W=e=>`${e.wasm}|${e.compatWasm}|${e.compatWorker}`,q=e=>{const t=f();return{wasm:e?.wasm||t.wasm,compatWasm:e?.compatWasm||t.compatWasm,compatWorker:e?.compatWorker||t.compatWorker}},$=e=>{const t=e=>(...t)=>{R&&("string"==typeof t[0]&&t[0].includes("ggml_webgpu: Failed to get an adapter")||e(...t))};return{...e,log:t(e.log),warn:t(e.warn),error:t(e.error)}},B=async()=>{if(_)return _;const e=await n.e(924).then(()=>n(577)),t=L||q(),a=new e.Wllama({default:t.wasm},{logger:$(e.LoggerWithoutDebug)});return L||(L=t,j=W(t)),a.setCompat({wasm:t.compatWasm,worker:t.compatWorker}),_=a,a},I=async()=>{const e=_;_=void 0;try{await(e?.exit())}catch{}},O=(e,t)=>e.name.includes(t)||!!e.metadata?.originalURL?.includes(t),P=e=>[e.cpu.file,...e.cpu.mmproj?[e.cpu.mmproj.file]:[]],A=(e,t)=>`https://huggingface.co/${e}/resolve/main/${t}`,U=async e=>{if(!e.startsWith("data:"))return await(await fetch(e)).arrayBuffer();const t=e.indexOf(","),n=t>=0?e.slice(0,t):"";if(t<0)throw new Error("Invalid image data");if(!n.includes(";base64"))return await(await fetch(e)).arrayBuffer();const a=atob(e.slice(t+1)),o=new Uint8Array(a.length);for(let e=0;e<a.length;e++)o[e]=a.charCodeAt(e);return o.buffer},F=async e=>{const t=[];for(const n of e){if("string"==typeof n.content){"system"==n.role?t.push({role:"system",content:n.content}):"assistant"==n.role?t.push({role:"assistant",content:n.content}):t.push({role:"user",content:n.content});continue}const e=[];for(const t of n.content)e.push("text"==t.type?{type:"text",text:t.text}:{type:"image",data:await U(t.url)});t.push({role:"user",content:e})}return t},S=async(e,t,n)=>{if(R=!0===n.logging,e.isModelLoaded())return await C({model:t,params:n,stopped:()=>!!n.signal?.aborted,start:async a=>{if((e=>e.some(e=>Array.isArray(e.content)&&e.content.some(e=>"image"==e.type)))(a)&&!e.supportInputModality("image"))throw new Error("Model does not accept images");return await e.createChatCompletion({messages:await F(a),...(o=n.limits,r=n.reasoning,{stream:!0,temperature:.7,max_tokens:r?o.maxReasoningTokens:o.maxReplyTokens}),abortSignal:n.signal,...t.reasoning?{chat_template_kwargs:{enable_thinking:n.reasoning}}:{}});var o,r}})},E={backend:i.cpu,startLLM:async({model:e,limits:t,onProgress:n,signal:a,logging:o,assets:r})=>{R=!0===o;const s=q(r),l=W(s);_&&l!=j&&await I(),L=s,j=l;const d=(g="undefined"!=typeof navigator&&navigator.hardwareConcurrency||4,u=t.maxThreads,Math.max(1,Math.min(Math.max(2,Math.min(8,(g||4)-1)),u)));var g,u;const m=await B(),f=A(e.cpu.repo,e.cpu.file),p=e.cpu.mmproj?.file,h=p?A(e.cpu.repo,p):"";if(a?.aborted)throw await I(),new Error("Cancelled");if(p){const t=await m.cacheManager.list(),n=t.some(t=>O(t,e.cpu.file)),a=t.some(e=>O(e,p));n&&!a&&await m.cacheManager.deleteMany(t=>O(t,e.cpu.file))}try{await m.loadModelFromUrl(h?{url:f,mmprojUrl:h}:f,{n_ctx:8192,n_threads:d,reasoning_budget_tokens:t.maxThinkingTokens,n_gpu_layers:0,useCache:!0,jinja:!0,signal:a,progressCallback:({loaded:e,total:t})=>{const a=t?e/t:0;n(a,a>=1?c.load:c.download)}})}catch(e){throw await I(),e}if(a?.aborted)throw await I(),new Error("Cancelled");if(!m.getLoadedContextInfo().n_ctx)throw await I(),new Error("Failed to create model context");return{model:e,backend:i.cpu,contextSize:8192,chat:t=>S(m,e,t),unload:async()=>{if(_==m)await I();else try{await m.exit()}catch{}}}},cached:async e=>{try{const t=await B(),n=await t.cacheManager.list();return P(e).every(e=>n.some(t=>O(t,e)))}catch{return!1}},hasCache:async()=>{try{const e=await B();return(await e.cacheManager.list()).length>0}catch{return!1}},remove:async e=>{try{const t=await B();await t.cacheManager.deleteMany(t=>P(e).some(e=>O(t,e)))}catch{}},purge:async()=>{try{const e=await B();await e.cacheManager.clear()}catch{}}},Q=((e={})=>{const t=e.engines?.cpu||E;let n,a,o,r,l,g,u,m=i.none,f=s.idle,p=0,h={percent:0,phase:c.download};const y=()=>e.backend||("undefined"==typeof window&&"undefined"==typeof self&&"undefined"==typeof Worker||"undefined"==typeof WebAssembly?i.none:i.cpu),w=async()=>{await t.purge()},x=(e,t)=>{h={percent:Math.max(0,Math.min(1,e)),phase:t||c.download},g?.(h.percent,h.phase)},v=e=>{f=e},k=()=>f==s.ready&&!!n&&!!a;return{load:async({model:e,limits:u,assets:f,logging:b,onProgress:T})=>{if(k()&&a?.id==e.id)return!0;if(o&&r==e.id)return g=T,T(h.percent,h.phase),await o;o&&(g=void 0,l?.abort(),await o.catch(()=>!1)),g=T;const M=++p,C=(async()=>{await(async()=>{try{if("undefined"==typeof navigator)return;await(navigator.storage?.persist?.())}catch{}})();const o=y();if(M!=p)return!1;if(o==i.none)return v(s.unsupported),!1;if(await(async e=>{if(a&&a.id!=e.id){const e=a,o=n;n=void 0,a=void 0,await(o?.unload()),await t.remove(e)}if(await t.hasCache())for(const n of d)n.id!=e.id&&await t.remove(n)})(e),M!=p)return!1;const r=await t.cached(e);if(M!=p)return!1;if(!r&&await(async()=>{try{if("undefined"==typeof navigator)return!1;if(!navigator.storage?.estimate)return!1;const{quota:e=0,usage:t=0}=await navigator.storage.estimate();return!!e&&t>=e}catch{return!1}})()&&await w(),M!=p)return!1;v(s.downloading),x(0,c.download),r&&x(1,c.load);const g=new AbortController;l=g;try{const r=await t.startLLM({model:e,limits:u,logging:b,signal:g.signal,assets:f,onProgress:(e,t)=>{M==p&&x(e,t)}});return M!=p||g.signal.aborted?(await r.unload(),!1):(n=r,a=e,m=o,v(s.ready),x(1,c.load),!0)}catch(e){return M!=p||(n=void 0,a=void 0,b&&console.log("Local model failed",e),(e=>["quota","no space","disk full","ns_error_dom_quota_reached"].some(t=>`${e?.name||""} ${e?.message||`${e}`}`.toLowerCase().includes(t)))(e)&&await w(),v(s.error)),!1}finally{l==g&&(l=void 0)}})().finally(()=>{o==C&&(o=void 0,r=void 0)});return o=C,r=e.id,await C},chat:async e=>{if(!k()||!n)return;for(;u;)await u.catch(()=>{});if(!k()||!n)return;const t=n.chat(e);u=t;try{return await t}finally{u==t&&(u=void 0)}},unload:async()=>{p++,l?.abort(),l=void 0,r=void 0;const e=n;n=void 0,a=void 0,v(s.idle),await(e?.unload())},cancelLoad:()=>{p++,l?.abort(),l=void 0,r=void 0,f==s.downloading&&v(s.idle)},ready:k,loading:()=>!k()&&f==s.downloading,status:()=>f,backend:()=>m,model:()=>a}})(),D=(e=>{let t,n=0;const a=t=>{const n=e.status(),a=e.backend(),o=g(t.input.model),i={availability:n==s.ready?r.online:n==s.error||n==s.unsupported?r.offline:r.away,status:n,backend:a,supportsImages:!!o&&u(o),ready:e.ready(),loading:e.loading(),requesting:t.requesting,phase:t.phase,percent:t.percent,...t.error?{error:t.error}:{}};t.input.onStatus?.(i)},i=async t=>{const{input:r}=t,s=!0===r.logging,i=g(r.model),l=r.messages.some(e=>e.role!=o.system&&"string"==typeof e.content&&!!e.content.trim()),d=r.messages.some(e=>e.role==o.user&&!!e.images?.some(e=>"string"==typeof e&&!!e)),m=l||d;if(!i)return t.error="Unknown model",void a(t);if(!m)return void a(t);if(d&&!l&&!u(i))return t.error="Model does not accept images",void a(t);const f=((e={})=>{const t=y;return{maxReplyTokens:w(e.maxReplyTokens,t.maxReplyTokens,1),maxThinkingTokens:w(e.maxThinkingTokens,t.maxThinkingTokens,1),maxReasoningTokens:w(e.maxReasoningTokens,t.maxReasoningTokens,1),maxImages:w(e.maxImages,t.maxImages,0),maxContentLength:w(e.maxContentLength,t.maxContentLength,1),promptCharBudget:w(e.promptCharBudget,t.promptCharBudget,1),maxThreads:w(e.maxThreads,t.maxThreads,1)}})(r.limits),p=await e.load({model:i,limits:f,logging:s,onProgress:(e,o)=>{t.token==n&&(t.percent=Math.round(100*e),t.phase=o,a(t))}}).catch(e=>(t.token==n&&(t.error=`${e?.message||`${e}`}`),!1));if(t.token!=n)return;if(!p)return t.cancelled||t.error||(t.error="Model not ready"),void a(t);const h=u(i),x=d&&!h?r.messages.map(({images:e,...t})=>t):r.messages;if(d&&!h&&!l)return t.error="Model does not accept images",void a(t);t.requesting=!0,t.error=void 0,t.percent=100,t.phase=c.load,a(t);let v,k="",b="";try{v=await e.chat({messages:x,limits:f,reasoning:!0===r.reasoning,logging:s,onReason:e=>{t.token!=n||t.cancelled||(k+=e,r.onThinking?.(k))},onText:e=>{t.token!=n||t.cancelled||(b+=e,r.onResponse?.(b))},signal:t.controller.signal})}catch(e){if(t.token!=n)return;return t.requesting=!1,t.error=`${e?.message||`${e}`}`,void a(t)}t.token==n&&(t.requesting=!1,v||t.cancelled||(t.error="No reply"),a(t))};return o=>{t?.controller.abort();const r={token:++n,input:o,controller:new AbortController,percent:e.ready()?100:0,phase:e.ready()?c.load:c.download,requesting:!1,cancelled:!1};return t=r,a(r),i(r),()=>(t=>{t.token==n&&(t.cancelled=!0,t.controller.abort(),e.status()!=s.ready?(e.cancelLoad(),a(t)):e.unload().then(()=>a(t)))})(r)}})(Q);module.exports=a})();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/*! MIT License. DegreeSign Chat SDK */
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
/*! For license information please see chat.node.min.mjs.LICENSE.txt */
|
|
2
|
+
import{dirname as e,join as t}from"node:path";import{fileURLToPath as n}from"node:url";var a={};const o={};function r(e){const t=o[e];if(void 0!==t)return t.exports;const n=o[e]={exports:{}};return a[e](n,n.exports,r),n.exports}var s,i,c,l,d,g;r.m=a,r.d=(e,t)=>{for(var n in t)r.o(t,n)&&!r.o(e,n)&&Object.defineProperty(e,n,{enumerable:!0,get:t[n]})},r.f={},r.e=e=>{const t=[];return r.f.j(e,t),Promise.all(t)},r.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),r.r=e=>{Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},(()=>{const e={924:()=>import("./engine-wllama.node.min.mjs")},t={792:0},n=e=>{let{__webpack_esm_ids__:n,__webpack_esm_modules__:a,__webpack_esm_runtime__:o}=e;var s,i,c=0;for(s in a)r.o(a,s)&&(r.m[s]=a[s]);for(o&&o(r);c<n.length;c++)i=n[c],r.o(t,i)&&t[i]&&t[i][0](),t[i]=0};r.f.j=(a,o)=>{let s=r.o(t,a)?t[a]:void 0;if(0!==s)if(s)o.push(s[1]);else{let r=e[a]().then(n,e=>{throw 0!==t[a]&&(t[a]=void 0),e});r=Promise.race([r,new Promise(e=>s=t[a]=[e])]),o.push(s[1]=r)}}})(),function(e){e.system="system",e.user="user",e.assistant="assistant"}(s||(s={})),function(e){e[e.online=0]="online",e[e.away=1]="away",e[e.offline=2]="offline"}(i||(i={})),function(e){e[e.idle=0]="idle",e[e.downloading=1]="downloading",e[e.ready=2]="ready",e[e.error=3]="error",e[e.unsupported=4]="unsupported"}(c||(c={})),function(e){e.cpu="cpu",e.none="none"}(l||(l={})),function(e){e.download="download",e.load="load"}(d||(d={})),function(e){e.qwen3_vl_2b="qwen3-vl-2b"}(g||(g={}));const u=[{id:g.qwen3_vl_2b,reasoning:!0,cpu:{repo:"Qwen/Qwen3-VL-2B-Thinking-GGUF",file:"Qwen3VL-2B-Thinking-Q4_K_M.gguf",mmproj:{file:"mmproj-Qwen3VL-2B-Thinking-Q8_0.gguf"}}}],m=e=>e?u.find(t=>t.id==e):void 0,f=e=>!!e.cpu.mmproj,p=()=>{return a=t(e(n("file:///media/x/store/code/DegreeSign/ds_chat/src/assets/nodeEsm.js")),"../assets/wllama"),{wasm:t(a,"wllama.wasm"),compatWasm:t(a,"compat/wllama.wasm"),compatWorker:t(a,"compat/wllama.js")};var a},h=288,w=async e=>{if(!e||"function"!=typeof fetch||"function"!=typeof createImageBitmap)return e;try{const t=await fetch(e),n=await createImageBitmap(await t.blob()),a=Math.min(n.width,n.height),o=Math.floor((n.width-a)/2),r=Math.floor((n.height-a)/2),s=((e,t)=>{if("undefined"!=typeof OffscreenCanvas)return new OffscreenCanvas(e,t);if("undefined"==typeof document)return;const n=document.createElement("canvas");return n.width=e,n.height=t,n})(h,h),i=s?s.getContext("2d"):null;if(!s||!i||a<1)return n.close(),e;if(i.drawImage(n,o,r,a,a,0,0,h,h),n.close(),(e=>"undefined"!=typeof OffscreenCanvas&&e instanceof OffscreenCanvas)(s)){const t=await s.convertToBlob({type:"image/jpeg",quality:.85});return await(e=>new Promise(t=>{if("undefined"==typeof FileReader)return void t("");const n=new FileReader;n.onerror=()=>t(""),n.onload=()=>t(`${n.result}`),n.readAsDataURL(e)}))(t)||e}return s.toDataURL("image/jpeg",.85)}catch{return e}},y={maxReplyTokens:200,maxThinkingTokens:64,maxReasoningTokens:150,maxImages:2,maxContentLength:1e3,promptCharBudget:1e4,maxThreads:2},x=(e,t,n)=>"number"==typeof e&&Number.isFinite(e)&&e>=n?Math.floor(e):t,k=["<|channel>thought\n","<|channel>thought","..."],v=["<channel|>","..."],b=(e,t)=>t.length?[...e?[{type:"text",text:e}]:[],...t.map(e=>({type:"image",url:e}))]:e,_=e=>"string"==typeof e?e?[{type:"text",text:e}]:[]:e,T=(e,t)=>{if("string"==typeof e&&"string"==typeof t)return`${e}\n${t}`;const n=[];for(const a of[..._(e),{type:"text",text:"\n"},..._(t)]){const e=n[n.length-1];"text"==a.type&&"text"==e?.type?e.text+=a.text:n.push(a)}return n},M=async({model:e,logging:t,onReason:n,onText:a,start:o,stopped:r})=>{let s="",i="",c="";const l=((e,t)=>{let n="",a=!1;const o=(e,t)=>{let n=-1,a="";for(const o of t){const t=e.indexOf(o);t>=0&&(n<0||t<n)&&(n=t,a=o)}return{at:n,tag:a}},r=(e,t)=>{let n="";for(const a of t)for(let t=Math.min(e.length,a.length-1);t>n.length;t--)if(e.endsWith(a.slice(0,t))){n=e.slice(e.length-t);break}return n};return{feed:s=>{let i=n+s;for(n="";i;){if(a){const{at:t,tag:s}=o(i,v);if(t>=0){t&&e(i.slice(0,t)),i=i.slice(t+s.length),a=!1;continue}const c=r(i,v);e(i.slice(0,i.length-c.length)),n=c;break}{const{at:e,tag:s}=o(i,k);if(e>=0){e&&t(i.slice(0,e)),i=i.slice(e+s.length),i.startsWith("\n")&&(i=i.slice(1)),a=!0;continue}const c=r(i,k);t(i.slice(0,i.length-c.length)),n=c;break}}},flush:()=>{n&&(a?e(n):t(n),n="")}}})(e=>{i+=e,n(e)},e=>{s+=e,a(e)});try{const e=await o();for await(const t of e){if(r())break;const e=t?.choices?.[0],a=e?.delta,o="string"==typeof a?.reasoning_content?a.reasoning_content:"string"==typeof a?.reasoning?a.reasoning:"";e?.finish_reason&&(c=e.finish_reason),o&&(i+=o,n(o)),a?.content&&l.feed(a.content)}l.flush()}catch(e){t&&console.log("Local chat failed",e)}const d=r()?void 0:s||void 0;return t&&(console.log("Local chat reply",e.id,d?"****":""),console.log("Local chat finish",e.id,c||"none",s.length,i.length)),d},C=async({model:e,params:t,start:n,stopped:a})=>{const o=await(async e=>{const t=[];for(const n of e){if("string"==typeof n.content){t.push(n);continue}const e=[];for(const t of n.content)e.push("image"==t.type?{type:"image",url:await w(t.url)}:t);t.push({role:"user",content:e})}return t})(((e,t=y)=>{const n=t.maxContentLength,a=e.filter(e=>"string"==typeof e.content&&!!e.content.trim()||!(e.role!=s.user||!e.images?.length)),o=[],r=[];let i=0,c=t.maxImages;for(let e=a.length-1;e>=0;e--){const l=a[e],d=("string"==typeof l.content?l.content:"").slice(0,n),g=l.role==s.user?(l.images||[]).filter(e=>"string"==typeof e&&!!e).slice(0,Math.max(0,c)):[];if(d||g.length){if(d&&i+d.length>t.promptCharBudget)break;i+=d.length,c-=g.length,l.role==s.system?o.unshift(d):l.role==s.assistant?r.unshift({role:"assistant",content:d}):r.unshift({role:"user",content:b(d,g)})}}for(;r.length&&"user"!=r[0].role;)r.shift();const l=[];for(const e of r){const t=l[l.length-1];"assistant"==t?.role&&"assistant"==e.role?t.content=`${t.content}\n${e.content}`:"user"==t?.role&&"user"==e.role?t.content=T(t.content,e.content):"assistant"==e.role?l.push({role:"assistant",content:e.content}):l.push({role:"user",content:e.content})}const d=o.join("\n\n"),g=[];return d&&g.push({role:"system",content:d}),g.push(...l),g})(t.messages,t.limits));return t.logging&&((e,t)=>{console.log("Local chat call",e.id,t.map(({role:e,content:t})=>({role:e,content:"****",...Array.isArray(t)?{images:t.filter(e=>"image"==e.type).length}:{}})))})(e,o),await M({model:e,logging:t.logging,onReason:t.onReason,onText:t.onText,start:()=>n(o),stopped:a})};let L,j,R="",W=!1;const $=e=>`${e.wasm}|${e.compatWasm}|${e.compatWorker}`,q=e=>{const t=p();return{wasm:e?.wasm||t.wasm,compatWasm:e?.compatWasm||t.compatWasm,compatWorker:e?.compatWorker||t.compatWorker}},B=e=>{const t=e=>(...t)=>{W&&("string"==typeof t[0]&&t[0].includes("ggml_webgpu: Failed to get an adapter")||e(...t))};return{...e,log:t(e.log),warn:t(e.warn),error:t(e.error)}},P=async()=>{if(L)return L;const e=await r.e(924).then(()=>r(577)),t=j||q(),n=new e.Wllama({default:t.wasm},{logger:B(e.LoggerWithoutDebug)});return j||(j=t,R=$(t)),n.setCompat({wasm:t.compatWasm,worker:t.compatWorker}),L=n,n},I=async()=>{const e=L;L=void 0;try{await(e?.exit())}catch{}},O=(e,t)=>e.name.includes(t)||!!e.metadata?.originalURL?.includes(t),A=e=>[e.cpu.file,...e.cpu.mmproj?[e.cpu.mmproj.file]:[]],U=(e,t)=>`https://huggingface.co/${e}/resolve/main/${t}`,E=async e=>{if(!e.startsWith("data:"))return await(await fetch(e)).arrayBuffer();const t=e.indexOf(","),n=t>=0?e.slice(0,t):"";if(t<0)throw new Error("Invalid image data");if(!n.includes(";base64"))return await(await fetch(e)).arrayBuffer();const a=atob(e.slice(t+1)),o=new Uint8Array(a.length);for(let e=0;e<a.length;e++)o[e]=a.charCodeAt(e);return o.buffer},F=async e=>{const t=[];for(const n of e){if("string"==typeof n.content){"system"==n.role?t.push({role:"system",content:n.content}):"assistant"==n.role?t.push({role:"assistant",content:n.content}):t.push({role:"user",content:n.content});continue}const e=[];for(const t of n.content)e.push("text"==t.type?{type:"text",text:t.text}:{type:"image",data:await E(t.url)});t.push({role:"user",content:e})}return t},Q=async(e,t,n)=>{if(W=!0===n.logging,e.isModelLoaded())return await C({model:t,params:n,stopped:()=>!!n.signal?.aborted,start:async a=>{if((e=>e.some(e=>Array.isArray(e.content)&&e.content.some(e=>"image"==e.type)))(a)&&!e.supportInputModality("image"))throw new Error("Model does not accept images");return await e.createChatCompletion({messages:await F(a),...(o=n.limits,r=n.reasoning,{stream:!0,temperature:.7,max_tokens:r?o.maxReasoningTokens:o.maxReplyTokens}),abortSignal:n.signal,...t.reasoning?{chat_template_kwargs:{enable_thinking:n.reasoning}}:{}});var o,r}})},S={backend:l.cpu,startLLM:async({model:e,limits:t,onProgress:n,signal:a,logging:o,assets:r})=>{W=!0===o;const s=q(r),i=$(s);L&&i!=R&&await I(),j=s,R=i;const c=(g="undefined"!=typeof navigator&&navigator.hardwareConcurrency||4,u=t.maxThreads,Math.max(1,Math.min(Math.max(2,Math.min(8,(g||4)-1)),u)));var g,u;const m=await P(),f=U(e.cpu.repo,e.cpu.file),p=e.cpu.mmproj?.file,h=p?U(e.cpu.repo,p):"";if(a?.aborted)throw await I(),new Error("Cancelled");if(p){const t=await m.cacheManager.list(),n=t.some(t=>O(t,e.cpu.file)),a=t.some(e=>O(e,p));n&&!a&&await m.cacheManager.deleteMany(t=>O(t,e.cpu.file))}try{await m.loadModelFromUrl(h?{url:f,mmprojUrl:h}:f,{n_ctx:8192,n_threads:c,reasoning_budget_tokens:t.maxThinkingTokens,n_gpu_layers:0,useCache:!0,jinja:!0,signal:a,progressCallback:({loaded:e,total:t})=>{const a=t?e/t:0;n(a,a>=1?d.load:d.download)}})}catch(e){throw await I(),e}if(a?.aborted)throw await I(),new Error("Cancelled");if(!m.getLoadedContextInfo().n_ctx)throw await I(),new Error("Failed to create model context");return{model:e,backend:l.cpu,contextSize:8192,chat:t=>Q(m,e,t),unload:async()=>{if(L==m)await I();else try{await m.exit()}catch{}}}},cached:async e=>{try{const t=await P(),n=await t.cacheManager.list();return A(e).every(e=>n.some(t=>O(t,e)))}catch{return!1}},hasCache:async()=>{try{const e=await P();return(await e.cacheManager.list()).length>0}catch{return!1}},remove:async e=>{try{const t=await P();await t.cacheManager.deleteMany(t=>A(e).some(e=>O(t,e)))}catch{}},purge:async()=>{try{const e=await P();await e.cacheManager.clear()}catch{}}},D=((e={})=>{const t=e.engines?.cpu||S;let n,a,o,r,s,i,g,m=l.none,f=c.idle,p=0,h={percent:0,phase:d.download};const w=()=>e.backend||("undefined"==typeof window&&"undefined"==typeof self&&"undefined"==typeof Worker||"undefined"==typeof WebAssembly?l.none:l.cpu),y=async()=>{await t.purge()},x=(e,t)=>{h={percent:Math.max(0,Math.min(1,e)),phase:t||d.download},i?.(h.percent,h.phase)},k=e=>{f=e},v=()=>f==c.ready&&!!n&&!!a;return{load:async({model:e,limits:g,assets:f,logging:b,onProgress:_})=>{if(v()&&a?.id==e.id)return!0;if(o&&r==e.id)return i=_,_(h.percent,h.phase),await o;o&&(i=void 0,s?.abort(),await o.catch(()=>!1)),i=_;const T=++p,M=(async()=>{await(async()=>{try{if("undefined"==typeof navigator)return;await(navigator.storage?.persist?.())}catch{}})();const o=w();if(T!=p)return!1;if(o==l.none)return k(c.unsupported),!1;if(await(async e=>{if(a&&a.id!=e.id){const e=a,o=n;n=void 0,a=void 0,await(o?.unload()),await t.remove(e)}if(await t.hasCache())for(const n of u)n.id!=e.id&&await t.remove(n)})(e),T!=p)return!1;const r=await t.cached(e);if(T!=p)return!1;if(!r&&await(async()=>{try{if("undefined"==typeof navigator)return!1;if(!navigator.storage?.estimate)return!1;const{quota:e=0,usage:t=0}=await navigator.storage.estimate();return!!e&&t>=e}catch{return!1}})()&&await y(),T!=p)return!1;k(c.downloading),x(0,d.download),r&&x(1,d.load);const i=new AbortController;s=i;try{const r=await t.startLLM({model:e,limits:g,logging:b,signal:i.signal,assets:f,onProgress:(e,t)=>{T==p&&x(e,t)}});return T!=p||i.signal.aborted?(await r.unload(),!1):(n=r,a=e,m=o,k(c.ready),x(1,d.load),!0)}catch(e){return T!=p||(n=void 0,a=void 0,b&&console.log("Local model failed",e),(e=>["quota","no space","disk full","ns_error_dom_quota_reached"].some(t=>`${e?.name||""} ${e?.message||`${e}`}`.toLowerCase().includes(t)))(e)&&await y(),k(c.error)),!1}finally{s==i&&(s=void 0)}})().finally(()=>{o==M&&(o=void 0,r=void 0)});return o=M,r=e.id,await M},chat:async e=>{if(!v()||!n)return;for(;g;)await g.catch(()=>{});if(!v()||!n)return;const t=n.chat(e);g=t;try{return await t}finally{g==t&&(g=void 0)}},unload:async()=>{p++,s?.abort(),s=void 0,r=void 0;const e=n;n=void 0,a=void 0,k(c.idle),await(e?.unload())},cancelLoad:()=>{p++,s?.abort(),s=void 0,r=void 0,f==c.downloading&&k(c.idle)},ready:v,loading:()=>!v()&&f==c.downloading,status:()=>f,backend:()=>m,model:()=>a}})(),V=(e=>{let t,n=0;const a=t=>{const n=e.status(),a=e.backend(),o=m(t.input.model),r={availability:n==c.ready?i.online:n==c.error||n==c.unsupported?i.offline:i.away,status:n,backend:a,supportsImages:!!o&&f(o),ready:e.ready(),loading:e.loading(),requesting:t.requesting,phase:t.phase,percent:t.percent,...t.error?{error:t.error}:{}};t.input.onStatus?.(r)},o=async t=>{const{input:o}=t,r=!0===o.logging,i=m(o.model),c=o.messages.some(e=>e.role!=s.system&&"string"==typeof e.content&&!!e.content.trim()),l=o.messages.some(e=>e.role==s.user&&!!e.images?.some(e=>"string"==typeof e&&!!e)),g=c||l;if(!i)return t.error="Unknown model",void a(t);if(!g)return void a(t);if(l&&!c&&!f(i))return t.error="Model does not accept images",void a(t);const u=((e={})=>{const t=y;return{maxReplyTokens:x(e.maxReplyTokens,t.maxReplyTokens,1),maxThinkingTokens:x(e.maxThinkingTokens,t.maxThinkingTokens,1),maxReasoningTokens:x(e.maxReasoningTokens,t.maxReasoningTokens,1),maxImages:x(e.maxImages,t.maxImages,0),maxContentLength:x(e.maxContentLength,t.maxContentLength,1),promptCharBudget:x(e.promptCharBudget,t.promptCharBudget,1),maxThreads:x(e.maxThreads,t.maxThreads,1)}})(o.limits),p=await e.load({model:i,limits:u,logging:r,onProgress:(e,o)=>{t.token==n&&(t.percent=Math.round(100*e),t.phase=o,a(t))}}).catch(e=>(t.token==n&&(t.error=`${e?.message||`${e}`}`),!1));if(t.token!=n)return;if(!p)return t.cancelled||t.error||(t.error="Model not ready"),void a(t);const h=f(i),w=l&&!h?o.messages.map(({images:e,...t})=>t):o.messages;if(l&&!h&&!c)return t.error="Model does not accept images",void a(t);t.requesting=!0,t.error=void 0,t.percent=100,t.phase=d.load,a(t);let k,v="",b="";try{k=await e.chat({messages:w,limits:u,reasoning:!0===o.reasoning,logging:r,onReason:e=>{t.token!=n||t.cancelled||(v+=e,o.onThinking?.(v))},onText:e=>{t.token!=n||t.cancelled||(b+=e,o.onResponse?.(b))},signal:t.controller.signal})}catch(e){if(t.token!=n)return;return t.requesting=!1,t.error=`${e?.message||`${e}`}`,void a(t)}t.token==n&&(t.requesting=!1,k||t.cancelled||(t.error="No reply"),a(t))};return r=>{t?.controller.abort();const s={token:++n,input:r,controller:new AbortController,percent:e.ready()?100:0,phase:e.ready()?d.load:d.download,requesting:!1,cancelled:!1};return t=s,a(s),o(s),()=>(t=>{t.token==n&&(t.cancelled=!0,t.controller.abort(),e.status()!=c.ready?(e.cancelLoad(),a(t)):e.unload().then(()=>a(t)))})(s)}})(D);export{g as ChatModelId,i as ChatStatus,l as LlmBackend,d as LlmPhase,s as LlmRole,c as LlmStatus,V as createChat};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
/*! MIT License. DegreeSign Chat SDK */
|