ai-world-sdk 1.3.2 → 1.3.5

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.
@@ -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.2",
3
+ "version": "1.3.5",
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",
@@ -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), versioned resource management (VersionedResourceClient), 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, VersionedResourceClient, versioned resource, version management, AgentSkillClient, agent skill, vscode extension, initAIWorld, or any AI model integration.
4
4
  ---
5
5
 
6
6
  # AI World SDK
@@ -12,13 +12,13 @@ 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 豆包图像/视频生成
19
19
  - 使用 MinIO 对象存储(文件上传/下载/管理)
20
20
  - 使用资源管理系统(权限控制: private/specific_users/public)
21
- - 提交数据库建表/迁移请求
21
+ - 使用版本化资源管理(资源名称+版本号管理)
22
22
  - 管理 Agent Skills(上传/下载/删除/列表)
23
23
  - **开发 VSCode 扩展**时集成 AI World 登录和 SDK 功能
24
24
 
@@ -117,7 +117,10 @@ sdkConfig.setToken('your-jwt-token');
117
117
  sdkConfig.setPluginId('my-plugin');
118
118
  ```
119
119
 
120
- 也可通过环境变量 `DEBUG_TOKEN`、`PLUGIN_ID`、`AI_WORLD_BASE_URL` 自动初始化。
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,61 @@ 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` / `aiping`
132
+ - Provider 对照表:`api2img`(推荐) / `gemini` / `aihubmix` / `shubiaobiao` / `aiping` / `openrouter` / `kunpo`
133
+ - **OpenRouter**:使用专用代理端点 `/api/llm/openrouter`,模型 ID 格式为 `provider/model`(如 `openai/gpt-4o-mini`、`anthropic/claude-sonnet-4-20250514`、`google/gemini-2.5-flash-preview`)
134
+ - **KUNPO API**:统一 LLM 网关(https://llm.ziy.cc),兼容 OpenAI 接口,使用专用代理端点 `/api/llm/kunpo`,一个 Key 访问 150+ 模型
130
135
  - 常用模型列表和 AI SDK 函数速查
131
136
 
137
+ #### OpenRouter 快速示例
138
+
139
+ ```typescript
140
+ import { createProvider } from 'ai-world-sdk';
141
+ import { generateText, streamText } from 'ai';
142
+
143
+ // OpenRouter(endpointType 传 'openai',SDK 内部自动使用 createOpenRouter)
144
+ const provider = createProvider('openrouter', 'openai', 'my-plugin');
145
+
146
+ // 非流式
147
+ const result = await generateText({
148
+ model: provider.languageModel('openai/gpt-4o-mini'),
149
+ prompt: '你好',
150
+ });
151
+
152
+ // 流式
153
+ const stream = streamText({
154
+ model: provider.languageModel('anthropic/claude-sonnet-4-20250514'),
155
+ prompt: '请介绍人工智能',
156
+ });
157
+ for await (const chunk of stream.textStream) {
158
+ process.stdout.write(chunk);
159
+ }
160
+ ```
161
+
162
+ #### KUNPO API 快速示例
163
+
164
+ ```typescript
165
+ import { createProvider } from 'ai-world-sdk';
166
+ import { generateText, streamText } from 'ai';
167
+
168
+ // KUNPO API(endpointType 传 'openai',兼容 OpenAI 接口)
169
+ const provider = createProvider('kunpo', 'openai', 'my-plugin');
170
+
171
+ // 非流式
172
+ const result = await generateText({
173
+ model: provider.languageModel('google/gemini-3.1-pro-preview'),
174
+ prompt: '你好',
175
+ });
176
+
177
+ // 流式
178
+ const stream = streamText({
179
+ model: provider.languageModel('anthropic/claude-haiku-4.5'),
180
+ prompt: '请介绍人工智能',
181
+ });
182
+ for await (const chunk of stream.textStream) {
183
+ process.stdout.write(chunk);
184
+ }
185
+ ```
186
+
132
187
  ### 文本生成 → `docs/text-generation.md`
133
188
 
134
189
  - `generateText` / `streamText` / `generateObject` / `streamObject`
@@ -139,9 +194,10 @@ sdkConfig.setPluginId('my-plugin');
139
194
  - `DoubaoImageGenerationClient`(豆包 Seedream)
140
195
  - `GeminiImageGenerationClient`
141
196
 
142
- ### 视频生成 → `docs/video-generation.md`
197
+ ### 视频生成 & 视频理解 → `docs/video-generation.md`
143
198
 
144
199
  - `VideoGenerationClient`(豆包 Seedance)
200
+ - `VideoUnderstandingClient`(豆包视频理解,基于 Chat Completions API)
145
201
  - `OpenAIVideoGenerationClient`(Sora)
146
202
 
147
203
  ### MinIO 对象存储 → `docs/minio-storage.md`
@@ -155,10 +211,11 @@ sdkConfig.setPluginId('my-plugin');
155
211
  - 三级权限: `private` / `specific_users` / `public`
156
212
  - 插件隔离与跨插件访问
157
213
 
158
- ### 数据库请求 → `docs/database-requests.md`
214
+ ### 版本化资源 → `docs/versioned-resource.md`
159
215
 
160
- - `DatabaseRequestClient` — 建表/迁移请求提交、列表、审核
161
- - 表名规则: `{pluginId}_{tableName}`
216
+ - `VersionedResourceClient` — 全局版本化资源管理
217
+ - 资源名称为唯一 ID,支持语义化版本号
218
+ - 支持 `latest` 别名获取/下载最新版本
162
219
 
163
220
  ### Agent Skills → `docs/agent-skills.md`
164
221
 
@@ -14,7 +14,8 @@
14
14
  | `aiping` | `gemini` | 平音 Gemini |
15
15
  | `aiping` | `anthropic` | 平音 Claude |
16
16
  | `gemini` | `gemini` | Google 原生,仅限 Gemini 系列模型 |
17
- | `openrouter` | `openrouter` | OpenRouter 兼容,模型兼容 OpenRouter 格式,可包括 GPT、以及经聚合的 Gemini/Claude 等(视 provider 能力),模型ID必须以gateway方式设置,如openai/gpt-4o-mini |
17
+ | `openrouter` | `openai` | OpenRouter 聚合服务,SDK 内部自动使用 `createOpenRouter` 和专用代理端点 `/api/llm/openrouter`。模型 ID 格式为 `provider/model`(如 `openai/gpt-4o-mini`、`anthropic/claude-sonnet-4-20250514`) |
18
+ | `kunpo` | `openai` | KUNPO API 统一 LLM 网关(https://llm.ziy.cc),兼容 OpenAI 接口,一个 Key 访问 150+ 模型。SDK 内部使用 `createOpenAI` 并路由到专用代理 `/api/llm/kunpo` |
18
19
 
19
20
  ## EndpointType 与模型对应关系
20
21
 
@@ -23,9 +24,9 @@
23
24
  | `gemini` | Google Gemini | 必须使用 Google 的 Gemini 模型(如 `gemini-2.5-flash`、`gemini-2.5-pro`) |
24
25
  | `anthropic` | Claude | 必须使用 Anthropic 的 Claude 模型(如 `claude-sonnet-4-5`、`claude-3-5-sonnet`);**仅 api2img、shubiaobiao、aiping 支持此 endpoint** |
25
26
  | `openai` | OpenAI 兼容 | 模型兼容 OpenAI 格式,可包括 GPT、以及经聚合的 Gemini/Claude 等(视 provider 能力) |
26
- | `openrouter` | OpenRouter 兼容 | OpenRouter 兼容,模型兼容 OpenRouter 格式,可包括 GPT、以及经聚合的 Gemini/Claude 等(视 provider 能力),模型ID必须以gateway方式设置,如openai/gpt-4o-mini |
27
+ | `openai` | OpenRouter 兼容 | provider `openrouter` 时,`endpointType` `openai`,SDK 内部自动切换到 `createOpenRouter` 和专用代理端点 |
27
28
 
28
- 规则:**anthropic 不是 provider**,仅 **api2img**、**shubiaobiao**、**aiping** 支持 EndpointType 为 `anthropic`(调用 Claude);`gemini` provider 用 `gemini` endpoint,其余按上表组合。
29
+ 规则:**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`;`kunpo` provider 的 `endpointType` 传 `openai`,SDK 内部使用 `createOpenAI` 并路由到专用代理 `/api/llm/kunpo`;其余按上表组合。
29
30
 
30
31
  > `doubao` 不通过 `createProvider` 使用,豆包有专用客户端(见 image-generation.md / video-generation.md)。
31
32
 
@@ -53,6 +54,20 @@ const p = createProvider('api2img', 'openai', 'my-plugin');
53
54
  p.languageModel('gpt-4o-mini');
54
55
  p.languageModel('gemini-2.5-flash');
55
56
  p.languageModel('claude-sonnet-4-5');
57
+
58
+ // OpenRouter(endpointType 传 'openai',SDK 内部自动切换到 createOpenRouter + 专用代理)
59
+ // 模型 ID 必须使用 provider/model 格式
60
+ const or = createProvider('openrouter', 'openai', 'my-plugin');
61
+ or.languageModel('openai/gpt-4o-mini');
62
+ or.languageModel('anthropic/claude-sonnet-4-20250514');
63
+ or.languageModel('google/gemini-2.5-flash-preview');
64
+
65
+ // KUNPO API(endpointType 传 'openai',SDK 内部使用 createOpenAI + 专用代理 /api/llm/kunpo)
66
+ // 兼容 OpenAI Chat Completions 格式,支持 150+ 模型
67
+ const kp = createProvider('kunpo', 'openai', 'my-plugin');
68
+ kp.languageModel('google/gemini-3.1-pro-preview');
69
+ kp.languageModel('anthropic/claude-haiku-4.5');
70
+ kp.languageModel('GLM-5.1');
56
71
  ```
57
72
 
58
73
  ### 检测模型可用性
@@ -70,6 +85,14 @@ const ok = await checkModel('api2img', 'openai', 'gpt-4o-mini', 'my-plugin');
70
85
  | `gemini-2.5-flash` / `gemini-2.5-pro` | 文本 | `gemini` | `gemini`(仅 Google) |
71
86
  | `claude-sonnet-4-6` / `claude-opus-4-6` | 文本 | `api2img`、`shubiaobiao` 或 `aiping` | `anthropic`(仅 Claude) |
72
87
  | `dall-e-3` / `gpt-image-1` | 图像 | `api2img`、`shubiaobiao` 或 `aiping` | `openai` |
88
+ | `openai/gpt-4o-mini` / `openai/gpt-4o` | 文本 | `openrouter` | `openai`(SDK 自动处理) |
89
+ | `anthropic/claude-sonnet-4-20250514` | 文本 | `openrouter` | `openai`(SDK 自动处理) |
90
+ | `google/gemini-2.5-flash-preview` | 文本 | `openrouter` | `openai`(SDK 自动处理) |
91
+ | `google/gemini-3.1-pro-preview` | 文本 | `kunpo` | `openai`(KUNPO API) |
92
+ | `anthropic/claude-haiku-4.5` | 文本 | `kunpo` | `openai`(KUNPO API) |
93
+ | `GLM-5.1` / `z-ai/glm-5v-turbo` | 文本 | `kunpo` | `openai`(KUNPO API) |
94
+ | `x-ai/grok-4.20` | 文本 | `kunpo` | `openai`(KUNPO API) |
95
+ | `google/gemma-4-26b-a4b-it` | 文本 | `kunpo` | `openai`(KUNPO API) |
73
96
  | `doubao-seedream-4-5-251128` | 图像 | — | 专用客户端 |
74
97
 
75
98
  ## AI SDK 函数速查
@@ -0,0 +1,64 @@
1
+ # 版本化资源管理
2
+
3
+ 独立于 SharedResource 的版本化资源系统。资源名称为全局唯一标识(不区分用户),支持语义化版本号管理。
4
+ 存储在 MinIO `ai-world-res` bucket 的 `resources/{name}/{version}/{filename}` 路径下。
5
+
6
+ ## 基本用法
7
+
8
+ ```typescript
9
+ import { VersionedResourceClient } from 'ai-world-sdk';
10
+
11
+ const vr = new VersionedResourceClient();
12
+
13
+ // 上传新版本(版本号必须高于当前最新版本)
14
+ const file = new File(['{"key": "value"}'], 'config.json', { type: 'application/json' });
15
+ const res = await vr.upload('my-config', '1.0.0', file, '初始版本');
16
+
17
+ // 上传更高版本
18
+ const file2 = new File(['{"key": "new"}'], 'config.json', { type: 'application/json' });
19
+ await vr.upload('my-config', '1.1.0', file2, '更新配置');
20
+
21
+ // 获取最新版本信息
22
+ const latest = await vr.getLatest('my-config');
23
+ console.log(latest.version); // "1.1.0"
24
+
25
+ // 获取指定版本信息
26
+ const v1 = await vr.getVersion('my-config', '1.0.0');
27
+
28
+ // 列出所有版本(按版本号降序)
29
+ const versions = await vr.listVersions('my-config');
30
+
31
+ // 下载指定版本
32
+ const blob = await vr.download('my-config', '1.0.0');
33
+
34
+ // 下载最新版本(使用 "latest" 别名)
35
+ const latestBlob = await vr.download('my-config', 'latest');
36
+
37
+ // 列出所有资源(分页,聚合最新版本信息)
38
+ const list = await vr.list({ page: 1, pageSize: 20, search: 'config' });
39
+
40
+ // 删除指定版本
41
+ await vr.deleteVersion('my-config', '1.0.0');
42
+ ```
43
+
44
+ ## 版本号规则
45
+
46
+ | 规则 | 说明 |
47
+ |------|------|
48
+ | 格式 | 语义化版本号(semver),如 `1.0.0`、`2.1.3` |
49
+ | 唯一性 | 同一资源名称下版本号唯一 |
50
+ | 递增约束 | 上传新版本时,版本号必须高于当前最新版本 |
51
+ | latest 别名 | 获取/下载时可使用 `latest` 代替具体版本号 |
52
+
53
+ ## 权限模型
54
+
55
+ | 操作 | 权限要求 |
56
+ |------|----------|
57
+ | 上传/删除 | `can_upload_shared_resources` 权限 |
58
+ | 查看/下载 | 所有已登录用户 |
59
+
60
+ ## 与 SharedResource / ResourceClient 的区别
61
+
62
+ - `SharedResource` — 平台级文件共享,按用户上传,无版本概念
63
+ - `ResourceClient` — 插件级资源管理,按 plugin_id 隔离,三级 ACL
64
+ - `VersionedResourceClient` — 全局版本化资源,资源名称为唯一 ID,支持多版本管理
@@ -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
@@ -1,151 +0,0 @@
1
- /**
2
- * Database Request Client
3
- * 数据库请求客户端
4
- * 通过后端 /api/database 提交建表/迁移请求,查看请求列表和详情
5
- * 所有登录用户可提交请求,管理员可审核
6
- */
7
- export interface DatabaseRequestClientConfig {
8
- baseUrl?: string;
9
- token?: string;
10
- headers?: Record<string, string>;
11
- }
12
- export type RequestType = "create" | "migrate";
13
- export type RequestStatus = "pending" | "approved" | "rejected";
14
- export interface ColumnDefinition {
15
- name: string;
16
- type: string;
17
- primary_key?: boolean;
18
- auto_increment?: boolean;
19
- nullable?: boolean;
20
- default?: unknown;
21
- length?: number;
22
- precision?: number;
23
- scale?: number;
24
- }
25
- export interface IndexDefinition {
26
- name: string;
27
- columns: string[];
28
- unique?: boolean;
29
- }
30
- export interface ForeignKeyDefinition {
31
- column: string;
32
- references_table: string;
33
- references_column: string;
34
- on_delete?: string;
35
- }
36
- export interface SchemaDefinition {
37
- columns: ColumnDefinition[];
38
- indexes?: IndexDefinition[];
39
- foreign_keys?: ForeignKeyDefinition[];
40
- }
41
- export interface SubmitCreateRequestOptions {
42
- tableName: string;
43
- schemaDefinition: SchemaDefinition;
44
- description?: string;
45
- }
46
- export interface SubmitMigrateRequestOptions {
47
- tableName: string;
48
- migrationSql: string;
49
- description?: string;
50
- }
51
- export interface DatabaseRequestInfo {
52
- id: number;
53
- requester_id: number;
54
- plugin_id: string;
55
- table_name: string;
56
- request_type: RequestType;
57
- schema_definition: SchemaDefinition | null;
58
- migration_sql: string | null;
59
- description: string | null;
60
- status: RequestStatus;
61
- reviewer_id: number | null;
62
- review_comment: string | null;
63
- created_at: string;
64
- reviewed_at: string | null;
65
- }
66
- export interface ListRequestsOptions {
67
- status?: RequestStatus;
68
- page?: number;
69
- pageSize?: number;
70
- }
71
- /**
72
- * Database Request Client
73
- * 数据库请求客户端类
74
- *
75
- * @example
76
- * ```typescript
77
- * import { DatabaseRequestClient, sdkConfig } from 'ai-world-sdk';
78
- *
79
- * sdkConfig.setPluginId('my-plugin');
80
- * const dbRequests = new DatabaseRequestClient();
81
- *
82
- * // 提交建表请求
83
- * const req = await dbRequests.submitCreateRequest({
84
- * tableName: 'user_scores',
85
- * schemaDefinition: {
86
- * columns: [
87
- * { name: 'id', type: 'integer', primary_key: true, auto_increment: true, nullable: false },
88
- * { name: 'user_id', type: 'integer', nullable: false },
89
- * { name: 'score', type: 'float', nullable: false },
90
- * ],
91
- * indexes: [{ name: 'idx_user_id', columns: ['user_id'] }],
92
- * },
93
- * description: '用户评分表',
94
- * });
95
- *
96
- * // 提交迁移请求
97
- * const migrateReq = await dbRequests.submitMigrateRequest({
98
- * tableName: 'user_scores',
99
- * migrationSql: 'ALTER TABLE my_plugin_user_scores ADD COLUMN level INTEGER DEFAULT 0;',
100
- * description: '添加 level 字段',
101
- * });
102
- *
103
- * // 列出我的请求
104
- * const list = await dbRequests.listRequests({ status: 'pending' });
105
- *
106
- * // 获取请求详情
107
- * const detail = await dbRequests.getRequest(req.id);
108
- *
109
- * // 获取请求总数
110
- * const total = await dbRequests.getRequestCount({ status: 'pending' });
111
- * ```
112
- */
113
- export declare class DatabaseRequestClient {
114
- private baseUrl;
115
- private headers;
116
- constructor(config?: DatabaseRequestClientConfig);
117
- private getPluginId;
118
- private handleErrorResponse;
119
- /**
120
- * Submit a table creation request
121
- * 提交建表请求
122
- */
123
- submitCreateRequest(options: SubmitCreateRequestOptions): Promise<DatabaseRequestInfo>;
124
- /**
125
- * Submit a migration request
126
- * 提交迁移请求
127
- */
128
- submitMigrateRequest(options: SubmitMigrateRequestOptions): Promise<DatabaseRequestInfo>;
129
- /**
130
- * List requests (admin sees all, regular users see own)
131
- * 列出请求列表(管理员看全部,普通用户看自己的)
132
- */
133
- listRequests(options?: ListRequestsOptions): Promise<DatabaseRequestInfo[]>;
134
- /**
135
- * Get request count
136
- * 获取请求总数
137
- */
138
- getRequestCount(options?: {
139
- status?: RequestStatus;
140
- }): Promise<number>;
141
- /**
142
- * Get request detail by ID
143
- * 获取请求详情
144
- */
145
- getRequest(requestId: number): Promise<DatabaseRequestInfo>;
146
- /**
147
- * Review a request (approve/reject) - requires can_manage_database permission
148
- * 审核请求(通过/拒绝)- 需要 can_manage_database 权限
149
- */
150
- reviewRequest(requestId: number, action: "approve" | "reject", comment?: string): Promise<DatabaseRequestInfo>;
151
- }