@bolloon/bolloon-agent 0.4.29 → 0.4.30

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.
Files changed (47) hide show
  1. package/dist/agents/contacts/chain.js +579 -0
  2. package/dist/agents/contacts/cli.js +158 -0
  3. package/dist/agents/contacts/consent.js +124 -0
  4. package/dist/agents/contacts/grant-payload.js +45 -0
  5. package/dist/agents/contacts/grants.js +451 -0
  6. package/dist/agents/contacts/policy.js +264 -0
  7. package/dist/agents/contacts/preview-types.js +6 -0
  8. package/dist/agents/contacts/providers.js +341 -0
  9. package/dist/agents/contacts/store.js +326 -0
  10. package/dist/agents/contacts/tools.js +154 -0
  11. package/dist/agents/contacts/types.js +148 -0
  12. package/dist/agents/pi-sdk.js +10 -0
  13. package/dist/electron-build/agents/contacts/chain.js +619 -0
  14. package/dist/electron-build/agents/contacts/chain.js.map +1 -0
  15. package/dist/electron-build/agents/contacts/consent.js +163 -0
  16. package/dist/electron-build/agents/contacts/consent.js.map +1 -0
  17. package/dist/electron-build/agents/contacts/grant-payload.js +52 -0
  18. package/dist/electron-build/agents/contacts/grant-payload.js.map +1 -0
  19. package/dist/electron-build/agents/contacts/grants.js +500 -0
  20. package/dist/electron-build/agents/contacts/grants.js.map +1 -0
  21. package/dist/electron-build/agents/contacts/policy.js +271 -0
  22. package/dist/electron-build/agents/contacts/policy.js.map +1 -0
  23. package/dist/electron-build/agents/contacts/preview-types.js +8 -0
  24. package/dist/electron-build/agents/contacts/preview-types.js.map +1 -0
  25. package/dist/electron-build/agents/contacts/providers.js +384 -0
  26. package/dist/electron-build/agents/contacts/providers.js.map +1 -0
  27. package/dist/electron-build/agents/contacts/store.js +370 -0
  28. package/dist/electron-build/agents/contacts/store.js.map +1 -0
  29. package/dist/electron-build/agents/contacts/tools.js +159 -0
  30. package/dist/electron-build/agents/contacts/tools.js.map +1 -0
  31. package/dist/electron-build/agents/contacts/types.js +166 -0
  32. package/dist/electron-build/agents/contacts/types.js.map +1 -0
  33. package/dist/electron-build/agents/external-events.js.map +1 -1
  34. package/dist/electron-build/agents/goal-store.js.map +1 -1
  35. package/dist/electron-build/agents/pi-sdk.js +10 -0
  36. package/dist/electron-build/agents/pi-sdk.js.map +1 -1
  37. package/dist/electron-build/security/tool-gate.js +4 -0
  38. package/dist/electron-build/security/tool-gate.js.map +1 -1
  39. package/dist/index.js +30 -0
  40. package/dist/security/tool-gate.js +4 -0
  41. package/dist/web/mobile-contacts.js +329 -0
  42. package/dist/web/mobile-core.js +481 -15
  43. package/dist/web/mobile.html +32 -0
  44. package/dist/web/mobile.js +139 -0
  45. package/dist/web/routes-contacts.js +420 -0
  46. package/dist/web/server.js +5 -0
  47. package/package.json +1 -1
