@bowenqt/qiniu-ai-sdk 0.1.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 +162 -0
- package/dist/client.d.ts +29 -0
- package/dist/client.d.ts.map +1 -0
- package/dist/client.js +63 -0
- package/dist/client.js.map +1 -0
- package/dist/client.mjs +59 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +26 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +7 -0
- package/dist/lib/request.d.ts +11 -0
- package/dist/lib/request.d.ts.map +1 -0
- package/dist/lib/request.js +57 -0
- package/dist/lib/request.js.map +1 -0
- package/dist/lib/request.mjs +52 -0
- package/dist/lib/types.d.ts +82 -0
- package/dist/lib/types.d.ts.map +1 -0
- package/dist/lib/types.js +4 -0
- package/dist/lib/types.js.map +1 -0
- package/dist/lib/types.mjs +3 -0
- package/dist/modules/chat/index.d.ts +11 -0
- package/dist/modules/chat/index.d.ts.map +1 -0
- package/dist/modules/chat/index.js +22 -0
- package/dist/modules/chat/index.js.map +1 -0
- package/dist/modules/chat/index.mjs +18 -0
- package/dist/modules/image/index.d.ts +51 -0
- package/dist/modules/image/index.d.ts.map +1 -0
- package/dist/modules/image/index.js +70 -0
- package/dist/modules/image/index.js.map +1 -0
- package/dist/modules/image/index.mjs +66 -0
- package/dist/modules/tools/index.d.ts +28 -0
- package/dist/modules/tools/index.d.ts.map +1 -0
- package/dist/modules/tools/index.js +31 -0
- package/dist/modules/tools/index.js.map +1 -0
- package/dist/modules/tools/index.mjs +27 -0
- package/dist/modules/video/index.d.ts +60 -0
- package/dist/modules/video/index.d.ts.map +1 -0
- package/dist/modules/video/index.js +67 -0
- package/dist/modules/video/index.js.map +1 -0
- package/dist/modules/video/index.mjs +63 -0
- package/package.json +61 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026
|
|
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,162 @@
|
|
|
1
|
+
# Qiniu AI SDK
|
|
2
|
+
|
|
3
|
+
TypeScript SDK for Qiniu Cloud AI Token API.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- 🚀 **Chat Completions** - OpenAI-compatible interface
|
|
8
|
+
- 🖼️ **Image Generation** - Kling, Gemini models
|
|
9
|
+
- 🎥 **Video Generation** - Kling, Sora, Veo models
|
|
10
|
+
- 🔍 **Web Search** - Real-time web search API
|
|
11
|
+
- ⏱️ **Built-in Polling** - Async task management with retry and cancellation
|
|
12
|
+
- 📦 **TypeScript First** - Full type definitions included
|
|
13
|
+
|
|
14
|
+
## Requirements
|
|
15
|
+
|
|
16
|
+
- Node.js >= 18.0.0 (uses native `fetch`)
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install @bowenqt/qiniu-ai-sdk
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Quick Start
|
|
25
|
+
|
|
26
|
+
```typescript
|
|
27
|
+
import { QiniuAI } from '@bowenqt/qiniu-ai-sdk';
|
|
28
|
+
|
|
29
|
+
const client = new QiniuAI({
|
|
30
|
+
apiKey: 'Sk-xxxxxxxxxxxxxxxx',
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// Chat completion
|
|
34
|
+
const chat = await client.chat.create({
|
|
35
|
+
model: 'gemini-2.5-flash',
|
|
36
|
+
messages: [{ role: 'user', content: 'Hello!' }],
|
|
37
|
+
});
|
|
38
|
+
console.log(chat.choices[0].message.content);
|
|
39
|
+
|
|
40
|
+
// Image generation (async)
|
|
41
|
+
const imageTask = await client.image.create({
|
|
42
|
+
model: 'kling-v1',
|
|
43
|
+
prompt: 'A futuristic city',
|
|
44
|
+
});
|
|
45
|
+
const imageResult = await client.image.waitForCompletion(imageTask.task_id);
|
|
46
|
+
console.log(imageResult.data?.[0].url);
|
|
47
|
+
|
|
48
|
+
// Video generation (async)
|
|
49
|
+
const videoTask = await client.video.create({
|
|
50
|
+
model: 'kling-video-o1',
|
|
51
|
+
prompt: 'A cat walking on the beach',
|
|
52
|
+
duration: '5',
|
|
53
|
+
});
|
|
54
|
+
const videoResult = await client.video.waitForCompletion(videoTask.id);
|
|
55
|
+
console.log(videoResult.task_result?.videos[0].url);
|
|
56
|
+
|
|
57
|
+
// Web search
|
|
58
|
+
const results = await client.sys.search({
|
|
59
|
+
query: 'Latest AI news',
|
|
60
|
+
max_results: 5,
|
|
61
|
+
});
|
|
62
|
+
console.log(results);
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## API Reference
|
|
66
|
+
|
|
67
|
+
### Client Initialization
|
|
68
|
+
|
|
69
|
+
```typescript
|
|
70
|
+
const client = new QiniuAI({
|
|
71
|
+
apiKey: string; // Required: Your Qiniu AI API key
|
|
72
|
+
baseUrl?: string; // Optional: API base URL (default: https://api.qnaigc.com/v1)
|
|
73
|
+
timeout?: number; // Optional: Request timeout in ms (default: 60000)
|
|
74
|
+
});
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Modules
|
|
78
|
+
|
|
79
|
+
#### `client.chat`
|
|
80
|
+
|
|
81
|
+
- `create(params: ChatCompletionRequest): Promise<ChatCompletionResponse>`
|
|
82
|
+
|
|
83
|
+
#### `client.image`
|
|
84
|
+
|
|
85
|
+
- `create(params: ImageGenerationRequest): Promise<{ task_id: string }>`
|
|
86
|
+
- `get(taskId: string): Promise<ImageTaskResponse>`
|
|
87
|
+
- `waitForCompletion(taskId: string, options?: WaitOptions): Promise<ImageTaskResponse>`
|
|
88
|
+
|
|
89
|
+
#### `client.video`
|
|
90
|
+
|
|
91
|
+
- `create(params: VideoGenerationRequest): Promise<{ id: string }>`
|
|
92
|
+
- `get(id: string): Promise<VideoTaskResponse>`
|
|
93
|
+
- `waitForCompletion(id: string, options?: WaitOptions): Promise<VideoTaskResponse>`
|
|
94
|
+
|
|
95
|
+
#### `client.sys`
|
|
96
|
+
|
|
97
|
+
- `search(params: WebSearchRequest): Promise<WebSearchResult[]>`
|
|
98
|
+
|
|
99
|
+
### Wait Options
|
|
100
|
+
|
|
101
|
+
For `waitForCompletion` methods:
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
interface WaitOptions {
|
|
105
|
+
intervalMs?: number; // Polling interval (default: 2000 for image, 3000 for video)
|
|
106
|
+
timeoutMs?: number; // Max wait time (default: 120000 for image, 600000 for video)
|
|
107
|
+
signal?: AbortSignal; // For cancellation support
|
|
108
|
+
maxRetries?: number; // Max retries for transient errors (default: 3)
|
|
109
|
+
}
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
### Error Handling
|
|
113
|
+
|
|
114
|
+
```typescript
|
|
115
|
+
import { QiniuAI, APIError } from '@bowenqt/qiniu-ai-sdk';
|
|
116
|
+
|
|
117
|
+
try {
|
|
118
|
+
await client.chat.create({ ... });
|
|
119
|
+
} catch (error) {
|
|
120
|
+
if (error instanceof APIError) {
|
|
121
|
+
console.log(error.status); // HTTP status code
|
|
122
|
+
console.log(error.code); // API error code (if any)
|
|
123
|
+
console.log(error.message); // Error message
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Cancellation
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
const controller = new AbortController();
|
|
132
|
+
|
|
133
|
+
// Cancel after 10 seconds
|
|
134
|
+
setTimeout(() => controller.abort(), 10000);
|
|
135
|
+
|
|
136
|
+
try {
|
|
137
|
+
const result = await client.image.waitForCompletion(taskId, {
|
|
138
|
+
signal: controller.signal,
|
|
139
|
+
});
|
|
140
|
+
} catch (error) {
|
|
141
|
+
if (error.message === 'Operation cancelled') {
|
|
142
|
+
console.log('Task was cancelled');
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
## Supported Models
|
|
148
|
+
|
|
149
|
+
### Chat
|
|
150
|
+
- `gemini-2.5-flash`, `gemini-pro`, `deepseek-v3`, `claude-*`, etc.
|
|
151
|
+
|
|
152
|
+
### Image Generation
|
|
153
|
+
- `kling-v1`, `kling-v1-5`, `kling-v2`, `kling-v2-1`
|
|
154
|
+
|
|
155
|
+
### Video Generation
|
|
156
|
+
- `kling-video-o1`, `kling-v2-1`, `kling-v2-5-turbo`
|
|
157
|
+
|
|
158
|
+
For the full list, check [Qiniu Model Plaza](https://www.qiniu.com/ai/models).
|
|
159
|
+
|
|
160
|
+
## License
|
|
161
|
+
|
|
162
|
+
MIT
|
package/dist/client.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { IQiniuClient } from './lib/types';
|
|
2
|
+
import { Chat } from './modules/chat';
|
|
3
|
+
import { Image } from './modules/image';
|
|
4
|
+
import { Video } from './modules/video';
|
|
5
|
+
import { Tools } from './modules/tools';
|
|
6
|
+
export interface QiniuAIOptions {
|
|
7
|
+
apiKey: string;
|
|
8
|
+
baseUrl?: string;
|
|
9
|
+
timeout?: number;
|
|
10
|
+
}
|
|
11
|
+
export declare class QiniuAI implements IQiniuClient {
|
|
12
|
+
chat: Chat;
|
|
13
|
+
image: Image;
|
|
14
|
+
video: Video;
|
|
15
|
+
sys: Tools;
|
|
16
|
+
private apiKey;
|
|
17
|
+
private baseUrl;
|
|
18
|
+
private timeout;
|
|
19
|
+
constructor(options: QiniuAIOptions);
|
|
20
|
+
/**
|
|
21
|
+
* Generic POST request wrapper
|
|
22
|
+
*/
|
|
23
|
+
post<T>(endpoint: string, body: any): Promise<T>;
|
|
24
|
+
/**
|
|
25
|
+
* Generic GET request wrapper
|
|
26
|
+
*/
|
|
27
|
+
get<T>(endpoint: string, params?: Record<string, string>): Promise<T>;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACxC,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AACxC,OAAO,EAAE,KAAK,EAAE,MAAM,iBAAiB,CAAC;AAExC,MAAM,WAAW,cAAc;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,OAAQ,YAAW,YAAY;IACjC,IAAI,EAAE,IAAI,CAAC;IACX,KAAK,EAAE,KAAK,CAAC;IACb,KAAK,EAAE,KAAK,CAAC;IACb,GAAG,EAAE,KAAK,CAAC;IAElB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,OAAO,CAAS;gBAEZ,OAAO,EAAE,cAAc;IAwBnC;;OAEG;IACG,IAAI,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,OAAO,CAAC,CAAC,CAAC;IAYtD;;OAEG;IACG,GAAG,CAAC,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC;CAgB9E"}
|
package/dist/client.js
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.QiniuAI = void 0;
|
|
4
|
+
const request_1 = require("./lib/request");
|
|
5
|
+
const chat_1 = require("./modules/chat");
|
|
6
|
+
const image_1 = require("./modules/image");
|
|
7
|
+
const video_1 = require("./modules/video");
|
|
8
|
+
const tools_1 = require("./modules/tools");
|
|
9
|
+
class QiniuAI {
|
|
10
|
+
constructor(options) {
|
|
11
|
+
// Enhanced validation
|
|
12
|
+
if (!options.apiKey || typeof options.apiKey !== 'string' || !options.apiKey.trim()) {
|
|
13
|
+
throw new Error('API Key is required and must be a non-empty string');
|
|
14
|
+
}
|
|
15
|
+
this.apiKey = options.apiKey.trim();
|
|
16
|
+
// Normalize baseUrl: remove trailing slashes
|
|
17
|
+
let baseUrl = options.baseUrl || 'https://api.qnaigc.com/v1';
|
|
18
|
+
this.baseUrl = baseUrl.replace(/\/+$/, '');
|
|
19
|
+
this.timeout = options.timeout || 60000;
|
|
20
|
+
if (this.timeout <= 0) {
|
|
21
|
+
throw new Error('Timeout must be a positive number');
|
|
22
|
+
}
|
|
23
|
+
// Initialize modules
|
|
24
|
+
this.chat = new chat_1.Chat(this);
|
|
25
|
+
this.image = new image_1.Image(this);
|
|
26
|
+
this.video = new video_1.Video(this);
|
|
27
|
+
this.sys = new tools_1.Tools(this);
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Generic POST request wrapper
|
|
31
|
+
*/
|
|
32
|
+
async post(endpoint, body) {
|
|
33
|
+
const url = `${this.baseUrl}${endpoint}`;
|
|
34
|
+
return (0, request_1.request)(url, {
|
|
35
|
+
method: 'POST',
|
|
36
|
+
headers: {
|
|
37
|
+
'Authorization': `Bearer ${this.apiKey}`,
|
|
38
|
+
},
|
|
39
|
+
body: JSON.stringify(body),
|
|
40
|
+
timeout: this.timeout,
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Generic GET request wrapper
|
|
45
|
+
*/
|
|
46
|
+
async get(endpoint, params) {
|
|
47
|
+
const url = new URL(`${this.baseUrl}${endpoint}`);
|
|
48
|
+
if (params) {
|
|
49
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
50
|
+
url.searchParams.append(key, value);
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
return (0, request_1.request)(url.toString(), {
|
|
54
|
+
method: 'GET',
|
|
55
|
+
headers: {
|
|
56
|
+
'Authorization': `Bearer ${this.apiKey}`,
|
|
57
|
+
},
|
|
58
|
+
timeout: this.timeout,
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
exports.QiniuAI = QiniuAI;
|
|
63
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":";;;AAAA,2CAAwC;AAExC,yCAAsC;AACtC,2CAAwC;AACxC,2CAAwC;AACxC,2CAAwC;AAQxC,MAAa,OAAO;IAUhB,YAAY,OAAuB;QAC/B,sBAAsB;QACtB,IAAI,CAAC,OAAO,CAAC,MAAM,IAAI,OAAO,OAAO,CAAC,MAAM,KAAK,QAAQ,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,EAAE,CAAC;YAClF,MAAM,IAAI,KAAK,CAAC,oDAAoD,CAAC,CAAC;QAC1E,CAAC;QAED,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QAEpC,6CAA6C;QAC7C,IAAI,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,2BAA2B,CAAC;QAC7D,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;QAE3C,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,KAAK,CAAC;QACxC,IAAI,IAAI,CAAC,OAAO,IAAI,CAAC,EAAE,CAAC;YACpB,MAAM,IAAI,KAAK,CAAC,mCAAmC,CAAC,CAAC;QACzD,CAAC;QAED,qBAAqB;QACrB,IAAI,CAAC,IAAI,GAAG,IAAI,WAAI,CAAC,IAAI,CAAC,CAAC;QAC3B,IAAI,CAAC,KAAK,GAAG,IAAI,aAAK,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,CAAC,KAAK,GAAG,IAAI,aAAK,CAAC,IAAI,CAAC,CAAC;QAC7B,IAAI,CAAC,GAAG,GAAG,IAAI,aAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,IAAI,CAAI,QAAgB,EAAE,IAAS;QACrC,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,OAAO,GAAG,QAAQ,EAAE,CAAC;QACzC,OAAO,IAAA,iBAAO,EAAI,GAAG,EAAE;YACnB,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACL,eAAe,EAAE,UAAU,IAAI,CAAC,MAAM,EAAE;aAC3C;YACD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC;YAC1B,OAAO,EAAE,IAAI,CAAC,OAAO;SACxB,CAAC,CAAC;IACP,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,GAAG,CAAI,QAAgB,EAAE,MAA+B;QAC1D,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,GAAG,QAAQ,EAAE,CAAC,CAAC;QAClD,IAAI,MAAM,EAAE,CAAC;YACT,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;gBAC5C,GAAG,CAAC,YAAY,CAAC,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACxC,CAAC,CAAC,CAAC;QACP,CAAC;QAED,OAAO,IAAA,iBAAO,EAAI,GAAG,CAAC,QAAQ,EAAE,EAAE;YAC9B,MAAM,EAAE,KAAK;YACb,OAAO,EAAE;gBACL,eAAe,EAAE,UAAU,IAAI,CAAC,MAAM,EAAE;aAC3C;YACD,OAAO,EAAE,IAAI,CAAC,OAAO;SACxB,CAAC,CAAC;IACP,CAAC;CACJ;AApED,0BAoEC"}
|
package/dist/client.mjs
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { request } from './lib/request.mjs';
|
|
2
|
+
import { Chat } from './modules/chat.mjs';
|
|
3
|
+
import { Image } from './modules/image.mjs';
|
|
4
|
+
import { Video } from './modules/video.mjs';
|
|
5
|
+
import { Tools } from './modules/tools.mjs';
|
|
6
|
+
export class QiniuAI {
|
|
7
|
+
constructor(options) {
|
|
8
|
+
// Enhanced validation
|
|
9
|
+
if (!options.apiKey || typeof options.apiKey !== 'string' || !options.apiKey.trim()) {
|
|
10
|
+
throw new Error('API Key is required and must be a non-empty string');
|
|
11
|
+
}
|
|
12
|
+
this.apiKey = options.apiKey.trim();
|
|
13
|
+
// Normalize baseUrl: remove trailing slashes
|
|
14
|
+
let baseUrl = options.baseUrl || 'https://api.qnaigc.com/v1';
|
|
15
|
+
this.baseUrl = baseUrl.replace(/\/+$/, '');
|
|
16
|
+
this.timeout = options.timeout || 60000;
|
|
17
|
+
if (this.timeout <= 0) {
|
|
18
|
+
throw new Error('Timeout must be a positive number');
|
|
19
|
+
}
|
|
20
|
+
// Initialize modules
|
|
21
|
+
this.chat = new Chat(this);
|
|
22
|
+
this.image = new Image(this);
|
|
23
|
+
this.video = new Video(this);
|
|
24
|
+
this.sys = new Tools(this);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Generic POST request wrapper
|
|
28
|
+
*/
|
|
29
|
+
async post(endpoint, body) {
|
|
30
|
+
const url = `${this.baseUrl}${endpoint}`;
|
|
31
|
+
return request(url, {
|
|
32
|
+
method: 'POST',
|
|
33
|
+
headers: {
|
|
34
|
+
'Authorization': `Bearer ${this.apiKey}`,
|
|
35
|
+
},
|
|
36
|
+
body: JSON.stringify(body),
|
|
37
|
+
timeout: this.timeout,
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Generic GET request wrapper
|
|
42
|
+
*/
|
|
43
|
+
async get(endpoint, params) {
|
|
44
|
+
const url = new URL(`${this.baseUrl}${endpoint}`);
|
|
45
|
+
if (params) {
|
|
46
|
+
Object.entries(params).forEach(([key, value]) => {
|
|
47
|
+
url.searchParams.append(key, value);
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
return request(url.toString(), {
|
|
51
|
+
method: 'GET',
|
|
52
|
+
headers: {
|
|
53
|
+
'Authorization': `Bearer ${this.apiKey}`,
|
|
54
|
+
},
|
|
55
|
+
timeout: this.timeout,
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=client.js.map
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { QiniuAI, QiniuAIOptions } from './client';
|
|
2
|
+
export { APIError } from './lib/request';
|
|
3
|
+
export * from './lib/types';
|
|
4
|
+
export type { ChatCompletionRequest, ChatCompletionResponse, ChatCompletionChunk, ChatMessage, ContentPart, ToolCall } from './lib/types';
|
|
5
|
+
export type { ImageGenerationRequest, ImageTaskResponse, WaitOptions as ImageWaitOptions } from './modules/image';
|
|
6
|
+
export type { VideoGenerationRequest, VideoTaskResponse, WaitOptions as VideoWaitOptions } from './modules/video';
|
|
7
|
+
export type { WebSearchRequest, WebSearchResult } from './modules/tools';
|
|
8
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAGnD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAGzC,cAAc,aAAa,CAAC;AAG5B,YAAY,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,mBAAmB,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAG1I,YAAY,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,WAAW,IAAI,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAGlH,YAAY,EAAE,sBAAsB,EAAE,iBAAiB,EAAE,WAAW,IAAI,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAGlH,YAAY,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.APIError = exports.QiniuAI = void 0;
|
|
18
|
+
// Main client
|
|
19
|
+
var client_1 = require("./client");
|
|
20
|
+
Object.defineProperty(exports, "QiniuAI", { enumerable: true, get: function () { return client_1.QiniuAI; } });
|
|
21
|
+
// Error types
|
|
22
|
+
var request_1 = require("./lib/request");
|
|
23
|
+
Object.defineProperty(exports, "APIError", { enumerable: true, get: function () { return request_1.APIError; } });
|
|
24
|
+
// Shared types
|
|
25
|
+
__exportStar(require("./lib/types"), exports);
|
|
26
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,cAAc;AACd,mCAAmD;AAA1C,iGAAA,OAAO,OAAA;AAEhB,cAAc;AACd,yCAAyC;AAAhC,mGAAA,QAAQ,OAAA;AAEjB,eAAe;AACf,8CAA4B"}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
interface RequestOptions extends RequestInit {
|
|
2
|
+
timeout?: number;
|
|
3
|
+
}
|
|
4
|
+
export declare class APIError extends Error {
|
|
5
|
+
status: number;
|
|
6
|
+
code?: string;
|
|
7
|
+
constructor(message: string, status: number, code?: string);
|
|
8
|
+
}
|
|
9
|
+
export declare function request<T>(url: string, options?: RequestOptions): Promise<T>;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=request.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request.d.ts","sourceRoot":"","sources":["../../src/lib/request.ts"],"names":[],"mappings":"AAAA,UAAU,cAAe,SAAQ,WAAW;IACxC,OAAO,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,qBAAa,QAAS,SAAQ,KAAK;IAC/B,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;gBACF,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM;CAM7D;AAED,wBAAsB,OAAO,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,CAAC,CAAC,CAgDtF"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.APIError = void 0;
|
|
4
|
+
exports.request = request;
|
|
5
|
+
class APIError extends Error {
|
|
6
|
+
constructor(message, status, code) {
|
|
7
|
+
super(message);
|
|
8
|
+
this.name = 'APIError';
|
|
9
|
+
this.status = status;
|
|
10
|
+
this.code = code;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
exports.APIError = APIError;
|
|
14
|
+
async function request(url, options = {}) {
|
|
15
|
+
const { timeout = 60000, ...fetchOptions } = options;
|
|
16
|
+
const controller = new AbortController();
|
|
17
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
18
|
+
try {
|
|
19
|
+
const response = await fetch(url, {
|
|
20
|
+
...fetchOptions,
|
|
21
|
+
signal: controller.signal,
|
|
22
|
+
headers: {
|
|
23
|
+
'Content-Type': 'application/json',
|
|
24
|
+
...fetchOptions.headers,
|
|
25
|
+
},
|
|
26
|
+
});
|
|
27
|
+
if (!response.ok) {
|
|
28
|
+
let errorMessage = `Request failed with status ${response.status}`;
|
|
29
|
+
let errorCode;
|
|
30
|
+
try {
|
|
31
|
+
const errorBody = await response.json();
|
|
32
|
+
// Support both OpenAI format and potential Qiniu format
|
|
33
|
+
errorMessage = errorBody.error?.message || errorBody.message || errorMessage;
|
|
34
|
+
errorCode = errorBody.error?.code || errorBody.code;
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
// ignore json parse error
|
|
38
|
+
}
|
|
39
|
+
throw new APIError(errorMessage, response.status, errorCode);
|
|
40
|
+
}
|
|
41
|
+
// Handle 204 No Content
|
|
42
|
+
if (response.status === 204) {
|
|
43
|
+
return {};
|
|
44
|
+
}
|
|
45
|
+
return await response.json();
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
if (error.name === 'AbortError') {
|
|
49
|
+
throw new APIError('Request timed out', 408);
|
|
50
|
+
}
|
|
51
|
+
throw error;
|
|
52
|
+
}
|
|
53
|
+
finally {
|
|
54
|
+
clearTimeout(timeoutId);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
//# sourceMappingURL=request.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request.js","sourceRoot":"","sources":["../../src/lib/request.ts"],"names":[],"mappings":";;;AAeA,0BAgDC;AA3DD,MAAa,QAAS,SAAQ,KAAK;IAG/B,YAAY,OAAe,EAAE,MAAc,EAAE,IAAa;QACtD,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,UAAU,CAAC;QACvB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;IACrB,CAAC;CACJ;AATD,4BASC;AAEM,KAAK,UAAU,OAAO,CAAI,GAAW,EAAE,UAA0B,EAAE;IACtE,MAAM,EAAE,OAAO,GAAG,KAAK,EAAE,GAAG,YAAY,EAAE,GAAG,OAAO,CAAC;IAErD,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,OAAO,CAAC,CAAC;IAEhE,IAAI,CAAC;QACD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;YAC9B,GAAG,YAAY;YACf,MAAM,EAAE,UAAU,CAAC,MAAM;YACzB,OAAO,EAAE;gBACL,cAAc,EAAE,kBAAkB;gBAClC,GAAG,YAAY,CAAC,OAAO;aAC1B;SACJ,CAAC,CAAC;QAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;YACf,IAAI,YAAY,GAAG,8BAA8B,QAAQ,CAAC,MAAM,EAAE,CAAC;YACnE,IAAI,SAA6B,CAAC;YAClC,IAAI,CAAC;gBACD,MAAM,SAAS,GAAG,MAAM,QAAQ,CAAC,IAAI,EAIpC,CAAC;gBACF,wDAAwD;gBACxD,YAAY,GAAG,SAAS,CAAC,KAAK,EAAE,OAAO,IAAI,SAAS,CAAC,OAAO,IAAI,YAAY,CAAC;gBAC7E,SAAS,GAAG,SAAS,CAAC,KAAK,EAAE,IAAI,IAAI,SAAS,CAAC,IAAI,CAAC;YACxD,CAAC;YAAC,MAAM,CAAC;gBACL,0BAA0B;YAC9B,CAAC;YACD,MAAM,IAAI,QAAQ,CAAC,YAAY,EAAE,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QACjE,CAAC;QAED,wBAAwB;QACxB,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;YAC1B,OAAO,EAAO,CAAC;QACnB,CAAC;QAED,OAAO,MAAM,QAAQ,CAAC,IAAI,EAAO,CAAC;IACtC,CAAC;IAAC,OAAO,KAAU,EAAE,CAAC;QAClB,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;YAC9B,MAAM,IAAI,QAAQ,CAAC,mBAAmB,EAAE,GAAG,CAAC,CAAC;QACjD,CAAC;QACD,MAAM,KAAK,CAAC;IAChB,CAAC;YAAS,CAAC;QACP,YAAY,CAAC,SAAS,CAAC,CAAC;IAC5B,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export class APIError extends Error {
|
|
2
|
+
constructor(message, status, code) {
|
|
3
|
+
super(message);
|
|
4
|
+
this.name = 'APIError';
|
|
5
|
+
this.status = status;
|
|
6
|
+
this.code = code;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
export async function request(url, options = {}) {
|
|
10
|
+
const { timeout = 60000, ...fetchOptions } = options;
|
|
11
|
+
const controller = new AbortController();
|
|
12
|
+
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
13
|
+
try {
|
|
14
|
+
const response = await fetch(url, {
|
|
15
|
+
...fetchOptions,
|
|
16
|
+
signal: controller.signal,
|
|
17
|
+
headers: {
|
|
18
|
+
'Content-Type': 'application/json',
|
|
19
|
+
...fetchOptions.headers,
|
|
20
|
+
},
|
|
21
|
+
});
|
|
22
|
+
if (!response.ok) {
|
|
23
|
+
let errorMessage = `Request failed with status ${response.status}`;
|
|
24
|
+
let errorCode;
|
|
25
|
+
try {
|
|
26
|
+
const errorBody = await response.json();
|
|
27
|
+
// Support both OpenAI format and potential Qiniu format
|
|
28
|
+
errorMessage = errorBody.error?.message || errorBody.message || errorMessage;
|
|
29
|
+
errorCode = errorBody.error?.code || errorBody.code;
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
// ignore json parse error
|
|
33
|
+
}
|
|
34
|
+
throw new APIError(errorMessage, response.status, errorCode);
|
|
35
|
+
}
|
|
36
|
+
// Handle 204 No Content
|
|
37
|
+
if (response.status === 204) {
|
|
38
|
+
return {};
|
|
39
|
+
}
|
|
40
|
+
return await response.json();
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
if (error.name === 'AbortError') {
|
|
44
|
+
throw new APIError('Request timed out', 408);
|
|
45
|
+
}
|
|
46
|
+
throw error;
|
|
47
|
+
}
|
|
48
|
+
finally {
|
|
49
|
+
clearTimeout(timeoutId);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=request.js.map
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
export interface ChatMessage {
|
|
2
|
+
role: 'system' | 'user' | 'assistant' | 'tool';
|
|
3
|
+
content: string | ContentPart[];
|
|
4
|
+
name?: string;
|
|
5
|
+
tool_calls?: ToolCall[];
|
|
6
|
+
}
|
|
7
|
+
export interface ContentPart {
|
|
8
|
+
type: 'text' | 'image_url';
|
|
9
|
+
text?: string;
|
|
10
|
+
image_url?: {
|
|
11
|
+
url: string;
|
|
12
|
+
detail?: 'auto' | 'low' | 'high';
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
export interface ToolCall {
|
|
16
|
+
id: string;
|
|
17
|
+
type: 'function';
|
|
18
|
+
function: {
|
|
19
|
+
name: string;
|
|
20
|
+
arguments: string;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
export interface ChatCompletionRequest {
|
|
24
|
+
model: string;
|
|
25
|
+
messages: ChatMessage[];
|
|
26
|
+
temperature?: number;
|
|
27
|
+
top_p?: number;
|
|
28
|
+
n?: number;
|
|
29
|
+
stream?: boolean;
|
|
30
|
+
stop?: string | string[];
|
|
31
|
+
max_tokens?: number;
|
|
32
|
+
presence_penalty?: number;
|
|
33
|
+
frequency_penalty?: number;
|
|
34
|
+
logit_bias?: Record<string, number>;
|
|
35
|
+
user?: string;
|
|
36
|
+
tools?: {
|
|
37
|
+
type: 'function';
|
|
38
|
+
function: {
|
|
39
|
+
name: string;
|
|
40
|
+
description?: string;
|
|
41
|
+
parameters: Record<string, any>;
|
|
42
|
+
};
|
|
43
|
+
}[];
|
|
44
|
+
tool_choice?: 'none' | 'auto' | {
|
|
45
|
+
type: 'function';
|
|
46
|
+
function: {
|
|
47
|
+
name: string;
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
export interface ChatCompletionResponse {
|
|
52
|
+
id: string;
|
|
53
|
+
object: 'chat.completion';
|
|
54
|
+
created: number;
|
|
55
|
+
model: string;
|
|
56
|
+
choices: {
|
|
57
|
+
index: number;
|
|
58
|
+
message: ChatMessage;
|
|
59
|
+
finish_reason: 'stop' | 'length' | 'tool_calls' | 'content_filter' | null;
|
|
60
|
+
}[];
|
|
61
|
+
usage?: {
|
|
62
|
+
prompt_tokens: number;
|
|
63
|
+
completion_tokens: number;
|
|
64
|
+
total_tokens: number;
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
export interface ChatCompletionChunk {
|
|
68
|
+
id: string;
|
|
69
|
+
object: 'chat.completion.chunk';
|
|
70
|
+
created: number;
|
|
71
|
+
model: string;
|
|
72
|
+
choices: {
|
|
73
|
+
index: number;
|
|
74
|
+
delta: Partial<ChatMessage>;
|
|
75
|
+
finish_reason: 'stop' | 'length' | 'tool_calls' | 'content_filter' | null;
|
|
76
|
+
}[];
|
|
77
|
+
}
|
|
78
|
+
export interface IQiniuClient {
|
|
79
|
+
post<T>(endpoint: string, body: any): Promise<T>;
|
|
80
|
+
get<T>(endpoint: string, params?: Record<string, string>): Promise<T>;
|
|
81
|
+
}
|
|
82
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":";AAAA,qDAAqD"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { IQiniuClient, ChatCompletionRequest, ChatCompletionResponse } from '../../lib/types';
|
|
2
|
+
export declare class Chat {
|
|
3
|
+
private client;
|
|
4
|
+
constructor(client: IQiniuClient);
|
|
5
|
+
/**
|
|
6
|
+
* Create a chat completion (non-streaming only)
|
|
7
|
+
* @throws Error if stream: true is passed (streaming not yet implemented)
|
|
8
|
+
*/
|
|
9
|
+
create(params: ChatCompletionRequest): Promise<ChatCompletionResponse>;
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/modules/chat/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,qBAAqB,EAAE,sBAAsB,EAAuB,MAAM,iBAAiB,CAAC;AAEnH,qBAAa,IAAI;IACb,OAAO,CAAC,MAAM,CAAe;gBAEjB,MAAM,EAAE,YAAY;IAIhC;;;OAGG;IACG,MAAM,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,sBAAsB,CAAC;CAa/E"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Chat = void 0;
|
|
4
|
+
class Chat {
|
|
5
|
+
constructor(client) {
|
|
6
|
+
this.client = client;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Create a chat completion (non-streaming only)
|
|
10
|
+
* @throws Error if stream: true is passed (streaming not yet implemented)
|
|
11
|
+
*/
|
|
12
|
+
async create(params) {
|
|
13
|
+
if (params.stream) {
|
|
14
|
+
throw new Error('Streaming is not yet supported in this SDK. ' +
|
|
15
|
+
'Please set stream: false or omit it. ' +
|
|
16
|
+
'For streaming, use the raw HTTP endpoint directly.');
|
|
17
|
+
}
|
|
18
|
+
return this.client.post('/chat/completions', params);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
exports.Chat = Chat;
|
|
22
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/modules/chat/index.ts"],"names":[],"mappings":";;;AAEA,MAAa,IAAI;IAGb,YAAY,MAAoB;QAC5B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACzB,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,MAAM,CAAC,MAA6B;QACtC,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CACX,8CAA8C;gBAC9C,uCAAuC;gBACvC,oDAAoD,CACvD,CAAC;QACN,CAAC;QACD,OAAO,IAAI,CAAC,MAAM,CAAC,IAAI,CAAyB,mBAAmB,EAAE,MAAM,CAAC,CAAC;IACjF,CAAC;CAIJ;AAxBD,oBAwBC"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
export class Chat {
|
|
2
|
+
constructor(client) {
|
|
3
|
+
this.client = client;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Create a chat completion (non-streaming only)
|
|
7
|
+
* @throws Error if stream: true is passed (streaming not yet implemented)
|
|
8
|
+
*/
|
|
9
|
+
async create(params) {
|
|
10
|
+
if (params.stream) {
|
|
11
|
+
throw new Error('Streaming is not yet supported in this SDK. ' +
|
|
12
|
+
'Please set stream: false or omit it. ' +
|
|
13
|
+
'For streaming, use the raw HTTP endpoint directly.');
|
|
14
|
+
}
|
|
15
|
+
return this.client.post('/chat/completions', params);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { IQiniuClient } from '../../lib/types';
|
|
2
|
+
export interface ImageGenerationRequest {
|
|
3
|
+
model: string;
|
|
4
|
+
prompt: string;
|
|
5
|
+
negative_prompt?: string;
|
|
6
|
+
aspect_ratio?: '16:9' | '9:16' | '1:1' | '4:3' | '3:4' | '3:2' | '2:3' | '21:9';
|
|
7
|
+
n?: number;
|
|
8
|
+
image?: string;
|
|
9
|
+
image_url?: string;
|
|
10
|
+
strength?: number;
|
|
11
|
+
}
|
|
12
|
+
export interface ImageTaskResponse {
|
|
13
|
+
task_id: string;
|
|
14
|
+
created?: number;
|
|
15
|
+
status?: string;
|
|
16
|
+
status_message?: string;
|
|
17
|
+
data?: {
|
|
18
|
+
index: number;
|
|
19
|
+
url: string;
|
|
20
|
+
}[];
|
|
21
|
+
error?: {
|
|
22
|
+
code: string;
|
|
23
|
+
message: string;
|
|
24
|
+
};
|
|
25
|
+
quantity?: number;
|
|
26
|
+
}
|
|
27
|
+
export interface WaitOptions {
|
|
28
|
+
intervalMs?: number;
|
|
29
|
+
timeoutMs?: number;
|
|
30
|
+
signal?: AbortSignal;
|
|
31
|
+
maxRetries?: number;
|
|
32
|
+
}
|
|
33
|
+
export declare class Image {
|
|
34
|
+
private client;
|
|
35
|
+
constructor(client: IQiniuClient);
|
|
36
|
+
/**
|
|
37
|
+
* Create an image generation task
|
|
38
|
+
*/
|
|
39
|
+
create(params: ImageGenerationRequest): Promise<{
|
|
40
|
+
task_id: string;
|
|
41
|
+
}>;
|
|
42
|
+
/**
|
|
43
|
+
* Get image generation task status
|
|
44
|
+
*/
|
|
45
|
+
get(taskId: string): Promise<ImageTaskResponse>;
|
|
46
|
+
/**
|
|
47
|
+
* Poll for completion with retry and cancellation support
|
|
48
|
+
*/
|
|
49
|
+
waitForCompletion(taskId: string, options?: WaitOptions): Promise<ImageTaskResponse>;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/modules/image/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,MAAM,WAAW,sBAAsB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,YAAY,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,CAAC;IAChF,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,iBAAiB;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,IAAI,CAAC,EAAE;QACH,KAAK,EAAE,MAAM,CAAC;QACd,GAAG,EAAE,MAAM,CAAC;KACf,EAAE,CAAC;IACJ,KAAK,CAAC,EAAE;QACJ,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,QAAQ,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,WAAW,WAAW;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAID,qBAAa,KAAK;IACd,OAAO,CAAC,MAAM,CAAe;gBAEjB,MAAM,EAAE,YAAY;IAIhC;;OAEG;IACG,MAAM,CAAC,MAAM,EAAE,sBAAsB,GAAG,OAAO,CAAC;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAI1E;;OAEG;IACG,GAAG,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAIrD;;OAEG;IACG,iBAAiB,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC;CA0DjG"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Image = void 0;
|
|
4
|
+
const TERMINAL_STATUSES = ['succeed', 'failed'];
|
|
5
|
+
class Image {
|
|
6
|
+
constructor(client) {
|
|
7
|
+
this.client = client;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Create an image generation task
|
|
11
|
+
*/
|
|
12
|
+
async create(params) {
|
|
13
|
+
return this.client.post('/images/generations', params);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Get image generation task status
|
|
17
|
+
*/
|
|
18
|
+
async get(taskId) {
|
|
19
|
+
return this.client.get(`/images/tasks/${taskId}`);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Poll for completion with retry and cancellation support
|
|
23
|
+
*/
|
|
24
|
+
async waitForCompletion(taskId, options = {}) {
|
|
25
|
+
const { intervalMs = 2000, timeoutMs = 120000, signal, maxRetries = 3, } = options;
|
|
26
|
+
if (intervalMs <= 0 || timeoutMs <= 0) {
|
|
27
|
+
throw new Error('intervalMs and timeoutMs must be positive numbers');
|
|
28
|
+
}
|
|
29
|
+
const start = Date.now();
|
|
30
|
+
let consecutiveErrors = 0;
|
|
31
|
+
while (Date.now() - start < timeoutMs) {
|
|
32
|
+
// Check for cancellation
|
|
33
|
+
if (signal?.aborted) {
|
|
34
|
+
throw new Error('Operation cancelled');
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
const result = await this.get(taskId);
|
|
38
|
+
consecutiveErrors = 0; // Reset on success
|
|
39
|
+
// Check for terminal status
|
|
40
|
+
if (result.status && TERMINAL_STATUSES.includes(result.status)) {
|
|
41
|
+
return result;
|
|
42
|
+
}
|
|
43
|
+
// Warn if status is unexpected (but continue polling)
|
|
44
|
+
if (result.status && !['processing', ...TERMINAL_STATUSES].includes(result.status)) {
|
|
45
|
+
console.warn(`[QiniuAI] Unexpected image task status: ${result.status}`);
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
catch (error) {
|
|
49
|
+
consecutiveErrors++;
|
|
50
|
+
if (consecutiveErrors >= maxRetries) {
|
|
51
|
+
throw new Error(`Failed to get task status after ${maxRetries} retries: ${error instanceof Error ? error.message : String(error)}`);
|
|
52
|
+
}
|
|
53
|
+
console.warn(`[QiniuAI] Transient error polling image task (retry ${consecutiveErrors}/${maxRetries}): ${error}`);
|
|
54
|
+
}
|
|
55
|
+
// Wait before next poll
|
|
56
|
+
await new Promise((resolve, reject) => {
|
|
57
|
+
const timeoutHandle = setTimeout(resolve, intervalMs);
|
|
58
|
+
if (signal) {
|
|
59
|
+
signal.addEventListener('abort', () => {
|
|
60
|
+
clearTimeout(timeoutHandle);
|
|
61
|
+
reject(new Error('Operation cancelled'));
|
|
62
|
+
}, { once: true });
|
|
63
|
+
}
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
throw new Error(`Timeout waiting for image generation after ${timeoutMs}ms`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
exports.Image = Image;
|
|
70
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/modules/image/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
const TERMINAL_STATUSES = ['succeed', 'failed'];
|
|
2
|
+
export class Image {
|
|
3
|
+
constructor(client) {
|
|
4
|
+
this.client = client;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Create an image generation task
|
|
8
|
+
*/
|
|
9
|
+
async create(params) {
|
|
10
|
+
return this.client.post('/images/generations', params);
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Get image generation task status
|
|
14
|
+
*/
|
|
15
|
+
async get(taskId) {
|
|
16
|
+
return this.client.get(`/images/tasks/${taskId}`);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Poll for completion with retry and cancellation support
|
|
20
|
+
*/
|
|
21
|
+
async waitForCompletion(taskId, options = {}) {
|
|
22
|
+
const { intervalMs = 2000, timeoutMs = 120000, signal, maxRetries = 3, } = options;
|
|
23
|
+
if (intervalMs <= 0 || timeoutMs <= 0) {
|
|
24
|
+
throw new Error('intervalMs and timeoutMs must be positive numbers');
|
|
25
|
+
}
|
|
26
|
+
const start = Date.now();
|
|
27
|
+
let consecutiveErrors = 0;
|
|
28
|
+
while (Date.now() - start < timeoutMs) {
|
|
29
|
+
// Check for cancellation
|
|
30
|
+
if (signal?.aborted) {
|
|
31
|
+
throw new Error('Operation cancelled');
|
|
32
|
+
}
|
|
33
|
+
try {
|
|
34
|
+
const result = await this.get(taskId);
|
|
35
|
+
consecutiveErrors = 0; // Reset on success
|
|
36
|
+
// Check for terminal status
|
|
37
|
+
if (result.status && TERMINAL_STATUSES.includes(result.status)) {
|
|
38
|
+
return result;
|
|
39
|
+
}
|
|
40
|
+
// Warn if status is unexpected (but continue polling)
|
|
41
|
+
if (result.status && !['processing', ...TERMINAL_STATUSES].includes(result.status)) {
|
|
42
|
+
console.warn(`[QiniuAI] Unexpected image task status: ${result.status}`);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
consecutiveErrors++;
|
|
47
|
+
if (consecutiveErrors >= maxRetries) {
|
|
48
|
+
throw new Error(`Failed to get task status after ${maxRetries} retries: ${error instanceof Error ? error.message : String(error)}`);
|
|
49
|
+
}
|
|
50
|
+
console.warn(`[QiniuAI] Transient error polling image task (retry ${consecutiveErrors}/${maxRetries}): ${error}`);
|
|
51
|
+
}
|
|
52
|
+
// Wait before next poll
|
|
53
|
+
await new Promise((resolve, reject) => {
|
|
54
|
+
const timeoutHandle = setTimeout(resolve, intervalMs);
|
|
55
|
+
if (signal) {
|
|
56
|
+
signal.addEventListener('abort', () => {
|
|
57
|
+
clearTimeout(timeoutHandle);
|
|
58
|
+
reject(new Error('Operation cancelled'));
|
|
59
|
+
}, { once: true });
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
throw new Error(`Timeout waiting for image generation after ${timeoutMs}ms`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { IQiniuClient } from '../../lib/types';
|
|
2
|
+
export interface WebSearchRequest {
|
|
3
|
+
query: string;
|
|
4
|
+
max_results?: number;
|
|
5
|
+
search_type?: 'web' | 'news';
|
|
6
|
+
time_filter?: 'day' | 'week' | 'month' | 'year';
|
|
7
|
+
site_filter?: string[];
|
|
8
|
+
}
|
|
9
|
+
export interface WebSearchResult {
|
|
10
|
+
title: string;
|
|
11
|
+
link: string;
|
|
12
|
+
snippet: string;
|
|
13
|
+
source?: string;
|
|
14
|
+
}
|
|
15
|
+
export interface WebSearchResponse {
|
|
16
|
+
results?: WebSearchResult[];
|
|
17
|
+
[index: number]: WebSearchResult;
|
|
18
|
+
}
|
|
19
|
+
export declare class Tools {
|
|
20
|
+
private client;
|
|
21
|
+
constructor(client: IQiniuClient);
|
|
22
|
+
/**
|
|
23
|
+
* Perform a web search
|
|
24
|
+
* @returns Array of search results
|
|
25
|
+
*/
|
|
26
|
+
search(params: WebSearchRequest): Promise<WebSearchResult[]>;
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/modules/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,MAAM,WAAW,gBAAgB;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IAC7B,WAAW,CAAC,EAAE,KAAK,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAC;IAChD,WAAW,CAAC,EAAE,MAAM,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,eAAe;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB;AAGD,MAAM,WAAW,iBAAiB;IAC9B,OAAO,CAAC,EAAE,eAAe,EAAE,CAAC;IAE5B,CAAC,KAAK,EAAE,MAAM,GAAG,eAAe,CAAC;CACpC;AAED,qBAAa,KAAK;IACd,OAAO,CAAC,MAAM,CAAe;gBAEjB,MAAM,EAAE,YAAY;IAIhC;;;OAGG;IACG,MAAM,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC;CAoBrE"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Tools = void 0;
|
|
4
|
+
class Tools {
|
|
5
|
+
constructor(client) {
|
|
6
|
+
this.client = client;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Perform a web search
|
|
10
|
+
* @returns Array of search results
|
|
11
|
+
*/
|
|
12
|
+
async search(params) {
|
|
13
|
+
if (!params.query || !params.query.trim()) {
|
|
14
|
+
throw new Error('Search query is required and must be a non-empty string');
|
|
15
|
+
}
|
|
16
|
+
// Call API and handle potential response formats
|
|
17
|
+
const response = await this.client.post('/search/web', params);
|
|
18
|
+
// Normalize response: handle both array and wrapper formats
|
|
19
|
+
if (Array.isArray(response)) {
|
|
20
|
+
return response;
|
|
21
|
+
}
|
|
22
|
+
if (response && 'results' in response && Array.isArray(response.results)) {
|
|
23
|
+
return response.results;
|
|
24
|
+
}
|
|
25
|
+
// If neither, return empty array with warning
|
|
26
|
+
console.warn('[QiniuAI] Unexpected search response format:', response);
|
|
27
|
+
return [];
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
exports.Tools = Tools;
|
|
31
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/modules/tools/index.ts"],"names":[],"mappings":";;;AAwBA,MAAa,KAAK;IAGd,YAAY,MAAoB;QAC5B,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACzB,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,MAAM,CAAC,MAAwB;QACjC,IAAI,CAAC,MAAM,CAAC,KAAK,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC;YACxC,MAAM,IAAI,KAAK,CAAC,yDAAyD,CAAC,CAAC;QAC/E,CAAC;QAED,iDAAiD;QACjD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAqD,aAAa,EAAE,MAAM,CAAC,CAAC;QAEnH,4DAA4D;QAC5D,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;YAC1B,OAAO,QAAQ,CAAC;QACpB,CAAC;QACD,IAAI,QAAQ,IAAI,SAAS,IAAI,QAAQ,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YACvE,OAAO,QAAQ,CAAC,OAAO,CAAC;QAC5B,CAAC;QAED,8CAA8C;QAC9C,OAAO,CAAC,IAAI,CAAC,8CAA8C,EAAE,QAAQ,CAAC,CAAC;QACvE,OAAO,EAAE,CAAC;IACd,CAAC;CACJ;AA/BD,sBA+BC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
export class Tools {
|
|
2
|
+
constructor(client) {
|
|
3
|
+
this.client = client;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Perform a web search
|
|
7
|
+
* @returns Array of search results
|
|
8
|
+
*/
|
|
9
|
+
async search(params) {
|
|
10
|
+
if (!params.query || !params.query.trim()) {
|
|
11
|
+
throw new Error('Search query is required and must be a non-empty string');
|
|
12
|
+
}
|
|
13
|
+
// Call API and handle potential response formats
|
|
14
|
+
const response = await this.client.post('/search/web', params);
|
|
15
|
+
// Normalize response: handle both array and wrapper formats
|
|
16
|
+
if (Array.isArray(response)) {
|
|
17
|
+
return response;
|
|
18
|
+
}
|
|
19
|
+
if (response && 'results' in response && Array.isArray(response.results)) {
|
|
20
|
+
return response.results;
|
|
21
|
+
}
|
|
22
|
+
// If neither, return empty array with warning
|
|
23
|
+
console.warn('[QiniuAI] Unexpected search response format:', response);
|
|
24
|
+
return [];
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { IQiniuClient } from '../../lib/types';
|
|
2
|
+
export interface VideoGenerationRequest {
|
|
3
|
+
model: string;
|
|
4
|
+
prompt: string;
|
|
5
|
+
image?: string;
|
|
6
|
+
image_url?: string;
|
|
7
|
+
duration?: '5' | '10';
|
|
8
|
+
aspect_ratio?: '16:9' | '1:1' | '9:16';
|
|
9
|
+
mode?: 'std' | 'pro';
|
|
10
|
+
negative_prompt?: string;
|
|
11
|
+
cfg_scale?: number;
|
|
12
|
+
}
|
|
13
|
+
export interface VideoTaskResponse {
|
|
14
|
+
id: string;
|
|
15
|
+
object?: 'video';
|
|
16
|
+
model?: string;
|
|
17
|
+
status: string;
|
|
18
|
+
created_at?: number;
|
|
19
|
+
updated_at?: number;
|
|
20
|
+
completed_at?: number;
|
|
21
|
+
seconds?: string;
|
|
22
|
+
size?: string;
|
|
23
|
+
mode?: 'std' | 'pro';
|
|
24
|
+
task_result?: {
|
|
25
|
+
videos: {
|
|
26
|
+
id: string;
|
|
27
|
+
url: string;
|
|
28
|
+
duration: string;
|
|
29
|
+
}[];
|
|
30
|
+
};
|
|
31
|
+
error?: {
|
|
32
|
+
code: string;
|
|
33
|
+
message: string;
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
export interface WaitOptions {
|
|
37
|
+
intervalMs?: number;
|
|
38
|
+
timeoutMs?: number;
|
|
39
|
+
signal?: AbortSignal;
|
|
40
|
+
maxRetries?: number;
|
|
41
|
+
}
|
|
42
|
+
export declare class Video {
|
|
43
|
+
private client;
|
|
44
|
+
constructor(client: IQiniuClient);
|
|
45
|
+
/**
|
|
46
|
+
* Create a video generation task
|
|
47
|
+
*/
|
|
48
|
+
create(params: VideoGenerationRequest): Promise<{
|
|
49
|
+
id: string;
|
|
50
|
+
}>;
|
|
51
|
+
/**
|
|
52
|
+
* Get video generation task status
|
|
53
|
+
*/
|
|
54
|
+
get(id: string): Promise<VideoTaskResponse>;
|
|
55
|
+
/**
|
|
56
|
+
* Poll for completion with retry and cancellation support
|
|
57
|
+
*/
|
|
58
|
+
waitForCompletion(id: string, options?: WaitOptions): Promise<VideoTaskResponse>;
|
|
59
|
+
}
|
|
60
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/modules/video/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,iBAAiB,CAAC;AAE/C,MAAM,WAAW,sBAAsB;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC;IACtB,YAAY,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;IACvC,IAAI,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,iBAAiB;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,KAAK,GAAG,KAAK,CAAC;IACrB,WAAW,CAAC,EAAE;QACV,MAAM,EAAE;YACJ,EAAE,EAAE,MAAM,CAAC;YACX,GAAG,EAAE,MAAM,CAAC;YACZ,QAAQ,EAAE,MAAM,CAAC;SACpB,EAAE,CAAC;KACP,CAAC;IACF,KAAK,CAAC,EAAE;QACJ,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;KACnB,CAAC;CACL;AAED,MAAM,WAAW,WAAW;IACxB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACvB;AAID,qBAAa,KAAK;IACd,OAAO,CAAC,MAAM,CAAe;gBAEjB,MAAM,EAAE,YAAY;IAIhC;;OAEG;IACG,MAAM,CAAC,MAAM,EAAE,sBAAsB,GAAG,OAAO,CAAC;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;IAIrE;;OAEG;IACG,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAIjD;;OAEG;IACG,iBAAiB,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,GAAE,WAAgB,GAAG,OAAO,CAAC,iBAAiB,CAAC;CAsD7F"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Video = void 0;
|
|
4
|
+
const TERMINAL_STATUSES = ['completed', 'failed'];
|
|
5
|
+
class Video {
|
|
6
|
+
constructor(client) {
|
|
7
|
+
this.client = client;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Create a video generation task
|
|
11
|
+
*/
|
|
12
|
+
async create(params) {
|
|
13
|
+
return this.client.post('/videos', params);
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Get video generation task status
|
|
17
|
+
*/
|
|
18
|
+
async get(id) {
|
|
19
|
+
return this.client.get(`/videos/${id}`);
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Poll for completion with retry and cancellation support
|
|
23
|
+
*/
|
|
24
|
+
async waitForCompletion(id, options = {}) {
|
|
25
|
+
const { intervalMs = 3000, timeoutMs = 600000, // 10 minutes default for video (longer than image)
|
|
26
|
+
signal, maxRetries = 3, } = options;
|
|
27
|
+
if (intervalMs <= 0 || timeoutMs <= 0) {
|
|
28
|
+
throw new Error('intervalMs and timeoutMs must be positive numbers');
|
|
29
|
+
}
|
|
30
|
+
const start = Date.now();
|
|
31
|
+
let consecutiveErrors = 0;
|
|
32
|
+
while (Date.now() - start < timeoutMs) {
|
|
33
|
+
if (signal?.aborted) {
|
|
34
|
+
throw new Error('Operation cancelled');
|
|
35
|
+
}
|
|
36
|
+
try {
|
|
37
|
+
const result = await this.get(id);
|
|
38
|
+
consecutiveErrors = 0;
|
|
39
|
+
if (result.status && TERMINAL_STATUSES.includes(result.status)) {
|
|
40
|
+
return result;
|
|
41
|
+
}
|
|
42
|
+
if (result.status && !['in_progress', 'pending', 'queued', ...TERMINAL_STATUSES].includes(result.status)) {
|
|
43
|
+
console.warn(`[QiniuAI] Unexpected video task status: ${result.status}`);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
consecutiveErrors++;
|
|
48
|
+
if (consecutiveErrors >= maxRetries) {
|
|
49
|
+
throw new Error(`Failed to get task status after ${maxRetries} retries: ${error instanceof Error ? error.message : String(error)}`);
|
|
50
|
+
}
|
|
51
|
+
console.warn(`[QiniuAI] Transient error polling video task (retry ${consecutiveErrors}/${maxRetries}): ${error}`);
|
|
52
|
+
}
|
|
53
|
+
await new Promise((resolve, reject) => {
|
|
54
|
+
const timeoutHandle = setTimeout(resolve, intervalMs);
|
|
55
|
+
if (signal) {
|
|
56
|
+
signal.addEventListener('abort', () => {
|
|
57
|
+
clearTimeout(timeoutHandle);
|
|
58
|
+
reject(new Error('Operation cancelled'));
|
|
59
|
+
}, { once: true });
|
|
60
|
+
}
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
throw new Error(`Timeout waiting for video generation after ${timeoutMs}ms`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
exports.Video = Video;
|
|
67
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/modules/video/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
const TERMINAL_STATUSES = ['completed', 'failed'];
|
|
2
|
+
export class Video {
|
|
3
|
+
constructor(client) {
|
|
4
|
+
this.client = client;
|
|
5
|
+
}
|
|
6
|
+
/**
|
|
7
|
+
* Create a video generation task
|
|
8
|
+
*/
|
|
9
|
+
async create(params) {
|
|
10
|
+
return this.client.post('/videos', params);
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Get video generation task status
|
|
14
|
+
*/
|
|
15
|
+
async get(id) {
|
|
16
|
+
return this.client.get(`/videos/${id}`);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Poll for completion with retry and cancellation support
|
|
20
|
+
*/
|
|
21
|
+
async waitForCompletion(id, options = {}) {
|
|
22
|
+
const { intervalMs = 3000, timeoutMs = 600000, // 10 minutes default for video (longer than image)
|
|
23
|
+
signal, maxRetries = 3, } = options;
|
|
24
|
+
if (intervalMs <= 0 || timeoutMs <= 0) {
|
|
25
|
+
throw new Error('intervalMs and timeoutMs must be positive numbers');
|
|
26
|
+
}
|
|
27
|
+
const start = Date.now();
|
|
28
|
+
let consecutiveErrors = 0;
|
|
29
|
+
while (Date.now() - start < timeoutMs) {
|
|
30
|
+
if (signal?.aborted) {
|
|
31
|
+
throw new Error('Operation cancelled');
|
|
32
|
+
}
|
|
33
|
+
try {
|
|
34
|
+
const result = await this.get(id);
|
|
35
|
+
consecutiveErrors = 0;
|
|
36
|
+
if (result.status && TERMINAL_STATUSES.includes(result.status)) {
|
|
37
|
+
return result;
|
|
38
|
+
}
|
|
39
|
+
if (result.status && !['in_progress', 'pending', 'queued', ...TERMINAL_STATUSES].includes(result.status)) {
|
|
40
|
+
console.warn(`[QiniuAI] Unexpected video task status: ${result.status}`);
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
catch (error) {
|
|
44
|
+
consecutiveErrors++;
|
|
45
|
+
if (consecutiveErrors >= maxRetries) {
|
|
46
|
+
throw new Error(`Failed to get task status after ${maxRetries} retries: ${error instanceof Error ? error.message : String(error)}`);
|
|
47
|
+
}
|
|
48
|
+
console.warn(`[QiniuAI] Transient error polling video task (retry ${consecutiveErrors}/${maxRetries}): ${error}`);
|
|
49
|
+
}
|
|
50
|
+
await new Promise((resolve, reject) => {
|
|
51
|
+
const timeoutHandle = setTimeout(resolve, intervalMs);
|
|
52
|
+
if (signal) {
|
|
53
|
+
signal.addEventListener('abort', () => {
|
|
54
|
+
clearTimeout(timeoutHandle);
|
|
55
|
+
reject(new Error('Operation cancelled'));
|
|
56
|
+
}, { once: true });
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
throw new Error(`Timeout waiting for video generation after ${timeoutMs}ms`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=index.js.map
|
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@bowenqt/qiniu-ai-sdk",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "TypeScript SDK for Qiniu Cloud AI Token API - Chat, Image, Video generation and more",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.mjs",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"require": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"default": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"import": {
|
|
15
|
+
"types": "./dist/index.d.ts",
|
|
16
|
+
"default": "./dist/index.mjs"
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist",
|
|
22
|
+
"README.md",
|
|
23
|
+
"LICENSE"
|
|
24
|
+
],
|
|
25
|
+
"scripts": {
|
|
26
|
+
"build": "npm run build:cjs && npm run build:esm",
|
|
27
|
+
"build:cjs": "tsc -p tsconfig.json",
|
|
28
|
+
"build:esm": "tsc -p tsconfig.esm.json && node scripts/fix-esm.js",
|
|
29
|
+
"clean": "rm -rf dist",
|
|
30
|
+
"prepublishOnly": "npm run clean && npm run build",
|
|
31
|
+
"test": "echo \"No tests yet\" && exit 0"
|
|
32
|
+
},
|
|
33
|
+
"keywords": [
|
|
34
|
+
"qiniu",
|
|
35
|
+
"ai",
|
|
36
|
+
"llm",
|
|
37
|
+
"openai",
|
|
38
|
+
"chat",
|
|
39
|
+
"image-generation",
|
|
40
|
+
"video-generation",
|
|
41
|
+
"sdk",
|
|
42
|
+
"typescript"
|
|
43
|
+
],
|
|
44
|
+
"author": "",
|
|
45
|
+
"license": "MIT",
|
|
46
|
+
"repository": {
|
|
47
|
+
"type": "git",
|
|
48
|
+
"url": "git+https://github.com/bowenQT/qiniu-ai-sdk.git"
|
|
49
|
+
},
|
|
50
|
+
"bugs": {
|
|
51
|
+
"url": "https://github.com/bowenQT/qiniu-ai-sdk/issues"
|
|
52
|
+
},
|
|
53
|
+
"homepage": "https://github.com/bowenQT/qiniu-ai-sdk#readme",
|
|
54
|
+
"engines": {
|
|
55
|
+
"node": ">=18.0.0"
|
|
56
|
+
},
|
|
57
|
+
"devDependencies": {
|
|
58
|
+
"@types/node": "^20.0.0",
|
|
59
|
+
"typescript": "^5.0.0"
|
|
60
|
+
}
|
|
61
|
+
}
|