@coralai/sps-plugin-api 0.7.0 → 0.9.0

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/index.d.ts CHANGED
@@ -121,12 +121,18 @@ export interface SpsCapabilityBase {
121
121
  mode: 'sync' | 'async';
122
122
  /**
123
123
  * 参数形状由**能力**定,不是卡片里的自由 JSON。
124
- * ⚠️ 运行时必须是一个 **Zod schema**(能力表拿它校验卡片参数)——
125
- * 这里只声明结构最小面,免得契约包为此依赖 zod。
124
+ *
125
+ * ✅ **两种都收**:Zod schema,或**标准 JSON Schema**
126
+ * (`{type:'object', properties, required}` —— 和 `sps.tools.inputSchema` 同形)。
127
+ * 注册时归一成 Zod;两种都不是**当场抛**,插件挂不上。
128
+ *
129
+ * 🔴 **为什么要收两种**:`sps.tools.inputSchema` 是 JSON Schema,而这里原本只收 Zod ——
130
+ * 同一个 API 面上同名字段两种含义,两种插件都写的作者必然会混
131
+ * (实测有人 5 个能力全传了 JSON Schema)。而如果他写的是 `.mjs`,类型也拦不住。
126
132
  */
127
133
  inputSchema: {
128
134
  parse(value: unknown): unknown;
129
- };
135
+ } | Record<string, unknown>;
130
136
  /**
131
137
  * 这个能力会写什么(相对项目根的路径模式)。
132
138
  * 🔴 **可审计性的来源**:不读代码就知道这张卡会写什么。
@@ -205,6 +211,32 @@ export interface SpsRegistryByKey<T = unknown> {
205
211
  get(key: string): T | undefined;
206
212
  list(): string[];
207
213
  }
214
+ /** `sps.media`:注册表 + **一个使用方法**。 */
215
+ export interface SpsMedia extends SpsRegistryByKey {
216
+ /**
217
+ * 用注册进来的适配器生成一个媒体资产并落盘。
218
+ *
219
+ * ⚠️ **同步等待**(一张图几十秒)。async 能力应当把它丢进 `sps.jobs`,
220
+ * 不要在 `start` 里 await —— 那会把 tick 卡住。
221
+ */
222
+ generate(spec: {
223
+ capability: 'image' | 'video' | 'music' | 'voice' | '3d' | 'embedding' | 'rerank';
224
+ prompt: string;
225
+ /** 运行目录(产物落这)。 */
226
+ cwd: string;
227
+ /** 相对 cwd 的输出路径;省略则自动命名到 assets/。 */
228
+ outPath?: string;
229
+ size?: string;
230
+ referenceUrl?: string;
231
+ /** 点名用哪一家;不传 = 按能力解析默认那家。 */
232
+ providerId?: string;
233
+ }): Promise<{
234
+ path: string;
235
+ provider: string;
236
+ model?: string;
237
+ bytes: number;
238
+ }>;
239
+ }
208
240
  /** 工厂自带 id,注册时不另给 key。 */
209
241
  export interface SpsRegistryByFactory<T = unknown> {
210
242
  register(factory: T): () => void;
@@ -222,6 +254,27 @@ export interface SpsNotifier {
222
254
  send(message: string, level?: 'info' | 'success' | 'warning' | 'error'): Promise<void>;
223
255
  };
224
256
  }
257
+ /** 与 `SpsAsyncPoll` 同形 —— async 能力的 `poll` 可以**直接透传**。 */
258
+ export type SpsJobStatus = SpsAsyncPoll;
259
+ /**
260
+ * 后台任务表:async 能力用它把长任务跑起来并拿到 handle。
261
+ *
262
+ * ```js
263
+ * start: (input, ctx) => ({ handle: jobs.start(() => media.generate({...})) }),
264
+ * poll: (handle) => jobs.poll(handle), // 形状一样,直接透传
265
+ * ```
266
+ *
267
+ * ⚠️ **在内存里。** `sps tick <project>` 是常驻循环进程,start 与 poll 在同一个进程 ——
268
+ * 但它会被 stop / 重启,那时 handle 就没了。
269
+ * 🔴 **认不出的 handle 会当失败并说明原因**,不会回 `{done:false}` ——
270
+ * 后者的表现是卡片一直等到超时、然后被归因成"任务太慢",而真因是进程重启过。
271
+ * ⚠️ 不做持久化:重启 ⇒ 那张卡失败并说清楚 ⇒ 重跑它。
272
+ */
273
+ export interface SpsJobs {
274
+ /** 立刻返回 handle。`fn` 抛出**不冒泡**(没人接得住),变成 `poll` 的 error。 */
275
+ start(fn: () => Promise<Record<string, unknown>>): string;
276
+ poll(handle: string): SpsJobStatus;
277
+ }
225
278
  /** 建一张卡。形状照 MCP 面上的 `add_card`,不另发明。 */
226
279
  export interface SpsNewCard {
227
280
  title: string;
@@ -425,6 +478,7 @@ export declare const SPS_SERVICES: {
425
478
  readonly events: "sps.events";
426
479
  readonly projects: "sps.projects";
427
480
  readonly cards: "sps.cards";
481
+ readonly jobs: "sps.jobs";
428
482
  readonly subprocess: "sps.subprocess";
429
483
  readonly attachments: "sps.attachments";
430
484
  readonly media: "sps.media";
@@ -446,8 +500,9 @@ export interface SpsPluginContext {
446
500
  'sps.events': SpsEvents;
447
501
  'sps.projects': SpsProjects;
448
502
  'sps.cards': SpsCards;
503
+ 'sps.jobs': SpsJobs;
449
504
  'sps.capabilities': SpsCapabilities;
450
- 'sps.media': SpsRegistryByKey;
505
+ 'sps.media': SpsMedia;
451
506
  'sps.im': SpsRegistryByKey;
452
507
  'sps.agents': SpsRegistryByFactory;
453
508
  'sps.repo': SpsRegistryByFactory;
package/dist/index.js CHANGED
@@ -23,6 +23,7 @@ export const SPS_SERVICES = {
23
23
  events: 'sps.events',
24
24
  projects: 'sps.projects',
25
25
  cards: 'sps.cards',
26
+ jobs: 'sps.jobs',
26
27
  subprocess: 'sps.subprocess',
27
28
  attachments: 'sps.attachments',
28
29
  media: 'sps.media',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coralai/sps-plugin-api",
3
- "version": "0.7.0",
3
+ "version": "0.9.0",
4
4
  "description": "sps 宿主半区的插件契约:ctx 上那些服务的方法签名。插件装它拿类型。",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",