@mlx-node/lm 0.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.
@@ -0,0 +1,22 @@
1
+ /**
2
+ * @mlx-node/lm - High-level inference API for MLX models
3
+ *
4
+ * This package provides everything needed for model loading and inference,
5
+ * aligned with Python's mlx-lm library.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * import { Qwen3Model, ModelLoader, QWEN3_CONFIGS } from '@mlx-node/lm';
10
+ *
11
+ * const model = await ModelLoader.loadPretrained('./models/qwen3-0.6b');
12
+ * const result = await model.generate([{ role: 'user', content: 'Hello!' }]);
13
+ * ```
14
+ */
15
+ export { Qwen3Model, Qwen3Tokenizer } from '@mlx-node/core';
16
+ export type { DType } from '@mlx-node/core';
17
+ export type { SamplingConfig, BatchGenerationResult } from '@mlx-node/core';
18
+ export type { ToolCallResult, ChatResult, ChatConfig, ChatMessage } from '@mlx-node/core';
19
+ export { type Qwen3Config, QWEN3_CONFIGS, type GenerationResult, type GenerationConfig, getQwen3Config, } from './models/qwen3-configs';
20
+ export { ModelLoader } from './models/model-loader';
21
+ export * from './tools';
22
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAGH,OAAO,EAAE,UAAU,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AAK5D,YAAY,EAAE,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAC5C,YAAY,EAAE,cAAc,EAAE,qBAAqB,EAAE,MAAM,gBAAgB,CAAC;AAG5E,YAAY,EAAE,cAAc,EAAE,UAAU,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAG1F,OAAO,EACL,KAAK,WAAW,EAChB,aAAa,EACb,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,cAAc,GACf,MAAM,wBAAwB,CAAC;AAEhC,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAGpD,cAAc,SAAS,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,21 @@
1
+ /**
2
+ * @mlx-node/lm - High-level inference API for MLX models
3
+ *
4
+ * This package provides everything needed for model loading and inference,
5
+ * aligned with Python's mlx-lm library.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * import { Qwen3Model, ModelLoader, QWEN3_CONFIGS } from '@mlx-node/lm';
10
+ *
11
+ * const model = await ModelLoader.loadPretrained('./models/qwen3-0.6b');
12
+ * const result = await model.generate([{ role: 'user', content: 'Hello!' }]);
13
+ * ```
14
+ */
15
+ // Model classes (for inference)
16
+ export { Qwen3Model, Qwen3Tokenizer } from '@mlx-node/core';
17
+ // Model utilities (TypeScript-only)
18
+ export { QWEN3_CONFIGS, getQwen3Config, } from './models/qwen3-configs';
19
+ export { ModelLoader } from './models/model-loader';
20
+ // Tool calling utilities
21
+ export * from './tools';
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Model loader utilities for Qwen3 models
3
+ *
4
+ * Handles loading pretrained weights from MLX format or converting from HuggingFace.
5
+ */
6
+ import { Qwen3Model } from '@mlx-node/core';
7
+ /**
8
+ * Model loader for Qwen3 models
9
+ */
10
+ export declare class ModelLoader {
11
+ /**
12
+ * Load a pretrained Qwen3 model from disk
13
+ *
14
+ * Delegates to Rust implementation for efficient loading without JavaScript memory limits.
15
+ *
16
+ * @param modelPath - Path to the model directory or file
17
+ * @param _deviceMap - Device placement (not used in MLX, kept for compatibility)
18
+ * @returns Loaded model
19
+ */
20
+ static loadPretrained(modelPath: string, _deviceMap?: string): Promise<Qwen3Model>;
21
+ /**
22
+ * Save model configuration and metadata to disk
23
+ *
24
+ * This delegates to the Rust implementation which efficiently handles
25
+ * model saving without running into JavaScript memory/array size limits.
26
+ *
27
+ * Note: This saves configuration and parameter metadata only.
28
+ * For full model weight serialization, use safetensors or binary format.
29
+ */
30
+ static saveModel(model: Qwen3Model, savePath: string): Promise<void>;
31
+ }
32
+ //# sourceMappingURL=model-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"model-loader.d.ts","sourceRoot":"","sources":["../../src/models/model-loader.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAE5C;;GAEG;AACH,qBAAa,WAAW;IACtB;;;;;;;;OAQG;WACU,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,GAAE,MAAe,GAAG,OAAO,CAAC,UAAU,CAAC;IAKhG;;;;;;;;OAQG;IACH,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAIrE"}
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Model loader utilities for Qwen3 models
3
+ *
4
+ * Handles loading pretrained weights from MLX format or converting from HuggingFace.
5
+ */
6
+ import { Qwen3Model } from '@mlx-node/core';
7
+ /**
8
+ * Model loader for Qwen3 models
9
+ */
10
+ export class ModelLoader {
11
+ /**
12
+ * Load a pretrained Qwen3 model from disk
13
+ *
14
+ * Delegates to Rust implementation for efficient loading without JavaScript memory limits.
15
+ *
16
+ * @param modelPath - Path to the model directory or file
17
+ * @param _deviceMap - Device placement (not used in MLX, kept for compatibility)
18
+ * @returns Loaded model
19
+ */
20
+ static async loadPretrained(modelPath, _deviceMap = 'auto') {
21
+ // Delegate to Rust implementation for efficient loading
22
+ return await Qwen3Model.loadPretrained(modelPath);
23
+ }
24
+ /**
25
+ * Save model configuration and metadata to disk
26
+ *
27
+ * This delegates to the Rust implementation which efficiently handles
28
+ * model saving without running into JavaScript memory/array size limits.
29
+ *
30
+ * Note: This saves configuration and parameter metadata only.
31
+ * For full model weight serialization, use safetensors or binary format.
32
+ */
33
+ static saveModel(model, savePath) {
34
+ // Delegate to Rust implementation for efficient saving
35
+ return model.saveModel(savePath);
36
+ }
37
+ }
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Qwen3 Model Configurations and Type Definitions
3
+ *
4
+ * This module provides:
5
+ * - Default configurations for common Qwen3 model sizes
6
+ * - Type re-exports from Rust with enhanced documentation
7
+ * - Helper functions for config management
8
+ */
9
+ import type { Qwen3Config as RustQwen3Config, GenerationConfig as RustGenerationConfig, GenerationResult as RustGenerationResult } from '@mlx-node/core';
10
+ /**
11
+ * Configuration for Qwen3 models
12
+ *
13
+ * All fields are required when creating a model directly.
14
+ * Use QWEN3_CONFIGS for pre-configured model sizes.
15
+ */
16
+ export type Qwen3Config = RustQwen3Config;
17
+ /**
18
+ * Configuration for text generation
19
+ *
20
+ * Controls sampling behavior, temperature, and stopping criteria.
21
+ */
22
+ export type GenerationConfig = RustGenerationConfig;
23
+ /**
24
+ * Result from text generation with detailed metadata
25
+ *
26
+ * Includes generated tokens, log probabilities, finish reason, and token count.
27
+ */
28
+ export type GenerationResult = RustGenerationResult;
29
+ /**
30
+ * Default configurations for common Qwen3 models
31
+ *
32
+ * Includes optimized hyperparameters for:
33
+ * - qwen3-0.6b: Smallest model (1024 hidden size, 28 layers)
34
+ * - qwen3-1.8b: Medium model (1536 hidden size, 28 layers)
35
+ * - qwen3-7b: Large model (3072 hidden size, 32 layers)
36
+ */
37
+ export declare const QWEN3_CONFIGS: {
38
+ [key: string]: Qwen3Config;
39
+ };
40
+ /**
41
+ * Get a Qwen3 configuration by name
42
+ *
43
+ * @param name - Model name (e.g., "qwen3-0.6b", "qwen3-1.8b", "qwen3-7b")
44
+ * @returns Model configuration
45
+ * @throws Error if model name is not recognized
46
+ */
47
+ export declare function getQwen3Config(name: string): Qwen3Config;
48
+ //# sourceMappingURL=qwen3-configs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"qwen3-configs.d.ts","sourceRoot":"","sources":["../../src/models/qwen3-configs.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EACV,WAAW,IAAI,eAAe,EAC9B,gBAAgB,IAAI,oBAAoB,EACxC,gBAAgB,IAAI,oBAAoB,EACzC,MAAM,gBAAgB,CAAC;AAExB;;;;;GAKG;AACH,MAAM,MAAM,WAAW,GAAG,eAAe,CAAC;AAE1C;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG,oBAAoB,CAAC;AAEpD;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG,oBAAoB,CAAC;AAEpD;;;;;;;GAOG;AACH,eAAO,MAAM,aAAa,EAAE;IAAE,CAAC,GAAG,EAAE,MAAM,GAAG,WAAW,CAAA;CAoDvD,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,WAAW,CAMxD"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Qwen3 Model Configurations and Type Definitions
3
+ *
4
+ * This module provides:
5
+ * - Default configurations for common Qwen3 model sizes
6
+ * - Type re-exports from Rust with enhanced documentation
7
+ * - Helper functions for config management
8
+ */
9
+ /**
10
+ * Default configurations for common Qwen3 models
11
+ *
12
+ * Includes optimized hyperparameters for:
13
+ * - qwen3-0.6b: Smallest model (1024 hidden size, 28 layers)
14
+ * - qwen3-1.8b: Medium model (1536 hidden size, 28 layers)
15
+ * - qwen3-7b: Large model (3072 hidden size, 32 layers)
16
+ */
17
+ export const QWEN3_CONFIGS = {
18
+ 'qwen3-0.6b': {
19
+ vocabSize: 151936,
20
+ hiddenSize: 1024,
21
+ numLayers: 28,
22
+ numHeads: 16,
23
+ numKvHeads: 8, // GQA with 2:1 ratio
24
+ headDim: 64, // hiddenSize / numHeads = 1024 / 16 = 64
25
+ intermediateSize: 3072,
26
+ rmsNormEps: 1e-6,
27
+ ropeTheta: 1000000.0,
28
+ maxPositionEmbeddings: 40960,
29
+ useQkNorm: true, // Qwen3 always uses QK normalization (core feature)
30
+ tieWordEmbeddings: true,
31
+ padTokenId: 151643,
32
+ eosTokenId: 151645,
33
+ bosTokenId: 151643,
34
+ },
35
+ 'qwen3-1.8b': {
36
+ vocabSize: 151936,
37
+ hiddenSize: 1536,
38
+ numLayers: 28,
39
+ numHeads: 12,
40
+ numKvHeads: 2, // GQA with 6:1 ratio
41
+ headDim: 128, // hiddenSize / numHeads = 1536 / 12 = 128
42
+ intermediateSize: 8960,
43
+ rmsNormEps: 1e-6,
44
+ ropeTheta: 1000000.0,
45
+ maxPositionEmbeddings: 131072,
46
+ useQkNorm: true, // Qwen3 always uses QK normalization (core feature)
47
+ tieWordEmbeddings: false,
48
+ padTokenId: 151643,
49
+ eosTokenId: 151645,
50
+ bosTokenId: 151643,
51
+ },
52
+ 'qwen3-7b': {
53
+ vocabSize: 151936,
54
+ hiddenSize: 3072,
55
+ numLayers: 32,
56
+ numHeads: 24,
57
+ numKvHeads: 4, // GQA with 6:1 ratio
58
+ headDim: 128, // hiddenSize / numHeads = 3072 / 24 = 128
59
+ intermediateSize: 18944,
60
+ rmsNormEps: 1e-6,
61
+ ropeTheta: 1000000.0,
62
+ maxPositionEmbeddings: 131072,
63
+ useQkNorm: true, // Qwen3 always uses QK normalization (core feature)
64
+ tieWordEmbeddings: false,
65
+ padTokenId: 151643,
66
+ eosTokenId: 151645,
67
+ bosTokenId: 151643,
68
+ },
69
+ };
70
+ /**
71
+ * Get a Qwen3 configuration by name
72
+ *
73
+ * @param name - Model name (e.g., "qwen3-0.6b", "qwen3-1.8b", "qwen3-7b")
74
+ * @returns Model configuration
75
+ * @throws Error if model name is not recognized
76
+ */
77
+ export function getQwen3Config(name) {
78
+ const config = QWEN3_CONFIGS[name];
79
+ if (!config) {
80
+ throw new Error(`Unknown model configuration: ${name}. Available models: ${Object.keys(QWEN3_CONFIGS).join(', ')}`);
81
+ }
82
+ return config;
83
+ }
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Tool calling utilities for Qwen3
3
+ *
4
+ * Provides types and helpers for working with tool/function calling in the chat() API.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { createToolDefinition, formatToolResponse } from '@mlx-node/lm';
9
+ *
10
+ * const weatherTool = createToolDefinition(
11
+ * 'get_weather',
12
+ * 'Get weather for a location',
13
+ * { location: { type: 'string', description: 'City name' } },
14
+ * ['location']
15
+ * );
16
+ *
17
+ * const result = await model.chat(messages, { tools: [weatherTool] });
18
+ *
19
+ * for (const call of result.toolCalls) {
20
+ * if (call.status === 'ok') {
21
+ * const toolResult = await executeMyTool(call.name, call.arguments);
22
+ * // Continue conversation with tool result
23
+ * messages.push({ role: 'user', content: formatToolResponse(toolResult) });
24
+ * }
25
+ * }
26
+ * ```
27
+ *
28
+ * @module tools
29
+ */
30
+ export * from './types';
31
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,cAAc,SAAS,CAAC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Tool calling utilities for Qwen3
3
+ *
4
+ * Provides types and helpers for working with tool/function calling in the chat() API.
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { createToolDefinition, formatToolResponse } from '@mlx-node/lm';
9
+ *
10
+ * const weatherTool = createToolDefinition(
11
+ * 'get_weather',
12
+ * 'Get weather for a location',
13
+ * { location: { type: 'string', description: 'City name' } },
14
+ * ['location']
15
+ * );
16
+ *
17
+ * const result = await model.chat(messages, { tools: [weatherTool] });
18
+ *
19
+ * for (const call of result.toolCalls) {
20
+ * if (call.status === 'ok') {
21
+ * const toolResult = await executeMyTool(call.name, call.arguments);
22
+ * // Continue conversation with tool result
23
+ * messages.push({ role: 'user', content: formatToolResponse(toolResult) });
24
+ * }
25
+ * }
26
+ * ```
27
+ *
28
+ * @module tools
29
+ */
30
+ export * from './types';
@@ -0,0 +1,206 @@
1
+ /**
2
+ * OpenAI-compatible tool calling types for Qwen3
3
+ *
4
+ * These types match the OpenAI function calling API format and can be used
5
+ * with applyChatTemplate() when tools are provided.
6
+ *
7
+ * @remarks
8
+ * **Important**: Due to NAPI-RS limitations with recursive generic types,
9
+ * `FunctionParameters.properties` must be passed as a JSON string to the Rust layer.
10
+ * Use the {@link createToolDefinition} helper to automatically handle this conversion.
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * // Recommended: Use the helper function
15
+ * const tool = createToolDefinition('get_weather', 'Get weather info', {
16
+ * location: { type: 'string', description: 'City name' },
17
+ * units: { type: 'string', enum: ['celsius', 'fahrenheit'] }
18
+ * }, ['location']);
19
+ *
20
+ * // Manual approach (if needed)
21
+ * const manualTool: ToolDefinition = {
22
+ * type: 'function',
23
+ * function: {
24
+ * name: 'get_weather',
25
+ * parameters: {
26
+ * type: 'object',
27
+ * properties: JSON.stringify({ location: { type: 'string' } }),
28
+ * required: ['location']
29
+ * }
30
+ * }
31
+ * };
32
+ * ```
33
+ */
34
+ /**
35
+ * Tool type - currently only "function" is supported
36
+ */
37
+ export type ToolType = 'function';
38
+ /**
39
+ * Function parameter property definition (JSON Schema subset)
40
+ *
41
+ * This type is used for the developer-friendly API in {@link createToolDefinition}.
42
+ * It represents the structure of JSON Schema properties.
43
+ */
44
+ export interface FunctionParameterProperty {
45
+ type: 'string' | 'number' | 'boolean' | 'integer' | 'array' | 'object';
46
+ description?: string;
47
+ enum?: string[];
48
+ items?: FunctionParameterProperty;
49
+ properties?: Record<string, FunctionParameterProperty>;
50
+ required?: string[];
51
+ }
52
+ /**
53
+ * Function parameters schema (JSON Schema subset)
54
+ *
55
+ * @remarks
56
+ * **NAPI Limitation**: The `properties` field must be a JSON string, not an object.
57
+ * This is because NAPI-RS cannot expose recursive generic types like
58
+ * `Record<string, FunctionParameterProperty>` directly to Rust.
59
+ *
60
+ * Use {@link createToolDefinition} to avoid manual JSON.stringify() calls.
61
+ */
62
+ export interface FunctionParameters {
63
+ /** Type of the parameters object (always "object") */
64
+ type: 'object';
65
+ /**
66
+ * JSON string of property definitions.
67
+ *
68
+ * @remarks
69
+ * Must be a JSON-stringified object, e.g.: `JSON.stringify({ name: { type: 'string' } })`
70
+ * Use {@link createToolDefinition} helper to avoid manual stringification.
71
+ */
72
+ properties?: string;
73
+ /** List of required parameter names */
74
+ required?: string[];
75
+ }
76
+ /**
77
+ * Function definition for tool calling
78
+ */
79
+ export interface FunctionDefinition {
80
+ /** Name of the function */
81
+ name: string;
82
+ /** Description of what the function does */
83
+ description?: string;
84
+ /** JSON Schema for the function parameters */
85
+ parameters?: FunctionParameters;
86
+ }
87
+ /**
88
+ * OpenAI-compatible tool definition
89
+ */
90
+ export interface ToolDefinition {
91
+ /** Tool type (currently only "function" is supported) */
92
+ type: ToolType;
93
+ /** Function definition */
94
+ function: FunctionDefinition;
95
+ }
96
+ /**
97
+ * Tool call made by an assistant
98
+ */
99
+ export interface ToolCall {
100
+ /** Optional unique identifier for the tool call */
101
+ id?: string;
102
+ /** Name of the tool/function to call */
103
+ name: string;
104
+ /** JSON string of arguments to pass to the tool */
105
+ arguments: string;
106
+ }
107
+ /**
108
+ * Chat message roles
109
+ */
110
+ export type ChatRole = 'system' | 'user' | 'assistant' | 'tool';
111
+ /**
112
+ * Chat message with tool calling support
113
+ *
114
+ * This extends the basic ChatMessage to support tool calls and responses.
115
+ */
116
+ export interface ChatMessageWithTools {
117
+ /** Message role */
118
+ role: ChatRole;
119
+ /** Message content */
120
+ content: string;
121
+ /** Tool calls made by the assistant (for assistant messages) */
122
+ toolCalls?: ToolCall[];
123
+ /** Tool call ID this message is responding to (for tool messages) */
124
+ toolCallId?: string;
125
+ /** Reasoning content for thinking mode (used with <think> tags) */
126
+ reasoningContent?: string;
127
+ }
128
+ /**
129
+ * Options for applying chat template with tools
130
+ */
131
+ export interface ApplyChatTemplateOptions {
132
+ /** Whether to add generation prompt at end (default: true) */
133
+ addGenerationPrompt?: boolean;
134
+ /** Array of tool definitions for function calling */
135
+ tools?: ToolDefinition[];
136
+ /**
137
+ * Control thinking mode behavior.
138
+ *
139
+ * @remarks
140
+ * **Counter-intuitive semantics** (from Qwen3's Jinja2 template):
141
+ * - `undefined` or `true`: Model thinks naturally (no tags added)
142
+ * - `false`: Adds empty `<think>\n\n</think>\n\n` tags to **disable** thinking
143
+ *
144
+ * The default is `false` for tool use, which disables thinking to avoid
145
+ * verbose reasoning during tool calls.
146
+ *
147
+ * @example
148
+ * ```typescript
149
+ * // Allow model to think (default behavior without tools)
150
+ * { enableThinking: true }
151
+ *
152
+ * // Disable thinking (adds empty <think></think> tags)
153
+ * { enableThinking: false }
154
+ * ```
155
+ */
156
+ enableThinking?: boolean;
157
+ }
158
+ /**
159
+ * Create a tool definition with automatic JSON stringification of properties.
160
+ *
161
+ * This helper handles the NAPI-RS limitation where `properties` must be a JSON string.
162
+ *
163
+ * @param name - The function name
164
+ * @param description - Description of what the function does
165
+ * @param properties - Object defining the function parameters (will be JSON stringified)
166
+ * @param required - Array of required parameter names
167
+ * @returns A properly formatted ToolDefinition ready for use with model.chat()
168
+ *
169
+ * @example
170
+ * ```typescript
171
+ * const weatherTool = createToolDefinition(
172
+ * 'get_weather',
173
+ * 'Get weather information for a location',
174
+ * {
175
+ * location: { type: 'string', description: 'City name' },
176
+ * units: { type: 'string', enum: ['celsius', 'fahrenheit'] }
177
+ * },
178
+ * ['location']
179
+ * );
180
+ *
181
+ * const result = await model.chat(messages, { tools: [weatherTool] });
182
+ * ```
183
+ */
184
+ export declare function createToolDefinition(name: string, description?: string, properties?: Record<string, FunctionParameterProperty>, required?: string[]): ToolDefinition;
185
+ /**
186
+ * Format a tool response for inclusion in a message
187
+ *
188
+ * Creates a properly formatted tool response string that can be used
189
+ * in tool messages when continuing a conversation after a tool call.
190
+ *
191
+ * @param content - The response content (will be JSON stringified if object)
192
+ * @returns Formatted tool response string wrapped in `<tool_response>` tags
193
+ *
194
+ * @example
195
+ * ```typescript
196
+ * // After executing a tool call from model.chat()
197
+ * const toolResult = await executeMyTool(call.arguments);
198
+ * const responseMessage = {
199
+ * role: 'user',
200
+ * content: formatToolResponse(toolResult)
201
+ * };
202
+ * const finalResult = await model.chat([...messages, responseMessage]);
203
+ * ```
204
+ */
205
+ export declare function formatToolResponse(content: unknown): string;
206
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/tools/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,UAAU,CAAC;AAElC;;;;;GAKG;AACH,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,GAAG,SAAS,GAAG,OAAO,GAAG,QAAQ,CAAC;IACvE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,CAAC,EAAE,yBAAyB,CAAC;IAClC,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAAC;IACvD,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,kBAAkB;IACjC,sDAAsD;IACtD,IAAI,EAAE,QAAQ,CAAC;IACf;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uCAAuC;IACvC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,2BAA2B;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,4CAA4C;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,8CAA8C;IAC9C,UAAU,CAAC,EAAE,kBAAkB,CAAC;CACjC;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,yDAAyD;IACzD,IAAI,EAAE,QAAQ,CAAC;IACf,0BAA0B;IAC1B,QAAQ,EAAE,kBAAkB,CAAC;CAC9B;AAED;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,mDAAmD;IACnD,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,mDAAmD;IACnD,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,QAAQ,GAAG,MAAM,GAAG,WAAW,GAAG,MAAM,CAAC;AAEhE;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,mBAAmB;IACnB,IAAI,EAAE,QAAQ,CAAC;IACf,sBAAsB;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,gEAAgE;IAChE,SAAS,CAAC,EAAE,QAAQ,EAAE,CAAC;IACvB,qEAAqE;IACrE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,mEAAmE;IACnE,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,8DAA8D;IAC9D,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,qDAAqD;IACrD,KAAK,CAAC,EAAE,cAAc,EAAE,CAAC;IACzB;;;;;;;;;;;;;;;;;;;OAmBG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,WAAW,CAAC,EAAE,MAAM,EACpB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,yBAAyB,CAAC,EACtD,QAAQ,CAAC,EAAE,MAAM,EAAE,GAClB,cAAc,CAehB;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,CAK3D"}
@@ -0,0 +1,101 @@
1
+ /**
2
+ * OpenAI-compatible tool calling types for Qwen3
3
+ *
4
+ * These types match the OpenAI function calling API format and can be used
5
+ * with applyChatTemplate() when tools are provided.
6
+ *
7
+ * @remarks
8
+ * **Important**: Due to NAPI-RS limitations with recursive generic types,
9
+ * `FunctionParameters.properties` must be passed as a JSON string to the Rust layer.
10
+ * Use the {@link createToolDefinition} helper to automatically handle this conversion.
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * // Recommended: Use the helper function
15
+ * const tool = createToolDefinition('get_weather', 'Get weather info', {
16
+ * location: { type: 'string', description: 'City name' },
17
+ * units: { type: 'string', enum: ['celsius', 'fahrenheit'] }
18
+ * }, ['location']);
19
+ *
20
+ * // Manual approach (if needed)
21
+ * const manualTool: ToolDefinition = {
22
+ * type: 'function',
23
+ * function: {
24
+ * name: 'get_weather',
25
+ * parameters: {
26
+ * type: 'object',
27
+ * properties: JSON.stringify({ location: { type: 'string' } }),
28
+ * required: ['location']
29
+ * }
30
+ * }
31
+ * };
32
+ * ```
33
+ */
34
+ /**
35
+ * Create a tool definition with automatic JSON stringification of properties.
36
+ *
37
+ * This helper handles the NAPI-RS limitation where `properties` must be a JSON string.
38
+ *
39
+ * @param name - The function name
40
+ * @param description - Description of what the function does
41
+ * @param properties - Object defining the function parameters (will be JSON stringified)
42
+ * @param required - Array of required parameter names
43
+ * @returns A properly formatted ToolDefinition ready for use with model.chat()
44
+ *
45
+ * @example
46
+ * ```typescript
47
+ * const weatherTool = createToolDefinition(
48
+ * 'get_weather',
49
+ * 'Get weather information for a location',
50
+ * {
51
+ * location: { type: 'string', description: 'City name' },
52
+ * units: { type: 'string', enum: ['celsius', 'fahrenheit'] }
53
+ * },
54
+ * ['location']
55
+ * );
56
+ *
57
+ * const result = await model.chat(messages, { tools: [weatherTool] });
58
+ * ```
59
+ */
60
+ export function createToolDefinition(name, description, properties, required) {
61
+ return {
62
+ type: 'function',
63
+ function: {
64
+ name,
65
+ description,
66
+ parameters: properties
67
+ ? {
68
+ type: 'object',
69
+ properties: JSON.stringify(properties),
70
+ required,
71
+ }
72
+ : undefined,
73
+ },
74
+ };
75
+ }
76
+ /**
77
+ * Format a tool response for inclusion in a message
78
+ *
79
+ * Creates a properly formatted tool response string that can be used
80
+ * in tool messages when continuing a conversation after a tool call.
81
+ *
82
+ * @param content - The response content (will be JSON stringified if object)
83
+ * @returns Formatted tool response string wrapped in `<tool_response>` tags
84
+ *
85
+ * @example
86
+ * ```typescript
87
+ * // After executing a tool call from model.chat()
88
+ * const toolResult = await executeMyTool(call.arguments);
89
+ * const responseMessage = {
90
+ * role: 'user',
91
+ * content: formatToolResponse(toolResult)
92
+ * };
93
+ * const finalResult = await model.chat([...messages, responseMessage]);
94
+ * ```
95
+ */
96
+ export function formatToolResponse(content) {
97
+ const contentStr = typeof content === 'string' ? content : JSON.stringify(content);
98
+ return `<tool_response>
99
+ ${contentStr}
100
+ </tool_response>`;
101
+ }
package/package.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "@mlx-node/lm",
3
+ "version": "0.0.0",
4
+ "files": [
5
+ "dist"
6
+ ],
7
+ "type": "module",
8
+ "main": "./dist/index.js",
9
+ "types": "./dist/index.d.ts",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/index.d.ts",
13
+ "import": "./dist/index.js"
14
+ }
15
+ },
16
+ "scripts": {
17
+ "build": "tsc -b",
18
+ "test": "vite test run"
19
+ },
20
+ "dependencies": {
21
+ "@mlx-node/core": "0.0.0"
22
+ }
23
+ }