@acedatacloud/sdk 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +97 -0
- package/dist/client.d.ts +31 -0
- package/dist/client.js +46 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +20 -0
- package/dist/resources/audio.d.ts +17 -0
- package/dist/resources/audio.js +30 -0
- package/dist/resources/chat.d.ts +30 -0
- package/dist/resources/chat.js +38 -0
- package/dist/resources/files.d.ts +9 -0
- package/dist/resources/files.js +59 -0
- package/dist/resources/images.d.ts +18 -0
- package/dist/resources/images.js +32 -0
- package/dist/resources/openai.d.ts +46 -0
- package/dist/resources/openai.js +59 -0
- package/dist/resources/platform.d.ts +41 -0
- package/dist/resources/platform.js +76 -0
- package/dist/resources/search.d.ts +14 -0
- package/dist/resources/search.js +22 -0
- package/dist/resources/tasks.d.ts +14 -0
- package/dist/resources/tasks.js +36 -0
- package/dist/resources/video.d.ts +17 -0
- package/dist/resources/video.js +30 -0
- package/dist/runtime/errors.d.ts +44 -0
- package/dist/runtime/errors.js +89 -0
- package/dist/runtime/index.d.ts +3 -0
- package/dist/runtime/index.js +19 -0
- package/dist/runtime/tasks.d.ts +17 -0
- package/dist/runtime/tasks.js +46 -0
- package/dist/runtime/transport.d.ts +31 -0
- package/dist/runtime/transport.js +210 -0
- package/package.json +28 -0
- package/src/client.ts +56 -0
- package/src/index.ts +19 -0
- package/src/resources/audio.ts +34 -0
- package/src/resources/chat.ts +63 -0
- package/src/resources/files.ts +27 -0
- package/src/resources/images.ts +36 -0
- package/src/resources/openai.ts +96 -0
- package/src/resources/platform.ts +77 -0
- package/src/resources/search.ts +23 -0
- package/src/resources/tasks.ts +38 -0
- package/src/resources/video.ts +34 -0
- package/src/runtime/errors.ts +93 -0
- package/src/runtime/index.ts +15 -0
- package/src/runtime/tasks.ts +57 -0
- package/src/runtime/transport.ts +257 -0
package/src/client.ts
ADDED
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/** Top-level AceDataCloud client for TypeScript. */
|
|
2
|
+
|
|
3
|
+
import { Transport, TransportOptions } from './runtime/transport';
|
|
4
|
+
import { Chat } from './resources/chat';
|
|
5
|
+
import { Images } from './resources/images';
|
|
6
|
+
import { Audio } from './resources/audio';
|
|
7
|
+
import { Video } from './resources/video';
|
|
8
|
+
import { Search } from './resources/search';
|
|
9
|
+
import { Tasks } from './resources/tasks';
|
|
10
|
+
import { Files } from './resources/files';
|
|
11
|
+
import { Platform } from './resources/platform';
|
|
12
|
+
import { OpenAI } from './resources/openai';
|
|
13
|
+
|
|
14
|
+
export interface AceDataCloudOptions {
|
|
15
|
+
apiToken?: string;
|
|
16
|
+
baseURL?: string;
|
|
17
|
+
platformBaseURL?: string;
|
|
18
|
+
timeout?: number;
|
|
19
|
+
maxRetries?: number;
|
|
20
|
+
headers?: Record<string, string>;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export class AceDataCloud {
|
|
24
|
+
readonly chat: Chat;
|
|
25
|
+
readonly images: Images;
|
|
26
|
+
readonly audio: Audio;
|
|
27
|
+
readonly video: Video;
|
|
28
|
+
readonly search: Search;
|
|
29
|
+
readonly tasks: Tasks;
|
|
30
|
+
readonly files: Files;
|
|
31
|
+
readonly platform: Platform;
|
|
32
|
+
readonly openai: OpenAI;
|
|
33
|
+
|
|
34
|
+
private transport: Transport;
|
|
35
|
+
|
|
36
|
+
constructor(opts: AceDataCloudOptions = {}) {
|
|
37
|
+
this.transport = new Transport({
|
|
38
|
+
apiToken: opts.apiToken,
|
|
39
|
+
baseURL: opts.baseURL,
|
|
40
|
+
platformBaseURL: opts.platformBaseURL,
|
|
41
|
+
timeout: opts.timeout,
|
|
42
|
+
maxRetries: opts.maxRetries,
|
|
43
|
+
headers: opts.headers,
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
this.chat = new Chat(this.transport);
|
|
47
|
+
this.images = new Images(this.transport);
|
|
48
|
+
this.audio = new Audio(this.transport);
|
|
49
|
+
this.video = new Video(this.transport);
|
|
50
|
+
this.search = new Search(this.transport);
|
|
51
|
+
this.tasks = new Tasks(this.transport);
|
|
52
|
+
this.files = new Files(this.transport);
|
|
53
|
+
this.platform = new Platform(this.transport);
|
|
54
|
+
this.openai = new OpenAI(this.transport);
|
|
55
|
+
}
|
|
56
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/** @acedatacloud/sdk — Official TypeScript SDK for AceDataCloud. */
|
|
2
|
+
|
|
3
|
+
export { AceDataCloud, AceDataCloudOptions } from './client';
|
|
4
|
+
|
|
5
|
+
export {
|
|
6
|
+
AceDataCloudError,
|
|
7
|
+
APIError,
|
|
8
|
+
AuthenticationError,
|
|
9
|
+
InsufficientBalanceError,
|
|
10
|
+
ModerationError,
|
|
11
|
+
RateLimitError,
|
|
12
|
+
ResourceDisabledError,
|
|
13
|
+
TimeoutError,
|
|
14
|
+
TokenMismatchError,
|
|
15
|
+
TransportError,
|
|
16
|
+
ValidationError,
|
|
17
|
+
} from './runtime/errors';
|
|
18
|
+
|
|
19
|
+
export { TaskHandle, TaskHandleOptions } from './runtime/tasks';
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/** Audio/music generation resources. */
|
|
2
|
+
|
|
3
|
+
import { Transport } from '../runtime/transport';
|
|
4
|
+
import { TaskHandle } from '../runtime/tasks';
|
|
5
|
+
|
|
6
|
+
export class Audio {
|
|
7
|
+
constructor(private transport: Transport) {}
|
|
8
|
+
|
|
9
|
+
async generate(opts: {
|
|
10
|
+
prompt: string;
|
|
11
|
+
model?: string;
|
|
12
|
+
tags?: string;
|
|
13
|
+
callbackUrl?: string;
|
|
14
|
+
wait?: boolean;
|
|
15
|
+
pollInterval?: number;
|
|
16
|
+
maxWait?: number;
|
|
17
|
+
[key: string]: unknown;
|
|
18
|
+
}): Promise<Record<string, unknown> | TaskHandle> {
|
|
19
|
+
const { prompt, model, tags, callbackUrl, wait: shouldWait, pollInterval, maxWait, ...rest } = opts;
|
|
20
|
+
const body: Record<string, unknown> = { prompt, ...rest };
|
|
21
|
+
if (model !== undefined) body.model = model;
|
|
22
|
+
if (tags !== undefined) body.tags = tags;
|
|
23
|
+
if (callbackUrl !== undefined) body.callback_url = callbackUrl;
|
|
24
|
+
|
|
25
|
+
const result = await this.transport.request('POST', '/suno/audios', { json: body });
|
|
26
|
+
const taskId = result.task_id as string | undefined;
|
|
27
|
+
|
|
28
|
+
if (!taskId || (result.data && !shouldWait)) return result;
|
|
29
|
+
|
|
30
|
+
const handle = new TaskHandle(taskId, '/suno/tasks', this.transport);
|
|
31
|
+
if (shouldWait) return handle.wait({ pollInterval, maxWait });
|
|
32
|
+
return handle;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/** Chat resources — native provider APIs (Claude Messages). */
|
|
2
|
+
|
|
3
|
+
import { Transport } from '../runtime/transport';
|
|
4
|
+
|
|
5
|
+
export class Messages {
|
|
6
|
+
constructor(private transport: Transport) {}
|
|
7
|
+
|
|
8
|
+
async create(opts: {
|
|
9
|
+
model: string;
|
|
10
|
+
messages: Array<Record<string, unknown>>;
|
|
11
|
+
maxTokens?: number;
|
|
12
|
+
stream?: false;
|
|
13
|
+
[key: string]: unknown;
|
|
14
|
+
}): Promise<Record<string, unknown>>;
|
|
15
|
+
async create(opts: {
|
|
16
|
+
model: string;
|
|
17
|
+
messages: Array<Record<string, unknown>>;
|
|
18
|
+
maxTokens?: number;
|
|
19
|
+
stream: true;
|
|
20
|
+
[key: string]: unknown;
|
|
21
|
+
}): Promise<AsyncGenerator<Record<string, unknown>>>;
|
|
22
|
+
async create(opts: {
|
|
23
|
+
model: string;
|
|
24
|
+
messages: Array<Record<string, unknown>>;
|
|
25
|
+
maxTokens?: number;
|
|
26
|
+
stream?: boolean;
|
|
27
|
+
[key: string]: unknown;
|
|
28
|
+
}): Promise<Record<string, unknown> | AsyncGenerator<Record<string, unknown>>> {
|
|
29
|
+
const { model, messages, maxTokens = 4096, stream, ...rest } = opts;
|
|
30
|
+
const body: Record<string, unknown> = { model, messages, max_tokens: maxTokens, ...rest };
|
|
31
|
+
|
|
32
|
+
if (stream) {
|
|
33
|
+
body.stream = true;
|
|
34
|
+
return this.stream(body);
|
|
35
|
+
}
|
|
36
|
+
return this.transport.request('POST', '/v1/messages', { json: body });
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
private async *stream(body: Record<string, unknown>): AsyncGenerator<Record<string, unknown>> {
|
|
40
|
+
for await (const chunk of this.transport.requestStream('POST', '/v1/messages', { json: body })) {
|
|
41
|
+
yield JSON.parse(chunk);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
async countTokens(opts: {
|
|
46
|
+
model: string;
|
|
47
|
+
messages: Array<Record<string, unknown>>;
|
|
48
|
+
[key: string]: unknown;
|
|
49
|
+
}): Promise<Record<string, unknown>> {
|
|
50
|
+
const { model, messages, ...rest } = opts;
|
|
51
|
+
return this.transport.request('POST', '/v1/messages/count_tokens', {
|
|
52
|
+
json: { model, messages, ...rest },
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export class Chat {
|
|
58
|
+
readonly messages: Messages;
|
|
59
|
+
|
|
60
|
+
constructor(transport: Transport) {
|
|
61
|
+
this.messages = new Messages(transport);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** File upload resources. */
|
|
2
|
+
|
|
3
|
+
import { Transport } from '../runtime/transport';
|
|
4
|
+
import * as fs from 'fs';
|
|
5
|
+
import * as path from 'path';
|
|
6
|
+
|
|
7
|
+
export class Files {
|
|
8
|
+
constructor(private transport: Transport) {}
|
|
9
|
+
|
|
10
|
+
async upload(
|
|
11
|
+
file: string | Buffer | Uint8Array,
|
|
12
|
+
opts: { filename?: string } = {}
|
|
13
|
+
): Promise<Record<string, unknown>> {
|
|
14
|
+
let data: Buffer | Uint8Array;
|
|
15
|
+
let filename: string;
|
|
16
|
+
|
|
17
|
+
if (typeof file === 'string') {
|
|
18
|
+
data = fs.readFileSync(file);
|
|
19
|
+
filename = opts.filename ?? path.basename(file);
|
|
20
|
+
} else {
|
|
21
|
+
data = file;
|
|
22
|
+
filename = opts.filename ?? 'upload';
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return this.transport.upload('/api/v1/files/', data, filename);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/** Image generation resources. */
|
|
2
|
+
|
|
3
|
+
import { Transport } from '../runtime/transport';
|
|
4
|
+
import { TaskHandle } from '../runtime/tasks';
|
|
5
|
+
|
|
6
|
+
export class Images {
|
|
7
|
+
constructor(private transport: Transport) {}
|
|
8
|
+
|
|
9
|
+
async generate(opts: {
|
|
10
|
+
prompt: string;
|
|
11
|
+
model?: string;
|
|
12
|
+
negativePrompt?: string;
|
|
13
|
+
imageUrl?: string;
|
|
14
|
+
callbackUrl?: string;
|
|
15
|
+
wait?: boolean;
|
|
16
|
+
pollInterval?: number;
|
|
17
|
+
maxWait?: number;
|
|
18
|
+
[key: string]: unknown;
|
|
19
|
+
}): Promise<Record<string, unknown> | TaskHandle> {
|
|
20
|
+
const { prompt, model, negativePrompt, imageUrl, callbackUrl, wait: shouldWait, pollInterval, maxWait, ...rest } = opts;
|
|
21
|
+
const body: Record<string, unknown> = { prompt, ...rest };
|
|
22
|
+
if (model !== undefined) body.model = model;
|
|
23
|
+
if (negativePrompt !== undefined) body.negative_prompt = negativePrompt;
|
|
24
|
+
if (imageUrl !== undefined) body.image_url = imageUrl;
|
|
25
|
+
if (callbackUrl !== undefined) body.callback_url = callbackUrl;
|
|
26
|
+
|
|
27
|
+
const result = await this.transport.request('POST', '/nano-banana/images', { json: body });
|
|
28
|
+
const taskId = result.task_id as string | undefined;
|
|
29
|
+
|
|
30
|
+
if (!taskId || (result.data && !shouldWait)) return result;
|
|
31
|
+
|
|
32
|
+
const handle = new TaskHandle(taskId, '/nano-banana/tasks', this.transport);
|
|
33
|
+
if (shouldWait) return handle.wait({ pollInterval, maxWait });
|
|
34
|
+
return handle;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/** OpenAI-compatible facade resources. */
|
|
2
|
+
|
|
3
|
+
import { Transport } from '../runtime/transport';
|
|
4
|
+
|
|
5
|
+
class Completions {
|
|
6
|
+
constructor(private transport: Transport) {}
|
|
7
|
+
|
|
8
|
+
async create(opts: {
|
|
9
|
+
model: string;
|
|
10
|
+
messages: Array<Record<string, unknown>>;
|
|
11
|
+
stream?: false;
|
|
12
|
+
[key: string]: unknown;
|
|
13
|
+
}): Promise<Record<string, unknown>>;
|
|
14
|
+
async create(opts: {
|
|
15
|
+
model: string;
|
|
16
|
+
messages: Array<Record<string, unknown>>;
|
|
17
|
+
stream: true;
|
|
18
|
+
[key: string]: unknown;
|
|
19
|
+
}): Promise<AsyncGenerator<Record<string, unknown>>>;
|
|
20
|
+
async create(opts: {
|
|
21
|
+
model: string;
|
|
22
|
+
messages: Array<Record<string, unknown>>;
|
|
23
|
+
stream?: boolean;
|
|
24
|
+
[key: string]: unknown;
|
|
25
|
+
}): Promise<Record<string, unknown> | AsyncGenerator<Record<string, unknown>>> {
|
|
26
|
+
const { model, messages, stream, ...rest } = opts;
|
|
27
|
+
const body: Record<string, unknown> = { model, messages, ...rest };
|
|
28
|
+
|
|
29
|
+
if (stream) {
|
|
30
|
+
body.stream = true;
|
|
31
|
+
return this.streamResponse(body);
|
|
32
|
+
}
|
|
33
|
+
return this.transport.request('POST', '/v1/chat/completions', { json: body });
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
private async *streamResponse(body: Record<string, unknown>): AsyncGenerator<Record<string, unknown>> {
|
|
37
|
+
for await (const chunk of this.transport.requestStream('POST', '/v1/chat/completions', { json: body })) {
|
|
38
|
+
yield JSON.parse(chunk);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
class ChatNamespace {
|
|
44
|
+
readonly completions: Completions;
|
|
45
|
+
constructor(transport: Transport) {
|
|
46
|
+
this.completions = new Completions(transport);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
class Responses {
|
|
51
|
+
constructor(private transport: Transport) {}
|
|
52
|
+
|
|
53
|
+
async create(opts: {
|
|
54
|
+
model: string;
|
|
55
|
+
input: string | Array<Record<string, unknown>>;
|
|
56
|
+
stream?: false;
|
|
57
|
+
[key: string]: unknown;
|
|
58
|
+
}): Promise<Record<string, unknown>>;
|
|
59
|
+
async create(opts: {
|
|
60
|
+
model: string;
|
|
61
|
+
input: string | Array<Record<string, unknown>>;
|
|
62
|
+
stream: true;
|
|
63
|
+
[key: string]: unknown;
|
|
64
|
+
}): Promise<AsyncGenerator<Record<string, unknown>>>;
|
|
65
|
+
async create(opts: {
|
|
66
|
+
model: string;
|
|
67
|
+
input: string | Array<Record<string, unknown>>;
|
|
68
|
+
stream?: boolean;
|
|
69
|
+
[key: string]: unknown;
|
|
70
|
+
}): Promise<Record<string, unknown> | AsyncGenerator<Record<string, unknown>>> {
|
|
71
|
+
const { model, input, stream, ...rest } = opts;
|
|
72
|
+
const body: Record<string, unknown> = { model, input, ...rest };
|
|
73
|
+
|
|
74
|
+
if (stream) {
|
|
75
|
+
body.stream = true;
|
|
76
|
+
return this.streamResponse(body);
|
|
77
|
+
}
|
|
78
|
+
return this.transport.request('POST', '/openai/responses', { json: body });
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
private async *streamResponse(body: Record<string, unknown>): AsyncGenerator<Record<string, unknown>> {
|
|
82
|
+
for await (const chunk of this.transport.requestStream('POST', '/openai/responses', { json: body })) {
|
|
83
|
+
yield JSON.parse(chunk);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export class OpenAI {
|
|
89
|
+
readonly chat: ChatNamespace;
|
|
90
|
+
readonly responses: Responses;
|
|
91
|
+
|
|
92
|
+
constructor(transport: Transport) {
|
|
93
|
+
this.chat = new ChatNamespace(transport);
|
|
94
|
+
this.responses = new Responses(transport);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/** Management-plane resources. */
|
|
2
|
+
|
|
3
|
+
import { Transport } from '../runtime/transport';
|
|
4
|
+
|
|
5
|
+
class Applications {
|
|
6
|
+
constructor(private transport: Transport) {}
|
|
7
|
+
|
|
8
|
+
async list(params?: Record<string, string>): Promise<Record<string, unknown>> {
|
|
9
|
+
return this.transport.request('GET', '/api/v1/applications/', { params, platform: true });
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
async create(opts: { serviceId: string; [key: string]: unknown }): Promise<Record<string, unknown>> {
|
|
13
|
+
const { serviceId, ...rest } = opts;
|
|
14
|
+
return this.transport.request('POST', '/api/v1/applications/', {
|
|
15
|
+
json: { service_id: serviceId, ...rest },
|
|
16
|
+
platform: true,
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
async get(applicationId: string): Promise<Record<string, unknown>> {
|
|
21
|
+
return this.transport.request('GET', `/api/v1/applications/${applicationId}/`, { platform: true });
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
class Credentials {
|
|
26
|
+
constructor(private transport: Transport) {}
|
|
27
|
+
|
|
28
|
+
async list(params?: Record<string, string>): Promise<Record<string, unknown>> {
|
|
29
|
+
return this.transport.request('GET', '/api/v1/credentials/', { params, platform: true });
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async create(opts: { applicationId: string; [key: string]: unknown }): Promise<Record<string, unknown>> {
|
|
33
|
+
const { applicationId, ...rest } = opts;
|
|
34
|
+
return this.transport.request('POST', '/api/v1/credentials/', {
|
|
35
|
+
json: { application_id: applicationId, ...rest },
|
|
36
|
+
platform: true,
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
async rotate(credentialId: string): Promise<Record<string, unknown>> {
|
|
41
|
+
return this.transport.request('POST', `/api/v1/credentials/${credentialId}/rotate/`, { platform: true });
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
async delete(credentialId: string): Promise<Record<string, unknown>> {
|
|
45
|
+
return this.transport.request('DELETE', `/api/v1/credentials/${credentialId}/`, { platform: true });
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
class Models {
|
|
50
|
+
constructor(private transport: Transport) {}
|
|
51
|
+
|
|
52
|
+
async list(params?: Record<string, string>): Promise<Record<string, unknown>> {
|
|
53
|
+
return this.transport.request('GET', '/api/v1/models/', { params, platform: true });
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
class Config {
|
|
58
|
+
constructor(private transport: Transport) {}
|
|
59
|
+
|
|
60
|
+
async get(): Promise<Record<string, unknown>> {
|
|
61
|
+
return this.transport.request('GET', '/api/v1/config/', { platform: true });
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
export class Platform {
|
|
66
|
+
readonly applications: Applications;
|
|
67
|
+
readonly credentials: Credentials;
|
|
68
|
+
readonly models: Models;
|
|
69
|
+
readonly config: Config;
|
|
70
|
+
|
|
71
|
+
constructor(transport: Transport) {
|
|
72
|
+
this.applications = new Applications(transport);
|
|
73
|
+
this.credentials = new Credentials(transport);
|
|
74
|
+
this.models = new Models(transport);
|
|
75
|
+
this.config = new Config(transport);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** Search resources. */
|
|
2
|
+
|
|
3
|
+
import { Transport } from '../runtime/transport';
|
|
4
|
+
|
|
5
|
+
export class Search {
|
|
6
|
+
constructor(private transport: Transport) {}
|
|
7
|
+
|
|
8
|
+
async google(opts: {
|
|
9
|
+
query: string;
|
|
10
|
+
type?: string;
|
|
11
|
+
country?: string;
|
|
12
|
+
language?: string;
|
|
13
|
+
page?: number;
|
|
14
|
+
[key: string]: unknown;
|
|
15
|
+
}): Promise<Record<string, unknown>> {
|
|
16
|
+
const { query, type = 'search', country, language, page, ...rest } = opts;
|
|
17
|
+
const body: Record<string, unknown> = { query, type, ...rest };
|
|
18
|
+
if (country !== undefined) body.country = country;
|
|
19
|
+
if (language !== undefined) body.language = language;
|
|
20
|
+
if (page !== undefined) body.page = page;
|
|
21
|
+
return this.transport.request('POST', '/serp/google', { json: body });
|
|
22
|
+
}
|
|
23
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/** Cross-service task retrieval. */
|
|
2
|
+
|
|
3
|
+
import { Transport } from '../runtime/transport';
|
|
4
|
+
import { TaskHandle } from '../runtime/tasks';
|
|
5
|
+
|
|
6
|
+
const SERVICE_TASK_ENDPOINTS: Record<string, string> = {
|
|
7
|
+
suno: '/suno/tasks',
|
|
8
|
+
'nano-banana': '/nano-banana/tasks',
|
|
9
|
+
seedream: '/seedream/tasks',
|
|
10
|
+
seedance: '/seedance/tasks',
|
|
11
|
+
sora: '/sora/tasks',
|
|
12
|
+
midjourney: '/midjourney/tasks',
|
|
13
|
+
luma: '/luma/tasks',
|
|
14
|
+
veo: '/veo/tasks',
|
|
15
|
+
flux: '/flux/tasks',
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export class Tasks {
|
|
19
|
+
constructor(private transport: Transport) {}
|
|
20
|
+
|
|
21
|
+
async get(taskId: string, opts: { service?: string } = {}): Promise<Record<string, unknown>> {
|
|
22
|
+
const service = opts.service ?? 'suno';
|
|
23
|
+
const endpoint = SERVICE_TASK_ENDPOINTS[service] ?? `/${service}/tasks`;
|
|
24
|
+
return this.transport.request('POST', endpoint, {
|
|
25
|
+
json: { id: taskId, action: 'retrieve' },
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
async wait(
|
|
30
|
+
taskId: string,
|
|
31
|
+
opts: { service?: string; pollInterval?: number; maxWait?: number } = {}
|
|
32
|
+
): Promise<Record<string, unknown>> {
|
|
33
|
+
const service = opts.service ?? 'suno';
|
|
34
|
+
const endpoint = SERVICE_TASK_ENDPOINTS[service] ?? `/${service}/tasks`;
|
|
35
|
+
const handle = new TaskHandle(taskId, endpoint, this.transport);
|
|
36
|
+
return handle.wait({ pollInterval: opts.pollInterval, maxWait: opts.maxWait });
|
|
37
|
+
}
|
|
38
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/** Video generation resources. */
|
|
2
|
+
|
|
3
|
+
import { Transport } from '../runtime/transport';
|
|
4
|
+
import { TaskHandle } from '../runtime/tasks';
|
|
5
|
+
|
|
6
|
+
export class Video {
|
|
7
|
+
constructor(private transport: Transport) {}
|
|
8
|
+
|
|
9
|
+
async generate(opts: {
|
|
10
|
+
prompt: string;
|
|
11
|
+
model?: string;
|
|
12
|
+
imageUrl?: string;
|
|
13
|
+
callbackUrl?: string;
|
|
14
|
+
wait?: boolean;
|
|
15
|
+
pollInterval?: number;
|
|
16
|
+
maxWait?: number;
|
|
17
|
+
[key: string]: unknown;
|
|
18
|
+
}): Promise<Record<string, unknown> | TaskHandle> {
|
|
19
|
+
const { prompt, model, imageUrl, callbackUrl, wait: shouldWait, pollInterval, maxWait, ...rest } = opts;
|
|
20
|
+
const body: Record<string, unknown> = { prompt, ...rest };
|
|
21
|
+
if (model !== undefined) body.model = model;
|
|
22
|
+
if (imageUrl !== undefined) body.image_url = imageUrl;
|
|
23
|
+
if (callbackUrl !== undefined) body.callback_url = callbackUrl;
|
|
24
|
+
|
|
25
|
+
const result = await this.transport.request('POST', '/sora/videos', { json: body });
|
|
26
|
+
const taskId = result.task_id as string | undefined;
|
|
27
|
+
|
|
28
|
+
if (!taskId || (result.data && !shouldWait)) return result;
|
|
29
|
+
|
|
30
|
+
const handle = new TaskHandle(taskId, '/sora/tasks', this.transport);
|
|
31
|
+
if (shouldWait) return handle.wait({ pollInterval, maxWait });
|
|
32
|
+
return handle;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/** AceDataCloud SDK errors. */
|
|
2
|
+
|
|
3
|
+
export class AceDataCloudError extends Error {
|
|
4
|
+
constructor(message: string) {
|
|
5
|
+
super(message);
|
|
6
|
+
this.name = 'AceDataCloudError';
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export class TransportError extends AceDataCloudError {
|
|
11
|
+
constructor(message: string) {
|
|
12
|
+
super(message);
|
|
13
|
+
this.name = 'TransportError';
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export class APIError extends AceDataCloudError {
|
|
18
|
+
statusCode: number;
|
|
19
|
+
code: string;
|
|
20
|
+
traceId?: string;
|
|
21
|
+
body: Record<string, unknown>;
|
|
22
|
+
|
|
23
|
+
constructor(opts: {
|
|
24
|
+
message: string;
|
|
25
|
+
statusCode: number;
|
|
26
|
+
code: string;
|
|
27
|
+
traceId?: string;
|
|
28
|
+
body?: Record<string, unknown>;
|
|
29
|
+
}) {
|
|
30
|
+
super(opts.message);
|
|
31
|
+
this.name = 'APIError';
|
|
32
|
+
this.statusCode = opts.statusCode;
|
|
33
|
+
this.code = opts.code;
|
|
34
|
+
this.traceId = opts.traceId;
|
|
35
|
+
this.body = opts.body ?? {};
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export class AuthenticationError extends APIError {
|
|
40
|
+
constructor(opts: ConstructorParameters<typeof APIError>[0]) {
|
|
41
|
+
super(opts);
|
|
42
|
+
this.name = 'AuthenticationError';
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export class TokenMismatchError extends APIError {
|
|
47
|
+
constructor(opts: ConstructorParameters<typeof APIError>[0]) {
|
|
48
|
+
super(opts);
|
|
49
|
+
this.name = 'TokenMismatchError';
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export class RateLimitError extends APIError {
|
|
54
|
+
constructor(opts: ConstructorParameters<typeof APIError>[0]) {
|
|
55
|
+
super(opts);
|
|
56
|
+
this.name = 'RateLimitError';
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export class ValidationError extends APIError {
|
|
61
|
+
constructor(opts: ConstructorParameters<typeof APIError>[0]) {
|
|
62
|
+
super(opts);
|
|
63
|
+
this.name = 'ValidationError';
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
export class InsufficientBalanceError extends APIError {
|
|
68
|
+
constructor(opts: ConstructorParameters<typeof APIError>[0]) {
|
|
69
|
+
super(opts);
|
|
70
|
+
this.name = 'InsufficientBalanceError';
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export class ResourceDisabledError extends APIError {
|
|
75
|
+
constructor(opts: ConstructorParameters<typeof APIError>[0]) {
|
|
76
|
+
super(opts);
|
|
77
|
+
this.name = 'ResourceDisabledError';
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
export class ModerationError extends APIError {
|
|
82
|
+
constructor(opts: ConstructorParameters<typeof APIError>[0]) {
|
|
83
|
+
super(opts);
|
|
84
|
+
this.name = 'ModerationError';
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
export class TimeoutError extends APIError {
|
|
89
|
+
constructor(opts: ConstructorParameters<typeof APIError>[0]) {
|
|
90
|
+
super(opts);
|
|
91
|
+
this.name = 'TimeoutError';
|
|
92
|
+
}
|
|
93
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export { Transport, TransportOptions } from './transport';
|
|
2
|
+
export { TaskHandle, TaskHandleOptions } from './tasks';
|
|
3
|
+
export {
|
|
4
|
+
AceDataCloudError,
|
|
5
|
+
APIError,
|
|
6
|
+
AuthenticationError,
|
|
7
|
+
InsufficientBalanceError,
|
|
8
|
+
ModerationError,
|
|
9
|
+
RateLimitError,
|
|
10
|
+
ResourceDisabledError,
|
|
11
|
+
TimeoutError,
|
|
12
|
+
TokenMismatchError,
|
|
13
|
+
TransportError,
|
|
14
|
+
ValidationError,
|
|
15
|
+
} from './errors';
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/** Task polling abstraction. */
|
|
2
|
+
|
|
3
|
+
import { Transport } from './transport';
|
|
4
|
+
|
|
5
|
+
export interface TaskHandleOptions {
|
|
6
|
+
pollInterval?: number;
|
|
7
|
+
maxWait?: number;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export class TaskHandle {
|
|
11
|
+
readonly id: string;
|
|
12
|
+
private pollEndpoint: string;
|
|
13
|
+
private transport: Transport;
|
|
14
|
+
private _result: Record<string, unknown> | null = null;
|
|
15
|
+
|
|
16
|
+
constructor(taskId: string, pollEndpoint: string, transport: Transport) {
|
|
17
|
+
this.id = taskId;
|
|
18
|
+
this.pollEndpoint = pollEndpoint;
|
|
19
|
+
this.transport = transport;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
async get(): Promise<Record<string, unknown>> {
|
|
23
|
+
return this.transport.request('POST', this.pollEndpoint, {
|
|
24
|
+
json: { id: this.id, action: 'retrieve' },
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
async isCompleted(): Promise<boolean> {
|
|
29
|
+
const state = await this.get();
|
|
30
|
+
const response = (state.response ?? state) as Record<string, unknown>;
|
|
31
|
+
const status = response.status as string;
|
|
32
|
+
return status === 'succeeded' || status === 'failed';
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
async wait(opts: TaskHandleOptions = {}): Promise<Record<string, unknown>> {
|
|
36
|
+
const pollInterval = opts.pollInterval ?? 3000;
|
|
37
|
+
const maxWait = opts.maxWait ?? 600_000;
|
|
38
|
+
const start = Date.now();
|
|
39
|
+
|
|
40
|
+
while (Date.now() - start < maxWait) {
|
|
41
|
+
const state = await this.get();
|
|
42
|
+
const response = (state.response ?? state) as Record<string, unknown>;
|
|
43
|
+
const status = response.status as string;
|
|
44
|
+
|
|
45
|
+
if (status === 'succeeded' || status === 'failed') {
|
|
46
|
+
this._result = state;
|
|
47
|
+
return state;
|
|
48
|
+
}
|
|
49
|
+
await new Promise((resolve) => setTimeout(resolve, pollInterval));
|
|
50
|
+
}
|
|
51
|
+
throw new Error(`Task ${this.id} did not complete within ${maxWait}ms`);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
get result(): Record<string, unknown> | null {
|
|
55
|
+
return this._result;
|
|
56
|
+
}
|
|
57
|
+
}
|