Skip to main content

zerolaunch_plugin_protocol/
messages.rs

1use serde::{Deserialize, Serialize};
2use zerolaunch_plugin_api::config::ComponentType;
3use zerolaunch_plugin_api::{
4    CandidateCacheSnapshot, CandidateId, ExecutionContext, KeywordInputSource, PluginContext,
5    Query, ScoredCandidate, SearchCandidate, TargetType,
6};
7
8// ─── plugin/initialize ───────────────────────────────────────────
9
10#[derive(Debug, Clone, Serialize, Deserialize)]
11pub struct InitializeParams {
12    #[serde(rename = "hostVersion")]
13    pub host_version: String,
14    #[serde(rename = "protocolVersion")]
15    pub protocol_version: String,
16    #[serde(rename = "dataDir")]
17    pub data_dir: String,
18    #[serde(rename = "logDir")]
19    pub log_dir: String,
20    #[serde(rename = "pluginId")]
21    pub plugin_id: String,
22    #[serde(rename = "locale")]
23    pub locale: String,
24}
25
26#[derive(Debug, Clone, Serialize, Deserialize)]
27pub struct InitializeResult {
28    #[serde(rename = "protocolVersion")]
29    pub protocol_version: String,
30}
31
32// ─── plugin/get_components ───────────────────────────────────────
33
34#[derive(Debug, Clone, Serialize, Deserialize)]
35pub struct ComponentDescriptor {
36    #[serde(rename = "componentId")]
37    pub component_id: String,
38    #[serde(rename = "componentName")]
39    pub component_name: String,
40    #[serde(rename = "componentDescription", default)]
41    pub component_description: String,
42    #[serde(rename = "componentType")]
43    pub component_type: ComponentType,
44    #[serde(rename = "kind")]
45    pub kind: ComponentKind,
46    #[serde(rename = "priority", default = "default_component_priority")]
47    pub priority: u32,
48}
49
50/// 默认组件优先级,与 `Configurable::priority()` 的默认值(50)一致。
51fn default_component_priority() -> u32 {
52    50
53}
54
55/// 与内置插件完全对等:Plugin / DataSource / ActionExecutor / SearchEngine /
56/// ScoreBooster / KeywordOptimizer / KeywordInjector 均可由第三方插件提供,
57/// 宿主按 kind 注册进对应管道(触发词路由 / 候选采集 / 执行器 / 搜索管道 / 候选管道)。
58#[derive(Debug, Clone, Serialize, Deserialize)]
59#[serde(tag = "type")]
60pub enum ComponentKind {
61    /// 主插件组件(插件级元数据由宿主从清单读取)。
62    #[serde(rename = "plugin")]
63    Plugin,
64    #[serde(rename = "data_source")]
65    DataSource,
66    #[serde(rename = "action_executor")]
67    ActionExecutor {
68        #[serde(rename = "targetTypes")]
69        target_types: Vec<TargetType>,
70    },
71    /// 搜索引擎 —— 参与搜索管道(与内置引擎互斥,仅允许一个启用)。
72    #[serde(rename = "search_engine")]
73    SearchEngine,
74    /// 分数增强器 —— 在引擎打分后追加分数修正(多个可同时启用)。
75    #[serde(rename = "score_booster")]
76    ScoreBooster,
77    /// 关键词优化器 —— 在候选管道中扩展搜索关键词。
78    /// input_source / priority 为声明属性,经 keyword_optimizer_info RPC 拉取。
79    #[serde(rename = "keyword_optimizer")]
80    KeywordOptimizer,
81    /// 关键词注入器 —— 基于候选项完整上下文注入额外关键词。
82    #[serde(rename = "keyword_injector")]
83    KeywordInjector,
84}
85
86// ─── plugin/get_settings_schema ──────────────────────────────────
87
88#[derive(Debug, Clone, Serialize, Deserialize)]
89pub struct GetSettingsSchemaParams {
90    #[serde(rename = "componentId")]
91    pub component_id: String,
92}
93
94// ─── plugin/get_settings ─────────────────────────────────────────
95
96#[derive(Debug, Clone, Serialize, Deserialize)]
97pub struct GetSettingsParams {
98    #[serde(rename = "componentId")]
99    pub component_id: String,
100}
101
102// ─── plugin/apply_settings ───────────────────────────────────────
103
104#[derive(Debug, Clone, Serialize, Deserialize)]
105pub struct ApplySettingsParams {
106    #[serde(rename = "componentId")]
107    pub component_id: String,
108    #[serde(rename = "settings")]
109    pub settings: serde_json::Value,
110}
111
112// ─── plugin/validate_settings ────────────────────────────────────
113
114#[derive(Debug, Clone, Serialize, Deserialize)]
115pub struct ValidateSettingsParams {
116    #[serde(rename = "componentId")]
117    pub component_id: String,
118    #[serde(rename = "settings")]
119    pub settings: serde_json::Value,
120}
121
122#[derive(Debug, Clone, Serialize, Deserialize)]
123pub struct ValidateSettingsResult {
124    #[serde(default)]
125    pub error: Option<String>,
126}
127
128// ─── plugin/config_actions ───────────────────────────────────────
129//
130// 响应为裸数组 `Vec<ConfigActionDef>`(宿主 discover 流程以数组反序列化,
131// 与 get_settings_schema 的裸数组约定一致)。
132
133#[derive(Debug, Clone, Serialize, Deserialize)]
134pub struct ConfigActionsParams {
135    #[serde(rename = "componentId")]
136    pub component_id: String,
137}
138
139// ─── plugin/execute_config_action ────────────────────────────────
140
141#[derive(Debug, Clone, Serialize, Deserialize)]
142pub struct ExecuteConfigActionParams {
143    #[serde(rename = "componentId")]
144    pub component_id: String,
145    #[serde(rename = "action")]
146    pub action: String,
147    #[serde(rename = "params")]
148    pub params: serde_json::Value,
149}
150
151// ─── plugin/query ────────────────────────────────────────────────
152
153#[derive(Debug, Clone, Serialize, Deserialize)]
154pub struct QueryParams {
155    #[serde(rename = "pluginId")]
156    pub plugin_id: String,
157    #[serde(rename = "ctx")]
158    pub ctx: PluginContext,
159    #[serde(rename = "query")]
160    pub query: Query,
161}
162
163// ─── plugin/execute_action ───────────────────────────────────────
164
165#[derive(Debug, Clone, Serialize, Deserialize)]
166pub struct ExecuteActionParams {
167    #[serde(rename = "pluginId")]
168    pub plugin_id: String,
169    #[serde(rename = "ctx")]
170    pub ctx: PluginContext,
171    #[serde(rename = "actionId")]
172    pub action_id: String,
173    #[serde(rename = "payload")]
174    pub payload: serde_json::Value,
175}
176
177// ─── plugin/fetch_candidates ─────────────────────────────────────
178
179#[derive(Debug, Clone, Serialize, Deserialize)]
180pub struct FetchCandidatesParams {
181    #[serde(rename = "componentId")]
182    pub component_id: String,
183}
184
185/// Serializable candidate payload returned by remote DataSource plugins.
186/// The host reconstructs CachedCandidateData from these on receipt.
187#[derive(Debug, Clone, Serialize, Deserialize)]
188pub struct FetchCandidatesResult {
189    #[serde(rename = "candidates")]
190    pub candidates: Vec<SearchCandidate>,
191}
192
193// ─── plugin/supported_target_types ───────────────────────────────
194
195#[derive(Debug, Clone, Serialize, Deserialize)]
196pub struct SupportedTargetTypesParams {
197    #[serde(rename = "componentId")]
198    pub component_id: String,
199}
200
201// ─── plugin/supported_actions ────────────────────────────────────
202
203#[derive(Debug, Clone, Serialize, Deserialize)]
204pub struct SupportedActionsParams {
205    #[serde(rename = "componentId")]
206    pub component_id: String,
207    #[serde(rename = "targetType")]
208    pub target_type: TargetType,
209}
210
211// ─── plugin/executor_execute ─────────────────────────────────────
212
213#[derive(Debug, Clone, Serialize, Deserialize)]
214pub struct ExecutorExecuteParams {
215    #[serde(rename = "componentId")]
216    pub component_id: String,
217    /// 完整执行上下文原样透传(与进程内 ActionExecutor 拿到的 ExecutionContext 一致:
218    /// target / display_name / user_args / parameter_snapshot / locale)。
219    #[serde(rename = "executionCtx")]
220    pub execution_ctx: ExecutionContext,
221    #[serde(rename = "actionId")]
222    pub action_id: String,
223}
224
225#[derive(Debug, Clone, Serialize, Deserialize)]
226pub struct ExecutorExecuteResult {
227    #[serde(default)]
228    pub error: Option<String>,
229}
230
231// ─── plugin/calculate_scores ─────────────────────────────────────
232//
233// SearchEngine 组件:对缓存候选计算分数(含全量候选与查询词,宿主按
234// ScoredCandidate 列表重建结果)。
235
236/// plugin/calculate_scores 请求参数。
237#[derive(Debug, Clone, Serialize, Deserialize)]
238pub struct CalculateScoresParams {
239    /// 目标组件 id(SearchEngine 组件)。
240    #[serde(rename = "componentId")]
241    pub component_id: String,
242    /// 全量候选快照(宿主 CachedCandidateData::to_data 导出,id 保真)。
243    #[serde(rename = "candidates")]
244    pub candidates: CandidateCacheSnapshot,
245    /// 用户查询词。
246    #[serde(rename = "query")]
247    pub query: String,
248}
249
250// ─── plugin/booster_boost ────────────────────────────────────────
251//
252// ScoreBooster 组件:对已计算分数做增强,返回增强后的分数列表(索引与传入一致)。
253
254/// plugin/booster_boost 请求参数。
255#[derive(Debug, Clone, Serialize, Deserialize)]
256pub struct BoosterBoostParams {
257    /// 目标组件 id(ScoreBooster 组件)。
258    #[serde(rename = "componentId")]
259    pub component_id: String,
260    /// 全量候选快照(宿主 CachedCandidateData::to_data 导出,id 保真)。
261    #[serde(rename = "candidates")]
262    pub candidates: CandidateCacheSnapshot,
263    /// 引擎计算出的当前分数列表。
264    #[serde(rename = "scored")]
265    pub scored: Vec<ScoredCandidate>,
266    /// 用户查询词。
267    #[serde(rename = "query")]
268    pub query: String,
269}
270
271// ─── plugin/booster_record ───────────────────────────────────────
272//
273// ScoreBooster 组件:记录用户确认(选中候选 → 学习用户习惯)。
274
275/// plugin/booster_record 请求参数。
276#[derive(Debug, Clone, Serialize, Deserialize)]
277pub struct BoosterRecordParams {
278    /// 目标组件 id(ScoreBooster 组件)。
279    #[serde(rename = "componentId")]
280    pub component_id: String,
281    /// 被选中候选项的 id(宿主侧缓存内的原始 id)。
282    #[serde(rename = "candidateId")]
283    pub candidate_id: CandidateId,
284    /// 全量候选快照(宿主 CachedCandidateData::to_data 导出,id 保真)。
285    #[serde(rename = "candidates")]
286    pub candidates: CandidateCacheSnapshot,
287    /// 用户查询词。
288    #[serde(rename = "query")]
289    pub query: String,
290}
291
292// ─── plugin/keyword_optimizer_info ───────────────────────────────
293//
294// KeywordOptimizer 组件的声明属性(input_source / priority),
295// 宿主在发现与设置变更时经本方法拉取并缓存。
296//
297// 响应为裸 `KeywordOptimizerInfo`。
298//
299// 载荷说明:`inputSource`(嵌套对象)取代了 1.x 的 `usesContext: bool`,属载荷级
300// breaking change,已随协议 major 提升到 2.0 —— 1.x 插件在 initialize 握手期被拒绝。
301
302/// KeywordOptimizer 组件的优化属性(经 keyword_optimizer_info RPC 拉取)。
303#[derive(Debug, Clone, Serialize, Deserialize)]
304pub struct KeywordOptimizerInfo {
305    /// 优化器消费的关键词产物来源(分层 DAG-lite 输入层)。
306    #[serde(rename = "inputSource")]
307    pub input_source: KeywordInputSource,
308    /// 链式执行优先级,小者先执行。
309    #[serde(rename = "priority")]
310    pub priority: u32,
311}
312
313/// plugin/keyword_optimizer_info 请求参数。
314#[derive(Debug, Clone, Serialize, Deserialize)]
315pub struct KeywordOptimizerInfoParams {
316    /// 目标组件 id(KeywordOptimizer 组件)。
317    #[serde(rename = "componentId")]
318    pub component_id: String,
319}
320
321// ─── plugin/keyword_optimize ─────────────────────────────────────
322//
323// KeywordOptimizer 组件:优化单个关键词(宿主按链序逐级调用)。
324//
325// 响应为裸 `Vec<String>`(优化生成的新关键词)。
326
327/// plugin/keyword_optimize 请求参数。
328#[derive(Debug, Clone, Serialize, Deserialize)]
329pub struct KeywordOptimizeParams {
330    /// 目标组件 id(KeywordOptimizer 组件)。
331    #[serde(rename = "componentId")]
332    pub component_id: String,
333    /// 待优化的关键词。
334    #[serde(rename = "keyword")]
335    pub keyword: String,
336    /// 本次调用携带的来源层(供第三方优化器决策,宿主按声明来源调用)。
337    /// serde default:字段缺失时反序列化回退 Refined,避免 INVALID_PARAMS
338    /// 导致优化器整体跳过。
339    #[serde(rename = "inputSource", default)]
340    pub input_source: KeywordInputSource,
341}
342
343// KeywordInjector 组件:对单个候选注入关键词(与内置逐候选语义一致)。
344//
345// 响应为裸 `Vec<String>`。
346
347/// plugin/keyword_inject 请求参数。
348#[derive(Debug, Clone, Serialize, Deserialize)]
349pub struct KeywordInjectParams {
350    /// 目标组件 id(KeywordInjector 组件)。
351    #[serde(rename = "componentId")]
352    pub component_id: String,
353    /// 待注入的候选项(完整上下文:target、keywords 等)。
354    #[serde(rename = "candidate")]
355    pub candidate: SearchCandidate,
356}
357
358// ─── plugin/init ─────────────────────────────────────────────────
359//
360// 插件初始化钩子:宿主在组件注册完成后调用,通知插件进程完成初始化。
361// 与 plugin/initialize(进程级握手)不同层:init 携带真实查询上下文
362// (trace_id / locale),对应内置插件启动期的 Plugin::init。
363
364/// plugin/init 请求参数。
365#[derive(Debug, Clone, Serialize, Deserialize)]
366pub struct InitParams {
367    /// 目标插件 id(宿主覆盖为 manifest 插件 id)。
368    #[serde(rename = "pluginId")]
369    pub plugin_id: String,
370    /// 宿主构造的初始化上下文(真实 trace_id 与当前语言)。
371    #[serde(rename = "ctx")]
372    pub ctx: PluginContext,
373}
374
375// ─── plugin/interaction_policy ───────────────────────────────────
376//
377// 响应为裸 `PanelInteraction`(与 get_settings_schema 的裸数组约定一致)。
378// 策略为插件级语义:宿主仅对 Plugin 种类组件调用;SDK 恒返回主插件策略。
379
380/// plugin/interaction_policy 请求参数。
381#[derive(Debug, Clone, Serialize, Deserialize)]
382pub struct InteractionPolicyParams {
383    /// 目标组件 id(仅 Plugin 种类组件会收到该请求)。
384    #[serde(rename = "componentId")]
385    pub component_id: String,
386}
387
388// ─── plugin/get_default_enabled ──────────────────────────────────
389//
390// 响应为裸 `bool`。
391
392/// plugin/get_default_enabled 请求参数。
393#[derive(Debug, Clone, Serialize, Deserialize)]
394pub struct GetDefaultEnabledParams {
395    /// 目标组件 id。
396    #[serde(rename = "componentId")]
397    pub component_id: String,
398}
399
400// ─── host/log ────────────────────────────────────────────────────
401
402#[derive(Debug, Clone, Serialize, Deserialize)]
403pub struct LogParams {
404    #[serde(rename = "level")]
405    pub level: String,
406    #[serde(rename = "message")]
407    pub message: String,
408}
409
410// ─── host/notify ─────────────────────────────────────────────────
411
412#[derive(Debug, Clone, Serialize, Deserialize)]
413pub struct NotifyParams {
414    #[serde(rename = "title")]
415    pub title: String,
416    #[serde(rename = "message")]
417    pub message: String,
418}
419
420// ─── host/shell.open ─────────────────────────────────────────────
421
422#[derive(Debug, Clone, Serialize, Deserialize)]
423pub struct ShellOpenParams {
424    #[serde(rename = "target")]
425    pub target: String,
426}
427
428// ─── host/shell.open_folder ─────────────────────────────────────
429
430#[derive(Debug, Clone, Serialize, Deserialize)]
431pub struct ShellOpenFolderParams {
432    #[serde(rename = "path")]
433    pub path: String,
434}
435
436// ─── host/shell.execute_elevation ────────────────────────────────
437
438#[derive(Debug, Clone, Serialize, Deserialize)]
439pub struct ShellExecuteElevationParams {
440    #[serde(rename = "path")]
441    pub path: String,
442}
443
444// ─── host/shell.execute_command ──────────────────────────────────
445
446#[derive(Debug, Clone, Serialize, Deserialize)]
447pub struct ShellExecuteCommandParams {
448    #[serde(rename = "cmd")]
449    pub cmd: String,
450}
451
452// ─── host/window.activate_by_process ─────────────────────────────
453
454#[derive(Debug, Clone, Serialize, Deserialize)]
455pub struct WindowActivateParams {
456    #[serde(rename = "pid")]
457    pub pid: u32,
458}
459
460// ─── host/icon.get ───────────────────────────────────────────────
461// 返回值:图标字节的 base64 字符串。字节格式为 WebP(编码失败回退可能为
462// PNG),消费方按字节头嗅探 MIME(RIFF....WEBP → image/webp,否则 image/png)。
463
464#[derive(Debug, Clone, Serialize, Deserialize)]
465pub struct IconGetParams {
466    #[serde(rename = "request")]
467    pub request: serde_json::Value,
468    #[serde(rename = "level")]
469    pub level: String,
470}
471
472// ─── host/path.resolve ───────────────────────────────────────────
473
474#[derive(Debug, Clone, Serialize, Deserialize)]
475pub struct PathResolveParams {
476    #[serde(rename = "kind")]
477    pub kind: String,
478}
479
480// ─── host/resource.upload ────────────────────────────────────────
481
482#[derive(Debug, Clone, Serialize, Deserialize)]
483pub struct ResourceUploadParams {
484    #[serde(rename = "resourceId")]
485    pub resource_id: String,
486    #[serde(rename = "filePath")]
487    pub file_path: String,
488    #[serde(rename = "maxSize")]
489    #[serde(default)]
490    pub max_size: Option<usize>,
491}
492
493// ─── host/resource.put ────────────────────────────────────────────
494
495#[derive(Debug, Clone, Serialize, Deserialize)]
496pub struct ResourcePutParams {
497    #[serde(rename = "resourceId")]
498    pub resource_id: String,
499    #[serde(rename = "bytesB64")]
500    pub bytes_b64: String,
501}
502
503// ─── host/resource.get ───────────────────────────────────────────
504
505#[derive(Debug, Clone, Serialize, Deserialize)]
506pub struct ResourceGetParams {
507    #[serde(rename = "resourceId")]
508    pub resource_id: String,
509}
510
511// ─── host/resource.delete ────────────────────────────────────────
512
513#[derive(Debug, Clone, Serialize, Deserialize)]
514pub struct ResourceDeleteParams {
515    #[serde(rename = "resourceId")]
516    pub resource_id: String,
517}
518
519// ─── host/resource.list ──────────────────────────────────────────
520
521#[derive(Debug, Clone, Serialize, Deserialize)]
522pub struct ResourceListParams {}
523
524// ─── host/parameter.resolve ──────────────────────────────────────
525
526#[derive(Debug, Clone, Serialize, Deserialize)]
527pub struct ParameterResolveParams {
528    #[serde(rename = "userArgs")]
529    pub user_args: Vec<String>,
530    /// 参数模板字符串(如 "https://google.com/search?q={query}")。
531    /// 命名注意:此字段是模板,不是插件 ID。字段曾名为 pluginId 但造成混淆,已更正。
532    #[serde(rename = "template")]
533    pub template: String,
534}