react-cai 1.0.0
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/dist/index.d.mts +45 -0
- package/dist/index.d.ts +45 -0
- package/dist/index.js +1 -0
- package/dist/index.mjs +1 -0
- package/package.json +29 -0
- package/scripts/embed-worker.js +20 -0
- package/src/index.ts +3 -0
- package/src/types.ts +44 -0
- package/src/useLocalAI.ts +109 -0
- package/src/worker-embedded.ts +1 -0
- package/src/worker.ts +63 -0
- package/tsconfig.json +20 -0
- package/tsup.config.ts +37 -0
package/src/worker.ts
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// src/worker.ts
|
|
2
|
+
import { CreateMLCEngine, MLCEngineInterface } from "@mlc-ai/web-llm";
|
|
3
|
+
import { WorkerMessage, WorkerPayload } from "./types";
|
|
4
|
+
|
|
5
|
+
let engine: MLCEngineInterface | null = null;
|
|
6
|
+
|
|
7
|
+
self.onmessage = async (e: MessageEvent<any>) => {
|
|
8
|
+
// FIX: Destructure from payload because the hook wraps it
|
|
9
|
+
const { type, payload } = e.data;
|
|
10
|
+
|
|
11
|
+
try {
|
|
12
|
+
if (type === "LOAD" && payload) {
|
|
13
|
+
const { model, options } = payload;
|
|
14
|
+
|
|
15
|
+
const chatOpts = options?.context_window_size
|
|
16
|
+
? { context_window_size: options.context_window_size }
|
|
17
|
+
: undefined;
|
|
18
|
+
|
|
19
|
+
const engineConfig: any = {
|
|
20
|
+
initProgressCallback: (report: any) => {
|
|
21
|
+
postMsg({ type: "PROGRESS", payload: report });
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
let targetId = "";
|
|
26
|
+
|
|
27
|
+
// Handle Custom Records vs String IDs
|
|
28
|
+
if (typeof model === "object") {
|
|
29
|
+
targetId = model.model_id;
|
|
30
|
+
engineConfig.appConfig = {
|
|
31
|
+
model_list: [model]
|
|
32
|
+
};
|
|
33
|
+
} else {
|
|
34
|
+
targetId = model;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Create engine
|
|
38
|
+
engine = await CreateMLCEngine(targetId, engineConfig, chatOpts);
|
|
39
|
+
postMsg({ type: "READY" });
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if (type === "GENERATE" && engine) {
|
|
43
|
+
const { messages } = e.data; // Note: chat() sends 'messages' at top level
|
|
44
|
+
|
|
45
|
+
const chunks = await engine.chat.completions.create({
|
|
46
|
+
messages,
|
|
47
|
+
stream: true,
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
for await (const chunk of chunks) {
|
|
51
|
+
const content = chunk.choices[0]?.delta?.content || "";
|
|
52
|
+
if (content) postMsg({ type: "TOKEN", payload: content });
|
|
53
|
+
}
|
|
54
|
+
postMsg({ type: "DONE" });
|
|
55
|
+
}
|
|
56
|
+
} catch (err: any) {
|
|
57
|
+
postMsg({ type: "ERROR", payload: err?.message || String(err) });
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
function postMsg(msg: WorkerMessage) {
|
|
62
|
+
self.postMessage(msg);
|
|
63
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2017",
|
|
4
|
+
"module": "ESNext",
|
|
5
|
+
"lib": ["DOM", "DOM.Iterable", "ESNext"],
|
|
6
|
+
"declaration": true,
|
|
7
|
+
"sourceMap": true,
|
|
8
|
+
"strict": true,
|
|
9
|
+
"moduleResolution": "node",
|
|
10
|
+
"allowSyntheticDefaultImports": true,
|
|
11
|
+
"esModuleInterop": true,
|
|
12
|
+
"skipLibCheck": true,
|
|
13
|
+
"forceConsistentCasingInFileNames": true,
|
|
14
|
+
"incremental": false, // <--- THIS IS THE FIX
|
|
15
|
+
"jsx": "react",
|
|
16
|
+
"types":["@webgpu/types"]
|
|
17
|
+
},
|
|
18
|
+
"include": ["src"],
|
|
19
|
+
"exclude": ["node_modules", "dist"]
|
|
20
|
+
}
|
package/tsup.config.ts
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { defineConfig } from "tsup";
|
|
2
|
+
// ✅ CORRECT IMPORT for the named export
|
|
3
|
+
import { ObfuscatorPlugin } from "esbuild-plugin-obfuscator";
|
|
4
|
+
|
|
5
|
+
export default defineConfig({
|
|
6
|
+
entry: ["src/index.ts", "src/worker.ts"],
|
|
7
|
+
format: ["cjs", "esm"],
|
|
8
|
+
dts: true,
|
|
9
|
+
clean: true,
|
|
10
|
+
external: ["react"],
|
|
11
|
+
noExternal: ["@mlc-ai/web-llm"],
|
|
12
|
+
|
|
13
|
+
// Protection Config
|
|
14
|
+
splitting: false,
|
|
15
|
+
sourcemap: false,
|
|
16
|
+
minify: true,
|
|
17
|
+
|
|
18
|
+
// ✅ FIX: Move 'drop' inside esbuildOptions
|
|
19
|
+
esbuildOptions(options) {
|
|
20
|
+
options.drop = ['console', 'debugger'];
|
|
21
|
+
},
|
|
22
|
+
|
|
23
|
+
esbuildPlugins: [
|
|
24
|
+
ObfuscatorPlugin({
|
|
25
|
+
compact: true,
|
|
26
|
+
controlFlowFlattening: true,
|
|
27
|
+
deadCodeInjection: true,
|
|
28
|
+
deadCodeInjectionThreshold: 0.2,
|
|
29
|
+
identifierNamesGenerator: 'hexadecimal',
|
|
30
|
+
|
|
31
|
+
// KEEP THIS FALSE so your Worker can still talk to React
|
|
32
|
+
renameProperties: false,
|
|
33
|
+
|
|
34
|
+
splitStrings: true,
|
|
35
|
+
}),
|
|
36
|
+
],
|
|
37
|
+
});
|