文档/RecommendSDK
通用开发

RecommendSDK

RecommendSDK

概述

RecommendSDK 让插件可以向 CoreBox 推荐引擎注册自定义推荐提供者。当用户在空 query 下打开 CoreBox 时,推荐引擎会调用所有已注册的 provider 来收集候选项,与内置的频率、时段、趋势等维度一起参与统一评分排序。

快速开始

EXAMPLE.JAVASCRIPT
// index.js (Prelude 脚本)
const dispose = recommend.registerProvider({
  id: 'my-plugin-weather',
  name: '天气推荐',

  canProvide(context) {
    // 只在早晨时段提供天气推荐
    const hour = new Date().getHours()
    return hour >= 6 && hour <= 10
  },

  getCandidates(context) {
    return [
      {
        id: 'weather-today',
        title: '今日天气',
        subtitle: '查看今天的天气预报',
        icon: { type: 'emoji', value: '🌤️' },
        priority: 80,
        action: 'show-weather'
      }
    ]
  }
})

API 参考

recommend.registerProvider(provider)

注册一个推荐提供者。

参数

字段类型必填说明
provider.idstring提供者唯一 ID
provider.namestring提供者显示名称
provider.canProvide(context: ContextSignal) => boolean判断当前上下文是否应提供推荐
provider.getCandidates(context: ContextSignal) => PluginRecommendCandidate[] | Promise<...>返回推荐候选项列表

返回值() => void — 取消注册函数。

recommend.unregisterProvider(providerId)

按 ID 注销一个推荐提供者。

参数

  • providerId: string — 提供者 ID

返回值boolean — 是否成功移除。

PluginRecommendCandidate

每个候选项的结构:

字段类型必填说明
idstring推荐项唯一 ID
titlestring显示标题
subtitlestring副标题 / 描述
icon{ type: string; value: string }图标配置(默认 💡
prioritynumber优先级 0-100,越高越靠前(默认 50
actionstring执行回调标识,传回插件用于区分动作
dataRecord<string, unknown>附加数据,会在 TuffItem.meta.pluginRecommend.data 中透传

ContextSignal

canProvidegetCandidates 收到的上下文对象:

字段类型说明
timeOfDay'morning' | 'afternoon' | 'evening' | 'night'当前时段
dayOfWeeknumber星期几(0-6)
isWorkdayboolean是否工作日
clipboard{ content: string; meta: { isUrl: boolean; isPath: boolean; isCode: boolean } }剪贴板内容及元信息

完整示例

EXAMPLE.JAVASCRIPT
// index.js
let weatherData = null

// 注册推荐提供者
const disposeProvider = recommend.registerProvider({
  id: 'smart-weather',
  name: '智能天气',

  canProvide(context) {
    return context.timeOfDay === 'morning' && weatherData !== null
  },

  async getCandidates(context) {
    const items = [{
      id: 'weather-forecast',
      title: `今日 ${weatherData.temp}°C ${weatherData.condition}`,
      subtitle: '点击查看详情',
      icon: { type: 'emoji', value: '🌡️' },
      priority: 85,
      action: 'open-weather-detail',
      data: { city: weatherData.city }
    }]

    if (weatherData.rain) {
      items.push({
        id: 'weather-rain-alert',
        title: '今日有雨,记得带伞',
        subtitle: `降雨概率 ${weatherData.rainChance}%`,
        icon: { type: 'emoji', value: '🌧️' },
        priority: 90,
        action: 'rain-detail',
        data: { rainChance: weatherData.rainChance }
      })
    }

    return items
  }
})

// 处理推荐项的点击回调
module.exports = {
  onFeatureTriggered(featureId, query, feature) {
    // 正常的 feature 触发逻辑
  }
}

技术说明

  • 主进程本地调用:Provider 的 canProvide()getCandidates() 在主进程中直接执行,不经过 IPC 序列化。
  • 超时保护:单个 provider 的 getCandidates() 最多执行 200ms,超时自动跳过。
  • 自动清理:插件禁用/卸载时,其注册的所有 provider 会被自动清理。
  • 评分机制:候选项的 priority(0-100)直接映射为推荐分数,与频率、趋势等内置维度统一排序。

最佳实践

  1. canProvide 要轻量 — 每次打开 CoreBox 都会调用,避免异步或重计算。
  2. 合理设置 priority — 60-80 适合常规推荐,80+ 适合高置信度(如剪贴板内容关联)。
  3. 返回 dispose 函数 — 在插件内部状态变化时可以动态注册/注销。
  4. 候选项数量控制 — 单个 provider 推荐返回 1-5 个候选项,过多会被排序裁剪。