ai-world-sdk 1.3.0 → 1.3.3
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/__tests__/example.test.js +27 -0
- package/dist/config.d.ts +3 -3
- package/dist/config.js +2 -2
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/llm.js +5 -0
- package/dist/openai_video_generation.d.ts +5 -4
- package/dist/provider_config.d.ts +1 -1
- package/dist/provider_config.js +2 -0
- package/dist/video_generation.d.ts +149 -2
- package/dist/video_generation.js +138 -3
- package/package.json +2 -1
- package/skills/ai-world-sdk/SKILL.md +35 -5
- package/skills/ai-world-sdk/docs/provider-and-models.md +20 -5
- package/skills/ai-world-sdk/docs/video-generation.md +104 -1
- package/skills/ai-world-sdk/docs/vscode-login.md +1 -1
|
@@ -40,6 +40,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
40
40
|
const dotenv = __importStar(require("dotenv"));
|
|
41
41
|
const index_1 = require("../index");
|
|
42
42
|
const fs_1 = require("fs");
|
|
43
|
+
const ai_1 = require("ai");
|
|
43
44
|
// Load environment variables from .env file
|
|
44
45
|
dotenv.config();
|
|
45
46
|
index_1.sdkConfig.setBaseUrl("http://localhost:8000");
|
|
@@ -1187,6 +1188,32 @@ describe("Langchain SDK Tests", () => {
|
|
|
1187
1188
|
console.log("响应内容:", content);
|
|
1188
1189
|
}
|
|
1189
1190
|
}, 30000);
|
|
1191
|
+
// ========== OpenRouter 测试 ==========
|
|
1192
|
+
test("ChatOpenAI - OpenRouter 基础测试", async () => {
|
|
1193
|
+
const provider = (0, index_1.createProvider)("openrouter", "openai", "test");
|
|
1194
|
+
const result = await (0, ai_1.generateText)({
|
|
1195
|
+
model: provider.languageModel('openai/gpt-4o-mini'),
|
|
1196
|
+
prompt: '你好',
|
|
1197
|
+
});
|
|
1198
|
+
console.log("result:", result);
|
|
1199
|
+
}, 30000);
|
|
1200
|
+
test("ChatOpenAI - OpenRouter 流式调用", async () => {
|
|
1201
|
+
const provider = (0, index_1.createProvider)("openrouter", "openai", "test");
|
|
1202
|
+
const stream = (0, ai_1.streamText)({
|
|
1203
|
+
model: provider.languageModel('openai/gpt-4o-mini'),
|
|
1204
|
+
prompt: '你好',
|
|
1205
|
+
});
|
|
1206
|
+
let fullText = "";
|
|
1207
|
+
for await (const part of stream.fullStream) {
|
|
1208
|
+
switch (part.type) {
|
|
1209
|
+
case 'text-delta':
|
|
1210
|
+
fullText += part.text;
|
|
1211
|
+
break;
|
|
1212
|
+
}
|
|
1213
|
+
}
|
|
1214
|
+
expect(fullText.length).toBeGreaterThan(0);
|
|
1215
|
+
console.log("fullText:", fullText);
|
|
1216
|
+
}, 30000);
|
|
1190
1217
|
// ========== OpenAI 视频生成测试 ==========
|
|
1191
1218
|
test("OpenAIVideoGenerationClient - 创建视频生成任务(文本)", async () => {
|
|
1192
1219
|
const openaiVideoClient = new index_1.OpenAIVideoGenerationClient({});
|
package/dist/config.d.ts
CHANGED
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
*
|
|
10
10
|
* 注意: {VERSION} 占位符会在构建时被替换为实际版本号
|
|
11
11
|
*/
|
|
12
|
-
export declare const SDK_SIGNATURE = "AI_WORLD_SDK_V:1.3.
|
|
12
|
+
export declare const SDK_SIGNATURE = "AI_WORLD_SDK_V:1.3.3";
|
|
13
13
|
/**
|
|
14
14
|
* 版本兼容性错误
|
|
15
15
|
*/
|
|
@@ -34,8 +34,8 @@ declare class SDKConfig {
|
|
|
34
34
|
private _authenticated;
|
|
35
35
|
private _authCheckPromise;
|
|
36
36
|
private _currentUser;
|
|
37
|
-
readonly sdkSignature = "AI_WORLD_SDK_V:1.3.
|
|
38
|
-
readonly sdkVersion = "1.3.
|
|
37
|
+
readonly sdkSignature = "AI_WORLD_SDK_V:1.3.3";
|
|
38
|
+
readonly sdkVersion = "1.3.3";
|
|
39
39
|
constructor();
|
|
40
40
|
/**
|
|
41
41
|
* Set global base URL
|
package/dist/config.js
CHANGED
|
@@ -7,7 +7,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
7
7
|
exports.sdkConfig = exports.VersionCompatibilityError = exports.SDK_SIGNATURE = void 0;
|
|
8
8
|
// SDK 版本号(构建时自动从 package.json 更新)
|
|
9
9
|
// 此版本号会在运行 npm run build 时自动从 package.json 读取并更新
|
|
10
|
-
const SDK_VERSION = "1.3.
|
|
10
|
+
const SDK_VERSION = "1.3.3";
|
|
11
11
|
/**
|
|
12
12
|
* SDK 特征码 - 用于在构建后的 JS 文件中识别 SDK 版本
|
|
13
13
|
* 格式: AI_WORLD_SDK_V:版本号
|
|
@@ -15,7 +15,7 @@ const SDK_VERSION = "1.3.0";
|
|
|
15
15
|
*
|
|
16
16
|
* 注意: {VERSION} 占位符会在构建时被替换为实际版本号
|
|
17
17
|
*/
|
|
18
|
-
exports.SDK_SIGNATURE = "AI_WORLD_SDK_V:1.3.
|
|
18
|
+
exports.SDK_SIGNATURE = "AI_WORLD_SDK_V:1.3.3";
|
|
19
19
|
/**
|
|
20
20
|
* 版本兼容性错误
|
|
21
21
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
import { BaseChatModel, BaseChatModelParams } from "./base";
|
|
8
8
|
import { DoubaoImageGenerationClient, DoubaoImageSize, type DoubaoImageGenerationConfig, type DoubaoImageGenerationRequest, type DoubaoImageGenerationResponse } from "./doubao-image-generation";
|
|
9
9
|
import { GeminiImageGenerationClient, type GeminiImageGenerationConfig, type GeminiImageGenerationRequest, type GeminiImageGenerationResponse } from "./gemini-image-generation";
|
|
10
|
-
import { VideoGenerationClient, type VideoGenerationConfig, type VideoGenerationRequest, type ContentGenerationTaskID, type ContentGenerationTask } from "./video_generation";
|
|
10
|
+
import { VideoGenerationClient, type VideoGenerationConfig, type VideoGenerationRequest, type ContentGenerationTaskID, type ContentGenerationTask, VideoUnderstandingClient, type VideoUnderstandingConfig, type VideoUnderstandingRequest, type VideoUnderstandingResponse, type VideoUnderstandingStreamChunk, type VideoUnderstandingMessage, type VideoUnderstandingContent } from "./video_generation";
|
|
11
11
|
import { OpenAIVideoGenerationClient, type OpenAIVideoGenerationConfig, type OpenAIVideoGenerationRequest, type OpenAIVideoTaskResponse } from "./openai_video_generation";
|
|
12
12
|
import { DownloadClient, type DownloadConfig, type DownloadOptions, type StreamDownloadOptions } from "./download";
|
|
13
13
|
import { AuthClient, getCurrentUserInfo, type AuthConfig, type UserInfo } from "./auth";
|
|
@@ -25,6 +25,7 @@ export interface LangchainClientConfig {
|
|
|
25
25
|
export { DoubaoImageGenerationClient, type DoubaoImageGenerationConfig, type DoubaoImageGenerationRequest, type DoubaoImageGenerationResponse, type DoubaoImageSize, };
|
|
26
26
|
export { GeminiImageGenerationClient, type GeminiImageGenerationConfig, type GeminiImageGenerationRequest, type GeminiImageGenerationResponse, };
|
|
27
27
|
export { VideoGenerationClient, type VideoGenerationConfig, type VideoGenerationRequest, type ContentGenerationTaskID, type ContentGenerationTask, };
|
|
28
|
+
export { VideoUnderstandingClient, type VideoUnderstandingConfig, type VideoUnderstandingRequest, type VideoUnderstandingResponse, type VideoUnderstandingStreamChunk, type VideoUnderstandingMessage, type VideoUnderstandingContent, };
|
|
28
29
|
export { OpenAIVideoGenerationClient, type OpenAIVideoGenerationConfig, type OpenAIVideoGenerationRequest, type OpenAIVideoTaskResponse, };
|
|
29
30
|
export { DownloadClient, type DownloadConfig, type DownloadOptions, type StreamDownloadOptions, };
|
|
30
31
|
export { MinioStorageClient, type MinioStorageConfig, type UploadResponse, type ObjectInfo, type PresignedUrlResponse, type UploadOptions, type ListOptions, } from "./minio";
|
package/dist/index.js
CHANGED
|
@@ -20,7 +20,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
20
20
|
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
21
21
|
};
|
|
22
22
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
-
exports.SDK_SIGNATURE = exports.VersionCompatibilityError = exports.sdkConfig = exports.getCurrentUserInfo = exports.AuthClient = exports.AgentSkillClient = exports.DatabaseRequestClient = exports.ResourceClient = exports.MinioStorageClient = exports.DownloadClient = exports.OpenAIVideoGenerationClient = exports.VideoGenerationClient = exports.GeminiImageGenerationClient = exports.DoubaoImageGenerationClient = exports.ChatAnthropic = exports.ChatGoogleGenerativeAI = exports.ChatOpenAI = exports.BaseChatModel = exports.AIMessageChunk = exports.SystemMessage = exports.AIMessage = exports.HumanMessage = void 0;
|
|
23
|
+
exports.SDK_SIGNATURE = exports.VersionCompatibilityError = exports.sdkConfig = exports.getCurrentUserInfo = exports.AuthClient = exports.AgentSkillClient = exports.DatabaseRequestClient = exports.ResourceClient = exports.MinioStorageClient = exports.DownloadClient = exports.OpenAIVideoGenerationClient = exports.VideoUnderstandingClient = exports.VideoGenerationClient = exports.GeminiImageGenerationClient = exports.DoubaoImageGenerationClient = exports.ChatAnthropic = exports.ChatGoogleGenerativeAI = exports.ChatOpenAI = exports.BaseChatModel = exports.AIMessageChunk = exports.SystemMessage = exports.AIMessage = exports.HumanMessage = void 0;
|
|
24
24
|
exports.createChatModel = createChatModel;
|
|
25
25
|
const openai_1 = require("./chat_models/openai");
|
|
26
26
|
const google_1 = require("./chat_models/google");
|
|
@@ -30,6 +30,7 @@ const gemini_image_generation_1 = require("./gemini-image-generation");
|
|
|
30
30
|
Object.defineProperty(exports, "GeminiImageGenerationClient", { enumerable: true, get: function () { return gemini_image_generation_1.GeminiImageGenerationClient; } });
|
|
31
31
|
const video_generation_1 = require("./video_generation");
|
|
32
32
|
Object.defineProperty(exports, "VideoGenerationClient", { enumerable: true, get: function () { return video_generation_1.VideoGenerationClient; } });
|
|
33
|
+
Object.defineProperty(exports, "VideoUnderstandingClient", { enumerable: true, get: function () { return video_generation_1.VideoUnderstandingClient; } });
|
|
33
34
|
const openai_video_generation_1 = require("./openai_video_generation");
|
|
34
35
|
Object.defineProperty(exports, "OpenAIVideoGenerationClient", { enumerable: true, get: function () { return openai_video_generation_1.OpenAIVideoGenerationClient; } });
|
|
35
36
|
const download_1 = require("./download");
|
package/dist/llm.js
CHANGED
|
@@ -7,6 +7,7 @@ const google_1 = require("@ai-sdk/google");
|
|
|
7
7
|
const openai_1 = require("@ai-sdk/openai");
|
|
8
8
|
const config_1 = require("./config");
|
|
9
9
|
const ai_1 = require("ai");
|
|
10
|
+
const ai_sdk_provider_1 = require("@openrouter/ai-sdk-provider");
|
|
10
11
|
/**
|
|
11
12
|
* 根据端点类型创建 ai-sdk ProviderV3
|
|
12
13
|
* 所有请求会通过后端代理(/api/llm/{endpointType})转发到实际 API
|
|
@@ -27,6 +28,10 @@ function createProvider(provider, endpointType, pluginId) {
|
|
|
27
28
|
Authorization: `Bearer ${config_1.sdkConfig.getToken()}`,
|
|
28
29
|
},
|
|
29
30
|
};
|
|
31
|
+
if (provider === "openrouter") {
|
|
32
|
+
settings.baseURL = `${serverUrl}/api/llm/openrouter`;
|
|
33
|
+
return (0, ai_sdk_provider_1.createOpenRouter)(settings);
|
|
34
|
+
}
|
|
30
35
|
switch (endpointType) {
|
|
31
36
|
case "openai":
|
|
32
37
|
return (0, openai_1.createOpenAI)(settings);
|
|
@@ -7,10 +7,11 @@ export interface OpenAIVideoGenerationConfig {
|
|
|
7
7
|
token?: string;
|
|
8
8
|
headers?: Record<string, string>;
|
|
9
9
|
}
|
|
10
|
+
export type OpenAIVideoGenerationProvider = "shubiaobiao" | "api2img" | "aiping";
|
|
10
11
|
export interface OpenAIVideoGenerationRequest {
|
|
11
12
|
prompt: string;
|
|
12
13
|
model?: string;
|
|
13
|
-
provider?:
|
|
14
|
+
provider?: OpenAIVideoGenerationProvider;
|
|
14
15
|
seconds?: "4" | "8" | "12";
|
|
15
16
|
size?: "720x1280" | "1280x720" | "1024x1792" | "1792x1024";
|
|
16
17
|
input_reference?: string;
|
|
@@ -107,7 +108,7 @@ export declare class OpenAIVideoGenerationClient {
|
|
|
107
108
|
* }
|
|
108
109
|
* ```
|
|
109
110
|
*/
|
|
110
|
-
getTask(taskId: string, provider:
|
|
111
|
+
getTask(taskId: string, provider: OpenAIVideoGenerationProvider): Promise<OpenAIVideoTaskResponse>;
|
|
111
112
|
/**
|
|
112
113
|
* 轮询等待任务完成
|
|
113
114
|
* Poll and wait for task completion
|
|
@@ -125,7 +126,7 @@ export declare class OpenAIVideoGenerationClient {
|
|
|
125
126
|
* console.log('Video URL:', result.url);
|
|
126
127
|
* ```
|
|
127
128
|
*/
|
|
128
|
-
waitForCompletion(taskId: string, provider?:
|
|
129
|
+
waitForCompletion(taskId: string, provider?: OpenAIVideoGenerationProvider, options?: {
|
|
129
130
|
maxAttempts?: number;
|
|
130
131
|
interval?: number;
|
|
131
132
|
onProgress?: (status: OpenAIVideoTaskResponse) => void;
|
|
@@ -184,5 +185,5 @@ export declare class OpenAIVideoGenerationClient {
|
|
|
184
185
|
* const thumbnail = await client.downloadVideo('vid_abc123', 'api2img', 'thumbnail');
|
|
185
186
|
* ```
|
|
186
187
|
*/
|
|
187
|
-
downloadVideo(taskId: string, provider?:
|
|
188
|
+
downloadVideo(taskId: string, provider?: OpenAIVideoGenerationProvider, variant?: "video" | "thumbnail"): Promise<Blob>;
|
|
188
189
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* 模型提供商
|
|
3
3
|
*/
|
|
4
|
-
export type AIModelProvider = "api2img" | "aihubmix" | "doubao" | "gemini" | "shubiaobiao" | "anthropic";
|
|
4
|
+
export type AIModelProvider = "api2img" | "aihubmix" | "doubao" | "gemini" | "shubiaobiao" | "anthropic" | "aiping" | "openrouter";
|
|
5
5
|
/**
|
|
6
6
|
* 模型端点类型
|
|
7
7
|
* - openai: OpenAI 兼容 API(/v1/chat/completions 等)
|
package/dist/provider_config.js
CHANGED
|
@@ -5,10 +5,12 @@ exports.getProviderConfig = getProviderConfig;
|
|
|
5
5
|
exports.PROVIDER_CONFIGS = {
|
|
6
6
|
shubiaobiao: { provider: "shubiaobiao", modelType: "openai" },
|
|
7
7
|
api2img: { provider: "api2img", modelType: "openai" },
|
|
8
|
+
aiping: { provider: "aiping", modelType: "openai" },
|
|
8
9
|
aihubmix: { provider: "aihubmix", modelType: "openai" },
|
|
9
10
|
doubao: { provider: "doubao", modelType: "openai" },
|
|
10
11
|
gemini: { provider: "gemini", modelType: "gemini" },
|
|
11
12
|
anthropic: { provider: "anthropic", modelType: "anthropic" },
|
|
13
|
+
openrouter: { provider: "openrouter", modelType: "openai" },
|
|
12
14
|
};
|
|
13
15
|
function getProviderConfig(provider) {
|
|
14
16
|
return exports.PROVIDER_CONFIGS[provider];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Video Generation Client
|
|
3
|
-
*
|
|
2
|
+
* Video Generation & Understanding Client
|
|
3
|
+
* 视频生成 & 视频理解客户端
|
|
4
4
|
*/
|
|
5
5
|
export interface VideoGenerationConfig {
|
|
6
6
|
baseUrl?: string;
|
|
@@ -88,3 +88,150 @@ export declare class VideoGenerationClient {
|
|
|
88
88
|
timeout?: number;
|
|
89
89
|
}): Promise<ContentGenerationTask>;
|
|
90
90
|
}
|
|
91
|
+
export interface VideoUnderstandingConfig {
|
|
92
|
+
baseUrl?: string;
|
|
93
|
+
token?: string;
|
|
94
|
+
headers?: Record<string, string>;
|
|
95
|
+
}
|
|
96
|
+
export interface VideoUnderstandingVideoURL {
|
|
97
|
+
url: string;
|
|
98
|
+
fps?: number;
|
|
99
|
+
}
|
|
100
|
+
export interface VideoUnderstandingContentText {
|
|
101
|
+
type: "text";
|
|
102
|
+
text: string;
|
|
103
|
+
}
|
|
104
|
+
export interface VideoUnderstandingContentVideo {
|
|
105
|
+
type: "video_url";
|
|
106
|
+
video_url: VideoUnderstandingVideoURL;
|
|
107
|
+
}
|
|
108
|
+
export interface VideoUnderstandingContentImage {
|
|
109
|
+
type: "image_url";
|
|
110
|
+
image_url: {
|
|
111
|
+
url: string;
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
export type VideoUnderstandingContent = VideoUnderstandingContentText | VideoUnderstandingContentVideo | VideoUnderstandingContentImage;
|
|
115
|
+
export interface VideoUnderstandingMessage {
|
|
116
|
+
role: "system" | "user" | "assistant";
|
|
117
|
+
content: string | VideoUnderstandingContent[];
|
|
118
|
+
}
|
|
119
|
+
export interface VideoUnderstandingRequest {
|
|
120
|
+
model?: string;
|
|
121
|
+
/** 视频 URL(简化参数,与 messages 二选一) */
|
|
122
|
+
video_url?: string;
|
|
123
|
+
/** 文本提示词(配合 video_url 使用) */
|
|
124
|
+
prompt?: string;
|
|
125
|
+
/** 视频采样帧率 */
|
|
126
|
+
fps?: number;
|
|
127
|
+
/** 完整消息列表(高级用法)。提供时忽略 video_url/prompt/fps */
|
|
128
|
+
messages?: VideoUnderstandingMessage[];
|
|
129
|
+
/** 是否流式输出 */
|
|
130
|
+
stream?: boolean;
|
|
131
|
+
/** 最大输出 token 数 */
|
|
132
|
+
max_tokens?: number;
|
|
133
|
+
/** 采样温度 */
|
|
134
|
+
temperature?: number;
|
|
135
|
+
/** 核采样参数 */
|
|
136
|
+
top_p?: number;
|
|
137
|
+
/** 用户标识 */
|
|
138
|
+
user?: string;
|
|
139
|
+
}
|
|
140
|
+
/** 视频理解使用情况 */
|
|
141
|
+
export interface VideoUnderstandingUsage {
|
|
142
|
+
/** 提示 token 数 */
|
|
143
|
+
prompt_tokens: number;
|
|
144
|
+
/** 完成 token 数 */
|
|
145
|
+
completion_tokens: number;
|
|
146
|
+
/** 总 token 数 */
|
|
147
|
+
total_tokens: number;
|
|
148
|
+
}
|
|
149
|
+
/** 视频理解选择 */
|
|
150
|
+
export interface VideoUnderstandingChoice {
|
|
151
|
+
/** 索引 */
|
|
152
|
+
index: number;
|
|
153
|
+
/** 消息 */
|
|
154
|
+
message: {
|
|
155
|
+
/** 角色 */
|
|
156
|
+
role: string;
|
|
157
|
+
/** 内容 */
|
|
158
|
+
content: string;
|
|
159
|
+
};
|
|
160
|
+
/** 完成原因 */
|
|
161
|
+
finish_reason: string | null;
|
|
162
|
+
}
|
|
163
|
+
export interface VideoUnderstandingResponse {
|
|
164
|
+
/** 任务 ID */
|
|
165
|
+
id: string;
|
|
166
|
+
/** 对象 */
|
|
167
|
+
object: string;
|
|
168
|
+
/** 模型 */
|
|
169
|
+
model: string;
|
|
170
|
+
/** 选择 */
|
|
171
|
+
choices: VideoUnderstandingChoice[];
|
|
172
|
+
/** 使用情况 */
|
|
173
|
+
usage?: VideoUnderstandingUsage;
|
|
174
|
+
}
|
|
175
|
+
export interface VideoUnderstandingStreamDelta {
|
|
176
|
+
/** 角色 */
|
|
177
|
+
role?: string;
|
|
178
|
+
/** 内容 */
|
|
179
|
+
content?: string;
|
|
180
|
+
}
|
|
181
|
+
export interface VideoUnderstandingStreamChoice {
|
|
182
|
+
/** 索引 */
|
|
183
|
+
index: number;
|
|
184
|
+
/** 增量 */
|
|
185
|
+
delta: VideoUnderstandingStreamDelta;
|
|
186
|
+
/** 完成原因 */
|
|
187
|
+
finish_reason: string | null;
|
|
188
|
+
}
|
|
189
|
+
export interface VideoUnderstandingStreamChunk {
|
|
190
|
+
/** 任务 ID */
|
|
191
|
+
id: string;
|
|
192
|
+
/** 对象 */
|
|
193
|
+
object: string;
|
|
194
|
+
/** 模型 */
|
|
195
|
+
model: string;
|
|
196
|
+
/** 选择 */
|
|
197
|
+
choices: VideoUnderstandingStreamChoice[];
|
|
198
|
+
}
|
|
199
|
+
export declare class VideoUnderstandingClient {
|
|
200
|
+
private headers;
|
|
201
|
+
constructor(config?: VideoUnderstandingConfig);
|
|
202
|
+
/**
|
|
203
|
+
* Analyze a video (non-streaming)
|
|
204
|
+
* 视频理解(非流式)
|
|
205
|
+
*/
|
|
206
|
+
understand(request: VideoUnderstandingRequest): Promise<VideoUnderstandingResponse>;
|
|
207
|
+
/**
|
|
208
|
+
* Analyze a video with streaming response
|
|
209
|
+
* 视频理解(流式)
|
|
210
|
+
*
|
|
211
|
+
* @returns AsyncGenerator yielding content chunks
|
|
212
|
+
*/
|
|
213
|
+
understandStream(request: VideoUnderstandingRequest): AsyncGenerator<VideoUnderstandingStreamChunk, void, unknown>;
|
|
214
|
+
/**
|
|
215
|
+
* Convenience: analyze video and return full text content
|
|
216
|
+
* 便捷方法:分析视频并返回完整文本
|
|
217
|
+
*/
|
|
218
|
+
analyzeVideo(videoUrl: string, options?: {
|
|
219
|
+
prompt?: string;
|
|
220
|
+
fps?: number;
|
|
221
|
+
model?: string;
|
|
222
|
+
max_tokens?: number;
|
|
223
|
+
}): Promise<string>;
|
|
224
|
+
/**
|
|
225
|
+
* Convenience: analyze video with streaming, collecting full text
|
|
226
|
+
* 便捷方法:流式分析视频,收集完整文本
|
|
227
|
+
*
|
|
228
|
+
* @param onChunk optional callback for each text chunk
|
|
229
|
+
*/
|
|
230
|
+
analyzeVideoStream(videoUrl: string, options?: {
|
|
231
|
+
prompt?: string;
|
|
232
|
+
fps?: number;
|
|
233
|
+
model?: string;
|
|
234
|
+
max_tokens?: number;
|
|
235
|
+
onChunk?: (text: string) => void;
|
|
236
|
+
}): Promise<string>;
|
|
237
|
+
}
|
package/dist/video_generation.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
/**
|
|
3
|
-
* Video Generation Client
|
|
4
|
-
*
|
|
3
|
+
* Video Generation & Understanding Client
|
|
4
|
+
* 视频生成 & 视频理解客户端
|
|
5
5
|
*/
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.VideoGenerationClient = void 0;
|
|
7
|
+
exports.VideoUnderstandingClient = exports.VideoGenerationClient = void 0;
|
|
8
8
|
const config_1 = require("./config");
|
|
9
9
|
const log_1 = require("./log");
|
|
10
10
|
class VideoGenerationClient {
|
|
@@ -92,3 +92,138 @@ class VideoGenerationClient {
|
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
94
|
exports.VideoGenerationClient = VideoGenerationClient;
|
|
95
|
+
class VideoUnderstandingClient {
|
|
96
|
+
constructor(config) {
|
|
97
|
+
// 合并全局 headers 和配置 headers
|
|
98
|
+
const globalHeaders = config_1.sdkConfig.getHeaders();
|
|
99
|
+
this.headers = {
|
|
100
|
+
"Content-Type": "application/json",
|
|
101
|
+
"Authorization": `Bearer ${config_1.sdkConfig.getToken()}`,
|
|
102
|
+
"X-Base-Url": config?.baseUrl || "",
|
|
103
|
+
...globalHeaders,
|
|
104
|
+
...config?.headers,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Analyze a video (non-streaming)
|
|
109
|
+
* 视频理解(非流式)
|
|
110
|
+
*/
|
|
111
|
+
async understand(request) {
|
|
112
|
+
config_1.sdkConfig.ensureVersionCompatible();
|
|
113
|
+
const url = `${config_1.sdkConfig.getServerUrl()}/api/video-proxy/understand`;
|
|
114
|
+
const body = { ...request, stream: false };
|
|
115
|
+
(0, log_1.logRequest)("POST", url, this.headers, body);
|
|
116
|
+
const response = await fetch(url, {
|
|
117
|
+
method: "POST",
|
|
118
|
+
headers: this.headers,
|
|
119
|
+
body: JSON.stringify(body),
|
|
120
|
+
});
|
|
121
|
+
if (!response.ok) {
|
|
122
|
+
const errorText = await response.text();
|
|
123
|
+
(0, log_1.logResponse)(response.status, response.statusText, response.headers, errorText);
|
|
124
|
+
throw new Error(`Video understanding API error: ${response.status} ${errorText}`);
|
|
125
|
+
}
|
|
126
|
+
const data = (await response.json());
|
|
127
|
+
(0, log_1.logResponse)(response.status, response.statusText, response.headers, data);
|
|
128
|
+
return data;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Analyze a video with streaming response
|
|
132
|
+
* 视频理解(流式)
|
|
133
|
+
*
|
|
134
|
+
* @returns AsyncGenerator yielding content chunks
|
|
135
|
+
*/
|
|
136
|
+
async *understandStream(request) {
|
|
137
|
+
config_1.sdkConfig.ensureVersionCompatible();
|
|
138
|
+
const url = `${config_1.sdkConfig.getServerUrl()}/api/video-proxy/understand`;
|
|
139
|
+
const body = { ...request, stream: true };
|
|
140
|
+
(0, log_1.logRequest)("POST", url, this.headers, body);
|
|
141
|
+
const response = await fetch(url, {
|
|
142
|
+
method: "POST",
|
|
143
|
+
headers: this.headers,
|
|
144
|
+
body: JSON.stringify(body),
|
|
145
|
+
});
|
|
146
|
+
if (!response.ok) {
|
|
147
|
+
const errorText = await response.text();
|
|
148
|
+
(0, log_1.logResponse)(response.status, response.statusText, response.headers, errorText);
|
|
149
|
+
throw new Error(`Video understanding stream API error: ${response.status} ${errorText}`);
|
|
150
|
+
}
|
|
151
|
+
const reader = response.body?.getReader();
|
|
152
|
+
if (!reader) {
|
|
153
|
+
throw new Error("Response body is not readable");
|
|
154
|
+
}
|
|
155
|
+
const decoder = new TextDecoder();
|
|
156
|
+
let buffer = "";
|
|
157
|
+
try {
|
|
158
|
+
while (true) {
|
|
159
|
+
const { done, value } = await reader.read();
|
|
160
|
+
if (done)
|
|
161
|
+
break;
|
|
162
|
+
buffer += decoder.decode(value, { stream: true });
|
|
163
|
+
const lines = buffer.split("\n");
|
|
164
|
+
buffer = lines.pop() || "";
|
|
165
|
+
for (const line of lines) {
|
|
166
|
+
const trimmed = line.trim();
|
|
167
|
+
if (!trimmed || !trimmed.startsWith("data: "))
|
|
168
|
+
continue;
|
|
169
|
+
const data = trimmed.slice(6);
|
|
170
|
+
if (data === "[DONE]")
|
|
171
|
+
return;
|
|
172
|
+
try {
|
|
173
|
+
const chunk = JSON.parse(data);
|
|
174
|
+
if (chunk.error) {
|
|
175
|
+
throw new Error(chunk.error.message);
|
|
176
|
+
}
|
|
177
|
+
yield chunk;
|
|
178
|
+
}
|
|
179
|
+
catch (e) {
|
|
180
|
+
if (e instanceof SyntaxError)
|
|
181
|
+
continue;
|
|
182
|
+
throw e;
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
finally {
|
|
188
|
+
reader.releaseLock();
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Convenience: analyze video and return full text content
|
|
193
|
+
* 便捷方法:分析视频并返回完整文本
|
|
194
|
+
*/
|
|
195
|
+
async analyzeVideo(videoUrl, options) {
|
|
196
|
+
const response = await this.understand({
|
|
197
|
+
video_url: videoUrl,
|
|
198
|
+
prompt: options?.prompt || "请详细描述这个视频的内容",
|
|
199
|
+
fps: options?.fps,
|
|
200
|
+
model: options?.model,
|
|
201
|
+
max_tokens: options?.max_tokens,
|
|
202
|
+
});
|
|
203
|
+
return response.choices?.[0]?.message?.content || "";
|
|
204
|
+
}
|
|
205
|
+
/**
|
|
206
|
+
* Convenience: analyze video with streaming, collecting full text
|
|
207
|
+
* 便捷方法:流式分析视频,收集完整文本
|
|
208
|
+
*
|
|
209
|
+
* @param onChunk optional callback for each text chunk
|
|
210
|
+
*/
|
|
211
|
+
async analyzeVideoStream(videoUrl, options) {
|
|
212
|
+
let fullText = "";
|
|
213
|
+
for await (const chunk of this.understandStream({
|
|
214
|
+
video_url: videoUrl,
|
|
215
|
+
prompt: options?.prompt || "请详细描述这个视频的内容",
|
|
216
|
+
fps: options?.fps,
|
|
217
|
+
model: options?.model,
|
|
218
|
+
max_tokens: options?.max_tokens,
|
|
219
|
+
})) {
|
|
220
|
+
const content = chunk.choices?.[0]?.delta?.content;
|
|
221
|
+
if (content) {
|
|
222
|
+
fullText += content;
|
|
223
|
+
options?.onChunk?.(content);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
return fullText;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
exports.VideoUnderstandingClient = VideoUnderstandingClient;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ai-world-sdk",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.3",
|
|
4
4
|
"description": "TypeScript SDK for AI World Platform - Chat Models, Image Generation, and Video Generation",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -78,6 +78,7 @@
|
|
|
78
78
|
"@ai-sdk/anthropic": "^3.0.43",
|
|
79
79
|
"@ai-sdk/google": "^3.0.29",
|
|
80
80
|
"@ai-sdk/openai": "^3.0.28",
|
|
81
|
+
"@openrouter/ai-sdk-provider": "^2.3.1",
|
|
81
82
|
"ai": "^6.0.85"
|
|
82
83
|
}
|
|
83
84
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: ai-world-sdk
|
|
3
|
-
description: Use when initializing ai-world-sdk or calling AI models in ai-world projects. Covers sdkConfig initialization, createProvider with Vercel AI SDK (generateText, streamText, generateImage), Doubao image/video generation, MinIO object storage (MinioStorageClient), resource management with ACL (ResourceClient), database requests (DatabaseRequestClient), agent skills management (AgentSkillClient), and VSCode extension login (initAIWorld). Triggers on ai-world-sdk, createProvider, sdkConfig, generateText, streamText, generateImage, doubao, MinioStorageClient, minio, ResourceClient, resource management, access control, file sharing, DatabaseRequestClient, database request, table creation, AgentSkillClient, agent skill, vscode extension, initAIWorld, or any AI model integration.
|
|
3
|
+
description: Use when initializing ai-world-sdk or calling AI models in ai-world projects. Covers sdkConfig initialization, createProvider with Vercel AI SDK (generateText, streamText, generateImage), Doubao image/video generation/understanding, MinIO object storage (MinioStorageClient), resource management with ACL (ResourceClient), database requests (DatabaseRequestClient), agent skills management (AgentSkillClient), and VSCode extension login (initAIWorld). Triggers on ai-world-sdk, createProvider, sdkConfig, generateText, streamText, generateImage, doubao, video understanding, VideoUnderstandingClient, MinioStorageClient, minio, ResourceClient, resource management, access control, file sharing, DatabaseRequestClient, database request, table creation, AgentSkillClient, agent skill, vscode extension, initAIWorld, or any AI model integration.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# AI World SDK
|
|
@@ -12,7 +12,7 @@ ai-world-sdk 是 AI World 平台的 TypeScript SDK,通过 `createProvider` 创
|
|
|
12
12
|
|
|
13
13
|
## When to Use
|
|
14
14
|
|
|
15
|
-
- 在 ai-world 插件中调用 AI
|
|
15
|
+
- 在 ai-world 插件中调用 AI 模型(文本、图像、视频生成/理解)
|
|
16
16
|
- 需要初始化 ai-world-sdk 配置
|
|
17
17
|
- 使用 `createProvider` 调用 Vercel AI SDK
|
|
18
18
|
- 使用 Doubao 豆包图像/视频生成
|
|
@@ -117,7 +117,10 @@ sdkConfig.setToken('your-jwt-token');
|
|
|
117
117
|
sdkConfig.setPluginId('my-plugin');
|
|
118
118
|
```
|
|
119
119
|
|
|
120
|
-
|
|
120
|
+
也可通过环境变量自动初始化:
|
|
121
|
+
- `AI_WORLD_BASE_URL` — 服务端地址,插件 JS 后端启动时由平台自动注入
|
|
122
|
+
- `PLUGIN_ID` — 插件 ID
|
|
123
|
+
- `DEBUG_TOKEN` — 调试用 JWT Token
|
|
121
124
|
|
|
122
125
|
## 功能模块
|
|
123
126
|
|
|
@@ -126,9 +129,35 @@ sdkConfig.setPluginId('my-plugin');
|
|
|
126
129
|
### Provider 与模型 → `docs/provider-and-models.md`
|
|
127
130
|
|
|
128
131
|
- `createProvider(provider, endpointType, pluginId)` 创建 Vercel AI SDK Provider
|
|
129
|
-
- Provider 对照表:`api2img`(推荐) / `gemini` / `aihubmix` / `shubiaobiao`
|
|
132
|
+
- Provider 对照表:`api2img`(推荐) / `gemini` / `aihubmix` / `shubiaobiao` / `aiping` / `openrouter`
|
|
133
|
+
- **OpenRouter**:使用专用代理端点 `/api/llm/openrouter`,模型 ID 格式为 `provider/model`(如 `openai/gpt-4o-mini`、`anthropic/claude-sonnet-4-20250514`、`google/gemini-2.5-flash-preview`)
|
|
130
134
|
- 常用模型列表和 AI SDK 函数速查
|
|
131
135
|
|
|
136
|
+
#### OpenRouter 快速示例
|
|
137
|
+
|
|
138
|
+
```typescript
|
|
139
|
+
import { createProvider } from 'ai-world-sdk';
|
|
140
|
+
import { generateText, streamText } from 'ai';
|
|
141
|
+
|
|
142
|
+
// OpenRouter(endpointType 传 'openai',SDK 内部自动使用 createOpenRouter)
|
|
143
|
+
const provider = createProvider('openrouter', 'openai', 'my-plugin');
|
|
144
|
+
|
|
145
|
+
// 非流式
|
|
146
|
+
const result = await generateText({
|
|
147
|
+
model: provider.languageModel('openai/gpt-4o-mini'),
|
|
148
|
+
prompt: '你好',
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
// 流式
|
|
152
|
+
const stream = streamText({
|
|
153
|
+
model: provider.languageModel('anthropic/claude-sonnet-4-20250514'),
|
|
154
|
+
prompt: '请介绍人工智能',
|
|
155
|
+
});
|
|
156
|
+
for await (const chunk of stream.textStream) {
|
|
157
|
+
process.stdout.write(chunk);
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
132
161
|
### 文本生成 → `docs/text-generation.md`
|
|
133
162
|
|
|
134
163
|
- `generateText` / `streamText` / `generateObject` / `streamObject`
|
|
@@ -139,9 +168,10 @@ sdkConfig.setPluginId('my-plugin');
|
|
|
139
168
|
- `DoubaoImageGenerationClient`(豆包 Seedream)
|
|
140
169
|
- `GeminiImageGenerationClient`
|
|
141
170
|
|
|
142
|
-
### 视频生成 → `docs/video-generation.md`
|
|
171
|
+
### 视频生成 & 视频理解 → `docs/video-generation.md`
|
|
143
172
|
|
|
144
173
|
- `VideoGenerationClient`(豆包 Seedance)
|
|
174
|
+
- `VideoUnderstandingClient`(豆包视频理解,基于 Chat Completions API)
|
|
145
175
|
- `OpenAIVideoGenerationClient`(Sora)
|
|
146
176
|
|
|
147
177
|
### MinIO 对象存储 → `docs/minio-storage.md`
|
|
@@ -10,17 +10,22 @@
|
|
|
10
10
|
| `shubiaobiao` | `openai` | 数标标 |
|
|
11
11
|
| `shubiaobiao` | `gemini` | 数标标 Gemini |
|
|
12
12
|
| `shubiaobiao` | `anthropic` | 数标标 Claude |
|
|
13
|
+
| `aiping` | `openai` | 平音 |
|
|
14
|
+
| `aiping` | `gemini` | 平音 Gemini |
|
|
15
|
+
| `aiping` | `anthropic` | 平音 Claude |
|
|
13
16
|
| `gemini` | `gemini` | Google 原生,仅限 Gemini 系列模型 |
|
|
17
|
+
| `openrouter` | `openai` | OpenRouter 聚合服务,SDK 内部自动使用 `createOpenRouter` 和专用代理端点 `/api/llm/openrouter`。模型 ID 格式为 `provider/model`(如 `openai/gpt-4o-mini`、`anthropic/claude-sonnet-4-20250514`) |
|
|
14
18
|
|
|
15
19
|
## EndpointType 与模型对应关系
|
|
16
20
|
|
|
17
21
|
| EndpointType | 适用模型 | 说明 |
|
|
18
22
|
|--------------|----------|------|
|
|
19
23
|
| `gemini` | Google Gemini | 必须使用 Google 的 Gemini 模型(如 `gemini-2.5-flash`、`gemini-2.5-pro`) |
|
|
20
|
-
| `anthropic` | Claude | 必须使用 Anthropic 的 Claude 模型(如 `claude-sonnet-4-5`、`claude-3-5-sonnet`);**仅 api2img、shubiaobiao 支持此 endpoint** |
|
|
24
|
+
| `anthropic` | Claude | 必须使用 Anthropic 的 Claude 模型(如 `claude-sonnet-4-5`、`claude-3-5-sonnet`);**仅 api2img、shubiaobiao、aiping 支持此 endpoint** |
|
|
21
25
|
| `openai` | OpenAI 兼容 | 模型兼容 OpenAI 格式,可包括 GPT、以及经聚合的 Gemini/Claude 等(视 provider 能力) |
|
|
26
|
+
| `openai` | OpenRouter 兼容 | 当 provider 为 `openrouter` 时,`endpointType` 传 `openai`,SDK 内部自动切换到 `createOpenRouter` 和专用代理端点 |
|
|
22
27
|
|
|
23
|
-
规则:**anthropic 不是 provider**,仅 **api2img**、**shubiaobiao** 支持 EndpointType 为 `anthropic`(调用 Claude);`gemini` provider 用 `gemini` endpoint
|
|
28
|
+
规则:**anthropic 不是 provider**,仅 **api2img**、**shubiaobiao**、**aiping** 支持 EndpointType 为 `anthropic`(调用 Claude);`gemini` provider 用 `gemini` endpoint;`openrouter` provider 的 `endpointType` 传 `openai`,SDK 内部会自动使用 `@openrouter/ai-sdk-provider` 的 `createOpenRouter` 并路由到专用代理 `/api/llm/openrouter`,其余按上表组合。
|
|
24
29
|
|
|
25
30
|
> `doubao` 不通过 `createProvider` 使用,豆包有专用客户端(见 image-generation.md / video-generation.md)。
|
|
26
31
|
|
|
@@ -40,7 +45,7 @@ const model = provider.languageModel('gpt-4o-mini');
|
|
|
40
45
|
// Google Gemini(EndpointType = gemini,仅 Google 模型)
|
|
41
46
|
createProvider('gemini', 'gemini', 'my-plugin').languageModel('gemini-2.5-flash');
|
|
42
47
|
|
|
43
|
-
// Anthropic Claude(仅 api2img / shubiaobiao 支持 endpointType = anthropic,仅 Claude 模型)
|
|
48
|
+
// Anthropic Claude(仅 api2img / shubiaobiao / aiping 支持 endpointType = anthropic,仅 Claude 模型)
|
|
44
49
|
createProvider('api2img', 'anthropic', 'my-plugin').languageModel('claude-sonnet-4-5');
|
|
45
50
|
|
|
46
51
|
// OpenAI 兼容(EndpointType = openai,模型兼容 OpenAI 格式;api2img 可聚合多模型)
|
|
@@ -48,6 +53,13 @@ const p = createProvider('api2img', 'openai', 'my-plugin');
|
|
|
48
53
|
p.languageModel('gpt-4o-mini');
|
|
49
54
|
p.languageModel('gemini-2.5-flash');
|
|
50
55
|
p.languageModel('claude-sonnet-4-5');
|
|
56
|
+
|
|
57
|
+
// OpenRouter(endpointType 传 'openai',SDK 内部自动切换到 createOpenRouter + 专用代理)
|
|
58
|
+
// 模型 ID 必须使用 provider/model 格式
|
|
59
|
+
const or = createProvider('openrouter', 'openai', 'my-plugin');
|
|
60
|
+
or.languageModel('openai/gpt-4o-mini');
|
|
61
|
+
or.languageModel('anthropic/claude-sonnet-4-20250514');
|
|
62
|
+
or.languageModel('google/gemini-2.5-flash-preview');
|
|
51
63
|
```
|
|
52
64
|
|
|
53
65
|
### 检测模型可用性
|
|
@@ -63,8 +75,11 @@ const ok = await checkModel('api2img', 'openai', 'gpt-4o-mini', 'my-plugin');
|
|
|
63
75
|
|------|------|----------|-------------|
|
|
64
76
|
| `gpt-4o-mini` / `gpt-4o` / `gpt-5.1` | 文本 | `api2img` | `openai`(OpenAI 兼容) |
|
|
65
77
|
| `gemini-2.5-flash` / `gemini-2.5-pro` | 文本 | `gemini` | `gemini`(仅 Google) |
|
|
66
|
-
| `claude-sonnet-4-
|
|
67
|
-
| `dall-e-3` / `gpt-image-1` | 图像 | `api2img` | `openai` |
|
|
78
|
+
| `claude-sonnet-4-6` / `claude-opus-4-6` | 文本 | `api2img`、`shubiaobiao` 或 `aiping` | `anthropic`(仅 Claude) |
|
|
79
|
+
| `dall-e-3` / `gpt-image-1` | 图像 | `api2img`、`shubiaobiao` 或 `aiping` | `openai` |
|
|
80
|
+
| `openai/gpt-4o-mini` / `openai/gpt-4o` | 文本 | `openrouter` | `openai`(SDK 自动处理) |
|
|
81
|
+
| `anthropic/claude-sonnet-4-20250514` | 文本 | `openrouter` | `openai`(SDK 自动处理) |
|
|
82
|
+
| `google/gemini-2.5-flash-preview` | 文本 | `openrouter` | `openai`(SDK 自动处理) |
|
|
68
83
|
| `doubao-seedream-4-5-251128` | 图像 | — | 专用客户端 |
|
|
69
84
|
|
|
70
85
|
## AI SDK 函数速查
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# 视频生成
|
|
1
|
+
# 视频生成 & 视频理解
|
|
2
2
|
|
|
3
3
|
## 豆包视频生成(Seedance)
|
|
4
4
|
|
|
@@ -26,6 +26,109 @@ if (result.status === 'succeeded') {
|
|
|
26
26
|
}
|
|
27
27
|
```
|
|
28
28
|
|
|
29
|
+
## 豆包视频理解
|
|
30
|
+
|
|
31
|
+
使用 `VideoUnderstandingClient` 分析视频内容。基于 Chat Completions API,支持传入视频 URL 进行理解分析。
|
|
32
|
+
|
|
33
|
+
参考文档: https://www.volcengine.com/docs/82379/1895586
|
|
34
|
+
|
|
35
|
+
### 支持的模型
|
|
36
|
+
|
|
37
|
+
| 模型 | 说明 |
|
|
38
|
+
|------|------|
|
|
39
|
+
| `doubao-seed-2-0-pro-260215` | 专业级视频理解 |
|
|
40
|
+
| `doubao-seed-2-0-lite-260215` | 轻量级视频理解 |
|
|
41
|
+
| `doubao-seed-2-0-mini-260215` | mini级视频理解 |
|
|
42
|
+
| `doubao-seed-2-0-code-preview-260215` | 代码预览视频理解 |
|
|
43
|
+
|
|
44
|
+
### 简化用法(推荐)
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
import { VideoUnderstandingClient } from 'ai-world-sdk';
|
|
48
|
+
|
|
49
|
+
const client = new VideoUnderstandingClient({});
|
|
50
|
+
|
|
51
|
+
// 一行代码分析视频
|
|
52
|
+
const description = await client.analyzeVideo(
|
|
53
|
+
'https://example.com/video.mp4',
|
|
54
|
+
{ prompt: '请详细描述这个视频的内容' }
|
|
55
|
+
);
|
|
56
|
+
console.log(description);
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
### 非流式请求
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
const response = await client.understand({
|
|
63
|
+
video_url: 'https://example.com/video.mp4',
|
|
64
|
+
prompt: '这个视频讲了什么?',
|
|
65
|
+
model: 'doubao-seed-2-0-pro-260215',
|
|
66
|
+
fps: 1, // 可选,视频采样帧率,默认为1秒,即每秒从视频中抽取一帧图像
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
console.log(response.choices[0].message.content);
|
|
70
|
+
console.log(response.usage); // { prompt_tokens, completion_tokens, total_tokens }
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### 流式请求
|
|
74
|
+
|
|
75
|
+
```typescript
|
|
76
|
+
// 方式1: 使用便捷方法
|
|
77
|
+
const text = await client.analyzeVideoStream(
|
|
78
|
+
'https://example.com/video.mp4',
|
|
79
|
+
{
|
|
80
|
+
prompt: '描述视频内容',
|
|
81
|
+
onChunk: (chunk) => process.stdout.write(chunk),
|
|
82
|
+
}
|
|
83
|
+
);
|
|
84
|
+
|
|
85
|
+
// 方式2: 使用 AsyncGenerator
|
|
86
|
+
for await (const chunk of client.understandStream({
|
|
87
|
+
video_url: 'https://example.com/video.mp4',
|
|
88
|
+
prompt: '描述视频内容',
|
|
89
|
+
})) {
|
|
90
|
+
const content = chunk.choices?.[0]?.delta?.content;
|
|
91
|
+
if (content) process.stdout.write(content);
|
|
92
|
+
}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### 高级用法(完整 messages)
|
|
96
|
+
|
|
97
|
+
```typescript
|
|
98
|
+
const response = await client.understand({
|
|
99
|
+
model: 'doubao-seed-2-0-pro-260215',
|
|
100
|
+
messages: [
|
|
101
|
+
{ role: 'system', content: '你是一个专业的视频分析助手' },
|
|
102
|
+
{
|
|
103
|
+
role: 'user',
|
|
104
|
+
content: [
|
|
105
|
+
{ type: 'text', text: '请分析这个视频中的关键事件' },
|
|
106
|
+
{
|
|
107
|
+
type: 'video_url',
|
|
108
|
+
video_url: {
|
|
109
|
+
url: 'https://example.com/video.mp4',
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
],
|
|
113
|
+
},
|
|
114
|
+
],
|
|
115
|
+
});
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### 参数说明
|
|
119
|
+
|
|
120
|
+
| 参数 | 类型 | 必填 | 说明 |
|
|
121
|
+
|------|------|------|------|
|
|
122
|
+
| `video_url` | `string` | 与 messages 二选一 | 视频 URL |
|
|
123
|
+
| `prompt` | `string` | 否 | 提示词(默认: "请详细描述这个视频的内容") |
|
|
124
|
+
| `fps` | `number` | 否 | 视频采样帧率,较高值提取更多帧但消耗更多 token |
|
|
125
|
+
| `model` | `string` | 否 | 模型名称(默认: doubao-seed-2-0-pro-260215) |
|
|
126
|
+
| `messages` | `VideoUnderstandingMessage[]` | 与 video_url 二选一 | 完整消息列表(高级用法) |
|
|
127
|
+
| `stream` | `boolean` | 否 | 是否流式输出(默认: false) |
|
|
128
|
+
| `max_tokens` | `number` | 否 | 最大输出 token 数(默认: 4096) |
|
|
129
|
+
| `temperature` | `number` | 否 | 采样温度 0.0-2.0 |
|
|
130
|
+
| `top_p` | `number` | 否 | 核采样参数 0.0-1.0 |
|
|
131
|
+
|
|
29
132
|
## OpenAI 视频生成(Sora)
|
|
30
133
|
|
|
31
134
|
```typescript
|