Skip to content

Commit e24422b

Browse files
authored
Merge pull request #122 from FliPPeDround/feat/sdk
feat: support SDK
2 parents 4324da4 + 4483b97 commit e24422b

27 files changed

Lines changed: 1247 additions & 7 deletions

SDK.md

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
# MiniMax SDK
2+
3+
TypeScript SDK for the [MiniMax](https://www.minimaxi.com) AI platform.
4+
5+
## Installation
6+
7+
```bash
8+
npm install mmx-cli
9+
```
10+
11+
## Quick Start
12+
13+
```typescript
14+
import { MiniMaxSDK } from 'mmx-cli/sdk';
15+
16+
const sdk = new MiniMaxSDK({
17+
apiKey: 'sk-xxxxx',
18+
region: 'global', // or 'cn'
19+
});
20+
```
21+
22+
You can also omit `apiKey` if it's already configured via `mmx config set api-key <key>`.
23+
24+
## Modules
25+
26+
### Text
27+
28+
```typescript
29+
const response = await sdk.text.chat({
30+
model: 'MiniMax-M2.7',
31+
messages: [{ role: 'user', content: 'Hello!' }],
32+
max_tokens: 4096,
33+
});
34+
35+
// Streaming
36+
const stream = await sdk.text.chat({
37+
model: 'MiniMax-M2.7',
38+
messages: [{ role: 'user', content: 'Write a poem' }],
39+
stream: true,
40+
});
41+
42+
for await (const event of stream) {
43+
console.log(event.choices[0]?.delta?.content);
44+
}
45+
```
46+
47+
### Image
48+
49+
```typescript
50+
const result = await sdk.image.generate({
51+
model: 'image-01',
52+
prompt: 'A cat in a spacesuit',
53+
width: 1024,
54+
height: 1024,
55+
n: 1,
56+
});
57+
```
58+
59+
### Video
60+
61+
```typescript
62+
// Synchronous — waits for completion
63+
const video = await sdk.video.generate({
64+
model: 'MiniMax-Hailuo-2.3',
65+
prompt: 'Ocean waves at sunset',
66+
});
67+
68+
// Asynchronous — returns task ID immediately
69+
const { taskId } = await sdk.video.generate({
70+
prompt: 'A robot painting',
71+
async: true,
72+
});
73+
74+
const task = await sdk.video.getTask({ taskId });
75+
76+
// Download
77+
const { size, save, downloadUrl } = await sdk.video.download({
78+
fileId: '176844028768320',
79+
outPath: './video.mp4',
80+
});
81+
```
82+
83+
### Speech
84+
85+
```typescript
86+
const speech = await sdk.speech.synthesize({
87+
model: 'speech-2.8-hd',
88+
text: 'Hello, world!',
89+
voice_setting: { voice_id: 'English_expressive_narrator' },
90+
audio_setting: { format: 'mp3', sample_rate: 32000, bitrate: 128000, channel: 1 },
91+
});
92+
93+
// Streaming
94+
const stream = await sdk.speech.synthesize({
95+
text: 'Stream me',
96+
stream: true,
97+
});
98+
99+
for await (const chunk of stream) {
100+
// process audio chunks
101+
}
102+
103+
// List voices
104+
const voices = await sdk.speech.voices();
105+
const englishVoices = await sdk.speech.voices('en');
106+
```
107+
108+
### Music
109+
110+
```typescript
111+
const music = await sdk.music.generate({
112+
model: 'music-2.6',
113+
prompt: 'Upbeat pop song',
114+
lyrics: '[verse] La da dee, sunny day',
115+
output_format: 'hex',
116+
});
117+
118+
// Instrumental
119+
const instrumental = await sdk.music.generate({
120+
prompt: 'Cinematic orchestral',
121+
instrumental: true,
122+
});
123+
124+
// Auto-generate lyrics
125+
const autoLyrics = await sdk.music.generate({
126+
prompt: 'Indie folk, melancholic, rainy night',
127+
lyrics_optimizer: true,
128+
});
129+
130+
// Streaming
131+
const stream = await sdk.music.generate({
132+
prompt: 'Upbeat pop',
133+
lyrics: '[verse] Hello world',
134+
stream: true,
135+
});
136+
137+
for await (const chunk of stream) {
138+
// process audio chunks
139+
}
140+
141+
// Structured prompt
142+
const structured = await sdk.music.generate({
143+
prompt: 'A beautiful song',
144+
vocals: 'warm male baritone',
145+
genre: 'jazz',
146+
mood: 'relaxing',
147+
instruments: 'piano, saxophone',
148+
bpm: 120,
149+
key: 'C major',
150+
});
151+
```
152+
153+
### Vision
154+
155+
```typescript
156+
const result = await sdk.vision.describe({
157+
image: 'https://example.com/photo.jpg',
158+
prompt: 'What breed is this dog?',
159+
});
160+
161+
console.log(result.content);
162+
```
163+
164+
### Search
165+
166+
```typescript
167+
const results = await sdk.search.query('MiniMax AI latest news');
168+
169+
for (const item of results.organic) {
170+
console.log(item.title, item.link, item.snippet);
171+
}
172+
```
173+
174+
### Quota
175+
176+
```typescript
177+
const quota = await sdk.quota.info();
178+
console.log(quota);
179+
```
180+
181+
## Custom Base URL
182+
183+
```typescript
184+
const sdk = new MiniMaxSDK({
185+
apiKey: 'sk-xxxxx',
186+
baseUrl: 'https://api.minimax.io',
187+
});
188+
```

build.ts

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,10 @@
11
import { readFileSync, writeFileSync } from 'fs';
2+
import dts from 'bun-plugin-dts';
23

34
const pkg = JSON.parse(readFileSync('package.json', 'utf-8'));
45
const VERSION = process.env.VERSION ?? pkg.version;
56
const OUT = 'dist/mmx.mjs';
7+
const SDK_OUT = 'dist/sdk.mjs';
68
const DEV_BUILD = process.argv.includes('--dev');
79

810
await Bun.build({
@@ -19,3 +21,16 @@ writeFileSync(OUT, Buffer.concat([Buffer.from('#!/usr/bin/env node\n'), content]
1921

2022
const size = (content.length / 1024).toFixed(0);
2123
console.log(`dist/mmx.mjs ${size}KB`);
24+
25+
await Bun.build({
26+
entrypoints: ['src/sdk/index.ts'],
27+
outdir: 'dist',
28+
naming: 'sdk.mjs',
29+
target: 'node',
30+
minify: false,
31+
plugins: [dts()],
32+
});
33+
34+
const sdkContent = readFileSync(SDK_OUT);
35+
const sdkSize = (sdkContent.length / 1024).toFixed(0);
36+
console.log(`dist/sdk.mjs ${sdkSize}KB`);

bun.lock

Lines changed: 40 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,17 @@
1010
"mmx": "dist/mmx.mjs"
1111
},
1212
"files": [
13-
"dist/mmx.mjs"
13+
"dist/mmx.mjs",
14+
"dist/sdk.mjs",
15+
"dist/index.d.ts"
1416
],
17+
"exports": {
18+
"./sdk": {
19+
"import": "./dist/sdk.mjs",
20+
"types": "./dist/index.d.ts"
21+
},
22+
"./package.json": "./package.json"
23+
},
1524
"scripts": {
1625
"dev": "bun run src/main.ts",
1726
"build": "bun run build.ts",
@@ -23,7 +32,9 @@
2332
"test:watch": "bun test --watch"
2433
},
2534
"dependencies": {
26-
"@clack/prompts": "^0.7.0"
35+
"@clack/prompts": "^0.7.0",
36+
"bun-plugin-dts": "^0.4.0",
37+
"es-toolkit": "^1.46.1"
2738
},
2839
"devDependencies": {
2940
"@eslint/js": "^9.0.0",

src/commands/speech/voices.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ function extractLanguage(voiceId: string): string {
1313
return match ? match[1] : voiceId;
1414
}
1515

16-
function filterByLanguage(voices: SystemVoiceInfo[], language: string): SystemVoiceInfo[] {
16+
export function filterByLanguage(voices: SystemVoiceInfo[], language: string): SystemVoiceInfo[] {
1717
const lang = language.toLowerCase();
1818
return voices.filter(v => {
1919
const voiceLang = extractLanguage(v.voice_id).toLowerCase();

src/commands/vision/describe.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ const MIME_TYPES: Record<string, string> = {
2424

2525
const MAX_IMAGE_SIZE_BYTES = 50 * 1024 * 1024; // 50 MB limit
2626

27-
async function toDataUri(image: string): Promise<string> {
27+
export async function toDataUri(image: string): Promise<string> {
2828
if (image.startsWith('data:')) return image;
2929

3030
if (image.startsWith('http://') || image.startsWith('https://')) {

src/errors/base.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,3 +21,15 @@ export class CLIError extends Error {
2121
};
2222
}
2323
}
24+
25+
export class SDKError extends CLIError {
26+
readonly exitCode: ExitCode;
27+
readonly hint?: string;
28+
29+
constructor(message: string, exitCode: ExitCode = ExitCode.GENERAL, hint?: string) {
30+
super(message);
31+
this.name = 'SDKError';
32+
this.exitCode = exitCode;
33+
this.hint = hint;
34+
}
35+
}

0 commit comments

Comments
 (0)