@keyflow2/keyflow-kit-wx-reply 0.2.9

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/API.md ADDED
@@ -0,0 +1,182 @@
1
+ # WeChat Data Service API(本地离线 / Windows)
2
+
3
+ ## 接入地址
4
+
5
+ - 默认基址:`http://<HOST:PORT>`,做成可配置项
6
+ - 实际基址:以 `config.json` 或 GUI 中的 `listen_host`、`listen_port` 为准
7
+ - 推荐做法:上层应用启动时先读自己的服务配置,或先请求一次 `GET /api/v1/health` / `GET /api/v1/state` 做探活
8
+ - 不建议写死非本机 IP;本项目的默认部署方式是**本机回环地址 + 本地端口**
9
+
10
+ 说明:
11
+ - 本服务只读微信本地数据库并解密/解析,**不提供 AI**。
12
+ - 适配上层应用:自动回复、个性化对话取数、人物画像/记忆。
13
+ - 所有接口路径均相对于上述基址,例如:`http://<HOST:PORT>/api/v1/health`
14
+
15
+ 鉴权(可选):
16
+ - `config.json` 设置 `api_token` 后,**所有写接口**需要带 `Authorization: Bearer <token>`(或 `X-Api-Token: <token>`)。
17
+
18
+ ## 基础接口
19
+
20
+ ### `GET /api/v1/health`
21
+
22
+ 返回服务健康状态与当前消息序号。
23
+
24
+ 响应示例:
25
+ ```json
26
+ {"ok":true,"time":1710000000,"last_seq":123}
27
+ ```
28
+
29
+ ### `GET /api/v1/state`
30
+
31
+ 返回轻量状态(适合上层应用启动时探活/同步游标)。
32
+
33
+ 响应示例:
34
+ ```json
35
+ {"time":1710000000,"last_seq":123,"contacts_loaded":true,"self_username":"wxid_xxx","write_auth_enabled":false}
36
+ ```
37
+
38
+ ## 联系人与会话
39
+
40
+ ### `GET /api/v1/contacts?query=&limit=50`
41
+
42
+ 联系人检索(昵称/备注/微信号模糊匹配)。
43
+
44
+ 响应示例:
45
+ ```json
46
+ {"items":[{"username":"wxid_xxx","nick_name":"张三","remark":"同事","display_name":"同事","is_group":false,"avatar_url":"/avatar/wxid_xxx"}]}
47
+ ```
48
+
49
+ ### `GET /api/v1/recent_contacts?limit=20&offset=0`
50
+
51
+ 最近查询过的联系人(服务端只负责保存;前端按需拉取数量/分页)。
52
+
53
+ 记录方式:
54
+ - 调用 `GET /api/v1/chats/{username}/history` 会自动记录
55
+ - 或手动调用 `POST /api/v1/recent_contacts`
56
+
57
+ 响应示例:
58
+ ```json
59
+ {"items":[{"username":"wxid_xxx","display_name":"同事","last_access_ts":1710000000,"access_count":3,"avatar_url":"/avatar/wxid_xxx"}],"limit":20,"offset":0}
60
+ ```
61
+
62
+ ### `POST /api/v1/recent_contacts`
63
+
64
+ 手动记录一次“最近查询联系人”。
65
+
66
+ 请求示例:
67
+ ```json
68
+ {"username":"wxid_xxx"}
69
+ ```
70
+
71
+ ### `GET /api/v1/sessions?limit=50`
72
+
73
+ 最近会话列表(来自 `session.db`,含未读数和最新消息摘要)。
74
+
75
+ 响应示例:
76
+ ```json
77
+ {"items":[{"username":"wxid_xxx","display_name":"同事","avatar_url":"/avatar/wxid_xxx","unread":0,"last_timestamp":1710000000,"last_msg_type":1,"summary":"晚上吃啥"}]}
78
+ ```
79
+
80
+ ### `GET /avatar/{username}`
81
+
82
+ 联系人头像(从 `head_image/head_image.db` 读取)。
83
+
84
+ ## 实时消息(给自动回复程序用)
85
+
86
+ ### `GET /api/v1/messages?after_seq=0&limit=200`
87
+
88
+ 拉取自 `after_seq` 之后的新消息(按 `seq` 递增)。`seq` 为服务内递增编号,适合做游标避免漏消息。
89
+
90
+ 响应示例:
91
+ ```json
92
+ {"last_seq":123,"items":[{"seq":123,"timestamp":1710000000,"username":"wxid_xxx","chat":"同事","type":"文本","content":"晚上吃啥"}]}
93
+ ```
94
+
95
+ ### `GET /stream`
96
+
97
+ SSE 实时推送(浏览器 EventSource 兼容)。普通消息走默认 `message` 事件;解析补全会通过自定义事件推送(如 `rich_update` / `image_update` / `message_detail`)。
98
+
99
+ ## 历史消息(给个性化/画像取数用)
100
+
101
+ ### `GET /api/v1/chats/{username}/history?limit=50&offset=0&start_ts=&end_ts=`
102
+
103
+ 获取指定联系人/群的历史消息(从 `message_*.db` 查询)。
104
+
105
+ 额外参数:
106
+ - `after_local_id`:断点续拉(仅返回 `local_id > after_local_id` 的消息)
107
+
108
+ 响应示例:
109
+ ```json
110
+ {"username":"wxid_xxx","display_name":"同事","items":[{"local_id":1,"timestamp":1710000000,"base_type":1,"text":"晚上吃啥","raw":"晚上吃啥"}]}
111
+ ```
112
+
113
+ 说明:
114
+ - 返回的 `items[]` 会包含 `sender_username`/`is_send`/`direction`(可用来避免对自己消息触发自动回复)。
115
+ - 返回 `last_local_id` 便于上层保存游标。
116
+
117
+ ## 消息处理状态(ACK / 幂等)
118
+
119
+ ### `GET /api/v1/chats/{username}/message_status?app_id=xxx&local_id=123`
120
+
121
+ 查询某条消息对某个上层应用的处理状态。
122
+
123
+ ### `GET /api/v1/chats/{username}/message_status?app_id=xxx&status=&limit=50&offset=0`
124
+
125
+ 列出该联系人下的处理状态记录(按 `updated_at` 倒序)。
126
+
127
+ ### `POST /api/v1/chats/{username}/message_status`
128
+
129
+ 写入/更新一条处理状态(Upsert)。
130
+
131
+ 请求示例:
132
+ ```json
133
+ {"app_id":"auto-reply","local_id":123,"status":"replied","info":{"reply_id":"..."}}
134
+ ```
135
+
136
+ ## 人物画像与记忆(不含 AI,仅存取)
137
+
138
+ 存储文件:`persona_db`(默认 `persona.db`)。
139
+
140
+ ### `GET /api/v1/people/{username}/profile`
141
+
142
+ 获取画像(并返回联系人基础信息 `contact`)。
143
+
144
+ ### `PATCH /api/v1/people/{username}/profile`
145
+
146
+ 更新画像字段:`tags` / `notes` / `auto_reply_policy`。
147
+
148
+ ### `GET /api/v1/people/{username}/memories?kind=&status=active&q=&limit=50&offset=0`
149
+
150
+ 列出记忆条目(支持按 kind/status 搜索与分页)。
151
+
152
+ ### `POST /api/v1/people/{username}/memories`
153
+
154
+ 新增记忆条目(示例字段:`kind`/`key`/`value`/`importance`/`confidence`/`status`/`source`/`evidence`/`expires_at`)。
155
+
156
+ ### `PATCH /api/v1/memories/{id}`
157
+
158
+ 更新记忆条目(同上字段,按需传递)。
159
+
160
+ ### `DELETE /api/v1/memories/{id}`
161
+
162
+ 软删除:将条目标记为 `invalidated`。
163
+
164
+ ## AI 运行记录(仅元数据存储,不执行 AI)
165
+
166
+ ### `GET /api/v1/people/{username}/runs?kind=&status=&limit=20&offset=0`
167
+
168
+ 列出画像/记忆/总结等 AI 运行记录(由上层应用写入)。
169
+
170
+ ### `POST /api/v1/people/{username}/runs`
171
+
172
+ 创建一条运行记录。
173
+
174
+ 请求示例:
175
+ ```json
176
+ {"app_id":"persona-ui","kind":"profile_refresh","status":"running","model":"gpt-4.1-mini","input_range":{"start_ts":1710000000,"end_ts":1710003600}}
177
+ ```
178
+
179
+ ### `PATCH /api/v1/runs/{run_id}`
180
+
181
+ 更新运行记录(例如结束时写入 `status/finished_at/error/tokens`)。
182
+
package/LICENSE ADDED
@@ -0,0 +1,202 @@
1
+ Apache License
2
+ Version 2.0, January 2004
3
+ http://www.apache.org/licenses/
4
+
5
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6
+
7
+ 1. Definitions.
8
+
9
+ "License" shall mean the terms and conditions for use, reproduction,
10
+ and distribution as defined by Sections 1 through 9 of this document.
11
+
12
+ "Licensor" shall mean the copyright owner or entity authorized by
13
+ the copyright owner that is granting the License.
14
+
15
+ "Legal Entity" shall mean the union of the acting entity and all
16
+ other entities that control, are controlled by, or are under common
17
+ control with that entity. For the purposes of this definition,
18
+ "control" means (i) the power, direct or indirect, to cause the
19
+ direction or management of such entity, whether by contract or
20
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
21
+ outstanding shares, or (iii) beneficial ownership of such entity.
22
+
23
+ "You" (or "Your") shall mean an individual or Legal Entity
24
+ exercising permissions granted by this License.
25
+
26
+ "Source" form shall mean the preferred form for making modifications,
27
+ including but not limited to software source code, documentation
28
+ source, and configuration files.
29
+
30
+ "Object" form shall mean any form resulting from mechanical
31
+ transformation or translation of a Source form, including but
32
+ not limited to compiled object code, generated documentation,
33
+ and conversions to other media types.
34
+
35
+ "Work" shall mean the work of authorship, whether in Source or
36
+ Object form, made available under the License, as indicated by a
37
+ copyright notice that is included in or attached to the work
38
+ (an example is provided in the Appendix below).
39
+
40
+ "Derivative Works" shall mean any work, whether in Source or Object
41
+ form, that is based on (or derived from) the Work and for which the
42
+ editorial revisions, annotations, elaborations, or other modifications
43
+ represent, as a whole, an original work of authorship. For the purposes
44
+ of this License, Derivative Works shall not include works that remain
45
+ separable from, or merely link (or bind by name) to the interfaces of,
46
+ the Work and Derivative Works thereof.
47
+
48
+ "Contribution" shall mean any work of authorship, including
49
+ the original version of the Work and any modifications or additions
50
+ to that Work or Derivative Works thereof, that is intentionally
51
+ submitted to Licensor for inclusion in the Work by the copyright owner
52
+ or by an individual or Legal Entity authorized to submit on behalf of
53
+ the copyright owner. For the purposes of this definition, "submitted"
54
+ means any form of electronic, verbal, or written communication sent
55
+ to the Licensor or its representatives, including but not limited to
56
+ communication on electronic mailing lists, source code control systems,
57
+ and issue tracking systems that are managed by, or on behalf of, the
58
+ Licensor for the purpose of discussing and improving the Work, but
59
+ excluding communication that is conspicuously marked or otherwise
60
+ designated in writing by the copyright owner as "Not a Contribution."
61
+
62
+ "Contributor" shall mean Licensor and any individual or Legal Entity
63
+ on behalf of whom a Contribution has been received by Licensor and
64
+ subsequently incorporated within the Work.
65
+
66
+ 2. Grant of Copyright License. Subject to the terms and conditions of
67
+ this License, each Contributor hereby grants to You a perpetual,
68
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69
+ copyright license to reproduce, prepare Derivative Works of,
70
+ publicly display, publicly perform, sublicense, and distribute the
71
+ Work and such Derivative Works in Source or Object form.
72
+
73
+ 3. Grant of Patent License. Subject to the terms and conditions of
74
+ this License, each Contributor hereby grants to You a perpetual,
75
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76
+ (except as stated in this section) patent license to make, have made,
77
+ use, offer to sell, sell, import, and otherwise transfer the Work,
78
+ where such license applies only to those patent claims licensable
79
+ by such Contributor that are necessarily infringed by their
80
+ Contribution(s) alone or by combination of their Contribution(s)
81
+ with the Work to which such Contribution(s) was submitted. If You
82
+ institute patent litigation against any entity (including a
83
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
84
+ or a Contribution incorporated within the Work constitutes direct
85
+ or contributory patent infringement, then any patent licenses
86
+ granted to You under this License for that Work shall terminate
87
+ as of the date such litigation is filed.
88
+
89
+ 4. Redistribution. You may reproduce and distribute copies of the
90
+ Work or Derivative Works thereof in any medium, with or without
91
+ modifications, and in Source or Object form, provided that You
92
+ meet the following conditions:
93
+
94
+ (a) You must give any other recipients of the Work or
95
+ Derivative Works a copy of this License; and
96
+
97
+ (b) You must cause any modified files to carry prominent notices
98
+ stating that You changed the files; and
99
+
100
+ (c) You must retain, in the Source form of any Derivative Works
101
+ that You distribute, all copyright, patent, trademark, and
102
+ attribution notices from the Source form of the Work,
103
+ excluding those notices that do not pertain to any part of
104
+ the Derivative Works; and
105
+
106
+ (d) If the Work includes a "NOTICE" text file as part of its
107
+ distribution, then any Derivative Works that You distribute must
108
+ include a readable copy of the attribution notices contained
109
+ within such NOTICE file, excluding those notices that do not
110
+ pertain to any part of the Derivative Works, in at least one
111
+ of the following places: within a NOTICE text file distributed
112
+ as part of the Derivative Works; within the Source form or
113
+ documentation, if provided along with the Derivative Works; or,
114
+ within a display generated by the Derivative Works, if and
115
+ wherever such third-party notices normally appear. The contents
116
+ of the NOTICE file are for informational purposes only and
117
+ do not modify the License. You may add Your own attribution
118
+ notices within Derivative Works that You distribute, alongside
119
+ or as an addendum to the NOTICE text from the Work, provided
120
+ that such additional attribution notices cannot be construed
121
+ as modifying the License.
122
+
123
+ You may add Your own copyright statement to Your modifications and
124
+ may provide additional or different license terms and conditions
125
+ for use, reproduction, or distribution of Your modifications, or
126
+ for any such Derivative Works as a whole, provided Your use,
127
+ reproduction, and distribution of the Work otherwise complies with
128
+ the conditions stated in this License.
129
+
130
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
131
+ any Contribution intentionally submitted for inclusion in the Work
132
+ by You to the Licensor shall be under the terms and conditions of
133
+ this License, without any additional terms or conditions.
134
+ Notwithstanding the above, nothing herein shall supersede or modify
135
+ the terms of any separate license agreement you may have executed
136
+ with Licensor regarding such Contributions.
137
+
138
+ 6. Trademarks. This License does not grant permission to use the trade
139
+ names, trademarks, service marks, or product names of the Licensor,
140
+ except as required for reasonable and customary use in describing the
141
+ origin of the Work and reproducing the content of the NOTICE file.
142
+
143
+ 7. Disclaimer of Warranty. Unless required by applicable law or
144
+ agreed to in writing, Licensor provides the Work (and each
145
+ Contributor provides its Contributions) on an "AS IS" BASIS,
146
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147
+ implied, including, without limitation, any warranties or conditions
148
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149
+ PARTICULAR PURPOSE. You are solely responsible for determining the
150
+ appropriateness of using or redistributing the Work and assume any
151
+ risks associated with Your exercise of permissions under this License.
152
+
153
+ 8. Limitation of Liability. In no event and under no legal theory,
154
+ whether in tort (including negligence), contract, or otherwise,
155
+ unless required by applicable law (such as deliberate and grossly
156
+ negligent acts) or agreed to in writing, shall any Contributor be
157
+ liable to You for damages, including any direct, indirect, special,
158
+ incidental, or consequential damages of any character arising as a
159
+ result of this License or out of the use or inability to use the
160
+ Work (including but not limited to damages for loss of goodwill,
161
+ work stoppage, computer failure or malfunction, or any and all
162
+ other commercial damages or losses), even if such Contributor
163
+ has been advised of the possibility of such damages.
164
+
165
+ 9. Accepting Warranty or Additional Liability. While redistributing
166
+ the Work or Derivative Works thereof, You may choose to offer,
167
+ and charge a fee for, acceptance of support, warranty, indemnity,
168
+ or other liability obligations and/or rights consistent with this
169
+ License. However, in accepting such obligations, You may act only
170
+ on Your own behalf and on Your sole responsibility, not on behalf
171
+ of any other Contributor, and only if You agree to indemnify,
172
+ defend, and hold each Contributor harmless for any liability
173
+ incurred by, or claims asserted against, such Contributor by reason
174
+ of your accepting any such warranty or additional liability.
175
+
176
+ END OF TERMS AND CONDITIONS
177
+
178
+ APPENDIX: How to apply the Apache License to your work.
179
+
180
+ To apply the Apache License to your work, attach the following
181
+ boilerplate notice, with the fields enclosed by brackets "[]"
182
+ replaced with your own identifying information. (Don't include
183
+ the brackets!) The text should be enclosed in the appropriate
184
+ comment syntax for the file format. We also recommend that a
185
+ file or class name and description of purpose be included on the
186
+ same "printed page" as the copyright notice for easier
187
+ identification within third-party archives.
188
+
189
+ Copyright [yyyy] [name of copyright owner]
190
+
191
+ Licensed under the Apache License, Version 2.0 (the "License");
192
+ you may not use this file except in compliance with the License.
193
+ You may obtain a copy of the License at
194
+
195
+ http://www.apache.org/licenses/LICENSE-2.0
196
+
197
+ Unless required by applicable law or agreed to in writing, software
198
+ distributed under the License is distributed on an "AS IS" BASIS,
199
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200
+ See the License for the specific language governing permissions and
201
+ limitations under the License.
202
+
@@ -0,0 +1,158 @@
1
+ # 上层应用规划(基于 WeChat Data Service)
2
+
3
+ 本仓库的定位是**本地离线的数据底座**:读取/解密微信本地数据库,并通过本机 HTTP API 提供联系人、会话、消息、头像,以及“画像/记忆/AI 运行元数据”的**存取**能力。
4
+ 注意:**本服务不做 AI**、也不负责“发送微信消息”(自动回复属于上层应用的能力)。
5
+
6
+ 本文档用于把你接下来要做的“上层应用”一次性列清楚:它们是什么、各自要做哪些功能、以及它们依赖底层服务的哪些接口。
7
+
8
+ 相关参考:
9
+ - API:`docs/API.md`
10
+ - 集成缺口/易踩坑:`docs/INTEGRATION_GAPS.md`
11
+ - 画像/记忆模型建议:`docs/PERSONA_MEMORY_MODEL.md`
12
+
13
+ ---
14
+
15
+ ## 硬约束(别做反)
16
+
17
+ - **首发 Windows、本地离线跑**:上层应用默认只连本机数据服务,默认地址是 `http://127.0.0.1:5678`。
18
+ - **端口可配置,但默认不要改**:实际以 `config.json` / GUI 中的 `listen_host`、`listen_port` 为准;若未改动,就按 `127.0.0.1:5678` 接入。
19
+ - **用户是普通人**:上层 UI 必须“少文字、强引导、少概念”,用流程化/卡片化/按钮化表达。
20
+ - **隐私优先**:默认不出网;若要调用 AI/云服务,只能由上层应用明确开关,并把“输入范围/上次运行时间/失败原因”写回(runs 记录)。
21
+ - **联系人主键只能用 `username`**:昵称/备注会变,只用于展示与搜索。
22
+
23
+ 服务接入基址:
24
+ - 默认:`http://127.0.0.1:5678`
25
+ - 健康检查:`GET /api/v1/health`
26
+ - 轻量状态:`GET /api/v1/state`
27
+ - 详细接口定义:见 `docs/API.md`
28
+
29
+ ---
30
+
31
+ ## 上层应用清单(建议最少先做 3 个)
32
+
33
+ ### 0) 服务管理器(已在本仓库内)
34
+
35
+ 用途:给普通用户配置并后台启动“数据服务”,提供开机自启、日志与诊断入口。
36
+ 这是所有上层应用的“运行前置条件”(确保服务可用)。
37
+
38
+ ---
39
+
40
+ ### 1) 微信消息自动回复(Auto Reply Agent)
41
+
42
+ **定位**:一个独立进程/应用,负责“读消息 → 决策 → 发消息”。(AI 可在此应用内集成,但不在数据底座做)
43
+
44
+ **P0 必做功能(能稳定跑且不乱回)**
45
+ - **服务连接与自检**:启动时探活;获取 `self_username`;提示用户“服务未启动/端口被占用/目录无效”的可操作原因。
46
+ - **联系人选择与歧义处理**:按昵称/备注/微信号搜索;多匹配时让用户确认;展示头像。
47
+ - **收消息(可靠)**
48
+ - 新消息拉取/订阅(SSE 或轮询)。
49
+ - 断点续跑:保存游标;重启后继续,不漏不重。
50
+ - 去重:优先用 `(username, local_id)`;拿不到时退化规则见 `docs/INTEGRATION_GAPS.md`。
51
+ - 方向判断:永远不对“自己发的消息”触发回复(依赖 `self_username`/`direction`)。
52
+ - **处理确认(ACK/幂等)**:每条消息对每个 app 只进入一次处理链路;处理结果写入 `message_status`。
53
+ - **安全阀**:限速/熔断(例如连续失败暂停);黑白名单;群聊默认不回或仅 @我 才回(策略可配置)。
54
+ - **可排障**:日志落盘;一键复制诊断信息(包含游标、最近错误、当前策略)。
55
+
56
+ **P1 功能(决定体验上限)**
57
+ - **规则系统**:按联系人/群、时间段、关键字、是否 @我、是否包含图片/语音等组合条件触发。
58
+ - **“人设/策略”接入点**:从画像/记忆读取“偏好/禁忌/称呼/语气”等,作为回复策略输入。
59
+ - **人工接管**:当用户正在手动聊天时自动暂停;或提供“一键暂停/恢复”。
60
+ - **群聊增强**:识别发送者;@谁;引用回复;“免打扰时段”。
61
+
62
+ **依赖底层服务的接口(现有)**
63
+ - 探活/状态:`GET /api/v1/health`、`GET /api/v1/state`
64
+ - 联系人:`GET /api/v1/contacts`、`GET /api/v1/sessions`、`GET /api/v1/recent_contacts`、`POST /api/v1/recent_contacts`
65
+ - 消息:`GET /api/v1/messages`、`GET /stream`、`GET /api/v1/chats/{username}/history`
66
+ - 幂等/ACK:`GET/POST /api/v1/chats/{username}/message_status`
67
+ - 画像/记忆读取(可选):`GET /api/v1/people/{username}/profile`、`GET /api/v1/people/{username}/memories`
68
+ - 头像:`GET /avatar/{username}`
69
+
70
+ **注意(上层必须自己解决)**
71
+ - **“发消息”**:需要 Windows 微信的自动化/注入/辅助功能等方案(不在本服务范围)。
72
+
73
+ ---
74
+
75
+ ### 2) 人物画像与记忆管理器(Persona / Memory Studio)
76
+
77
+ **定位**:一个面向普通用户的“联系人信息中心”,用来查看/编辑画像与记忆;也作为上层 AI 生成画像/记忆的“人工校正入口”。
78
+
79
+ **前端你描述的核心界面能力(对应后端职责)**
80
+ - 联系人基础信息(头像、备注/昵称、会话摘要)
81
+ - “上一次聊天聊了什么”(来自 sessions 最新摘要 + 可跳转历史)
82
+ - 与此人相关的“记忆”(偏好、禁忌、重要信息、性格特点等)
83
+
84
+ **P0 必做功能**
85
+ - **联系人检索 + 最近访问**:支持取最近 N 条;返回头像;最近访问自动记录。
86
+ - **画像展示/编辑(非 AI)**:标签、备注、自动回复策略(例如:是否允许自动回复/是否仅工作时间/称呼)。
87
+ - **记忆 CRUD(结构化)**
88
+ - 新增/编辑/作废(软删除)记忆条目。
89
+ - 记忆状态:`active` / `pending(待确认)` / `invalidated`(AI 推断默认 pending,避免“当事实写死”)。
90
+ - evidence:每条记忆可挂 1–3 条证据(可跳转到原对话)。
91
+ - **AI 运行记录时间线(只存元数据)**
92
+ - 展示“上次刷新时间/用的模型/输入范围/成功失败原因”。
93
+ - 允许“重新刷新”(实际调用 AI 在上层做,底层只存结果与 run 记录)。
94
+ - **备份/迁移**:导出/导入 `persona.db`(对普通用户非常关键)。
95
+
96
+ **P1 功能**
97
+ - 记忆搜索/筛选(按 kind/status/关键词/重要度/时间)
98
+ - 冲突提示与合并(同一 key 多条候选记忆)
99
+ - 审计/撤销(谁在什么时候改了哪条记忆,按 app_id/source)
100
+
101
+ **依赖底层服务的接口(现有)**
102
+ - 联系人/会话/头像:`GET /api/v1/contacts`、`GET /api/v1/sessions`、`GET/POST /api/v1/recent_contacts`、`GET /avatar/{username}`
103
+ - 历史对话:`GET /api/v1/chats/{username}/history`
104
+ - 画像/记忆:`GET/PATCH /api/v1/people/{username}/profile`、`GET/POST /api/v1/people/{username}/memories`、`PATCH/DELETE /api/v1/memories/{id}`
105
+ - AI runs:`GET/POST /api/v1/people/{username}/runs`、`PATCH /api/v1/runs/{run_id}`
106
+
107
+ ---
108
+
109
+ ### 3) 个性化策略引擎(Personalization / Policy Engine)
110
+
111
+ **定位**:一个“面向上层应用的内部组件/服务”,负责把聊天历史转成可用的“策略/约束/风格”,写回画像/记忆库;供自动回复或其它应用复用。
112
+
113
+ 它可以是:
114
+ - 纯规则/模板(不需要 AI)
115
+ - 或者调用 AI(但 AI 仍在此上层组件内完成)
116
+
117
+ **P0 必做功能(先把工程问题解决)**
118
+ - 增量刷新:明确本次输入范围(start/end_ts 或 local_id 范围),并写入 run 记录
119
+ - 写回可追溯:写入 memories 时带 `source/app_id`、`evidence`、`confidence`
120
+ - 待确认:低置信度/推断类结论默认 `pending`
121
+ - 冲突策略:同一 key 的记忆如何“替换/追加/作废”
122
+
123
+ **依赖底层服务的接口(现有)**
124
+ - 取数:`GET /api/v1/chats/{username}/history`、`GET /api/v1/sessions`
125
+ - 写回:profile/memories/runs 系列接口(同上)
126
+
127
+ ---
128
+
129
+ ## 可选上层应用(按需再做)
130
+
131
+ ### 4) 对话检索与导出(Search / Export)
132
+
133
+ 用途:让用户把“某人/某段时间”的对话导出为 JSON/Markdown/CSV,用于备份、迁移、或喂给外部工具。
134
+ 建议:先做“单联系人导出”,不要一上来做全库索引(复杂且很吃资源)。
135
+
136
+ ### 5) 本地事件桥(Automation Bridge)
137
+
138
+ 用途:把新消息事件转成“本机 webhook/脚本触发/系统通知”,给其它桌面自动化工具使用。
139
+ 关键:去重 + ACK + 限速,避免风暴。
140
+
141
+ ### 6) SDK/封装库(给你自己用)
142
+
143
+ 用途:给上层应用提供一个统一的 API Client(Python/Node 任选),把:
144
+ - SSE 连接、断线重连
145
+ - 游标保存
146
+ - `api_token` 注入
147
+ - `(username, local_id)` 去重与 ACK
148
+ 都封装掉,避免每个应用各写一遍然后各踩一遍坑。
149
+
150
+ ---
151
+
152
+ ## 最小推进建议(Occam:先做最少但可用)
153
+
154
+ 如果你要最快做出“能卖给普通用户”的组合,建议顺序:
155
+ 1) **服务管理器(已做)**:确保安装/自启/日志可用
156
+ 2) **自动回复(P0)**:可靠收消息 + 幂等 + 安全阀(发消息方案另做)
157
+ 3) **画像/记忆管理器(P0)**:让用户能看见/能改/能确认 pending(建立信任)
158
+ 4) 再上个性化策略引擎(把 AI/规则的复杂度封装在内部)
Binary file
Binary file
Binary file
package/manifest.json ADDED
@@ -0,0 +1,60 @@
1
+ {
2
+ "id": "wx-reply",
3
+ "name": "WX 回复",
4
+ "version": "0.2.9",
5
+ "description": "微信聊天回复助手:依赖电脑端 wechat-decrypt 本地解密服务(https://github.com/hc-tec/wechat-decrypt)读取会话,再结合宿主共享 AI 生成候选回复;不是下载后即可直接使用,需先在电脑运行该服务并让手机可访问。",
6
+ "icons": {
7
+ "48": "icons/icon-48.png",
8
+ "96": "icons/icon-96.png",
9
+ "128": "icons/icon-128.png"
10
+ },
11
+ "entry": {
12
+ "bundle": { "html": "ui/app/index.html" }
13
+ },
14
+ "runtimePermissions": [
15
+ "input.insert",
16
+ "storage.read",
17
+ "storage.write",
18
+ "network.fetch",
19
+ "ai.request",
20
+ "panel.state.write"
21
+ ],
22
+ "network": {
23
+ "mode": "host-proxy",
24
+ "allowAbsoluteUrls": true
25
+ },
26
+ "bindings": [
27
+ {
28
+ "id": "wx.reply",
29
+ "title": "微信回复",
30
+ "triggers": ["manual"],
31
+ "categories": ["chat", "wechat", "reply"],
32
+ "preferredPresentation": "panel.compose",
33
+ "entry": { "view": "picker", "defaultAction": "insert" }
34
+ }
35
+ ],
36
+ "discovery": {
37
+ "launchMode": "panel-first",
38
+ "slash": {
39
+ "enabled": true,
40
+ "commands": ["wx"],
41
+ "aliases": ["w"],
42
+ "tags": ["wechat", "reply", "chat"]
43
+ }
44
+ },
45
+ "ai": {
46
+ "executionMode": "direct-model",
47
+ "backendHints": {
48
+ "preferredBackendClass": "direct-model",
49
+ "latencyTier": "interactive",
50
+ "latencyBudgetMs": 2200,
51
+ "requireStructuredJson": true,
52
+ "requiredCapabilities": [],
53
+ "notes": [
54
+ "Generate two concise WeChat replies.",
55
+ "Prefer strict JSON output.",
56
+ "Use selected contact context when available."
57
+ ]
58
+ }
59
+ }
60
+ }
package/package.json ADDED
@@ -0,0 +1,25 @@
1
+ {
2
+ "name": "@keyflow2/keyflow-kit-wx-reply",
3
+ "version": "0.2.9",
4
+ "description": "微信聊天回复助手:依赖电脑端 wechat-decrypt 本地解密服务(https://github.com/hc-tec/wechat-decrypt)读取会话,再结合宿主共享 AI 生成候选回复;不是下载后即可直接使用,需先在电脑运行该服务并让手机可访问。",
5
+ "keywords": [
6
+ "keyflow",
7
+ "function-kit",
8
+ "ime",
9
+ "webview"
10
+ ],
11
+ "license": "Apache-2.0",
12
+ "repository": {
13
+ "type": "git",
14
+ "url": "git+https://github.com/hc-tec/keyflow.git"
15
+ },
16
+ "bugs": {
17
+ "url": "https://github.com/hc-tec/keyflow/issues"
18
+ },
19
+ "homepage": "https://github.com/hc-tec/keyflow#readme",
20
+ "keyflow": {
21
+ "kind": "function-kit",
22
+ "kitId": "wx-reply",
23
+ "manifest": "manifest.json"
24
+ }
25
+ }