seacloud-sdk 0.9.6 → 0.9.8
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/dist/cli.js +223 -10
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +252 -1
- package/dist/index.js +113 -10
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -13,7 +13,51 @@ var SeacloudError = class extends Error {
|
|
|
13
13
|
};
|
|
14
14
|
|
|
15
15
|
// src/core/config.ts
|
|
16
|
-
function
|
|
16
|
+
function isInIframe() {
|
|
17
|
+
try {
|
|
18
|
+
return typeof globalThis.window !== "undefined" && globalThis.window.self !== globalThis.window.top;
|
|
19
|
+
} catch (e) {
|
|
20
|
+
return true;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
async function getTokenFromParent(timeout = 5e3) {
|
|
24
|
+
if (!isInIframe()) {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
return new Promise((resolve) => {
|
|
28
|
+
const messageHandler = (event) => {
|
|
29
|
+
if (event.data && event.data.type === "seaverse:token") {
|
|
30
|
+
cleanup();
|
|
31
|
+
const token = event.data.payload?.accessToken;
|
|
32
|
+
resolve(token || null);
|
|
33
|
+
} else if (event.data && event.data.type === "seaverse:error") {
|
|
34
|
+
cleanup();
|
|
35
|
+
console.warn("[SeaCloud SDK] Error getting token from parent:", event.data.error);
|
|
36
|
+
resolve(null);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
const timeoutId = setTimeout(() => {
|
|
40
|
+
cleanup();
|
|
41
|
+
resolve(null);
|
|
42
|
+
}, timeout);
|
|
43
|
+
const cleanup = () => {
|
|
44
|
+
clearTimeout(timeoutId);
|
|
45
|
+
globalThis.window.removeEventListener("message", messageHandler);
|
|
46
|
+
};
|
|
47
|
+
globalThis.window.addEventListener("message", messageHandler);
|
|
48
|
+
try {
|
|
49
|
+
globalThis.window.parent.postMessage(
|
|
50
|
+
{ type: "seaverse:get_token" },
|
|
51
|
+
"*"
|
|
52
|
+
// 允许任何源,支持跨域场景
|
|
53
|
+
);
|
|
54
|
+
} catch (e) {
|
|
55
|
+
cleanup();
|
|
56
|
+
resolve(null);
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
async function getApiToken(providedApiKey) {
|
|
17
61
|
if (providedApiKey) {
|
|
18
62
|
return providedApiKey;
|
|
19
63
|
}
|
|
@@ -29,19 +73,24 @@ function getApiToken(providedApiKey) {
|
|
|
29
73
|
if (typeof process !== "undefined" && process.env?.API_SERVICE_TOKEN) {
|
|
30
74
|
return process.env.API_SERVICE_TOKEN;
|
|
31
75
|
}
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
76
|
+
if (typeof globalThis.window !== "undefined") {
|
|
77
|
+
const parentToken = await getTokenFromParent();
|
|
78
|
+
if (parentToken) {
|
|
79
|
+
return parentToken;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return "";
|
|
35
83
|
}
|
|
36
84
|
function createConfig(options = {}) {
|
|
37
|
-
const apiKey =
|
|
85
|
+
const apiKey = options.apiKey;
|
|
38
86
|
const baseUrl = options.baseUrl || (typeof process !== "undefined" ? process.env?.SEACLOUD_BASE_URL : void 0) || "https://proxy-rs.seaverse.ai";
|
|
39
87
|
const fetchImpl = options.fetch || (globalThis.fetch ? globalThis.fetch.bind(globalThis) : void 0);
|
|
40
88
|
if (!fetchImpl) {
|
|
41
89
|
throw new Error("fetch is not available. Please provide a fetch implementation in config or upgrade to Node.js 18+");
|
|
42
90
|
}
|
|
43
91
|
return {
|
|
44
|
-
apiKey,
|
|
92
|
+
apiKey: apiKey || "",
|
|
93
|
+
// 提供默认空字符串,实际请求时会动态获取
|
|
45
94
|
baseUrl,
|
|
46
95
|
fetch: fetchImpl,
|
|
47
96
|
timeout: options.timeout || 3e4
|
|
@@ -86,7 +135,7 @@ var SeacloudClient = class {
|
|
|
86
135
|
*/
|
|
87
136
|
async createTask(endpoint, body) {
|
|
88
137
|
const url = `${this.config.baseUrl}${endpoint}`;
|
|
89
|
-
const currentToken = getApiToken(this.providedApiKey);
|
|
138
|
+
const currentToken = await getApiToken(this.providedApiKey);
|
|
90
139
|
const controller = new AbortController();
|
|
91
140
|
const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);
|
|
92
141
|
try {
|
|
@@ -133,7 +182,7 @@ var SeacloudClient = class {
|
|
|
133
182
|
*/
|
|
134
183
|
async getTaskStatus(endpoint, taskId) {
|
|
135
184
|
const url = `${this.config.baseUrl}${endpoint}/task/${taskId}`;
|
|
136
|
-
const currentToken = getApiToken(this.providedApiKey);
|
|
185
|
+
const currentToken = await getApiToken(this.providedApiKey);
|
|
137
186
|
const controller = new AbortController();
|
|
138
187
|
const timeoutId = setTimeout(() => controller.abort(), this.config.timeout);
|
|
139
188
|
try {
|
|
@@ -230,6 +279,7 @@ async function llmChatCompletions(params) {
|
|
|
230
279
|
const client = getClient();
|
|
231
280
|
const config = client.getConfig();
|
|
232
281
|
const url = `${config.baseUrl}/llm/chat/completions`;
|
|
282
|
+
const token = await getApiToken(config.apiKey);
|
|
233
283
|
const controller = new AbortController();
|
|
234
284
|
const timeoutId = setTimeout(() => controller.abort(), config.timeout);
|
|
235
285
|
try {
|
|
@@ -237,7 +287,7 @@ async function llmChatCompletions(params) {
|
|
|
237
287
|
method: "POST",
|
|
238
288
|
headers: {
|
|
239
289
|
"Content-Type": "application/json",
|
|
240
|
-
"Authorization": `Bearer ${
|
|
290
|
+
"Authorization": `Bearer ${token}`
|
|
241
291
|
},
|
|
242
292
|
body: JSON.stringify(params),
|
|
243
293
|
signal: controller.signal
|
|
@@ -505,6 +555,39 @@ function createTextMessage(role, text) {
|
|
|
505
555
|
content: [{ type: "text", text }]
|
|
506
556
|
};
|
|
507
557
|
}
|
|
558
|
+
|
|
559
|
+
// src/api/app_search.ts
|
|
560
|
+
async function appSearch(params) {
|
|
561
|
+
const client = getClient();
|
|
562
|
+
const config = client.getConfig();
|
|
563
|
+
const url = `${config.baseUrl}/model/v1/template/specs`;
|
|
564
|
+
const controller = new AbortController();
|
|
565
|
+
const timeoutId = setTimeout(() => controller.abort(), config.timeout);
|
|
566
|
+
try {
|
|
567
|
+
const requestId = `req-${Date.now()}-${Math.random().toString(36).substring(7)}`;
|
|
568
|
+
const response = await config.fetch(url, {
|
|
569
|
+
method: "POST",
|
|
570
|
+
headers: {
|
|
571
|
+
"Content-Type": "application/json",
|
|
572
|
+
"Authorization": `Bearer ${config.apiKey}`,
|
|
573
|
+
"X-Request-Id": requestId,
|
|
574
|
+
"X-Project": "KIIRA"
|
|
575
|
+
},
|
|
576
|
+
body: JSON.stringify(params),
|
|
577
|
+
signal: controller.signal
|
|
578
|
+
});
|
|
579
|
+
clearTimeout(timeoutId);
|
|
580
|
+
if (!response.ok) {
|
|
581
|
+
const errorBody = await response.text();
|
|
582
|
+
throw new Error(`HTTP ${response.status}: ${errorBody}`);
|
|
583
|
+
}
|
|
584
|
+
const result = await response.json();
|
|
585
|
+
return result;
|
|
586
|
+
} catch (error) {
|
|
587
|
+
clearTimeout(timeoutId);
|
|
588
|
+
throw error;
|
|
589
|
+
}
|
|
590
|
+
}
|
|
508
591
|
var __filename$1 = fileURLToPath(import.meta.url);
|
|
509
592
|
dirname(__filename$1);
|
|
510
593
|
function showHelp() {
|
|
@@ -517,8 +600,13 @@ Usage:
|
|
|
517
600
|
Commands:
|
|
518
601
|
llm <prompt> Chat with LLM models
|
|
519
602
|
agent <prompt> Chat with Fast Agent (supports image/video generation)
|
|
603
|
+
app <subcommand> App-related operations (search, generation)
|
|
520
604
|
<model> Test specific model generation
|
|
521
605
|
|
|
606
|
+
App Subcommands:
|
|
607
|
+
app search <ids> Query template specifications by template IDs
|
|
608
|
+
app generation Create generation task from template
|
|
609
|
+
|
|
522
610
|
LLM Options:
|
|
523
611
|
--model <name> Model name (default: seaart-mix-sonnet-4-5)
|
|
524
612
|
--stream Enable streaming mode
|
|
@@ -531,6 +619,13 @@ Agent Options:
|
|
|
531
619
|
--stream Enable streaming mode
|
|
532
620
|
--session-id <id> Session ID for multi-turn conversation
|
|
533
621
|
|
|
622
|
+
App Search Options:
|
|
623
|
+
--type <type> Template type (default: comfyui)
|
|
624
|
+
|
|
625
|
+
App Generation Options:
|
|
626
|
+
--template-id <id> Template ID (required)
|
|
627
|
+
--params <json> Input parameters as JSON string (required)
|
|
628
|
+
|
|
534
629
|
Model Generation Options:
|
|
535
630
|
--api-key <key> API key (or set API_SERVICE_TOKEN env var)
|
|
536
631
|
--base-url <url> Base URL (default: http://proxy.sg.seaverse.dev)
|
|
@@ -552,6 +647,13 @@ Examples:
|
|
|
552
647
|
# Chat with Agent (streaming)
|
|
553
648
|
seacloud agent "Create a cat image" --stream
|
|
554
649
|
|
|
650
|
+
# Query template specifications (app search)
|
|
651
|
+
seacloud app search "template-id-1,template-id-2"
|
|
652
|
+
seacloud app search "template-abc" --type comfyui
|
|
653
|
+
|
|
654
|
+
# Create generation task (app generation)
|
|
655
|
+
seacloud app generation --template-id "d26trpte878eqsnm3bjg" --params '[{"field":"prompt1","value":"hello"}]'
|
|
656
|
+
|
|
555
657
|
# Test model generation
|
|
556
658
|
seacloud flux_1_1_pro --params '{"prompt":"a beautiful sunset"}'
|
|
557
659
|
|
|
@@ -591,7 +693,7 @@ function parseArgs(args) {
|
|
|
591
693
|
}
|
|
592
694
|
async function testModel(model, options) {
|
|
593
695
|
const apiKey = options.apiKey || process.env.API_SERVICE_TOKEN || "";
|
|
594
|
-
const baseUrl = options.baseUrl || process.env.
|
|
696
|
+
const baseUrl = options.baseUrl || process.env.SEACLOUD_BASE_URL || "http://proxy.sg.seaverse.dev";
|
|
595
697
|
if (!options.params) {
|
|
596
698
|
console.error("Error: --params required. Provide JSON parameters for the model");
|
|
597
699
|
process.exit(1);
|
|
@@ -761,6 +863,95 @@ async function runAgent(prompt, args) {
|
|
|
761
863
|
console.log("Message ID:", response.msg_id);
|
|
762
864
|
}
|
|
763
865
|
}
|
|
866
|
+
async function runAppGeneration(args) {
|
|
867
|
+
const options = {};
|
|
868
|
+
for (let i = 0; i < args.length; i++) {
|
|
869
|
+
const arg = args[i];
|
|
870
|
+
if (arg === "--template-id") options.templateId = args[++i];
|
|
871
|
+
else if (arg === "--params") {
|
|
872
|
+
try {
|
|
873
|
+
options.params = JSON.parse(args[++i]);
|
|
874
|
+
} catch (e) {
|
|
875
|
+
console.error("Error: --params must be valid JSON array");
|
|
876
|
+
console.error(`Example: --params '[{"field":"prompt1","value":"hello"}]'`);
|
|
877
|
+
process.exit(1);
|
|
878
|
+
}
|
|
879
|
+
} else if (arg === "--api-key") options.apiKey = args[++i];
|
|
880
|
+
else if (arg === "--base-url") options.baseUrl = args[++i];
|
|
881
|
+
}
|
|
882
|
+
if (!options.templateId) {
|
|
883
|
+
console.error("Error: --template-id required");
|
|
884
|
+
console.error("Usage: seacloud app generation --template-id <id> --params <json>");
|
|
885
|
+
process.exit(1);
|
|
886
|
+
}
|
|
887
|
+
if (!options.params) {
|
|
888
|
+
console.error("Error: --params required");
|
|
889
|
+
console.error("Usage: seacloud app generation --template-id <id> --params <json>");
|
|
890
|
+
console.error(`Example: --params '[{"field":"prompt1","value":"hello"}]'`);
|
|
891
|
+
process.exit(1);
|
|
892
|
+
}
|
|
893
|
+
const apiKey = options.apiKey || process.env.API_SERVICE_TOKEN || "";
|
|
894
|
+
const baseUrl = options.baseUrl || process.env.SEACLOUD_BASE_URL || "http://proxy.sg.seaverse.dev";
|
|
895
|
+
const client = new SeacloudClient({ apiKey, baseUrl });
|
|
896
|
+
try {
|
|
897
|
+
console.log("Creating task...");
|
|
898
|
+
const task = await client.createTask("/model/v1/generation", {
|
|
899
|
+
model: "comfyui",
|
|
900
|
+
input: [{ params: { template_id: options.templateId, inputs: options.params } }]
|
|
901
|
+
});
|
|
902
|
+
console.log(`Task created: ${task.id}`);
|
|
903
|
+
console.log(`Initial status: ${task.status}`);
|
|
904
|
+
console.log("");
|
|
905
|
+
if (task.status === "failed") {
|
|
906
|
+
console.error("Task failed immediately:", task.error);
|
|
907
|
+
process.exit(1);
|
|
908
|
+
}
|
|
909
|
+
console.log("Polling for results...");
|
|
910
|
+
let attempt = 0;
|
|
911
|
+
const maxAttempts = 120;
|
|
912
|
+
const intervalMs = 3e3;
|
|
913
|
+
while (attempt < maxAttempts) {
|
|
914
|
+
attempt++;
|
|
915
|
+
const result = await client.getTaskStatus("/model/v1/generation", task.id);
|
|
916
|
+
process.stdout.write(`\rAttempt ${attempt}/${maxAttempts} - Status: ${result.status} `);
|
|
917
|
+
if (result.status === "completed") {
|
|
918
|
+
console.log("\n\nTask completed!");
|
|
919
|
+
console.log("\nResults:");
|
|
920
|
+
console.log(JSON.stringify(result, null, 2));
|
|
921
|
+
process.exit(0);
|
|
922
|
+
}
|
|
923
|
+
if (result.status === "failed") {
|
|
924
|
+
console.log("\n\nTask failed!");
|
|
925
|
+
console.error("Error:", result.error);
|
|
926
|
+
process.exit(1);
|
|
927
|
+
}
|
|
928
|
+
await new Promise((resolve) => setTimeout(resolve, intervalMs));
|
|
929
|
+
}
|
|
930
|
+
console.log("\n\nTimeout: Task did not complete within the time limit");
|
|
931
|
+
process.exit(1);
|
|
932
|
+
} catch (error) {
|
|
933
|
+
console.error("\nError:", error.message);
|
|
934
|
+
process.exit(1);
|
|
935
|
+
}
|
|
936
|
+
}
|
|
937
|
+
async function runAppSearch(templateIdsStr, args) {
|
|
938
|
+
const options = { type: "comfyui" };
|
|
939
|
+
for (let i = 0; i < args.length; i++) {
|
|
940
|
+
const arg = args[i];
|
|
941
|
+
if (arg === "--type") options.type = args[++i];
|
|
942
|
+
else if (arg === "--api-key") options.apiKey = args[++i];
|
|
943
|
+
else if (arg === "--base-url") options.baseUrl = args[++i];
|
|
944
|
+
}
|
|
945
|
+
const apiKey = options.apiKey || process.env.API_SERVICE_TOKEN || "";
|
|
946
|
+
const baseUrl = options.baseUrl || process.env.SEACLOUD_BASE_URL || "http://proxy.sg.seaverse.dev";
|
|
947
|
+
initSeacloud(apiKey, { baseUrl });
|
|
948
|
+
const templateIds = templateIdsStr.split(",").map((id) => id.trim());
|
|
949
|
+
const result = await appSearch({
|
|
950
|
+
type: options.type,
|
|
951
|
+
template_ids: templateIds
|
|
952
|
+
});
|
|
953
|
+
console.log(JSON.stringify(result, null, 2));
|
|
954
|
+
}
|
|
764
955
|
async function main() {
|
|
765
956
|
const args = process.argv.slice(2);
|
|
766
957
|
if (args.length === 0 || args[0] === "--help" || args[0] === "-h") {
|
|
@@ -783,6 +974,28 @@ async function main() {
|
|
|
783
974
|
process.exit(1);
|
|
784
975
|
}
|
|
785
976
|
await runAgent(args[1], args.slice(2));
|
|
977
|
+
} else if (command === "app") {
|
|
978
|
+
const subcommand = args[1];
|
|
979
|
+
if (!subcommand) {
|
|
980
|
+
console.error("Error: subcommand required for app command");
|
|
981
|
+
console.log("Usage: seacloud app <subcommand> [options]");
|
|
982
|
+
console.log("Subcommands: search, generation");
|
|
983
|
+
process.exit(1);
|
|
984
|
+
}
|
|
985
|
+
if (subcommand === "search") {
|
|
986
|
+
if (args.length < 3) {
|
|
987
|
+
console.error("Error: template IDs required for app search command");
|
|
988
|
+
console.log('Usage: seacloud app search "<id1,id2,...>" [options]');
|
|
989
|
+
process.exit(1);
|
|
990
|
+
}
|
|
991
|
+
await runAppSearch(args[2], args.slice(3));
|
|
992
|
+
} else if (subcommand === "generation") {
|
|
993
|
+
await runAppGeneration(args.slice(2));
|
|
994
|
+
} else {
|
|
995
|
+
console.error(`Error: unknown subcommand '${subcommand}'`);
|
|
996
|
+
console.log("Available subcommands: search, generation");
|
|
997
|
+
process.exit(1);
|
|
998
|
+
}
|
|
786
999
|
} else {
|
|
787
1000
|
const model = command;
|
|
788
1001
|
if (model.startsWith("--")) {
|