xsai 0.0.2 → 0.0.4

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/README.md CHANGED
@@ -2,6 +2,46 @@
2
2
 
3
3
  Extra-small AI SDK for any OpenAI-compatible API.
4
4
 
5
+ <!-- automd:badges color="lime" license bundlephobia -->
6
+
7
+ [![npm version](https://img.shields.io/npm/v/xsai?color=lime)](https://npmjs.com/package/xsai)
8
+ [![npm downloads](https://img.shields.io/npm/dm/xsai?color=lime)](https://npm.chart.dev/xsai)
9
+ [![bundle size](https://img.shields.io/bundlephobia/minzip/xsai?color=lime)](https://bundlephobia.com/package/xsai)
10
+ [![license](https://img.shields.io/github/license/moeru-ai/xsai?color=lime)](https://github.com/moeru-ai/xsai/blob/main/LICENSE)
11
+
12
+ <!-- /automd -->
13
+
14
+ ## Why?
15
+
16
+ I'm working on a tiny local-LLM translator - [ARPK](https://github.com/moeru-ai/arpk), which is currently (v0.2.4) 449KB, of which 26% is `ollama-js` (the other 13% is the pointless `whatwg-fetch` that comes with `ollama-js`!)
17
+
18
+ I wanted to make every byte count, so I started writing a lightweight library - xsAI.
19
+
20
+ It provides an interface similar to the Vercel AI SDK, ESM-only and zero dependencies for minimal installation size.
21
+
22
+ ## Install
23
+
24
+ <!-- automd:pm-install auto=false -->
25
+
26
+ ```sh
27
+ # npm
28
+ npm install xsai
29
+
30
+ # yarn
31
+ yarn add xsai
32
+
33
+ # pnpm
34
+ pnpm install xsai
35
+
36
+ # bun
37
+ bun install xsai
38
+
39
+ # deno
40
+ deno install xsai
41
+ ```
42
+
43
+ <!-- /automd -->
44
+
5
45
  ## License
6
46
 
7
47
  [MIT](LICENSE.md)
package/dist/index.d.ts CHANGED
@@ -1,29 +1,58 @@
1
- interface Message {
2
- content: string;
3
- role: 'assistant' | 'system' | 'user' | ({} & string);
4
- }
5
-
6
- type Model = 'gemma2' | 'llama3.1' | 'llama3.2' | 'llama3.2-vision' | 'mistral-nemo' | 'mistral-small' | 'nemotron' | 'qwen2.5' | 'qwen2.5-coder' | ({} & string);
1
+ type GenerationModel = 'gemma2' | 'llama3.1' | 'llama3.2' | 'llama3.2-vision' | 'mistral-nemo' | 'mistral-small' | 'nemotron' | 'qwen2.5' | 'qwen2.5-coder' | ({} & string);
2
+ type EmbedModel = 'all-minilm' | 'mxbai-embed-large' | 'nomic-embed-text' | ({} & string);
7
3
 
8
4
  interface CommonRequestOptions {
9
- /**
10
- * @default `http://localhost:11434/v1`
11
- */
5
+ /** @default `http://localhost:11434/v1` */
12
6
  base?: string;
7
+ /** @default `undefined` */
8
+ headers?: HeadersInit;
9
+ }
10
+
11
+ interface EmbedOptions extends CommonRequestOptions {
12
+ [key: string]: unknown;
13
+ input: string | string[];
14
+ model: EmbedModel;
15
+ /** @default `embeddings` */
16
+ path?: 'embeddings' | ({} & string);
17
+ }
18
+ interface EmbedResponseUsage {
19
+ prompt_tokens: number;
20
+ total_tokens: number;
21
+ }
22
+ interface EmbedResult {
23
+ embedding: number[];
24
+ request: Request;
25
+ response: Response;
26
+ usage: EmbedResponseUsage;
13
27
  }
28
+ declare const embed: (options: EmbedOptions) => Promise<{
29
+ embedding: number[];
30
+ request: Request;
31
+ response: Response;
32
+ usage: EmbedResponseUsage;
33
+ }>;
34
+
35
+ type FinishReason = 'content_filter' | 'error' | 'length' | 'other' | 'stop' | 'tool-calls' | ({} & string);
14
36
 
15
37
  interface GenerateTextOptions extends CommonRequestOptions {
16
- messages?: Message[];
17
- model: Model;
38
+ [key: string]: unknown;
39
+ model: GenerationModel;
18
40
  /** @default `completions` */
19
41
  path?: 'completions' | ({} & string);
20
42
  prompt: string;
21
43
  }
44
+ interface GenerateTextResponseUsage {
45
+ completion_tokens: number;
46
+ prompt_tokens: number;
47
+ total_tokens: number;
48
+ }
22
49
  interface GenerateTextResult {
50
+ finishReason: FinishReason;
23
51
  request: Request;
24
52
  response: Response;
25
53
  text: string;
54
+ usage: GenerateTextResponseUsage;
26
55
  }
27
56
  declare const generateText: (options: GenerateTextOptions) => Promise<GenerateTextResult>;
28
57
 
29
- export { generateText };
58
+ export { type EmbedOptions, type EmbedResponseUsage, type EmbedResult, type GenerateTextOptions, type GenerateTextResult, embed, generateText };
package/dist/index.js CHANGED
@@ -2,23 +2,48 @@ const clean = (record) => Object.fromEntries(Object.entries(record).filter(([, v
2
2
 
3
3
  const base = "http://localhost:11434/v1/";
4
4
 
5
+ const embed = async (options) => {
6
+ const request = new Request(new URL(options.path ?? "embeddings", options.base ?? base), {
7
+ body: JSON.stringify(clean({
8
+ ...options,
9
+ base: void 0,
10
+ headers: void 0,
11
+ path: void 0
12
+ })),
13
+ headers: options.headers,
14
+ method: "POST"
15
+ });
16
+ const response = await fetch(request);
17
+ const json = await response.json();
18
+ return {
19
+ embedding: json.data[0].embedding,
20
+ request,
21
+ response,
22
+ usage: json.usage
23
+ };
24
+ };
25
+
5
26
  const generateText = async (options) => {
6
27
  const request = new Request(new URL(options.path ?? "completions", options.base ?? base), {
7
28
  body: JSON.stringify(clean({
8
29
  stream: false,
9
30
  ...options,
10
31
  base: void 0,
32
+ headers: void 0,
11
33
  path: void 0
12
34
  })),
35
+ headers: options.headers,
13
36
  method: "POST"
14
37
  });
15
38
  const response = await fetch(request);
16
39
  const json = await response.json();
17
40
  return {
41
+ finishReason: json.choices[0].finish_reason,
18
42
  request,
19
43
  response,
20
- text: json.choices[0].text
44
+ text: json.choices[0].text,
45
+ usage: json.usage
21
46
  };
22
47
  };
23
48
 
24
- export { generateText };
49
+ export { embed, generateText };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xsai",
3
- "version": "0.0.2",
3
+ "version": "0.0.4",
4
4
  "type": "module",
5
5
  "author": "藍+85CD",
6
6
  "license": "MIT",
@@ -30,6 +30,7 @@
30
30
  "@importantimport/tsconfig": "^0.1.1",
31
31
  "@types/eslint": "^9.6.1",
32
32
  "@types/node": "^22.9.1",
33
+ "automd": "^0.3.12",
33
34
  "bumpp": "^9.8.1",
34
35
  "eslint": "^9.15.0",
35
36
  "jiti": "^2.4.0",