@vetta-org/plugin-sdk 0.3.5 → 0.3.7

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/docs/media.md CHANGED
@@ -24,6 +24,7 @@ const submitted = await ctx.media.submit({
24
24
  kind: "image",
25
25
  mode: "text-to-image",
26
26
  prompt: "a red fox in snow",
27
+ modelId: "openai/gpt-image-2",
27
28
  dimensions: { width: 1024, height: 1024 },
28
29
  inputs: [],
29
30
  });
@@ -77,6 +78,12 @@ try {
77
78
 
78
79
  消费插件可用 `onProvidersChanged()` 监听 Provider 增删,并重新执行能力发现。插件并行激活时不能依赖固定加载顺序。
79
80
 
81
+ 官方系统插件如果需要遵循宿主 Agent 的图片 Provider 与模型选择,应使用 `ctx.official.agent.getImageGeneration()` 读取
82
+ `textToImageProviderId` / `textToImageModelId` 与 `imageToImageProviderId` / `imageToImageModelId`。只保存了 Provider 的旧配置
83
+ 继续使用该 Provider 的 `defaultModelId`。已保存但当前不存在或不支持对应模式的 Provider/模型必须报告
84
+ `provider-unavailable`,不能静默切换到另一条路由。
85
+ Provider 的凭据、模型和服务端参数仍由 Provider 自己管理,不应复制到 Agent 设置。
86
+
80
87
  ## 注册 Provider
81
88
 
82
89
  Provider 插件需要 `media.provider.register`。只有远程传输才需要 `network.fetch`;本地渲染输出可使用插件 Blob 或工作区文件。
@@ -92,6 +99,14 @@ ctx.media.registerProvider({
92
99
  aspectRatios: ["16:9", "9:16"],
93
100
  resolutions: ["efficient", "balanced", "quality"],
94
101
  defaultResolution: "balanced",
102
+ models: [{
103
+ id: "acme/video-v2",
104
+ displayName: "Video v2",
105
+ sourceId: "acme",
106
+ sourceDisplayName: "Acme",
107
+ modes: ["image-to-video"],
108
+ }],
109
+ defaultModelId: "acme/video-v2",
95
110
  durationsSeconds: [5, 10],
96
111
  }],
97
112
  async submit(request, context) {
@@ -124,13 +139,15 @@ ctx.media.registerProvider({
124
139
  });
125
140
  ```
126
141
 
127
- Provider 收到的 `inputs` 只有不透明 ID、媒体类型和 MIME,不包含插件 Blob 命名空间或工作区路径。只有当前任务上下文能用 `uploadInput()` 把对应文件流式上传到 HTTP(S) 服务。Provider 输出 source 支持 `remote-url`、`plugin-blob` 和 `workspace-file`,宿主会按 Provider 权限读取并导入为消费方临时产物。
142
+ Provider 收到的 `inputs` 只有不透明 ID、媒体类型和 MIME,不包含插件 Blob 命名空间或工作区路径。只有当前任务上下文能读取它们:`uploadInput()` 把文件流式上传到 HTTP(S) 服务;`readInput()` 返回 `{ mimeType, data }`,用于 Gemini `inlineData` 一类必须把字节放进 JSON 的 API。`readInput()` 上限 32 MB,调用结束、取消或 Provider 卸载后句柄立即失效,不能读取未列入本次请求的文件。Provider 输出 source 支持 `remote-url`、`plugin-blob` 和 `workspace-file`,宿主会按 Provider 权限读取并导入为消费方临时产物。
143
+
144
+ `models` 是可选的兼容字段:省略时按旧版 Provider 级能力工作。提供时,模型 `id` 在同一 capability 内必须唯一,模型的 `modes` 必须是 Provider `modes` 的子集,`defaultModelId` 必须引用目录中的模型。消费者没有传 `modelId` 时宿主使用 `defaultModelId`;显式模型缺失或不支持当前模式时返回 `invalid-request`,不会静默替换。模型可用 `sourceId` / `sourceDisplayName` 表达同一 Provider 后面的上游供应商分组。
128
145
 
129
146
  `resolutions` 是 Provider 自定义的稳定选项 ID,不保证具有 `720p`、`2K` 等固定视频制式语义;例如本地模型可以用它表达像素预算档位,再在 Provider 内转换为最终宽高。若声明 `defaultResolution`,该值必须同时出现在 `resolutions` 中。消费者在没有已保存值或已有值不受当前模型支持时优先采用这个显式默认值。
130
147
 
131
148
  ## Provider SPI
132
149
 
133
- 通用媒体契约和 capability token 定义在 `@vetta-org/capability-sdk`,当前协议版本为 4。注册表、通用任务、临时产物存储、输入解析与网络传输位于 desktop 主进程。插件 Provider 通过受控 IPC 回调桥接到同一个 Registry,注销时会中止仍在执行的调用。
150
+ 通用媒体契约和 capability token 定义在 `@vetta-org/capability-sdk`,当前协议版本为 5。注册表、通用任务、临时产物存储、输入解析与网络传输位于 desktop 主进程。插件 Provider 通过受控 IPC 回调桥接到同一个 Registry,注销时会中止仍在执行的调用。使用模型目录或 `readInput()` 的插件应声明 `pluginApiVersion: ^2.4.0`;旧 Provider 不声明模型目录时继续按原行为运行。
134
151
 
135
152
  需要宿主凭据或其它主进程特权的实现仍应注册为宿主 Provider;普通远端服务、本地模型或 sidecar 可用 Provider 插件适配。两者对消费者暴露同一契约。
136
153
 
@@ -113,6 +113,10 @@ ctx.permissions.require("fs.read"); // 缺则抛 Plugin permission denied: fs.r
113
113
  - `replaceOwnedProviders(providers)` 是**原子快照**:省略即删除。所以每次写入都得重建完整真相。
114
114
  - 正因如此,写之前先 `listOwnedProviders()` 读回宿主当前持有的状态并做对账——否则上游一时没返回的
115
115
  模型会被当成用户丢失的模型抹掉。读回的 `apiKey` 是掩码,下次写入要带上真凭据。
116
+ - SDK 0.3.7 的模型定义可声明 `reasoning: true`、`reasoningLevels`(上游原始档位字符串数组)和
117
+ `defaultReasoningLevel`。例如 CPA 可发布 `["low", "medium", "high", "xhigh", "max"]`。
118
+ 档位省略或为空时回退到宿主的 API 类型预设;显式列表的默认值无效或省略时使用第一项,用户已选择的档位优先。
119
+ 需搭配保留这两个字段的 Desktop 模型写入合同;旧宿主可能静默清除它们,单独升级插件不能修复宿主。
116
120
 
117
121
  ### ctx.ocr(`ai.ocr.recognize` / `ai.ocr.provider.register`)
118
122
 
@@ -152,19 +152,28 @@ function Icon() {
152
152
  import { Button, Switch, Slider, Dialog, DialogContent, cn } from "@vetta-org/ui";
153
153
  ```
154
154
 
155
+ 同时在 Vite 配置中显式开启宿主 UI 共享:
156
+
157
+ ```ts
158
+ vettaPluginFederation({
159
+ name: "my_plugin",
160
+ hostUi: true,
161
+ });
162
+ ```
163
+
155
164
  约定:
156
165
 
157
166
  | 项 | 说明 |
158
167
  | --- | --- |
159
168
  | 运行时 | 由宿主单例提供(MF share + `vetta-host://ui`),**不要**打进插件 bundle |
160
- | 构建 | `vettaPluginFederation` 已把 `@vetta-org/ui` 设为 `shared.singleton + import:false`,并 rollup external |
169
+ | 构建 | `hostUi: true` 会把 `@vetta-org/ui` 设为 `shared.singleton + import:false`,并 rollup external |
161
170
  | `package.json` | 仅作类型 / 本地 tsc:`devDependencies` 里 `@vetta-org/ui`(仓库内 `workspace:*`,仓库外按发布版本) |
162
171
  | 样式 | 组件 class 走宿主全局 token / Tailwind;插件 scoped CSS **管不到** Dialog 等 portal 到 `document.body` 的浮层(浮层依赖宿主已加载的全局样式,这是预期行为) |
163
172
  | 宿主版本 | 需要宿主提供 `vetta-host://ui` shim:desktop **>= 0.5.31**,且 `@vetta-org/plugin-vite` **>= 0.0.5**。旧宿主上 import `@vetta-org/ui` 会在加载插件时解析失败(模块找不到,整个插件不激活)——若你的插件要兼容更早的 App,就别用这条通道,自写 JSX + 语义 class |
164
173
  | 稳定性 | **半稳定、可选**。宿主会尽量不无故破坏,但不对跨 App 大版本做 semver 承诺;props / 导出变更时官方插件随 monorepo 同改 |
165
174
  | 不在此列 | `@vetta-org/theme-ui/plugin-ui` 是独立的按需共享合同,见下节;不要从其它 `@vetta-org/theme-ui/*` 入口导入宿主业务 View |
166
175
 
167
- 默认路径仍是:自写 JSX + 语义 class(`bg-background` / `text-foreground`…)。`@vetta-org/ui` 适合按钮、开关、对话框等控件统一,不是强制。
176
+ 默认路径仍是:自写 JSX + 语义 class(`bg-background` / `text-foreground`…)。`@vetta-org/ui` 适合按钮、开关、对话框等控件统一,不是强制。未导入它的插件不要开启 `hostUi`,也不要声明该依赖。
168
177
 
169
178
  顶层不要对 `@vetta-org/ui` 做立即求值(与 React 相同,见上文「MF 顶层 JSX 陷阱」)——在组件函数内使用即可。
170
179
 
@@ -23,9 +23,9 @@ packages/plugins/presets/
23
23
 
24
24
  ## 构建与集成
25
25
 
26
- - **构建制品**:`bun run build:presets` 先构建根 workspace 中的插件 SDK / 构建包,再逐个产出 `release/<id>-<version>.zip`。`dev` / `start` / 打包流程都会先跑它。
26
+ - **构建制品**:`bun run build:presets` 先构建根 workspace 中的插件 SDK / 构建包,再逐个产出 `release/<id>-<version>.vettapkg`。`dev` / `start` / 打包流程都会先跑它。
27
27
  - **依赖管理**:presets 与其它 monorepo 包统一属于根 workspace、共用根 `bun.lock`;`@vetta-org/plugin-sdk`、`@vetta-org/plugin-vite` 等本地包经 `workspace:*` 直链仓库源码。
28
- - **校验**:Desktop 按 preset 的 `plugin.json` 精确定位 zip,拒绝路径穿越、id/version 不一致、入口或样式缺失的归档。
28
+ - **校验**:Desktop 按 preset 的 `plugin.json` 精确定位 `.vettapkg`,拒绝路径穿越、id/version 不一致、入口或样式缺失的归档。
29
29
  - **dev**:zip 解压到 `apps/desktop/.artifacts/system-plugins/<id>/`,主进程只读该 staging,不直接读 preset 源码或 `dist/`。
30
30
  - **打包**:`prepare-pack.js` 从 zip 解压到打包 staging 的 `system-plugins/<id>/`,再随 `extraResources` 进入 `Resources/system-plugins/<id>/`。
31
31
 
package/docs/ui-slots.md CHANGED
@@ -106,6 +106,7 @@ interface PluginGlobalSlotContribution {
106
106
  - 导航入口默认落在侧边栏的「更多」收纳里;用户可以拖动排序,也可以 **pin 到左上方置顶区**(含「新会话」最多 5 个),布局按 key 持久化
107
107
  - 组件收到 `{ pluginId, viewId }`,一个组件可以服务多个注册
108
108
  - `icon` 是 **iconify class 字符串**(如 `"icon-[solar--widget-4-linear]"`),不是 ReactNode——宿主要把它渲染进自己的导航按钮,并按 key 持久化布局
109
+ - **图标 class 必须由你自己的 CSS 生成**:宿主只是把字符串挂到按钮上,Tailwind 只生成它扫得到的字面量,而你的源码不在宿主扫描范围内——漏了这步导航项就是个空格子,且不会有任何报错。在插件的 CSS 里加一行 `@plugin "@iconify/tailwind4";`(并把用到的图标集如 `@iconify-json/mdi` 装成 devDependency),规则会连同内联 SVG 一起进入 `dist/style.css`,宿主激活插件时加载。另外图标名要在图标集里**真实存在**:例如 solar 没有任何 git 图标,写 `solar:git-branch-bold` 同样是空格子
109
110
  - **不写 `icon` 就用插件自己的 Logo**:宿主回落到 `plugin.json` 的 `icon`。包内图片(`svg` / `png` / `webp` 等)默认按主题前景色 mask 成**单色**,因此自带图形的插件不必去图标集里找一个近似的;Iconify 名照常当 class 用。两者都不存在时才落到宿主默认图标
110
111
  - **`iconTint: false` 保留原图色彩**:导航项改用 `<img>` 渲染。选之前先掂量:入口只有 16px、与内置单色图标并排,且固定色彩无法跟随主题——深色 logo 会在深色侧边栏里消失。**只对彩色 logo 有意义**:单色图形 tint 后反而更清晰统一,而整块不透明的彩色图 tint 后会糊成一个纯色块。对 Iconify class 图标无效(它们始终跟随主题色)
111
112
  - **`sidebar: false` 不占导航位**:视图只出现在「设置 → 更多选项」,宿主在设置壳内打开它(两层侧栏保留,切换其它插件页面是一次点击)。配置页、安装引导、诊断台这类「装完就不常回来」的 surface 应该选它——侧边栏是用户自己策划的稀缺空间,每个插件都常驻一格,会把用户真正高频的入口挤进收纳菜单
@@ -344,6 +345,7 @@ pdfjs.getDocument({ url: file.getUrl() });
344
345
 
345
346
  向活动面板注册一个 tab。
346
347
 
348
+ - **`order` 决定默认排位**(越小越靠前,缺省 100 即排在全部内置之后)。内置取值可作标尺:文件 0、批量 10、浏览器 15、计划 18、待办 20、后台任务 30。宿主把下限钳到 10,「文件」永远第一;用户拖出来的顺序优先于它
347
349
  - 权限:`ui.slot.activity-tab`(注册 **warn+noop**;`openActivityTab` / `setActivityTabVisible` **抛错**)
348
350
  - **`scope_use` fail-closed**(必写,否则任何场景不显示)
349
351
  - **默认注册即上栏**(`initiallyVisible` 缺省 `true`)。声明 `initiallyVisible: false` 表示「出现条件我自己管」:注册只入池,之后用 `setActivityTabVisible` 静默上栏/下栏(如 git 只在仓库目录上栏、工作台跟随输入栏 toggle),或用 `openActivityTab` 上栏并抢焦点打开(如图像生成完成后跳到历史)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vetta-org/plugin-sdk",
3
- "version": "0.3.5",
3
+ "version": "0.3.7",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -17,6 +17,10 @@
17
17
  "types": "./dist/npm-package.d.ts",
18
18
  "import": "./dist/npm-package.js"
19
19
  },
20
+ "./logger": {
21
+ "types": "./dist/logger.d.ts",
22
+ "import": "./dist/logger.js"
23
+ },
20
24
  "./tailwind-theme.css": "./src/tailwind-theme.css"
21
25
  },
22
26
  "files": [