@@ -0,0 +1,370 @@
1
+ "use strict";
2
+ /**
3
+ * contacts/store.ts — 联系方式事实的唯一落盘层 (2026-09-19, Phase 1/4)
4
+ *
5
+ * 目录: ~/.bolloon/contacts/
6
+ * social-identity.json SocialIdentity (DID 主身份 + 已验证 contactId 列表)
7
+ * contacts.json VerifiedContact[] (含 normalizedValue, 只在本层读写)
8
+ * secrets.json Secret Store, **0600**; 记录里只引用 secretRef
9
+ * sent.json SendRecord[] (requestId 去重 + 回信关联)
10
+ * ledger.jsonl 只追加的通信台账 (脱敏, 可回放)
11
+ * outbox/ 本地投递通道 (provider=local-sink) 的真落盘目录
12
+ *
13
+ * 纪律:
14
+ * - 所有写都是 tmp + rename (原子); secrets.json 额外 chmod 0600。
15
+ * - 读失败**不吞成空**: 解析损坏时抛/标记, 由调用方决定, 不许静默当成"没有联系方式"。
16
+ * - 任何对外返回值都先过 `maskContact()` —— 明文只在本层内部流转。
17
+ */
18
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
19
+ if (k2 === undefined) k2 = k;
20
+ var desc = Object.getOwnPropertyDescriptor(m, k);
21
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
22
+ desc = { enumerable: true, get: function() { return m[k]; } };
23
+ }
24
+ Object.defineProperty(o, k2, desc);
25
+ }) : (function(o, m, k, k2) {
26
+ if (k2 === undefined) k2 = k;
27
+ o[k2] = m[k];
28
+ }));
29
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
30
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
31
+ }) : function(o, v) {
32
+ o["default"] = v;
33
+ });
34
+ var __importStar = (this && this.__importStar) || (function () {
35
+ var ownKeys = function(o) {
36
+ ownKeys = Object.getOwnPropertyNames || function (o) {
37
+ var ar = [];
38
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
39
+ return ar;
40
+ };
41
+ return ownKeys(o);
42
+ };
43
+ return function (mod) {
44
+ if (mod && mod.__esModule) return mod;
45
+ var result = {};
46
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
47
+ __setModuleDefault(result, mod);
48
+ return result;
49
+ };
50
+ })();
51
+ Object.defineProperty(exports, "__esModule", { value: true });
52
+ exports.ContactsStore = exports.SecretStore = void 0;
53
+ exports.contactsDir = contactsDir;
54
+ exports.maskContact = maskContact;
55
+ exports.contactsStore = contactsStore;
56
+ exports.resetContactsStore = resetContactsStore;
57
+ exports.secretsFileMode = secretsFileMode;
58
+ const fs = __importStar(require("fs"));
59
+ const fsp = __importStar(require("fs/promises"));
60
+ const os = __importStar(require("os"));
61
+ const path = __importStar(require("path"));
62
+ const types_js_1 = require("./types.js");
63
+ const home = () => process.env.HOME || os.homedir() || '/tmp';
64
+ function contactsDir(homeDir) {
65
+ return path.join(homeDir || home(), '.bolloon', 'contacts');
66
+ }
67
+ const f = (dir, name) => path.join(dir, name);
68
+ // ── 原子写 + 权限 ───────────────────────────────────────────────────────────
69
+ async function writeJsonAtomic(file, data, mode) {
70
+ // 目录可能还没建 (例如首个动作就是写 secret) → 先建, 否则 rename 必 ENOENT
71
+ await fsp.mkdir(path.dirname(file), { recursive: true });
72
+ const tmp = `${file}.tmp-${process.pid}-${Date.now().toString(36)}`;
73
+ await fsp.writeFile(tmp, JSON.stringify(data, null, 2), 'utf8');
74
+ if (mode) {
75
+ try {
76
+ await fsp.chmod(tmp, mode);
77
+ }
78
+ catch { /* 平台不支持就算了, 但要如实记 */ }
79
+ }
80
+ await fsp.rename(tmp, file);
81
+ if (mode) {
82
+ try {
83
+ await fsp.chmod(file, mode);
84
+ }
85
+ catch { /* 同上 */ }
86
+ }
87
+ }
88
+ async function readJson(file) {
89
+ try {
90
+ return JSON.parse(await fsp.readFile(file, 'utf8'));
91
+ }
92
+ catch (err) {
93
+ if (err?.code === 'ENOENT')
94
+ return null;
95
+ // 损坏的文件绝不静默当空: 抛出去, 让上层报 degraded
96
+ throw new Error(`联系方式存储损坏 (${file}): ${err?.message || err}`);
97
+ }
98
+ }
99
+ /** 任何离开 store 的联系方式都要走这里 (明文 → 脱敏) */
100
+ function maskContact(c) {
101
+ const { normalizedValue: _drop, consentScope: _scope, secretRef: _ref, ...rest } = c;
102
+ return { ...rest, displayValue: c.displayValue || (0, types_js_1.displayFor)(c.kind, c.normalizedValue) };
103
+ }
104
+ class SecretStore {
105
+ dir;
106
+ constructor(dir) { this.dir = dir; }
107
+ file() { return f(this.dir, 'secrets.json'); }
108
+ async list() {
109
+ const all = (await readJson(this.file())) || [];
110
+ return all.map(({ value: _v, ...rest }) => rest);
111
+ }
112
+ /** 真值只在这里出现; 调用方只能是 provider 适配器 */
113
+ async get(ref) {
114
+ if (!ref)
115
+ return null;
116
+ const all = (await readJson(this.file())) || [];
117
+ return all.find((s) => s.ref === ref) || null;
118
+ }
119
+ async put(ref, provider, value) {
120
+ const all = (await readJson(this.file())) || [];
121
+ const i = all.findIndex((s) => s.ref === ref);
122
+ const entry = { ref, provider, value, createdAt: all[i]?.createdAt || new Date().toISOString(), lastVerifiedAt: all[i]?.lastVerifiedAt };
123
+ if (i >= 0)
124
+ all[i] = entry;
125
+ else
126
+ all.push(entry);
127
+ await writeJsonAtomic(this.file(), all, 0o600);
128
+ }
129
+ async remove(ref) {
130
+ const all = (await readJson(this.file())) || [];
131
+ await writeJsonAtomic(this.file(), all.filter((s) => s.ref !== ref), 0o600);
132
+ }
133
+ async has(ref) { return !!(await this.get(ref)); }
134
+ }
135
+ exports.SecretStore = SecretStore;
136
+ // ── 主 store ────────────────────────────────────────────────────────────────
137
+ class ContactsStore {
138
+ dir;
139
+ secrets;
140
+ constructor(homeDir) {
141
+ this.dir = contactsDir(homeDir);
142
+ this.secrets = new SecretStore(this.dir);
143
+ }
144
+ async ensureDirs() {
145
+ await fsp.mkdir(this.dir, { recursive: true });
146
+ await fsp.mkdir(f(this.dir, 'outbox'), { recursive: true });
147
+ }
148
+ // ── 身份 ──────────────────────────────────────────────────────────────────
149
+ async getIdentity(ownerDid) {
150
+ const ids = (await readJson(f(this.dir, 'social-identity.json'))) || [];
151
+ return ids.find((i) => i.ownerDid === ownerDid) || null;
152
+ }
153
+ async ensureIdentity(ownerDid, displayName = '') {
154
+ await this.ensureDirs();
155
+ const file = f(this.dir, 'social-identity.json');
156
+ const ids = (await readJson(file)) || [];
157
+ let id = ids.find((i) => i.ownerDid === ownerDid);
158
+ if (!id) {
159
+ id = {
160
+ identityId: (0, types_js_1.newIdentityId)(),
161
+ ownerDid,
162
+ displayName,
163
+ verifiedContacts: [],
164
+ privacyPolicy: {
165
+ plaintextVisibleToAgent: false,
166
+ batchAllowed: false,
167
+ note: '明文联系方式不进 prompt/Run/Git; 外部只看到 已验证/可联系/不可联系/需要重新授权',
168
+ },
169
+ createdAt: new Date().toISOString(),
170
+ updatedAt: new Date().toISOString(),
171
+ };
172
+ ids.push(id);
173
+ }
174
+ await writeJsonAtomic(file, ids);
175
+ return id;
176
+ }
177
+ // ── 联系方式 ──────────────────────────────────────────────────────────────
178
+ async listContacts(opts = {}) {
179
+ const all = (await readJson(f(this.dir, 'contacts.json'))) || [];
180
+ return opts.identityId ? all.filter((c) => c.identityId === opts.identityId) : all;
181
+ }
182
+ async getContact(contactId) {
183
+ return (await this.listContacts()).find((c) => c.contactId === contactId) || null;
184
+ }
185
+ /** 内部用 —— 拿明文值 (只有 provider / 回信校验该调) */
186
+ async getNormalized(contactId) {
187
+ const c = await this.getContact(contactId);
188
+ return c ? c.normalizedValue : null;
189
+ }
190
+ async putContact(c) {
191
+ await this.ensureDirs();
192
+ const file = f(this.dir, 'contacts.json');
193
+ const all = (await readJson(file)) || [];
194
+ const i = all.findIndex((x) => x.contactId === c.contactId);
195
+ c.updatedAt = new Date().toISOString();
196
+ if (i >= 0)
197
+ all[i] = c;
198
+ else
199
+ all.push(c);
200
+ // 2026-09-19: contacts.json 里存 normalizedValue (真发信要用它), 所以按 0600 落盘 ——
201
+ // 明文联系方式不该有"随便能被别人读"的副本; Run/Goal/ledger 里永远只有脱敏值。
202
+ await writeJsonAtomic(file, all, 0o600);
203
+ // 身份里的 verifiedContacts 跟着走
204
+ const sf = f(this.dir, 'social-identity.json');
205
+ const ids = (await readJson(sf)) || [];
206
+ const idIdx = ids.findIndex((x) => x.identityId === c.identityId);
207
+ if (idIdx >= 0) {
208
+ const list = new Set(ids[idIdx].verifiedContacts);
209
+ if (c.verificationStatus === 'verified' && !c.revokedAt)
210
+ list.add(c.contactId);
211
+ else
212
+ list.delete(c.contactId);
213
+ ids[idIdx].verifiedContacts = [...list];
214
+ ids[idIdx].updatedAt = new Date().toISOString();
215
+ await writeJsonAtomic(sf, ids);
216
+ }
217
+ return c;
218
+ }
219
+ /** 按 contactId → DID → 明确名称/别名 匹配 (禁止模糊姓名自动发送) */
220
+ async resolve(opts) {
221
+ const all = (await this.listContacts({ identityId: opts.identityId })).filter((c) => !c.revokedAt);
222
+ if (opts.contactId) {
223
+ const hit = all.find((c) => c.contactId === opts.contactId);
224
+ return { contact: hit || null, by: hit ? 'contactId' : 'none' };
225
+ }
226
+ if (opts.did) {
227
+ const hits = all.filter((c) => c.peerDid && c.peerDid === opts.did);
228
+ if (hits.length === 1)
229
+ return { contact: hits[0], by: 'did' };
230
+ if (hits.length > 1)
231
+ return { contact: null, by: 'none', ambiguous: true };
232
+ }
233
+ if (opts.name) {
234
+ const n = opts.name.trim().toLowerCase();
235
+ const hits = all.filter((c) => (c.aliases || []).some((a) => a.trim().toLowerCase() === n));
236
+ if (hits.length === 1)
237
+ return { contact: hits[0], by: 'name' };
238
+ if (hits.length > 1)
239
+ return { contact: null, by: 'none', ambiguous: true };
240
+ }
241
+ return { contact: null, by: 'none' };
242
+ }
243
+ // ── 发送台账 (去重 + 回信关联) ─────────────────────────────────────────────
244
+ async listSends() {
245
+ return (await readJson(f(this.dir, 'sent.json'))) || [];
246
+ }
247
+ /** 同一 requestId 已发过 → 返回旧记录 (调用方必须拒绝重复发送) */
248
+ async findSend(requestId) {
249
+ return (await this.listSends()).find((s) => s.requestId === requestId) || null;
250
+ }
251
+ async findSendByThread(threadToken) {
252
+ return (await this.listSends()).find((s) => s.threadToken === threadToken) || null;
253
+ }
254
+ async recordSend(rec) {
255
+ await this.ensureDirs();
256
+ const file = f(this.dir, 'sent.json');
257
+ const all = await this.listSends();
258
+ all.push(rec);
259
+ await writeJsonAtomic(file, all.slice(-500));
260
+ }
261
+ async patchSend(requestId, patch) {
262
+ const file = f(this.dir, 'sent.json');
263
+ const all = await this.listSends();
264
+ const i = all.findIndex((s) => s.requestId === requestId);
265
+ if (i < 0)
266
+ return;
267
+ all[i] = { ...all[i], ...patch };
268
+ await writeJsonAtomic(file, all.slice(-500));
269
+ }
270
+ /** 当天该 contact 的发送条数 (速率限制真值) */
271
+ async countSentToday(contactId, now = Date.now()) {
272
+ const day = new Date(now).toISOString().slice(0, 10);
273
+ return (await this.listSends()).filter((s) => s.contactId === contactId && s.sentAt.slice(0, 10) === day && s.status === 'sent').length;
274
+ }
275
+ async countSentForGoal(goalId) {
276
+ return (await this.listSends()).filter((s) => s.goalId === goalId && s.status === 'sent').length;
277
+ }
278
+ async markUsed(contactId) {
279
+ const c = await this.getContact(contactId);
280
+ if (!c)
281
+ return;
282
+ c.lastUsedAt = new Date().toISOString();
283
+ await this.putContact(c);
284
+ }
285
+ // ── 待批准正文 (用户内容, 0600, 发完即删) ───────────────────────────────────
286
+ /** 待批准时把真实正文暂存起来 —— consents.json 里只放脱敏预览 */
287
+ async putPendingBody(requestId, body, subject, exec) {
288
+ const file = path.join(this.dir, 'pending', `${requestId}.json`);
289
+ // 2026-09-19: 执行参数 (是否等回复 / 等多久) 必须和正文一起留下来 ——
290
+ // 否则"批准后执行"会退回默认 48h, 把用户/任务指定的等待窗口丢掉 (真跑抓到过)。
291
+ await writeJsonAtomic(file, {
292
+ requestId, body, subject, replyExpected: exec?.replyExpected, replyWindowMs: exec?.replyWindowMs,
293
+ createdAt: new Date().toISOString(),
294
+ }, 0o600);
295
+ }
296
+ async getPendingBody(requestId) {
297
+ try {
298
+ const raw = JSON.parse(await fsp.readFile(path.join(this.dir, 'pending', `${requestId}.json`), 'utf8'));
299
+ return { body: String(raw?.body || ''), subject: raw?.subject, replyExpected: raw?.replyExpected, replyWindowMs: raw?.replyWindowMs };
300
+ }
301
+ catch {
302
+ return null;
303
+ }
304
+ }
305
+ async clearPendingBody(requestId) {
306
+ try {
307
+ await fsp.unlink(path.join(this.dir, 'pending', `${requestId}.json`));
308
+ }
309
+ catch { /* 没有就算了 */ }
310
+ }
311
+ // ── 台账 (只追加) ─────────────────────────────────────────────────────────
312
+ evidenceRefFor(contactId, activity, ts) {
313
+ return `contact:${contactId}@${ts}#${activity}`;
314
+ }
315
+ async appendLedger(entry) {
316
+ await this.ensureDirs();
317
+ const full = {
318
+ ...entry,
319
+ detail: String(entry.detail || '').slice(0, 300),
320
+ evidenceRef: entry.evidenceRef || this.evidenceRefFor(entry.contactId || '-', entry.activity, entry.ts),
321
+ };
322
+ await fsp.appendFile(f(this.dir, 'ledger.jsonl'), JSON.stringify(full) + '\n', 'utf8');
323
+ return full;
324
+ }
325
+ async readLedger(opts = {}) {
326
+ try {
327
+ const raw = await fsp.readFile(f(this.dir, 'ledger.jsonl'), 'utf8');
328
+ let rows = raw.split('\n').filter(Boolean).map((l) => { try {
329
+ return JSON.parse(l);
330
+ }
331
+ catch {
332
+ return null;
333
+ } }).filter(Boolean);
334
+ if (opts.contactId)
335
+ rows = rows.filter((r) => r.contactId === opts.contactId);
336
+ if (opts.goalId)
337
+ rows = rows.filter((r) => r.goalId === opts.goalId);
338
+ return opts.limit ? rows.slice(-opts.limit) : rows;
339
+ }
340
+ catch (err) {
341
+ if (err?.code === 'ENOENT')
342
+ return [];
343
+ throw err;
344
+ }
345
+ }
346
+ }
347
+ exports.ContactsStore = ContactsStore;
348
+ /** 单例 (默认 HOME); 测试要隔离时直接 new ContactsStore(tmpHome) */
349
+ let _default = null;
350
+ function contactsStore(homeDir) {
351
+ if (homeDir)
352
+ return new ContactsStore(homeDir);
353
+ if (!_default)
354
+ _default = new ContactsStore();
355
+ return _default;
356
+ }
357
+ function resetContactsStore() { _default = null; }
358
+ /** 文件权限自检 (doctor 用): secrets.json 必须 0600 */
359
+ async function secretsFileMode(homeDir) {
360
+ const p = f(contactsDir(homeDir), 'secrets.json');
361
+ try {
362
+ const st = fs.statSync(p);
363
+ const mode = (st.mode & 0o777).toString(8);
364
+ return { path: p, mode, ok: mode === '600' };
365
+ }
366
+ catch {
367
+ return { path: p, mode: null, ok: true }; // 还没有 secret = 不算问题
368
+ }
369
+ }
370
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../../../src/agents/contacts/store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,159 @@
1
+ "use strict";
2
+ /**
3
+ * contacts/tools.ts — 暴露给 Agent 的联系工具 (2026-09-19, Phase 8)
4
+ *
5
+ * 设计铁律:
6
+ * - Agent **拿不到**手机号/邮箱原文, 只能拿 `contactId` + 脱敏 displayValue。
7
+ * - Agent **不能**指定任意收件人地址 —— 只能指定已授权 contactId (或已在别名表里的名字)。
8
+ * - 每个工具都经 policy 判定, 返回里带 blockKind / requiresApproval, 不吞掉拒绝原因。
9
+ *
10
+ * 六个工具: contact.list_authorized / preview / request_consent / send / await_reply / revoke
11
+ */
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.CONTACT_TOOL_NAMES = void 0;
14
+ exports.registerContactTools = registerContactTools;
15
+ exports.CONTACT_TOOL_NAMES = [
16
+ 'contact.list_authorized',
17
+ 'contact.preview',
18
+ 'contact.request_consent',
19
+ 'contact.send',
20
+ 'contact.await_reply',
21
+ 'contact.revoke',
22
+ ];
23
+ function text(v) { return String(v ?? '').trim(); }
24
+ function registerContactTools(ctx, chain) {
25
+ const registered = [];
26
+ ctx.tools.set('contact.list_authorized', {
27
+ name: 'contact.list_authorized',
28
+ description: '列出已授权可联系的联系方式 (只返回脱敏值: 联系人不给完整手机号/邮箱)。需要联系某人先调这个; 拿到的 contactId 才能用于发送。',
29
+ parameters: {},
30
+ execute: async () => {
31
+ const list = await chain.listAuthorized();
32
+ return {
33
+ success: true,
34
+ contacts: list,
35
+ channels: chain.channels(),
36
+ note: list.length ? '只能对这里列出的 contactId 发送; 未验证/已撤销的一律发不出去' : '还没有任何已绑定的联系方式 —— 需要用户在 CLI/桌面/手机上先绑定并验证',
37
+ };
38
+ },
39
+ });
40
+ ctx.tools.set('contact.preview', {
41
+ name: 'contact.preview',
42
+ description: '生成一份可审计的发送预览 (联系人/通道/收件人脱敏/任务/权限/是否需要人工批准), 不发送任何东西。',
43
+ parameters: {
44
+ contactId: '联系人 id (必填, 来自 contact.list_authorized)',
45
+ body: '正文 (必填)',
46
+ subject: '主题 (可选, 邮箱用)',
47
+ goalId: '关联的长期任务 id (可选但强烈建议; 未绑定的任务联系人会被拒绝)',
48
+ },
49
+ execute: async (args) => {
50
+ const contactId = text(args.contactId);
51
+ if (!contactId)
52
+ return { success: false, error: 'contactId 必填 (不允许按姓名直接发送)' };
53
+ const { decision, text: rendered } = await chain.preview({
54
+ contactId, body: text(args.body), subject: text(args.subject) || undefined, goalId: text(args.goalId) || undefined,
55
+ });
56
+ return {
57
+ success: true,
58
+ preview: rendered,
59
+ allowed: decision.allowed,
60
+ blockKind: decision.blockKind,
61
+ reason: decision.reason,
62
+ requiresApproval: decision.requiresApproval,
63
+ reallySent: decision.reallySent,
64
+ };
65
+ },
66
+ });
67
+ const sendLike = (name, description) => async (args) => {
68
+ const contactId = text(args.contactId);
69
+ if (!contactId)
70
+ return { success: false, error: 'contactId 必填 (不允许按姓名直接发送; 用 contact.list_authorized 拿 id)' };
71
+ const res = await chain.send({
72
+ contactId,
73
+ goalId: text(args.goalId) || undefined,
74
+ runId: text(args.runId) || undefined,
75
+ taskKind: text(args.taskKind) || undefined,
76
+ subject: text(args.subject) || undefined,
77
+ body: text(args.body),
78
+ requestId: text(args.requestId) || undefined,
79
+ replyExpected: args.replyExpected !== false,
80
+ });
81
+ const ok = res.status === 'sent' || res.status === 'awaiting_reply';
82
+ return {
83
+ success: ok,
84
+ status: res.status,
85
+ reason: res.reason,
86
+ blockKind: res.blockKind,
87
+ requestId: res.requestId,
88
+ consentId: res.consentId,
89
+ preview: res.preview,
90
+ evidenceRef: res.evidenceRef,
91
+ goalStatus: res.goalStatus,
92
+ // 让 Agent 说人话: 被拒/等批准时必须如实转述, 不许假装已发送
93
+ note: res.status === 'awaiting_approval'
94
+ ? '已生成待批准请求: 需要用户在 CLI/桌面/手机点批准后才会真正发送 (首次联系/敏感内容/策略要求时必然如此)'
95
+ : res.status === 'denied' ? `被策略拒绝 (${res.blockKind}): ${res.reason}` : undefined,
96
+ };
97
+ };
98
+ const sendParams = {
99
+ contactId: '联系人 id (必填)',
100
+ body: '正文 (必填)',
101
+ subject: '主题 (可选)',
102
+ goalId: '长期任务 id (任务绑定联系人必须给)',
103
+ runId: '当前 Run id (可选; 通信证据会写进这个 Run)',
104
+ requestId: '幂等 id (可选; 同一个 requestId 绝不会重复发送)',
105
+ replyExpected: '是否等待回复 (默认 true; goalId 存在时会绑定外部等待)',
106
+ };
107
+ ctx.tools.set('contact.send', {
108
+ name: 'contact.send',
109
+ description: '联系一个人 (手机号/邮箱): 经策略判定 —— 首次联系/敏感内容需要用户批准, 批量永远禁止, 未验证/已撤销一律拒绝。发送成功后若等待回复, 任务会进入 awaiting_external。',
110
+ parameters: sendParams,
111
+ execute: sendLike('contact.send', ''),
112
+ });
113
+ ctx.tools.set('contact.request_consent', {
114
+ name: 'contact.request_consent',
115
+ description: '就某次联系向用户请求授权 (不发送): 生成待批准请求 + 可审计预览, 用户批准后才发送。',
116
+ parameters: sendParams,
117
+ execute: sendLike('contact.request_consent', ''),
118
+ });
119
+ ctx.tools.set('contact.await_reply', {
120
+ name: 'contact.await_reply',
121
+ description: '查看某次联系是否在等待回复 / 是否已收到回复 / 是否超时 (只读)。',
122
+ parameters: { requestId: '发送时拿到的 requestId (必填)' },
123
+ execute: async (args) => {
124
+ const requestId = text(args.requestId);
125
+ if (!requestId)
126
+ return { success: false, error: 'requestId 必填' };
127
+ const rec = await chain.store.findSend(requestId);
128
+ if (!rec)
129
+ return { success: false, error: `没有 requestId=${requestId} 的发送记录` };
130
+ const ledger = await chain.store.readLedger({ limit: 200 });
131
+ const mine = ledger.filter((l) => l.detail.includes(requestId) || (l.contactId === rec.contactId && l.goalId === rec.goalId));
132
+ return {
133
+ success: true,
134
+ status: rec.status,
135
+ goalId: rec.goalId,
136
+ sentAt: rec.sentAt,
137
+ replied: mine.some((l) => l.activity === 'contact.reply_received'),
138
+ timedOut: mine.some((l) => l.activity === 'contact.wait_expired'),
139
+ provider: rec.provider,
140
+ evidence: mine.slice(-5).map((l) => ({ activity: l.activity, ts: l.ts, detail: l.detail, evidenceRef: l.evidenceRef })),
141
+ };
142
+ },
143
+ });
144
+ ctx.tools.set('contact.revoke', {
145
+ name: 'contact.revoke',
146
+ description: '撤销某个联系方式的授权 (用户级动作; 撤销后历史证据保留但后续调用一律拒绝)。',
147
+ parameters: { contactId: '联系人 id (必填)', reason: '撤销原因 (可选)' },
148
+ execute: async (args) => {
149
+ const contactId = text(args.contactId);
150
+ if (!contactId)
151
+ return { success: false, error: 'contactId 必填' };
152
+ const r = await chain.revoke({ contactId, by: 'agent_request', reason: text(args.reason) || undefined });
153
+ return { success: r.ok, error: r.error, affectedGoals: r.affectedGoals, evidenceRef: r.evidenceRef };
154
+ },
155
+ });
156
+ registered.push(...exports.CONTACT_TOOL_NAMES);
157
+ return registered;
158
+ }
159
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../../../src/agents/contacts/tools.ts"],"names":[],"mappings":"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"}