@apicity/alibaba 0.1.0-alpha.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/LICENSE +21 -0
- package/README.md +316 -0
- package/dist/src/alibaba.d.ts +9 -0
- package/dist/src/alibaba.d.ts.map +1 -0
- package/dist/src/alibaba.js +299 -0
- package/dist/src/alibaba.js.map +1 -0
- package/dist/src/example.d.ts +8 -0
- package/dist/src/example.d.ts.map +1 -0
- package/dist/src/example.js +141 -0
- package/dist/src/example.js.map +1 -0
- package/dist/src/index.d.ts +7 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +5 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/middleware.d.ts +34 -0
- package/dist/src/middleware.d.ts.map +1 -0
- package/dist/src/middleware.js +219 -0
- package/dist/src/middleware.js.map +1 -0
- package/dist/src/sse.d.ts +6 -0
- package/dist/src/sse.d.ts.map +1 -0
- package/dist/src/sse.js +55 -0
- package/dist/src/sse.js.map +1 -0
- package/dist/src/types.d.ts +100 -0
- package/dist/src/types.d.ts.map +1 -0
- package/dist/src/types.js +14 -0
- package/dist/src/types.js.map +1 -0
- package/dist/src/zod.d.ts +3457 -0
- package/dist/src/zod.d.ts.map +1 -0
- package/dist/src/zod.js +520 -0
- package/dist/src/zod.js.map +1 -0
- package/package.json +63 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Justin Tanner
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,316 @@
|
|
|
1
|
+
# @apicity/alibaba
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@apicity/alibaba)
|
|
4
|
+
[](package.json)
|
|
5
|
+
[](tsconfig.json)
|
|
6
|
+
|
|
7
|
+
Alibaba Cloud Model Studio provider for chat completions, image generation, and streaming.
|
|
8
|
+
|
|
9
|
+
## Installation
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install @apicity/alibaba
|
|
13
|
+
# or
|
|
14
|
+
pnpm add @apicity/alibaba
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import { alibaba as createAlibaba } from "@apicity/alibaba";
|
|
21
|
+
|
|
22
|
+
const alibaba = createAlibaba({ apiKey: process.env.ALIBABA_API_KEY! });
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
## Real-world example: Wan 2.7 image-to-video with async task polling
|
|
26
|
+
|
|
27
|
+
DashScope's `aigc/*` family is async-by-default: every video, image, and
|
|
28
|
+
audio generation endpoint returns immediately with a `task_id` and a
|
|
29
|
+
`task_status` of `PENDING`, and the actual artifact lives behind a
|
|
30
|
+
separate `GET /api/v1/tasks/{taskId}` you poll until it transitions to
|
|
31
|
+
`SUCCEEDED`. The provider hides the `X-DashScope-Async: enable` header
|
|
32
|
+
plumbing but keeps the two-call shape visible because it lets you
|
|
33
|
+
checkpoint the `task_id`, walk away, and resume later from any process.
|
|
34
|
+
The example below mines every `task_id`, timestamp, prompt, and resolution
|
|
35
|
+
from
|
|
36
|
+
[`tests/recordings/alibaba_1329897167/wan-i2v_2196817451/`](../../../tests/recordings/alibaba_1329897167/wan-i2v_2196817451/),
|
|
37
|
+
which is the HAR replayed by
|
|
38
|
+
[`tests/integration/alibaba-wan-i2v.test.ts`](../../../tests/integration/alibaba-wan-i2v.test.ts).
|
|
39
|
+
|
|
40
|
+
```typescript
|
|
41
|
+
import { readFileSync } from "node:fs";
|
|
42
|
+
import { alibaba as createAlibaba, AlibabaError } from "@apicity/alibaba";
|
|
43
|
+
import type {
|
|
44
|
+
AlibabaVideoSynthesisSubmitResponse,
|
|
45
|
+
AlibabaTaskStatusResponse,
|
|
46
|
+
AlibabaTaskStatus,
|
|
47
|
+
} from "@apicity/alibaba";
|
|
48
|
+
|
|
49
|
+
const alibaba = createAlibaba({
|
|
50
|
+
apiKey: process.env.DASHSCOPE_API_KEY!,
|
|
51
|
+
// The SUCCEEDED-path round-trip in the recording is ~47s wall-clock;
|
|
52
|
+
// bump the per-request timeout above the default 30s so the submit
|
|
53
|
+
// call doesn't fight a slow scheduling spike.
|
|
54
|
+
timeout: 60_000,
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
// 1. Inline the source frame as a `data:` URL. DashScope also accepts
|
|
58
|
+
// https:// URLs and `oss://` URIs (the latter only when the request
|
|
59
|
+
// carries `X-DashScope-OssResourceResolve: enable`, which the
|
|
60
|
+
// provider sets automatically on every aigc/* call). Inlining is the
|
|
61
|
+
// zero-infra path — no public bucket, no presigned URL — at the cost
|
|
62
|
+
// of paying the upload bytes once per submit.
|
|
63
|
+
const frame = readFileSync("./cat.jpg");
|
|
64
|
+
const dataUrl = `data:image/jpeg;base64,${frame.toString("base64")}`;
|
|
65
|
+
|
|
66
|
+
// 2. `media[].type: "first_frame"` is the I2V kick-off — Wan animates
|
|
67
|
+
// forward from the still. Other media types in the same array slot
|
|
68
|
+
// drive different conditioning modes: `last_frame` (animate
|
|
69
|
+
// backward), `first_clip` (continue a video), `reference` (style
|
|
70
|
+
// transfer). The Zod schema enforces that `first_frame` cannot
|
|
71
|
+
// coexist with `first_clip` and that exactly one of each type is
|
|
72
|
+
// present — invalid combinations fail at `.schema.safeParse(...)`
|
|
73
|
+
// before a single byte hits the wire.
|
|
74
|
+
//
|
|
75
|
+
// 3. `prompt_extend: true` runs the prompt through DashScope's
|
|
76
|
+
// server-side prompt-enhancement model first, which materially
|
|
77
|
+
// improves motion fidelity on terse prompts like the one below.
|
|
78
|
+
// The enhanced prompt is echoed back in the SUCCEEDED response as
|
|
79
|
+
// `actual_prompt` so you can audit what actually got rendered.
|
|
80
|
+
// `watermark: false` removes the corner badge — silently ignored
|
|
81
|
+
// on tiers that don't permit it.
|
|
82
|
+
const submit: AlibabaVideoSynthesisSubmitResponse =
|
|
83
|
+
await alibaba.post.api.v1.services.aigc.videoGeneration.videoSynthesis({
|
|
84
|
+
model: "wan2.7-i2v",
|
|
85
|
+
input: {
|
|
86
|
+
prompt:
|
|
87
|
+
"The odd-eyed white cat blinks slowly, whiskers twitching, " +
|
|
88
|
+
"then turns its head toward the camera",
|
|
89
|
+
media: [{ type: "first_frame", url: dataUrl }],
|
|
90
|
+
},
|
|
91
|
+
parameters: {
|
|
92
|
+
resolution: "720P",
|
|
93
|
+
duration: 5,
|
|
94
|
+
prompt_extend: true,
|
|
95
|
+
watermark: false,
|
|
96
|
+
},
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
console.log(
|
|
100
|
+
`task=${submit.output.task_id} status=${submit.output.task_status}`,
|
|
101
|
+
);
|
|
102
|
+
// → "task=5a674d6b-6a42-4b07-98bb-147ba79879ea status=PENDING"
|
|
103
|
+
|
|
104
|
+
// 4. Poll until terminal. The status state machine is
|
|
105
|
+
// PENDING → RUNNING → (SUCCEEDED | FAILED | CANCELED), with
|
|
106
|
+
// SUSPENDED as a transient quota-bound retry state. Treat anything
|
|
107
|
+
// not in TERMINAL as "keep polling." A 5–10s interval matches the
|
|
108
|
+
// server-side scheduling cadence — the recorded run did 8 polls
|
|
109
|
+
// over ~47s, so faster polling just burns rate-limit budget without
|
|
110
|
+
// moving the task forward.
|
|
111
|
+
const TERMINAL: ReadonlyArray<AlibabaTaskStatus> = [
|
|
112
|
+
"SUCCEEDED",
|
|
113
|
+
"FAILED",
|
|
114
|
+
"CANCELED",
|
|
115
|
+
];
|
|
116
|
+
let status: AlibabaTaskStatusResponse = await alibaba.get.api.v1.tasks(
|
|
117
|
+
submit.output.task_id,
|
|
118
|
+
);
|
|
119
|
+
while (!TERMINAL.includes(status.output.task_status)) {
|
|
120
|
+
await new Promise((r) => setTimeout(r, 5000));
|
|
121
|
+
status = await alibaba.get.api.v1.tasks(submit.output.task_id);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// 5. The task-status response shape *grows* as the task progresses —
|
|
125
|
+
// `submit_time` and `scheduled_time` appear once it leaves PENDING;
|
|
126
|
+
// `end_time`, `orig_prompt`, `video_url`, and `usage` only land on
|
|
127
|
+
// SUCCEEDED. `code` and `message` populate on FAILED. Always branch
|
|
128
|
+
// on `task_status` before reading the success-only fields, since
|
|
129
|
+
// they're typed `string | undefined`.
|
|
130
|
+
if (status.output.task_status !== "SUCCEEDED") {
|
|
131
|
+
throw new AlibabaError(
|
|
132
|
+
`i2v task ${status.output.task_id} ${status.output.task_status}: ` +
|
|
133
|
+
`${status.output.code ?? "?"}: ${status.output.message ?? "?"}`,
|
|
134
|
+
500,
|
|
135
|
+
status.output,
|
|
136
|
+
status.output.code,
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
console.log(status.output.video_url);
|
|
141
|
+
// → "https://dashscope-a717.oss-accelerate.aliyuncs.com/.../70873660-metadata_user_a54afaea6b53dd4e.mp4?Expires=1776489167&..."
|
|
142
|
+
|
|
143
|
+
const elapsed =
|
|
144
|
+
new Date(status.output.end_time!).getTime() -
|
|
145
|
+
new Date(status.output.submit_time!).getTime();
|
|
146
|
+
console.log(
|
|
147
|
+
`model=wan2.7-i2v ${status.usage!.SR}p×${status.usage!.output_video_duration}s ` +
|
|
148
|
+
`elapsed=${(elapsed / 1000).toFixed(1)}s videos=${status.usage!.video_count}`,
|
|
149
|
+
);
|
|
150
|
+
// → "model=wan2.7-i2v 720p×5s elapsed=47.4s videos=1"
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
**Notes**
|
|
154
|
+
|
|
155
|
+
- The returned `video_url` is a presigned OSS URL with a short
|
|
156
|
+
`Expires=` window (≈1 hour in the recording above) — download or
|
|
157
|
+
re-host it immediately, don't store the URL itself. The bucket is
|
|
158
|
+
hosted on `oss-accelerate.aliyuncs.com`, which fronts an Alibaba CDN
|
|
159
|
+
that resolves close to the caller; no auth header is required for the
|
|
160
|
+
GET.
|
|
161
|
+
- The submit call is *cheap* even when the task later FAILS — billing
|
|
162
|
+
is only charged on SUCCEEDED tasks per `usage.duration` (seconds of
|
|
163
|
+
output video). A failed content-safety screen (`code:
|
|
164
|
+
"DataInspectionFailed"`) on the input frame returns a SUCCEEDED-shape
|
|
165
|
+
HTTP 200 with `task_status: "FAILED"`, not a 4xx — this is why the
|
|
166
|
+
example above always reads `task_status` rather than relying on
|
|
167
|
+
exception flow for content-related rejects.
|
|
168
|
+
- The same `videoSynthesis` endpoint dispatches across the entire Wan
|
|
169
|
+
2.7 family by changing `model`: `wan2.7-i2v` for image→video,
|
|
170
|
+
`wan2.7-t2v` for text→video (drop the `media` array), and
|
|
171
|
+
`wan2.7-videoedit` for video-style transfer (use `media[].type:
|
|
172
|
+
"video"`). The Zod schema enforces the per-model media-type
|
|
173
|
+
combinations — `videoedit` requires a `video` entry, `i2v` requires
|
|
174
|
+
`first_frame` or `first_clip`, etc.
|
|
175
|
+
- For payloads where the input frame exceeds DashScope's 10MB
|
|
176
|
+
embedded-data-URL ceiling, swap the inline `data:` URL for an
|
|
177
|
+
`oss://{key}` URI obtained via `uploadFile(provider, {...})` — the
|
|
178
|
+
exported helper does the `getPolicy` + multipart OSS PostObject
|
|
179
|
+
dance and returns the URI ready to drop into `media[].url`. The
|
|
180
|
+
`X-DashScope-OssResourceResolve` header is set automatically on
|
|
181
|
+
every aigc/* call so the URI resolves server-side.
|
|
182
|
+
- Errors throw `AlibabaError` with `status` and the parsed `body`. The
|
|
183
|
+
native aigc error shape (`{code, message, request_id}`) is surfaced
|
|
184
|
+
in `error.code` — wrap with `withRetry` from `@apicity/alibaba` for
|
|
185
|
+
`429` / `503`, but skip retries on `code === "DataInspectionFailed"`
|
|
186
|
+
/ `"InvalidParameter"` since those are deterministic rejects.
|
|
187
|
+
|
|
188
|
+
## API Reference
|
|
189
|
+
|
|
190
|
+
7 endpoints across 4 groups. Each method mirrors an upstream URL path.
|
|
191
|
+
|
|
192
|
+
### compatibleMode
|
|
193
|
+
|
|
194
|
+
<details>
|
|
195
|
+
<summary><code>GET</code> <b><code>alibaba.compatibleMode.v1.models</code></b></summary>
|
|
196
|
+
|
|
197
|
+
<code>GET https://dashscope.aliyuncs.com/compatible-mode/v1/models</code>
|
|
198
|
+
|
|
199
|
+
[Upstream docs ↗](https://help.aliyun.com/zh/model-studio)
|
|
200
|
+
|
|
201
|
+
```typescript
|
|
202
|
+
const res = await alibaba.compatibleMode.v1.models({ /* ... */ });
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
Source: [`packages/provider/alibaba/src/alibaba.ts`](src/alibaba.ts)
|
|
206
|
+
|
|
207
|
+
</details>
|
|
208
|
+
|
|
209
|
+
<details>
|
|
210
|
+
<summary><code>POST</code> <b><code>alibaba.compatibleMode.v1.chat.completions</code></b></summary>
|
|
211
|
+
|
|
212
|
+
<code>POST https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions</code>
|
|
213
|
+
|
|
214
|
+
[Upstream docs ↗](https://help.aliyun.com/zh/model-studio)
|
|
215
|
+
|
|
216
|
+
```typescript
|
|
217
|
+
const res = await alibaba.compatibleMode.v1.chat.completions({ /* ... */ });
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
Source: [`packages/provider/alibaba/src/alibaba.ts`](src/alibaba.ts)
|
|
221
|
+
|
|
222
|
+
</details>
|
|
223
|
+
|
|
224
|
+
### services
|
|
225
|
+
|
|
226
|
+
<details>
|
|
227
|
+
<summary><code>POST</code> <b><code>alibaba.api.v1.services.aigc.imageGeneration.generation</code></b></summary>
|
|
228
|
+
|
|
229
|
+
<code>POST https://dashscope.aliyuncs.com/api/v1/services/aigc/image-generation/generation</code>
|
|
230
|
+
|
|
231
|
+
```typescript
|
|
232
|
+
const res = await alibaba.api.v1.services.aigc.imageGeneration.generation({ /* ... */ });
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
Source: [`packages/provider/alibaba/src/alibaba.ts`](src/alibaba.ts)
|
|
236
|
+
|
|
237
|
+
</details>
|
|
238
|
+
|
|
239
|
+
<details>
|
|
240
|
+
<summary><code>POST</code> <b><code>alibaba.api.v1.services.aigc.multimodalGeneration.generation</code></b></summary>
|
|
241
|
+
|
|
242
|
+
<code>POST https://dashscope.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation</code>
|
|
243
|
+
|
|
244
|
+
[Upstream docs ↗](https://www.alibabacloud.com/help/en/model-studio/qwen-image-edit)
|
|
245
|
+
|
|
246
|
+
```typescript
|
|
247
|
+
const res = await alibaba.api.v1.services.aigc.multimodalGeneration.generation({ /* ... */ });
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
Source: [`packages/provider/alibaba/src/alibaba.ts`](src/alibaba.ts)
|
|
251
|
+
|
|
252
|
+
</details>
|
|
253
|
+
|
|
254
|
+
<details>
|
|
255
|
+
<summary><code>POST</code> <b><code>alibaba.api.v1.services.aigc.videoGeneration.videoSynthesis</code></b></summary>
|
|
256
|
+
|
|
257
|
+
<code>POST https://dashscope.aliyuncs.com/api/v1/services/aigc/video-generation/video-synthesis</code>
|
|
258
|
+
|
|
259
|
+
[Upstream docs ↗](https://help.aliyun.com/zh/model-studio)
|
|
260
|
+
|
|
261
|
+
```typescript
|
|
262
|
+
const res = await alibaba.api.v1.services.aigc.videoGeneration.videoSynthesis({ /* ... */ });
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
Source: [`packages/provider/alibaba/src/alibaba.ts`](src/alibaba.ts)
|
|
266
|
+
|
|
267
|
+
</details>
|
|
268
|
+
|
|
269
|
+
### tasks
|
|
270
|
+
|
|
271
|
+
<details>
|
|
272
|
+
<summary><code>GET</code> <b><code>alibaba.api.v1.tasks</code></b></summary>
|
|
273
|
+
|
|
274
|
+
<code>GET https://dashscope.aliyuncs.com/api/v1/tasks/{taskId}</code>
|
|
275
|
+
|
|
276
|
+
[Upstream docs ↗](https://help.aliyun.com/zh/model-studio)
|
|
277
|
+
|
|
278
|
+
```typescript
|
|
279
|
+
const res = await alibaba.api.v1.tasks({ /* ... */ });
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
Source: [`packages/provider/alibaba/src/alibaba.ts`](src/alibaba.ts)
|
|
283
|
+
|
|
284
|
+
</details>
|
|
285
|
+
|
|
286
|
+
### uploads
|
|
287
|
+
|
|
288
|
+
<details>
|
|
289
|
+
<summary><code>GET</code> <b><code>alibaba.api.v1.uploads</code></b></summary>
|
|
290
|
+
|
|
291
|
+
<code>GET https://dashscope.aliyuncs.com/api/v1/uploads</code>
|
|
292
|
+
|
|
293
|
+
[Upstream docs ↗](https://help.aliyun.com/zh/model-studio)
|
|
294
|
+
|
|
295
|
+
```typescript
|
|
296
|
+
const res = await alibaba.api.v1.uploads({ /* ... */ });
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
Source: [`packages/provider/alibaba/src/alibaba.ts`](src/alibaba.ts)
|
|
300
|
+
|
|
301
|
+
</details>
|
|
302
|
+
|
|
303
|
+
## Middleware
|
|
304
|
+
|
|
305
|
+
```typescript
|
|
306
|
+
import { alibaba as createAlibaba, withRetry } from "@apicity/alibaba";
|
|
307
|
+
|
|
308
|
+
const alibaba = createAlibaba({ apiKey: process.env.ALIBABA_API_KEY! });
|
|
309
|
+
const models = withRetry(alibaba.get.v1.models, { retries: 3 });
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
Part of the [apicity](https://github.com/justintanner/apicity) monorepo.
|
|
313
|
+
|
|
314
|
+
## License
|
|
315
|
+
|
|
316
|
+
MIT — see [LICENSE](LICENSE).
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { AlibabaOptions, AlibabaProvider } from "./types";
|
|
2
|
+
export declare function alibaba(opts: AlibabaOptions): AlibabaProvider;
|
|
3
|
+
export declare function uploadFile(provider: AlibabaProvider, args: {
|
|
4
|
+
model: string;
|
|
5
|
+
data: Uint8Array | Buffer;
|
|
6
|
+
filename: string;
|
|
7
|
+
contentType: string;
|
|
8
|
+
}): Promise<string>;
|
|
9
|
+
//# sourceMappingURL=alibaba.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alibaba.d.ts","sourceRoot":"","sources":["../../src/alibaba.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EAKd,eAAe,EAWhB,MAAM,SAAS,CAAC;AAUjB,wBAAgB,OAAO,CAAC,IAAI,EAAE,cAAc,GAAG,eAAe,CA2X7D;AAMD,wBAAsB,UAAU,CAC9B,QAAQ,EAAE,eAAe,EACzB,IAAI,EAAE;IACJ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,UAAU,GAAG,MAAM,CAAC;IAC1B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;CACrB,GACA,OAAO,CAAC,MAAM,CAAC,CAwCjB"}
|
|
@@ -0,0 +1,299 @@
|
|
|
1
|
+
import { AlibabaError, } from "./types.js";
|
|
2
|
+
import { AlibabaChatRequestSchema, AlibabaVideoSynthesisRequestSchema, AlibabaImageGenerationRequestSchema, AlibabaMultimodalGenerationRequestSchema, } from "./zod.js";
|
|
3
|
+
import { sseToIterable } from "./sse.js";
|
|
4
|
+
import { attachExamples } from "./example.js";
|
|
5
|
+
export function alibaba(opts) {
|
|
6
|
+
const baseURL = opts.baseURL ?? "https://dashscope.aliyuncs.com/compatible-mode/v1";
|
|
7
|
+
const nativeBaseURL = (() => {
|
|
8
|
+
const u = new URL(baseURL);
|
|
9
|
+
return `${u.origin}/api/v1`;
|
|
10
|
+
})();
|
|
11
|
+
const doFetch = opts.fetch ?? fetch;
|
|
12
|
+
const timeout = opts.timeout ?? 30000;
|
|
13
|
+
function attachAbortHandler(signal, controller) {
|
|
14
|
+
if (signal.aborted) {
|
|
15
|
+
controller.abort();
|
|
16
|
+
}
|
|
17
|
+
else {
|
|
18
|
+
signal.addEventListener("abort", () => controller.abort(), {
|
|
19
|
+
once: true,
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
// DashScope returns either OpenAI-compat `{error: {message}}` (compatible-mode
|
|
24
|
+
// endpoints) or the native shape `{code, message, request_id}` (aigc/*
|
|
25
|
+
// endpoints). Surface whichever the server actually returned so callers see
|
|
26
|
+
// the real reason (e.g. `DataInspectionFailed`) instead of a bare status.
|
|
27
|
+
function formatErrorMessage(status, body) {
|
|
28
|
+
if (typeof body === "object" && body !== null) {
|
|
29
|
+
if ("error" in body) {
|
|
30
|
+
const err = body.error;
|
|
31
|
+
if (err?.message)
|
|
32
|
+
return `Alibaba API error ${status}: ${err.message}`;
|
|
33
|
+
}
|
|
34
|
+
const native = body;
|
|
35
|
+
if (native.code && native.message) {
|
|
36
|
+
return `Alibaba API error ${status}: ${native.code}: ${native.message}`;
|
|
37
|
+
}
|
|
38
|
+
if (native.message)
|
|
39
|
+
return `Alibaba API error ${status}: ${native.message}`;
|
|
40
|
+
}
|
|
41
|
+
return `Alibaba API error: ${status}`;
|
|
42
|
+
}
|
|
43
|
+
async function makeRequest(path, body, signal, options = {}) {
|
|
44
|
+
const controller = new AbortController();
|
|
45
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
46
|
+
if (signal) {
|
|
47
|
+
attachAbortHandler(signal, controller);
|
|
48
|
+
}
|
|
49
|
+
try {
|
|
50
|
+
const res = await doFetch(`${options.baseOverride ?? baseURL}${path}`, {
|
|
51
|
+
method: "POST",
|
|
52
|
+
headers: {
|
|
53
|
+
Authorization: `Bearer ${opts.apiKey}`,
|
|
54
|
+
"Content-Type": "application/json",
|
|
55
|
+
...(options.extraHeaders ?? {}),
|
|
56
|
+
},
|
|
57
|
+
body: JSON.stringify(body),
|
|
58
|
+
signal: controller.signal,
|
|
59
|
+
});
|
|
60
|
+
clearTimeout(timeoutId);
|
|
61
|
+
if (!res.ok) {
|
|
62
|
+
let resBody = null;
|
|
63
|
+
try {
|
|
64
|
+
resBody = await res.json();
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
// ignore parse errors
|
|
68
|
+
}
|
|
69
|
+
throw new AlibabaError(formatErrorMessage(res.status, resBody), res.status, resBody);
|
|
70
|
+
}
|
|
71
|
+
return (await res.json());
|
|
72
|
+
}
|
|
73
|
+
catch (error) {
|
|
74
|
+
clearTimeout(timeoutId);
|
|
75
|
+
if (error instanceof AlibabaError)
|
|
76
|
+
throw error;
|
|
77
|
+
throw new AlibabaError(`Alibaba request failed: ${error}`, 500);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
async function* makeStreamRequest(path, body, signal) {
|
|
81
|
+
const controller = new AbortController();
|
|
82
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
83
|
+
if (signal) {
|
|
84
|
+
attachAbortHandler(signal, controller);
|
|
85
|
+
}
|
|
86
|
+
try {
|
|
87
|
+
const res = await doFetch(`${baseURL}${path}`, {
|
|
88
|
+
method: "POST",
|
|
89
|
+
headers: {
|
|
90
|
+
Authorization: `Bearer ${opts.apiKey}`,
|
|
91
|
+
"Content-Type": "application/json",
|
|
92
|
+
},
|
|
93
|
+
body: JSON.stringify(body),
|
|
94
|
+
signal: controller.signal,
|
|
95
|
+
});
|
|
96
|
+
clearTimeout(timeoutId);
|
|
97
|
+
if (!res.ok) {
|
|
98
|
+
let resBody = null;
|
|
99
|
+
try {
|
|
100
|
+
resBody = await res.json();
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
// ignore parse errors
|
|
104
|
+
}
|
|
105
|
+
throw new AlibabaError(formatErrorMessage(res.status, resBody), res.status, resBody);
|
|
106
|
+
}
|
|
107
|
+
for await (const { data } of sseToIterable(res)) {
|
|
108
|
+
if (data === "[DONE]") {
|
|
109
|
+
break;
|
|
110
|
+
}
|
|
111
|
+
try {
|
|
112
|
+
yield JSON.parse(data);
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
// ignore non-JSON lines
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
finally {
|
|
120
|
+
clearTimeout(timeoutId);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
async function makeGetRequest(path, signal, options = {}) {
|
|
124
|
+
const controller = new AbortController();
|
|
125
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
126
|
+
if (signal) {
|
|
127
|
+
attachAbortHandler(signal, controller);
|
|
128
|
+
}
|
|
129
|
+
const qs = options.query
|
|
130
|
+
? `?${new URLSearchParams(options.query).toString()}`
|
|
131
|
+
: "";
|
|
132
|
+
try {
|
|
133
|
+
const res = await doFetch(`${options.baseOverride ?? baseURL}${path}${qs}`, {
|
|
134
|
+
method: "GET",
|
|
135
|
+
headers: {
|
|
136
|
+
Authorization: `Bearer ${opts.apiKey}`,
|
|
137
|
+
},
|
|
138
|
+
signal: controller.signal,
|
|
139
|
+
});
|
|
140
|
+
clearTimeout(timeoutId);
|
|
141
|
+
if (!res.ok) {
|
|
142
|
+
let resBody = null;
|
|
143
|
+
try {
|
|
144
|
+
resBody = await res.json();
|
|
145
|
+
}
|
|
146
|
+
catch {
|
|
147
|
+
// ignore parse errors
|
|
148
|
+
}
|
|
149
|
+
throw new AlibabaError(formatErrorMessage(res.status, resBody), res.status, resBody);
|
|
150
|
+
}
|
|
151
|
+
return (await res.json());
|
|
152
|
+
}
|
|
153
|
+
catch (error) {
|
|
154
|
+
clearTimeout(timeoutId);
|
|
155
|
+
if (error instanceof AlibabaError)
|
|
156
|
+
throw error;
|
|
157
|
+
throw new AlibabaError(`Alibaba request failed: ${error}`, 500);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
// -- Namespace construction -----------------------------------------------
|
|
161
|
+
const postV1 = {
|
|
162
|
+
chat: {
|
|
163
|
+
// sig-ok: dashscope subdomain hoisted by walker
|
|
164
|
+
// POST https://dashscope.aliyuncs.com/compatible-mode/v1/chat/completions
|
|
165
|
+
// Docs: https://help.aliyun.com/zh/model-studio
|
|
166
|
+
completions: Object.assign(async (req, signal) => {
|
|
167
|
+
return makeRequest("/chat/completions", req, signal);
|
|
168
|
+
}, {
|
|
169
|
+
schema: AlibabaChatRequestSchema,
|
|
170
|
+
}),
|
|
171
|
+
},
|
|
172
|
+
};
|
|
173
|
+
const postStreamV1 = {
|
|
174
|
+
chat: {
|
|
175
|
+
completions: Object.assign((req, signal) => {
|
|
176
|
+
return makeStreamRequest("/chat/completions", { ...req, stream: true }, signal);
|
|
177
|
+
}, {
|
|
178
|
+
schema: AlibabaChatRequestSchema,
|
|
179
|
+
}),
|
|
180
|
+
},
|
|
181
|
+
};
|
|
182
|
+
const getV1 = {
|
|
183
|
+
// sig-ok: dashscope subdomain hoisted by walker
|
|
184
|
+
// GET https://dashscope.aliyuncs.com/compatible-mode/v1/models
|
|
185
|
+
// Docs: https://help.aliyun.com/zh/model-studio
|
|
186
|
+
models: async (signal) => {
|
|
187
|
+
return makeGetRequest("/models", signal);
|
|
188
|
+
},
|
|
189
|
+
};
|
|
190
|
+
const postApiV1 = {
|
|
191
|
+
services: {
|
|
192
|
+
aigc: {
|
|
193
|
+
videoGeneration: {
|
|
194
|
+
// sig-ok: dashscope subdomain hoisted by walker
|
|
195
|
+
// POST https://dashscope.aliyuncs.com/api/v1/services/aigc/video-generation/video-synthesis
|
|
196
|
+
// Docs: https://help.aliyun.com/zh/model-studio
|
|
197
|
+
videoSynthesis: Object.assign(async (req, signal) => {
|
|
198
|
+
return makeRequest("/services/aigc/video-generation/video-synthesis", req, signal, {
|
|
199
|
+
baseOverride: nativeBaseURL,
|
|
200
|
+
extraHeaders: {
|
|
201
|
+
"X-DashScope-Async": "enable",
|
|
202
|
+
// Required for any oss:// URI in the body to be resolved
|
|
203
|
+
// server-side. Harmless when no oss:// URIs are present.
|
|
204
|
+
"X-DashScope-OssResourceResolve": "enable",
|
|
205
|
+
},
|
|
206
|
+
});
|
|
207
|
+
}, {
|
|
208
|
+
schema: AlibabaVideoSynthesisRequestSchema,
|
|
209
|
+
}),
|
|
210
|
+
},
|
|
211
|
+
imageGeneration: {
|
|
212
|
+
// sig-ok: dashscope subdomain hoisted by walker
|
|
213
|
+
// POST https://dashscope.aliyuncs.com/api/v1/services/aigc/image-generation/generation
|
|
214
|
+
// Docs: https://www.alibabacloud.com/help/en/model-studio/image-generation
|
|
215
|
+
generation: Object.assign(async (req, signal) => {
|
|
216
|
+
return makeRequest("/services/aigc/image-generation/generation", req, signal, {
|
|
217
|
+
baseOverride: nativeBaseURL,
|
|
218
|
+
extraHeaders: { "X-DashScope-Async": "enable" },
|
|
219
|
+
});
|
|
220
|
+
}, {
|
|
221
|
+
schema: AlibabaImageGenerationRequestSchema,
|
|
222
|
+
}),
|
|
223
|
+
},
|
|
224
|
+
multimodalGeneration: {
|
|
225
|
+
// sig-ok: dashscope subdomain hoisted by walker
|
|
226
|
+
// POST https://dashscope.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation
|
|
227
|
+
// Docs: https://www.alibabacloud.com/help/en/model-studio/qwen-image-edit
|
|
228
|
+
generation: Object.assign(async (req, signal) => {
|
|
229
|
+
return makeRequest("/services/aigc/multimodal-generation/generation", req, signal, { baseOverride: nativeBaseURL });
|
|
230
|
+
}, {
|
|
231
|
+
schema: AlibabaMultimodalGenerationRequestSchema,
|
|
232
|
+
}),
|
|
233
|
+
},
|
|
234
|
+
},
|
|
235
|
+
},
|
|
236
|
+
};
|
|
237
|
+
const getApiV1 = {
|
|
238
|
+
// sig-ok: dashscope subdomain hoisted by walker
|
|
239
|
+
// GET https://dashscope.aliyuncs.com/api/v1/tasks/{taskId}
|
|
240
|
+
// Docs: https://help.aliyun.com/zh/model-studio
|
|
241
|
+
tasks: async (taskId, signal) => {
|
|
242
|
+
return makeGetRequest(`/tasks/${encodeURIComponent(taskId)}`, signal, { baseOverride: nativeBaseURL });
|
|
243
|
+
},
|
|
244
|
+
// sig-ok: dashscope subdomain hoisted by walker
|
|
245
|
+
// GET https://dashscope.aliyuncs.com/api/v1/uploads
|
|
246
|
+
// Docs: https://help.aliyun.com/zh/model-studio
|
|
247
|
+
uploads: async (params, signal) => {
|
|
248
|
+
return makeGetRequest("/uploads", signal, {
|
|
249
|
+
baseOverride: nativeBaseURL,
|
|
250
|
+
query: { action: params.action, model: params.model },
|
|
251
|
+
});
|
|
252
|
+
},
|
|
253
|
+
};
|
|
254
|
+
return attachExamples({
|
|
255
|
+
post: {
|
|
256
|
+
compatibleMode: { v1: postV1 },
|
|
257
|
+
stream: { compatibleMode: { v1: postStreamV1 } },
|
|
258
|
+
api: { v1: postApiV1 },
|
|
259
|
+
},
|
|
260
|
+
get: {
|
|
261
|
+
compatibleMode: { v1: getV1 },
|
|
262
|
+
api: { v1: getApiV1 },
|
|
263
|
+
},
|
|
264
|
+
});
|
|
265
|
+
}
|
|
266
|
+
// Upload a file to DashScope's model-scoped OSS bucket via the
|
|
267
|
+
// `getPolicy` + OSS PostObject flow. Returns an `oss://{key}` URI that the
|
|
268
|
+
// matching aigc/* endpoints (e.g. video-synthesis) can resolve server-side.
|
|
269
|
+
// Falls through whatever fetch implementation `provider` was constructed with.
|
|
270
|
+
export async function uploadFile(provider, args) {
|
|
271
|
+
const policyRes = await provider.get.api.v1.uploads({
|
|
272
|
+
action: "getPolicy",
|
|
273
|
+
model: args.model,
|
|
274
|
+
});
|
|
275
|
+
const p = policyRes.data;
|
|
276
|
+
const uploadDir = p.upload_dir.replace(/^\/+|\/+$/g, "");
|
|
277
|
+
const key = `${uploadDir}/${args.filename}`;
|
|
278
|
+
const form = new FormData();
|
|
279
|
+
form.append("key", key);
|
|
280
|
+
form.append("OSSAccessKeyId", p.oss_access_key_id);
|
|
281
|
+
form.append("policy", p.policy);
|
|
282
|
+
form.append("Signature", p.signature);
|
|
283
|
+
form.append("x-oss-object-acl", p.x_oss_object_acl);
|
|
284
|
+
form.append("x-oss-forbid-overwrite", p.x_oss_forbid_overwrite);
|
|
285
|
+
form.append("Content-Type", args.contentType);
|
|
286
|
+
form.append("success_action_status", "200");
|
|
287
|
+
// `file` MUST be last — OSS PostObject spec.
|
|
288
|
+
form.append("file", new Blob([new Uint8Array(args.data)], { type: args.contentType }), args.filename);
|
|
289
|
+
const endpoint = p.upload_host.startsWith("http")
|
|
290
|
+
? p.upload_host
|
|
291
|
+
: `https://${p.upload_host}`;
|
|
292
|
+
const res = await fetch(endpoint, { method: "POST", body: form });
|
|
293
|
+
if (!res.ok) {
|
|
294
|
+
const body = await res.text().catch(() => "");
|
|
295
|
+
throw new AlibabaError(`OSS PostObject failed: ${res.status} ${res.statusText} ${body}`, res.status, body);
|
|
296
|
+
}
|
|
297
|
+
return `oss://${key}`;
|
|
298
|
+
}
|
|
299
|
+
//# sourceMappingURL=alibaba.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"alibaba.js","sourceRoot":"","sources":["../../src/alibaba.ts"],"names":[],"mappings":"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"}
|