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/match_query ──────────────────────────────────────────
164
165/// `plugin/match_query` 请求参数 —— 宿主路由阶段询问插件是否接管当前输入。
166///
167/// 使用范围:宿主(`RemoteComponent` → SDK 分发);对全部启用中的行内插件调用。
168/// 响应为布尔值(true = 接管)。
169#[derive(Debug, Clone, Serialize, Deserialize)]
170pub struct MatchQueryParams {
171    /// 用户在搜索栏中输入的原始字符串(未做小写化等预处理)。
172    #[serde(rename = "rawQuery")]
173    pub raw_query: String,
174    /// 该插件声明的触发词(宿主从清单/代码元数据读取后随请求下发)。
175    /// 用途:让插件的默认 `match_query` 实现能就地完成框架关键词判定,无需在插件代码里重复声明。
176    #[serde(rename = "triggerKeywords")]
177    pub trigger_keywords: Vec<String>,
178}
179
180// ─── plugin/execute_action ───────────────────────────────────────
181
182#[derive(Debug, Clone, Serialize, Deserialize)]
183pub struct ExecuteActionParams {
184    #[serde(rename = "pluginId")]
185    pub plugin_id: String,
186    #[serde(rename = "ctx")]
187    pub ctx: PluginContext,
188    #[serde(rename = "actionId")]
189    pub action_id: String,
190    #[serde(rename = "payload")]
191    pub payload: serde_json::Value,
192}
193
194// ─── plugin/fetch_candidates ─────────────────────────────────────
195
196#[derive(Debug, Clone, Serialize, Deserialize)]
197pub struct FetchCandidatesParams {
198    #[serde(rename = "componentId")]
199    pub component_id: String,
200}
201
202/// Serializable candidate payload returned by remote DataSource plugins.
203/// The host reconstructs CachedCandidateData from these on receipt.
204#[derive(Debug, Clone, Serialize, Deserialize)]
205pub struct FetchCandidatesResult {
206    #[serde(rename = "candidates")]
207    pub candidates: Vec<SearchCandidate>,
208}
209
210// ─── plugin/supported_target_types ───────────────────────────────
211
212#[derive(Debug, Clone, Serialize, Deserialize)]
213pub struct SupportedTargetTypesParams {
214    #[serde(rename = "componentId")]
215    pub component_id: String,
216}
217
218// ─── plugin/supported_actions ────────────────────────────────────
219
220#[derive(Debug, Clone, Serialize, Deserialize)]
221pub struct SupportedActionsParams {
222    #[serde(rename = "componentId")]
223    pub component_id: String,
224    #[serde(rename = "targetType")]
225    pub target_type: TargetType,
226}
227
228// ─── plugin/executor_execute ─────────────────────────────────────
229
230#[derive(Debug, Clone, Serialize, Deserialize)]
231pub struct ExecutorExecuteParams {
232    #[serde(rename = "componentId")]
233    pub component_id: String,
234    /// 完整执行上下文原样透传(与进程内 ActionExecutor 拿到的 ExecutionContext 一致:
235    /// target / display_name / user_args / parameter_snapshot / locale)。
236    #[serde(rename = "executionCtx")]
237    pub execution_ctx: ExecutionContext,
238    #[serde(rename = "actionId")]
239    pub action_id: String,
240}
241
242#[derive(Debug, Clone, Serialize, Deserialize)]
243pub struct ExecutorExecuteResult {
244    #[serde(default)]
245    pub error: Option<String>,
246}
247
248// ─── plugin/calculate_scores ─────────────────────────────────────
249//
250// SearchEngine 组件:对缓存候选计算分数(含全量候选与查询词,宿主按
251// ScoredCandidate 列表重建结果)。
252
253/// plugin/calculate_scores 请求参数。
254#[derive(Debug, Clone, Serialize, Deserialize)]
255pub struct CalculateScoresParams {
256    /// 目标组件 id(SearchEngine 组件)。
257    #[serde(rename = "componentId")]
258    pub component_id: String,
259    /// 全量候选快照(宿主 CachedCandidateData::to_data 导出,id 保真)。
260    #[serde(rename = "candidates")]
261    pub candidates: CandidateCacheSnapshot,
262    /// 用户查询词。
263    #[serde(rename = "query")]
264    pub query: String,
265}
266
267// ─── plugin/booster_boost ────────────────────────────────────────
268//
269// ScoreBooster 组件:对已计算分数做增强,返回增强后的分数列表(索引与传入一致)。
270
271/// plugin/booster_boost 请求参数。
272#[derive(Debug, Clone, Serialize, Deserialize)]
273pub struct BoosterBoostParams {
274    /// 目标组件 id(ScoreBooster 组件)。
275    #[serde(rename = "componentId")]
276    pub component_id: String,
277    /// 全量候选快照(宿主 CachedCandidateData::to_data 导出,id 保真)。
278    #[serde(rename = "candidates")]
279    pub candidates: CandidateCacheSnapshot,
280    /// 引擎计算出的当前分数列表。
281    #[serde(rename = "scored")]
282    pub scored: Vec<ScoredCandidate>,
283    /// 用户查询词。
284    #[serde(rename = "query")]
285    pub query: String,
286}
287
288// ─── plugin/booster_record ───────────────────────────────────────
289//
290// ScoreBooster 组件:记录用户确认(选中候选 → 学习用户习惯)。
291
292/// plugin/booster_record 请求参数。
293#[derive(Debug, Clone, Serialize, Deserialize)]
294pub struct BoosterRecordParams {
295    /// 目标组件 id(ScoreBooster 组件)。
296    #[serde(rename = "componentId")]
297    pub component_id: String,
298    /// 被选中候选项的 id(宿主侧缓存内的原始 id)。
299    #[serde(rename = "candidateId")]
300    pub candidate_id: CandidateId,
301    /// 全量候选快照(宿主 CachedCandidateData::to_data 导出,id 保真)。
302    #[serde(rename = "candidates")]
303    pub candidates: CandidateCacheSnapshot,
304    /// 用户查询词。
305    #[serde(rename = "query")]
306    pub query: String,
307}
308
309// ─── plugin/keyword_optimizer_info ───────────────────────────────
310//
311// KeywordOptimizer 组件的声明属性(input_source / priority),
312// 宿主在发现与设置变更时经本方法拉取并缓存。
313//
314// 响应为裸 `KeywordOptimizerInfo`。
315//
316// 载荷说明:`inputSource`(嵌套对象)取代了 1.x 的 `usesContext: bool`,属载荷级
317// breaking change,已随协议 major 提升到 2.0 —— 1.x 插件在 initialize 握手期被拒绝。
318
319/// KeywordOptimizer 组件的优化属性(经 keyword_optimizer_info RPC 拉取)。
320#[derive(Debug, Clone, Serialize, Deserialize)]
321pub struct KeywordOptimizerInfo {
322    /// 优化器消费的关键词产物来源(分层 DAG-lite 输入层)。
323    #[serde(rename = "inputSource")]
324    pub input_source: KeywordInputSource,
325    /// 链式执行优先级,小者先执行。
326    #[serde(rename = "priority")]
327    pub priority: u32,
328}
329
330/// plugin/keyword_optimizer_info 请求参数。
331#[derive(Debug, Clone, Serialize, Deserialize)]
332pub struct KeywordOptimizerInfoParams {
333    /// 目标组件 id(KeywordOptimizer 组件)。
334    #[serde(rename = "componentId")]
335    pub component_id: String,
336}
337
338// ─── plugin/keyword_optimize ─────────────────────────────────────
339//
340// KeywordOptimizer 组件:优化单个关键词(宿主按链序逐级调用)。
341//
342// 响应为裸 `Vec<String>`(优化生成的新关键词)。
343
344/// plugin/keyword_optimize 请求参数。
345#[derive(Debug, Clone, Serialize, Deserialize)]
346pub struct KeywordOptimizeParams {
347    /// 目标组件 id(KeywordOptimizer 组件)。
348    #[serde(rename = "componentId")]
349    pub component_id: String,
350    /// 待优化的关键词。
351    #[serde(rename = "keyword")]
352    pub keyword: String,
353    /// 本次调用携带的来源层(供第三方优化器决策,宿主按声明来源调用)。
354    /// serde default:字段缺失时反序列化回退 Refined,避免 INVALID_PARAMS
355    /// 导致优化器整体跳过。
356    #[serde(rename = "inputSource", default)]
357    pub input_source: KeywordInputSource,
358}
359
360// KeywordInjector 组件:对单个候选注入关键词(与内置逐候选语义一致)。
361//
362// 响应为裸 `Vec<String>`。
363
364/// plugin/keyword_inject 请求参数。
365#[derive(Debug, Clone, Serialize, Deserialize)]
366pub struct KeywordInjectParams {
367    /// 目标组件 id(KeywordInjector 组件)。
368    #[serde(rename = "componentId")]
369    pub component_id: String,
370    /// 待注入的候选项(完整上下文:target、keywords 等)。
371    #[serde(rename = "candidate")]
372    pub candidate: SearchCandidate,
373}
374
375// ─── plugin/init ─────────────────────────────────────────────────
376//
377// 插件初始化钩子:宿主在组件注册完成后调用,通知插件进程完成初始化。
378// 与 plugin/initialize(进程级握手)不同层:init 携带真实查询上下文
379// (trace_id / locale),对应内置插件启动期的 Plugin::init。
380
381/// plugin/init 请求参数。
382#[derive(Debug, Clone, Serialize, Deserialize)]
383pub struct InitParams {
384    /// 目标插件 id(宿主覆盖为 manifest 插件 id)。
385    #[serde(rename = "pluginId")]
386    pub plugin_id: String,
387    /// 宿主构造的初始化上下文(真实 trace_id 与当前语言)。
388    #[serde(rename = "ctx")]
389    pub ctx: PluginContext,
390}
391
392// ─── plugin/interaction_policy ───────────────────────────────────
393//
394// 响应为裸 `PanelInteraction`(与 get_settings_schema 的裸数组约定一致)。
395// 策略为插件级语义:宿主仅对 Plugin 种类组件调用;SDK 恒返回主插件策略。
396
397/// plugin/interaction_policy 请求参数。
398#[derive(Debug, Clone, Serialize, Deserialize)]
399pub struct InteractionPolicyParams {
400    /// 目标组件 id(仅 Plugin 种类组件会收到该请求)。
401    #[serde(rename = "componentId")]
402    pub component_id: String,
403}
404
405// ─── plugin/get_default_enabled ──────────────────────────────────
406//
407// 响应为裸 `bool`。
408
409/// plugin/get_default_enabled 请求参数。
410#[derive(Debug, Clone, Serialize, Deserialize)]
411pub struct GetDefaultEnabledParams {
412    /// 目标组件 id。
413    #[serde(rename = "componentId")]
414    pub component_id: String,
415}
416
417// ─── host/log ────────────────────────────────────────────────────
418
419#[derive(Debug, Clone, Serialize, Deserialize)]
420pub struct LogParams {
421    #[serde(rename = "level")]
422    pub level: String,
423    #[serde(rename = "message")]
424    pub message: String,
425}
426
427// ─── host/notify ─────────────────────────────────────────────────
428
429#[derive(Debug, Clone, Serialize, Deserialize)]
430pub struct NotifyParams {
431    #[serde(rename = "title")]
432    pub title: String,
433    #[serde(rename = "message")]
434    pub message: String,
435}
436
437// ─── host/shell.open ─────────────────────────────────────────────
438
439#[derive(Debug, Clone, Serialize, Deserialize)]
440pub struct ShellOpenParams {
441    #[serde(rename = "target")]
442    pub target: String,
443}
444
445// ─── host/shell.open_folder ─────────────────────────────────────
446
447#[derive(Debug, Clone, Serialize, Deserialize)]
448pub struct ShellOpenFolderParams {
449    #[serde(rename = "path")]
450    pub path: String,
451}
452
453// ─── host/shell.execute_elevation ────────────────────────────────
454
455#[derive(Debug, Clone, Serialize, Deserialize)]
456pub struct ShellExecuteElevationParams {
457    #[serde(rename = "path")]
458    pub path: String,
459}
460
461// ─── host/shell.execute_command ──────────────────────────────────
462
463#[derive(Debug, Clone, Serialize, Deserialize)]
464pub struct ShellExecuteCommandParams {
465    #[serde(rename = "cmd")]
466    pub cmd: String,
467}
468
469// ─── host/window.activate_by_process ─────────────────────────────
470
471#[derive(Debug, Clone, Serialize, Deserialize)]
472pub struct WindowActivateParams {
473    #[serde(rename = "pid")]
474    pub pid: u32,
475}
476
477// ─── host/icon.get ───────────────────────────────────────────────
478// 返回值:图标字节的 base64 字符串。字节格式为 WebP(编码失败回退可能为
479// PNG),消费方按字节头嗅探 MIME(RIFF....WEBP → image/webp,否则 image/png)。
480
481#[derive(Debug, Clone, Serialize, Deserialize)]
482pub struct IconGetParams {
483    #[serde(rename = "request")]
484    pub request: serde_json::Value,
485    #[serde(rename = "level")]
486    pub level: String,
487}
488
489// ─── host/path.resolve ───────────────────────────────────────────
490
491#[derive(Debug, Clone, Serialize, Deserialize)]
492pub struct PathResolveParams {
493    #[serde(rename = "kind")]
494    pub kind: String,
495}
496
497// ─── host/resource.upload ────────────────────────────────────────
498
499#[derive(Debug, Clone, Serialize, Deserialize)]
500pub struct ResourceUploadParams {
501    #[serde(rename = "resourceId")]
502    pub resource_id: String,
503    #[serde(rename = "filePath")]
504    pub file_path: String,
505    #[serde(rename = "maxSize")]
506    #[serde(default)]
507    pub max_size: Option<usize>,
508}
509
510// ─── host/resource.put ────────────────────────────────────────────
511
512#[derive(Debug, Clone, Serialize, Deserialize)]
513pub struct ResourcePutParams {
514    #[serde(rename = "resourceId")]
515    pub resource_id: String,
516    #[serde(rename = "bytesB64")]
517    pub bytes_b64: String,
518}
519
520// ─── host/resource.get ───────────────────────────────────────────
521
522#[derive(Debug, Clone, Serialize, Deserialize)]
523pub struct ResourceGetParams {
524    #[serde(rename = "resourceId")]
525    pub resource_id: String,
526}
527
528// ─── host/resource.delete ────────────────────────────────────────
529
530#[derive(Debug, Clone, Serialize, Deserialize)]
531pub struct ResourceDeleteParams {
532    #[serde(rename = "resourceId")]
533    pub resource_id: String,
534}
535
536// ─── host/resource.list ──────────────────────────────────────────
537
538#[derive(Debug, Clone, Serialize, Deserialize)]
539pub struct ResourceListParams {}
540
541// ─── host/parameter.resolve ──────────────────────────────────────
542
543#[derive(Debug, Clone, Serialize, Deserialize)]
544pub struct ParameterResolveParams {
545    #[serde(rename = "userArgs")]
546    pub user_args: Vec<String>,
547    /// 参数模板字符串(如 "https://google.com/search?q={query}")。
548    /// 命名注意:此字段是模板,不是插件 ID。字段曾名为 pluginId 但造成混淆,已更正。
549    #[serde(rename = "template")]
550    pub template: String,
551}